From 0632e854728e8e64552ae08f90852d4a2658539e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 5 Aug 2005 18:59:21 +0000 Subject: [PATCH] * add proper error codes and patch everything to make use of it * parameter validity checkin in all user visible functions of libavahi-core * two new python tools/examples avahi-resolve-host-name and avahi-resolve-address git-svn-id: file:///home/lennart/svn/public/avahi/trunk@238 941a03a8-eaeb-0310-b9a0-b1bbd8fe43fe --- avahi-common/dbus.h | 26 +++- avahi-common/rr.c | 46 ++++++ avahi-common/rr.h | 8 +- avahi-common/util.c | 94 ++++++++++++ avahi-common/util.h | 5 + avahi-core/avahi-reflector.c | 3 +- avahi-core/avahi-test.c | 3 +- avahi-core/browse-dns-server.c | 16 ++- avahi-core/browse-domain.c | 17 ++- avahi-core/browse-service-type.c | 13 +- avahi-core/browse-service.c | 21 ++- avahi-core/browse.c | 10 +- avahi-core/conformance-test.c | 3 +- avahi-core/core.h | 42 +++++- avahi-core/resolve-address.c | 5 + avahi-core/resolve-host-name.c | 21 ++- avahi-core/resolve-service.c | 27 +++- avahi-core/server.c | 190 +++++++++++++++++++++---- avahi-core/server.h | 4 + avahi-daemon/dbus-protocol.c | 176 ++++++++++++----------- avahi-daemon/main.c | 6 +- avahi-daemon/static-services.c | 7 +- avahi-discover-standalone/main.c | 5 +- avahi-utils/Makefile.am | 16 ++- avahi-utils/avahi-resolve-address.in | 53 +++++++ avahi-utils/avahi-resolve-host-name.in | 53 +++++++ doxygen.cfg | 2 +- examples/browse-services.c | 16 ++- examples/publish-service.c | 18 ++- 29 files changed, 755 insertions(+), 151 deletions(-) create mode 100755 avahi-utils/avahi-resolve-address.in create mode 100755 avahi-utils/avahi-resolve-host-name.in diff --git a/avahi-common/dbus.h b/avahi-common/dbus.h index ddbd47a..64696d2 100644 --- a/avahi-common/dbus.h +++ b/avahi-common/dbus.h @@ -32,13 +32,25 @@ AVAHI_C_DECL_BEGIN #define AVAHI_DBUS_INTERFACE_SERVICE_TYPE_BROWSER AVAHI_DBUS_NAME".ServiceTypeBrowser" #define AVAHI_DBUS_INTERFACE_SERVICE_BROWSER AVAHI_DBUS_NAME".ServiceBrowser" -#define AVAHI_DBUS_ERROR_INVALID_SERVICE "org.freedesktop.Avahi.InvalidServiceError" -#define AVAHI_DBUS_ERROR_INVALID_ADDRESS "org.freedesktop.Avahi.InvalidAddressError" -#define AVAHI_DBUS_ERROR_TIMEOUT "org.freedesktop.Avahi.TimeoutError" -#define AVAHI_DBUS_ERROR_TOO_MANY_CLIENTS "org.freedesktop.Avahi.TooManyClientsError" -#define AVAHI_DBUS_ERROR_TOO_MANY_OBJECTS "org.freedesktop.Avahi.TooManyObjectsError" -#define AVAHI_DBUS_ERROR_TOO_MANY_ENTRIES "org.freedesktop.Avahi.TooManyEntriesError" -#define AVAHI_DBUS_ERROR_OS "org.freedesktop.Avahi.OSError" +#define AVAHI_DBUS_ERR_FAILURE "org.freedesktop.Avahi.Failure" +#define AVAHI_DBUS_ERR_BAD_STATE "org.freedesktop.Avahi.BadStateError" +#define AVAHI_DBUS_ERR_INVALID_HOST_NAME "org.freedesktop.Avahi.InvalidHostNameError" +#define AVAHI_DBUS_ERR_INVALID_DOMAIN_NAME "org.freedesktop.Avahi.InvalidDomainNameError" +#define AVAHI_DBUS_ERR_NO_NETWORK "org.freedesktop.Avahi.NoNetworkError" +#define AVAHI_DBUS_ERR_INVALID_TTL "org.freedesktop.Avahi.InvalidTTLError" +#define AVAHI_DBUS_ERR_IS_PATTERN "org.freedesktop.Avahi.IsPatternError" +#define AVAHI_DBUS_ERR_LOCAL_COLLISION "org.freedesktop.Avahi.LocalCollisionError" +#define AVAHI_DBUS_ERR_INVALID_RECORD "org.freedesktop.Avahi.InvalidRecordError" +#define AVAHI_DBUS_ERR_INVALID_SERVICE_NAME "org.freedesktop.Avahi.InvalidServiceNameError" +#define AVAHI_DBUS_ERR_INVALID_SERVICE_TYPE "org.freedesktop.Avahi.InvalidServiceTypeError" +#define AVAHI_DBUS_ERR_INVALID_PORT "org.freedesktop.Avahi.InvalidPortError" +#define AVAHI_DBUS_ERR_INVALID_KEY "org.freedesktop.Avahi.InvalidKeyError" +#define AVAHI_DBUS_ERR_INVALID_ADDRESS "org.freedesktop.Avahi.InvalidAddressError" +#define AVAHI_DBUS_ERR_TIMEOUT "org.freedesktop.Avahi.TimeoutError" +#define AVAHI_DBUS_ERR_TOO_MANY_CLIENTS "org.freedesktop.Avahi.TooManyClientsError" +#define AVAHI_DBUS_ERR_TOO_MANY_OBJECTS "org.freedesktop.Avahi.TooManyObjectsError" +#define AVAHI_DBUS_ERR_TOO_MANY_ENTRIES "org.freedesktop.Avahi.TooManyEntriesError" +#define AVAHI_DBUS_ERR_OS "org.freedesktop.Avahi.OSError" AVAHI_C_DECL_END diff --git a/avahi-common/rr.c b/avahi-common/rr.c index c510e7f..1a30146 100644 --- a/avahi-common/rr.c +++ b/avahi-common/rr.c @@ -552,3 +552,49 @@ gboolean avahi_record_is_goodbye(AvahiRecord *r) { return r->ttl == 0; } + +gboolean avahi_key_valid(AvahiKey *k) { + g_assert(k); + + if (!avahi_valid_domain_name(k->name)) + return FALSE; + + return TRUE; +} + +gboolean avahi_record_valid(AvahiRecord *r) { + g_assert(r); + + if (!avahi_key_valid(r->key)) + return FALSE; + + switch (r->key->type) { + + case AVAHI_DNS_TYPE_PTR: + case AVAHI_DNS_TYPE_CNAME: + return avahi_valid_domain_name(r->data.ptr.name); + + case AVAHI_DNS_TYPE_SRV: + return avahi_valid_domain_name(r->data.srv.name); + + case AVAHI_DNS_TYPE_HINFO: + return + strlen(r->data.hinfo.os) <= 255 && + strlen(r->data.hinfo.cpu) <= 255; + + + case AVAHI_DNS_TYPE_TXT: { + + AvahiStringList *strlst; + + for (strlst = r->data.txt.string_list; strlst; strlst = strlst->next) + if (strlst->size > 255) + return FALSE; + + return TRUE; + } + } + + + return TRUE; +} diff --git a/avahi-common/rr.h b/avahi-common/rr.h index 25d6eee..f5349e9 100644 --- a/avahi-common/rr.h +++ b/avahi-common/rr.h @@ -82,13 +82,11 @@ typedef struct { guint32 ttl; /**< DNS TTL of this record */ union { - struct { gpointer data; guint16 size; } generic; /**< Generic record data for unknown types */ - struct { guint16 priority; @@ -200,6 +198,12 @@ gint avahi_record_lexicographical_compare(AvahiRecord *a, AvahiRecord *b); /** Return TRUE if the specified record is an mDNS goodbye record. i.e. TTL is zero. */ gboolean avahi_record_is_goodbye(AvahiRecord *r); +/** Check whether the specified key is valid */ +gboolean avahi_key_valid(AvahiKey *k); + +/** Check whether the specified record is valid */ +gboolean avahi_record_valid(AvahiRecord *r); + AVAHI_C_DECL_END #endif diff --git a/avahi-common/util.c b/avahi-common/util.c index 8be7b88..a977bb2 100644 --- a/avahi-common/util.c +++ b/avahi-common/util.c @@ -414,3 +414,97 @@ gchar *avahi_format_mac_address(const guint8* mac, guint size) { *(--t) = 0; return r; } + +gboolean avahi_valid_service_type(const gchar *t) { + const gchar *p; + g_assert(t); + + if (strlen(t) < 5) + return FALSE; + + if (*t != '_') + return FALSE; + + if (!(p = strchr(t, '.'))) + return FALSE; + + if (p - t > 63 || p - t < 2) + return FALSE; + + if (*(++p) != '_') + return FALSE; + + if (strchr(p, '.')) + return FALSE; + + if (strlen(p) > 63 || strlen(p) < 2) + return FALSE; + + return TRUE; +} + +gboolean avahi_valid_domain_name(const gchar *t) { + const gchar *p, *dp; + gboolean dot = FALSE; + + g_assert(t); + + if (*t == 0) + return FALSE; + + /* Domains may not start with a dot */ + if (*t == '.') + return FALSE; + + dp = t; + + for (p = t; *p; p++) { + + if (*p == '.') { + if (dot) /* Two subsequent dots */ + return FALSE; + + if (p - dp > 63) + return FALSE; + + dot = TRUE; + dp = p + 1; + } else + dot = FALSE; + + } + + if (p - dp > 63) + return FALSE; + + /* A trailing dot IS allowed */ + + return TRUE; +} + +gboolean avahi_valid_service_name(const gchar *t) { + g_assert(t); + + if (*t == 0) + return FALSE; + + if (strlen(t) > 63) + return FALSE; + + return TRUE; +} + +gboolean avahi_valid_host_name(const gchar *t) { + g_assert(t); + + if (*t == 0) + return FALSE; + + if (strlen(t) > 63) + return FALSE; + + if (strchr(t, '.')) + return FALSE; + + return TRUE; +} diff --git a/avahi-common/util.h b/avahi-common/util.h index 731a5a1..0d4fb4b 100644 --- a/avahi-common/util.h +++ b/avahi-common/util.h @@ -60,6 +60,11 @@ guint avahi_domain_hash(const gchar *s); gchar *avahi_format_mac_address(const guint8* mac, guint size); +gboolean avahi_valid_service_type(const gchar *t); +gboolean avahi_valid_domain_name(const gchar *t); +gboolean avahi_valid_service_name(const gchar *t); +gboolean avahi_valid_host_name(const gchar *t); + AVAHI_C_DECL_END #endif diff --git a/avahi-core/avahi-reflector.c b/avahi-core/avahi-reflector.c index 7af0dd4..0a91b87 100644 --- a/avahi-core/avahi-reflector.c +++ b/avahi-core/avahi-reflector.c @@ -34,6 +34,7 @@ int main(int argc, char*argv[]) { AvahiServer *server; AvahiServerConfig config; GMainLoop *loop; + gint error; avahi_server_config_init(&config); config.publish_hinfo = FALSE; @@ -43,7 +44,7 @@ int main(int argc, char*argv[]) { config.use_ipv6 = FALSE; config.enable_reflector = TRUE; - server = avahi_server_new(NULL, &config, NULL, NULL); + server = avahi_server_new(NULL, &config, NULL, NULL, &error); avahi_server_config_free(&config); loop = g_main_loop_new(NULL, FALSE); diff --git a/avahi-core/avahi-test.c b/avahi-core/avahi-test.c index cc950d4..5db2473 100644 --- a/avahi-core/avahi-test.c +++ b/avahi-core/avahi-test.c @@ -217,10 +217,11 @@ int main(int argc, char *argv[]) { AvahiServiceBrowser *sb; AvahiServiceResolver *sr; AvahiDNSServerBrowser *dsb; + gint error; avahi_server_config_init(&config); /* config.host_name = g_strdup("test"); */ - server = avahi_server_new(NULL, &config, server_callback, NULL); + server = avahi_server_new(NULL, &config, server_callback, NULL, &error); avahi_server_config_free(&config); k = avahi_key_new("_http._tcp.local", AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_PTR); diff --git a/avahi-core/browse-dns-server.c b/avahi-core/browse-dns-server.c index f8e8f30..057f3e3 100644 --- a/avahi-core/browse-dns-server.c +++ b/avahi-core/browse-dns-server.c @@ -157,15 +157,21 @@ AvahiDNSServerBrowser *avahi_dns_server_browser_new(AvahiServer *server, AvahiIf g_assert(callback); g_assert(type == AVAHI_DNS_SERVER_RESOLVE || type == AVAHI_DNS_SERVER_UPDATE); + if (domain && !avahi_valid_domain_name(domain)) { + avahi_server_set_errno(server, AVAHI_ERR_INVALID_DOMAIN_NAME); + return NULL; + } + b = g_new(AvahiDNSServerBrowser, 1); b->server = server; - b->domain_name = avahi_normalize_name(domain ? domain : "local."); + b->domain_name = avahi_normalize_name(domain ? domain : "local"); b->callback = callback; b->userdata = userdata; b->aprotocol = aprotocol; b->n_info = 0; AVAHI_LLIST_HEAD_INIT(AvahiDNSServerInfo, b->info); + AVAHI_LLIST_PREPEND(AvahiDNSServerBrowser, browser, server->dns_server_browsers, b); n = g_strdup_printf("%s.%s",type == AVAHI_DNS_SERVER_RESOLVE ? "_domain._udp" : "_dns-update._udp", b->domain_name); k = avahi_key_new(n, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_SRV); @@ -174,7 +180,10 @@ AvahiDNSServerBrowser *avahi_dns_server_browser_new(AvahiServer *server, AvahiIf b->record_browser = avahi_record_browser_new(server, interface, protocol, k, record_browser_callback, b); avahi_key_unref(k); - AVAHI_LLIST_PREPEND(AvahiDNSServerBrowser, browser, server->dns_server_browsers, b); + if (!b->record_browser) { + avahi_dns_server_browser_free(b); + return NULL; + } return b; } @@ -187,7 +196,8 @@ void avahi_dns_server_browser_free(AvahiDNSServerBrowser *b) { AVAHI_LLIST_REMOVE(AvahiDNSServerBrowser, browser, b->server->dns_server_browsers, b); - avahi_record_browser_free(b->record_browser); + if (b->record_browser) + avahi_record_browser_free(b->record_browser); g_free(b->domain_name); g_free(b); } diff --git a/avahi-core/browse-domain.c b/avahi-core/browse-domain.c index c6331b4..de3cb1b 100644 --- a/avahi-core/browse-domain.c +++ b/avahi-core/browse-domain.c @@ -60,6 +60,12 @@ AvahiDomainBrowser *avahi_domain_browser_new(AvahiServer *server, AvahiIfIndex i g_assert(server); g_assert(callback); + g_assert(type >= AVAHI_DOMAIN_BROWSER_BROWSE && type <= AVAHI_DOMAIN_BROWSER_BROWSE_LEGACY); + + if (domain && !avahi_valid_domain_name(domain)) { + avahi_server_set_errno(server, AVAHI_ERR_INVALID_DOMAIN_NAME); + return NULL; + } b = g_new(AvahiDomainBrowser, 1); b->server = server; @@ -67,6 +73,8 @@ AvahiDomainBrowser *avahi_domain_browser_new(AvahiServer *server, AvahiIfIndex i b->callback = callback; b->userdata = userdata; + AVAHI_LLIST_PREPEND(AvahiDomainBrowser, browser, server->domain_browsers, b); + switch (type) { case AVAHI_DOMAIN_BROWSER_BROWSE: n = g_strdup_printf("b._dns-sd._udp.%s", b->domain_name); @@ -97,7 +105,10 @@ AvahiDomainBrowser *avahi_domain_browser_new(AvahiServer *server, AvahiIfIndex i b->record_browser = avahi_record_browser_new(server, interface, protocol, k, record_browser_callback, b); avahi_key_unref(k); - AVAHI_LLIST_PREPEND(AvahiDomainBrowser, browser, server->domain_browsers, b); + if (!b->record_browser) { + avahi_domain_browser_free(b); + return NULL; + } return b; } @@ -107,7 +118,9 @@ void avahi_domain_browser_free(AvahiDomainBrowser *b) { AVAHI_LLIST_REMOVE(AvahiDomainBrowser, browser, b->server->domain_browsers, b); - avahi_record_browser_free(b->record_browser); + if (b->record_browser) + avahi_record_browser_free(b->record_browser); + g_free(b->domain_name); g_free(b); } diff --git a/avahi-core/browse-service-type.c b/avahi-core/browse-service-type.c index 7cd6cf7..3534b6f 100644 --- a/avahi-core/browse-service-type.c +++ b/avahi-core/browse-service-type.c @@ -90,12 +90,18 @@ AvahiServiceTypeBrowser *avahi_service_type_browser_new(AvahiServer *server, gin g_assert(server); g_assert(callback); + if (domain && !avahi_valid_domain_name(domain)) { + avahi_server_set_errno(server, AVAHI_ERR_INVALID_DOMAIN_NAME); + return NULL; + } + b = g_new(AvahiServiceTypeBrowser, 1); b->server = server; b->domain_name = avahi_normalize_name(domain ? domain : "local"); b->callback = callback; b->userdata = userdata; + AVAHI_LLIST_PREPEND(AvahiServiceTypeBrowser, browser, server->service_type_browsers, b); n = g_strdup_printf("_services._dns-sd._udp.%s", b->domain_name); k = avahi_key_new(n, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_PTR); @@ -104,7 +110,8 @@ AvahiServiceTypeBrowser *avahi_service_type_browser_new(AvahiServer *server, gin b->record_browser = avahi_record_browser_new(server, interface, protocol, k, record_browser_callback, b); avahi_key_unref(k); - AVAHI_LLIST_PREPEND(AvahiServiceTypeBrowser, browser, server->service_type_browsers, b); + if (!b->record_browser) + return NULL; return b; } @@ -114,7 +121,9 @@ void avahi_service_type_browser_free(AvahiServiceTypeBrowser *b) { AVAHI_LLIST_REMOVE(AvahiServiceTypeBrowser, browser, b->server->service_type_browsers, b); - avahi_record_browser_free(b->record_browser); + if (b->record_browser) + avahi_record_browser_free(b->record_browser); + g_free(b->domain_name); g_free(b); } diff --git a/avahi-core/browse-service.c b/avahi-core/browse-service.c index f72ce6c..34a2536 100644 --- a/avahi-core/browse-service.c +++ b/avahi-core/browse-service.c @@ -93,21 +93,36 @@ AvahiServiceBrowser *avahi_service_browser_new(AvahiServer *server, AvahiIfIndex g_assert(callback); g_assert(service_type); + if (!avahi_valid_service_type(service_type)) { + avahi_server_set_errno(server, AVAHI_ERR_INVALID_SERVICE_TYPE); + return NULL; + } + + if (domain && !avahi_valid_domain_name(domain)) { + avahi_server_set_errno(server, AVAHI_ERR_INVALID_DOMAIN_NAME); + return NULL; + } + b = g_new(AvahiServiceBrowser, 1); b->server = server; b->domain_name = avahi_normalize_name(domain ? domain : "local"); b->service_type = avahi_normalize_name(service_type); b->callback = callback; b->userdata = userdata; + AVAHI_LLIST_PREPEND(AvahiServiceBrowser, browser, server->service_browsers, b); n = g_strdup_printf("%s.%s", b->service_type, b->domain_name); k = avahi_key_new(n, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_PTR); g_free(n); b->record_browser = avahi_record_browser_new(server, interface, protocol, k, record_browser_callback, b); + avahi_key_unref(k); - AVAHI_LLIST_PREPEND(AvahiServiceBrowser, browser, server->service_browsers, b); + if (!b->record_browser) { + avahi_service_browser_free(b); + return NULL; + } return b; } @@ -117,7 +132,9 @@ void avahi_service_browser_free(AvahiServiceBrowser *b) { AVAHI_LLIST_REMOVE(AvahiServiceBrowser, browser, b->server->service_browsers, b); - avahi_record_browser_free(b->record_browser); + if (b->record_browser) + avahi_record_browser_free(b->record_browser); + g_free(b->domain_name); g_free(b->service_type); g_free(b); diff --git a/avahi-core/browse.c b/avahi-core/browse.c index 5f4d216..5885cb4 100644 --- a/avahi-core/browse.c +++ b/avahi-core/browse.c @@ -124,7 +124,15 @@ AvahiRecordBrowser *avahi_record_browser_new(AvahiServer *server, AvahiIfIndex i g_assert(key); g_assert(callback); - g_assert(!avahi_key_is_pattern(key)); + if (avahi_key_is_pattern(key)) { + avahi_server_set_errno(server, AVAHI_ERR_IS_PATTERN); + return NULL; + } + + if (!avahi_key_valid(key)) { + avahi_server_set_errno(server, AVAHI_ERR_INVALID_KEY); + return NULL; + } b = g_new(AvahiRecordBrowser, 1); b->dead = FALSE; diff --git a/avahi-core/conformance-test.c b/avahi-core/conformance-test.c index ccc9a12..13704c3 100644 --- a/avahi-core/conformance-test.c +++ b/avahi-core/conformance-test.c @@ -101,8 +101,9 @@ static void server_callback(AvahiServer *s, AvahiServerState state, gpointer use int main(int argc, char *argv[]) { GMainLoop *loop = NULL; + gint error; - avahi = avahi_server_new(NULL, NULL, server_callback, NULL); + avahi = avahi_server_new(NULL, NULL, server_callback, NULL, &error); loop = g_main_loop_new(NULL, FALSE); g_timeout_add(1000*5, dump_timeout, avahi); diff --git a/avahi-core/core.h b/avahi-core/core.h index 25e9c0a..1adf244 100644 --- a/avahi-core/core.h +++ b/avahi-core/core.h @@ -35,7 +35,9 @@ #include +#ifndef DOXYGEN_SHOULD_SKIP_THIS AVAHI_C_DECL_BEGIN +#endif /** An mDNS responder object */ typedef struct AvahiServer AvahiServer; @@ -46,19 +48,42 @@ typedef struct AvahiEntry AvahiEntry; /** A group of locally registered DNS RRs */ typedef struct AvahiEntryGroup AvahiEntryGroup; +#ifndef DOXYGEN_SHOULD_SKIP_THIS AVAHI_C_DECL_END +#endif #include #include #include +#ifndef DOXYGEN_SHOULD_SKIP_THIS AVAHI_C_DECL_BEGIN +#endif /** Error codes used by avahi */ enum { - AVAHI_OK = 0, /**< OK */ - AVAHI_ERR_FAILURE = -1, /**< Generic error code */ - AVAHI_ERR_BAD_STATE = -2 /**< Object was in a bad state */ + AVAHI_OK = 0, /**< OK */ + AVAHI_ERR_FAILURE = -1, /**< Generic error code */ + AVAHI_ERR_BAD_STATE = -2, /**< Object was in a bad state */ + AVAHI_ERR_INVALID_HOST_NAME = -3, /**< Invalid host name */ + AVAHI_ERR_INVALID_DOMAIN_NAME = -4, /**< Invalid domain name */ + AVAHI_ERR_NO_NETWORK = -5, /**< No suitable network protocol available */ + AVAHI_ERR_INVALID_TTL = -6, /**< Invalid DNS TTL */ + AVAHI_ERR_IS_PATTERN = -7, /**< RR key is pattern */ + AVAHI_ERR_LOCAL_COLLISION = -8, /**< Local name collision */ + AVAHI_ERR_INVALID_RECORD = -9, /**< Invalid RR */ + AVAHI_ERR_INVALID_SERVICE_NAME = -10, /**< Invalid service name */ + AVAHI_ERR_INVALID_SERVICE_TYPE = -11, /**< Invalid service type */ + AVAHI_ERR_INVALID_PORT = -12, /**< Invalid port number */ + AVAHI_ERR_INVALID_KEY = -13, /**< Invalid key */ + AVAHI_ERR_INVALID_ADDRESS = -14, /**< Invalid address */ + AVAHI_ERR_TIMEOUT = -15, /**< Timeout reached */ + AVAHI_ERR_TOO_MANY_CLIENTS = -16, /**< Too many clients */ + AVAHI_ERR_TOO_MANY_OBJECTS = -17, /**< Too many objects */ + AVAHI_ERR_TOO_MANY_ENTRIES = -18, /**< Too many entries */ + AVAHI_ERR_OS = -19, /**< OS error */ + AVAHI_ERR_ACCESS_DENIED = -20, /**< Access denied */ + AVAHI_ERR_MAX = -21 }; /** States of a server object */ @@ -113,7 +138,8 @@ 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. The server makes an internal deep copy of this structure, so you may free it using avahi_server_config_done() immediately after calling this function. */ 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 */); + gpointer userdata, /**< An opaque pointer which is passed to the callback function */ + gint *error); /** Free an mDNS responder object */ void avahi_server_free(AvahiServer* s); @@ -603,6 +629,14 @@ AvahiDNSServerBrowser *avahi_dns_server_browser_new( /** Free an AvahiDNSServerBrowser object */ void avahi_dns_server_browser_free(AvahiDNSServerBrowser *b); +/** Return a human readable error string for the specified error code */ +const gchar *avahi_strerror(gint error); + +/** Return the last error code */ +gint avahi_server_errno(AvahiServer *s); + +#ifndef DOXYGEN_SHOULD_SKIP_THIS AVAHI_C_DECL_END +#endif #endif diff --git a/avahi-core/resolve-address.c b/avahi-core/resolve-address.c index d315ac9..89f9bcf 100644 --- a/avahi-core/resolve-address.c +++ b/avahi-core/resolve-address.c @@ -111,6 +111,11 @@ AvahiAddressResolver *avahi_address_resolver_new(AvahiServer *server, AvahiIfInd r->record_browser = avahi_record_browser_new(server, interface, protocol, k, record_browser_callback, r); avahi_key_unref(k); + + if (!r->record_browser) { + avahi_address_resolver_free(r); + return NULL; + } return r; } diff --git a/avahi-core/resolve-host-name.c b/avahi-core/resolve-host-name.c index 0ab2e73..c18722d 100644 --- a/avahi-core/resolve-host-name.c +++ b/avahi-core/resolve-host-name.c @@ -115,6 +115,11 @@ AvahiHostNameResolver *avahi_host_name_resolver_new(AvahiServer *server, AvahiIf g_assert(aprotocol == AVAHI_PROTO_UNSPEC || aprotocol == AVAHI_PROTO_INET || aprotocol == AVAHI_PROTO_INET6); + if (!avahi_valid_domain_name(host_name)) { + avahi_server_set_errno(server, AVAHI_ERR_INVALID_HOST_NAME); + return NULL; + } + r = g_new(AvahiHostNameResolver, 1); r->server = server; r->host_name = avahi_normalize_name(host_name); @@ -127,20 +132,34 @@ AvahiHostNameResolver *avahi_host_name_resolver_new(AvahiServer *server, AvahiIf r->time_event = avahi_time_event_queue_add(server->time_event_queue, &tv, time_event_callback, r); AVAHI_LLIST_PREPEND(AvahiHostNameResolver, resolver, server->host_name_resolvers, r); + + r->record_browser_aaaa = r->record_browser_a = NULL; if (aprotocol == AVAHI_PROTO_INET || aprotocol == AVAHI_PROTO_UNSPEC) { k = avahi_key_new(host_name, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_A); r->record_browser_a = avahi_record_browser_new(server, interface, protocol, k, record_browser_callback, r); avahi_key_unref(k); + + if (!r->record_browser_a) + goto fail; } if (aprotocol == AVAHI_PROTO_INET6 || aprotocol == AVAHI_PROTO_UNSPEC) { k = avahi_key_new(host_name, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_AAAA); r->record_browser_aaaa = avahi_record_browser_new(server, interface, protocol, k, record_browser_callback, r); avahi_key_unref(k); + + if (!r->record_browser_aaaa) + goto fail; } - + + g_assert(r->record_browser_aaaa || r->record_browser_a); + return r; + +fail: + avahi_host_name_resolver_free(r); + return NULL; } void avahi_host_name_resolver_free(AvahiHostNameResolver *r) { diff --git a/avahi-core/resolve-service.c b/avahi-core/resolve-service.c index b15af4f..2ad38f8 100644 --- a/avahi-core/resolve-service.c +++ b/avahi-core/resolve-service.c @@ -206,6 +206,21 @@ AvahiServiceResolver *avahi_service_resolver_new(AvahiServer *server, AvahiIfInd g_assert(aprotocol == AVAHI_PROTO_UNSPEC || aprotocol == AVAHI_PROTO_INET || aprotocol == AVAHI_PROTO_INET6); + if (!avahi_valid_service_name(name)) { + avahi_server_set_errno(server, AVAHI_ERR_INVALID_SERVICE_NAME); + return NULL; + } + + if (!avahi_valid_service_type(type)) { + avahi_server_set_errno(server, AVAHI_ERR_INVALID_SERVICE_TYPE); + return NULL; + } + + if (!avahi_valid_domain_name(domain)) { + avahi_server_set_errno(server, AVAHI_ERR_INVALID_DOMAIN_NAME); + return NULL; + } + r = g_new(AvahiServiceResolver, 1); r->server = server; r->service_name = g_strdup(name); @@ -234,10 +249,20 @@ AvahiServiceResolver *avahi_service_resolver_new(AvahiServer *server, AvahiIfInd r->record_browser_srv = avahi_record_browser_new(server, interface, protocol, k, record_browser_callback, r); avahi_key_unref(k); + if (!r->record_browser_srv) { + avahi_service_resolver_free(r); + return NULL; + } + k = avahi_key_new(t, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_TXT); r->record_browser_txt = avahi_record_browser_new(server, interface, protocol, k, record_browser_callback, r); avahi_key_unref(k); - + + if (!r->record_browser_txt) { + avahi_service_resolver_free(r); + return NULL; + } + return r; } diff --git a/avahi-core/server.c b/avahi-core/server.c index 3c38507..c4acf35 100644 --- a/avahi-core/server.c +++ b/avahi-core/server.c @@ -259,6 +259,7 @@ static void incoming_probe(AvahiServer *s, AvahiRecord *record, AvahiInterface * } } + if (!ours) { if (won) @@ -1221,6 +1222,9 @@ gint avahi_server_set_host_name(AvahiServer *s, const gchar *host_name) { g_assert(s); g_assert(host_name); + if (host_name && !avahi_valid_host_name(host_name)) + return avahi_server_set_errno(s, AVAHI_ERR_INVALID_HOST_NAME); + withdraw_host_rrs(s); g_free(s->host_name); @@ -1236,6 +1240,9 @@ gint avahi_server_set_domain_name(AvahiServer *s, const gchar *domain_name) { g_assert(s); g_assert(domain_name); + if (domain_name && !avahi_valid_domain_name(domain_name)) + return avahi_server_set_errno(s, AVAHI_ERR_INVALID_DOMAIN_NAME); + withdraw_host_rrs(s); g_free(s->domain_name); @@ -1257,8 +1264,20 @@ static void prepare_pollfd(AvahiServer *s, GPollFD *pollfd, gint fd) { g_source_add_poll(s->source, pollfd); } -AvahiServer *avahi_server_new(GMainContext *c, const AvahiServerConfig *sc, AvahiServerCallback callback, gpointer userdata) { +static gint valid_server_config(const AvahiServerConfig *sc) { + + if (sc->host_name && !avahi_valid_host_name(sc->host_name)) + return AVAHI_ERR_INVALID_HOST_NAME; + + if (sc->domain_name && !avahi_valid_domain_name(sc->domain_name)) + return AVAHI_ERR_INVALID_DOMAIN_NAME; + + return AVAHI_OK; +} + +AvahiServer *avahi_server_new(GMainContext *c, const AvahiServerConfig *sc, AvahiServerCallback callback, gpointer userdata, gint *error) { AvahiServer *s; + gint e; static GSourceFuncs source_funcs = { prepare_func, @@ -1269,6 +1288,12 @@ AvahiServer *avahi_server_new(GMainContext *c, const AvahiServerConfig *sc, Avah NULL }; + if ((e = valid_server_config(sc)) < 0) { + if (error) + *error = e; + return NULL; + } + s = g_new(AvahiServer, 1); s->n_host_rr_pending = 0; s->need_entry_cleanup = s->need_group_cleanup = s->need_browser_cleanup = FALSE; @@ -1282,9 +1307,12 @@ AvahiServer *avahi_server_new(GMainContext *c, const AvahiServerConfig *sc, Avah s->fd_ipv6 = s->config.use_ipv6 ? avahi_open_socket_ipv6() : -1; if (s->fd_ipv6 < 0 && s->fd_ipv4 < 0) { - g_critical("Selected neither IPv6 nor IPv4 support, aborting.\n"); avahi_server_config_free(&s->config); g_free(s); + + if (error) + *error = AVAHI_ERR_NO_NETWORK; + return NULL; } @@ -1354,6 +1382,8 @@ AvahiServer *avahi_server_new(GMainContext *c, const AvahiServerConfig *sc, Avah s->hinfo_entry_group = NULL; s->browse_domain_entry_group = NULL; register_stuff(s); + + s->error = AVAHI_OK; return s; } @@ -1461,13 +1491,16 @@ gint avahi_server_add( g_assert(r); if (r->ttl == 0) - return -1; + return avahi_server_set_errno(s, AVAHI_ERR_INVALID_TTL); if (avahi_key_is_pattern(r->key)) - return -1; + return avahi_server_set_errno(s, AVAHI_ERR_IS_PATTERN); + + if (!avahi_record_valid(r)) + return avahi_server_set_errno(s, AVAHI_ERR_INVALID_RECORD); if (check_record_conflict(s, interface, protocol, r, flags) < 0) - return -1; + return avahi_server_set_errno(s, AVAHI_ERR_LOCAL_COLLISION); e = g_new(AvahiEntry, 1); e->server = s; @@ -1551,6 +1584,7 @@ gint avahi_server_add_ptr( AvahiRecord *r; gint ret; + g_assert(s); g_assert(dest); r = avahi_record_new_full(name ? name : s->host_name_fqdn, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_PTR, ttl); @@ -1570,11 +1604,16 @@ gint avahi_server_add_address( AvahiAddress *a) { gchar *n = NULL; - gint ret = 0; + gint ret = AVAHI_OK; g_assert(s); g_assert(a); name = name ? (n = avahi_normalize_name(name)) : s->host_name_fqdn; + + if (!avahi_valid_domain_name(name)) { + avahi_server_set_errno(s, AVAHI_ERR_INVALID_HOST_NAME); + goto fail; + } if (a->family == AVAHI_PROTO_INET) { gchar *reverse; @@ -1584,11 +1623,14 @@ gint avahi_server_add_address( r->data.a.address = a->data.ipv4; ret = avahi_server_add(s, g, interface, protocol, flags | AVAHI_ENTRY_UNIQUE | AVAHI_ENTRY_ALLOWMUTIPLE, r); avahi_record_unref(r); + + if (ret < 0) + goto fail; reverse = avahi_reverse_lookup_name_ipv4(&a->data.ipv4); - ret |= avahi_server_add_ptr(s, g, interface, protocol, flags | AVAHI_ENTRY_UNIQUE, AVAHI_DEFAULT_TTL_HOST_NAME, reverse, name); + ret = avahi_server_add_ptr(s, g, interface, protocol, flags | AVAHI_ENTRY_UNIQUE, AVAHI_DEFAULT_TTL_HOST_NAME, reverse, name); g_free(reverse); - + } else { gchar *reverse; AvahiRecord *r; @@ -1598,14 +1640,22 @@ gint avahi_server_add_address( ret = avahi_server_add(s, g, interface, protocol, flags | AVAHI_ENTRY_UNIQUE | AVAHI_ENTRY_ALLOWMUTIPLE, r); avahi_record_unref(r); + if (ret < 0) + goto fail; + reverse = avahi_reverse_lookup_name_ipv6_arpa(&a->data.ipv6); - ret |= avahi_server_add_ptr(s, g, interface, protocol, flags | AVAHI_ENTRY_UNIQUE, AVAHI_DEFAULT_TTL_HOST_NAME, reverse, name); + ret = avahi_server_add_ptr(s, g, interface, protocol, flags | AVAHI_ENTRY_UNIQUE, AVAHI_DEFAULT_TTL_HOST_NAME, reverse, name); g_free(reverse); + + if (ret < 0) + goto fail; reverse = avahi_reverse_lookup_name_ipv6_int(&a->data.ipv6); - ret |= avahi_server_add_ptr(s, g, interface, protocol, flags | AVAHI_ENTRY_UNIQUE, AVAHI_DEFAULT_TTL_HOST_NAME, reverse, name); + ret = avahi_server_add_ptr(s, g, interface, protocol, flags | AVAHI_ENTRY_UNIQUE, AVAHI_DEFAULT_TTL_HOST_NAME, reverse, name); g_free(reverse); } + +fail: g_free(n); @@ -1645,6 +1695,8 @@ gint avahi_server_add_txt_strlst( const gchar *name, AvahiStringList *strlst) { + g_assert(s); + return server_add_txt_strlst_nocopy(s, g, interface, protocol, flags, ttl, name, avahi_string_list_copy(strlst)); } @@ -1721,19 +1773,31 @@ static gint server_add_service_strlst_nocopy( gchar ptr_name[256], svc_name[256], ename[64], enum_ptr[256]; gchar *t, *d; - AvahiRecord *r; + AvahiRecord *r = NULL; gint ret = 0; g_assert(s); g_assert(type); g_assert(name); + if (!avahi_valid_service_name(name)) + return avahi_server_set_errno(s, AVAHI_ERR_INVALID_SERVICE_NAME); + + if (!avahi_valid_service_type(type)) + return avahi_server_set_errno(s, AVAHI_ERR_INVALID_SERVICE_TYPE); + + if (domain && !avahi_valid_domain_name(domain)) + return avahi_server_set_errno(s, AVAHI_ERR_INVALID_DOMAIN_NAME); + + if (host && !avahi_valid_domain_name(host)) + return avahi_server_set_errno(s, AVAHI_ERR_INVALID_HOST_NAME); + + if (port == 0) + return avahi_server_set_errno(s, AVAHI_ERR_INVALID_PORT); + escape_service_name(ename, sizeof(ename), name); - if (domain) { - while (domain[0] == '.') - domain++; - } else + if (!domain) domain = s->domain_name; if (!host) @@ -1745,23 +1809,35 @@ static gint server_add_service_strlst_nocopy( g_snprintf(ptr_name, sizeof(ptr_name), "%s.%s", t, d); g_snprintf(svc_name, sizeof(svc_name), "%s.%s.%s", ename, t, d); - ret = avahi_server_add_ptr(s, g, interface, protocol, AVAHI_ENTRY_NULL, AVAHI_DEFAULT_TTL, ptr_name, svc_name); + if ((ret = avahi_server_add_ptr(s, g, interface, protocol, AVAHI_ENTRY_NULL, AVAHI_DEFAULT_TTL, ptr_name, svc_name)) < 0) + goto fail; r = avahi_record_new_full(svc_name, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_SRV, AVAHI_DEFAULT_TTL_HOST_NAME); r->data.srv.priority = 0; r->data.srv.weight = 0; r->data.srv.port = port; r->data.srv.name = avahi_normalize_name(host); - ret |= avahi_server_add(s, g, interface, protocol, AVAHI_ENTRY_UNIQUE, r); + ret = avahi_server_add(s, g, interface, protocol, AVAHI_ENTRY_UNIQUE, r); avahi_record_unref(r); - ret |= server_add_txt_strlst_nocopy(s, g, interface, protocol, AVAHI_ENTRY_UNIQUE, AVAHI_DEFAULT_TTL, svc_name, strlst); + if (ret < 0) + goto fail; + + ret = server_add_txt_strlst_nocopy(s, g, interface, protocol, AVAHI_ENTRY_UNIQUE, AVAHI_DEFAULT_TTL, svc_name, strlst); + strlst = NULL; + + if (ret < 0) + goto fail; g_snprintf(enum_ptr, sizeof(enum_ptr), "_services._dns-sd._udp.%s", d); - ret |=avahi_server_add_ptr(s, g, interface, protocol, AVAHI_ENTRY_NULL, AVAHI_DEFAULT_TTL, enum_ptr, ptr_name); + ret = avahi_server_add_ptr(s, g, interface, protocol, AVAHI_ENTRY_NULL, AVAHI_DEFAULT_TTL, enum_ptr, ptr_name); +fail: + g_free(d); g_free(t); + + avahi_string_list_free(strlst); return ret; } @@ -1778,6 +1854,10 @@ gint avahi_server_add_service_strlst( guint16 port, AvahiStringList *strlst) { + g_assert(s); + g_assert(type); + g_assert(name); + return server_add_service_strlst_nocopy(s, g, interface, protocol, name, type, domain, host, port, avahi_string_list_copy(strlst)); } @@ -1866,6 +1946,12 @@ gint avahi_server_add_dns_server_address( g_assert(type == AVAHI_DNS_SERVER_UPDATE || type == AVAHI_DNS_SERVER_RESOLVE); g_assert(address->family == AVAHI_PROTO_INET || address->family == AVAHI_PROTO_INET6); + if (domain && !avahi_valid_domain_name(domain)) + return avahi_server_set_errno(s, AVAHI_ERR_INVALID_DOMAIN_NAME); + + if (port == 0) + return avahi_server_set_errno(s, AVAHI_ERR_INVALID_PORT); + if (address->family == AVAHI_PROTO_INET) { hexstring(n+3, sizeof(n)-3, &address->data, 4); r = avahi_record_new_full(n, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_A, AVAHI_DEFAULT_TTL_HOST_NAME); @@ -1878,10 +1964,11 @@ gint avahi_server_add_dns_server_address( ret = avahi_server_add(s, g, interface, protocol, AVAHI_ENTRY_UNIQUE | AVAHI_ENTRY_ALLOWMUTIPLE, r); avahi_record_unref(r); - - ret |= avahi_server_add_dns_server_name(s, g, interface, protocol, domain, type, n, port); - return ret; + if (ret < 0) + return ret; + + return avahi_server_add_dns_server_name(s, g, interface, protocol, domain, type, n, port); } gint avahi_server_add_dns_server_name( @@ -1902,10 +1989,13 @@ gint avahi_server_add_dns_server_name( g_assert(name); g_assert(type == AVAHI_DNS_SERVER_UPDATE || type == AVAHI_DNS_SERVER_RESOLVE); - if (domain) { - while (domain[0] == '.') - domain++; - } else + if (domain && !avahi_valid_domain_name(domain)) + return avahi_server_set_errno(s, AVAHI_ERR_INVALID_DOMAIN_NAME); + + if (port == 0) + return avahi_server_set_errno(s, AVAHI_ERR_INVALID_PORT); + + if (!domain) domain = s->domain_name; d = avahi_normalize_name(domain); @@ -1946,6 +2036,8 @@ void avahi_entry_group_change_state(AvahiEntryGroup *g, AvahiEntryGroupState sta if (g->state == state) return; + g_assert(state >= AVAHI_ENTRY_GROUP_UNCOMMITED && state <= AVAHI_ENTRY_GROUP_COLLISION); + g->state = state; if (g->callback) @@ -2031,7 +2123,7 @@ gint avahi_entry_group_commit(AvahiEntryGroup *g) { g_assert(!g->dead); if (g->state != AVAHI_ENTRY_GROUP_UNCOMMITED && g->state != AVAHI_ENTRY_GROUP_COLLISION) - return AVAHI_ERR_BAD_STATE; + return avahi_server_set_errno(g->server, AVAHI_ERR_BAD_STATE); g->n_register_try++; @@ -2201,3 +2293,47 @@ AvahiServerConfig* avahi_server_config_copy(AvahiServerConfig *ret, const AvahiS return ret; } + +const gchar *avahi_strerror(gint error) { + g_assert(-error >= 0 && -error < -AVAHI_ERR_MAX); + + const gchar * const msg[- AVAHI_ERR_MAX] = { + "OK", + "Operation failed", + "Bad state", + "Invalid host name", + "Invalid domain name", + "No suitable network protocol available", + "Invalid DNS TTL", + "Resource record key is pattern", + "Local name collision", + "Invalid record", + "Invalid service name", + "Invalid service type", + "Invalid port number", + "Invalid record key", + "Invalid address", + "Timeout reached", + "Too many clients", + "Too many objects", + "Too many entries", + "OS Error", + "Access denied" + }; + + return msg[-error]; +} + +gint avahi_server_errno(AvahiServer *s) { + g_assert(s); + + return s->error; +} + +/* Just for internal use */ +gint avahi_server_set_errno(AvahiServer *s, gint error) { + g_assert(s); + + return s->error = error; +} + diff --git a/avahi-core/server.h b/avahi-core/server.h index 7049f58..6572fbb 100644 --- a/avahi-core/server.h +++ b/avahi-core/server.h @@ -131,6 +131,8 @@ struct AvahiServer { /* Used for reflection of legacy unicast packets */ AvahiLegacyUnicastReflectSlot **legacy_unicast_reflect_slots; guint16 legacy_unicast_reflect_id; + + gint error; }; gboolean avahi_server_entry_match_interface(AvahiEntry *e, AvahiInterface *i); @@ -152,4 +154,6 @@ void avahi_host_rr_entry_group_callback(AvahiServer *s, AvahiEntryGroup *g, Avah void avahi_server_decrease_host_rr_pending(AvahiServer *s); void avahi_server_increase_host_rr_pending(AvahiServer *s); +gint avahi_server_set_errno(AvahiServer *s, gint error); + #endif diff --git a/avahi-daemon/dbus-protocol.c b/avahi-daemon/dbus-protocol.c index 311d664..a87712d 100644 --- a/avahi-daemon/dbus-protocol.c +++ b/avahi-daemon/dbus-protocol.c @@ -319,10 +319,37 @@ static Client *client_get(const gchar *name, gboolean create) { return client; } -static DBusHandlerResult respond_error(DBusConnection *c, DBusMessage *m, const gchar *error, const gchar *text) { +static DBusHandlerResult respond_error(DBusConnection *c, DBusMessage *m, gint error, const gchar *text) { DBusMessage *reply; - reply = dbus_message_new_error(m, error, text); + const gchar * const table[- AVAHI_ERR_MAX] = { + NULL, /* OK */ + AVAHI_DBUS_ERR_FAILURE, + AVAHI_DBUS_ERR_BAD_STATE, + AVAHI_DBUS_ERR_INVALID_HOST_NAME, + AVAHI_DBUS_ERR_INVALID_DOMAIN_NAME, + AVAHI_DBUS_ERR_NO_NETWORK, + AVAHI_DBUS_ERR_INVALID_TTL, + AVAHI_DBUS_ERR_IS_PATTERN, + AVAHI_DBUS_ERR_LOCAL_COLLISION, + AVAHI_DBUS_ERR_INVALID_RECORD, + AVAHI_DBUS_ERR_INVALID_SERVICE_NAME, + AVAHI_DBUS_ERR_INVALID_SERVICE_TYPE, + AVAHI_DBUS_ERR_INVALID_PORT, + AVAHI_DBUS_ERR_INVALID_KEY, + AVAHI_DBUS_ERR_INVALID_ADDRESS, + AVAHI_DBUS_ERR_TIMEOUT, + AVAHI_DBUS_ERR_TOO_MANY_CLIENTS, + AVAHI_DBUS_ERR_TOO_MANY_OBJECTS, + AVAHI_DBUS_ERR_TOO_MANY_ENTRIES, + AVAHI_DBUS_ERR_OS, + DBUS_ERROR_ACCESS_DENIED + }; + + g_assert(-error > -AVAHI_OK); + g_assert(-error < -AVAHI_ERR_MAX); + + reply = dbus_message_new_error(m, table[-error], text ? text : avahi_strerror(error)); dbus_connection_send(c, reply, NULL); dbus_message_unref(reply); @@ -467,7 +494,6 @@ fail: return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } - static void entry_group_callback(AvahiServer *s, AvahiEntryGroup *g, AvahiEntryGroupState state, gpointer userdata) { EntryGroupInfo *i = userdata; DBusMessage *m; @@ -506,7 +532,7 @@ static DBusHandlerResult msg_entry_group_impl(DBusConnection *c, DBusMessage *m, /* Access control */ if (strcmp(dbus_message_get_sender(m), i->client->name)) - return respond_error(c, m, DBUS_ERROR_ACCESS_DENIED, NULL); + return respond_error(c, m, AVAHI_ERR_ACCESS_DENIED, NULL); if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_ENTRY_GROUP, "Free")) { @@ -548,10 +574,10 @@ static DBusHandlerResult msg_entry_group_impl(DBusConnection *c, DBusMessage *m, goto fail; } - b = avahi_entry_group_is_empty(i->entry_group); - + b = !!avahi_entry_group_is_empty(i->entry_group); + reply = dbus_message_new_method_return(m); - dbus_message_append_args(m, DBUS_TYPE_BOOLEAN, &b, DBUS_TYPE_INVALID); + dbus_message_append_args(reply, DBUS_TYPE_BOOLEAN, &b, DBUS_TYPE_INVALID); dbus_connection_send(c, reply, NULL); dbus_message_unref(reply); @@ -584,7 +610,7 @@ static DBusHandlerResult msg_entry_group_impl(DBusConnection *c, DBusMessage *m, DBUS_TYPE_STRING, &host, DBUS_TYPE_UINT16, &port, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &txt, &txt_len, - DBUS_TYPE_INVALID) || !type || !*type || !name || !*name || !port) { + DBUS_TYPE_INVALID) || !type || !name) { avahi_log_warn("Error parsing EntryGroup::AddService message"); goto fail; } @@ -592,7 +618,7 @@ static DBusHandlerResult msg_entry_group_impl(DBusConnection *c, DBusMessage *m, if (i->n_entries >= MAX_ENTRIES_PER_ENTRY_GROUP) { avahi_log_warn("Too many entries per entry group, client request failed."); dbus_free_string_array(txt); - return respond_error(c, m, AVAHI_DBUS_ERROR_TOO_MANY_ENTRIES, NULL); + return respond_error(c, m, AVAHI_ERR_TOO_MANY_ENTRIES, NULL); } strlst = avahi_string_list_new_from_array((const gchar**) txt, txt_len); @@ -605,9 +631,8 @@ static DBusHandlerResult msg_entry_group_impl(DBusConnection *c, DBusMessage *m, host = NULL; if (avahi_server_add_service_strlst(avahi_server, i->entry_group, (AvahiIfIndex) interface, (AvahiProtocol) protocol, name, type, domain, host, port, strlst) < 0) { - avahi_log_warn("Failed to add service: %s", name); avahi_string_list_free(strlst); - return respond_error(c, m, AVAHI_DBUS_ERROR_INVALID_SERVICE, NULL); + return respond_error(c, m, avahi_server_errno(avahi_server), NULL); } else i->n_entries ++; @@ -626,25 +651,23 @@ static DBusHandlerResult msg_entry_group_impl(DBusConnection *c, DBusMessage *m, DBUS_TYPE_INT32, &protocol, DBUS_TYPE_STRING, &name, DBUS_TYPE_STRING, &address, - DBUS_TYPE_INVALID) || !name || !*name || !address || !*address) { + DBUS_TYPE_INVALID) || !name || !address) { avahi_log_warn("Error parsing EntryGroup::AddAddress message"); goto fail; } if (i->n_entries >= MAX_ENTRIES_PER_ENTRY_GROUP) { avahi_log_warn("Too many entries per entry group, client request failed."); - return respond_error(c, m, AVAHI_DBUS_ERROR_TOO_MANY_ENTRIES, NULL); + return respond_error(c, m, AVAHI_ERR_TOO_MANY_ENTRIES, NULL); } if (!(avahi_address_parse(address, AVAHI_PROTO_UNSPEC, &a))) { - avahi_log_warn("Error parsing address data"); - return respond_error(c, m, AVAHI_DBUS_ERROR_INVALID_ADDRESS, NULL); + return respond_error(c, m, AVAHI_ERR_INVALID_ADDRESS, NULL); } - if (avahi_server_add_address(avahi_server, i->entry_group, (AvahiIfIndex) interface, (AvahiProtocol) protocol, 0, name, &a) < 0) { - avahi_log_warn("Failed to add service: %s", name); - return respond_error(c, m, AVAHI_DBUS_ERROR_INVALID_ADDRESS, NULL); - } else + if (avahi_server_add_address(avahi_server, i->entry_group, (AvahiIfIndex) interface, (AvahiProtocol) protocol, 0, name, &a) < 0) + return respond_error(c, m, avahi_server_errno(avahi_server), NULL); + else i->n_entries ++; return respond_ok(c, m); @@ -661,7 +684,6 @@ fail: static void host_name_resolver_callback(AvahiHostNameResolver *r, AvahiIfIndex interface, AvahiProtocol protocol, AvahiResolverEvent event, const gchar *host_name, const AvahiAddress *a, gpointer userdata) { HostNameResolverInfo *i = userdata; - DBusMessage *reply; g_assert(r); g_assert(host_name); @@ -670,6 +692,7 @@ static void host_name_resolver_callback(AvahiHostNameResolver *r, AvahiIfIndex i if (event == AVAHI_RESOLVER_FOUND) { char t[256], *pt = t; gint32 i_interface, i_protocol, i_aprotocol; + DBusMessage *reply; g_assert(a); avahi_address_snprint(t, sizeof(t), a); @@ -688,20 +711,19 @@ static void host_name_resolver_callback(AvahiHostNameResolver *r, AvahiIfIndex i DBUS_TYPE_STRING, &pt, DBUS_TYPE_INVALID); + dbus_connection_send(server->bus, reply, NULL); + dbus_message_unref(reply); } else { g_assert(event == AVAHI_RESOLVER_TIMEOUT); - reply = dbus_message_new_error(i->message, AVAHI_DBUS_ERROR_TIMEOUT, NULL); - } - dbus_connection_send(server->bus, reply, NULL); - dbus_message_unref(reply); + respond_error(server->bus, i->message, AVAHI_ERR_TIMEOUT, NULL); + } host_name_resolver_free(i); } static void address_resolver_callback(AvahiAddressResolver *r, AvahiIfIndex interface, AvahiProtocol protocol, AvahiResolverEvent event, const AvahiAddress *address, const gchar *host_name, gpointer userdata) { AddressResolverInfo *i = userdata; - DBusMessage *reply; g_assert(r); g_assert(address); @@ -710,6 +732,7 @@ static void address_resolver_callback(AvahiAddressResolver *r, AvahiIfIndex inte if (event == AVAHI_RESOLVER_FOUND) { char t[256], *pt = t; gint32 i_interface, i_protocol, i_aprotocol; + DBusMessage *reply; g_assert(host_name); avahi_address_snprint(t, sizeof(t), address); @@ -728,14 +751,13 @@ static void address_resolver_callback(AvahiAddressResolver *r, AvahiIfIndex inte DBUS_TYPE_STRING, &host_name, DBUS_TYPE_INVALID); + dbus_connection_send(server->bus, reply, NULL); + dbus_message_unref(reply); } else { g_assert(event == AVAHI_RESOLVER_TIMEOUT); - reply = dbus_message_new_error(i->message, AVAHI_DBUS_ERROR_TIMEOUT, NULL); + respond_error(server->bus, i->message, AVAHI_ERR_TIMEOUT, NULL); } - dbus_connection_send(server->bus, reply, NULL); - dbus_message_unref(reply); - address_resolver_free(i); } @@ -760,7 +782,7 @@ static DBusHandlerResult msg_domain_browser_impl(DBusConnection *c, DBusMessage /* Access control */ if (strcmp(dbus_message_get_sender(m), i->client->name)) - return respond_error(c, m, DBUS_ERROR_ACCESS_DENIED, NULL); + return respond_error(c, m, AVAHI_ERR_ACCESS_DENIED, NULL); if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_DOMAIN_BROWSER, "Free")) { @@ -828,7 +850,7 @@ static DBusHandlerResult msg_service_type_browser_impl(DBusConnection *c, DBusMe /* Access control */ if (strcmp(dbus_message_get_sender(m), i->client->name)) - return respond_error(c, m, DBUS_ERROR_ACCESS_DENIED, NULL); + return respond_error(c, m, AVAHI_ERR_ACCESS_DENIED, NULL); if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_SERVICE_TYPE_BROWSER, "Free")) { @@ -894,11 +916,11 @@ static DBusHandlerResult msg_service_browser_impl(DBusConnection *c, DBusMessage /* Introspection */ if (dbus_message_is_method_call(m, DBUS_INTERFACE_INTROSPECTABLE, "Introspect")) - return handle_introspect(c, m, "ServiceBrowser.introspect"); + return handle_introspect(c, m, "ServiceBrowser.Introspect"); /* Access control */ if (strcmp(dbus_message_get_sender(m), i->client->name)) - return respond_error(c, m, DBUS_ERROR_ACCESS_DENIED, NULL); + return respond_error(c, m, AVAHI_ERR_ACCESS_DENIED, NULL); if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_SERVICE_BROWSER, "Free")) { @@ -964,7 +986,6 @@ static void service_resolver_callback( gpointer userdata) { ServiceResolverInfo *i = userdata; - DBusMessage *reply; g_assert(r); g_assert(i); @@ -975,6 +996,7 @@ static void service_resolver_callback( gchar **array; guint n, j; AvahiStringList *p; + DBusMessage *reply; g_assert(host_name); @@ -1009,18 +1031,17 @@ static void service_resolver_callback( for (j = 0; j < n; j++) g_free(array[j]); + dbus_connection_send(server->bus, reply, NULL); + dbus_message_unref(reply); } else { g_assert(event == AVAHI_RESOLVER_TIMEOUT); - reply = dbus_message_new_error(i->message, AVAHI_DBUS_ERROR_TIMEOUT, NULL); - } - dbus_connection_send(server->bus, reply, NULL); - dbus_message_unref(reply); + respond_error(server->bus, i->message, AVAHI_ERR_TIMEOUT, NULL); + } service_resolver_free(i); } - static DBusHandlerResult msg_server_impl(DBusConnection *c, DBusMessage *m, void *userdata) { DBusError error; @@ -1092,7 +1113,7 @@ static DBusHandlerResult msg_server_impl(DBusConnection *c, DBusMessage *m, void if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { gchar txt[256]; g_snprintf(txt, sizeof(txt), "OS Error: %s", strerror(errno)); - return respond_error(c, m, AVAHI_DBUS_ERROR_OS, txt); + return respond_error(c, m, AVAHI_ERR_OS, txt); } memset(&ifr, 0, sizeof(ifr)); @@ -1102,7 +1123,7 @@ static DBusHandlerResult msg_server_impl(DBusConnection *c, DBusMessage *m, void gchar txt[256]; g_snprintf(txt, sizeof(txt), "OS Error: %s", strerror(errno)); close(fd); - return respond_error(c, m, AVAHI_DBUS_ERROR_OS, txt); + return respond_error(c, m, AVAHI_ERR_OS, txt); } close(fd); @@ -1114,7 +1135,7 @@ static DBusHandlerResult msg_server_impl(DBusConnection *c, DBusMessage *m, void int fd; struct ifreq ifr; - if (!(dbus_message_get_args(m, &error, DBUS_TYPE_STRING, &n, DBUS_TYPE_INVALID)) || !n || !*n) { + if (!(dbus_message_get_args(m, &error, DBUS_TYPE_STRING, &n, DBUS_TYPE_INVALID)) || !n) { avahi_log_warn("Error parsing Server::GetNetworkInterfaceIndexByName message"); goto fail; } @@ -1122,7 +1143,7 @@ static DBusHandlerResult msg_server_impl(DBusConnection *c, DBusMessage *m, void if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { gchar txt[256]; g_snprintf(txt, sizeof(txt), "OS Error: %s", strerror(errno)); - return respond_error(c, m, AVAHI_DBUS_ERROR_OS, txt); + return respond_error(c, m, AVAHI_ERR_OS, txt); } memset(&ifr, 0, sizeof(ifr)); @@ -1132,7 +1153,7 @@ static DBusHandlerResult msg_server_impl(DBusConnection *c, DBusMessage *m, void gchar txt[256]; g_snprintf(txt, sizeof(txt), "OS Error: %s", strerror(errno)); close(fd); - return respond_error(c, m, AVAHI_DBUS_ERROR_OS, txt); + return respond_error(c, m, AVAHI_ERR_OS, txt); } close(fd); @@ -1142,7 +1163,7 @@ static DBusHandlerResult msg_server_impl(DBusConnection *c, DBusMessage *m, void } else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_SERVER, "GetAlternativeHostName")) { gchar *n, * t; - if (!(dbus_message_get_args(m, &error, DBUS_TYPE_STRING, &n, DBUS_TYPE_INVALID)) || !n || !*n) { + if (!(dbus_message_get_args(m, &error, DBUS_TYPE_STRING, &n, DBUS_TYPE_INVALID)) || !n) { avahi_log_warn("Error parsing Server::GetAlternativeHostName message"); goto fail; } @@ -1156,7 +1177,7 @@ static DBusHandlerResult msg_server_impl(DBusConnection *c, DBusMessage *m, void } else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_SERVER, "GetAlternativeServiceName")) { gchar *n, *t; - if (!(dbus_message_get_args(m, &error, DBUS_TYPE_STRING, &n, DBUS_TYPE_INVALID)) || !n || !*n) { + if (!(dbus_message_get_args(m, &error, DBUS_TYPE_STRING, &n, DBUS_TYPE_INVALID)) || !n) { avahi_log_warn("Error parsing Server::GetAlternativeServiceName message"); goto fail; } @@ -1186,12 +1207,12 @@ static DBusHandlerResult msg_server_impl(DBusConnection *c, DBusMessage *m, void if (!(client = client_get(dbus_message_get_sender(m), TRUE))) { avahi_log_warn("Too many clients, client request failed."); - return respond_error(c, m, AVAHI_DBUS_ERROR_TOO_MANY_CLIENTS, NULL); + return respond_error(c, m, AVAHI_ERR_TOO_MANY_CLIENTS, NULL); } if (client->n_objects >= MAX_OBJECTS_PER_CLIENT) { avahi_log_warn("Too many objects for client '%s', client request failed.", client->name); - return respond_error(c, m, AVAHI_DBUS_ERROR_TOO_MANY_OBJECTS, NULL); + return respond_error(c, m, AVAHI_ERR_TOO_MANY_OBJECTS, NULL); } i = g_new(EntryGroupInfo, 1); @@ -1203,9 +1224,8 @@ static DBusHandlerResult msg_server_impl(DBusConnection *c, DBusMessage *m, void client->n_objects++; if (!(i->entry_group = avahi_entry_group_new(avahi_server, entry_group_callback, i))) { - avahi_log_warn("Failed to create entry group"); entry_group_free(i); - goto fail; + return respond_error(c, m, avahi_server_errno(avahi_server), NULL); } dbus_connection_register_object_path(c, i->path, &vtable, i); @@ -1223,19 +1243,19 @@ static DBusHandlerResult msg_server_impl(DBusConnection *c, DBusMessage *m, void DBUS_TYPE_INT32, &protocol, DBUS_TYPE_STRING, &name, DBUS_TYPE_INT32, &aprotocol, - DBUS_TYPE_INVALID) || !name || !*name) { + DBUS_TYPE_INVALID) || !name) { avahi_log_warn("Error parsing Server::ResolveHostName message"); goto fail; } if (!(client = client_get(dbus_message_get_sender(m), TRUE))) { avahi_log_warn("Too many clients, client request failed."); - return respond_error(c, m, AVAHI_DBUS_ERROR_TOO_MANY_CLIENTS, NULL); + return respond_error(c, m, AVAHI_ERR_TOO_MANY_CLIENTS, NULL); } if (client->n_objects >= MAX_OBJECTS_PER_CLIENT) { avahi_log_warn("Too many objects for client '%s', client request failed.", client->name); - return respond_error(c, m, AVAHI_DBUS_ERROR_TOO_MANY_OBJECTS, NULL); + return respond_error(c, m, AVAHI_ERR_TOO_MANY_OBJECTS, NULL); } i = g_new(HostNameResolverInfo, 1); @@ -1246,8 +1266,7 @@ static DBusHandlerResult msg_server_impl(DBusConnection *c, DBusMessage *m, void if (!(i->host_name_resolver = avahi_host_name_resolver_new(avahi_server, (AvahiIfIndex) interface, (AvahiProtocol) protocol, name, (AvahiProtocol) aprotocol, host_name_resolver_callback, i))) { host_name_resolver_free(i); - avahi_log_warn("Failed to create host name resolver"); - goto fail; + return respond_error(c, m, avahi_server_errno(avahi_server), NULL); } return DBUS_HANDLER_RESULT_HANDLED; @@ -1264,24 +1283,22 @@ static DBusHandlerResult msg_server_impl(DBusConnection *c, DBusMessage *m, void DBUS_TYPE_INT32, &interface, DBUS_TYPE_INT32, &protocol, DBUS_TYPE_STRING, &address, - DBUS_TYPE_INVALID) || !address || !*address) { + DBUS_TYPE_INVALID) || !address) { avahi_log_warn("Error parsing Server::ResolveAddress message"); goto fail; } - if (!avahi_address_parse(address, AVAHI_PROTO_UNSPEC, &a)) { - avahi_log_warn("Error parsing address data"); - return respond_error(c, m, AVAHI_DBUS_ERROR_INVALID_ADDRESS, NULL); - } + if (!avahi_address_parse(address, AVAHI_PROTO_UNSPEC, &a)) + return respond_error(c, m, AVAHI_ERR_INVALID_ADDRESS, NULL); if (!(client = client_get(dbus_message_get_sender(m), TRUE))) { avahi_log_warn("Too many clients, client request failed."); - return respond_error(c, m, AVAHI_DBUS_ERROR_TOO_MANY_CLIENTS, NULL); + return respond_error(c, m, AVAHI_ERR_TOO_MANY_CLIENTS, NULL); } if (client->n_objects >= MAX_OBJECTS_PER_CLIENT) { avahi_log_warn("Too many objects for client '%s', client request failed.", client->name); - return respond_error(c, m, AVAHI_DBUS_ERROR_TOO_MANY_OBJECTS, NULL); + return respond_error(c, m, AVAHI_ERR_TOO_MANY_OBJECTS, NULL); } i = g_new(AddressResolverInfo, 1); @@ -1292,8 +1309,7 @@ static DBusHandlerResult msg_server_impl(DBusConnection *c, DBusMessage *m, void if (!(i->address_resolver = avahi_address_resolver_new(avahi_server, (AvahiIfIndex) interface, (AvahiProtocol) protocol, &a, address_resolver_callback, i))) { address_resolver_free(i); - avahi_log_warn("Failed to create address resolver"); - goto fail; + return respond_error(c, m, avahi_server_errno(avahi_server), NULL); } return DBUS_HANDLER_RESULT_HANDLED; @@ -1326,12 +1342,12 @@ static DBusHandlerResult msg_server_impl(DBusConnection *c, DBusMessage *m, void if (!(client = client_get(dbus_message_get_sender(m), TRUE))) { avahi_log_warn("Too many clients, client request failed."); - return respond_error(c, m, AVAHI_DBUS_ERROR_TOO_MANY_CLIENTS, NULL); + return respond_error(c, m, AVAHI_ERR_TOO_MANY_CLIENTS, NULL); } if (client->n_objects >= MAX_OBJECTS_PER_CLIENT) { avahi_log_warn("Too many objects for client '%s', client request failed.", client->name); - return respond_error(c, m, AVAHI_DBUS_ERROR_TOO_MANY_OBJECTS, NULL); + return respond_error(c, m, AVAHI_ERR_TOO_MANY_OBJECTS, NULL); } if (!*domain) @@ -1345,9 +1361,8 @@ static DBusHandlerResult msg_server_impl(DBusConnection *c, DBusMessage *m, void client->n_objects++; if (!(i->domain_browser = avahi_domain_browser_new(avahi_server, (AvahiIfIndex) interface, (AvahiProtocol) protocol, domain, (AvahiDomainBrowserType) type, domain_browser_callback, i))) { - avahi_log_warn("Failed to create domain browser"); domain_browser_free(i); - goto fail; + return respond_error(c, m, avahi_server_errno(avahi_server), NULL); } dbus_connection_register_object_path(c, i->path, &vtable, i); @@ -1379,13 +1394,13 @@ static DBusHandlerResult msg_server_impl(DBusConnection *c, DBusMessage *m, void if (!(client = client_get(dbus_message_get_sender(m), TRUE))) { avahi_log_warn("Too many clients, client request failed."); - return respond_error(c, m, AVAHI_DBUS_ERROR_TOO_MANY_CLIENTS, NULL); + return respond_error(c, m, AVAHI_ERR_TOO_MANY_CLIENTS, NULL); } if (client->n_objects >= MAX_OBJECTS_PER_CLIENT) { avahi_log_warn("Too many objects for client '%s', client request failed.", client->name); - return respond_error(c, m, AVAHI_DBUS_ERROR_TOO_MANY_OBJECTS, NULL); + return respond_error(c, m, AVAHI_ERR_TOO_MANY_OBJECTS, NULL); } if (!*domain) @@ -1399,9 +1414,8 @@ static DBusHandlerResult msg_server_impl(DBusConnection *c, DBusMessage *m, void client->n_objects++; if (!(i->service_type_browser = avahi_service_type_browser_new(avahi_server, (AvahiIfIndex) interface, (AvahiProtocol) protocol, domain, service_type_browser_callback, i))) { - avahi_log_warn("Failed to create service type browser"); service_type_browser_free(i); - goto fail; + return respond_error(c, m, avahi_server_errno(avahi_server), NULL); } dbus_connection_register_object_path(c, i->path, &vtable, i); @@ -1427,20 +1441,20 @@ static DBusHandlerResult msg_server_impl(DBusConnection *c, DBusMessage *m, void DBUS_TYPE_INT32, &protocol, DBUS_TYPE_STRING, &type, DBUS_TYPE_STRING, &domain, - DBUS_TYPE_INVALID) || !type || !*type) { + DBUS_TYPE_INVALID) || !type) { avahi_log_warn("Error parsing Server::ServiceBrowserNew message"); goto fail; } if (!(client = client_get(dbus_message_get_sender(m), TRUE))) { avahi_log_warn("Too many clients, client request failed."); - return respond_error(c, m, AVAHI_DBUS_ERROR_TOO_MANY_CLIENTS, NULL); + return respond_error(c, m, AVAHI_ERR_TOO_MANY_CLIENTS, NULL); } if (client->n_objects >= MAX_OBJECTS_PER_CLIENT) { avahi_log_warn("Too many objects for client '%s', client request failed.", client->name); - return respond_error(c, m, AVAHI_DBUS_ERROR_TOO_MANY_OBJECTS, NULL); + return respond_error(c, m, AVAHI_ERR_TOO_MANY_OBJECTS, NULL); } if (!*domain) @@ -1454,9 +1468,8 @@ static DBusHandlerResult msg_server_impl(DBusConnection *c, DBusMessage *m, void client->n_objects++; if (!(i->service_browser = avahi_service_browser_new(avahi_server, (AvahiIfIndex) interface, (AvahiProtocol) protocol, type, domain, service_browser_callback, i))) { - avahi_log_warn("Failed to create service browser"); service_browser_free(i); - goto fail; + return respond_error(c, m, avahi_server_errno(avahi_server), NULL); } dbus_connection_register_object_path(c, i->path, &vtable, i); @@ -1476,19 +1489,19 @@ static DBusHandlerResult msg_server_impl(DBusConnection *c, DBusMessage *m, void DBUS_TYPE_STRING, &type, DBUS_TYPE_STRING, &domain, DBUS_TYPE_INT32, &aprotocol, - DBUS_TYPE_INVALID) || !name || !*name || !type || !*type) { + DBUS_TYPE_INVALID) || !name || !type) { avahi_log_warn("Error parsing Server::ResolveService message"); goto fail; } if (!(client = client_get(dbus_message_get_sender(m), TRUE))) { avahi_log_warn("Too many clients, client request failed."); - return respond_error(c, m, AVAHI_DBUS_ERROR_TOO_MANY_CLIENTS, NULL); + return respond_error(c, m, AVAHI_ERR_TOO_MANY_CLIENTS, NULL); } if (client->n_objects >= MAX_OBJECTS_PER_CLIENT) { avahi_log_warn("Too many objects for client '%s', client request failed.", client->name); - return respond_error(c, m, AVAHI_DBUS_ERROR_TOO_MANY_OBJECTS, NULL); + return respond_error(c, m, AVAHI_ERR_TOO_MANY_OBJECTS, NULL); } if (!*domain) @@ -1502,8 +1515,7 @@ static DBusHandlerResult msg_server_impl(DBusConnection *c, DBusMessage *m, void if (!(i->service_resolver = avahi_service_resolver_new(avahi_server, (AvahiIfIndex) interface, (AvahiProtocol) protocol, name, type, domain, (AvahiProtocol) aprotocol, service_resolver_callback, i))) { service_resolver_free(i); - avahi_log_warn("Failed to create service resolver"); - goto fail; + return respond_error(c, m, avahi_server_errno(avahi_server), NULL); } return DBUS_HANDLER_RESULT_HANDLED; diff --git a/avahi-daemon/main.c b/avahi-daemon/main.c index 1083416..99bf860 100644 --- a/avahi-daemon/main.c +++ b/avahi-daemon/main.c @@ -150,6 +150,7 @@ static AvahiEntryGroup* add_dns_servers(AvahiServer *s, AvahiEntryGroup* g, gcha else if (avahi_server_add_dns_server_address(s, g, -1, AF_UNSPEC, NULL, AVAHI_DNS_SERVER_RESOLVE, &a, 53) < 0) { avahi_entry_group_free(g); + avahi_log_error("Failed to add DNS server address: %s", avahi_strerror(avahi_server_errno(s))); return NULL; } } @@ -500,6 +501,7 @@ static gint run_server(DaemonConfig *c) { gint r = -1; GIOChannel *io = NULL; guint watch_id = (guint) -1; + gint error; g_assert(c); @@ -527,8 +529,10 @@ static gint run_server(DaemonConfig *c) { goto finish; #endif - if (!(avahi_server = avahi_server_new(NULL, &c->server_config, server_callback, c))) + if (!(avahi_server = avahi_server_new(NULL, &c->server_config, server_callback, c, &error))) { + avahi_log_error("Failed to create server: %s", avahi_strerror(error)); goto finish; + } load_resolv_conf(c); diff --git a/avahi-daemon/static-services.c b/avahi-daemon/static-services.c index 8c54eab..0fdff14 100644 --- a/avahi-daemon/static-services.c +++ b/avahi-daemon/static-services.c @@ -193,9 +193,6 @@ static void add_static_service_group_to_server(StaticServiceGroup *g) { g_assert(g); - if (g->entry_group) - return; - if (g->chosen_name) g_free(g->chosen_name); @@ -218,7 +215,9 @@ static void add_static_service_group_to_server(StaticServiceGroup *g) { g->chosen_name, s->type, s->domain_name, s->host_name, s->port, s->txt_records) < 0) { - avahi_log_error("Failed to add service '%s' of type '%s', ignoring service group (%s)", g->chosen_name, s->type, g->filename); + avahi_log_error("Failed to add service '%s' of type '%s', ignoring service group (%s): %s", + g->chosen_name, s->type, g->filename, + avahi_strerror(avahi_server_errno(avahi_server))); remove_static_service_group_from_server(g); return; } diff --git a/avahi-discover-standalone/main.c b/avahi-discover-standalone/main.c index daecdaa..00984ec 100644 --- a/avahi-discover-standalone/main.c +++ b/avahi-discover-standalone/main.c @@ -267,6 +267,7 @@ int main(int argc, char *argv[]) { GladeXML *xml; AvahiServerConfig config; GtkTreeViewColumn *c; + gint error; gtk_init(&argc, &argv); glade_init(); @@ -293,9 +294,11 @@ int main(int argc, char *argv[]) { avahi_server_config_init(&config); config.publish_hinfo = config.publish_addresses = config.publish_domain = config.publish_workstation = FALSE; - server = avahi_server_new(NULL, &config, NULL, NULL); + server = avahi_server_new(NULL, &config, NULL, NULL, &error); avahi_server_config_free(&config); + g_assert(server); + service_type_browser = avahi_service_type_browser_new(server, -1, AF_UNSPEC, argc >= 2 ? argv[1] : NULL, service_type_browser_callback, NULL); gtk_main(); diff --git a/avahi-utils/Makefile.am b/avahi-utils/Makefile.am index 90b908c..144ee12 100644 --- a/avahi-utils/Makefile.am +++ b/avahi-utils/Makefile.am @@ -24,14 +24,18 @@ pythonscripts = \ avahi-publish-service \ avahi-dump-all \ avahi-discover \ - avahi-bookmarks + avahi-bookmarks \ + avahi-resolve-host-name \ + avahi-resolve-address EXTRA_DIST = \ avahi-publish-address.in \ avahi-publish-service.in \ avahi-dump-all.in \ avahi-discover.in \ - avahi-bookmarks.in + avahi-bookmarks.in \ + avahi-resolve-host-name.in \ + avahi-resolve-address.in if HAVE_PYTHON bin_SCRIPTS = $(pythonscripts) @@ -58,4 +62,12 @@ avahi-bookmarks: avahi-bookmarks.in sed -e 's,@PYTHON\@,$(PYTHON),g' $< > $@ chmod +x $@ +avahi-resolve-host-name: avahi-resolve-host-name.in + sed -e 's,@PYTHON\@,$(PYTHON),g' $< > $@ + chmod +x $@ + +avahi-resolve-address: avahi-resolve-address.in + sed -e 's,@PYTHON\@,$(PYTHON),g' $< > $@ + chmod +x $@ + CLEANFILES = $(pythonscripts) diff --git a/avahi-utils/avahi-resolve-address.in b/avahi-utils/avahi-resolve-address.in new file mode 100755 index 0000000..b72a95b --- /dev/null +++ b/avahi-utils/avahi-resolve-address.in @@ -0,0 +1,53 @@ +#!@PYTHON@ +# -*-python-*- +# $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. + +import sys, getopt + +try: + import avahi, gobject, dbus +except ImportError: + print "Sorry, to use this tool you need to install Avahi, pygtk and python-dbus." + sys.exit(1) + +try: + import dbus.glib +except ImportError, e: + pass + + +if len(sys.argv) <= 1: + print "Please specify host name(s) to resolve." + sys.exit(1) + +bus = dbus.SystemBus() +server = dbus.Interface(bus.get_object(avahi.DBUS_NAME, avahi.DBUS_PATH_SERVER), avahi.DBUS_INTERFACE_SERVER) + +ret = 0 + +for a in sys.argv[1:]: + try: + r = server.ResolveAddress(avahi.IF_UNSPEC, avahi.PROTO_UNSPEC, a) + print r[3], r[4] + except dbus.DBusException, e: + print "Resolving '%s' failed: %s" % (a, str(e)) + ret = 1 + +sys.exit(ret) diff --git a/avahi-utils/avahi-resolve-host-name.in b/avahi-utils/avahi-resolve-host-name.in new file mode 100755 index 0000000..cc24526 --- /dev/null +++ b/avahi-utils/avahi-resolve-host-name.in @@ -0,0 +1,53 @@ +#!@PYTHON@ +# -*-python-*- +# $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. + +import sys, getopt + +try: + import avahi, gobject, dbus +except ImportError: + print "Sorry, to use this tool you need to install Avahi, pygtk and python-dbus." + sys.exit(1) + +try: + import dbus.glib +except ImportError, e: + pass + + +if len(sys.argv) <= 1: + print "Please specify host name(s) to resolve." + sys.exit(1) + +bus = dbus.SystemBus() +server = dbus.Interface(bus.get_object(avahi.DBUS_NAME, avahi.DBUS_PATH_SERVER), avahi.DBUS_INTERFACE_SERVER) + +ret = 0 + +for name in sys.argv[1:]: + try: + r = server.ResolveHostName(avahi.IF_UNSPEC, avahi.PROTO_UNSPEC, name, avahi.PROTO_UNSPEC) + print r[2], r[4] + except dbus.DBusException, e: + print "Resolving '%s' failed: %s" % (name, str(e)) + ret = 1 + +sys.exit(ret) diff --git a/doxygen.cfg b/doxygen.cfg index f081d41..315fbd1 100644 --- a/doxygen.cfg +++ b/doxygen.cfg @@ -173,7 +173,7 @@ EXPAND_ONLY_PREDEF = NO SEARCH_INCLUDES = YES INCLUDE_PATH = INCLUDE_FILE_PATTERNS = -PREDEFINED = +PREDEFINED = DOXYGEN_SHOULD_SKIP_THIS EXPAND_AS_DEFINED = SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- diff --git a/examples/browse-services.c b/examples/browse-services.c index bb8eed8..c58d230 100644 --- a/examples/browse-services.c +++ b/examples/browse-services.c @@ -77,6 +77,8 @@ int main(int argc, char*argv[]) { AvahiServerConfig config; AvahiServer *server = NULL; AvahiServiceBrowser *sb; + gint error; + int ret = 1; /* Do not publish any local records */ avahi_server_config_init(&config); @@ -86,11 +88,17 @@ int main(int argc, char*argv[]) { config.publish_domain = FALSE; /* Allocate a new server */ - server = avahi_server_new(NULL, &config, NULL, NULL); + server = avahi_server_new(NULL, &config, NULL, NULL, &error); /* Free the configuration data */ avahi_server_config_free(&config); + /* Check wether creating the server object succeeded */ + if (!server) { + g_message("Failed to create server: %s", avahi_strerror(error)); + goto fail; + } + /* Create the service browser */ sb = avahi_service_browser_new(server, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "_http._tcp", NULL, browse_callback, server); @@ -98,6 +106,10 @@ int main(int argc, char*argv[]) { main_loop = g_main_loop_new(NULL, FALSE); g_main_loop_run(main_loop); + ret = 0; + +fail: + /* Cleanup things */ if (sb) avahi_service_browser_free(sb); @@ -108,5 +120,5 @@ int main(int argc, char*argv[]) { if (main_loop) g_main_loop_unref(main_loop); - return 0; + return ret; } diff --git a/examples/publish-service.c b/examples/publish-service.c index 7c9879c..a936147 100644 --- a/examples/publish-service.c +++ b/examples/publish-service.c @@ -121,7 +121,9 @@ static void server_callback(AvahiServer *s, AvahiServerState state, gpointer use int main(int argc, char*argv[]) { AvahiServerConfig config; AvahiServer *server = NULL; - + gint error; + int ret = 1; + srand(time(NULL)); name = g_strdup("MegaPrinter"); @@ -132,15 +134,25 @@ int main(int argc, char*argv[]) { config.publish_workstation = FALSE; /* Allocate a new server */ - server = avahi_server_new(NULL, &config, server_callback, NULL); + server = avahi_server_new(NULL, &config, server_callback, NULL, &error); /* Free the configuration data */ avahi_server_config_free(&config); + + /* Check wether creating the server object succeeded */ + if (!server) { + g_message("Failed to create server: %s", avahi_strerror(error)); + goto fail; + } /* Run the main loop */ main_loop = g_main_loop_new(NULL, FALSE); g_main_loop_run(main_loop); + ret = 0; + +fail: + /* Cleanup things */ if (group) avahi_entry_group_free(group); @@ -153,5 +165,5 @@ int main(int argc, char*argv[]) { g_free(name); - return 0; + return ret; } -- 2.39.2