Created
May 9, 2009 06:22
-
-
Save gaspard/109158 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* $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); | |
group = g; | |
/* 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 with a remote service | |
* 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 *n, r[128]; | |
int ret; | |
assert(c); | |
/* If this is the first time we're called, let's create a new | |
* entry group if necessary */ | |
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; | |
} | |
/* If the group is empty (either because it was just created, or | |
* because it was reset previously, add our entries. */ | |
if (avahi_entry_group_is_empty(group)) { | |
fprintf(stderr, "Adding service '%s'\n", name); | |
/* Create some random TXT data */ | |
snprintf(r, sizeof(r), "random=%i", rand()); | |
/* We will now add two services and one subtype to the entry | |
* group. The two services have the same name, but differ in | |
* the service type (IPP vs. BSD LPR). Only services with the | |
* same name should be put in the same entry group. */ | |
/* 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) { | |
if (ret == AVAHI_ERR_COLLISION) | |
goto collision; | |
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) { | |
if (ret == AVAHI_ERR_COLLISION) | |
goto collision; | |
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; | |
collision: | |
/* A service name collision with a local service 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); | |
avahi_entry_group_reset(group); | |
create_services(c); | |
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 */ | |
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 quit_callback(AVAHI_GCC_UNUSED AvahiTimeout *e, void *userdata) { | |
fprintf(stderr, "Quit\n"); | |
avahi_simple_poll_quit(simple_poll); | |
} | |
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 10s quit. */ | |
avahi_simple_poll_get(simple_poll)->timeout_new( | |
avahi_simple_poll_get(simple_poll), | |
avahi_elapse_time(&tv, 300*10, 0), | |
quit_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; | |
} | |
/* | |
valgrind --leak-check=full --show-reachable=yes --track-origins=yes ./publish | |
==23709== Memcheck, a memory error detector. | |
==23709== Copyright (C) 2002-2008, and GNU GPL'd, by Julian Seward et al. | |
==23709== Using LibVEX rev 1884, a library for dynamic binary translation. | |
==23709== Copyright (C) 2004-2008, and GNU GPL'd, by OpenWorks LLP. | |
==23709== Using valgrind-3.4.1-Debian, a dynamic binary instrumentation framework. | |
==23709== Copyright (C) 2000-2008, and GNU GPL'd, by Julian Seward et al. | |
==23709== For more details, rerun with: -v | |
==23709== | |
Adding service 'MegaPrinter' | |
Service 'MegaPrinter' successfully established. | |
Quit | |
==23709== | |
==23709== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 23 from 1) | |
==23709== malloc/free: in use at exit: 3,064 bytes in 20 blocks. | |
==23709== malloc/free: 399 allocs, 379 frees, 18,448 bytes allocated. | |
==23709== For counts of detected errors, rerun with: -v | |
==23709== searching for pointers to 20 not-freed blocks. | |
==23709== checked 95,424 bytes. | |
==23709== | |
==23709== 812 bytes in 11 blocks are still reachable in loss record 1 of 2 | |
==23709== at 0x4026FDE: malloc (vg_replace_malloc.c:207) | |
==23709== by 0x41F0252: dbus_malloc (in /lib/libdbus-1.so.3.4.0) | |
==23709== by 0x41EE19D: (within /lib/libdbus-1.so.3.4.0) | |
==23709== by 0x41D0E24: (within /lib/libdbus-1.so.3.4.0) | |
==23709== by 0x404130F: avahi_client_new (client.c:449) | |
==23709== by 0x804936A: main (in /home/gaspard/git/rubyk/oscit/build/publish) | |
==23709== | |
==23709== | |
==23709== 2,252 bytes in 9 blocks are still reachable in loss record 2 of 2 | |
==23709== at 0x40270FC: realloc (vg_replace_malloc.c:429) | |
==23709== by 0x41F01D7: dbus_realloc (in /lib/libdbus-1.so.3.4.0) | |
==23709== by 0x41F0D7E: (within /lib/libdbus-1.so.3.4.0) | |
==23709== by 0x41F1081: (within /lib/libdbus-1.so.3.4.0) | |
==23709== by 0x41F13DF: (within /lib/libdbus-1.so.3.4.0) | |
==23709== by 0x41EF713: (within /lib/libdbus-1.so.3.4.0) | |
==23709== by 0x41EF9BF: (within /lib/libdbus-1.so.3.4.0) | |
==23709== by 0x41DB56D: (within /lib/libdbus-1.so.3.4.0) | |
==23709== by 0x41E02A8: dbus_message_iter_append_basic (in /lib/libdbus-1.so.3.4.0) | |
==23709== by 0x41E2248: dbus_message_new_error (in /lib/libdbus-1.so.3.4.0) | |
==23709== by 0x41E46FB: (within /lib/libdbus-1.so.3.4.0) | |
==23709== by 0x41D5BE7: dbus_connection_send_with_reply (in /lib/libdbus-1.so.3.4.0) | |
==23709== | |
==23709== LEAK SUMMARY: | |
==23709== definitely lost: 0 bytes in 0 blocks. | |
==23709== possibly lost: 0 bytes in 0 blocks. | |
==23709== still reachable: 3,064 bytes in 20 blocks. | |
==23709== suppressed: 0 bytes in 0 blocks. | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment