X-Git-Url: http://git.meshlink.io/?a=blobdiff_plain;f=avahi-client%2Fresolver.c;h=ddea755dc7409bbf91365a075105b3ace9793d1f;hb=5af9f469d85a9281bc5484e9f5a8740751591dfe;hp=aaff5023ff12ff3b039a0b17b976d284bfbe95fa;hpb=4743c6236a42978862fa6cf3fa95e40c04fcbd5e;p=catta diff --git a/avahi-client/resolver.c b/avahi-client/resolver.c index aaff502..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); -} - -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; + return DBUS_HANDLER_RESULT_HANDLED; - 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; + + for (r = client->host_name_resolvers; r; r = r->host_name_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_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); - if (r->call) - dbus_pending_call_block(r->call); + } else { + + assert(event == AVAHI_RESOLVER_TIMEOUT); + + r->callback(r, (AvahiIfIndex) 0, (AvahiProtocol) 0, AVAHI_RESOLVER_TIMEOUT, NULL, NULL, r->userdata); + } - return AVAHI_OK; + 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,23 +481,72 @@ 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, AvahiIfIndex interface, + AvahiProtocol protocol, const AvahiAddress *a, AvahiAddressResolverCallback callback, void *userdata) { @@ -525,11 +555,15 @@ AvahiAddressResolver * avahi_address_resolver_new_a( assert (a); - avahi_address_snprint (addr, sizeof (addr), a); + if (!avahi_address_snprint (addr, sizeof (addr), a)) { + avahi_client_set_errno(client, AVAHI_ERR_INVALID_ADDRESS); + return NULL; + } - return avahi_address_resolver_new (client, interface, - a->family, addr, - callback, userdata); + return avahi_address_resolver_new ( + client, interface, protocol, + addr, + callback, userdata); } AvahiAddressResolver * avahi_address_resolver_new( @@ -542,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); @@ -563,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; } @@ -585,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; @@ -608,6 +659,9 @@ fail: if (message) dbus_message_unref(message); + if (reply) + dbus_message_unref(reply); + return NULL; } @@ -620,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; -}