From abc3054d3823547b72f44e51faef63b51f028b3e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 28 Aug 2005 01:15:48 +0000 Subject: * Move service/host name/address resolvers to asynchronous interfaces * drop xxx_get_dbus_path() functions * drop xxx_block() functions * fix compiler warning about missing const * fix some minor memory corruption bugs git-svn-id: file:///home/lennart/svn/public/avahi/trunk@462 941a03a8-eaeb-0310-b9a0-b1bbd8fe43fe --- avahi-client/browser.c | 78 +-------- avahi-client/client-test.c | 45 ++--- avahi-client/client.c | 69 +++++++- avahi-client/client.h | 21 --- avahi-client/internal.h | 12 +- avahi-client/resolver.c | 424 ++++++++++++++++++++++++--------------------- 6 files changed, 336 insertions(+), 313 deletions(-) diff --git a/avahi-client/browser.c b/avahi-client/browser.c index 854ed1f..34a3601 100644 --- a/avahi-client/browser.c +++ b/avahi-client/browser.c @@ -38,55 +38,6 @@ #include "client.h" #include "internal.h" -static int 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; -} - AvahiDomainBrowser* avahi_domain_browser_new( AvahiClient *client, AvahiIfIndex interface, @@ -97,7 +48,7 @@ AvahiDomainBrowser* avahi_domain_browser_new( void *userdata) { AvahiDomainBrowser *db = NULL; - DBusMessage *message = NULL, *reply; + DBusMessage *message = NULL, *reply = NULL; DBusError error; char *path; int32_t i_interface, i_protocol, bt; @@ -206,7 +157,7 @@ int avahi_domain_browser_free (AvahiDomainBrowser *b) { client = b->client; if (b->path && client->state != AVAHI_CLIENT_DISCONNECTED) - r = simple_method_call(client, b->path, AVAHI_DBUS_INTERFACE_DOMAIN_BROWSER, "Free"); + r = avahi_client_simple_method_call(client, b->path, AVAHI_DBUS_INTERFACE_DOMAIN_BROWSER, "Free"); AVAHI_LLIST_REMOVE(AvahiDomainBrowser, domain_browsers, client->domain_browsers, b); @@ -216,12 +167,6 @@ int avahi_domain_browser_free (AvahiDomainBrowser *b) { return r; } -const char* avahi_domain_browser_get_dbus_path(AvahiDomainBrowser *b) { - assert(b); - - return b->path; -} - DBusHandlerResult avahi_domain_browser_event (AvahiClient *client, AvahiBrowserEvent event, DBusMessage *message) { AvahiDomainBrowser *db = NULL; DBusError error; @@ -274,7 +219,7 @@ AvahiServiceTypeBrowser* avahi_service_type_browser_new( void *userdata) { AvahiServiceTypeBrowser *b = NULL; - DBusMessage *message = NULL, *reply; + DBusMessage *message = NULL, *reply = NULL; DBusError error; char *path; int32_t i_interface, i_protocol; @@ -381,7 +326,7 @@ int avahi_service_type_browser_free (AvahiServiceTypeBrowser *b) { client = b->client; if (b->path && client->state != AVAHI_CLIENT_DISCONNECTED) - r = simple_method_call(client, b->path, AVAHI_DBUS_INTERFACE_SERVICE_TYPE_BROWSER, "Free"); + r = avahi_client_simple_method_call(client, b->path, AVAHI_DBUS_INTERFACE_SERVICE_TYPE_BROWSER, "Free"); AVAHI_LLIST_REMOVE(AvahiServiceTypeBrowser, service_type_browsers, b->client->service_type_browsers, b); @@ -390,12 +335,6 @@ int avahi_service_type_browser_free (AvahiServiceTypeBrowser *b) { return r; } -const char* avahi_service_type_browser_get_dbus_path(AvahiServiceTypeBrowser *b) { - assert(b); - - return b->path; -} - DBusHandlerResult avahi_service_type_browser_event (AvahiClient *client, AvahiBrowserEvent event, DBusMessage *message) { AvahiServiceTypeBrowser *b = NULL; DBusError error; @@ -451,7 +390,7 @@ AvahiServiceBrowser* avahi_service_browser_new( void *userdata) { AvahiServiceBrowser *b = NULL; - DBusMessage *message = NULL, *reply; + DBusMessage *message = NULL, *reply = NULL; DBusError error; char *path; int32_t i_protocol, i_interface; @@ -560,7 +499,7 @@ int avahi_service_browser_free (AvahiServiceBrowser *b) { client = b->client; if (b->path && client->state != AVAHI_CLIENT_DISCONNECTED) - r = simple_method_call(client, b->path, AVAHI_DBUS_INTERFACE_SERVICE_BROWSER, "Free"); + r = avahi_client_simple_method_call(client, b->path, AVAHI_DBUS_INTERFACE_SERVICE_BROWSER, "Free"); AVAHI_LLIST_REMOVE(AvahiServiceBrowser, service_browsers, b->client->service_browsers, b); @@ -569,11 +508,6 @@ int avahi_service_browser_free (AvahiServiceBrowser *b) { return r; } -const char* avahi_service_browser_get_dbus_path(AvahiServiceBrowser *b) { - assert(b); - - return b->path; -} DBusHandlerResult avahi_service_browser_event (AvahiClient *client, AvahiBrowserEvent event, DBusMessage *message) { AvahiServiceBrowser *b = NULL; diff --git a/avahi-client/client-test.c b/avahi-client/client-test.c index 67b977a..a65a925 100644 --- a/avahi-client/client-test.c +++ b/avahi-client/client-test.c @@ -37,19 +37,19 @@ static AvahiSimplePoll *simple_poll = NULL; static void avahi_client_callback (AvahiClient *c, AvahiClientState state, void *user_data) { - printf ("Callback on client, state -> %d, data -> %s\n", state, (char*)user_data); + printf ("CLIENT: Callback on %p, state -> %d, data -> %s\n", (void*) c, state, (char*)user_data); } static void avahi_entry_group_callback (AvahiEntryGroup *g, AvahiEntryGroupState state, void *user_data) { - printf ("Callback on %s, state -> %d, data -> %s\n", avahi_entry_group_get_dbus_path(g), state, (char*)user_data); + printf ("ENTRY-GROUP: Callback on %p, state -> %d, data -> %s\n", (void*) g, state, (char*)user_data); } static void avahi_domain_browser_callback (AvahiDomainBrowser *b, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, const char *domain, void *user_data) { - printf ("Callback on %s, interface (%d), protocol (%d), event (%d), domain (%s), data (%s)\n", avahi_domain_browser_get_dbus_path (b), interface, protocol, event, domain, (char*)user_data); + printf ("DOMAIN-BROWSER: Callback on %p, interface (%d), protocol (%d), event (%d), domain (%s), data (%s)\n", (void*) b, interface, protocol, event, domain, (char*)user_data); } static void @@ -59,30 +59,33 @@ avahi_service_resolver_callback (AvahiServiceResolver *r, AvahiIfIndex interface char *txtr; if (event == AVAHI_RESOLVER_TIMEOUT) { - printf ("ServiceResolver timed out\n"); - avahi_service_resolver_free (r); + printf ("SERVICE-RESOLVER: ServiceResolver %p timed out (%s %s)\n", (void*) r, name, type); return; } avahi_address_snprint (addr, sizeof (addr), a); txtr = avahi_string_list_to_string (txt); - printf ("Callback on ServiceResolver, interface (%d), protocol (%d), event (%d), name (%s), type (%s), domain (%s), host_name (%s), address (%s), port (%d), txtdata (%s), data(%s)\n", interface, protocol, event, name, type, domain, host_name, addr, port, txtr, (char*)user_data); + printf ("SERVICE-RESOLVER: Callback on ServiceResolver, interface (%d), protocol (%d), event (%d), name (%s), type (%s), domain (%s), host_name (%s), address (%s), port (%d), txtdata (%s), data(%s)\n", interface, protocol, event, name, type, domain, host_name, addr, port, txtr, (char*)user_data); + avahi_free(txtr); } static void avahi_service_browser_callback (AvahiServiceBrowser *b, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, const char *name, const char *type, const char *domain, void *user_data) { AvahiServiceResolver *sr; + + printf ("SERVICE-BROWSER: Callback on %p, interface (%d), protocol (%d), event (%d), name (%s), type (%s), domain (%s), data (%s)\n", (void*) b, interface, protocol, event, name, type, domain, (char*)user_data); + if (b && name) { sr = avahi_service_resolver_new (avahi_service_browser_get_client (b), interface, protocol, name, type, domain, AF_UNSPEC, avahi_service_resolver_callback, "xxXXxx"); + printf("New service resolver %p\n", (void*) sr); } - printf ("Callback on %s, interface (%d), protocol (%d), event (%d), name (%s), type (%s), domain (%s), data (%s)\n", avahi_service_browser_get_dbus_path (b), interface, protocol, event, name, type, domain, (char*)user_data); } static void avahi_service_type_browser_callback (AvahiServiceTypeBrowser *b, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, const char *type, const char *domain, void *user_data) { - printf ("Callback on %s, interface (%d), protocol (%d), event (%d), type (%s), domain (%s), data (%s)\n", avahi_service_type_browser_get_dbus_path (b), interface, protocol, event, type, domain, (char*)user_data); + printf ("SERVICE-TYPE-BROWSER: Callback on %p, interface (%d), protocol (%d), event (%d), type (%s), domain (%s), data (%s)\n", (void*) b, interface, protocol, event, type, domain, (char*)user_data); } static void @@ -91,12 +94,11 @@ avahi_address_resolver_callback (AvahiAddressResolver *r, AvahiIfIndex interface char addr[64]; if (event == AVAHI_RESOLVER_TIMEOUT) { - printf ("Callback on AddressResolver, timed out.\n"); - avahi_address_resolver_free (r); + printf ("ADDRESS-RESOLVER: Callback on AddressResolver, timed out.\n"); return; } avahi_address_snprint (addr, sizeof (addr), address); - printf ("Callback on AddressResolver, interface (%d), protocol (%d), even (%d), aprotocol (%d), address (%s), name (%s), data(%s)\n", interface, protocol, event, aprotocol, addr, name); + printf ("ADDRESS-RESOLVER: Callback on AddressResolver, interface (%d), protocol (%d), even (%d), aprotocol (%d), address (%s), name (%s), data(%s)\n", interface, protocol, event, aprotocol, addr, name, (char*) userdata); } static void @@ -108,8 +110,7 @@ avahi_host_name_resolver_callback (AvahiHostNameResolver *r, AvahiIfIndex interf if (event == AVAHI_RESOLVER_TIMEOUT) { - printf ("Callback on HostNameResolver, timed out.\n"); - avahi_host_name_resolver_free (r); + printf ("HOST-NAME-RESOLVER: Callback on HostNameResolver, timed out.\n"); return; } client = avahi_host_name_resolver_get_client (r); @@ -121,7 +122,7 @@ avahi_host_name_resolver_callback (AvahiHostNameResolver *r, AvahiIfIndex interf printf ("Failed to create AddressResolver\n"); } avahi_address_snprint (addr, sizeof (addr), a); - printf ("Callback on HostNameResolver, interface (%d), protocol (%d), event (%d), name (%s), address (%s), data (%s)\n", interface, protocol, event, name, addr, (char*)user_data); + printf ("HOST-NAME-RESOLVER: Callback on HostNameResolver, interface (%d), protocol (%d), event (%d), name (%s), address (%s), data (%s)\n", interface, protocol, event, name, addr, (char*)user_data); } static void test_free_domain_browser(AvahiTimeout *timeout, void* userdata) { @@ -144,7 +145,7 @@ static void test_entry_group_reset (AvahiTimeout *timeout, void* userdata) printf ("Resetting entry group\n"); avahi_entry_group_reset (g); - avahi_entry_group_add_service (g, AVAHI_IF_UNSPEC, AF_UNSPEC, "Lathiat's Site", "_http._tcp", "", "", 80, "foo=bar2", NULL); + avahi_entry_group_add_service (g, AVAHI_IF_UNSPEC, AF_UNSPEC, "Lathiat's Site", "_http._tcp", NULL, NULL, 80, "foo=bar2", NULL); avahi_entry_group_commit (g); } @@ -192,9 +193,9 @@ int main (int argc, char *argv[]) { assert(group); - printf("Sucessfully created entry group, path %s\n", avahi_entry_group_get_dbus_path (group)); + printf("Sucessfully created entry group %p\n", (void*) group); - avahi_entry_group_add_service (group, AVAHI_IF_UNSPEC, AF_UNSPEC, "Lathiat's Site", "_http._tcp", "", "", 80, "foo=bar", NULL); + avahi_entry_group_add_service (group, AVAHI_IF_UNSPEC, AF_UNSPEC, "Lathiat's Site", "_http._tcp", NULL, NULL, 80, "foo=bar", NULL); avahi_entry_group_commit (group); @@ -203,21 +204,21 @@ int main (int argc, char *argv[]) { if (domain == NULL) printf ("Failed to create domain browser object\n"); else - printf ("Sucessfully created domain browser, path %s\n", avahi_domain_browser_get_dbus_path (domain)); + printf ("Sucessfully created domain browser %p\n", (void*) domain); st = avahi_service_type_browser_new (avahi, AVAHI_IF_UNSPEC, AF_UNSPEC, "", avahi_service_type_browser_callback, "omghai3u"); if (st == NULL) printf ("Failed to create service type browser object\n"); else - printf ("Sucessfully created service type browser, path %s\n", avahi_service_type_browser_get_dbus_path (st)); + printf ("Sucessfully created service type browser %p\n", (void*) st); sb = avahi_service_browser_new (avahi, AVAHI_IF_UNSPEC, AF_UNSPEC, "_http._tcp", "", avahi_service_browser_callback, "omghai3u"); if (sb == NULL) printf ("Failed to create service browser object\n"); else - printf ("Sucessfully created service browser, path %s\n", avahi_service_browser_get_dbus_path (sb)); + printf ("Sucessfully created service browser %p\n", (void*) sb); - hnr = avahi_host_name_resolver_new (avahi, AVAHI_IF_UNSPEC, AF_UNSPEC, "hotbox.local", AF_UNSPEC, avahi_host_name_resolver_callback, "omghai4u"); + hnr = avahi_host_name_resolver_new (avahi, AVAHI_IF_UNSPEC, AF_UNSPEC, "ecstasy.local", AF_UNSPEC, avahi_host_name_resolver_callback, "omghai4u"); if (hnr == NULL) printf ("Failed to create hostname resolver object\n"); else @@ -238,6 +239,8 @@ int main (int argc, char *argv[]) { if (avahi_simple_poll_iterate(simple_poll, -1) != 0) break; + printf("terminating...\n"); + fail: if (avahi) diff --git a/avahi-client/client.c b/avahi-client/client.c index 1bffc49..b536beb 100644 --- a/avahi-client/client.c +++ b/avahi-client/client.c @@ -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: @@ -238,7 +254,7 @@ static DBusConnection* avahi_dbus_bus_get (DBusError *error) { DBusConnection *conn; - char *env_addr; + const char *env_addr; env_addr = getenv ("DBUS_SYSTEM_BUS_ADDRESS"); @@ -527,3 +543,54 @@ 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; +} + diff --git a/avahi-client/client.h b/avahi-client/client.h index 9d57c50..2d8f41b 100644 --- a/avahi-client/client.h +++ b/avahi-client/client.h @@ -213,9 +213,6 @@ int avahi_entry_group_add_service_va( uint16_t port, va_list va); -/** Get the D-Bus path of an AvahiEntryGroup object, for debugging purposes only. */ -const char* avahi_entry_group_get_dbus_path (AvahiEntryGroup *); - /** Browse for domains on the local network */ AvahiDomainBrowser* avahi_domain_browser_new (AvahiClient *client, AvahiIfIndex interface, @@ -228,9 +225,6 @@ AvahiDomainBrowser* avahi_domain_browser_new (AvahiClient *client, /** Get the parent client of an AvahiDomainBrowser object */ AvahiClient* avahi_domain_browser_get_client (AvahiDomainBrowser *); -/** Get the D-Bus path of an AvahiDomainBrowser object, for debugging purposes only. */ -const char* avahi_domain_browser_get_dbus_path (AvahiDomainBrowser *); - /** Cleans up and frees an AvahiDomainBrowser object */ int avahi_domain_browser_free (AvahiDomainBrowser *); @@ -246,9 +240,6 @@ AvahiServiceTypeBrowser* avahi_service_type_browser_new ( /** Get the parent client of an AvahiServiceTypeBrowser object */ AvahiClient* avahi_service_type_browser_get_client (AvahiServiceTypeBrowser *); -/** Get the D-Bus path of an AvahiServiceTypeBrowser object, for debugging purposes only. */ -const char* avahi_service_type_browser_get_dbus_path(AvahiServiceTypeBrowser *); - /** Cleans up and frees an AvahiServiceTypeBrowser object */ int avahi_service_type_browser_free (AvahiServiceTypeBrowser *); @@ -262,9 +253,6 @@ AvahiServiceBrowser* avahi_service_browser_new ( AvahiServiceBrowserCallback callback, void *userdata); -/** Get the D-Bus path of an AvahiServiceBrowser object, for debugging purposes only. */ -const char* avahi_service_browser_get_dbus_path (AvahiServiceBrowser *); - /** Get the parent client of an AvahiServiceBrowser object */ AvahiClient* avahi_service_browser_get_client (AvahiServiceBrowser *); @@ -289,9 +277,6 @@ AvahiClient* avahi_service_resolver_get_client (AvahiServiceResolver *); /** Free a service resolver object */ int avahi_service_resolver_free(AvahiServiceResolver *r); -/** Block until the resolving is complete */ -int avahi_service_resolver_block(AvahiServiceResolver *r); - /** Create a new hostname resolver object */ AvahiHostNameResolver * avahi_host_name_resolver_new( AvahiClient *client, @@ -308,9 +293,6 @@ AvahiClient* avahi_host_name_resolver_get_client (AvahiHostNameResolver *); /** Free a hostname resolver object */ int avahi_host_name_resolver_free(AvahiHostNameResolver *r); -/** Block until the resolving is complete */ -int avahi_host_name_resolver_block(AvahiHostNameResolver *r); - /** Create a new address resolver object from an address string. Set aprotocol to AF_UNSPEC for protocol detection. */ AvahiAddressResolver * avahi_address_resolver_new( AvahiClient *client, @@ -335,9 +317,6 @@ AvahiClient* avahi_address_resolver_get_client (AvahiAddressResolver *); /** Free a AvahiAddressResolver resolver object */ int avahi_address_resolver_free(AvahiAddressResolver *r); -/** Block until the resolving is complete */ -int avahi_address_resolver_block(AvahiAddressResolver *r); - #ifndef DOXYGEN_SHOULD_SKIP_THIS AVAHI_C_DECL_END #endif diff --git a/avahi-client/internal.h b/avahi-client/internal.h index f5401fc..b826175 100644 --- a/avahi-client/internal.h +++ b/avahi-client/internal.h @@ -80,7 +80,7 @@ struct AvahiServiceTypeBrowser { }; struct AvahiServiceResolver { - DBusPendingCall *call; + char *path; AvahiClient *client; AvahiServiceResolverCallback callback; void *userdata; @@ -89,7 +89,6 @@ struct AvahiServiceResolver { struct AvahiHostNameResolver { char *path; - DBusPendingCall *call; AvahiClient *client; AvahiHostNameResolverCallback callback; void *userdata; @@ -98,7 +97,6 @@ struct AvahiHostNameResolver { struct AvahiAddressResolver { char *path; - DBusPendingCall *call; AvahiClient *client; AvahiAddressResolverCallback callback; void *userdata; @@ -111,9 +109,13 @@ int avahi_client_set_dbus_error(AvahiClient *client, DBusError *error); void avahi_entry_group_set_state(AvahiEntryGroup *group, AvahiEntryGroupState state); DBusHandlerResult avahi_domain_browser_event (AvahiClient *client, AvahiBrowserEvent event, DBusMessage *message); - DBusHandlerResult avahi_service_type_browser_event (AvahiClient *client, AvahiBrowserEvent event, DBusMessage *message); - DBusHandlerResult avahi_service_browser_event (AvahiClient *client, AvahiBrowserEvent event, DBusMessage *message); +DBusHandlerResult avahi_service_resolver_event (AvahiClient *client, AvahiResolverEvent event, DBusMessage *message); +DBusHandlerResult avahi_host_name_resolver_event (AvahiClient *client, AvahiResolverEvent event, DBusMessage *message); +DBusHandlerResult avahi_address_resolver_event (AvahiClient *client, AvahiResolverEvent event, DBusMessage *message); + +int avahi_client_simple_method_call(AvahiClient *client, const char *path, const char *interface, const char *method); + #endif diff --git a/avahi-client/resolver.c b/avahi-client/resolver.c index c564a97..ddea755 100644 --- a/avahi-client/resolver.c +++ b/avahi-client/resolver.c @@ -38,22 +38,30 @@ #include "client.h" #include "internal.h" -static void -service_pending_call_callback(DBusPendingCall *pending, void *userdata) { - AvahiServiceResolver *r = userdata; - DBusMessage *message = NULL; - AvahiStringList *strlst = NULL; +/* AvahiServiceResolver implementation */ + +DBusHandlerResult avahi_service_resolver_event (AvahiClient *client, AvahiResolverEvent event, DBusMessage *message) { + AvahiServiceResolver *r = NULL; DBusError error; + const char *path; + AvahiStringList *strlst = NULL; + + assert(client); + assert(message); - assert(pending); - assert(r); + dbus_error_init (&error); - dbus_error_init(&error); + if (!(path = dbus_message_get_path(message))) + goto fail; + + for (r = client->service_resolvers; r; r = r->service_resolvers_next) + if (strcmp (r->path, path) == 0) + break; - if (!(message = dbus_pending_call_steal_reply(pending))) + if (!r) goto fail; - if (dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_METHOD_RETURN) { + if (event == AVAHI_RESOLVER_FOUND) { int j; int32_t interface; AvahiProtocol protocol, aprotocol; @@ -127,143 +135,25 @@ service_pending_call_callback(DBusPendingCall *pending, void *userdata) { } r->callback(r, (AvahiIfIndex) interface, (AvahiProtocol) protocol, AVAHI_RESOLVER_FOUND, name, type, domain, host, &a, port, strlst, r->userdata); + + avahi_string_list_free(strlst); } else { - - assert(dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_ERROR); - - avahi_client_set_errno(r->client, avahi_error_dbus_to_number(dbus_message_get_error_name(message))); - + assert(event == AVAHI_RESOLVER_TIMEOUT); + r->callback(r, (AvahiIfIndex) 0, (AvahiProtocol) 0, AVAHI_RESOLVER_TIMEOUT, NULL, NULL, NULL, NULL, NULL, 0, NULL, r->userdata); } -fail: - - if (message) - dbus_message_unref(message); - - avahi_string_list_free(strlst); - - dbus_error_free (&error); -} + return DBUS_HANDLER_RESULT_HANDLED; -static void -hostname_pending_call_callback(DBusPendingCall *pending, void *userdata) { - AvahiHostNameResolver *r = userdata; - DBusMessage *message = NULL; - DBusError error; - assert(pending); - assert(r); - - dbus_error_init(&error); - - if (!(message = dbus_pending_call_steal_reply(pending))) - goto fail; - - if (dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_METHOD_RETURN) { - int32_t interface; - AvahiProtocol protocol, aprotocol; - char *name, *address; - AvahiAddress a; - - if (!dbus_message_get_args( - message, &error, - DBUS_TYPE_INT32, &interface, - DBUS_TYPE_INT32, &protocol, - DBUS_TYPE_STRING, &name, - DBUS_TYPE_INT32, &aprotocol, - DBUS_TYPE_STRING, &address, - DBUS_TYPE_INVALID) || - dbus_error_is_set (&error)) { - fprintf(stderr, "Failed to parse resolver event.\n"); - goto fail; - } - - assert(address); - if (!avahi_address_parse(address, (AvahiProtocol) aprotocol, &a)) { - fprintf(stderr, "Failed to parse address\n"); - goto fail; - } - - r->callback(r, (AvahiIfIndex) interface, (AvahiProtocol) protocol, AVAHI_RESOLVER_FOUND, name, &a, r->userdata); - - } else { - - assert(dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_ERROR); - - avahi_client_set_errno(r->client, avahi_error_dbus_to_number(dbus_message_get_error_name(message))); - - r->callback(r, (AvahiIfIndex) 0, (AvahiProtocol) 0, AVAHI_RESOLVER_TIMEOUT, NULL, NULL, r->userdata); - } - fail: - - if (message) - dbus_message_unref(message); - dbus_error_free (&error); + avahi_string_list_free(strlst); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } -static void -address_pending_call_callback(DBusPendingCall *pending, void *userdata) { - AvahiAddressResolver *r = userdata; - DBusMessage *message = NULL; - DBusError error; - - assert(pending); - assert(r); - - dbus_error_init(&error); - - if (!(message = dbus_pending_call_steal_reply(pending))) - goto fail; - if (dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_METHOD_RETURN) { - int32_t interface; - AvahiProtocol protocol, aprotocol; - char *name, *address; - AvahiAddress a; - - if (!dbus_message_get_args( - message, &error, - DBUS_TYPE_INT32, &interface, - DBUS_TYPE_INT32, &protocol, - DBUS_TYPE_INT32, &aprotocol, - DBUS_TYPE_STRING, &address, - DBUS_TYPE_STRING, &name, - DBUS_TYPE_INVALID) || - dbus_error_is_set (&error)) { - fprintf(stderr, "Failed to parse resolver event.\n"); - goto fail; - } - - assert(address); - if (!avahi_address_parse(address, (AvahiProtocol) aprotocol, &a)) { - fprintf(stderr, "Failed to parse address\n"); - goto fail; - } - - r->callback(r, (AvahiIfIndex) interface, (AvahiProtocol) protocol, AVAHI_RESOLVER_FOUND, (AvahiProtocol) aprotocol, &a, name, r->userdata); - - } else { - - assert(dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_ERROR); - - avahi_client_set_errno(r->client, avahi_error_dbus_to_number(dbus_message_get_error_name(message))); - - r->callback(r, (AvahiIfIndex) 0, (AvahiProtocol) 0, AVAHI_RESOLVER_TIMEOUT, (AvahiProtocol) 0, NULL, NULL, r->userdata); - } - -fail: - - if (message) - dbus_message_unref(message); - - dbus_error_free (&error); -} - -/* AvahiServiceResolver implementation */ AvahiServiceResolver * avahi_service_resolver_new( AvahiClient *client, AvahiIfIndex interface, @@ -277,8 +167,9 @@ AvahiServiceResolver * avahi_service_resolver_new( DBusError error; AvahiServiceResolver *r; - DBusMessage *message; + DBusMessage *message = NULL, *reply = NULL; int32_t i_interface, i_protocol, i_aprotocol; + char *path; assert(client); assert(name); @@ -302,11 +193,11 @@ AvahiServiceResolver * avahi_service_resolver_new( r->client = client; r->callback = callback; r->userdata = userdata; - r->call = NULL; + r->path = NULL; AVAHI_LLIST_PREPEND(AvahiServiceResolver, service_resolvers, client->service_resolvers, r); - if (!(message = dbus_message_new_method_call(AVAHI_DBUS_NAME, AVAHI_DBUS_PATH_SERVER, AVAHI_DBUS_INTERFACE_SERVER, "ResolveService"))) { + if (!(message = dbus_message_new_method_call(AVAHI_DBUS_NAME, AVAHI_DBUS_PATH_SERVER, AVAHI_DBUS_INTERFACE_SERVER, "ServiceResolverNew"))) { avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY); goto fail; } @@ -328,13 +219,30 @@ AvahiServiceResolver * avahi_service_resolver_new( goto fail; } - if (!dbus_connection_send_with_reply(client->bus, message, &r->call, -1) || - !dbus_pending_call_set_notify(r->call, service_pending_call_callback, r, NULL)) { + 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; + } + + if (!dbus_message_get_args (reply, &error, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID) || + dbus_error_is_set(&error) || + !path) { + avahi_client_set_errno(client, AVAHI_ERR_DBUS_ERROR); + goto fail; + } + + if (!(r->path = avahi_strdup(path))) { + + /* FIXME: We don't remove the object on the server side */ + avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY); goto fail; } + dbus_message_unref(message); + dbus_message_unref(reply); return r; @@ -351,6 +259,9 @@ fail: if (message) dbus_message_unref(message); + if (reply) + dbus_message_unref(reply); + return NULL; } @@ -363,35 +274,85 @@ AvahiClient* avahi_service_resolver_get_client (AvahiServiceResolver *r) { int avahi_service_resolver_free(AvahiServiceResolver *r) { AvahiClient *client; + int ret = AVAHI_OK; assert(r); client = r->client; - if (r->call) { - dbus_pending_call_cancel(r->call); - dbus_pending_call_unref(r->call); - } + if (r->path && client->state != AVAHI_CLIENT_DISCONNECTED) + ret = avahi_client_simple_method_call(client, r->path, AVAHI_DBUS_INTERFACE_SERVICE_RESOLVER, "Free"); AVAHI_LLIST_REMOVE(AvahiServiceResolver, service_resolvers, client->service_resolvers, r); + avahi_free(r->path); avahi_free(r); - return AVAHI_OK; + return ret; } -int avahi_service_resolver_block(AvahiServiceResolver *r) { - AvahiClient *client; +/* AvahiHostNameResolver implementation */ - assert(r); - client = r->client; +DBusHandlerResult avahi_host_name_resolver_event (AvahiClient *client, AvahiResolverEvent event, DBusMessage *message) { + AvahiHostNameResolver *r = NULL; + DBusError error; + const char *path; + + assert(client); + assert(message); + + dbus_error_init (&error); + + if (!(path = dbus_message_get_path(message))) + goto fail; - if (r->call) - dbus_pending_call_block(r->call); + for (r = client->host_name_resolvers; r; r = r->host_name_resolvers_next) + if (strcmp (r->path, path) == 0) + break; - return AVAHI_OK; + if (!r) + goto fail; + + if (event == AVAHI_RESOLVER_FOUND) { + int32_t interface; + AvahiProtocol protocol, aprotocol; + char *name, *address; + AvahiAddress a; + + if (!dbus_message_get_args( + message, &error, + DBUS_TYPE_INT32, &interface, + DBUS_TYPE_INT32, &protocol, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_INT32, &aprotocol, + DBUS_TYPE_STRING, &address, + DBUS_TYPE_INVALID) || + dbus_error_is_set (&error)) { + fprintf(stderr, "Failed to parse resolver event.\n"); + goto fail; + } + + assert(address); + if (!avahi_address_parse(address, (AvahiProtocol) aprotocol, &a)) { + fprintf(stderr, "Failed to parse address\n"); + goto fail; + } + + r->callback(r, (AvahiIfIndex) interface, (AvahiProtocol) protocol, AVAHI_RESOLVER_FOUND, name, &a, r->userdata); + + } else { + + assert(event == AVAHI_RESOLVER_TIMEOUT); + + r->callback(r, (AvahiIfIndex) 0, (AvahiProtocol) 0, AVAHI_RESOLVER_TIMEOUT, NULL, NULL, r->userdata); + } + + return DBUS_HANDLER_RESULT_HANDLED; + +fail: + dbus_error_free (&error); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } -/* AvahiHostNameResolver implementation */ AvahiHostNameResolver * avahi_host_name_resolver_new( AvahiClient *client, @@ -404,8 +365,9 @@ AvahiHostNameResolver * avahi_host_name_resolver_new( DBusError error; AvahiHostNameResolver *r; - DBusMessage *message; + DBusMessage *message = NULL, *reply = NULL; int32_t i_interface, i_protocol, i_aprotocol; + char *path; assert(client); assert(name); @@ -425,11 +387,11 @@ AvahiHostNameResolver * avahi_host_name_resolver_new( r->client = client; r->callback = callback; r->userdata = userdata; - r->call = NULL; + r->path = NULL; AVAHI_LLIST_PREPEND(AvahiHostNameResolver, host_name_resolvers, client->host_name_resolvers, r); - if (!(message = dbus_message_new_method_call(AVAHI_DBUS_NAME, AVAHI_DBUS_PATH_SERVER, AVAHI_DBUS_INTERFACE_SERVER, "ResolveHostName"))) { + if (!(message = dbus_message_new_method_call(AVAHI_DBUS_NAME, AVAHI_DBUS_PATH_SERVER, AVAHI_DBUS_INTERFACE_SERVER, "HostNameResolverNew"))) { avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY); goto fail; } @@ -449,13 +411,29 @@ AvahiHostNameResolver * avahi_host_name_resolver_new( goto fail; } - if (!dbus_connection_send_with_reply(client->bus, message, &r->call, -1) || - !dbus_pending_call_set_notify(r->call, hostname_pending_call_callback, r, NULL)) { + 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; + } + + if (!dbus_message_get_args (reply, &error, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID) || + dbus_error_is_set(&error) || + !path) { + avahi_client_set_errno(client, AVAHI_ERR_DBUS_ERROR); + goto fail; + } + + if (!(r->path = avahi_strdup(path))) { + + /* FIXME: We don't remove the object on the server side */ + avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY); goto fail; } dbus_message_unref(message); + dbus_message_unref(reply); return r; @@ -472,26 +450,29 @@ fail: if (message) dbus_message_unref(message); + if (reply) + dbus_message_unref(reply); + return NULL; } int avahi_host_name_resolver_free(AvahiHostNameResolver *r) { + int ret = AVAHI_OK; AvahiClient *client; assert(r); client = r->client; - if (r->call) { - dbus_pending_call_cancel(r->call); - dbus_pending_call_unref(r->call); - } + if (r->path && client->state != AVAHI_CLIENT_DISCONNECTED) + ret = avahi_client_simple_method_call(client, r->path, AVAHI_DBUS_INTERFACE_HOST_NAME_RESOLVER, "Free"); AVAHI_LLIST_REMOVE(AvahiHostNameResolver, host_name_resolvers, client->host_name_resolvers, r); + avahi_free(r->path); avahi_free(r); - return AVAHI_OK; + return ret; } AvahiClient* avahi_host_name_resolver_get_client (AvahiHostNameResolver *r) { @@ -500,19 +481,67 @@ AvahiClient* avahi_host_name_resolver_get_client (AvahiHostNameResolver *r) { return r->client; } -int avahi_host_name_resolver_block(AvahiHostNameResolver *r) { - AvahiClient *client; +/* AvahiAddressResolver implementation */ - assert(r); - client = r->client; +DBusHandlerResult avahi_address_resolver_event (AvahiClient *client, AvahiResolverEvent event, DBusMessage *message) { + AvahiAddressResolver *r = NULL; + DBusError error; + const char *path; - if (r->call) - dbus_pending_call_block(r->call); + assert(client); + assert(message); + + dbus_error_init (&error); - return AVAHI_OK; -} + if (!(path = dbus_message_get_path(message))) + goto fail; -/* AvahiAddressResolver implementation */ + for (r = client->address_resolvers; r; r = r->address_resolvers_next) + if (strcmp (r->path, path) == 0) + break; + + if (!r) + goto fail; + + if (event == AVAHI_RESOLVER_FOUND) { + int32_t interface; + AvahiProtocol protocol, aprotocol; + char *name, *address; + AvahiAddress a; + + if (!dbus_message_get_args( + message, &error, + DBUS_TYPE_INT32, &interface, + DBUS_TYPE_INT32, &protocol, + DBUS_TYPE_INT32, &aprotocol, + DBUS_TYPE_STRING, &address, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_INVALID) || + dbus_error_is_set (&error)) { + fprintf(stderr, "Failed to parse resolver event.\n"); + goto fail; + } + + assert(address); + if (!avahi_address_parse(address, (AvahiProtocol) aprotocol, &a)) { + fprintf(stderr, "Failed to parse address\n"); + goto fail; + } + + r->callback(r, (AvahiIfIndex) interface, (AvahiProtocol) protocol, AVAHI_RESOLVER_FOUND, (AvahiProtocol) aprotocol, &a, name, r->userdata); + } else { + + assert(event == AVAHI_RESOLVER_TIMEOUT); + + r->callback(r, (AvahiIfIndex) 0, (AvahiProtocol) 0, AVAHI_RESOLVER_TIMEOUT, (AvahiProtocol) 0, NULL, NULL, r->userdata); + } + + return DBUS_HANDLER_RESULT_HANDLED; + +fail: + dbus_error_free (&error); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} AvahiAddressResolver * avahi_address_resolver_new_a( AvahiClient *client, @@ -547,9 +576,10 @@ AvahiAddressResolver * avahi_address_resolver_new( DBusError error; AvahiAddressResolver *r; - DBusMessage *message; + DBusMessage *message = NULL, *reply = NULL; int32_t i_interface; AvahiProtocol i_protocol; + char *path; assert(client); @@ -568,11 +598,11 @@ AvahiAddressResolver * avahi_address_resolver_new( r->client = client; r->callback = callback; r->userdata = userdata; - r->call = NULL; + r->path = NULL; AVAHI_LLIST_PREPEND(AvahiAddressResolver, address_resolvers, client->address_resolvers, r); - if (!(message = dbus_message_new_method_call(AVAHI_DBUS_NAME, AVAHI_DBUS_PATH_SERVER, AVAHI_DBUS_INTERFACE_SERVER, "ResolveAddress"))) { + if (!(message = dbus_message_new_method_call(AVAHI_DBUS_NAME, AVAHI_DBUS_PATH_SERVER, AVAHI_DBUS_INTERFACE_SERVER, "AddressResolverNew"))) { avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY); goto fail; } @@ -590,13 +620,29 @@ AvahiAddressResolver * avahi_address_resolver_new( goto fail; } - if (!dbus_connection_send_with_reply(client->bus, message, &r->call, -1) || - !dbus_pending_call_set_notify(r->call, address_pending_call_callback, r, NULL)) { + 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; + } + + if (!dbus_message_get_args (reply, &error, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID) || + dbus_error_is_set(&error) || + !path) { + avahi_client_set_errno(client, AVAHI_ERR_DBUS_ERROR); + goto fail; + } + + if (!(r->path = avahi_strdup(path))) { + + /* FIXME: We don't remove the object on the server side */ + avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY); goto fail; } dbus_message_unref(message); + dbus_message_unref(reply); return r; @@ -613,6 +659,9 @@ fail: if (message) dbus_message_unref(message); + if (reply) + dbus_message_unref(reply); + return NULL; } @@ -625,30 +674,19 @@ AvahiClient* avahi_address_resolver_get_client (AvahiAddressResolver *r) { int avahi_address_resolver_free(AvahiAddressResolver *r) { AvahiClient *client; + int ret = AVAHI_OK; assert(r); client = r->client; - if (r->call) { - dbus_pending_call_cancel(r->call); - dbus_pending_call_unref(r->call); - } + if (r->path && client->state != AVAHI_CLIENT_DISCONNECTED) + ret = avahi_client_simple_method_call(client, r->path, AVAHI_DBUS_INTERFACE_ADDRESS_RESOLVER, "Free"); AVAHI_LLIST_REMOVE(AvahiAddressResolver, address_resolvers, client->address_resolvers, r); + avahi_free(r->path); avahi_free(r); - return AVAHI_OK; + return ret; } -int avahi_address_resolver_block(AvahiAddressResolver *r) { - AvahiClient *client; - - assert(r); - client = r->client; - - if (r->call) - dbus_pending_call_block(r->call); - - return AVAHI_OK; -} -- cgit