X-Git-Url: http://git.meshlink.io/?a=blobdiff_plain;f=avahi-client%2Fclient.c;h=f665613c0598e09dc3199620a38bbab0bcdc92b3;hb=043eb084c1c76f5b62fc1745942bddfddf17fbf1;hp=54d19e57724aec3196af1182d764d13edd0b886f;hpb=9e4237ebed07d00bf1176178d1358b475d749b27;p=catta diff --git a/avahi-client/client.c b/avahi-client/client.c index 54d19e5..f665613 100644 --- a/avahi-client/client.c +++ b/avahi-client/client.c @@ -39,6 +39,8 @@ #include "client.h" #include "internal.h" +#define AVAHI_CLIENT_DBUS_API_SUPPORTED ((uint32_t) 0x0201) + static int init_server(AvahiClient *client, int *ret_error); int avahi_client_set_errno (AvahiClient *client, int error) { @@ -65,7 +67,11 @@ static void client_set_state (AvahiClient *client, AvahiServerState state) { switch (client->state) { case AVAHI_CLIENT_FAILURE: if (client->bus) { +#ifdef HAVE_DBUS_CONNECTION_CLOSE + dbus_connection_close(client->bus); +#else dbus_connection_disconnect(client->bus); +#endif dbus_connection_unref(client->bus); client->bus = NULL; } @@ -345,26 +351,57 @@ fail: static int check_version(AvahiClient *client, int *ret_error) { DBusMessage *message = NULL, *reply = NULL; DBusError error; - char *version; + uint32_t version; int e = AVAHI_ERR_NO_MEMORY; assert(client); dbus_error_init(&error); - if (!(message = dbus_message_new_method_call(AVAHI_DBUS_NAME, AVAHI_DBUS_PATH_SERVER, AVAHI_DBUS_INTERFACE_SERVER, "GetVersionString"))) + if (!(message = dbus_message_new_method_call(AVAHI_DBUS_NAME, AVAHI_DBUS_PATH_SERVER, AVAHI_DBUS_INTERFACE_SERVER, "GetAPIVersion"))) goto fail; reply = dbus_connection_send_with_reply_and_block (client->bus, message, -1, &error); - if (!reply || dbus_error_is_set (&error)) - goto fail; + if (!reply || dbus_error_is_set (&error)) { + char *version_str; - if (!dbus_message_get_args (reply, &error, DBUS_TYPE_STRING, &version, DBUS_TYPE_INVALID) || - dbus_error_is_set (&error)) - goto fail; + if (!dbus_error_is_set(&error) || strcmp(error.name, DBUS_ERROR_UNKNOWN_METHOD)) + goto fail; + + /* If the method GetAPIVersion is not known, we look if + * GetVersionString matches "avahi 0.6" which is the only + * version we support which doesn't have GetAPIVersion() .*/ + + dbus_message_unref(message); + if (reply) dbus_message_unref(reply); + dbus_error_free(&error); + + if (!(message = dbus_message_new_method_call(AVAHI_DBUS_NAME, AVAHI_DBUS_PATH_SERVER, AVAHI_DBUS_INTERFACE_SERVER, "GetVersionString"))) + goto fail; + + reply = dbus_connection_send_with_reply_and_block (client->bus, message, -1, &error); + + if (!reply || dbus_error_is_set (&error)) + goto fail; + + if (!dbus_message_get_args (reply, &error, DBUS_TYPE_STRING, &version_str, DBUS_TYPE_INVALID) || + dbus_error_is_set (&error)) + goto fail; + + version = strcmp(version_str, "avahi 0.6") == 0 ? 0x0201 : 0x0000; + + } else { + + if (!dbus_message_get_args (reply, &error, DBUS_TYPE_UINT32, &version, DBUS_TYPE_INVALID) || + dbus_error_is_set(&error)) + goto fail; + } - if (strcmp(version, PACKAGE_STRING) != 0) { + /*fprintf(stderr, "API Version 0x%04x\n", version);*/ + + if ((version & 0xFF00) != (AVAHI_CLIENT_DBUS_API_SUPPORTED & 0xFF00) || + (version & 0x00FF) < (AVAHI_CLIENT_DBUS_API_SUPPORTED & 0x00FF)) { e = AVAHI_ERR_VERSION_MISMATCH; goto fail; } @@ -404,11 +441,18 @@ static int init_server(AvahiClient *client, int *ret_error) { } /* This function acts like dbus_bus_get but creates a private - * connection instead */ + * connection instead. */ static DBusConnection* avahi_dbus_bus_get(DBusError *error) { DBusConnection *c; - const char *a; +#ifdef HAVE_DBUS_BUS_GET_PRIVATE + if (!(c = dbus_bus_get_private(DBUS_BUS_SYSTEM, error))) + return NULL; + + dbus_connection_set_exit_on_disconnect(c, FALSE); +#else + const char *a; + if (!(a = getenv("DBUS_SYSTEM_BUS_ADDRESS")) || !*a) a = DBUS_SYSTEM_BUS_DEFAULT_ADDRESS; @@ -418,10 +462,15 @@ static DBusConnection* avahi_dbus_bus_get(DBusError *error) { dbus_connection_set_exit_on_disconnect(c, FALSE); if (!dbus_bus_register(c, error)) { +#ifdef HAVE_DBUS_CONNECTION_CLOSE dbus_connection_close(c); +#else + dbus_connection_disconnect(c); +#endif dbus_connection_unref(c); return NULL; } +#endif return c; } @@ -544,8 +593,13 @@ fail: if (dbus_error_is_set(&error)) { - if (ret_error) - *ret_error = avahi_error_dbus_to_number(error.name); + if (ret_error) { + if (strcmp(error.name, DBUS_ERROR_FILE_NOT_FOUND) == 0) + /* DBUS returns this error when the DBUS daemon is not running */ + *ret_error = AVAHI_ERR_NO_DAEMON; + else + *ret_error = avahi_error_dbus_to_number(error.name); + } dbus_error_free(&error); } @@ -556,6 +610,15 @@ fail: void avahi_client_free(AvahiClient *client) { assert(client); + if (client->bus) + /* Disconnect in advance, so that the free() functions won't + * issue needless server calls */ +#ifdef HAVE_DBUS_CONNECTION_CLOSE + dbus_connection_close(client->bus); +#else + dbus_connection_disconnect(client->bus); +#endif + while (client->groups) avahi_entry_group_free(client->groups); @@ -580,10 +643,8 @@ void avahi_client_free(AvahiClient *client) { while (client->record_browsers) avahi_record_browser_free(client->record_browsers); - if (client->bus) { - dbus_connection_disconnect(client->bus); + if (client->bus) dbus_connection_unref(client->bus); - } avahi_free(client->version_string); avahi_free(client->host_name); @@ -820,5 +881,63 @@ fail: int avahi_client_is_connected(AvahiClient *client) { assert(client); - return client->state == AVAHI_CLIENT_S_RUNNING || client->state == AVAHI_CLIENT_S_REGISTERING || client->state == AVAHI_CLIENT_S_COLLISION; + return + client->bus && + dbus_connection_get_is_connected(client->bus) && + (client->state == AVAHI_CLIENT_S_RUNNING || client->state == AVAHI_CLIENT_S_REGISTERING || client->state == AVAHI_CLIENT_S_COLLISION); +} + +int avahi_client_set_host_name(AvahiClient* client, const char *name) { + DBusMessage *message = NULL, *reply = NULL; + DBusError error; + + assert(client); + + if (!avahi_client_is_connected(client)) + return avahi_client_set_errno(client, AVAHI_ERR_BAD_STATE); + + dbus_error_init (&error); + + if (!(message = dbus_message_new_method_call (AVAHI_DBUS_NAME, AVAHI_DBUS_PATH_SERVER, AVAHI_DBUS_INTERFACE_SERVER, "SetHostName"))) { + avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY); + goto fail; + } + + if (!dbus_message_append_args (message, DBUS_TYPE_STRING, &name, 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 (!reply || dbus_error_is_set (&error)) + goto fail; + + if (!dbus_message_get_args(reply, &error, DBUS_TYPE_INVALID) || + dbus_error_is_set (&error)) + goto fail; + + dbus_message_unref(message); + dbus_message_unref(reply); + + avahi_free(client->host_name); + client->host_name = NULL; + avahi_free(client->host_name_fqdn); + client->host_name_fqdn = NULL; + + return 0; + +fail: + + 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); + } + + return client->error; }