aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--GNUmakefile15
-rw-r--r--mdns.c187
-rw-r--r--mdns.h3
-rw-r--r--xenwatch.c7
4 files changed, 206 insertions, 6 deletions
diff --git a/GNUmakefile b/GNUmakefile
index d8cff65..76ff4e2 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -6,8 +6,8 @@ include mk/Variables.mk
CFLAGS += -DVERSION='"$(VERSION)"'
# build
-TARGETS := xenlog
-GTK_TARGETS := xenwatch
+TARGETS := xenlog
+GTK_TARGETS := xenwatch
# default target
all: build
@@ -21,12 +21,17 @@ include mk/Autoconf.mk
define make-config
LIB := $(LIB)
HAVE_GTK := $(call ac_pkg_config,gtk+-x11-2.0)
+HAVE_AVAHI := $(call ac_pkg_config,avahi-glib)
endef
# gtk stuff
ifeq ($(HAVE_GTK),yes)
- $(GTK_TARGETS) : CFLAGS += $(shell pkg-config --cflags gtk+-x11-2.0) -Wno-strict-prototypes
- $(GTK_TARGETS) : LDLIBS += $(shell pkg-config --libs gtk+-x11-2.0)
+ pkgs := gtk+-x11-2.0
+ ifeq ($(HAVE_AVAHI),yes)
+ pkgs += avahi-glib avahi-client
+ endif
+ $(GTK_TARGETS) : CFLAGS += $(shell pkg-config --cflags $(pkgs)) -Wno-strict-prototypes
+ $(GTK_TARGETS) : LDLIBS += $(shell pkg-config --libs $(pkgs))
TARGETS += $(GTK_TARGETS)
endif
@@ -56,7 +61,7 @@ realclean distclean: clean
#############################################
-xenwatch: xenwatch.o xs_view.o xs_store.o xd_view.o xd_store.o tcp.o
+xenwatch: xenwatch.o xs_view.o xs_store.o xd_view.o xd_store.o tcp.o mdns.o
xenlog: xenlog.o
diff --git a/mdns.c b/mdns.c
new file mode 100644
index 0000000..19e44ca
--- /dev/null
+++ b/mdns.c
@@ -0,0 +1,187 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include <glib.h>
+
+#include <avahi-client/client.h>
+#include <avahi-client/lookup.h>
+#include <avahi-common/error.h>
+#include <avahi-common/timeval.h>
+#include <avahi-glib/glib-watch.h>
+#include <avahi-glib/glib-malloc.h>
+
+#include "list.h"
+#include "mdns.h"
+
+/* ---------------------------------------------------------------------- */
+
+static const char *revents[] = {
+ [ AVAHI_RESOLVER_FOUND ] = "FOUND",
+ [ AVAHI_RESOLVER_FAILURE ] = "FAILURE",
+};
+static const char *bevents[] = {
+ [ AVAHI_BROWSER_NEW ] = "NEW",
+ [ AVAHI_BROWSER_REMOVE ] = "REMOVE",
+ [ AVAHI_BROWSER_CACHE_EXHAUSTED ] = "CACHE_EXHAUSTED",
+ [ AVAHI_BROWSER_ALL_FOR_NOW ] = "ALL_FOR_NOW",
+ [ AVAHI_BROWSER_FAILURE ] = "FAILURE",
+};
+
+static const AvahiPoll *poll_api;
+static AvahiGLibPoll *glib_poll;
+static AvahiClient *client;
+
+struct mdns_entry {
+ const char *name;
+ const char *type;
+ const char *domain;
+ AvahiIfIndex interface;
+ AvahiProtocol protocol;
+
+ const char *address;
+ const char *hostname;
+ uint16_t port;
+
+ struct list_head next;
+};
+static LIST_HEAD(mdns_entries);
+
+/* ---------------------------------------------------------------------- */
+
+static void resolve_callback(AvahiServiceResolver *r,
+ AvahiIfIndex interface,
+ AvahiProtocol protocol,
+ AvahiResolverEvent event,
+ const char *name,
+ const char *type,
+ const char *domain,
+ const char *host_name,
+ const AvahiAddress *address,
+ uint16_t port,
+ AvahiStringList *txt,
+ AvahiLookupResultFlags flags,
+ void* userdata)
+{
+ struct mdns_entry *e = userdata;
+ char a[AVAHI_ADDRESS_STR_MAX];
+
+ switch (event) {
+ case AVAHI_RESOLVER_FOUND:
+ avahi_address_snprint(a, sizeof(a), address);
+ e->address = strdup(a);
+ e->hostname = strdup(host_name);
+ e->port = port;
+ fprintf(stderr, "%s @ %s: %s | %s if #%d | %s:%d (%s)\n",
+ e->type, e->domain, e->name,
+ avahi_proto_to_string(e->protocol), e->interface,
+ e->address, e->port, e->hostname);
+ break;
+ default:
+ fprintf(stderr, "%s: %s (#%d)\n", __FUNCTION__,
+ revents[event], event);
+ break;
+ }
+ avahi_service_resolver_free(r);
+}
+
+static void browse_callback(AvahiServiceBrowser *b,
+ AvahiIfIndex interface,
+ AvahiProtocol protocol,
+ AvahiBrowserEvent event,
+ const char *name,
+ const char *type,
+ const char *domain,
+ AvahiLookupResultFlags flags,
+ void* userdata)
+{
+ AvahiClient *c = userdata;
+ struct mdns_entry *e;
+
+ switch (event) {
+ case AVAHI_BROWSER_NEW:
+ e = malloc(sizeof(*e));
+ memset(e,0,sizeof(*e));
+ e->name = strdup(name);
+ e->type = strdup(type);
+ e->domain = strdup(domain);
+ e->interface = interface;
+ e->protocol = protocol;
+ list_add_tail(&e->next, &mdns_entries);
+ avahi_service_resolver_new(c, interface, protocol, name, type, domain,
+ AVAHI_PROTO_UNSPEC, 0, resolve_callback, e);
+ break;
+ case AVAHI_BROWSER_REMOVE:
+ fprintf(stderr, "%s: DEL: service '%s' of type '%s' in domain '%s'\n",
+ __FUNCTION__, name, type, domain);
+ break;
+ default:
+ fprintf(stderr, "%s: %s (#%d)\n", __FUNCTION__,
+ bevents[event], event);
+ break;
+ }
+}
+
+static void
+client_callback(AvahiClient *client, AvahiClientState state, void *userdata)
+{
+ switch (state) {
+ case AVAHI_CLIENT_FAILURE:
+ fprintf(stderr, "%s: error: connection lost\n", __FUNCTION__);
+ break;
+ default:
+ fprintf(stderr, "%s: state %d\n", __FUNCTION__, state);
+ break;
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+void mdns_fini(void)
+{
+ if (client) {
+ avahi_client_free(client);
+ client = NULL;
+ }
+ if (glib_poll) {
+ avahi_glib_poll_free(glib_poll);
+ glib_poll = NULL;
+ }
+}
+
+int mdns_init(void)
+{
+ int error;
+
+ /* Create the GLIB Adaptor */
+ avahi_set_allocator(avahi_glib_allocator());
+ glib_poll = avahi_glib_poll_new(NULL, G_PRIORITY_DEFAULT);
+ poll_api = avahi_glib_poll_get(glib_poll);
+ client = avahi_client_new(poll_api, AVAHI_CLIENT_NO_FAIL,
+ client_callback, NULL /* user data */,
+ &error);
+ if (client == NULL)
+ goto fail;
+ return 0;
+
+fail:
+ mdns_fini();
+ return -1;
+}
+
+int mdns_browse(const char *service, const char *domain)
+{
+ AvahiServiceBrowser *sb = NULL;
+
+ if (NULL == domain)
+ domain = avahi_client_get_domain_name(client);
+ sb = avahi_service_browser_new(client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC,
+ service, domain, 0, browse_callback, client);
+ if (NULL == sb) {
+ fprintf(stderr, "%s: failed to create service browser: %s\n",
+ __FUNCTION__, avahi_strerror(avahi_client_errno(client)));
+ return -1;
+ }
+ return 0;
+}
diff --git a/mdns.h b/mdns.h
new file mode 100644
index 0000000..7729380
--- /dev/null
+++ b/mdns.h
@@ -0,0 +1,3 @@
+int mdns_init(void);
+int mdns_browse(const char *service, const char *domain);
+void mdns_fini(void);
diff --git a/xenwatch.c b/xenwatch.c
index 558256b..6f56c74 100644
--- a/xenwatch.c
+++ b/xenwatch.c
@@ -12,10 +12,11 @@
#include <gtk/gtk.h>
#include "xenviews.h"
+#include "mdns.h"
/* ------------------------------------------------------------------ */
-static Display *dpy;
+static Display *dpy;
/* ------------------------------------------------------------------ */
@@ -31,8 +32,12 @@ main(int argc, char *argv[])
xen_doms_create_window();
gtk_widget_show_all(xd_toplevel);
+ mdns_init();
+ mdns_browse("_ssh._tcp", NULL);
+
gtk_main();
+ mdns_fini();
fprintf(stderr,"bye...\n");
exit(0);
}