From dad41109f1726a876dd918290187d0a5296b267d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 20 Aug 2005 14:12:10 +0000 Subject: * many improvements to avahi-client (especially error handling) * Document AVahi error handling a little git-svn-id: file:///home/lennart/svn/public/avahi/trunk@358 941a03a8-eaeb-0310-b9a0-b1bbd8fe43fe --- avahi-client/client-test.c | 38 ++-- avahi-client/client.c | 351 ++++++++++++++++++++----------- avahi-client/client.h | 71 +++++-- avahi-client/entrygroup.c | 513 ++++++++++++++++++++++++++++++++------------- avahi-client/internal.h | 9 +- avahi-common/dbus.c | 66 +++--- avahi-common/dbus.h | 9 +- avahi-common/error.h | 22 +- avahi-common/gccmacro.h | 10 + 9 files changed, 732 insertions(+), 357 deletions(-) diff --git a/avahi-client/client-test.c b/avahi-client/client-test.c index 0dd1707..29dd62a 100644 --- a/avahi-client/client-test.c +++ b/avahi-client/client-test.c @@ -42,7 +42,7 @@ avahi_client_callback (AvahiClient *c, AvahiClientState state, void *user_data) static void avahi_entry_group_callback (AvahiEntryGroup *g, AvahiEntryGroupState state, void *user_data) { - printf ("XXX: Callback on %s, state -> %d, data -> %s\n", avahi_entry_group_path (g), state, (char*)user_data); + printf ("XXX: Callback on %s, state -> %d, data -> %s\n", avahi_entry_group_get_dbus_path(g), state, (char*)user_data); } static void @@ -76,17 +76,15 @@ static void test_free_entry_group (AvahiTimeout *timeout, void* userdata) printf ("XXX: freeing entry group\n"); avahi_entry_group_free (g); } -int -main (int argc, char *argv[]) -{ + +int main (int argc, char *argv[]) { AvahiClient *avahi; AvahiEntryGroup *group; - AvahiStringList *txt; AvahiDomainBrowser *domain; AvahiServiceBrowser *sb; AvahiServiceTypeBrowser *st; AvahiSimplePoll *simple_poll; - char *ret; + const char *ret; int error; struct timeval tv; @@ -98,36 +96,28 @@ main (int argc, char *argv[]) goto fail; } - assert (avahi != NULL); + printf("State: %i\n", avahi_client_get_state(avahi)); ret = avahi_client_get_version_string (avahi); - printf ("Avahi Server Version: %s (Error Return: %s)\n", ret, avahi_strerror (avahi_client_errno (avahi))); - avahi_free (ret); + printf("Avahi Server Version: %s (Error Return: %s)\n", ret, ret ? "OK" : avahi_strerror(avahi_client_errno(avahi))); ret = avahi_client_get_host_name (avahi); - printf ("Host Name: %s (Error Return: %s)\n", ret, avahi_strerror (avahi_client_errno (avahi))); - avahi_free (ret); + printf("Host Name: %s (Error Return: %s)\n", ret, ret ? "OK" : avahi_strerror(avahi_client_errno(avahi))); ret = avahi_client_get_domain_name (avahi); - printf ("Domain Name: %s (Error Return: %s)\n", ret, avahi_strerror (avahi_client_errno (avahi))); - avahi_free (ret); + printf("Domain Name: %s (Error Return: %s)\n", ret, ret ? "OK" : avahi_strerror(avahi_client_errno(avahi))); ret = avahi_client_get_host_name_fqdn (avahi); - printf ("FQDN: %s (Error Return: %s)\n", ret, avahi_strerror (avahi_client_errno (avahi))); - avahi_free (ret); + printf("FQDN: %s (Error Return: %s)\n", ret, ret ? "OK" : avahi_strerror(avahi_client_errno(avahi))); group = avahi_entry_group_new (avahi, avahi_entry_group_callback, "omghai"); + printf("Creating entry group: %s\n", group ? "OK" : avahi_strerror(avahi_client_errno (avahi))); - printf ("Creating entry group: %s\n", avahi_strerror (avahi_client_errno (avahi))); - - if (group == NULL) - printf ("Failed to create entry group object\n"); - else - printf ("Sucessfully created entry group, path %s\n", avahi_entry_group_path (group)); - - txt = avahi_string_list_new ("foo=bar", NULL); + assert(group); + + printf("Sucessfully created entry group, path %s\n", avahi_entry_group_get_dbus_path (group)); - avahi_entry_group_add_service (group, AVAHI_IF_UNSPEC, AF_UNSPEC, "Lathiat's Site", "_http._tcp", "", "", 80, txt); + avahi_entry_group_add_service (group, AVAHI_IF_UNSPEC, AF_UNSPEC, "Lathiat's Site", "_http._tcp", "", "", 80, "foo=bar", NULL); avahi_entry_group_commit (group); diff --git a/avahi-client/client.c b/avahi-client/client.c index 1159152..242afff 100644 --- a/avahi-client/client.c +++ b/avahi-client/client.c @@ -23,20 +23,18 @@ #include #endif -#include -#include -#include -#include -#include -#include -#include #include #include #include #include -#include +#include +#include +#include +#include +#include +#include #include "client.h" #include "internal.h" @@ -46,75 +44,132 @@ int avahi_client_set_errno (AvahiClient *client, int error) { return client->error = error; } - + +int avahi_client_set_dbus_error(AvahiClient *client, DBusError *error) { + assert(client); + assert(error); + + return avahi_client_set_errno(client, avahi_error_dbus_to_number(error->name)); +} + static void client_set_state (AvahiClient *client, AvahiServerState state) { - assert(state); + assert(client); if (client->state == state) return; client->state = state; + switch (client->state) { + case AVAHI_CLIENT_DISCONNECTED: + if (client->bus) { + dbus_connection_disconnect(client->bus); + dbus_connection_unref(client->bus); + client->bus = NULL; + } + + /* Fall through */ + + case AVAHI_CLIENT_S_COLLISION: + case AVAHI_CLIENT_S_REGISTERING: + + /* Clear cached strings */ + avahi_free(client->host_name); + avahi_free(client->host_name_fqdn); + avahi_free(client->domain_name); + + client->host_name = NULL; + client->host_name_fqdn = NULL; + client->domain_name = NULL; + break; + + case AVAHI_CLIENT_S_INVALID: + case AVAHI_CLIENT_S_RUNNING: + break; + + } + if (client->callback) client->callback (client, state, client->userdata); } -static DBusHandlerResult -filter_func (DBusConnection *bus, DBusMessage *message, void *data) -{ - AvahiClient *client = data; +static DBusHandlerResult filter_func(DBusConnection *bus, DBusMessage *message, void *userdata) { + AvahiClient *client = userdata; DBusError error; + + assert(bus); + assert(message); - printf ("dbus: interface=%s, path=%s, member=%s\n", + dbus_error_init (&error); + + fprintf(stderr, "dbus: interface=%s, path=%s, member=%s\n", dbus_message_get_interface (message), dbus_message_get_path (message), dbus_message_get_member (message)); - dbus_error_init (&error); + if (client->state == AVAHI_CLIENT_DISCONNECTED) + goto fail; + + if (dbus_message_is_signal(message, DBUS_INTERFACE_LOCAL, "Disconnected")) { - if (dbus_message_is_signal(message, DBUS_INTERFACE_DBUS, "NameOwnerChanged")) { + /* The DBUS server died or kicked us */ + client_set_state(client, AVAHI_CLIENT_DISCONNECTED); + + } if (dbus_message_is_signal(message, DBUS_INTERFACE_DBUS, "NameOwnerChanged")) { char *name, *old, *new; - dbus_message_get_args(message, &error, DBUS_TYPE_STRING, &name, DBUS_TYPE_STRING, &old, DBUS_TYPE_STRING, &new, DBUS_TYPE_INVALID); - if (dbus_error_is_set (&error)) { - dbus_error_free (&error); - goto out; + if (!(dbus_message_get_args( + message, &error, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_STRING, &old, + DBUS_TYPE_STRING, &new, + DBUS_TYPE_INVALID) || dbus_error_is_set (&error))) { + + fprintf(stderr, "WARNING: Failed to parse NameOwnerChanged signal: %s\n", error.message); + goto fail; } - if (strcmp (name, AVAHI_DBUS_NAME) == 0) { + if (strcmp(name, AVAHI_DBUS_NAME) == 0) - if (old == NULL && new != NULL) { - client_set_state (client, AVAHI_CLIENT_RECONNECTED); - } else if (old != NULL && new == NULL) { - client_set_state (client, AVAHI_CLIENT_DISCONNECTED); - /* XXX: we really need to expire all entry groups */ - } + /* Regardless if the server lost or acquired its name or + * if the name was transfered: our services are no longer + * available, so we disconnect ourselves */ + + client_set_state(client, AVAHI_CLIENT_DISCONNECTED); + + } else if (dbus_message_is_signal (message, AVAHI_DBUS_INTERFACE_SERVER, "StateChanged")) { + int32_t state; + + if (!(dbus_message_get_args( + message, &error, + DBUS_TYPE_INT32, &state, + DBUS_TYPE_INVALID) || dbus_error_is_set (&error))) { + fprintf(stderr, "WARNING: Failed to parse Server.StateChanged signal: %s\n", error.message); + goto fail; } - } else if (dbus_message_is_signal (message, AVAHI_DBUS_NAME, "StateChanged")) { - /* XXX: todo */ - printf ("server statechange\n"); + + client_set_state(client, (AvahiClientState) state); + } else if (dbus_message_is_signal (message, AVAHI_DBUS_INTERFACE_ENTRY_GROUP, "StateChanged")) { const char *path; - AvahiEntryGroup *n, *group = NULL; - path = dbus_message_get_path (message); - - for (n = client->groups; n != NULL; n = n->groups_next) - { - if (strcmp (n->path, path) == 0) - { - group = n; + AvahiEntryGroup *g; + path = dbus_message_get_path(message); + + for (g = client->groups; g; g = g->groups_next) + if (strcmp(g->path, path) == 0) break; - } - } - if (group != NULL) { - int state; - dbus_message_get_args (message, &error, DBUS_TYPE_INT32, &state, DBUS_TYPE_INVALID); - if (dbus_error_is_set (&error)) - goto out; + if (g) { + int32_t state; + if (!(dbus_message_get_args (message, &error, DBUS_TYPE_INT32, &state, DBUS_TYPE_INVALID)) || + dbus_error_is_set(&error)) { + fprintf(stderr, "WARNING: Failed to parse EntryGroup.StateChanged signal: %s\n", error.message); + goto fail; + } - avahi_entry_group_state_change (group, state); + avahi_entry_group_set_state(g, state); } + } else if (dbus_message_is_signal (message, AVAHI_DBUS_INTERFACE_DOMAIN_BROWSER, "ItemNew")) { return avahi_domain_browser_event (client, AVAHI_BROWSER_NEW, message); } else if (dbus_message_is_signal (message, AVAHI_DBUS_INTERFACE_DOMAIN_BROWSER, "ItemRemove")) { @@ -131,14 +186,10 @@ filter_func (DBusConnection *bus, DBusMessage *message, void *data) return DBUS_HANDLER_RESULT_HANDLED; -out: - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; -} - -static int translate_dbus_error(const DBusError *error) { - assert(error); +fail: - return avahi_error_dbus_to_number (error->name); + dbus_error_free (&error); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } static int get_server_state(AvahiClient *client, int *ret_error) { @@ -169,7 +220,7 @@ static int get_server_state(AvahiClient *client, int *ret_error) { fail: if (dbus_error_is_set(&error)) { - e = translate_dbus_error(&error); + e = avahi_error_dbus_to_number (error.name); dbus_error_free(&error); } else e = AVAHI_ERR_NO_MEMORY; @@ -196,7 +247,12 @@ AvahiClient *avahi_client_new(const AvahiPoll *poll_api, AvahiClientCallback cal client->error = AVAHI_OK; client->callback = callback; client->userdata = userdata; - client->state = AVAHI_SERVER_INVALID; + client->state = AVAHI_CLIENT_DISCONNECTED; + + client->host_name = NULL; + client->host_name_fqdn = NULL; + client->domain_name = NULL; + client->version_string = NULL; AVAHI_LLIST_HEAD_INIT(AvahiEntryGroup, client->groups); AVAHI_LLIST_HEAD_INIT(AvahiDomainBrowser, client->domain_browsers); @@ -204,11 +260,8 @@ AvahiClient *avahi_client_new(const AvahiPoll *poll_api, AvahiClientCallback cal AVAHI_LLIST_HEAD_INIT(AvahiServiceTypeBrowser, client->service_type_browsers); client->bus = dbus_bus_get(DBUS_BUS_SYSTEM, &error); - if (dbus_error_is_set (&error)) { - if (ret_error) - *ret_error = translate_dbus_error(&error); + if (!client->bus || dbus_error_is_set (&error)) goto fail; - } if (avahi_dbus_connection_glue(client->bus, poll_api) < 0) { if (ret_error) @@ -230,11 +283,8 @@ AvahiClient *avahi_client_new(const AvahiPoll *poll_api, AvahiClientCallback cal "path='" AVAHI_DBUS_PATH_SERVER "'", &error); - if (dbus_error_is_set (&error)) { - if (ret_error) - *ret_error = translate_dbus_error(&error); + if (dbus_error_is_set (&error)) goto fail; - } dbus_bus_add_match ( client->bus, @@ -244,22 +294,23 @@ AvahiClient *avahi_client_new(const AvahiPoll *poll_api, AvahiClientCallback cal "path='" DBUS_PATH_DBUS "'", &error); - if (dbus_error_is_set (&error)) { - if (ret_error) - *ret_error = translate_dbus_error(&error); + if (dbus_error_is_set (&error)) + goto fail; + + dbus_bus_add_match ( + client->bus, + "type='signal', " + "interface='" DBUS_INTERFACE_LOCAL "'", + &error); + + if (dbus_error_is_set (&error)) goto fail; - } if (!(dbus_bus_name_has_owner(client->bus, AVAHI_DBUS_NAME, &error))) { - if (dbus_error_is_set (&error)) { - if (ret_error) - *ret_error = translate_dbus_error(&error); - goto fail; - } - if (ret_error) *ret_error = AVAHI_ERR_NO_DAEMON; + goto fail; } @@ -273,8 +324,13 @@ fail: if (client) avahi_client_free(client); - if (dbus_error_is_set(&error)) + if (dbus_error_is_set(&error)) { + + if (ret_error) + *ret_error = avahi_error_dbus_to_number(error.name); + dbus_error_free(&error); + } return NULL; } @@ -298,88 +354,135 @@ void avahi_client_free(AvahiClient *client) { while (client->service_type_browsers) avahi_service_type_browser_free(client->service_type_browsers); + + avahi_free(client->version_string); + avahi_free(client->host_name); + avahi_free(client->host_name_fqdn); + avahi_free(client->domain_name); avahi_free(client); } -static char* -avahi_client_get_string_reply_and_block (AvahiClient *client, const char *method, const char *param) -{ - DBusMessage *message; - DBusMessage *reply; +static char* avahi_client_get_string_reply_and_block (AvahiClient *client, const char *method, const char *param) { + DBusMessage *message = NULL, *reply = NULL; DBusError error; - char *ret, *new; + char *ret, *n; - if (client == NULL || method == NULL) return NULL; + assert(client); + assert(method); dbus_error_init (&error); - message = dbus_message_new_method_call (AVAHI_DBUS_NAME, AVAHI_DBUS_PATH_SERVER, AVAHI_DBUS_INTERFACE_SERVER, method); + if (!(message = dbus_message_new_method_call (AVAHI_DBUS_NAME, AVAHI_DBUS_PATH_SERVER, AVAHI_DBUS_INTERFACE_SERVER, method))) { + avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY); + goto fail; + } - if (param != NULL) - { - if (!dbus_message_append_args (message, DBUS_TYPE_STRING, ¶m, DBUS_TYPE_INVALID)) - { - avahi_client_set_errno (client, AVAHI_ERR_DBUS_ERROR); - return NULL; + if (param) { + if (!dbus_message_append_args (message, DBUS_TYPE_STRING, ¶m, DBUS_TYPE_INVALID)) { + avahi_client_set_errno (client, AVAHI_ERR_NO_MEMORY); + goto fail; } } reply = dbus_connection_send_with_reply_and_block (client->bus, message, -1, &error); - if (dbus_error_is_set (&error)) - { - dbus_error_free (&error); - dbus_message_unref (message); + if (!reply || dbus_error_is_set (&error)) + goto fail; - avahi_client_set_errno (client, AVAHI_ERR_DBUS_ERROR); - return NULL; + if (!dbus_message_get_args (reply, &error, DBUS_TYPE_STRING, &ret, DBUS_TYPE_INVALID) || + dbus_error_is_set (&error)) + goto fail; + + if (!(n = avahi_strdup(ret))) { + avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY); + goto fail; } - if (reply == NULL) - { - dbus_message_unref (message); + dbus_message_unref(message); + dbus_message_unref(reply); + + return n; + +fail: - avahi_client_set_errno (client, AVAHI_ERR_DBUS_ERROR); - return NULL; + if (message) + dbus_message_unref(message); + if (reply) + dbus_message_unref(reply); + + if (dbus_error_is_set(&error)) { + avahi_client_set_dbus_error(client, &error); + dbus_error_free(&error); } - dbus_message_get_args (reply, &error, DBUS_TYPE_STRING, &ret, DBUS_TYPE_INVALID); + return NULL; +} - if (dbus_error_is_set (&error)) - { - dbus_error_free (&error); +const char* avahi_client_get_version_string (AvahiClient *client) { + assert(client); - avahi_client_set_errno (client, AVAHI_ERR_DBUS_ERROR); + if (client->state == AVAHI_CLIENT_DISCONNECTED) { + avahi_client_set_errno(client, AVAHI_ERR_BAD_STATE); return NULL; } - new = avahi_strdup (ret); + if (!client->version_string) + client->version_string = avahi_client_get_string_reply_and_block(client, "GetVersionString", NULL); - avahi_client_set_errno (client, AVAHI_OK); - return new; + return client->version_string; } -char* -avahi_client_get_version_string (AvahiClient *client) -{ - return avahi_client_get_string_reply_and_block (client, "GetVersionString", NULL); +const char* avahi_client_get_domain_name (AvahiClient *client) { + assert(client); + + if (client->state == AVAHI_CLIENT_DISCONNECTED) { + avahi_client_set_errno(client, AVAHI_ERR_BAD_STATE); + return NULL; + } + + if (!client->domain_name) + client->domain_name = avahi_client_get_string_reply_and_block(client, "GetDomainName", NULL); + + return client->domain_name; } -char* -avahi_client_get_domain_name (AvahiClient *client) -{ - return avahi_client_get_string_reply_and_block (client, "GetDomainName", NULL); +const char* avahi_client_get_host_name (AvahiClient *client) { + assert(client); + + if (client->state == AVAHI_CLIENT_DISCONNECTED) { + avahi_client_set_errno(client, AVAHI_ERR_BAD_STATE); + return NULL; + } + + if (!client->host_name) + client->host_name = avahi_client_get_string_reply_and_block(client, "GetHostName", NULL); + + return client->host_name; } -char* -avahi_client_get_host_name (AvahiClient *client) -{ - return avahi_client_get_string_reply_and_block (client, "GetHostName", NULL); +const char* avahi_client_get_host_name_fqdn (AvahiClient *client) { + assert(client); + + if (client->state == AVAHI_CLIENT_DISCONNECTED) { + avahi_client_set_errno(client, AVAHI_ERR_BAD_STATE); + return NULL; + } + + if (!client->host_name_fqdn) + client->host_name_fqdn = avahi_client_get_string_reply_and_block(client, "GetHostNameFqdn", NULL); + + return client->host_name_fqdn; } -char* -avahi_client_get_host_name_fqdn (AvahiClient *client) -{ - return avahi_client_get_string_reply_and_block (client, "GetHostNameFqdn", NULL); +AvahiClientState avahi_client_get_state(AvahiClient *client) { + assert(client); + + return client->state; +} + +int avahi_client_errno(AvahiClient *client) { + assert(client); + + return client->error; } diff --git a/avahi-client/client.h b/avahi-client/client.h index 5aa3efc..fee6d91 100644 --- a/avahi-client/client.h +++ b/avahi-client/client.h @@ -29,6 +29,7 @@ #include #include #include +#include /** \file client.h Definitions and functions for the client API over D-Bus */ @@ -44,8 +45,11 @@ typedef struct AvahiServiceTypeBrowser AvahiServiceTypeBrowser; /** States of a client object, note that AvahiServerStates are also emitted */ typedef enum { - AVAHI_CLIENT_DISCONNECTED = 100, /**< Lost DBUS connection to the Avahi daemon */ - AVAHI_CLIENT_RECONNECTED = 101 /**< Regained connection to the daemon, all records need to be re-added */ + AVAHI_CLIENT_S_INVALID = AVAHI_SERVER_INVALID, + AVAHI_CLIENT_S_REGISTERING = AVAHI_SERVER_REGISTERING, + AVAHI_CLIENT_S_RUNNING = AVAHI_SERVER_RUNNING, + AVAHI_CLIENT_S_COLLISION = AVAHI_SERVER_COLLISION, + AVAHI_CLIENT_DISCONNECTED = 100 /**< Lost DBUS connection to the Avahi daemon */ } AvahiClientState; /** The function prototype for the callback of an AvahiClient */ @@ -70,16 +74,22 @@ AvahiClient* avahi_client_new (const AvahiPoll *poll_api, AvahiClientCallback ca void avahi_client_free(AvahiClient *client); /** Get the version of the server */ -char* avahi_client_get_version_string (AvahiClient*); +const char* avahi_client_get_version_string (AvahiClient*); /** Get host name */ -char* avahi_client_get_host_name (AvahiClient*); +const char* avahi_client_get_host_name (AvahiClient*); /** Get domain name */ -char* avahi_client_get_domain_name (AvahiClient*); +const char* avahi_client_get_domain_name (AvahiClient*); /** Get FQDN domain name */ -char* avahi_client_get_host_name_fqdn (AvahiClient*); +const char* avahi_client_get_host_name_fqdn (AvahiClient*); + +/** Get state */ +AvahiClientState avahi_client_get_state(AvahiClient *client); + +/** Get the last error number */ +int avahi_client_errno (AvahiClient*); /** Create a new AvahiEntryGroup object */ AvahiEntryGroup* avahi_entry_group_new (AvahiClient*, AvahiEntryGroupCallback callback, void *userdata); @@ -99,26 +109,47 @@ int avahi_entry_group_get_state (AvahiEntryGroup*); /** Check if an AvahiEntryGroup is empty */ int avahi_entry_group_is_empty (AvahiEntryGroup*); -/** Get the last error number */ -int avahi_client_errno (AvahiClient*); - /** Get an AvahiEntryGroup's owning client instance */ AvahiClient* avahi_entry_group_get_client (AvahiEntryGroup*); +/** Add a service, takes a variable NULL terminated list of text records */ +int avahi_entry_group_add_service( + AvahiEntryGroup *group, + AvahiIfIndex interface, + AvahiProtocol protocol, + const char *name, + const char *type, + const char *domain, + const char *host, + uint16_t port, + ...) AVAHI_GCC_SENTINEL; + /** Add a service, takes an AvahiStringList for text records */ -int -avahi_entry_group_add_service (AvahiEntryGroup *group, - AvahiIfIndex interface, - AvahiProtocol protocol, - const char *name, - const char *type, - const char *domain, - const char *host, - uint16_t port, - AvahiStringList *txt); +int avahi_entry_group_add_service_strlst( + AvahiEntryGroup *group, + AvahiIfIndex interface, + AvahiProtocol protocol, + const char *name, + const char *type, + const char *domain, + const char *host, + uint16_t port, + AvahiStringList *txt); + +/** Add a service, takes a NULL terminated va_list for text records */ +int avahi_entry_group_add_service_va( + AvahiEntryGroup *group, + AvahiIfIndex interface, + AvahiProtocol protocol, + const char *name, + const char *type, + const char *domain, + const char *host, + uint16_t port, + va_list va); /** Get the D-Bus path of an AvahiEntryGroup object, for debugging purposes only. */ -const char* avahi_entry_group_path (AvahiEntryGroup *); +const char* avahi_entry_group_get_dbus_path (AvahiEntryGroup *); /** Browse for domains on the local network */ AvahiDomainBrowser* avahi_domain_browser_new (AvahiClient *client, diff --git a/avahi-client/entrygroup.c b/avahi-client/entrygroup.c index dbd1a4e..c22d8a6 100644 --- a/avahi-client/entrygroup.c +++ b/avahi-client/entrygroup.c @@ -38,236 +38,455 @@ #include "client.h" #include "internal.h" -void avahi_entry_group_state_change (AvahiEntryGroup *group, int state) -{ - if (group == NULL || group->callback == NULL) +void avahi_entry_group_set_state(AvahiEntryGroup *group, AvahiEntryGroupState state) { + assert(group); + + if (group->state == state) return; - group->callback (group, state, group->userdata); + group->state = state; + + if (group->callback) + group->callback(group, state, group->userdata); } -AvahiEntryGroup* -avahi_entry_group_new (AvahiClient *client, AvahiEntryGroupCallback callback, void *user_data) -{ - AvahiEntryGroup *tmp = NULL; - DBusMessage *message = NULL, *reply; +static int retrieve_state(AvahiEntryGroup *group) { + DBusMessage *message, *reply; DBusError error; - char *path; + int r = AVAHI_OK; + int32_t state; + AvahiClient *client; + + dbus_error_init(&error); - if (client == NULL) - return NULL; + assert(group); + client = group->client; - dbus_error_init (&error); + if (!(message = dbus_message_new_method_call(AVAHI_DBUS_NAME, group->path, AVAHI_DBUS_INTERFACE_ENTRY_GROUP, "GetState"))) { + r = avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY); + goto fail; + } + + if (!(reply = dbus_connection_send_with_reply_and_block(client->bus, message, -1, &error)) || + dbus_error_is_set (&error)) { + r = avahi_client_set_errno(client, AVAHI_ERR_DBUS_ERROR); + goto fail; + } + + if (!dbus_message_get_args(reply, &error, DBUS_TYPE_INT32, &state, DBUS_TYPE_INVALID) || + dbus_error_is_set (&error)) { + r = avahi_client_set_errno(client, AVAHI_ERR_DBUS_ERROR); + goto fail; + } + + dbus_message_unref(message); + dbus_message_unref(reply); + + avahi_entry_group_set_state(group, (AvahiEntryGroupState) state); + + return AVAHI_OK; + +fail: + if (dbus_error_is_set(&error)) { + r = avahi_client_set_dbus_error(client, &error); + dbus_error_free(&error); + } - message = dbus_message_new_method_call (AVAHI_DBUS_NAME, AVAHI_DBUS_PATH_SERVER, - AVAHI_DBUS_INTERFACE_SERVER, "EntryGroupNew"); + if (message) + dbus_message_unref(message); - reply = dbus_connection_send_with_reply_and_block (client->bus, message, -1, &error); + if (reply) + dbus_message_unref(reply); - if (dbus_error_is_set (&error)) - { - dbus_error_free (&error); + return r; +} - avahi_client_set_errno (client, AVAHI_ERR_DBUS_ERROR); +AvahiEntryGroup* avahi_entry_group_new (AvahiClient *client, AvahiEntryGroupCallback callback, void *userdata) { + AvahiEntryGroup *group = NULL; + DBusMessage *message = NULL, *reply = NULL; + DBusError error; + char *path; + + assert(client); + + dbus_error_init (&error); + + if (client->state == AVAHI_CLIENT_DISCONNECTED) { + avahi_client_set_errno(client, AVAHI_ERR_BAD_STATE); goto fail; } - if (reply == NULL) - { + if (!(group = avahi_new(AvahiEntryGroup, 1))) { + avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY); + goto fail; + } + + group->client = client; + group->callback = callback; + group->userdata = userdata; + group->state = AVAHI_ENTRY_GROUP_UNCOMMITED; + AVAHI_LLIST_PREPEND(AvahiEntryGroup, groups, client->groups, group); + + if (!(message = dbus_message_new_method_call( + AVAHI_DBUS_NAME, + AVAHI_DBUS_PATH_SERVER, + AVAHI_DBUS_INTERFACE_SERVER, + "EntryGroupNew"))) { + avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY); + goto fail; + } + if (!(reply = dbus_connection_send_with_reply_and_block (client->bus, message, -1, &error)) || + dbus_error_is_set (&error)) { avahi_client_set_errno (client, AVAHI_ERR_DBUS_ERROR); goto fail; } - dbus_message_get_args (reply, &error, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID); - - if (dbus_error_is_set (&error)) - { + if (!dbus_message_get_args(reply, &error, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID) || + dbus_error_is_set (&error)) { avahi_client_set_errno (client, AVAHI_ERR_DBUS_ERROR); goto fail; } + + if (!(group->path = avahi_strdup (path))) { - tmp = avahi_new(AvahiEntryGroup, 1); + /* FIXME: We don't remove the object on the server side */ - tmp->client = client; + avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY); + goto fail; + } - tmp->path = avahi_strdup (path); - tmp->callback = callback; - tmp->userdata = user_data; - AVAHI_LLIST_PREPEND(AvahiEntryGroup, groups, client->groups, tmp); + if (retrieve_state(group) < 0) + goto fail; - dbus_message_unref (message); + dbus_message_unref(message); + dbus_message_unref(reply); - avahi_client_set_errno (client, AVAHI_OK); - return tmp; + return group; fail: - if (tmp) avahi_free (tmp); - if (message) dbus_message_unref (message); + if (dbus_error_is_set(&error)) { + avahi_client_set_dbus_error(client, &error); + dbus_error_free(&error); + } + + if (group) + avahi_entry_group_free(group); + + if (message) + dbus_message_unref(message); + + if (reply) + dbus_message_unref(reply); + return NULL; } -int -avahi_entry_group_free (AvahiEntryGroup *group) -{ - AvahiClient *client = group->client; - DBusMessage *message; - - if (group == NULL || group->path == NULL) - return avahi_client_set_errno (client, AVAHI_ERR_INVALID_OBJECT); +static int entry_group_simple_method_call(AvahiEntryGroup *group, const char *method) { + DBusMessage *message, *reply; + DBusError error; + int r = AVAHI_OK; + AvahiClient *client; + + dbus_error_init(&error); - message = dbus_message_new_method_call (AVAHI_DBUS_NAME, - group->path, AVAHI_DBUS_INTERFACE_ENTRY_GROUP, "Free"); + assert(group); + client = group->client; + + if (!(message = dbus_message_new_method_call(AVAHI_DBUS_NAME, group->path, AVAHI_DBUS_INTERFACE_ENTRY_GROUP, method))) { + r = avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY); + goto fail; + } + + if (!(reply = dbus_connection_send_with_reply_and_block(client->bus, message, -1, &error)) || + dbus_error_is_set (&error)) { + r = avahi_client_set_errno(client, AVAHI_ERR_DBUS_ERROR); + goto fail; + } + + if (!dbus_message_get_args(reply, &error, DBUS_TYPE_INVALID) || + dbus_error_is_set (&error)) { + r = avahi_client_set_errno(client, AVAHI_ERR_DBUS_ERROR); + goto fail; + } - if (message == NULL) - return avahi_client_set_errno (client, AVAHI_ERR_DBUS_ERROR); + dbus_message_unref(message); + dbus_message_unref(reply); - dbus_connection_send (client->bus, message, NULL); + return AVAHI_OK; - AVAHI_LLIST_REMOVE(AvahiEntryGroup, groups, client->groups, group); +fail: + if (dbus_error_is_set(&error)) { + r = avahi_client_set_dbus_error(client, &error); + dbus_error_free(&error); + } + + if (message) + dbus_message_unref(message); - avahi_free (group); + if (reply) + dbus_message_unref(reply); - return avahi_client_set_errno (client, AVAHI_OK); + return r; } -int -avahi_entry_group_commit (AvahiEntryGroup *group) -{ - DBusMessage *message; - DBusError error; +int avahi_entry_group_free(AvahiEntryGroup *group) { + AvahiClient *client = group->client; + int r = AVAHI_OK; + + assert(group); + + if (group->path && client->state != AVAHI_CLIENT_DISCONNECTED) + r = entry_group_simple_method_call(group, "Free"); + + AVAHI_LLIST_REMOVE(AvahiEntryGroup, groups, client->groups, group); - dbus_error_init (&error); + avahi_free(group->path); + avahi_free(group); - message = dbus_message_new_method_call (AVAHI_DBUS_NAME, group->path, - AVAHI_DBUS_INTERFACE_ENTRY_GROUP, "Commit"); + return r; +} - dbus_connection_send (group->client->bus, message, NULL); +int avahi_entry_group_commit(AvahiEntryGroup *group) { + assert(group); + + if (!group->path || group->client->state == AVAHI_CLIENT_DISCONNECTED) + return avahi_client_set_errno(group->client, AVAHI_ERR_BAD_STATE); - return avahi_client_set_errno (group->client, AVAHI_OK); + return entry_group_simple_method_call(group, "Commit"); } -int -avahi_entry_group_reset (AvahiEntryGroup *group) -{ - DBusMessage *message; +int avahi_entry_group_reset(AvahiEntryGroup *group) { + assert(group); + + if (!group->path || group->client->state == AVAHI_CLIENT_DISCONNECTED) + return avahi_client_set_errno(group->client, AVAHI_ERR_BAD_STATE); - message = dbus_message_new_method_call (AVAHI_DBUS_NAME, group->path, - AVAHI_DBUS_INTERFACE_ENTRY_GROUP, "Reset"); + return entry_group_simple_method_call(group, "Reset"); +} - dbus_connection_send (group->client->bus, message, NULL); +int avahi_entry_group_get_state (AvahiEntryGroup *group) { + assert (group); - return avahi_client_set_errno (group->client, AVAHI_OK); + return group->state; } -int -avahi_entry_group_get_state (AvahiEntryGroup *group) -{ +AvahiClient* avahi_entry_group_get_client (AvahiEntryGroup *group) { + assert(group); + + return group->client; +} + +int avahi_entry_group_is_empty (AvahiEntryGroup *group) { DBusMessage *message, *reply; DBusError error; - int state; - - dbus_error_init (&error); - - message = dbus_message_new_method_call (AVAHI_DBUS_NAME, group->path, - AVAHI_DBUS_INTERFACE_ENTRY_GROUP, "GetState"); - - reply = dbus_connection_send_with_reply_and_block (group->client->bus, message, -1, &error); - - if (dbus_error_is_set (&error)) - { - dbus_error_free (&error); + int r = AVAHI_OK; + int b; + AvahiClient *client; + + assert(group); + client = group->client; - return avahi_client_set_errno (group->client, AVAHI_ERR_DBUS_ERROR); + dbus_error_init(&error); + + if (!(message = dbus_message_new_method_call(AVAHI_DBUS_NAME, group->path, AVAHI_DBUS_INTERFACE_ENTRY_GROUP, "IsEmpty"))) { + r = avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY); + goto fail; + } + + if (!(reply = dbus_connection_send_with_reply_and_block(client->bus, message, -1, &error)) || + dbus_error_is_set (&error)) { + r = avahi_client_set_errno(client, AVAHI_ERR_DBUS_ERROR); + goto fail; + } + + if (!dbus_message_get_args(reply, &error, DBUS_TYPE_BOOLEAN, &b, DBUS_TYPE_INVALID) || + dbus_error_is_set (&error)) { + r = avahi_client_set_errno(client, AVAHI_ERR_DBUS_ERROR); + goto fail; } - dbus_message_get_args(message, &error, DBUS_TYPE_BOOLEAN, &state, DBUS_TYPE_INVALID); - - if (dbus_error_is_set (&error)) - { - dbus_error_free (&error); + dbus_message_unref(message); + dbus_message_unref(reply); - return avahi_client_set_errno (group->client, AVAHI_ERR_DBUS_ERROR); + return !!b; + +fail: + if (dbus_error_is_set(&error)) { + r = avahi_client_set_dbus_error(client, &error); + dbus_error_free(&error); } - avahi_client_set_errno (group->client, AVAHI_OK); - return state; -} + if (message) + dbus_message_unref(message); -int -avahi_client_errno (AvahiClient *client) -{ - return client->error; -} + if (reply) + dbus_message_unref(reply); -AvahiClient* -avahi_entry_group_get_client (AvahiEntryGroup *group) -{ - return group->client; -} - -int -avahi_entry_group_is_empty (AvahiEntryGroup *group) -{ - return AVAHI_OK; + return r; } -int -avahi_entry_group_add_service (AvahiEntryGroup *group, - AvahiIfIndex interface, - AvahiProtocol protocol, - const char *name, - const char *type, - const char *domain, - const char *host, - uint16_t port, - AvahiStringList *txt) -{ - DBusMessage *message; +int avahi_entry_group_add_service_strlst( + AvahiEntryGroup *group, + AvahiIfIndex interface, + AvahiProtocol protocol, + const char *name, + const char *type, + const char *domain, + const char *host, + uint16_t port, + AvahiStringList *txt) { + + DBusMessage *message = NULL, *reply = NULL; DBusMessageIter iter, sub; AvahiStringList *p; + int reverse = 0, r = AVAHI_OK; + DBusError error; + AvahiClient *client; - message = dbus_message_new_method_call (AVAHI_DBUS_NAME, group->path, - AVAHI_DBUS_INTERFACE_ENTRY_GROUP, "AddService"); + assert(group); + assert(name); + assert(type); - if (!message) - { - dbus_message_unref (message); - return avahi_client_set_errno (group->client, AVAHI_ERR_DBUS_ERROR); + client = group->client; + + dbus_error_init(&error); + + if (!(message = dbus_message_new_method_call (AVAHI_DBUS_NAME, group->path, AVAHI_DBUS_INTERFACE_ENTRY_GROUP, "AddService"))) { + r = avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY); + goto fail; } - if (!dbus_message_append_args (message, DBUS_TYPE_INT32, &interface, DBUS_TYPE_INT32, &protocol, - DBUS_TYPE_STRING, &name, DBUS_TYPE_STRING, &type, DBUS_TYPE_STRING, &domain, - DBUS_TYPE_STRING, &host, DBUS_TYPE_UINT16, &port, DBUS_TYPE_INVALID)) - { - dbus_message_unref (message); - return avahi_client_set_errno (group->client, AVAHI_ERR_DBUS_ERROR); + if (!dbus_message_append_args( + message, + DBUS_TYPE_INT32, &interface, + DBUS_TYPE_INT32, &protocol, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_STRING, &type, + DBUS_TYPE_STRING, &domain, + DBUS_TYPE_STRING, &host, + DBUS_TYPE_UINT16, &port, + DBUS_TYPE_INVALID)) { + r = avahi_client_set_errno(group->client, AVAHI_ERR_NO_MEMORY); + goto fail; } dbus_message_iter_init_append(message, &iter); - dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_BYTE_AS_STRING, &sub); + + /* Reverse the string list, so that we can pass it in-order to the server */ + txt = avahi_string_list_reverse(txt); + reverse = 1; + + if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "ay", &sub)) { + r = avahi_client_set_errno(group->client, AVAHI_ERR_NO_MEMORY); + goto fail; + } /* Assemble the AvahiStringList into an Array of Array of Bytes to send over dbus */ for (p = txt; p != NULL; p = p->next) { DBusMessageIter sub2; const uint8_t *data = p->text; + + if (!(dbus_message_iter_open_container(&sub, DBUS_TYPE_ARRAY, "y", &sub2)) || + !(dbus_message_iter_append_fixed_array(&sub2, DBUS_TYPE_BYTE, &data, p->size)) || + !(dbus_message_iter_close_container(&sub, &sub2))) { + r = avahi_client_set_errno(group->client, AVAHI_ERR_NO_MEMORY); + goto fail; + } + } + + if (!dbus_message_iter_close_container(&iter, &sub)) { + r = avahi_client_set_errno(group->client, AVAHI_ERR_NO_MEMORY); + goto fail; + } + + /* Reverse the string list to the original state */ + txt = avahi_string_list_reverse(txt); + reverse = 0; + + if (!(reply = dbus_connection_send_with_reply_and_block(client->bus, message, -1, &error)) || + dbus_error_is_set (&error)) { + r = avahi_client_set_errno(client, AVAHI_ERR_DBUS_ERROR); + goto fail; + } + + if (!dbus_message_get_args(reply, &error, DBUS_TYPE_INVALID) || + dbus_error_is_set (&error)) { + r = avahi_client_set_errno(client, AVAHI_ERR_DBUS_ERROR); + goto fail; + } - dbus_message_iter_open_container(&sub, DBUS_TYPE_ARRAY, "y", &sub2); - dbus_message_iter_append_fixed_array(&sub2, DBUS_TYPE_BYTE, &data, p->size); - dbus_message_iter_close_container(&sub, &sub2); + dbus_message_unref(message); + dbus_message_unref(reply); + + return AVAHI_OK; + +fail: + if (reverse) + txt = avahi_string_list_reverse(txt); + + if (dbus_error_is_set(&error)) { + r = avahi_client_set_dbus_error(client, &error); + dbus_error_free(&error); } - dbus_message_iter_close_container(&iter, &sub); + if (message) + dbus_message_unref(message); - dbus_connection_send (group->client->bus, message, NULL); + if (reply) + dbus_message_unref(reply); - return avahi_client_set_errno (group->client, AVAHI_OK); + return r; } -/* XXX: debug function */ -const char* avahi_entry_group_path (AvahiEntryGroup *group) -{ - if (group != NULL) return group->path; - else return NULL; +int avahi_entry_group_add_service( + AvahiEntryGroup *group, + AvahiIfIndex interface, + AvahiProtocol protocol, + const char *name, + const char *type, + const char *domain, + const char *host, + uint16_t port, + ...) { + + va_list va; + int r; + + assert(group); + + va_start(va, port); + r = avahi_entry_group_add_service_va(group, interface, protocol, name, type, domain, host, port, va); + va_end(va); + return r; +} + +int avahi_entry_group_add_service_va( + AvahiEntryGroup *group, + AvahiIfIndex interface, + AvahiProtocol protocol, + const char *name, + const char *type, + const char *domain, + const char *host, + uint16_t port, + va_list va) { + + int r; + AvahiStringList *txt; + + assert(group); + + txt = avahi_string_list_new_va(va); + r = avahi_entry_group_add_service_strlst(group, interface, protocol, name, type, domain, host, port, txt); + avahi_string_list_free(txt); + + return r; +} + +const char* avahi_entry_group_get_dbus_path(AvahiEntryGroup *group) { + assert(group); + + return group->path; } diff --git a/avahi-client/internal.h b/avahi-client/internal.h index 92a5fbc..3859d70 100644 --- a/avahi-client/internal.h +++ b/avahi-client/internal.h @@ -29,8 +29,11 @@ struct AvahiClient { const AvahiPoll *poll_api; DBusConnection *bus; int error; - AvahiServerState state; + AvahiClientState state; + /* Cache for some seldom changing server data */ + char *version_string, *host_name, *host_name_fqdn, *domain_name; + AvahiClientCallback callback; void *userdata; @@ -42,6 +45,7 @@ struct AvahiClient { struct AvahiEntryGroup { char *path; + AvahiEntryGroupState state; AvahiClient *client; AvahiEntryGroupCallback callback; void *userdata; @@ -73,8 +77,9 @@ struct AvahiServiceTypeBrowser { }; int avahi_client_set_errno (AvahiClient *client, int error); +int avahi_client_set_dbus_error(AvahiClient *client, DBusError *error); -void avahi_entry_group_state_change (AvahiEntryGroup *group, int state); +void avahi_entry_group_set_state(AvahiEntryGroup *group, AvahiEntryGroupState state); DBusHandlerResult avahi_domain_browser_event (AvahiClient *client, AvahiBrowserEvent event, DBusMessage *message); diff --git a/avahi-common/dbus.c b/avahi-common/dbus.c index 7c627a6..e2b3a3f 100644 --- a/avahi-common/dbus.c +++ b/avahi-common/dbus.c @@ -31,52 +31,48 @@ #include static const char * 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, - AVAHI_DBUS_ERR_ACCESS_DENIED, - AVAHI_DBUS_ERR_INVALID_OPERATION, - AVAHI_DBUS_ERR_DBUS_ERROR, - AVAHI_DBUS_ERR_NOT_CONNECTED, - AVAHI_DBUS_ERR_NO_MEMORY, - AVAHI_DBUS_ERR_INVALID_OBJECT, - AVAHI_DBUS_ERR_NO_DAEMON - }; + 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, + AVAHI_DBUS_ERR_ACCESS_DENIED, + AVAHI_DBUS_ERR_INVALID_OPERATION, + AVAHI_DBUS_ERR_DBUS_ERROR, + AVAHI_DBUS_ERR_NOT_CONNECTED, + AVAHI_DBUS_ERR_NO_MEMORY, + AVAHI_DBUS_ERR_INVALID_OBJECT, + AVAHI_DBUS_ERR_NO_DAEMON +}; -int -avahi_error_dbus_to_number (const char *s) -{ +int avahi_error_dbus_to_number(const char *s) { int e; assert(s); for (e = -1; e > AVAHI_ERR_MAX; e--) - if (strcmp (s, table[-e]) == 0) + if (strcmp(s, table[-e]) == 0) return e; return AVAHI_ERR_DBUS_ERROR; } -const char * -avahi_error_number_to_dbus (int error) -{ +const char *avahi_error_number_to_dbus(int error) { assert(error > AVAHI_ERR_MAX); assert(error < 1); diff --git a/avahi-common/dbus.h b/avahi-common/dbus.h index 0164bdb..bcbbb99 100644 --- a/avahi-common/dbus.h +++ b/avahi-common/dbus.h @@ -27,7 +27,9 @@ #include #include +#ifndef DOXYGEN_SHOULD_SKIP_THIS AVAHI_C_DECL_BEGIN +#endif #define AVAHI_DBUS_NAME "org.freedesktop.Avahi" #define AVAHI_DBUS_INTERFACE_SERVER AVAHI_DBUS_NAME".Server" @@ -64,13 +66,14 @@ AVAHI_C_DECL_BEGIN #define AVAHI_DBUS_ERR_INVALID_OBJECT "org.freedesktop.Avahi.InvalidObjectError" #define AVAHI_DBUS_ERR_NO_DAEMON "org.freedesktop.Avahi.NoDaemonError" - /** Convert a DBus error string into an Avahi error number */ -int avahi_error_dbus_to_number (const char *s); +int avahi_error_dbus_to_number(const char *s); /** Convert an Avahi error number into a DBus error string. Result should not be freed */ -const char * avahi_error_number_to_dbus (int error); +const char * avahi_error_number_to_dbus(int error); +#ifndef DOXYGEN_SHOULD_SKIP_THIS AVAHI_C_DECL_END +#endif #endif diff --git a/avahi-common/error.h b/avahi-common/error.h index b367ffb..dc3f333 100644 --- a/avahi-common/error.h +++ b/avahi-common/error.h @@ -26,7 +26,24 @@ #include +/** \mainpage + * + * \section Error Reporting + * + * Some notes on the Avahai erro handling: + * + * \li Error codes are negative integers and defined in the enum AVAHI_ERR_xx + * \li If a function returns some kind of non-negative integer value on success, a failure is indicated by returning the error code directly. + * \li If a function returns a pointer of some kind on success, a failure is indicated by returning NULL + * \li The last error number may be retrieved by calling avahi_server_errno() (for the server API) or avahi_client_errno() (for the client API) + * \li Just like the libc errno the Avahi errno is NOT reset to AVAHI_OK if a function call succeeds. + * \li You may convert a numeric error code into a human readable string using avahi_strerror.c + * + */ + +#ifndef DOXYGEN_SHOULD_SKIP_THIS AVAHI_C_DECL_BEGIN +#endif /** Error codes used by avahi */ enum { @@ -61,8 +78,7 @@ enum { /**** **** IF YOU ADD A NEW ERROR CODE HERE, PLEASE DON'T FORGET TO ADD **** IT TO THE STRING ARRAY IN avahi_strerror() IN error.c AND - **** TO THE ARRAY IN respond_error() IN dbus-protocol.c - **** AND FINALLY TO dbus.h! + **** TO THE ARRAY IN dbus.c AND FINALLY TO dbus.h! **** **** Also remember to update the MAX value below. ****/ @@ -73,6 +89,8 @@ enum { /** Return a human readable error string for the specified error code */ const char *avahi_strerror(int error); +#ifndef DOXYGEN_SHOULD_SKIP_THIS AVAHI_C_DECL_END +#endif #endif diff --git a/avahi-common/gccmacro.h b/avahi-common/gccmacro.h index 24f206f..33ff847 100644 --- a/avahi-common/gccmacro.h +++ b/avahi-common/gccmacro.h @@ -24,6 +24,12 @@ /** \file gccmacro.h Defines some macros for GCC extensions */ +#include + +#ifndef DOXYGEN_SHOULD_SKIP_THIS +AVAHI_C_DECL_BEGIN +#endif + #ifdef __GNUC__ #if __GNUC__ >= 4 #define AVAHI_GCC_SENTINEL __attribute__ ((sentinel)) @@ -55,4 +61,8 @@ #define AVAHI_GCC_NORETURN #endif +#ifndef DOXYGEN_SHOULD_SKIP_THIS +AVAHI_C_DECL_END +#endif + #endif -- cgit