summaryrefslogtreecommitdiffstats
path: root/trunk/examples
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/examples')
-rw-r--r--trunk/examples/Makefile.am65
-rw-r--r--trunk/examples/client-browse-services.c199
-rw-r--r--trunk/examples/client-publish-service.c246
-rw-r--r--trunk/examples/core-browse-services.c215
-rw-r--r--trunk/examples/core-publish-service.c246
-rw-r--r--trunk/examples/glib-integration.c148
6 files changed, 1119 insertions, 0 deletions
diff --git a/trunk/examples/Makefile.am b/trunk/examples/Makefile.am
new file mode 100644
index 0000000..e6e66f5
--- /dev/null
+++ b/trunk/examples/Makefile.am
@@ -0,0 +1,65 @@
+# $Id$
+#
+# This file is part of avahi.
+#
+# avahi is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation; either version 2 of the
+# License, or (at your option) any later version.
+#
+# avahi is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+# License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with avahi; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+# USA.
+
+AM_CFLAGS=-I$(top_srcdir)
+
+if ENABLE_TESTS
+noinst_PROGRAMS = \
+ core-publish-service \
+ core-browse-services
+endif
+
+core_publish_service_SOURCES = core-publish-service.c
+core_publish_service_CFLAGS = $(AM_CFLAGS)
+core_publish_service_LDADD = $(AM_LDADD) ../avahi-core/libavahi-core.la ../avahi-common/libavahi-common.la
+
+core_browse_services_SOURCES = core-browse-services.c
+core_browse_services_CFLAGS = $(AM_CFLAGS)
+core_browse_services_LDADD = $(AM_LDADD) ../avahi-core/libavahi-core.la ../avahi-common/libavahi-common.la
+
+if HAVE_DBUS
+if ENABLE_TESTS
+
+noinst_PROGRAMS += \
+ client-publish-service \
+ client-browse-services
+endif
+
+client_publish_service_SOURCES = client-publish-service.c
+client_publish_service_CFLAGS = $(AM_CFLAGS)
+client_publish_service_LDADD = $(AM_LDADD) ../avahi-client/libavahi-client.la ../avahi-common/libavahi-common.la
+
+client_browse_services_SOURCES = client-browse-services.c
+client_browse_services_CFLAGS = $(AM_CFLAGS)
+client_browse_services_LDADD = $(AM_LDADD) ../avahi-client/libavahi-client.la ../avahi-common/libavahi-common.la
+
+if HAVE_GLIB
+
+if ENABLE_TESTS
+noinst_PROGRAMS += \
+ glib-integration
+endif
+
+glib_integration_SOURCES = glib-integration.c
+glib_integration_CFLAGS = $(AM_CFLAGS) $(GLIB20_CFLAGS)
+glib_integration_LDADD = $(AM_LDADD) $(GLIB20_LIBS) ../avahi-client/libavahi-client.la ../avahi-common/libavahi-common.la ../avahi-glib/libavahi-glib.la
+
+endif
+
+endif
diff --git a/trunk/examples/client-browse-services.c b/trunk/examples/client-browse-services.c
new file mode 100644
index 0000000..37550ef
--- /dev/null
+++ b/trunk/examples/client-browse-services.c
@@ -0,0 +1,199 @@
+/* $Id$ */
+
+/***
+ This file is part of avahi.
+
+ avahi is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ avahi is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
+ Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with avahi; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <time.h>
+
+#include <avahi-client/client.h>
+#include <avahi-client/lookup.h>
+
+#include <avahi-common/simple-watch.h>
+#include <avahi-common/malloc.h>
+#include <avahi-common/error.h>
+
+static AvahiSimplePoll *simple_poll = NULL;
+
+static void resolve_callback(
+ AvahiServiceResolver *r,
+ AVAHI_GCC_UNUSED AvahiIfIndex interface,
+ AVAHI_GCC_UNUSED 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,
+ AVAHI_GCC_UNUSED void* userdata) {
+
+ assert(r);
+
+ /* Called whenever a service has been resolved successfully or timed out */
+
+ switch (event) {
+ case AVAHI_RESOLVER_FAILURE:
+ fprintf(stderr, "(Resolver) Failed to resolve service '%s' of type '%s' in domain '%s': %s\n", name, type, domain, avahi_strerror(avahi_client_errno(avahi_service_resolver_get_client(r))));
+ break;
+
+ case AVAHI_RESOLVER_FOUND: {
+ char a[AVAHI_ADDRESS_STR_MAX], *t;
+
+ fprintf(stderr, "Service '%s' of type '%s' in domain '%s':\n", name, type, domain);
+
+ avahi_address_snprint(a, sizeof(a), address);
+ t = avahi_string_list_to_string(txt);
+ fprintf(stderr,
+ "\t%s:%u (%s)\n"
+ "\tTXT=%s\n"
+ "\tcookie is %u\n"
+ "\tis_local: %i\n"
+ "\tour_own: %i\n"
+ "\twide_area: %i\n"
+ "\tmulticast: %i\n"
+ "\tcached: %i\n",
+ host_name, port, a,
+ t,
+ avahi_string_list_get_service_cookie(txt),
+ !!(flags & AVAHI_LOOKUP_RESULT_LOCAL),
+ !!(flags & AVAHI_LOOKUP_RESULT_OUR_OWN),
+ !!(flags & AVAHI_LOOKUP_RESULT_WIDE_AREA),
+ !!(flags & AVAHI_LOOKUP_RESULT_MULTICAST),
+ !!(flags & AVAHI_LOOKUP_RESULT_CACHED));
+
+ avahi_free(t);
+ }
+ }
+
+ 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,
+ AVAHI_GCC_UNUSED AvahiLookupResultFlags flags,
+ void* userdata) {
+
+ AvahiClient *c = userdata;
+ assert(b);
+
+ /* Called whenever a new services becomes available on the LAN or is removed from the LAN */
+
+ switch (event) {
+ case AVAHI_BROWSER_FAILURE:
+
+ fprintf(stderr, "(Browser) %s\n", avahi_strerror(avahi_client_errno(avahi_service_browser_get_client(b))));
+ avahi_simple_poll_quit(simple_poll);
+ return;
+
+ case AVAHI_BROWSER_NEW:
+ fprintf(stderr, "(Browser) NEW: service '%s' of type '%s' in domain '%s'\n", name, type, domain);
+
+ /* We ignore the returned resolver object. In the callback
+ function we free it. If the server is terminated before
+ the callback function is called the server will free
+ the resolver for us. */
+
+ if (!(avahi_service_resolver_new(c, interface, protocol, name, type, domain, AVAHI_PROTO_UNSPEC, 0, resolve_callback, c)))
+ fprintf(stderr, "Failed to resolve service '%s': %s\n", name, avahi_strerror(avahi_client_errno(c)));
+
+ break;
+
+ case AVAHI_BROWSER_REMOVE:
+ fprintf(stderr, "(Browser) REMOVE: service '%s' of type '%s' in domain '%s'\n", name, type, domain);
+ break;
+
+ case AVAHI_BROWSER_ALL_FOR_NOW:
+ case AVAHI_BROWSER_CACHE_EXHAUSTED:
+ fprintf(stderr, "(Browser) %s\n", event == AVAHI_BROWSER_CACHE_EXHAUSTED ? "CACHE_EXHAUSTED" : "ALL_FOR_NOW");
+ break;
+ }
+}
+
+static void client_callback(AvahiClient *c, AvahiClientState state, AVAHI_GCC_UNUSED void * userdata) {
+ assert(c);
+
+ /* Called whenever the client or server state changes */
+
+ if (state == AVAHI_CLIENT_FAILURE) {
+ fprintf(stderr, "Server connection failre: %s\n", avahi_strerror(avahi_client_errno(c)));
+ avahi_simple_poll_quit(simple_poll);
+ }
+}
+
+int main(AVAHI_GCC_UNUSED int argc, AVAHI_GCC_UNUSED char*argv[]) {
+ AvahiClient *client = NULL;
+ AvahiServiceBrowser *sb = NULL;
+ int error;
+ int ret = 1;
+
+ /* Allocate main loop object */
+ if (!(simple_poll = avahi_simple_poll_new())) {
+ fprintf(stderr, "Failed to create simple poll object.\n");
+ goto fail;
+ }
+
+ /* Allocate a new client */
+ client = avahi_client_new(avahi_simple_poll_get(simple_poll), 0, client_callback, NULL, &error);
+
+ /* Check wether creating the client object succeeded */
+ if (!client) {
+ fprintf(stderr, "Failed to create client: %s\n", avahi_strerror(error));
+ goto fail;
+ }
+
+ /* Create the service browser */
+ if (!(sb = avahi_service_browser_new(client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "_http._tcp", NULL, 0, browse_callback, client))) {
+ fprintf(stderr, "Failed to create service browser: %s\n", avahi_strerror(avahi_client_errno(client)));
+ goto fail;
+ }
+
+ /* Run the main loop */
+ avahi_simple_poll_loop(simple_poll);
+
+ ret = 0;
+
+fail:
+
+ /* Cleanup things */
+ if (sb)
+ avahi_service_browser_free(sb);
+
+ if (client)
+ avahi_client_free(client);
+
+ if (simple_poll)
+ avahi_simple_poll_free(simple_poll);
+
+ return ret;
+}
diff --git a/trunk/examples/client-publish-service.c b/trunk/examples/client-publish-service.c
new file mode 100644
index 0000000..94dcd1e
--- /dev/null
+++ b/trunk/examples/client-publish-service.c
@@ -0,0 +1,246 @@
+/* $Id$ */
+
+/***
+ This file is part of avahi.
+
+ avahi is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ avahi is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
+ Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with avahi; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <time.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#include <avahi-client/client.h>
+#include <avahi-client/publish.h>
+
+#include <avahi-common/alternative.h>
+#include <avahi-common/simple-watch.h>
+#include <avahi-common/malloc.h>
+#include <avahi-common/error.h>
+#include <avahi-common/timeval.h>
+
+static AvahiEntryGroup *group = NULL;
+static AvahiSimplePoll *simple_poll = NULL;
+static char *name = NULL;
+
+static void create_services(AvahiClient *c);
+
+static void entry_group_callback(AvahiEntryGroup *g, AvahiEntryGroupState state, AVAHI_GCC_UNUSED void *userdata) {
+ assert(g == group || group == NULL);
+
+ /* Called whenever the entry group state changes */
+
+ switch (state) {
+ case AVAHI_ENTRY_GROUP_ESTABLISHED :
+ /* The entry group has been established successfully */
+ fprintf(stderr, "Service '%s' successfully established.\n", name);
+ break;
+
+ case AVAHI_ENTRY_GROUP_COLLISION : {
+ char *n;
+
+ /* A service name collision happened. Let's pick a new name */
+ n = avahi_alternative_service_name(name);
+ avahi_free(name);
+ name = n;
+
+ fprintf(stderr, "Service name collision, renaming service to '%s'\n", name);
+
+ /* And recreate the services */
+ create_services(avahi_entry_group_get_client(g));
+ break;
+ }
+
+ case AVAHI_ENTRY_GROUP_FAILURE :
+
+ fprintf(stderr, "Entry group failure: %s\n", avahi_strerror(avahi_client_errno(avahi_entry_group_get_client(g))));
+
+ /* Some kind of failure happened while we were registering our services */
+ avahi_simple_poll_quit(simple_poll);
+ break;
+
+ case AVAHI_ENTRY_GROUP_UNCOMMITED:
+ case AVAHI_ENTRY_GROUP_REGISTERING:
+ ;
+ }
+}
+
+static void create_services(AvahiClient *c) {
+ char r[128];
+ int ret;
+ assert(c);
+
+ /* If this is the first time we're called, let's create a new entry group */
+ if (!group)
+ if (!(group = avahi_entry_group_new(c, entry_group_callback, NULL))) {
+ fprintf(stderr, "avahi_entry_group_new() failed: %s\n", avahi_strerror(avahi_client_errno(c)));
+ goto fail;
+ }
+
+ fprintf(stderr, "Adding service '%s'\n", name);
+
+ /* Create some random TXT data */
+ snprintf(r, sizeof(r), "random=%i", rand());
+
+ /* Add the service for IPP */
+ if ((ret = avahi_entry_group_add_service(group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, name, "_ipp._tcp", NULL, NULL, 651, "test=blah", r, NULL)) < 0) {
+ fprintf(stderr, "Failed to add _ipp._tcp service: %s\n", avahi_strerror(ret));
+ goto fail;
+ }
+
+ /* Add the same service for BSD LPR */
+ if ((ret = avahi_entry_group_add_service(group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, name, "_printer._tcp", NULL, NULL, 515, NULL)) < 0) {
+ fprintf(stderr, "Failed to add _printer._tcp service: %s\n", avahi_strerror(ret));
+ goto fail;
+ }
+
+ /* Add an additional (hypothetic) subtype */
+ if ((ret = avahi_entry_group_add_service_subtype(group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, name, "_printer._tcp", NULL, "_magic._sub._printer._tcp") < 0)) {
+ fprintf(stderr, "Failed to add subtype _magic._sub._printer._tcp: %s\n", avahi_strerror(ret));
+ goto fail;
+ }
+
+ /* Tell the server to register the service */
+ if ((ret = avahi_entry_group_commit(group)) < 0) {
+ fprintf(stderr, "Failed to commit entry_group: %s\n", avahi_strerror(ret));
+ goto fail;
+ }
+
+ return;
+
+fail:
+ avahi_simple_poll_quit(simple_poll);
+}
+
+static void client_callback(AvahiClient *c, AvahiClientState state, AVAHI_GCC_UNUSED void * userdata) {
+ assert(c);
+
+ /* Called whenever the client or server state changes */
+
+ switch (state) {
+ case AVAHI_CLIENT_S_RUNNING:
+
+ /* The server has startup successfully and registered its host
+ * name on the network, so it's time to create our services */
+ if (!group)
+ create_services(c);
+ break;
+
+ case AVAHI_CLIENT_FAILURE:
+
+ fprintf(stderr, "Client failure: %s\n", avahi_strerror(avahi_client_errno(c)));
+ avahi_simple_poll_quit(simple_poll);
+
+ break;
+
+ case AVAHI_CLIENT_S_COLLISION:
+
+ /* Let's drop our registered services. When the server is back
+ * in AVAHI_SERVER_RUNNING state we will register them
+ * again with the new host name. */
+
+ case AVAHI_CLIENT_S_REGISTERING:
+
+ /* The server records are now being established. This
+ * might be caused by a host name change. We need to wait
+ * for our own records to register until the host name is
+ * properly esatblished. */
+
+ if (group)
+ avahi_entry_group_reset(group);
+
+ break;
+
+ case AVAHI_CLIENT_CONNECTING:
+ ;
+ }
+}
+
+static void modify_callback(AVAHI_GCC_UNUSED AvahiTimeout *e, void *userdata) {
+ AvahiClient *client = userdata;
+
+ fprintf(stderr, "Doing some weird modification\n");
+
+ avahi_free(name);
+ name = avahi_strdup("Modified MegaPrinter");
+
+ /* If the server is currently running, we need to remove our
+ * service and create it anew */
+ if (avahi_client_get_state(client) == AVAHI_CLIENT_S_RUNNING) {
+
+ /* Remove the old services */
+ if (group)
+ avahi_entry_group_reset(group);
+
+ /* And create them again with the new name */
+ create_services(client);
+ }
+}
+
+int main(AVAHI_GCC_UNUSED int argc, AVAHI_GCC_UNUSED char*argv[]) {
+ AvahiClient *client = NULL;
+ int error;
+ int ret = 1;
+ struct timeval tv;
+
+ /* Allocate main loop object */
+ if (!(simple_poll = avahi_simple_poll_new())) {
+ fprintf(stderr, "Failed to create simple poll object.\n");
+ goto fail;
+ }
+
+ name = avahi_strdup("MegaPrinter");
+
+ /* Allocate a new client */
+ client = avahi_client_new(avahi_simple_poll_get(simple_poll), 0, client_callback, NULL, &error);
+
+ /* Check wether creating the client object succeeded */
+ if (!client) {
+ fprintf(stderr, "Failed to create client: %s\n", avahi_strerror(error));
+ goto fail;
+ }
+
+ /* After 20s do some weird modification to the service */
+ avahi_simple_poll_get(simple_poll)->timeout_new(
+ avahi_simple_poll_get(simple_poll),
+ avahi_elapse_time(&tv, 1000*10, 0),
+ modify_callback,
+ client);
+
+ /* Run the main loop */
+ avahi_simple_poll_loop(simple_poll);
+
+ ret = 0;
+
+fail:
+
+ /* Cleanup things */
+
+ if (client)
+ avahi_client_free(client);
+
+ if (simple_poll)
+ avahi_simple_poll_free(simple_poll);
+
+ avahi_free(name);
+
+ return ret;
+}
diff --git a/trunk/examples/core-browse-services.c b/trunk/examples/core-browse-services.c
new file mode 100644
index 0000000..53b18ee
--- /dev/null
+++ b/trunk/examples/core-browse-services.c
@@ -0,0 +1,215 @@
+/* $Id$ */
+
+/* PLEASE NOTE *
+ * This file demonstrates how to use Avahi's core API, this is
+ * the embeddable mDNS stack for embedded applications.
+ *
+ * End user applications should *not* use this API and should use
+ * the D-Bus or C APIs, please see
+ * client-browse-services.c and glib-integration.c
+ *
+ * I repeat, you probably do *not* want to use this example.
+ */
+
+/***
+ This file is part of avahi.
+
+ avahi is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ avahi is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
+ Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with avahi; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <time.h>
+
+#include <avahi-core/core.h>
+#include <avahi-core/lookup.h>
+#include <avahi-common/simple-watch.h>
+#include <avahi-common/malloc.h>
+#include <avahi-common/error.h>
+
+static AvahiSimplePoll *simple_poll = NULL;
+static AvahiServer *server = NULL;
+
+static void resolve_callback(
+ AvahiSServiceResolver *r,
+ AVAHI_GCC_UNUSED AvahiIfIndex interface,
+ AVAHI_GCC_UNUSED 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,
+ AVAHI_GCC_UNUSED void* userdata) {
+
+ assert(r);
+
+ /* Called whenever a service has been resolved successfully or timed out */
+
+ switch (event) {
+ case AVAHI_RESOLVER_FAILURE:
+ fprintf(stderr, "(Resolver) Failed to resolve service '%s' of type '%s' in domain '%s': %s\n", name, type, domain, avahi_strerror(avahi_server_errno(server)));
+ break;
+
+ case AVAHI_RESOLVER_FOUND: {
+ char a[AVAHI_ADDRESS_STR_MAX], *t;
+
+ fprintf(stderr, "(Resolver) Service '%s' of type '%s' in domain '%s':\n", name, type, domain);
+
+ avahi_address_snprint(a, sizeof(a), address);
+ t = avahi_string_list_to_string(txt);
+ fprintf(stderr,
+ "\t%s:%u (%s)\n"
+ "\tTXT=%s\n"
+ "\tcookie is %u\n"
+ "\tis_local: %i\n"
+ "\twide_area: %i\n"
+ "\tmulticast: %i\n"
+ "\tcached: %i\n",
+ host_name, port, a,
+ t,
+ avahi_string_list_get_service_cookie(txt),
+ !!(flags & AVAHI_LOOKUP_RESULT_LOCAL),
+ !!(flags & AVAHI_LOOKUP_RESULT_WIDE_AREA),
+ !!(flags & AVAHI_LOOKUP_RESULT_MULTICAST),
+ !!(flags & AVAHI_LOOKUP_RESULT_CACHED));
+ avahi_free(t);
+ }
+ }
+
+ avahi_s_service_resolver_free(r);
+}
+
+static void browse_callback(
+ AvahiSServiceBrowser *b,
+ AvahiIfIndex interface,
+ AvahiProtocol protocol,
+ AvahiBrowserEvent event,
+ const char *name,
+ const char *type,
+ const char *domain,
+ AVAHI_GCC_UNUSED AvahiLookupResultFlags flags,
+ void* userdata) {
+
+ AvahiServer *s = userdata;
+ assert(b);
+
+ /* Called whenever a new services becomes available on the LAN or is removed from the LAN */
+
+ switch (event) {
+
+ case AVAHI_BROWSER_FAILURE:
+
+ fprintf(stderr, "(Browser) %s\n", avahi_strerror(avahi_server_errno(server)));
+ avahi_simple_poll_quit(simple_poll);
+ return;
+
+ case AVAHI_BROWSER_NEW:
+ fprintf(stderr, "(Browser) NEW: service '%s' of type '%s' in domain '%s'\n", name, type, domain);
+
+ /* We ignore the returned resolver object. In the callback
+ function we free it. If the server is terminated before
+ the callback function is called the server will free
+ the resolver for us. */
+
+ if (!(avahi_s_service_resolver_new(s, interface, protocol, name, type, domain, AVAHI_PROTO_UNSPEC, 0, resolve_callback, s)))
+ fprintf(stderr, "Failed to resolve service '%s': %s\n", name, avahi_strerror(avahi_server_errno(s)));
+
+ break;
+
+ case AVAHI_BROWSER_REMOVE:
+ fprintf(stderr, "(Browser) REMOVE: service '%s' of type '%s' in domain '%s'\n", name, type, domain);
+ break;
+
+ case AVAHI_BROWSER_ALL_FOR_NOW:
+ case AVAHI_BROWSER_CACHE_EXHAUSTED:
+ fprintf(stderr, "(Browser) %s\n", event == AVAHI_BROWSER_CACHE_EXHAUSTED ? "CACHE_EXHAUSTED" : "ALL_FOR_NOW");
+ break;
+ }
+}
+
+int main(AVAHI_GCC_UNUSED int argc, AVAHI_GCC_UNUSED char*argv[]) {
+ AvahiServerConfig config;
+ AvahiSServiceBrowser *sb = NULL;
+ int error;
+ int ret = 1;
+
+ /* Initialize the psuedo-RNG */
+ srand(time(NULL));
+
+ /* Allocate main loop object */
+ if (!(simple_poll = avahi_simple_poll_new())) {
+ fprintf(stderr, "Failed to create simple poll object.\n");
+ goto fail;
+ }
+
+ /* Do not publish any local records */
+ avahi_server_config_init(&config);
+ config.publish_hinfo = 0;
+ config.publish_addresses = 0;
+ config.publish_workstation = 0;
+ config.publish_domain = 0;
+
+ /* Set a unicast DNS server for wide area DNS-SD */
+ avahi_address_parse("192.168.50.1", AVAHI_PROTO_UNSPEC, &config.wide_area_servers[0]);
+ config.n_wide_area_servers = 1;
+ config.enable_wide_area = 1;
+
+ /* Allocate a new server */
+ server = avahi_server_new(avahi_simple_poll_get(simple_poll), &config, NULL, NULL, &error);
+
+ /* Free the configuration data */
+ avahi_server_config_free(&config);
+
+ /* Check wether creating the server object succeeded */
+ if (!server) {
+ fprintf(stderr, "Failed to create server: %s\n", avahi_strerror(error));
+ goto fail;
+ }
+
+ /* Create the service browser */
+ if (!(sb = avahi_s_service_browser_new(server, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "_http._tcp", NULL, 0, browse_callback, server))) {
+ fprintf(stderr, "Failed to create service browser: %s\n", avahi_strerror(avahi_server_errno(server)));
+ goto fail;
+ }
+
+ /* Run the main loop */
+ avahi_simple_poll_loop(simple_poll);
+
+ ret = 0;
+
+fail:
+
+ /* Cleanup things */
+ if (sb)
+ avahi_s_service_browser_free(sb);
+
+ if (server)
+ avahi_server_free(server);
+
+ if (simple_poll)
+ avahi_simple_poll_free(simple_poll);
+
+ return ret;
+}
diff --git a/trunk/examples/core-publish-service.c b/trunk/examples/core-publish-service.c
new file mode 100644
index 0000000..6370383
--- /dev/null
+++ b/trunk/examples/core-publish-service.c
@@ -0,0 +1,246 @@
+/* $Id$ */
+
+/***
+ This file is part of avahi.
+
+ avahi is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ avahi is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
+ Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with avahi; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <time.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#include <avahi-core/core.h>
+#include <avahi-core/publish.h>
+#include <avahi-common/simple-watch.h>
+#include <avahi-common/malloc.h>
+#include <avahi-common/alternative.h>
+#include <avahi-common/error.h>
+
+static AvahiSEntryGroup *group = NULL;
+static AvahiSimplePoll *simple_poll = NULL;
+static char *name = NULL;
+
+static void create_services(AvahiServer *s);
+
+static void entry_group_callback(AvahiServer *s, AvahiSEntryGroup *g, AvahiEntryGroupState state, AVAHI_GCC_UNUSED void *userdata) {
+ assert(s);
+ assert(g == group);
+
+ /* Called whenever the entry group state changes */
+
+ switch (state) {
+
+ case AVAHI_ENTRY_GROUP_ESTABLISHED:
+
+ /* The entry group has been established successfully */
+ fprintf(stderr, "Service '%s' successfully established.\n", name);
+ break;
+
+ case AVAHI_ENTRY_GROUP_COLLISION: {
+ char *n;
+
+ /* A service name collision happened. Let's pick a new name */
+ n = avahi_alternative_service_name(name);
+ avahi_free(name);
+ name = n;
+
+ fprintf(stderr, "Service name collision, renaming service to '%s'\n", name);
+
+ /* And recreate the services */
+ create_services(s);
+ break;
+ }
+
+ case AVAHI_ENTRY_GROUP_FAILURE :
+
+ fprintf(stderr, "Entry group failure: %s\n", avahi_strerror(avahi_server_errno(s)));
+
+ /* Some kind of failure happened while we were registering our services */
+ avahi_simple_poll_quit(simple_poll);
+ break;
+
+ case AVAHI_ENTRY_GROUP_UNCOMMITED:
+ case AVAHI_ENTRY_GROUP_REGISTERING:
+ ;
+ }
+}
+
+static void create_services(AvahiServer *s) {
+ char r[128];
+ int ret;
+ assert(s);
+
+ /* If this is the first time we're called, let's create a new entry group */
+ if (!group)
+ if (!(group = avahi_s_entry_group_new(s, entry_group_callback, NULL))) {
+ fprintf(stderr, "avahi_entry_group_new() failed: %s\n", avahi_strerror(avahi_server_errno(s)));
+ goto fail;
+ }
+
+ fprintf(stderr, "Adding service '%s'\n", name);
+
+ /* Create some random TXT data */
+ snprintf(r, sizeof(r), "random=%i", rand());
+
+ /* Add the service for IPP */
+ if ((ret = avahi_server_add_service(s, group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, name, "_ipp._tcp", NULL, NULL, 651, "test=blah", r, NULL)) < 0) {
+ fprintf(stderr, "Failed to add _ipp._tcp service: %s\n", avahi_strerror(ret));
+ goto fail;
+ }
+
+ /* Add the same service for BSD LPR */
+ if ((ret = avahi_server_add_service(s, group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, name, "_printer._tcp", NULL, NULL, 515, NULL)) < 0) {
+ fprintf(stderr, "Failed to add _printer._tcp service: %s\n", avahi_strerror(ret));
+ goto fail;
+ }
+
+ /* Add an additional (hypothetic) subtype */
+ if ((ret = avahi_server_add_service_subtype(s, group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, name, "_printer._tcp", NULL, "_magic._sub._printer._tcp") < 0)) {
+ fprintf(stderr, "Failed to add subtype _magic._sub._printer._tcp: %s\n", avahi_strerror(ret));
+ goto fail;
+ }
+
+ /* Tell the server to register the service */
+ if ((ret = avahi_s_entry_group_commit(group)) < 0) {
+ fprintf(stderr, "Failed to commit entry_group: %s\n", avahi_strerror(ret));
+ goto fail;
+ }
+
+ return;
+
+fail:
+ avahi_simple_poll_quit(simple_poll);
+}
+
+static void server_callback(AvahiServer *s, AvahiServerState state, AVAHI_GCC_UNUSED void * userdata) {
+ assert(s);
+
+ /* Called whenever the server state changes */
+
+ switch (state) {
+
+ case AVAHI_SERVER_RUNNING:
+ /* The serve has startup successfully and registered its host
+ * name on the network, so it's time to create our services */
+
+ if (!group)
+ create_services(s);
+
+ break;
+
+ case AVAHI_SERVER_COLLISION: {
+ char *n;
+ int r;
+
+ /* A host name collision happened. Let's pick a new name for the server */
+ n = avahi_alternative_host_name(avahi_server_get_host_name(s));
+ fprintf(stderr, "Host name collision, retrying with '%s'\n", n);
+ r = avahi_server_set_host_name(s, n);
+ avahi_free(n);
+
+ if (r < 0) {
+ fprintf(stderr, "Failed to set new host name: %s\n", avahi_strerror(r));
+
+ avahi_simple_poll_quit(simple_poll);
+ return;
+ }
+
+ }
+
+ /* Fall through */
+
+ case AVAHI_SERVER_REGISTERING:
+
+ /* Let's drop our registered services. When the server is back
+ * in AVAHI_SERVER_RUNNING state we will register them
+ * again with the new host name. */
+ if (group)
+ avahi_s_entry_group_reset(group);
+
+ break;
+
+ case AVAHI_SERVER_FAILURE:
+
+ /* Terminate on failure */
+
+ fprintf(stderr, "Server failure: %s\n", avahi_strerror(avahi_server_errno(s)));
+ avahi_simple_poll_quit(simple_poll);
+ break;
+
+ case AVAHI_SERVER_INVALID:
+ ;
+ }
+}
+
+int main(AVAHI_GCC_UNUSED int argc, AVAHI_GCC_UNUSED char*argv[]) {
+ AvahiServerConfig config;
+ AvahiServer *server = NULL;
+ int error;
+ int ret = 1;
+
+ /* Initialize the pseudo-RNG */
+ srand(time(NULL));
+
+ /* Allocate main loop object */
+ if (!(simple_poll = avahi_simple_poll_new())) {
+ fprintf(stderr, "Failed to create simple poll object.\n");
+ goto fail;
+ }
+
+ name = avahi_strdup("MegaPrinter");
+
+ /* Let's set the host name for this server. */
+ avahi_server_config_init(&config);
+ config.host_name = avahi_strdup("gurkiman");
+ config.publish_workstation = 0;
+
+ /* Allocate a new server */
+ server = avahi_server_new(avahi_simple_poll_get(simple_poll), &config, server_callback, NULL, &error);
+
+ /* Free the configuration data */
+ avahi_server_config_free(&config);
+
+ /* Check wether creating the server object succeeded */
+ if (!server) {
+ fprintf(stderr, "Failed to create server: %s\n", avahi_strerror(error));
+ goto fail;
+ }
+
+ /* Run the main loop */
+ avahi_simple_poll_loop(simple_poll);
+
+ ret = 0;
+
+fail:
+
+ /* Cleanup things */
+
+ if (server)
+ avahi_server_free(server);
+
+ if (simple_poll)
+ avahi_simple_poll_free(simple_poll);
+
+ avahi_free(name);
+
+ return ret;
+}
diff --git a/trunk/examples/glib-integration.c b/trunk/examples/glib-integration.c
new file mode 100644
index 0000000..ab53687
--- /dev/null
+++ b/trunk/examples/glib-integration.c
@@ -0,0 +1,148 @@
+/* $Id$ */
+
+/***
+ This file is part of avahi.
+
+ avahi is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ avahi is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
+ Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with avahi; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib.h>
+
+#include <avahi-client/client.h>
+#include <avahi-common/error.h>
+#include <avahi-common/timeval.h>
+#include <avahi-glib/glib-watch.h>
+#include <avahi-glib/glib-malloc.h>
+
+/* Callback for Avahi API Timeout Event */
+static void
+avahi_timeout_event (AVAHI_GCC_UNUSED AvahiTimeout *timeout, AVAHI_GCC_UNUSED void *userdata)
+{
+ g_message ("Avahi API Timeout reached!");
+}
+
+/* Callback for GLIB API Timeout Event */
+static gboolean
+avahi_timeout_event_glib (void *userdata)
+{
+ GMainLoop *loop = userdata;
+
+ g_message ("GLIB API Timeout reached, quitting main loop!");
+
+ /* Quit the application */
+ g_main_loop_quit (loop);
+
+ return FALSE; /* Don't re-schedule timeout event */
+}
+
+/* Callback for state changes on the Client */
+static void
+avahi_client_callback (AVAHI_GCC_UNUSED AvahiClient *client, AvahiClientState state, void *userdata)
+{
+ GMainLoop *loop = userdata;
+
+ g_message ("Avahi Client State Change: %d", state);
+
+ if (state == AVAHI_CLIENT_FAILURE)
+ {
+ /* We we're disconnected from the Daemon */
+ g_message ("Disconnected from the Avahi Daemon: %s", avahi_strerror(avahi_client_errno(client)));
+
+ /* Quit the application */
+ g_main_loop_quit (loop);
+ }
+}
+
+int
+main (AVAHI_GCC_UNUSED int argc, AVAHI_GCC_UNUSED char *argv[])
+{
+ GMainLoop *loop = NULL;
+ const AvahiPoll *poll_api;
+ AvahiGLibPoll *glib_poll;
+ AvahiClient *client;
+ struct timeval tv;
+ const char *version;
+ int error;
+
+ /* Optional: Tell avahi to use g_malloc and g_free */
+ avahi_set_allocator (avahi_glib_allocator ());
+
+ /* Create the GLIB main loop */
+ loop = g_main_loop_new (NULL, FALSE);
+
+ /* Create the GLIB Adaptor */
+ glib_poll = avahi_glib_poll_new (NULL, G_PRIORITY_DEFAULT);
+ poll_api = avahi_glib_poll_get (glib_poll);
+
+ /* Example, schedule a timeout event with the Avahi API */
+ avahi_elapse_time (&tv, /* timeval structure */
+ 1000, /* 1 second */
+ 0); /* "jitter" - Random additional delay from 0 to this value */
+
+ poll_api->timeout_new (poll_api, /* The AvahiPoll object */
+ &tv, /* struct timeval indicating when to go activate */
+ avahi_timeout_event, /* Pointer to function to call */
+ NULL); /* User data to pass to function */
+
+ /* Schedule a timeout event with the glib api */
+ g_timeout_add (5000, /* 5 seconds */
+ avahi_timeout_event_glib, /* Pointer to function callback */
+ loop); /* User data to pass to function */
+
+ /* Create a new AvahiClient instance */
+ client = avahi_client_new (poll_api, /* AvahiPoll object from above */
+ 0,
+ avahi_client_callback, /* Callback function for Client state changes */
+ loop, /* User data */
+ &error); /* Error return */
+
+ /* Check the error return code */
+ if (client == NULL)
+ {
+ /* Print out the error string */
+ g_warning ("Error initializing Avahi: %s", avahi_strerror (error));
+
+ goto fail;
+ }
+
+ /* Make a call to get the version string from the daemon */
+ version = avahi_client_get_version_string (client);
+
+ /* Check if the call suceeded */
+ if (version == NULL)
+ {
+ g_warning ("Error getting version string: %s", avahi_strerror (avahi_client_errno (client)));
+
+ goto fail;
+ }
+
+ g_message ("Avahi Server Version: %s", version);
+
+ /* Start the GLIB Main Loop */
+ g_main_loop_run (loop);
+
+fail:
+ /* Clean up */
+ g_main_loop_unref (loop);
+ avahi_client_free (client);
+ avahi_glib_poll_free (glib_poll);
+
+ return 0;
+}