From: Lennart Poettering Date: Fri, 20 May 2005 14:54:00 +0000 (+0000) Subject: Add support for server state change callbacks X-Git-Url: https://git.meshlink.io/?a=commitdiff_plain;h=4de3df3db7df43474176533d0b5fac851dd4a9b4;p=catta Add support for server state change callbacks git-svn-id: file:///home/lennart/svn/public/avahi/trunk@78 941a03a8-eaeb-0310-b9a0-b1bbd8fe43fe --- diff --git a/avahi-core/Makefile.am b/avahi-core/Makefile.am index 7554d24..de82b0a 100644 --- a/avahi-core/Makefile.am +++ b/avahi-core/Makefile.am @@ -56,7 +56,8 @@ libavahi_core_la_SOURCES = \ announce.c announce.h \ subscribe.c subscribe.h \ strlst.c strlst.h \ - rrlist.c rrlist.h + rrlist.c rrlist.h \ + alternative.c alternative.h prioq_test_SOURCES = \ prioq-test.c \ @@ -93,7 +94,7 @@ avahi_test_LDADD = $(AM_LDADD) alternative_test_SOURCES = \ alternative-test.c \ - util.c util.h + alternative.c alternative.h alternative_test_CFLAGS = $(AM_CFLAGS) alternative_test_LDADD = $(AM_LDADD) diff --git a/avahi-core/alternative-test.c b/avahi-core/alternative-test.c index 18bc698..9e26d24 100644 --- a/avahi-core/alternative-test.c +++ b/avahi-core/alternative-test.c @@ -25,7 +25,7 @@ #include -#include "util.h" +#include "alternative.h" int main(int argc, char *argv[]) { gchar *r = NULL; diff --git a/avahi-core/alternative.c b/avahi-core/alternative.c new file mode 100644 index 0000000..c9a0f48 --- /dev/null +++ b/avahi-core/alternative.c @@ -0,0 +1,81 @@ +/* $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 +#endif + +#include +#include +#include + +#include "alternative.h" + +gchar * avahi_alternative_host_name(const gchar *s) { + const gchar *p, *e = NULL; + gchar *c, *r; + gint n; + + g_assert(s); + + for (p = s; *p; p++) + if (!isdigit(*p)) + e = p+1; + + if (e && *e) + n = atoi(e)+1; + else + n = 2; + + c = e ? g_strndup(s, e-s) : g_strdup(s); + r = g_strdup_printf("%s%i", c, n); + g_free(c); + + return r; + +} + +gchar *avahi_alternative_service_name(const gchar *s) { + const gchar *e; + g_assert(s); + + if ((e = strstr(s, " #"))) { + const gchar *n, *p; + e += 2; + + while ((n = strstr(e, " #"))) + e = n + 2; + + for (p = e; *p; p++) + if (!isdigit(*p)) { + e = NULL; + break; + } + } + + if (e) { + gchar *r, *c = g_strndup(s, e-s); + r = g_strdup_printf("%s%i", c, atoi(e)+1); + g_free(c); + return r; + } else + return g_strdup_printf("%s #2", s); +} diff --git a/avahi-core/alternative.h b/avahi-core/alternative.h new file mode 100644 index 0000000..3aed5b2 --- /dev/null +++ b/avahi-core/alternative.h @@ -0,0 +1,39 @@ +#ifndef fooalternativehfoo +#define fooalternativehfoo + +/* $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. +***/ + +#include + +/** Find an alternative for the specified host name. If called with an + * original host name, "2" is appended, Afterwards the number is + * increased on each call. (i.e. "foo" becomes "foo2" becomes "foo3" + * and so on.)*/ +gchar *avahi_alternative_host_name(const gchar *s); + +/** Find an alternative for the specified service name. If called with + an original service name, " #2" is appended. Afterwards the number + is increased on each call (i.e. "foo" becomes "foo #2" becomes + "foo #3" and so on.)*/ +gchar *avahi_alternative_service_name(const gchar *s); + +#endif diff --git a/avahi-core/announce.c b/avahi-core/announce.c index ddcfd39..75766a9 100644 --- a/avahi-core/announce.c +++ b/avahi-core/announce.c @@ -122,8 +122,8 @@ static void next_state(AvahiAnnouncement *a) { gchar *t; - g_message("Enough probes for record [%s]", t = avahi_record_to_string(a->entry->record)); - g_free(t); +/* g_message("Enough probes for record [%s]", t = avahi_record_to_string(a->entry->record)); */ +/* g_free(t); */ if (a->entry->group) { g_assert(a->entry->group->n_probing); @@ -161,11 +161,11 @@ static void next_state(AvahiAnnouncement *a) { avahi_server_generate_response(a->server, a->interface, NULL, NULL, 0, FALSE); if (++a->n_iteration >= 4) { - gchar *t; +/* gchar *t; */ /* Announcing done */ - g_message("Enough announcements for record [%s]", t = avahi_record_to_string(a->entry->record)); - g_free(t); +/* g_message("Enough announcements for record [%s]", t = avahi_record_to_string(a->entry->record)); */ +/* g_free(t); */ a->state = AVAHI_ESTABLISHED; @@ -239,7 +239,7 @@ static void go_to_initial_state(AvahiAnnouncement *a, gboolean immediately) { static void new_announcement(AvahiServer *s, AvahiInterface *i, AvahiEntry *e) { AvahiAnnouncement *a; - gchar *t; +/* gchar *t; */ g_assert(s); g_assert(i); @@ -254,7 +254,7 @@ static void new_announcement(AvahiServer *s, AvahiInterface *i, AvahiEntry *e) { /* We don't want duplicate announcements */ if (avahi_get_announcement(s, e, i)) - return; + return; a = g_new(AvahiAnnouncement, 1); a->server = s; @@ -267,8 +267,8 @@ static void new_announcement(AvahiServer *s, AvahiInterface *i, AvahiEntry *e) { go_to_initial_state(a, FALSE); - g_message("New announcement on interface %s.%i for entry [%s] state=%i", i->hardware->name, i->protocol, t = avahi_record_to_string(e->record), a->state); - g_free(t); +/* g_message("New announcement on interface %s.%i for entry [%s] state=%i", i->hardware->name, i->protocol, t = avahi_record_to_string(e->record), a->state); */ +/* g_free(t); */ } void avahi_announce_interface(AvahiServer *s, AvahiInterface *i) { diff --git a/avahi-core/avahi-test.c b/avahi-core/avahi-test.c index f3ed3cc..a090a12 100644 --- a/avahi-core/avahi-test.c +++ b/avahi-core/avahi-test.c @@ -29,6 +29,11 @@ #include #include "core.h" +#include "alternative.h" + +static AvahiEntryGroup *group = NULL; +static AvahiServer *server = NULL; +static gchar *service_name = NULL; static gboolean quit_timeout(gpointer data) { g_main_loop_quit(data); @@ -55,45 +60,89 @@ static void subscription(AvahiSubscription *s, AvahiRecord *r, gint interface, g g_free(t); } + +static void remove_entries(void); +static void create_entries(gboolean new_name); + static void entry_group_callback(AvahiServer *s, AvahiEntryGroup *g, AvahiEntryGroupState state, gpointer userdata) { - g_message("entry group state: %i", state); + g_message("=======> entry group state: %i", state); + + if (state == AVAHI_ENTRY_GROUP_COLLISION) { + remove_entries(); + create_entries(TRUE); + } } -int main(int argc, char *argv[]) { - AvahiServer *avahi; - GMainLoop *loop = NULL; - AvahiSubscription *s; - AvahiKey *k; - AvahiEntryGroup *g; - - avahi = avahi_server_new(NULL, NULL); +static void server_callback(AvahiServer *s, AvahiServerState state, gpointer userdata) { + g_message("=======> server state: %i", state); + + if (state == AVAHI_SERVER_RUNNING) + create_entries(FALSE); + else if (state == AVAHI_SERVER_COLLISION) { + gchar *n; + remove_entries(); + + n = avahi_alternative_host_name(avahi_server_get_host_name(s)); + avahi_server_set_host_name(s, n); + g_free(n); + } +} + +static void remove_entries(void) { + if (group) + avahi_entry_group_free(group); - g = avahi_entry_group_new(avahi, entry_group_callback, NULL); + group = NULL; +} + +static void create_entries(gboolean new_name) { + remove_entries(); + + group = avahi_entry_group_new(server, entry_group_callback, NULL); -/* avahi_server_add_text(avahi, g, 0, AF_UNSPEC, AVAHI_ENTRY_UNIQUE, "HALLO", avahi_server_get_hostname(avahi), NULL); */ -/* avahi_server_add_text(avahi, g, 0, AF_UNSPEC, AVAHI_ENTRY_UNIQUE, "hallo", "waldo", NULL); */ + if (!service_name) + service_name = g_strdup("Test Service"); + else if (new_name) { + gchar *n = avahi_alternative_service_name(avahi_server_get_host_name(server)); + g_free(service_name); + service_name = n; + } - avahi_server_add_service(avahi, g, 0, AF_UNSPEC, "_http._tcp", "gurke", NULL, NULL, 80, "foo", NULL); + avahi_server_add_service(server, group, 0, AF_UNSPEC, "_http._tcp", service_name, NULL, NULL, 80, "foo", NULL); + avahi_server_add_service(server, group, 0, AF_UNSPEC, "_ftp._tcp", service_name, NULL, NULL, 21, "foo", NULL); + avahi_server_add_service(server, group, 0, AF_UNSPEC, "_webdav._tcp", service_name, NULL, NULL, 80, "foo", NULL); - avahi_entry_group_commit(g); + avahi_entry_group_commit(group); - avahi_server_dump(avahi, stdout); +} +int main(int argc, char *argv[]) { + GMainLoop *loop = NULL; +/* AvahiSubscription *s; */ +/* AvahiKey *k; */ + server = avahi_server_new(NULL, NULL, server_callback, NULL); + /* k = avahi_key_new("HALLO", AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_TXT); */ /* s = avahi_subscription_new(avahi, k, 0, AF_UNSPEC, subscription, NULL); */ /* avahi_key_unref(k); */ loop = g_main_loop_new(NULL, FALSE); - g_timeout_add(1000*5, dump_timeout, avahi); + g_timeout_add(1000*5, dump_timeout, server); /* g_timeout_add(1000*30, quit_timeout, loop); */ g_main_loop_run(loop); g_main_loop_unref(loop); /* avahi_subscription_free(s); */ - avahi_entry_group_free(g); - avahi_server_free(avahi); + + if (group) + avahi_entry_group_free(group); + + if (server) + avahi_server_free(server); + + g_free(service_name); return 0; } diff --git a/avahi-core/cache.c b/avahi-core/cache.c index cba9c0b..2f0c166 100644 --- a/avahi-core/cache.c +++ b/avahi-core/cache.c @@ -231,13 +231,13 @@ static void expire_in_one_second(AvahiCache *c, AvahiCacheEntry *e) { } void avahi_cache_update(AvahiCache *c, AvahiRecord *r, gboolean unique, const AvahiAddress *a) { - gchar *txt; +/* gchar *txt; */ g_assert(c); g_assert(r && r->ref >= 1); - g_message("cache update: %s", (txt = avahi_record_to_string(r))); - g_free(txt); +/* g_message("cache update: %s", (txt = avahi_record_to_string(r))); */ +/* g_free(txt); */ if (r->ttl == 0) { /* This is a goodbye request */ @@ -278,7 +278,7 @@ void avahi_cache_update(AvahiCache *c, AvahiRecord *r, gboolean unique, const Av if (e) { - g_message("found matching cache entry"); +/* g_message("found matching cache entry"); */ /* We need to update the hash table key if we replace the * record */ @@ -292,7 +292,7 @@ void avahi_cache_update(AvahiCache *c, AvahiRecord *r, gboolean unique, const Av } else { /* No entry found, therefore we create a new one */ - g_message("couldn't find matching cache entry"); +/* g_message("couldn't find matching cache entry"); */ e = g_new(AvahiCacheEntry, 1); e->cache = c; diff --git a/avahi-core/conformance-test.c b/avahi-core/conformance-test.c index 74c3833..4bcd691 100644 --- a/avahi-core/conformance-test.c +++ b/avahi-core/conformance-test.c @@ -31,6 +31,7 @@ #include "core.h" #include "util.h" +#include "alternative.h" static gchar *name = NULL; static AvahiEntryGroup *group = NULL; @@ -68,7 +69,6 @@ static void create_service(gchar *t) { static gboolean rename_timeout(gpointer data) { - if (access("flag", F_OK) == 0) { create_service("New - Bonjour Service Name"); return FALSE; @@ -77,8 +77,6 @@ static gboolean rename_timeout(gpointer data) { return TRUE; } - - static void entry_group_callback(AvahiServer *s, AvahiEntryGroup *g, AvahiEntryGroupState state, gpointer userdata) { if (state == AVAHI_ENTRY_GROUP_COLLISION) create_service(NULL); @@ -88,10 +86,14 @@ static void entry_group_callback(AvahiServer *s, AvahiEntryGroup *g, AvahiEntryG } } +static void server_callback(AvahiServer *s, AvahiServerState state, gpointer userdata) { + g_message("server state: %i", state); +} + int main(int argc, char *argv[]) { GMainLoop *loop = NULL; - avahi = avahi_server_new(NULL, NULL); + avahi = avahi_server_new(NULL, NULL, server_callback, NULL); create_service("gurke"); avahi_server_dump(avahi, stdout); diff --git a/avahi-core/core.h b/avahi-core/core.h index 49b09b5..d27f02e 100644 --- a/avahi-core/core.h +++ b/avahi-core/core.h @@ -25,48 +25,84 @@ #include #include +/** An mDNS responder object */ typedef struct AvahiServer AvahiServer; + +/** A locally registered DNS resource record */ typedef struct AvahiEntry AvahiEntry; + +/** A group of locally registered DNS RRs */ typedef struct AvahiEntryGroup AvahiEntryGroup; #include #include +/** States of a server object */ typedef enum { - AVAHI_ENTRY_NULL = 0, - AVAHI_ENTRY_UNIQUE = 1, - AVAHI_ENTRY_NOPROBE = 2, - AVAHI_ENTRY_NOANNOUNCE = 4 + AVAHI_SERVER_INVALID = -1, /**< Invalid state (initial) */ + AVAHI_SERVER_REGISTERING = 0, /**< Host RRs are being registered */ + AVAHI_SERVER_RUNNING, /**< All host RRs have been established */ + AVAHI_SERVER_COLLISION /**< There is a collision with a host RR. All host RRs have been withdrawn, the user should set a new host name via avahi_server_set_host_name() */ +} AvahiServerState; + +/** Flags for server entries */ +typedef enum { + AVAHI_ENTRY_NULL = 0, /**< No special flags */ + AVAHI_ENTRY_UNIQUE = 1, /**< The RRset is intended to be unique */ + AVAHI_ENTRY_NOPROBE = 2, /**< Though the RRset is intended to be unique no probes shall be sent */ + AVAHI_ENTRY_NOANNOUNCE = 4 /**< Do not announce this RR to other hosts */ } AvahiEntryFlags; +/** States of an entry group object */ typedef enum { - AVAHI_ENTRY_GROUP_UNCOMMITED, - AVAHI_ENTRY_GROUP_REGISTERING, - AVAHI_ENTRY_GROUP_ESTABLISHED, - AVAHI_ENTRY_GROUP_COLLISION + AVAHI_ENTRY_GROUP_UNCOMMITED = -1, /**< The group has not yet been commited, the user must still call avahi_entry_group_commit() */ + AVAHI_ENTRY_GROUP_REGISTERING = 0, /**< The entries of the group are currently being registered */ + AVAHI_ENTRY_GROUP_ESTABLISHED, /**< The entries have successfully been established */ + AVAHI_ENTRY_GROUP_COLLISION /**< A name collision for one of the entries in the group has been detected, the entries have been withdrawn */ } AvahiEntryGroupState; +/** Prototype for callback functions which are called whenever the state of an AvahiServer object changes */ +typedef void (*AvahiServerCallback) (AvahiServer *s, AvahiServerState state, gpointer userdata); + +/** Prototype for callback functions which are called whenever the state of an AvahiEntryGroup object changes */ typedef void (*AvahiEntryGroupCallback) (AvahiServer *s, AvahiEntryGroup *g, AvahiEntryGroupState state, gpointer userdata); +/** Stores configuration options for a server instance */ typedef struct AvahiServerConfig { - gboolean register_hinfo; - gboolean register_addresses; - gboolean use_ipv4; - gboolean use_ipv6; - gchar *host_name; - gchar *domain_name; - gboolean check_response_ttl; + gchar *host_name; /**< Default host name. If left empty defaults to the result of gethostname(2) of the libc */ + gchar *domain_name; /**< Default domain name. If left empty defaults to .local */ + gboolean use_ipv4; /**< Enable IPv4 support */ + gboolean use_ipv6; /**< Enable IPv6 support */ + gboolean register_hinfo; /**< Register a HINFO record for the host containing the local OS and CPU type */ + gboolean register_addresses; /**< Register A, AAAA and PTR records for all local IP addresses */ + gboolean check_response_ttl; /**< If enabled the server ignores all incoming responses with IP TTL != 255 */ } AvahiServerConfig; -AvahiServer *avahi_server_new(GMainContext *c, const AvahiServerConfig *sc); +/** Allocate a new mDNS responder object. */ +AvahiServer *avahi_server_new( + GMainContext *c, /**< The GLIB main loop context to attach to */ + const AvahiServerConfig *sc, /**< If non-NULL a pointer to a configuration structure for the server */ + AvahiServerCallback callback, /**< A callback which is called whenever the state of the server changes */ + gpointer userdata /**< An opaque pointer which is passed to the callback function */); + +/** Free an mDNS responder object */ void avahi_server_free(AvahiServer* s); AvahiServerConfig* avahi_server_config_init(AvahiServerConfig *c); AvahiServerConfig* avahi_server_config_copy(AvahiServerConfig *ret, const AvahiServerConfig *c); void avahi_server_config_free(AvahiServerConfig *c); -const gchar* avahi_server_get_domain(AvahiServer *s); +const gchar* avahi_server_get_domain_name(AvahiServer *s); const gchar* avahi_server_get_host_name(AvahiServer *s); +const gchar* avahi_server_get_host_name_fqdn(AvahiServer *s); + +void avahi_server_set_host_name(AvahiServer *s, const gchar *host_name); +void avahi_server_set_domain_name(AvahiServer *s, const gchar *domain_name); + +gpointer avahi_server_get_data(AvahiServer *s); +void avahi_server_set_data(AvahiServer *s, gpointer userdata); + +AvahiServerState avhai_server_get_state(AvahiServer *s); const AvahiRecord *avahi_server_iterate(AvahiServer *s, AvahiEntryGroup *g, void **state); void avahi_server_dump(AvahiServer *s, FILE *f); @@ -75,6 +111,8 @@ AvahiEntryGroup *avahi_entry_group_new(AvahiServer *s, AvahiEntryGroupCallback c void avahi_entry_group_free(AvahiEntryGroup *g); void avahi_entry_group_commit(AvahiEntryGroup *g); AvahiEntryGroupState avahi_entry_group_get_state(AvahiEntryGroup *g); +void avahi_entry_group_set_data(AvahiEntryGroup *g, gpointer userdata); +gpointer avahi_entry_group_get_data(AvahiEntryGroup *g); void avahi_server_add( AvahiServer *s, diff --git a/avahi-core/iface.c b/avahi-core/iface.c index 61e5a4a..b2c49f7 100644 --- a/avahi-core/iface.c +++ b/avahi-core/iface.c @@ -37,25 +37,36 @@ #include "socket.h" #include "announce.h" -static void update_address_rr(AvahiInterfaceMonitor *m, AvahiInterfaceAddress *a, int remove) { +static void update_address_rr(AvahiInterfaceMonitor *m, AvahiInterfaceAddress *a, gboolean remove) { g_assert(m); g_assert(a); - if (!avahi_interface_address_relevant(a) || remove) { + + if (avahi_interface_address_relevant(a) && + !remove && + m->server->config.register_addresses && + (m->server->state == AVAHI_SERVER_RUNNING || + m->server->state == AVAHI_SERVER_REGISTERING)) { + + if (!a->entry_group) { + a->entry_group = avahi_entry_group_new(m->server, avahi_host_rr_entry_group_callback, NULL); + avahi_server_add_address(m->server, a->entry_group, a->interface->hardware->index, AF_UNSPEC, 0, NULL, &a->address); + avahi_entry_group_commit(a->entry_group); + } + } else { + if (a->entry_group) { + + if (avahi_entry_group_get_state(a->entry_group) == AVAHI_ENTRY_GROUP_REGISTERING) + avahi_server_decrease_host_rr_pending(m->server); + avahi_entry_group_free(a->entry_group); a->entry_group = NULL; } - } else { - if (!a->entry_group && m->server->config.register_addresses) { - a->entry_group = avahi_entry_group_new(m->server, NULL, NULL); - avahi_server_add_address(m->server, a->entry_group, a->interface->hardware->index, AF_UNSPEC, 0, NULL, &a->address); - avahi_entry_group_commit(a->entry_group); - } - } + } } -static void update_interface_rr(AvahiInterfaceMonitor *m, AvahiInterface *i, int remove) { +static void update_interface_rr(AvahiInterfaceMonitor *m, AvahiInterface *i, gboolean remove) { AvahiInterfaceAddress *a; g_assert(m); g_assert(i); @@ -64,7 +75,7 @@ static void update_interface_rr(AvahiInterfaceMonitor *m, AvahiInterface *i, int update_address_rr(m, a, remove); } -static void update_hw_interface_rr(AvahiInterfaceMonitor *m, AvahiHwInterface *hw, int remove) { +static void update_hw_interface_rr(AvahiInterfaceMonitor *m, AvahiHwInterface *hw, gboolean remove) { AvahiInterface *i; g_assert(m); @@ -483,17 +494,17 @@ AvahiHwInterface* avahi_interface_monitor_get_hw_interface(AvahiInterfaceMonitor void avahi_interface_send_packet_unicast(AvahiInterface *i, AvahiDnsPacket *p, const AvahiAddress *a, guint16 port) { g_assert(i); g_assert(p); - char t[64]; +/* char t[64]; */ if (!avahi_interface_relevant(i)) return; g_assert(!a || a->family == i->protocol); - if (a) - g_message("unicast sending on '%s.%i' to %s:%u", i->hardware->name, i->protocol, avahi_address_snprint(t, sizeof(t), a), port); - else - g_message("multicast sending on '%s.%i'", i->hardware->name, i->protocol); +/* if (a) */ +/* g_message("unicast sending on '%s.%i' to %s:%u", i->hardware->name, i->protocol, avahi_address_snprint(t, sizeof(t), a), port); */ +/* else */ +/* g_message("multicast sending on '%s.%i'", i->hardware->name, i->protocol); */ if (i->protocol == AF_INET && i->monitor->server->fd_ipv4 >= 0) avahi_send_dns_packet_ipv4(i->monitor->server->fd_ipv4, i->hardware->index, p, a ? &a->data.ipv4 : NULL, port); @@ -581,7 +592,6 @@ gboolean avahi_interface_match(AvahiInterface *i, gint index, guchar protocol) { return TRUE; } - void avahi_interface_monitor_walk(AvahiInterfaceMonitor *m, gint interface, guchar protocol, AvahiInterfaceMonitorWalkCallback callback, gpointer userdata) { g_assert(m); g_assert(callback); @@ -611,3 +621,12 @@ void avahi_interface_monitor_walk(AvahiInterfaceMonitor *m, gint interface, guch callback(m, i, userdata); } } + +void avahi_update_host_rrs(AvahiInterfaceMonitor *m, gboolean remove) { + AvahiInterface *i; + + g_assert(m); + + for (i = m->interfaces; i; i = i->interface_next) + update_interface_rr(m, i, remove); +} diff --git a/avahi-core/iface.h b/avahi-core/iface.h index ab75a18..d18bbe6 100644 --- a/avahi-core/iface.h +++ b/avahi-core/iface.h @@ -125,4 +125,6 @@ typedef void (*AvahiInterfaceMonitorWalkCallback)(AvahiInterfaceMonitor *m, Avah void avahi_interface_monitor_walk(AvahiInterfaceMonitor *m, gint index, guchar protocol, AvahiInterfaceMonitorWalkCallback callback, gpointer userdata); +void avahi_update_host_rrs(AvahiInterfaceMonitor *m, gboolean remove); + #endif diff --git a/avahi-core/probe-sched.c b/avahi-core/probe-sched.c index 9cea3e0..9089bba 100644 --- a/avahi-core/probe-sched.c +++ b/avahi-core/probe-sched.c @@ -267,7 +267,7 @@ gboolean avahi_probe_scheduler_post(AvahiProbeScheduler *s, AvahiRecord *record, pj->delivery = tv; pj->time_event = avahi_time_event_queue_add(s->time_event_queue, &pj->delivery, elapse_callback, pj); - g_message("Accepted new probe job."); +/* g_message("Accepted new probe job."); */ return TRUE; } diff --git a/avahi-core/query-sched.c b/avahi-core/query-sched.c index 32d0e91..7cdba04 100644 --- a/avahi-core/query-sched.c +++ b/avahi-core/query-sched.c @@ -326,7 +326,7 @@ gboolean avahi_query_scheduler_post(AvahiQueryScheduler *s, AvahiKey *key, gbool g_assert(key); if ((qj = find_history_job(s, key))) { - g_message("Query suppressed by local duplicate suppression (history)"); +/* g_message("Query suppressed by local duplicate suppression (history)"); */ return FALSE; } @@ -335,7 +335,7 @@ gboolean avahi_query_scheduler_post(AvahiQueryScheduler *s, AvahiKey *key, gbool if ((qj = find_scheduled_job(s, key))) { /* Duplicate questions suppression */ - g_message("Query suppressed by local duplicate suppression (scheduled)"); +/* g_message("Query suppressed by local duplicate suppression (scheduled)"); */ if (avahi_timeval_compare(&tv, &qj->delivery) < 0) { /* If the new entry should be scheduled earlier, @@ -346,7 +346,7 @@ gboolean avahi_query_scheduler_post(AvahiQueryScheduler *s, AvahiKey *key, gbool return TRUE; } else { - g_message("Accepted new query job.\n"); +/* g_message("Accepted new query job.\n"); */ qj = job_new(s, key, FALSE); qj->delivery = tv; @@ -367,7 +367,7 @@ void avahi_query_scheduler_incoming(AvahiQueryScheduler *s, AvahiKey *key) { * "DUPLICATE QUESTION SUPPRESION". */ if ((qj = find_scheduled_job(s, key))) { - g_message("Query suppressed by distributed duplicate suppression"); +/* g_message("Query suppressed by distributed duplicate suppression"); */ job_mark_done(s, qj); return; } diff --git a/avahi-core/response-sched.c b/avahi-core/response-sched.c index c4218eb..f88c63a 100644 --- a/avahi-core/response-sched.c +++ b/avahi-core/response-sched.c @@ -339,7 +339,7 @@ gboolean avahi_response_scheduler_post(AvahiResponseScheduler *s, AvahiRecord *r avahi_record_is_goodbye(record) == avahi_record_is_goodbye(rj->record) && rj->record->ttl >= record->ttl/2) { - g_message("Response suppressed by known answer suppression."); +/* g_message("Response suppressed by known answer suppression."); */ return FALSE; } @@ -349,7 +349,7 @@ gboolean avahi_response_scheduler_post(AvahiResponseScheduler *s, AvahiRecord *r if (avahi_record_is_goodbye(record) == avahi_record_is_goodbye(rj->record) && rj->record->ttl >= record->ttl/2 && (rj->flush_cache || !flush_cache)) { - g_message("Response suppressed by local duplicate suppression (history)"); +/* g_message("Response suppressed by local duplicate suppression (history)"); */ return FALSE; } @@ -360,7 +360,7 @@ gboolean avahi_response_scheduler_post(AvahiResponseScheduler *s, AvahiRecord *r avahi_elapse_time(&tv, immediately ? 0 : AVAHI_RESPONSE_DEFER_MSEC, immediately ? 0 : AVAHI_RESPONSE_JITTER_MSEC); if ((rj = find_scheduled_job(s, record))) { - g_message("Response suppressed by local duplicate suppression (scheduled)"); +/* g_message("Response suppressed by local duplicate suppression (scheduled)"); */ /* Update a little ... */ @@ -384,7 +384,7 @@ gboolean avahi_response_scheduler_post(AvahiResponseScheduler *s, AvahiRecord *r return TRUE; } else { - g_message("Accepted new response job."); +/* g_message("Accepted new response job."); */ /* Create a new job and schedule it */ rj = job_new(s, record, AVAHI_SCHEDULED); @@ -414,7 +414,7 @@ void avahi_response_scheduler_incoming(AvahiResponseScheduler *s, AvahiRecord *r record->ttl >= rj->record->ttl/2) { /* sensible TTL */ /* A matching entry was found, so let's mark it done */ - g_message("Response suppressed by distributed duplicate suppression"); +/* g_message("Response suppressed by distributed duplicate suppression"); */ job_mark_done(s, rj); } @@ -450,7 +450,7 @@ void avahi_response_scheduler_suppress(AvahiResponseScheduler *s, AvahiRecord *r record->ttl >= rj->record->ttl/2) { /* sensible TTL */ /* A matching entry was found, so let's drop it */ - g_message("Known answer suppression active!"); +/* g_message("Known answer suppression active!"); */ job_free(s, rj); } } diff --git a/avahi-core/rr.c b/avahi-core/rr.c index a21595f..f69d2e2 100644 --- a/avahi-core/rr.c +++ b/avahi-core/rr.c @@ -457,16 +457,16 @@ static gint uint16_cmp(guint16 a, guint16 b) { gint avahi_record_lexicographical_compare(AvahiRecord *a, AvahiRecord *b) { gint r; - gchar *t1, *t2; +/* gchar *t1, *t2; */ g_assert(a); g_assert(b); - t1 = avahi_record_to_string(a); - t2 = avahi_record_to_string(b); - g_message("lexicocmp: %s %s", t1, t2); - g_free(t1); - g_free(t2); +/* t1 = avahi_record_to_string(a); */ +/* t2 = avahi_record_to_string(b); */ +/* g_message("lexicocmp: %s %s", t1, t2); */ +/* g_free(t1); */ +/* g_free(t2); */ if (a == b) return 0; @@ -486,8 +486,6 @@ gint avahi_record_lexicographical_compare(AvahiRecord *a, AvahiRecord *b) { (r = uint16_cmp(a->data.srv.weight, b->data.srv.weight)) == 0 && (r = uint16_cmp(a->data.srv.port, b->data.srv.port)) == 0) r = avahi_binary_domain_cmp(a->data.srv.name, b->data.srv.name); - - g_message("SRV: %i", r); return r; } diff --git a/avahi-core/server.c b/avahi-core/server.c index 316952b..f04ae67 100644 --- a/avahi-core/server.c +++ b/avahi-core/server.c @@ -149,14 +149,14 @@ void avahi_server_prepare_response(AvahiServer *s, AvahiInterface *i, AvahiEntry void avahi_server_prepare_matching_responses(AvahiServer *s, AvahiInterface *i, AvahiKey *k, gboolean unicast_response) { AvahiEntry *e; - gchar *txt; +/* gchar *txt; */ g_assert(s); g_assert(i); g_assert(k); - g_message("Posting responses matching [%s]", txt = avahi_key_to_string(k)); - g_free(txt); +/* g_message("Posting responses matching [%s]", txt = avahi_key_to_string(k)); */ +/* g_free(txt); */ if (avahi_key_is_pattern(k)) { @@ -258,7 +258,7 @@ static gboolean handle_conflict(AvahiServer *s, AvahiInterface *i, AvahiRecord * t = avahi_record_to_string(record); - g_message("CHECKING FOR CONFLICT: [%s]", t); +/* g_message("CHECKING FOR CONFLICT: [%s]", t); */ for (e = g_hash_table_lookup(s->entries_by_key, record->key); e; e = n) { n = e->by_key_next; @@ -543,8 +543,8 @@ static void handle_response(AvahiServer *s, AvahiDnsPacket *p, AvahiInterface *i if (record->key->type != AVAHI_DNS_TYPE_ANY) { - g_message("Handling response: %s", txt = avahi_record_to_string(record)); - g_free(txt); +/* g_message("Handling response: %s", txt = avahi_record_to_string(record)); */ +/* g_free(txt); */ if (handle_conflict(s, i, record, cache_flush, a)) { avahi_cache_update(i->cache, record, cache_flush, a); @@ -572,7 +572,7 @@ static void dispatch_packet(AvahiServer *s, AvahiDnsPacket *p, struct sockaddr * return; } - g_message("new packet recieved on interface '%s.%i'.", i->hardware->name, i->protocol); +/* g_message("new packet recieved on interface '%s.%i'.", i->hardware->name, i->protocol); */ if (sa->sa_family == AF_INET6) { static const guint8 ipv4_in_ipv6[] = { @@ -616,7 +616,7 @@ static void dispatch_packet(AvahiServer *s, AvahiDnsPacket *p, struct sockaddr * handle_query(s, p, i, &a, port, legacy_unicast); - g_message("Handled query"); +/* g_message("Handled query"); */ } else { if (port != AVAHI_MDNS_PORT) { @@ -638,7 +638,7 @@ static void dispatch_packet(AvahiServer *s, AvahiDnsPacket *p, struct sockaddr * } handle_response(s, p, i, &a); - g_message("Handled response"); +/* g_message("Handled response"); */ } } @@ -697,24 +697,86 @@ static gboolean dispatch_func(GSource *source, GSourceFunc callback, gpointer us return TRUE; } -static void add_default_entries(AvahiServer *s) { - AvahiAddress a; +static void server_set_state(AvahiServer *s, AvahiServerState state) { + g_assert(s); + + if (s->state == state) + return; + s->state = state; + + if (s->callback) + s->callback(s, state, s->userdata); +} + +static void withdraw_host_rrs(AvahiServer *s) { g_assert(s); - if (s->config.register_hinfo) { - struct utsname utsname; - AvahiRecord *r; - - /* Fill in HINFO rr */ - r = avahi_record_new_full(s->host_name_fqdn, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_HINFO); - uname(&utsname); - r->data.hinfo.cpu = g_strdup(g_strup(utsname.machine)); - r->data.hinfo.os = g_strdup(g_strup(utsname.sysname)); - avahi_server_add(s, NULL, 0, AF_UNSPEC, AVAHI_ENTRY_UNIQUE, r); - avahi_record_unref(r); + if (s->hinfo_entry_group) { + avahi_entry_group_free(s->hinfo_entry_group); + s->hinfo_entry_group = NULL; } + avahi_update_host_rrs(s->monitor, TRUE); + s->n_host_rr_pending = 0; +} + +void avahi_server_decrease_host_rr_pending(AvahiServer *s) { + g_assert(s); + + g_assert(s->n_host_rr_pending > 0); + + if (--s->n_host_rr_pending == 0) + server_set_state(s, AVAHI_SERVER_RUNNING); +} + +void avahi_server_increase_host_rr_pending(AvahiServer *s) { + g_assert(s); + + s->n_host_rr_pending ++; +} + +void avahi_host_rr_entry_group_callback(AvahiServer *s, AvahiEntryGroup *g, AvahiEntryGroupState state, void *userdata) { + g_assert(s); + g_assert(g); + + if (state == AVAHI_ENTRY_GROUP_REGISTERING && + s->state == AVAHI_SERVER_REGISTERING) + avahi_server_increase_host_rr_pending(s); + else if (state == AVAHI_ENTRY_GROUP_COLLISION) { + withdraw_host_rrs(s); + server_set_state(s, AVAHI_SERVER_COLLISION); + } else if (state == AVAHI_ENTRY_GROUP_ESTABLISHED && + s->state == AVAHI_SERVER_REGISTERING) + avahi_server_decrease_host_rr_pending(s); +} + +static void register_hinfo(AvahiServer *s) { + struct utsname utsname; + AvahiRecord *r; + + g_assert(s); + + if (!s->config.register_hinfo || s->hinfo_entry_group) + return; + + s->hinfo_entry_group = avahi_entry_group_new(s, avahi_host_rr_entry_group_callback, NULL); + + /* Fill in HINFO rr */ + r = avahi_record_new_full(s->host_name_fqdn, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_HINFO); + uname(&utsname); + r->data.hinfo.cpu = g_strdup(g_strup(utsname.machine)); + r->data.hinfo.os = g_strdup(g_strup(utsname.sysname)); + avahi_server_add(s, s->hinfo_entry_group, 0, AF_UNSPEC, AVAHI_ENTRY_UNIQUE, r); + avahi_record_unref(r); + + avahi_entry_group_commit(s->hinfo_entry_group); +} + +static void register_localhost(AvahiServer *s) { + AvahiAddress a; + g_assert(s); + /* Add localhost entries */ avahi_address_parse("127.0.0.1", AF_INET, &a); avahi_server_add_address(s, NULL, 0, AF_UNSPEC, AVAHI_ENTRY_NOPROBE|AVAHI_ENTRY_NOANNOUNCE, "localhost", &a); @@ -723,7 +785,55 @@ static void add_default_entries(AvahiServer *s) { avahi_server_add_address(s, NULL, 0, AF_UNSPEC, AVAHI_ENTRY_NOPROBE|AVAHI_ENTRY_NOANNOUNCE, "ip6-localhost", &a); } -AvahiServer *avahi_server_new(GMainContext *c, const AvahiServerConfig *sc) { +static void register_stuff(AvahiServer *s) { + g_assert(s); + + server_set_state(s, AVAHI_SERVER_REGISTERING); + register_hinfo(s); + avahi_update_host_rrs(s->monitor, FALSE); + + if (s->n_host_rr_pending == 0) + server_set_state(s, AVAHI_SERVER_RUNNING); +} + +static void update_fqdn(AvahiServer *s) { + g_assert(s); + + g_assert(s->host_name); + g_assert(s->domain_name); + + g_free(s->host_name_fqdn); + s->host_name_fqdn = g_strdup_printf("%s.%s", s->host_name, s->domain_name); +} + +void avahi_server_set_host_name(AvahiServer *s, const gchar *host_name) { + g_assert(s); + g_assert(host_name); + + withdraw_host_rrs(s); + + g_free(s->host_name); + s->host_name = host_name ? avahi_normalize_name(host_name) : avahi_get_host_name(); + s->host_name[strcspn(s->host_name, ".")] = 0; + update_fqdn(s); + + register_stuff(s); +} + +void avahi_server_set_domain_name(AvahiServer *s, const gchar *domain_name) { + g_assert(s); + g_assert(domain_name); + + withdraw_host_rrs(s); + + g_free(s->domain_name); + s->domain_name = domain_name ? avahi_normalize_name(domain_name) : g_strdup("local."); + update_fqdn(s); + + register_stuff(s); +} + +AvahiServer *avahi_server_new(GMainContext *c, const AvahiServerConfig *sc, AvahiServerCallback callback, gpointer userdata) { AvahiServer *s; static GSourceFuncs source_funcs = { @@ -736,7 +846,7 @@ AvahiServer *avahi_server_new(GMainContext *c, const AvahiServerConfig *sc) { }; s = g_new(AvahiServer, 1); - + s->n_host_rr_pending = 0; s->need_entry_cleanup = s->need_group_cleanup = FALSE; if (sc) @@ -763,6 +873,25 @@ AvahiServer *avahi_server_new(GMainContext *c, const AvahiServerConfig *sc) { g_main_context_ref(s->context = c); else s->context = g_main_context_default(); + + /* Prepare IO source registration */ + s->source = g_source_new(&source_funcs, sizeof(GSource) + sizeof(AvahiServer*)); + *((AvahiServer**) (((guint8*) s->source) + sizeof(GSource))) = s; + + memset(&s->pollfd_ipv4, 0, sizeof(s->pollfd_ipv4)); + s->pollfd_ipv4.fd = s->fd_ipv4; + s->pollfd_ipv4.events = G_IO_IN|G_IO_ERR|G_IO_HUP; + g_source_add_poll(s->source, &s->pollfd_ipv4); + + memset(&s->pollfd_ipv6, 0, sizeof(s->pollfd_ipv6)); + s->pollfd_ipv6.fd = s->fd_ipv6; + s->pollfd_ipv6.events = G_IO_IN|G_IO_ERR|G_IO_HUP; + g_source_add_poll(s->source, &s->pollfd_ipv6); + + g_source_attach(s->source, s->context); + + s->callback = callback; + s->userdata = userdata; AVAHI_LLIST_HEAD_INIT(AvahiEntry, s->entries); s->entries_by_key = g_hash_table_new((GHashFunc) avahi_key_hash, (GEqualFunc) avahi_key_equal); @@ -772,37 +901,26 @@ AvahiServer *avahi_server_new(GMainContext *c, const AvahiServerConfig *sc) { s->subscription_hashtable = g_hash_table_new((GHashFunc) avahi_key_hash, (GEqualFunc) avahi_key_equal); /* Get host name */ - s->host_name = avahi_get_host_name(); + s->host_name = s->config.host_name ? avahi_normalize_name(s->config.host_name) : avahi_get_host_name(); s->host_name[strcspn(s->host_name, ".")] = 0; - - s->domain = avahi_normalize_name("local."); - - s->host_name_fqdn = g_strdup_printf("%s.%s", s->host_name, s->domain); + s->domain_name = s->config.domain_name ? avahi_normalize_name(s->config.domain_name) : g_strdup("local."); + s->host_name_fqdn = NULL; + update_fqdn(s); s->record_list = avahi_record_list_new(); s->time_event_queue = avahi_time_event_queue_new(s->context, G_PRIORITY_DEFAULT+10); /* Slightly less priority than the FDs */ + + s->state = AVAHI_SERVER_INVALID; + s->monitor = avahi_interface_monitor_new(s); avahi_interface_monitor_sync(s->monitor); - - add_default_entries(s); - - /* Prepare IO source registration */ - s->source = g_source_new(&source_funcs, sizeof(GSource) + sizeof(AvahiServer*)); - *((AvahiServer**) (((guint8*) s->source) + sizeof(GSource))) = s; - memset(&s->pollfd_ipv4, 0, sizeof(s->pollfd_ipv4)); - s->pollfd_ipv4.fd = s->fd_ipv4; - s->pollfd_ipv4.events = G_IO_IN|G_IO_ERR|G_IO_HUP; - g_source_add_poll(s->source, &s->pollfd_ipv4); - - memset(&s->pollfd_ipv6, 0, sizeof(s->pollfd_ipv6)); - s->pollfd_ipv6.fd = s->fd_ipv6; - s->pollfd_ipv6.events = G_IO_IN|G_IO_ERR|G_IO_HUP; - g_source_add_poll(s->source, &s->pollfd_ipv6); - - g_source_attach(s->source, s->context); + register_localhost(s); + s->hinfo_entry_group = NULL; + register_stuff(s); + return s; } @@ -833,7 +951,7 @@ void avahi_server_free(AvahiServer* s) { close(s->fd_ipv6); g_free(s->host_name); - g_free(s->domain); + g_free(s->domain_name); g_free(s->host_name_fqdn); g_source_destroy(s->source); @@ -1175,7 +1293,7 @@ void avahi_entry_group_change_state(AvahiEntryGroup *g, AvahiEntryGroupState sta if (g->state == state) return; - + g->state = state; if (g->callback) { @@ -1238,18 +1356,54 @@ AvahiEntryGroupState avahi_entry_group_get_state(AvahiEntryGroup *g) { return g->state; } -const gchar* avahi_server_get_domain(AvahiServer *s) { +void avahi_entry_group_set_data(AvahiEntryGroup *g, gpointer userdata) { + g_assert(g); + + g->userdata = userdata; +} + +gpointer avahi_entry_group_get_data(AvahiEntryGroup *g) { + g_assert(g); + + return g->userdata; +} + +const gchar* avahi_server_get_domain_name(AvahiServer *s) { g_assert(s); - return s->domain; + return s->domain_name; } const gchar* avahi_server_get_host_name(AvahiServer *s) { g_assert(s); + return s->host_name; +} + +const gchar* avahi_server_get_host_name_fqdn(AvahiServer *s) { + g_assert(s); + return s->host_name_fqdn; } +gpointer avahi_server_get_data(AvahiServer *s) { + g_assert(s); + + return s->userdata; +} + +void avahi_server_set_data(AvahiServer *s, gpointer userdata) { + g_assert(s); + + s->userdata = userdata; +} + +AvahiServerState avhai_server_get_state(AvahiServer *s) { + g_assert(s); + + return s->state; +} + AvahiServerConfig* avahi_server_config_init(AvahiServerConfig *c) { g_assert(c); diff --git a/avahi-core/server.h b/avahi-core/server.h index 4d0e8a3..fddf17e 100644 --- a/avahi-core/server.h +++ b/avahi-core/server.h @@ -82,13 +82,20 @@ struct AvahiServer { AvahiTimeEventQueue *time_event_queue; - gchar *host_name, *host_name_fqdn, *domain; + gchar *host_name, *host_name_fqdn, *domain_name; gint fd_ipv4, fd_ipv6; GPollFD pollfd_ipv4, pollfd_ipv6; GSource *source; + AvahiServerState state; + AvahiServerCallback callback; + gpointer userdata; + + AvahiEntryGroup *hinfo_entry_group; + guint n_host_rr_pending; + /* Used for assembling responses */ AvahiRecordList *record_list; }; @@ -107,4 +114,9 @@ gboolean avahi_entry_commited(AvahiEntry *e); void avahi_server_enumerate_aux_records(AvahiServer *s, AvahiInterface *i, AvahiRecord *r, void (*callback)(AvahiServer *s, AvahiRecord *r, gboolean flush_cache, gpointer userdata), gpointer userdata); +void avahi_host_rr_entry_group_callback(AvahiServer *s, AvahiEntryGroup *g, AvahiEntryGroupState state, void *userdata); + +void avahi_server_decrease_host_rr_pending(AvahiServer *s); +void avahi_server_increase_host_rr_pending(AvahiServer *s); + #endif diff --git a/avahi-core/util.c b/avahi-core/util.c index fa5eb71..91403e6 100644 --- a/avahi-core/util.c +++ b/avahi-core/util.c @@ -404,54 +404,3 @@ gint avahi_domain_hash(const gchar *s) { } } - -gchar * avahi_alternative_host_name(const gchar *s) { - const gchar *p, *e = NULL; - gchar *c, *r; - gint n; - - g_assert(s); - - for (p = s; *p; p++) - if (!isdigit(*p)) - e = p+1; - - if (e && *e) - n = atoi(e)+1; - else - n = 2; - - c = e ? g_strndup(s, e-s) : g_strdup(s); - r = g_strdup_printf("%s%i", c, n); - g_free(c); - - return r; - -} - -gchar *avahi_alternative_service_name(const gchar *s) { - const gchar *e; - g_assert(s); - - if ((e = strstr(s, " #"))) { - const gchar *n, *p; - e += 2; - - while ((n = strstr(e, " #"))) - e = n + 2; - - for (p = e; *p; p++) - if (!isdigit(*p)) { - e = NULL; - break; - } - } - - if (e) { - gchar *r, *c = g_strndup(s, e-s); - r = g_strdup_printf("%s%i", c, atoi(e)+1); - g_free(c); - return r; - } else - return g_strdup_printf("%s #2", s); -} diff --git a/avahi-core/util.h b/avahi-core/util.h index 04dd425..45b4ce7 100644 --- a/avahi-core/util.h +++ b/avahi-core/util.h @@ -52,8 +52,4 @@ gchar *avahi_escape_label(const guint8* src, guint src_length, gchar **ret_name, gint avahi_domain_hash(const gchar *s); -gchar *avahi_alternative_host_name(const gchar *s); -gchar *avahi_alternative_service_name(const gchar *s); - - #endif diff --git a/doxygen/doxygen.conf.in b/doxygen/doxygen.conf.in index 062dabe..cf0e378 100644 --- a/doxygen/doxygen.conf.in +++ b/doxygen/doxygen.conf.in @@ -417,7 +417,7 @@ WARN_LOGFILE = # directories like "/usr/src/myproject". Separate the files or directories # with spaces. -INPUT = ../avahi-core/core.h ../avahi-core/address.h ../avahi-core/rr.h ../avahi-core/strlst.h +INPUT = ../avahi-core/core.h ../avahi-core/address.h ../avahi-core/rr.h ../avahi-core/strlst.h ../avahi-core/alternative.h # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp