diff options
Diffstat (limited to 'trunk/examples')
-rw-r--r-- | trunk/examples/Makefile.am | 65 | ||||
-rw-r--r-- | trunk/examples/client-browse-services.c | 199 | ||||
-rw-r--r-- | trunk/examples/client-publish-service.c | 246 | ||||
-rw-r--r-- | trunk/examples/core-browse-services.c | 215 | ||||
-rw-r--r-- | trunk/examples/core-publish-service.c | 246 | ||||
-rw-r--r-- | trunk/examples/glib-integration.c | 148 |
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; +} |