X-Git-Url: http://git.meshlink.io/?a=blobdiff_plain;f=avahi-client%2Fclient.c;h=93d768a85bef970558ccc8959fa57a1110f1991a;hb=5af9f469d85a9281bc5484e9f5a8740751591dfe;hp=2361cbc1c3d1e755db8090c3ea37e98122fa1b48;hpb=d0c6f66e03793c19c034c26c1267f9382167b3ad;p=catta diff --git a/avahi-client/client.c b/avahi-client/client.c index 2361cbc..93d768a 100644 --- a/avahi-client/client.c +++ b/avahi-client/client.c @@ -102,10 +102,10 @@ static DBusHandlerResult filter_func(DBusConnection *bus, DBusMessage *message, 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)); +/* 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)); */ if (client->state == AVAHI_CLIENT_DISCONNECTED) goto fail; @@ -185,6 +185,22 @@ static DBusHandlerResult filter_func(DBusConnection *bus, DBusMessage *message, else if (dbus_message_is_signal(message, AVAHI_DBUS_INTERFACE_SERVICE_BROWSER, "ItemRemove")) return avahi_service_browser_event (client, AVAHI_BROWSER_REMOVE, message); + else if (dbus_message_is_signal(message, AVAHI_DBUS_INTERFACE_SERVICE_RESOLVER, "Found")) + return avahi_service_resolver_event (client, AVAHI_RESOLVER_FOUND, message); + else if (dbus_message_is_signal(message, AVAHI_DBUS_INTERFACE_SERVICE_RESOLVER, "Timeout")) + return avahi_service_resolver_event (client, AVAHI_RESOLVER_TIMEOUT, message); + + else if (dbus_message_is_signal(message, AVAHI_DBUS_INTERFACE_HOST_NAME_RESOLVER, "Found")) + return avahi_host_name_resolver_event (client, AVAHI_RESOLVER_FOUND, message); + else if (dbus_message_is_signal(message, AVAHI_DBUS_INTERFACE_HOST_NAME_RESOLVER, "Timeout")) + return avahi_host_name_resolver_event (client, AVAHI_RESOLVER_TIMEOUT, message); + + else if (dbus_message_is_signal(message, AVAHI_DBUS_INTERFACE_ADDRESS_RESOLVER, "Found")) + return avahi_address_resolver_event (client, AVAHI_RESOLVER_FOUND, message); + else if (dbus_message_is_signal(message, AVAHI_DBUS_INTERFACE_ADDRESS_RESOLVER, "Timeout")) + return avahi_address_resolver_event (client, AVAHI_RESOLVER_TIMEOUT, message); + + return DBUS_HANDLER_RESULT_HANDLED; fail: @@ -232,6 +248,39 @@ fail: return e; } +/* This function acts like dbus_bus_get but creates a private + * connection instead */ +static DBusConnection* +avahi_dbus_bus_get (DBusError *error) +{ + DBusConnection *conn; + const char *env_addr; + + env_addr = getenv ("DBUS_SYSTEM_BUS_ADDRESS"); + + if (env_addr == NULL || (*env_addr == 0)) + { + env_addr = DBUS_SYSTEM_BUS_DEFAULT_ADDRESS; + } + + conn = dbus_connection_open_private (env_addr, error); + + if (!conn) + return NULL; + + dbus_connection_set_exit_on_disconnect (conn, FALSE); + + if (!dbus_bus_register (conn, error)) + { + dbus_connection_close (conn); + dbus_connection_unref (conn); + + return NULL; + } + + return conn; +} + AvahiClient *avahi_client_new(const AvahiPoll *poll_api, AvahiClientCallback callback, void *userdata, int *ret_error) { AvahiClient *client = NULL; DBusError error; @@ -254,13 +303,17 @@ AvahiClient *avahi_client_new(const AvahiPoll *poll_api, AvahiClientCallback cal client->host_name_fqdn = NULL; client->domain_name = NULL; client->version_string = NULL; - + client->local_service_cookie_valid = 0; + AVAHI_LLIST_HEAD_INIT(AvahiEntryGroup, client->groups); AVAHI_LLIST_HEAD_INIT(AvahiDomainBrowser, client->domain_browsers); AVAHI_LLIST_HEAD_INIT(AvahiServiceBrowser, client->service_browsers); AVAHI_LLIST_HEAD_INIT(AvahiServiceTypeBrowser, client->service_type_browsers); + AVAHI_LLIST_HEAD_INIT(AvahiServiceResolver, client->service_resolvers); + AVAHI_LLIST_HEAD_INIT(AvahiHostNameResolver, client->host_name_resolvers); + AVAHI_LLIST_HEAD_INIT(AvahiAddressResolver, client->address_resolvers); - if (!(client->bus = dbus_bus_get(DBUS_BUS_SYSTEM, &error)) || + if (!(client->bus = avahi_dbus_bus_get(&error)) || dbus_error_is_set (&error)) goto fail; @@ -352,6 +405,9 @@ void avahi_client_free(AvahiClient *client) { while (client->service_type_browsers) avahi_service_type_browser_free(client->service_type_browsers); + while (client->service_resolvers) + avahi_service_resolver_free(client->service_resolvers); + if (client->bus) { dbus_connection_disconnect(client->bus); dbus_connection_unref(client->bus); @@ -488,3 +544,170 @@ int avahi_client_errno(AvahiClient *client) { return client->error; } + +/* Just for internal use */ +int avahi_client_simple_method_call(AvahiClient *client, const char *path, const char *interface, const char *method) { + DBusMessage *message = NULL, *reply = NULL; + DBusError error; + int r = AVAHI_OK; + + dbus_error_init(&error); + + assert(client); + assert(path); + assert(interface); + assert(method); + + if (!(message = dbus_message_new_method_call(AVAHI_DBUS_NAME, path, interface, 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; + } + + dbus_message_unref(message); + dbus_message_unref(reply); + + return AVAHI_OK; + +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); + + if (reply) + dbus_message_unref(reply); + + return r; +} + +uint32_t avahi_client_get_local_service_cookie(AvahiClient *client) { + DBusMessage *message = NULL, *reply = NULL; + DBusError error; + assert(client); + + if (client->state == AVAHI_CLIENT_DISCONNECTED) { + avahi_client_set_errno(client, AVAHI_ERR_BAD_STATE); + return AVAHI_SERVICE_COOKIE_INVALID; + } + + if (client->local_service_cookie_valid) + return client->local_service_cookie; + + dbus_error_init (&error); + + if (!(message = dbus_message_new_method_call(AVAHI_DBUS_NAME, AVAHI_DBUS_PATH_SERVER, AVAHI_DBUS_INTERFACE_SERVER, "GetLocalServiceCookie"))) { + 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_UINT32, &client->local_service_cookie, DBUS_TYPE_INVALID) || + dbus_error_is_set (&error)) + goto fail; + + dbus_message_unref(message); + dbus_message_unref(reply); + + client->local_service_cookie_valid = 1; + return client->local_service_cookie; + +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 AVAHI_SERVICE_COOKIE_INVALID; +} + +int avahi_client_is_service_local(AvahiClient *client, AvahiIfIndex interface, AvahiProtocol protocol, const char *name, const char *type, const char *domain) { + DBusMessage *message = NULL, *reply = NULL; + DBusError error; + int32_t i_interface, i_protocol; + int b; + + assert(client); + assert(name); + assert(type); + assert(domain); + + if (client->state == AVAHI_CLIENT_DISCONNECTED) { + avahi_client_set_errno(client, AVAHI_ERR_BAD_STATE); + return AVAHI_SERVICE_COOKIE_INVALID; + } + + dbus_error_init (&error); + + if (!(message = dbus_message_new_method_call(AVAHI_DBUS_NAME, AVAHI_DBUS_PATH_SERVER, AVAHI_DBUS_INTERFACE_SERVER, "IsServiceLocal"))) { + avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY); + goto fail; + } + + i_interface = (int32_t) interface; + i_protocol = (int32_t) protocol; + + if (!dbus_message_append_args( + message, + DBUS_TYPE_INT32, &i_interface, + DBUS_TYPE_INT32, &i_protocol, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_STRING, &type, + DBUS_TYPE_STRING, &domain, + 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_BOOLEAN, &b, DBUS_TYPE_INVALID) || + dbus_error_is_set (&error)) + goto fail; + + dbus_message_unref(message); + dbus_message_unref(reply); + + return b; + +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 AVAHI_SERVICE_COOKIE_INVALID; +}