4 This file is part of avahi.
6 avahi is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as
8 published by the Free Software Foundation; either version 2.1 of the
9 License, or (at your option) any later version.
11 avahi is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
14 Public License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with avahi; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
27 #include <sys/ioctl.h>
37 #include <dbus/dbus.h>
39 #include <avahi-common/dbus.h>
40 #include <avahi-common/llist.h>
41 #include <avahi-common/malloc.h>
42 #include <avahi-common/dbus.h>
43 #include <avahi-common/dbus-watch-glue.h>
44 #include <avahi-common/alternative.h>
45 #include <avahi-common/error.h>
46 #include <avahi-core/log.h>
47 #include <avahi-core/core.h>
49 #include "dbus-protocol.h"
52 typedef struct Server Server;
53 typedef struct Client Client;
54 typedef struct EntryGroupInfo EntryGroupInfo;
55 typedef struct SyncHostNameResolverInfo SyncHostNameResolverInfo;
56 typedef struct AsyncHostNameResolverInfo AsyncHostNameResolverInfo;
57 typedef struct SyncAddressResolverInfo SyncAddressResolverInfo;
58 typedef struct AsyncAddressResolverInfo AsyncAddressResolverInfo;
59 typedef struct DomainBrowserInfo DomainBrowserInfo;
60 typedef struct ServiceTypeBrowserInfo ServiceTypeBrowserInfo;
61 typedef struct ServiceBrowserInfo ServiceBrowserInfo;
62 typedef struct SyncServiceResolverInfo SyncServiceResolverInfo;
63 typedef struct AsyncServiceResolverInfo AsyncServiceResolverInfo;
65 #define MAX_CLIENTS 20
66 #define MAX_OBJECTS_PER_CLIENT 50
67 #define MAX_ENTRIES_PER_ENTRY_GROUP 20
69 /* #define VALGRIND_WORKAROUND */
71 struct EntryGroupInfo {
74 AvahiSEntryGroup *entry_group;
79 AVAHI_LLIST_FIELDS(EntryGroupInfo, entry_groups);
82 struct SyncHostNameResolverInfo {
84 AvahiSHostNameResolver *host_name_resolver;
87 AVAHI_LLIST_FIELDS(SyncHostNameResolverInfo, sync_host_name_resolvers);
90 struct AsyncHostNameResolverInfo {
93 AvahiSHostNameResolver *host_name_resolver;
96 AVAHI_LLIST_FIELDS(AsyncHostNameResolverInfo, async_host_name_resolvers);
99 struct SyncAddressResolverInfo {
101 AvahiSAddressResolver *address_resolver;
102 DBusMessage *message;
104 AVAHI_LLIST_FIELDS(SyncAddressResolverInfo, sync_address_resolvers);
107 struct AsyncAddressResolverInfo {
110 AvahiSAddressResolver *address_resolver;
113 AVAHI_LLIST_FIELDS(AsyncAddressResolverInfo, async_address_resolvers);
116 struct DomainBrowserInfo {
119 AvahiSDomainBrowser *domain_browser;
122 AVAHI_LLIST_FIELDS(DomainBrowserInfo, domain_browsers);
125 struct ServiceTypeBrowserInfo {
128 AvahiSServiceTypeBrowser *service_type_browser;
131 AVAHI_LLIST_FIELDS(ServiceTypeBrowserInfo, service_type_browsers);
134 struct ServiceBrowserInfo {
137 AvahiSServiceBrowser *service_browser;
140 AVAHI_LLIST_FIELDS(ServiceBrowserInfo, service_browsers);
143 struct SyncServiceResolverInfo {
145 AvahiSServiceResolver *service_resolver;
146 DBusMessage *message;
148 AVAHI_LLIST_FIELDS(SyncServiceResolverInfo, sync_service_resolvers);
151 struct AsyncServiceResolverInfo {
154 AvahiSServiceResolver *service_resolver;
157 AVAHI_LLIST_FIELDS(AsyncServiceResolverInfo, async_service_resolvers);
166 AVAHI_LLIST_FIELDS(Client, clients);
167 AVAHI_LLIST_HEAD(EntryGroupInfo, entry_groups);
168 AVAHI_LLIST_HEAD(SyncHostNameResolverInfo, sync_host_name_resolvers);
169 AVAHI_LLIST_HEAD(AsyncHostNameResolverInfo, async_host_name_resolvers);
170 AVAHI_LLIST_HEAD(SyncAddressResolverInfo, sync_address_resolvers);
171 AVAHI_LLIST_HEAD(AsyncAddressResolverInfo, async_address_resolvers);
172 AVAHI_LLIST_HEAD(DomainBrowserInfo, domain_browsers);
173 AVAHI_LLIST_HEAD(ServiceTypeBrowserInfo, service_type_browsers);
174 AVAHI_LLIST_HEAD(ServiceBrowserInfo, service_browsers);
175 AVAHI_LLIST_HEAD(SyncServiceResolverInfo, sync_service_resolvers);
176 AVAHI_LLIST_HEAD(AsyncServiceResolverInfo, async_service_resolvers);
181 AVAHI_LLIST_HEAD(Client, clients);
186 static Server *server = NULL;
188 static void entry_group_free(EntryGroupInfo *i) {
192 avahi_s_entry_group_free(i->entry_group);
193 dbus_connection_unregister_object_path(server->bus, i->path);
195 AVAHI_LLIST_REMOVE(EntryGroupInfo, entry_groups, i->client->entry_groups, i);
197 i->client->n_objects--;
198 assert(i->client->n_objects >= 0);
203 static void sync_host_name_resolver_free(SyncHostNameResolverInfo *i) {
206 if (i->host_name_resolver)
207 avahi_s_host_name_resolver_free(i->host_name_resolver);
208 dbus_message_unref(i->message);
209 AVAHI_LLIST_REMOVE(SyncHostNameResolverInfo, sync_host_name_resolvers, i->client->sync_host_name_resolvers, i);
211 i->client->n_objects--;
212 assert(i->client->n_objects >= 0);
217 static void async_host_name_resolver_free(AsyncHostNameResolverInfo *i) {
220 if (i->host_name_resolver)
221 avahi_s_host_name_resolver_free(i->host_name_resolver);
222 dbus_connection_unregister_object_path(server->bus, i->path);
223 AVAHI_LLIST_REMOVE(AsyncHostNameResolverInfo, async_host_name_resolvers, i->client->async_host_name_resolvers, i);
225 i->client->n_objects--;
226 assert(i->client->n_objects >= 0);
231 static void sync_address_resolver_free(SyncAddressResolverInfo *i) {
234 if (i->address_resolver)
235 avahi_s_address_resolver_free(i->address_resolver);
236 dbus_message_unref(i->message);
237 AVAHI_LLIST_REMOVE(SyncAddressResolverInfo, sync_address_resolvers, i->client->sync_address_resolvers, i);
239 i->client->n_objects--;
240 assert(i->client->n_objects >= 0);
245 static void async_address_resolver_free(AsyncAddressResolverInfo *i) {
248 if (i->address_resolver)
249 avahi_s_address_resolver_free(i->address_resolver);
250 dbus_connection_unregister_object_path(server->bus, i->path);
251 AVAHI_LLIST_REMOVE(AsyncAddressResolverInfo, async_address_resolvers, i->client->async_address_resolvers, i);
253 i->client->n_objects--;
254 assert(i->client->n_objects >= 0);
259 static void domain_browser_free(DomainBrowserInfo *i) {
262 if (i->domain_browser)
263 avahi_s_domain_browser_free(i->domain_browser);
264 dbus_connection_unregister_object_path(server->bus, i->path);
266 AVAHI_LLIST_REMOVE(DomainBrowserInfo, domain_browsers, i->client->domain_browsers, i);
268 i->client->n_objects--;
269 assert(i->client->n_objects >= 0);
274 static void service_type_browser_free(ServiceTypeBrowserInfo *i) {
277 if (i->service_type_browser)
278 avahi_s_service_type_browser_free(i->service_type_browser);
279 dbus_connection_unregister_object_path(server->bus, i->path);
281 AVAHI_LLIST_REMOVE(ServiceTypeBrowserInfo, service_type_browsers, i->client->service_type_browsers, i);
283 i->client->n_objects--;
284 assert(i->client->n_objects >= 0);
289 static void service_browser_free(ServiceBrowserInfo *i) {
292 if (i->service_browser)
293 avahi_s_service_browser_free(i->service_browser);
294 dbus_connection_unregister_object_path(server->bus, i->path);
296 AVAHI_LLIST_REMOVE(ServiceBrowserInfo, service_browsers, i->client->service_browsers, i);
298 i->client->n_objects--;
299 assert(i->client->n_objects >= 0);
304 static void sync_service_resolver_free(SyncServiceResolverInfo *i) {
307 if (i->service_resolver)
308 avahi_s_service_resolver_free(i->service_resolver);
309 dbus_message_unref(i->message);
310 AVAHI_LLIST_REMOVE(SyncServiceResolverInfo, sync_service_resolvers, i->client->sync_service_resolvers, i);
312 i->client->n_objects--;
313 assert(i->client->n_objects >= 0);
318 static void async_service_resolver_free(AsyncServiceResolverInfo *i) {
321 if (i->service_resolver)
322 avahi_s_service_resolver_free(i->service_resolver);
324 dbus_connection_unregister_object_path(server->bus, i->path);
325 AVAHI_LLIST_REMOVE(AsyncServiceResolverInfo, async_service_resolvers, i->client->async_service_resolvers, i);
327 i->client->n_objects--;
328 assert(i->client->n_objects >= 0);
333 static void client_free(Client *c) {
338 while (c->entry_groups)
339 entry_group_free(c->entry_groups);
341 while (c->sync_host_name_resolvers)
342 sync_host_name_resolver_free(c->sync_host_name_resolvers);
344 while (c->async_host_name_resolvers)
345 async_host_name_resolver_free(c->async_host_name_resolvers);
347 while (c->sync_address_resolvers)
348 sync_address_resolver_free(c->sync_address_resolvers);
350 while (c->async_address_resolvers)
351 async_address_resolver_free(c->async_address_resolvers);
353 while (c->domain_browsers)
354 domain_browser_free(c->domain_browsers);
356 while (c->service_type_browsers)
357 service_type_browser_free(c->service_type_browsers);
359 while (c->service_browsers)
360 service_browser_free(c->service_browsers);
362 while (c->sync_service_resolvers)
363 sync_service_resolver_free(c->sync_service_resolvers);
365 while (c->async_service_resolvers)
366 async_service_resolver_free(c->async_service_resolvers);
368 assert(c->n_objects == 0);
371 AVAHI_LLIST_REMOVE(Client, clients, server->clients, c);
374 server->n_clients --;
375 assert(server->n_clients >= 0);
378 static Client *client_get(const char *name, int create) {
384 for (client = server->clients; client; client = client->clients_next)
385 if (!strcmp(name, client->name))
391 if (server->n_clients >= MAX_CLIENTS)
394 /* If not existant yet, create a new entry */
395 client = avahi_new(Client, 1);
396 client->id = server->current_id++;
397 client->name = avahi_strdup(name);
398 client->current_id = 0;
399 client->n_objects = 0;
401 AVAHI_LLIST_HEAD_INIT(EntryGroupInfo, client->entry_groups);
402 AVAHI_LLIST_HEAD_INIT(SyncHostNameResolverInfo, client->sync_host_name_resolvers);
403 AVAHI_LLIST_HEAD_INIT(AsyncHostNameResolverInfo, client->async_host_name_resolvers);
404 AVAHI_LLIST_HEAD_INIT(SyncAddressResolverInfo, client->sync_address_resolvers);
405 AVAHI_LLIST_HEAD_INIT(AsyncAddressResolverInfo, client->async_address_resolvers);
406 AVAHI_LLIST_HEAD_INIT(DomainBrowserInfo, client->domain_browsers);
407 AVAHI_LLIST_HEAD_INIT(ServiceTypeBrowserInfo, client->service_type_browsers);
408 AVAHI_LLIST_HEAD_INIT(ServiceBrowserInfo, client->service_browsers);
409 AVAHI_LLIST_HEAD_INIT(SyncServiceResolverInfo, client->sync_service_resolvers);
410 AVAHI_LLIST_HEAD_INIT(AsyncServiceResolverInfo, client->async_service_resolvers);
412 AVAHI_LLIST_PREPEND(Client, clients, server->clients, client);
415 assert(server->n_clients > 0);
420 static DBusHandlerResult respond_error(DBusConnection *c, DBusMessage *m, int error, const char *text) {
423 assert(-error > -AVAHI_OK);
424 assert(-error < -AVAHI_ERR_MAX);
426 reply = dbus_message_new_error(m, avahi_error_number_to_dbus (error), text ? text : avahi_strerror(error));
427 dbus_connection_send(c, reply, NULL);
428 dbus_message_unref(reply);
430 return DBUS_HANDLER_RESULT_HANDLED;
433 static DBusHandlerResult respond_string(DBusConnection *c, DBusMessage *m, const char *text) {
436 reply = dbus_message_new_method_return(m);
437 dbus_message_append_args(reply, DBUS_TYPE_STRING, &text, DBUS_TYPE_INVALID);
438 dbus_connection_send(c, reply, NULL);
439 dbus_message_unref(reply);
441 return DBUS_HANDLER_RESULT_HANDLED;
444 static DBusHandlerResult respond_int32(DBusConnection *c, DBusMessage *m, int32_t i) {
447 reply = dbus_message_new_method_return(m);
448 dbus_message_append_args(reply, DBUS_TYPE_INT32, &i, DBUS_TYPE_INVALID);
449 dbus_connection_send(c, reply, NULL);
450 dbus_message_unref(reply);
452 return DBUS_HANDLER_RESULT_HANDLED;
455 static DBusHandlerResult respond_uint32(DBusConnection *c, DBusMessage *m, uint32_t u) {
458 reply = dbus_message_new_method_return(m);
459 dbus_message_append_args(reply, DBUS_TYPE_UINT32, &u, DBUS_TYPE_INVALID);
460 dbus_connection_send(c, reply, NULL);
461 dbus_message_unref(reply);
463 return DBUS_HANDLER_RESULT_HANDLED;
466 static DBusHandlerResult respond_ok(DBusConnection *c, DBusMessage *m) {
469 reply = dbus_message_new_method_return(m);
470 dbus_connection_send(c, reply, NULL);
471 dbus_message_unref(reply);
473 return DBUS_HANDLER_RESULT_HANDLED;
476 static DBusHandlerResult respond_path(DBusConnection *c, DBusMessage *m, const char *path) {
479 reply = dbus_message_new_method_return(m);
480 dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID);
481 dbus_connection_send(c, reply, NULL);
482 dbus_message_unref(reply);
484 return DBUS_HANDLER_RESULT_HANDLED;
487 static char *file_get_contents(char *fname) {
495 if (!(fd = open(fname, O_RDONLY))) {
496 avahi_log_error("Failed to open %s: %s", fname, strerror(errno));
500 if (fstat(fd, &st) < 0) {
501 avahi_log_error("stat(%s) failed: %s", fname, strerror(errno));
505 if (!(S_ISREG(st.st_mode))) {
506 avahi_log_error("Invalid file %s", fname);
510 if (st.st_size > 1024*1024) { /** 1MB */
511 avahi_log_error("File too large %s", fname);
515 buf = avahi_new(char, st.st_size+1);
517 if ((size = read(fd, buf, st.st_size)) < 0) {
518 avahi_log_error("read() failed: %s\n", strerror(errno));
538 static DBusHandlerResult handle_introspect(DBusConnection *c, DBusMessage *m, const char *fname) {
539 char *path, *contents;
546 dbus_error_init(&error);
548 if (!dbus_message_get_args(m, &error, DBUS_TYPE_INVALID)) {
549 avahi_log_error("Error parsing Introspect message: %s", error.message);
553 path = avahi_strdup_printf("%s/%s", AVAHI_DBUS_INTROSPECTION_DIR, fname);
554 contents = file_get_contents(path);
558 avahi_log_error("Failed to load introspection data.");
562 respond_string(c, m, contents);
563 avahi_free(contents);
565 return DBUS_HANDLER_RESULT_HANDLED;
568 if (dbus_error_is_set(&error))
569 dbus_error_free(&error);
571 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
575 static DBusHandlerResult msg_signal_filter_impl(DBusConnection *c, DBusMessage *m, void *userdata) {
578 dbus_error_init(&error);
580 /* avahi_log_debug(__FILE__": interface=%s, path=%s, member=%s", */
581 /* dbus_message_get_interface(m), */
582 /* dbus_message_get_path(m), */
583 /* dbus_message_get_member(m)); */
585 if (dbus_message_is_signal(m, DBUS_INTERFACE_LOCAL, "Disconnected")) {
586 /* No, we shouldn't quit, but until we get somewhere
587 * usefull such that we can restore our state, we will */
588 avahi_log_warn("Disconnnected from D-BUS, terminating...");
590 raise(SIGQUIT); /* The signal handler will catch this and terminate the process cleanly*/
592 return DBUS_HANDLER_RESULT_HANDLED;
594 } else if (dbus_message_is_signal(m, DBUS_INTERFACE_DBUS, "NameAcquired")) {
597 if (!dbus_message_get_args(m, &error, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID)) {
598 avahi_log_warn("Error parsing NameAcquired message");
602 /* avahi_log_info(__FILE__": name acquired (%s)", name); */
603 return DBUS_HANDLER_RESULT_HANDLED;
605 } else if (dbus_message_is_signal(m, DBUS_INTERFACE_DBUS, "NameOwnerChanged")) {
606 char *name, *old, *new;
608 if (!dbus_message_get_args(m, &error, DBUS_TYPE_STRING, &name, DBUS_TYPE_STRING, &old, DBUS_TYPE_STRING, &new, DBUS_TYPE_INVALID)) {
609 avahi_log_warn("Error parsing NameOwnerChanged message");
616 if ((client = client_get(name, FALSE))) {
617 avahi_log_debug(__FILE__": client %s vanished.", name);
624 if (dbus_error_is_set(&error))
625 dbus_error_free(&error);
627 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
630 static void entry_group_callback(AvahiServer *s, AvahiSEntryGroup *g, AvahiEntryGroupState state, void* userdata) {
631 EntryGroupInfo *i = userdata;
639 m = dbus_message_new_signal(i->path, AVAHI_DBUS_INTERFACE_ENTRY_GROUP, "StateChanged");
641 dbus_message_append_args(m, DBUS_TYPE_INT32, &t, DBUS_TYPE_INVALID);
642 dbus_message_set_destination(m, i->client->name);
643 dbus_connection_send(server->bus, m, NULL);
644 dbus_message_unref(m);
647 static DBusHandlerResult msg_entry_group_impl(DBusConnection *c, DBusMessage *m, void *userdata) {
649 EntryGroupInfo *i = userdata;
655 dbus_error_init(&error);
657 avahi_log_debug(__FILE__": interface=%s, path=%s, member=%s",
658 dbus_message_get_interface(m),
659 dbus_message_get_path(m),
660 dbus_message_get_member(m));
663 if (dbus_message_is_method_call(m, DBUS_INTERFACE_INTROSPECTABLE, "Introspect"))
664 return handle_introspect(c, m, "EntryGroup.introspect");
667 if (strcmp(dbus_message_get_sender(m), i->client->name))
668 return respond_error(c, m, AVAHI_ERR_ACCESS_DENIED, NULL);
670 if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_ENTRY_GROUP, "Free")) {
672 if (!dbus_message_get_args(m, &error, DBUS_TYPE_INVALID)) {
673 avahi_log_warn("Error parsing EntryGroup::Free message");
678 return respond_ok(c, m);
680 } else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_ENTRY_GROUP, "Commit")) {
682 if (!dbus_message_get_args(m, &error, DBUS_TYPE_INVALID)) {
683 avahi_log_warn("Error parsing EntryGroup::Commit message");
687 avahi_s_entry_group_commit(i->entry_group);
688 return respond_ok(c, m);
691 } else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_ENTRY_GROUP, "Reset")) {
693 if (!dbus_message_get_args(m, &error, DBUS_TYPE_INVALID)) {
694 avahi_log_warn("Error parsing EntryGroup::Reset message");
698 avahi_s_entry_group_reset(i->entry_group);
699 return respond_ok(c, m);
701 } else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_ENTRY_GROUP, "IsEmpty")) {
705 if (!dbus_message_get_args(m, &error, DBUS_TYPE_INVALID)) {
706 avahi_log_warn("Error parsing EntryGroup::IsEmpty message");
710 b = !!avahi_s_entry_group_is_empty(i->entry_group);
712 reply = dbus_message_new_method_return(m);
713 dbus_message_append_args(reply, DBUS_TYPE_BOOLEAN, &b, DBUS_TYPE_INVALID);
714 dbus_connection_send(c, reply, NULL);
715 dbus_message_unref(reply);
717 return DBUS_HANDLER_RESULT_HANDLED;
719 } else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_ENTRY_GROUP, "GetState")) {
720 AvahiEntryGroupState state;
722 if (!dbus_message_get_args(m, &error, DBUS_TYPE_INVALID)) {
723 avahi_log_warn("Error parsing EntryGroup::GetState message");
727 state = avahi_s_entry_group_get_state(i->entry_group);
728 return respond_int32(c, m, (int32_t) state);
730 } else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_ENTRY_GROUP, "AddService")) {
731 int32_t interface, protocol;
732 char *type, *name, *domain, *host;
734 AvahiStringList *strlst;
735 DBusMessageIter iter, sub;
738 if (!dbus_message_get_args(
740 DBUS_TYPE_INT32, &interface,
741 DBUS_TYPE_INT32, &protocol,
742 DBUS_TYPE_STRING, &name,
743 DBUS_TYPE_STRING, &type,
744 DBUS_TYPE_STRING, &domain,
745 DBUS_TYPE_STRING, &host,
746 DBUS_TYPE_UINT16, &port,
747 DBUS_TYPE_INVALID) || !type || !name) {
748 avahi_log_warn("Error parsing EntryGroup::AddService message");
752 dbus_message_iter_init(m, &iter);
754 for (j = 0; j < 7; j++)
755 dbus_message_iter_next(&iter);
757 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY ||
758 dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_ARRAY) {
759 avahi_log_warn("Error parsing EntryGroup::AddService message 2");
764 dbus_message_iter_recurse(&iter, &sub);
767 DBusMessageIter sub2;
771 if ((at = dbus_message_iter_get_arg_type(&sub)) == DBUS_TYPE_INVALID)
774 assert(at == DBUS_TYPE_ARRAY);
776 if (dbus_message_iter_get_element_type(&sub) != DBUS_TYPE_BYTE) {
777 avahi_log_warn("Error parsing EntryGroup::AddService message");
781 dbus_message_iter_recurse(&sub, &sub2);
782 dbus_message_iter_get_fixed_array(&sub2, &k, &n);
783 strlst = avahi_string_list_add_arbitrary(strlst, k, n);
785 dbus_message_iter_next(&sub);
788 if (i->n_entries >= MAX_ENTRIES_PER_ENTRY_GROUP) {
789 avahi_string_list_free(strlst);
790 avahi_log_warn("Too many entries per entry group, client request failed.");
791 return respond_error(c, m, AVAHI_ERR_TOO_MANY_ENTRIES, NULL);
794 if (domain && !*domain)
800 if (avahi_server_add_service_strlst(avahi_server, i->entry_group, (AvahiIfIndex) interface, (AvahiProtocol) protocol, name, type, domain, host, port, strlst) < 0) {
801 avahi_string_list_free(strlst);
802 return respond_error(c, m, avahi_server_errno(avahi_server), NULL);
806 avahi_string_list_free(strlst);
808 return respond_ok(c, m);
810 } else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_ENTRY_GROUP, "AddAddress")) {
811 int32_t interface, protocol;
812 char *name, *address;
815 if (!dbus_message_get_args(
817 DBUS_TYPE_INT32, &interface,
818 DBUS_TYPE_INT32, &protocol,
819 DBUS_TYPE_STRING, &name,
820 DBUS_TYPE_STRING, &address,
821 DBUS_TYPE_INVALID) || !name || !address) {
822 avahi_log_warn("Error parsing EntryGroup::AddAddress message");
826 if (i->n_entries >= MAX_ENTRIES_PER_ENTRY_GROUP) {
827 avahi_log_warn("Too many entries per entry group, client request failed.");
828 return respond_error(c, m, AVAHI_ERR_TOO_MANY_ENTRIES, NULL);
831 if (!(avahi_address_parse(address, AVAHI_PROTO_UNSPEC, &a))) {
832 return respond_error(c, m, AVAHI_ERR_INVALID_ADDRESS, NULL);
835 if (avahi_server_add_address(avahi_server, i->entry_group, (AvahiIfIndex) interface, (AvahiProtocol) protocol, 0, name, &a) < 0)
836 return respond_error(c, m, avahi_server_errno(avahi_server), NULL);
840 return respond_ok(c, m);
843 avahi_log_warn("Missed message %s::%s()", dbus_message_get_interface(m), dbus_message_get_member(m));
846 if (dbus_error_is_set(&error))
847 dbus_error_free(&error);
849 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
852 static void sync_host_name_resolver_callback(AvahiSHostNameResolver *r, AvahiIfIndex interface, AvahiProtocol protocol, AvahiResolverEvent event, const char *host_name, const AvahiAddress *a, void* userdata) {
853 SyncHostNameResolverInfo *i = userdata;
859 if (event == AVAHI_RESOLVER_FOUND) {
860 char t[256], *pt = t;
861 int32_t i_interface, i_protocol, i_aprotocol;
865 avahi_address_snprint(t, sizeof(t), a);
867 i_interface = (int32_t) interface;
868 i_protocol = (int32_t) protocol;
869 i_aprotocol = (int32_t) a->family;
871 reply = dbus_message_new_method_return(i->message);
872 dbus_message_append_args(
874 DBUS_TYPE_INT32, &i_interface,
875 DBUS_TYPE_INT32, &i_protocol,
876 DBUS_TYPE_STRING, &host_name,
877 DBUS_TYPE_INT32, &i_aprotocol,
878 DBUS_TYPE_STRING, &pt,
881 dbus_connection_send(server->bus, reply, NULL);
882 dbus_message_unref(reply);
884 assert(event == AVAHI_RESOLVER_TIMEOUT);
886 respond_error(server->bus, i->message, AVAHI_ERR_TIMEOUT, NULL);
889 sync_host_name_resolver_free(i);
892 static void sync_address_resolver_callback(AvahiSAddressResolver *r, AvahiIfIndex interface, AvahiProtocol protocol, AvahiResolverEvent event, const AvahiAddress *address, const char *host_name, void* userdata) {
893 SyncAddressResolverInfo *i = userdata;
899 if (event == AVAHI_RESOLVER_FOUND) {
900 char t[256], *pt = t;
901 int32_t i_interface, i_protocol, i_aprotocol;
905 avahi_address_snprint(t, sizeof(t), address);
907 i_interface = (int32_t) interface;
908 i_protocol = (int32_t) protocol;
909 i_aprotocol = (int32_t) address->family;
911 reply = dbus_message_new_method_return(i->message);
912 dbus_message_append_args(
914 DBUS_TYPE_INT32, &i_interface,
915 DBUS_TYPE_INT32, &i_protocol,
916 DBUS_TYPE_INT32, &i_aprotocol,
917 DBUS_TYPE_STRING, &pt,
918 DBUS_TYPE_STRING, &host_name,
921 dbus_connection_send(server->bus, reply, NULL);
922 dbus_message_unref(reply);
924 assert(event == AVAHI_RESOLVER_TIMEOUT);
925 respond_error(server->bus, i->message, AVAHI_ERR_TIMEOUT, NULL);
928 sync_address_resolver_free(i);
931 static DBusHandlerResult msg_domain_browser_impl(DBusConnection *c, DBusMessage *m, void *userdata) {
933 DomainBrowserInfo *i = userdata;
939 dbus_error_init(&error);
941 avahi_log_debug(__FILE__": interface=%s, path=%s, member=%s",
942 dbus_message_get_interface(m),
943 dbus_message_get_path(m),
944 dbus_message_get_member(m));
947 if (dbus_message_is_method_call(m, DBUS_INTERFACE_INTROSPECTABLE, "Introspect"))
948 return handle_introspect(c, m, "DomainBrowser.introspect");
951 if (strcmp(dbus_message_get_sender(m), i->client->name))
952 return respond_error(c, m, AVAHI_ERR_ACCESS_DENIED, NULL);
954 if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_DOMAIN_BROWSER, "Free")) {
956 if (!dbus_message_get_args(m, &error, DBUS_TYPE_INVALID)) {
957 avahi_log_warn("Error parsing DomainBrowser::Free message");
961 domain_browser_free(i);
962 return respond_ok(c, m);
966 avahi_log_warn("Missed message %s::%s()", dbus_message_get_interface(m), dbus_message_get_member(m));
969 if (dbus_error_is_set(&error))
970 dbus_error_free(&error);
972 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
975 static void domain_browser_callback(AvahiSDomainBrowser *b, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, const char *domain, void* userdata) {
976 DomainBrowserInfo *i = userdata;
978 int32_t i_interface, i_protocol;
984 i_interface = (int32_t) interface;
985 i_protocol = (int32_t) protocol;
987 m = dbus_message_new_signal(i->path, AVAHI_DBUS_INTERFACE_DOMAIN_BROWSER, event == AVAHI_BROWSER_NEW ? "ItemNew" : "ItemRemove");
988 dbus_message_append_args(
990 DBUS_TYPE_INT32, &i_interface,
991 DBUS_TYPE_INT32, &i_protocol,
992 DBUS_TYPE_STRING, &domain,
994 dbus_message_set_destination(m, i->client->name);
995 dbus_connection_send(server->bus, m, NULL);
996 dbus_message_unref(m);
999 static DBusHandlerResult msg_service_type_browser_impl(DBusConnection *c, DBusMessage *m, void *userdata) {
1001 ServiceTypeBrowserInfo *i = userdata;
1007 dbus_error_init(&error);
1009 avahi_log_debug(__FILE__": interface=%s, path=%s, member=%s",
1010 dbus_message_get_interface(m),
1011 dbus_message_get_path(m),
1012 dbus_message_get_member(m));
1015 if (dbus_message_is_method_call(m, DBUS_INTERFACE_INTROSPECTABLE, "Introspect"))
1016 return handle_introspect(c, m, "ServiceTypeBrowser.introspect");
1018 /* Access control */
1019 if (strcmp(dbus_message_get_sender(m), i->client->name))
1020 return respond_error(c, m, AVAHI_ERR_ACCESS_DENIED, NULL);
1022 if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_SERVICE_TYPE_BROWSER, "Free")) {
1024 if (!dbus_message_get_args(m, &error, DBUS_TYPE_INVALID)) {
1025 avahi_log_warn("Error parsing ServiceTypeBrowser::Free message");
1029 service_type_browser_free(i);
1030 return respond_ok(c, m);
1034 avahi_log_warn("Missed message %s::%s()", dbus_message_get_interface(m), dbus_message_get_member(m));
1037 if (dbus_error_is_set(&error))
1038 dbus_error_free(&error);
1040 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
1043 static void service_type_browser_callback(AvahiSServiceTypeBrowser *b, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, const char *type, const char *domain, void* userdata) {
1044 ServiceTypeBrowserInfo *i = userdata;
1046 int32_t i_interface, i_protocol;
1053 i_interface = (int32_t) interface;
1054 i_protocol = (int32_t) protocol;
1056 m = dbus_message_new_signal(i->path, AVAHI_DBUS_INTERFACE_SERVICE_TYPE_BROWSER, event == AVAHI_BROWSER_NEW ? "ItemNew" : "ItemRemove");
1057 dbus_message_append_args(
1059 DBUS_TYPE_INT32, &i_interface,
1060 DBUS_TYPE_INT32, &i_protocol,
1061 DBUS_TYPE_STRING, &type,
1062 DBUS_TYPE_STRING, &domain,
1064 dbus_message_set_destination(m, i->client->name);
1065 dbus_connection_send(server->bus, m, NULL);
1066 dbus_message_unref(m);
1069 static DBusHandlerResult msg_service_browser_impl(DBusConnection *c, DBusMessage *m, void *userdata) {
1071 ServiceBrowserInfo *i = userdata;
1077 dbus_error_init(&error);
1079 avahi_log_debug(__FILE__": interface=%s, path=%s, member=%s",
1080 dbus_message_get_interface(m),
1081 dbus_message_get_path(m),
1082 dbus_message_get_member(m));
1085 if (dbus_message_is_method_call(m, DBUS_INTERFACE_INTROSPECTABLE, "Introspect"))
1086 return handle_introspect(c, m, "ServiceBrowser.Introspect");
1088 /* Access control */
1089 if (strcmp(dbus_message_get_sender(m), i->client->name))
1090 return respond_error(c, m, AVAHI_ERR_ACCESS_DENIED, NULL);
1092 if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_SERVICE_BROWSER, "Free")) {
1094 if (!dbus_message_get_args(m, &error, DBUS_TYPE_INVALID)) {
1095 avahi_log_warn("Error parsing ServiceBrowser::Free message");
1099 service_browser_free(i);
1100 return respond_ok(c, m);
1104 avahi_log_warn("Missed message %s::%s()", dbus_message_get_interface(m), dbus_message_get_member(m));
1107 if (dbus_error_is_set(&error))
1108 dbus_error_free(&error);
1110 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
1113 static void service_browser_callback(AvahiSServiceBrowser *b, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, const char *name, const char *type, const char *domain, void* userdata) {
1114 ServiceBrowserInfo *i = userdata;
1116 int32_t i_interface, i_protocol;
1124 i_interface = (int32_t) interface;
1125 i_protocol = (int32_t) protocol;
1127 m = dbus_message_new_signal(i->path, AVAHI_DBUS_INTERFACE_SERVICE_BROWSER, event == AVAHI_BROWSER_NEW ? "ItemNew" : "ItemRemove");
1128 dbus_message_append_args(
1130 DBUS_TYPE_INT32, &i_interface,
1131 DBUS_TYPE_INT32, &i_protocol,
1132 DBUS_TYPE_STRING, &name,
1133 DBUS_TYPE_STRING, &type,
1134 DBUS_TYPE_STRING, &domain,
1136 dbus_message_set_destination(m, i->client->name);
1137 dbus_connection_send(server->bus, m, NULL);
1138 dbus_message_unref(m);
1141 static void append_string_list(DBusMessage *reply, AvahiStringList *txt) {
1143 DBusMessageIter iter, sub;
1147 dbus_message_iter_init_append(reply, &iter);
1148 dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "ay", &sub);
1150 for (p = txt; p; p = p->next) {
1151 DBusMessageIter sub2;
1152 const uint8_t *data = p->text;
1154 dbus_message_iter_open_container(&sub, DBUS_TYPE_ARRAY, "y", &sub2);
1155 dbus_message_iter_append_fixed_array(&sub2, DBUS_TYPE_BYTE, &data, p->size);
1156 dbus_message_iter_close_container(&sub, &sub2);
1159 dbus_message_iter_close_container(&iter, &sub);
1162 static void sync_service_resolver_callback(
1163 AvahiSServiceResolver *r,
1164 AvahiIfIndex interface,
1165 AvahiProtocol protocol,
1166 AvahiResolverEvent event,
1170 const char *host_name,
1171 const AvahiAddress *a,
1173 AvahiStringList *txt,
1176 SyncServiceResolverInfo *i = userdata;
1181 if (event == AVAHI_RESOLVER_FOUND) {
1182 char t[256], *pt = t;
1183 int32_t i_interface, i_protocol, i_aprotocol;
1189 avahi_address_snprint(t, sizeof(t), a);
1191 i_interface = (int32_t) interface;
1192 i_protocol = (int32_t) protocol;
1193 i_aprotocol = (int32_t) a->family;
1195 reply = dbus_message_new_method_return(i->message);
1196 dbus_message_append_args(
1198 DBUS_TYPE_INT32, &i_interface,
1199 DBUS_TYPE_INT32, &i_protocol,
1200 DBUS_TYPE_STRING, &name,
1201 DBUS_TYPE_STRING, &type,
1202 DBUS_TYPE_STRING, &domain,
1203 DBUS_TYPE_STRING, &host_name,
1204 DBUS_TYPE_INT32, &i_aprotocol,
1205 DBUS_TYPE_STRING, &pt,
1206 DBUS_TYPE_UINT16, &port,
1209 append_string_list(reply, txt);
1211 dbus_connection_send(server->bus, reply, NULL);
1212 dbus_message_unref(reply);
1214 assert(event == AVAHI_RESOLVER_TIMEOUT);
1216 respond_error(server->bus, i->message, AVAHI_ERR_TIMEOUT, NULL);
1219 sync_service_resolver_free(i);
1222 static void async_address_resolver_callback(AvahiSAddressResolver *r, AvahiIfIndex interface, AvahiProtocol protocol, AvahiResolverEvent event, const AvahiAddress *address, const char *host_name, void* userdata) {
1223 AsyncAddressResolverInfo *i = userdata;
1230 if (event == AVAHI_RESOLVER_FOUND) {
1231 char t[256], *pt = t;
1232 int32_t i_interface, i_protocol, i_aprotocol;
1235 avahi_address_snprint(t, sizeof(t), address);
1237 i_interface = (int32_t) interface;
1238 i_protocol = (int32_t) protocol;
1239 i_aprotocol = (int32_t) address->family;
1241 reply = dbus_message_new_signal(i->path, AVAHI_DBUS_INTERFACE_ADDRESS_RESOLVER, "Found");
1242 dbus_message_append_args(
1244 DBUS_TYPE_INT32, &i_interface,
1245 DBUS_TYPE_INT32, &i_protocol,
1246 DBUS_TYPE_INT32, &i_aprotocol,
1247 DBUS_TYPE_STRING, &pt,
1248 DBUS_TYPE_STRING, &host_name,
1252 assert(event == AVAHI_RESOLVER_TIMEOUT);
1254 reply = dbus_message_new_signal(i->path, AVAHI_DBUS_INTERFACE_ADDRESS_RESOLVER, "Timeout");
1257 dbus_message_set_destination(reply, i->client->name);
1258 dbus_connection_send(server->bus, reply, NULL);
1259 dbus_message_unref(reply);
1262 static DBusHandlerResult msg_async_address_resolver_impl(DBusConnection *c, DBusMessage *m, void *userdata) {
1264 AsyncAddressResolverInfo *i = userdata;
1270 dbus_error_init(&error);
1272 avahi_log_debug(__FILE__": interface=%s, path=%s, member=%s",
1273 dbus_message_get_interface(m),
1274 dbus_message_get_path(m),
1275 dbus_message_get_member(m));
1278 if (dbus_message_is_method_call(m, DBUS_INTERFACE_INTROSPECTABLE, "Introspect"))
1279 return handle_introspect(c, m, "AddressResolver.Introspect");
1281 /* Access control */
1282 if (strcmp(dbus_message_get_sender(m), i->client->name))
1283 return respond_error(c, m, AVAHI_ERR_ACCESS_DENIED, NULL);
1285 if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_ADDRESS_RESOLVER, "Free")) {
1287 if (!dbus_message_get_args(m, &error, DBUS_TYPE_INVALID)) {
1288 avahi_log_warn("Error parsing AddressResolver::Free message");
1292 async_address_resolver_free(i);
1293 return respond_ok(c, m);
1297 avahi_log_warn("Missed message %s::%s()", dbus_message_get_interface(m), dbus_message_get_member(m));
1300 if (dbus_error_is_set(&error))
1301 dbus_error_free(&error);
1303 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
1306 static void async_host_name_resolver_callback(AvahiSHostNameResolver *r, AvahiIfIndex interface, AvahiProtocol protocol, AvahiResolverEvent event, const char *host_name, const AvahiAddress *a, void* userdata) {
1307 AsyncHostNameResolverInfo *i = userdata;
1314 if (event == AVAHI_RESOLVER_FOUND) {
1315 char t[256], *pt = t;
1316 int32_t i_interface, i_protocol, i_aprotocol;
1319 avahi_address_snprint(t, sizeof(t), a);
1321 i_interface = (int32_t) interface;
1322 i_protocol = (int32_t) protocol;
1323 i_aprotocol = (int32_t) a->family;
1325 reply = dbus_message_new_signal(i->path, AVAHI_DBUS_INTERFACE_HOST_NAME_RESOLVER, "Found");
1326 dbus_message_append_args(
1328 DBUS_TYPE_INT32, &i_interface,
1329 DBUS_TYPE_INT32, &i_protocol,
1330 DBUS_TYPE_STRING, &host_name,
1331 DBUS_TYPE_INT32, &i_aprotocol,
1332 DBUS_TYPE_STRING, &pt,
1335 assert(event == AVAHI_RESOLVER_TIMEOUT);
1337 reply = dbus_message_new_signal(i->path, AVAHI_DBUS_INTERFACE_HOST_NAME_RESOLVER, "Timeout");
1340 dbus_message_set_destination(reply, i->client->name);
1341 dbus_connection_send(server->bus, reply, NULL);
1342 dbus_message_unref(reply);
1345 static DBusHandlerResult msg_async_host_name_resolver_impl(DBusConnection *c, DBusMessage *m, void *userdata) {
1347 AsyncHostNameResolverInfo *i = userdata;
1353 dbus_error_init(&error);
1355 avahi_log_debug(__FILE__": interface=%s, path=%s, member=%s",
1356 dbus_message_get_interface(m),
1357 dbus_message_get_path(m),
1358 dbus_message_get_member(m));
1361 if (dbus_message_is_method_call(m, DBUS_INTERFACE_INTROSPECTABLE, "Introspect"))
1362 return handle_introspect(c, m, "HostNameResolver.Introspect");
1364 /* Access control */
1365 if (strcmp(dbus_message_get_sender(m), i->client->name))
1366 return respond_error(c, m, AVAHI_ERR_ACCESS_DENIED, NULL);
1368 if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_HOST_NAME_RESOLVER, "Free")) {
1370 if (!dbus_message_get_args(m, &error, DBUS_TYPE_INVALID)) {
1371 avahi_log_warn("Error parsing HostNameResolver::Free message");
1375 async_host_name_resolver_free(i);
1376 return respond_ok(c, m);
1379 avahi_log_warn("Missed message %s::%s()", dbus_message_get_interface(m), dbus_message_get_member(m));
1382 if (dbus_error_is_set(&error))
1383 dbus_error_free(&error);
1385 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
1388 static void async_service_resolver_callback(
1389 AvahiSServiceResolver *r,
1390 AvahiIfIndex interface,
1391 AvahiProtocol protocol,
1392 AvahiResolverEvent event,
1396 const char *host_name,
1397 const AvahiAddress *a,
1399 AvahiStringList *txt,
1402 AsyncServiceResolverInfo *i = userdata;
1408 if (event == AVAHI_RESOLVER_FOUND) {
1409 char t[256], *pt = t;
1410 int32_t i_interface, i_protocol, i_aprotocol;
1414 /* avahi_log_debug(__FILE__": [%s] Successfully resolved service <%s.%s.%s>", i->path, name, type, domain); */
1417 avahi_address_snprint(t, sizeof(t), a);
1419 i_interface = (int32_t) interface;
1420 i_protocol = (int32_t) protocol;
1421 i_aprotocol = (int32_t) a->family;
1423 reply = dbus_message_new_signal(i->path, AVAHI_DBUS_INTERFACE_SERVICE_RESOLVER, "Found");
1424 dbus_message_append_args(
1426 DBUS_TYPE_INT32, &i_interface,
1427 DBUS_TYPE_INT32, &i_protocol,
1428 DBUS_TYPE_STRING, &name,
1429 DBUS_TYPE_STRING, &type,
1430 DBUS_TYPE_STRING, &domain,
1431 DBUS_TYPE_STRING, &host_name,
1432 DBUS_TYPE_INT32, &i_aprotocol,
1433 DBUS_TYPE_STRING, &pt,
1434 DBUS_TYPE_UINT16, &port,
1437 append_string_list(reply, txt);
1440 assert(event == AVAHI_RESOLVER_TIMEOUT);
1442 /* avahi_log_debug(__FILE__": [%s] Failed to resolve service <%s.%s.%s>", i->path, name, type, domain); */
1444 reply = dbus_message_new_signal(i->path, AVAHI_DBUS_INTERFACE_SERVICE_RESOLVER, "Timeout");
1447 dbus_message_set_destination(reply, i->client->name);
1448 dbus_connection_send(server->bus, reply, NULL);
1449 dbus_message_unref(reply);
1452 static DBusHandlerResult msg_async_service_resolver_impl(DBusConnection *c, DBusMessage *m, void *userdata) {
1454 AsyncServiceResolverInfo *i = userdata;
1460 dbus_error_init(&error);
1462 avahi_log_debug(__FILE__": interface=%s, path=%s, member=%s",
1463 dbus_message_get_interface(m),
1464 dbus_message_get_path(m),
1465 dbus_message_get_member(m));
1468 if (dbus_message_is_method_call(m, DBUS_INTERFACE_INTROSPECTABLE, "Introspect"))
1469 return handle_introspect(c, m, "ServiceResolver.Introspect");
1471 /* Access control */
1472 if (strcmp(dbus_message_get_sender(m), i->client->name))
1473 return respond_error(c, m, AVAHI_ERR_ACCESS_DENIED, NULL);
1475 if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_SERVICE_RESOLVER, "Free")) {
1477 if (!dbus_message_get_args(m, &error, DBUS_TYPE_INVALID)) {
1478 avahi_log_warn("Error parsing ServiceResolver::Free message");
1482 async_service_resolver_free(i);
1483 return respond_ok(c, m);
1486 avahi_log_warn("Missed message %s::%s()", dbus_message_get_interface(m), dbus_message_get_member(m));
1489 if (dbus_error_is_set(&error))
1490 dbus_error_free(&error);
1492 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
1495 static DBusHandlerResult msg_server_impl(DBusConnection *c, DBusMessage *m, void *userdata) {
1498 dbus_error_init(&error);
1500 avahi_log_debug(__FILE__": interface=%s, path=%s, member=%s",
1501 dbus_message_get_interface(m),
1502 dbus_message_get_path(m),
1503 dbus_message_get_member(m));
1505 if (dbus_message_is_method_call(m, DBUS_INTERFACE_INTROSPECTABLE, "Introspect"))
1506 return handle_introspect(c, m, "Server.introspect");
1508 else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_SERVER, "GetHostName")) {
1510 if (!dbus_message_get_args(m, &error, DBUS_TYPE_INVALID)) {
1511 avahi_log_warn("Error parsing Server::GetHostName message");
1515 return respond_string(c, m, avahi_server_get_host_name(avahi_server));
1517 } else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_SERVER, "GetDomainName")) {
1519 if (!dbus_message_get_args(m, &error, DBUS_TYPE_INVALID)) {
1520 avahi_log_warn("Error parsing Server::GetDomainName message");
1524 return respond_string(c, m, avahi_server_get_domain_name(avahi_server));
1526 } else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_SERVER, "GetHostNameFqdn")) {
1528 if (!(dbus_message_get_args(m, &error, DBUS_TYPE_INVALID))) {
1529 avahi_log_warn("Error parsing Server::GetHostNameFqdn message");
1533 return respond_string(c, m, avahi_server_get_host_name_fqdn(avahi_server));
1535 } else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_SERVER, "GetVersionString")) {
1537 if (!(dbus_message_get_args(m, &error, DBUS_TYPE_INVALID))) {
1538 avahi_log_warn("Error parsing Server::GetVersionString message");
1542 return respond_string(c, m, PACKAGE_STRING);
1544 } else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_SERVER, "GetState")) {
1545 AvahiServerState state;
1547 if (!(dbus_message_get_args(m, &error, DBUS_TYPE_INVALID))) {
1548 avahi_log_warn("Error parsing Server::GetState message");
1552 state = avahi_server_get_state(avahi_server);
1553 return respond_int32(c, m, (int32_t) state);
1555 } else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_SERVER, "GetLocalServiceCookie")) {
1557 if (!(dbus_message_get_args(m, &error, DBUS_TYPE_INVALID))) {
1558 avahi_log_warn("Error parsing Server::GetLocalServiceCookie message");
1562 return respond_uint32(c, m, avahi_server_get_local_service_cookie(avahi_server));
1564 } else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_SERVER, "GetNetworkInterfaceNameByIndex")) {
1569 if (!(dbus_message_get_args(m, &error, DBUS_TYPE_INT32, &idx, DBUS_TYPE_INVALID))) {
1570 avahi_log_warn("Error parsing Server::GetNetworkInterfaceNameByIndex message");
1574 #ifdef VALGRIND_WORKAROUND
1575 return respond_string(c, m, "blah");
1578 if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
1579 if ((fd = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
1581 snprintf(txt, sizeof(txt), "OS Error: %s", strerror(errno));
1582 return respond_error(c, m, AVAHI_ERR_OS, txt);
1585 memset(&ifr, 0, sizeof(ifr));
1586 ifr.ifr_ifindex = idx;
1588 if (ioctl(fd, SIOCGIFNAME, &ifr) < 0) {
1590 snprintf(txt, sizeof(txt), "OS Error: %s", strerror(errno));
1592 return respond_error(c, m, AVAHI_ERR_OS, txt);
1597 return respond_string(c, m, ifr.ifr_name);
1600 } else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_SERVER, "GetNetworkInterfaceIndexByName")) {
1605 if (!(dbus_message_get_args(m, &error, DBUS_TYPE_STRING, &n, DBUS_TYPE_INVALID)) || !n) {
1606 avahi_log_warn("Error parsing Server::GetNetworkInterfaceIndexByName message");
1610 #ifdef VALGRIND_WORKAROUND
1611 return respond_int32(c, m, 1);
1613 if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
1614 if ((fd = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
1616 snprintf(txt, sizeof(txt), "OS Error: %s", strerror(errno));
1617 return respond_error(c, m, AVAHI_ERR_OS, txt);
1620 memset(&ifr, 0, sizeof(ifr));
1621 snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s", n);
1623 if (ioctl(fd, SIOCGIFINDEX, &ifr) < 0) {
1625 snprintf(txt, sizeof(txt), "OS Error: %s", strerror(errno));
1627 return respond_error(c, m, AVAHI_ERR_OS, txt);
1632 return respond_int32(c, m, ifr.ifr_ifindex);
1635 } else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_SERVER, "GetAlternativeHostName")) {
1638 if (!(dbus_message_get_args(m, &error, DBUS_TYPE_STRING, &n, DBUS_TYPE_INVALID)) || !n) {
1639 avahi_log_warn("Error parsing Server::GetAlternativeHostName message");
1643 t = avahi_alternative_host_name(n);
1644 respond_string(c, m, t);
1647 return DBUS_HANDLER_RESULT_HANDLED;
1649 } else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_SERVER, "GetAlternativeServiceName")) {
1652 if (!(dbus_message_get_args(m, &error, DBUS_TYPE_STRING, &n, DBUS_TYPE_INVALID)) || !n) {
1653 avahi_log_warn("Error parsing Server::GetAlternativeServiceName message");
1657 t = avahi_alternative_service_name(n);
1658 respond_string(c, m, t);
1661 return DBUS_HANDLER_RESULT_HANDLED;
1663 } else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_SERVER, "EntryGroupNew")) {
1666 static const DBusObjectPathVTable vtable = {
1668 msg_entry_group_impl,
1675 if (!dbus_message_get_args(m, &error, DBUS_TYPE_INVALID)) {
1676 avahi_log_warn("Error parsing Server::EntryGroupNew message");
1680 if (!(client = client_get(dbus_message_get_sender(m), TRUE))) {
1681 avahi_log_warn("Too many clients, client request failed.");
1682 return respond_error(c, m, AVAHI_ERR_TOO_MANY_CLIENTS, NULL);
1685 if (client->n_objects >= MAX_OBJECTS_PER_CLIENT) {
1686 avahi_log_warn("Too many objects for client '%s', client request failed.", client->name);
1687 return respond_error(c, m, AVAHI_ERR_TOO_MANY_OBJECTS, NULL);
1690 i = avahi_new(EntryGroupInfo, 1);
1691 i->id = ++client->current_id;
1693 i->path = avahi_strdup_printf("/Client%u/EntryGroup%u", client->id, i->id);
1695 AVAHI_LLIST_PREPEND(EntryGroupInfo, entry_groups, client->entry_groups, i);
1696 client->n_objects++;
1698 if (!(i->entry_group = avahi_s_entry_group_new(avahi_server, entry_group_callback, i))) {
1699 entry_group_free(i);
1700 return respond_error(c, m, avahi_server_errno(avahi_server), NULL);
1703 dbus_connection_register_object_path(c, i->path, &vtable, i);
1704 return respond_path(c, m, i->path);
1706 } else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_SERVER, "ResolveHostName")) {
1708 int32_t interface, protocol, aprotocol;
1710 SyncHostNameResolverInfo *i;
1712 if (!dbus_message_get_args(
1714 DBUS_TYPE_INT32, &interface,
1715 DBUS_TYPE_INT32, &protocol,
1716 DBUS_TYPE_STRING, &name,
1717 DBUS_TYPE_INT32, &aprotocol,
1718 DBUS_TYPE_INVALID) || !name) {
1719 avahi_log_warn("Error parsing Server::ResolveHostName message");
1723 if (!(client = client_get(dbus_message_get_sender(m), TRUE))) {
1724 avahi_log_warn("Too many clients, client request failed.");
1725 return respond_error(c, m, AVAHI_ERR_TOO_MANY_CLIENTS, NULL);
1728 if (client->n_objects >= MAX_OBJECTS_PER_CLIENT) {
1729 avahi_log_warn("Too many objects for client '%s', client request failed.", client->name);
1730 return respond_error(c, m, AVAHI_ERR_TOO_MANY_OBJECTS, NULL);
1733 i = avahi_new(SyncHostNameResolverInfo, 1);
1735 i->message = dbus_message_ref(m);
1736 AVAHI_LLIST_PREPEND(SyncHostNameResolverInfo, sync_host_name_resolvers, client->sync_host_name_resolvers, i);
1737 client->n_objects++;
1739 if (!(i->host_name_resolver = avahi_s_host_name_resolver_new(avahi_server, (AvahiIfIndex) interface, (AvahiProtocol) protocol, name, (AvahiProtocol) aprotocol, sync_host_name_resolver_callback, i))) {
1740 sync_host_name_resolver_free(i);
1741 return respond_error(c, m, avahi_server_errno(avahi_server), NULL);
1744 return DBUS_HANDLER_RESULT_HANDLED;
1746 } else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_SERVER, "ResolveAddress")) {
1748 int32_t interface, protocol;
1750 SyncAddressResolverInfo *i;
1753 if (!dbus_message_get_args(
1755 DBUS_TYPE_INT32, &interface,
1756 DBUS_TYPE_INT32, &protocol,
1757 DBUS_TYPE_STRING, &address,
1758 DBUS_TYPE_INVALID) || !address) {
1759 avahi_log_warn("Error parsing Server::ResolveAddress message");
1763 if (!avahi_address_parse(address, AVAHI_PROTO_UNSPEC, &a))
1764 return respond_error(c, m, AVAHI_ERR_INVALID_ADDRESS, NULL);
1766 if (!(client = client_get(dbus_message_get_sender(m), TRUE))) {
1767 avahi_log_warn("Too many clients, client request failed.");
1768 return respond_error(c, m, AVAHI_ERR_TOO_MANY_CLIENTS, NULL);
1771 if (client->n_objects >= MAX_OBJECTS_PER_CLIENT) {
1772 avahi_log_warn("Too many objects for client '%s', client request failed.", client->name);
1773 return respond_error(c, m, AVAHI_ERR_TOO_MANY_OBJECTS, NULL);
1776 i = avahi_new(SyncAddressResolverInfo, 1);
1778 i->message = dbus_message_ref(m);
1779 AVAHI_LLIST_PREPEND(SyncAddressResolverInfo, sync_address_resolvers, client->sync_address_resolvers, i);
1780 client->n_objects++;
1782 if (!(i->address_resolver = avahi_s_address_resolver_new(avahi_server, (AvahiIfIndex) interface, (AvahiProtocol) protocol, &a, sync_address_resolver_callback, i))) {
1783 sync_address_resolver_free(i);
1784 return respond_error(c, m, avahi_server_errno(avahi_server), NULL);
1787 return DBUS_HANDLER_RESULT_HANDLED;
1789 } else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_SERVER, "DomainBrowserNew")) {
1791 DomainBrowserInfo *i;
1792 static const DBusObjectPathVTable vtable = {
1794 msg_domain_browser_impl,
1800 int32_t interface, protocol, type;
1803 if (!dbus_message_get_args(
1805 DBUS_TYPE_INT32, &interface,
1806 DBUS_TYPE_INT32, &protocol,
1807 DBUS_TYPE_STRING, &domain,
1808 DBUS_TYPE_INT32, &type,
1809 DBUS_TYPE_INVALID) || type < 0 || type >= AVAHI_DOMAIN_BROWSER_MAX) {
1810 avahi_log_warn("Error parsing Server::DomainBrowserNew message");
1814 if (!(client = client_get(dbus_message_get_sender(m), TRUE))) {
1815 avahi_log_warn("Too many clients, client request failed.");
1816 return respond_error(c, m, AVAHI_ERR_TOO_MANY_CLIENTS, NULL);
1819 if (client->n_objects >= MAX_OBJECTS_PER_CLIENT) {
1820 avahi_log_warn("Too many objects for client '%s', client request failed.", client->name);
1821 return respond_error(c, m, AVAHI_ERR_TOO_MANY_OBJECTS, NULL);
1827 i = avahi_new(DomainBrowserInfo, 1);
1828 i->id = ++client->current_id;
1830 i->path = avahi_strdup_printf("/Client%u/DomainBrowser%u", client->id, i->id);
1831 AVAHI_LLIST_PREPEND(DomainBrowserInfo, domain_browsers, client->domain_browsers, i);
1832 client->n_objects++;
1834 if (!(i->domain_browser = avahi_s_domain_browser_new(avahi_server, (AvahiIfIndex) interface, (AvahiProtocol) protocol, domain, (AvahiDomainBrowserType) type, domain_browser_callback, i))) {
1835 domain_browser_free(i);
1836 return respond_error(c, m, avahi_server_errno(avahi_server), NULL);
1839 dbus_connection_register_object_path(c, i->path, &vtable, i);
1840 return respond_path(c, m, i->path);
1842 } else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_SERVER, "ServiceTypeBrowserNew")) {
1844 ServiceTypeBrowserInfo *i;
1845 static const DBusObjectPathVTable vtable = {
1847 msg_service_type_browser_impl,
1853 int32_t interface, protocol;
1856 if (!dbus_message_get_args(
1858 DBUS_TYPE_INT32, &interface,
1859 DBUS_TYPE_INT32, &protocol,
1860 DBUS_TYPE_STRING, &domain,
1861 DBUS_TYPE_INVALID)) {
1862 avahi_log_warn("Error parsing Server::ServiceTypeBrowserNew message");
1866 if (!(client = client_get(dbus_message_get_sender(m), TRUE))) {
1867 avahi_log_warn("Too many clients, client request failed.");
1868 return respond_error(c, m, AVAHI_ERR_TOO_MANY_CLIENTS, NULL);
1872 if (client->n_objects >= MAX_OBJECTS_PER_CLIENT) {
1873 avahi_log_warn("Too many objects for client '%s', client request failed.", client->name);
1874 return respond_error(c, m, AVAHI_ERR_TOO_MANY_OBJECTS, NULL);
1880 i = avahi_new(ServiceTypeBrowserInfo, 1);
1881 i->id = ++client->current_id;
1883 i->path = avahi_strdup_printf("/Client%u/ServiceTypeBrowser%u", client->id, i->id);
1884 AVAHI_LLIST_PREPEND(ServiceTypeBrowserInfo, service_type_browsers, client->service_type_browsers, i);
1885 client->n_objects++;
1887 if (!(i->service_type_browser = avahi_s_service_type_browser_new(avahi_server, (AvahiIfIndex) interface, (AvahiProtocol) protocol, domain, service_type_browser_callback, i))) {
1888 service_type_browser_free(i);
1889 return respond_error(c, m, avahi_server_errno(avahi_server), NULL);
1892 dbus_connection_register_object_path(c, i->path, &vtable, i);
1893 return respond_path(c, m, i->path);
1895 } else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_SERVER, "ServiceBrowserNew")) {
1897 ServiceBrowserInfo *i;
1898 static const DBusObjectPathVTable vtable = {
1900 msg_service_browser_impl,
1906 int32_t interface, protocol;
1907 char *domain, *type;
1909 if (!dbus_message_get_args(
1911 DBUS_TYPE_INT32, &interface,
1912 DBUS_TYPE_INT32, &protocol,
1913 DBUS_TYPE_STRING, &type,
1914 DBUS_TYPE_STRING, &domain,
1915 DBUS_TYPE_INVALID) || !type) {
1916 avahi_log_warn("Error parsing Server::ServiceBrowserNew message");
1920 if (!(client = client_get(dbus_message_get_sender(m), TRUE))) {
1921 avahi_log_warn("Too many clients, client request failed.");
1922 return respond_error(c, m, AVAHI_ERR_TOO_MANY_CLIENTS, NULL);
1926 if (client->n_objects >= MAX_OBJECTS_PER_CLIENT) {
1927 avahi_log_warn("Too many objects for client '%s', client request failed.", client->name);
1928 return respond_error(c, m, AVAHI_ERR_TOO_MANY_OBJECTS, NULL);
1934 i = avahi_new(ServiceBrowserInfo, 1);
1935 i->id = ++client->current_id;
1937 i->path = avahi_strdup_printf("/Client%u/ServiceBrowser%u", client->id, i->id);
1938 AVAHI_LLIST_PREPEND(ServiceBrowserInfo, service_browsers, client->service_browsers, i);
1939 client->n_objects++;
1941 if (!(i->service_browser = avahi_s_service_browser_new(avahi_server, (AvahiIfIndex) interface, (AvahiProtocol) protocol, type, domain, service_browser_callback, i))) {
1942 service_browser_free(i);
1943 return respond_error(c, m, avahi_server_errno(avahi_server), NULL);
1946 dbus_connection_register_object_path(c, i->path, &vtable, i);
1947 return respond_path(c, m, i->path);
1949 } else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_SERVER, "ResolveService")) {
1951 int32_t interface, protocol, aprotocol;
1952 char *name, *type, *domain;
1953 SyncServiceResolverInfo *i;
1955 if (!dbus_message_get_args(
1957 DBUS_TYPE_INT32, &interface,
1958 DBUS_TYPE_INT32, &protocol,
1959 DBUS_TYPE_STRING, &name,
1960 DBUS_TYPE_STRING, &type,
1961 DBUS_TYPE_STRING, &domain,
1962 DBUS_TYPE_INT32, &aprotocol,
1963 DBUS_TYPE_INVALID) || !name || !type) {
1964 avahi_log_warn("Error parsing Server::ResolveService message");
1968 if (!(client = client_get(dbus_message_get_sender(m), TRUE))) {
1969 avahi_log_warn("Too many clients, client request failed.");
1970 return respond_error(c, m, AVAHI_ERR_TOO_MANY_CLIENTS, NULL);
1973 if (client->n_objects >= MAX_OBJECTS_PER_CLIENT) {
1974 avahi_log_warn("Too many objects for client '%s', client request failed.", client->name);
1975 return respond_error(c, m, AVAHI_ERR_TOO_MANY_OBJECTS, NULL);
1981 i = avahi_new(SyncServiceResolverInfo, 1);
1983 i->message = dbus_message_ref(m);
1984 AVAHI_LLIST_PREPEND(SyncServiceResolverInfo, sync_service_resolvers, client->sync_service_resolvers, i);
1985 client->n_objects++;
1987 if (!(i->service_resolver = avahi_s_service_resolver_new(avahi_server, (AvahiIfIndex) interface, (AvahiProtocol) protocol, name, type, domain, (AvahiProtocol) aprotocol, sync_service_resolver_callback, i))) {
1988 sync_service_resolver_free(i);
1989 return respond_error(c, m, avahi_server_errno(avahi_server), NULL);
1992 return DBUS_HANDLER_RESULT_HANDLED;
1994 } else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_SERVER, "ServiceResolverNew")) {
1996 int32_t interface, protocol, aprotocol;
1997 char *name, *type, *domain;
1998 AsyncServiceResolverInfo *i;
1999 static const DBusObjectPathVTable vtable = {
2001 msg_async_service_resolver_impl,
2008 if (!dbus_message_get_args(
2010 DBUS_TYPE_INT32, &interface,
2011 DBUS_TYPE_INT32, &protocol,
2012 DBUS_TYPE_STRING, &name,
2013 DBUS_TYPE_STRING, &type,
2014 DBUS_TYPE_STRING, &domain,
2015 DBUS_TYPE_INT32, &aprotocol,
2016 DBUS_TYPE_INVALID) || !name || !type) {
2017 avahi_log_warn("Error parsing Server::ServiceResolverNew message");
2021 if (!(client = client_get(dbus_message_get_sender(m), TRUE))) {
2022 avahi_log_warn(__FILE__": Too many clients, client request failed.");
2023 return respond_error(c, m, AVAHI_ERR_TOO_MANY_CLIENTS, NULL);
2026 if (client->n_objects >= MAX_OBJECTS_PER_CLIENT) {
2027 avahi_log_warn(__FILE__": Too many objects for client '%s', client request failed.", client->name);
2028 return respond_error(c, m, AVAHI_ERR_TOO_MANY_OBJECTS, NULL);
2031 i = avahi_new(AsyncServiceResolverInfo, 1);
2032 i->id = ++client->current_id;
2034 i->path = avahi_strdup_printf("/Client%u/ServiceResolver%u", client->id, i->id);
2035 AVAHI_LLIST_PREPEND(AsyncServiceResolverInfo, async_service_resolvers, client->async_service_resolvers, i);
2036 client->n_objects++;
2038 if (!(i->service_resolver = avahi_s_service_resolver_new(avahi_server, (AvahiIfIndex) interface, (AvahiProtocol) protocol, name, type, domain, (AvahiProtocol) aprotocol, async_service_resolver_callback, i))) {
2039 async_service_resolver_free(i);
2040 return respond_error(c, m, avahi_server_errno(avahi_server), NULL);
2043 /* avahi_log_debug(__FILE__": [%s], new service resolver for <%s.%s.%s>", i->path, name, type, domain); */
2045 dbus_connection_register_object_path(c, i->path, &vtable, i);
2046 return respond_path(c, m, i->path);
2048 } else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_SERVER, "HostNameResolverNew")) {
2050 int32_t interface, protocol, aprotocol;
2052 AsyncHostNameResolverInfo *i;
2053 static const DBusObjectPathVTable vtable = {
2055 msg_async_host_name_resolver_impl,
2062 if (!dbus_message_get_args(
2064 DBUS_TYPE_INT32, &interface,
2065 DBUS_TYPE_INT32, &protocol,
2066 DBUS_TYPE_STRING, &name,
2067 DBUS_TYPE_INT32, &aprotocol,
2068 DBUS_TYPE_INVALID) || !name) {
2069 avahi_log_warn("Error parsing Server::HostNameResolverNew message");
2073 if (!(client = client_get(dbus_message_get_sender(m), TRUE))) {
2074 avahi_log_warn(__FILE__": Too many clients, client request failed.");
2075 return respond_error(c, m, AVAHI_ERR_TOO_MANY_CLIENTS, NULL);
2078 if (client->n_objects >= MAX_OBJECTS_PER_CLIENT) {
2079 avahi_log_warn(__FILE__": Too many objects for client '%s', client request failed.", client->name);
2080 return respond_error(c, m, AVAHI_ERR_TOO_MANY_OBJECTS, NULL);
2083 i = avahi_new(AsyncHostNameResolverInfo, 1);
2084 i->id = ++client->current_id;
2086 i->path = avahi_strdup_printf("/Client%u/HostNameResolver%u", client->id, i->id);
2087 AVAHI_LLIST_PREPEND(AsyncHostNameResolverInfo, async_host_name_resolvers, client->async_host_name_resolvers, i);
2088 client->n_objects++;
2090 if (!(i->host_name_resolver = avahi_s_host_name_resolver_new(avahi_server, (AvahiIfIndex) interface, (AvahiProtocol) protocol, name, aprotocol, async_host_name_resolver_callback, i))) {
2091 async_host_name_resolver_free(i);
2092 return respond_error(c, m, avahi_server_errno(avahi_server), NULL);
2095 dbus_connection_register_object_path(c, i->path, &vtable, i);
2096 return respond_path(c, m, i->path);
2098 } else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_SERVER, "AddressResolverNew")) {
2100 int32_t interface, protocol;
2102 AsyncAddressResolverInfo *i;
2104 static const DBusObjectPathVTable vtable = {
2106 msg_async_address_resolver_impl,
2113 if (!dbus_message_get_args(
2115 DBUS_TYPE_INT32, &interface,
2116 DBUS_TYPE_INT32, &protocol,
2117 DBUS_TYPE_STRING, &address,
2118 DBUS_TYPE_INVALID) || !address) {
2119 avahi_log_warn("Error parsing Server::AddressResolverNew message");
2123 if (!avahi_address_parse(address, AVAHI_PROTO_UNSPEC, &a))
2124 return respond_error(c, m, AVAHI_ERR_INVALID_ADDRESS, NULL);
2126 if (!(client = client_get(dbus_message_get_sender(m), TRUE))) {
2127 avahi_log_warn(__FILE__": Too many clients, client request failed.");
2128 return respond_error(c, m, AVAHI_ERR_TOO_MANY_CLIENTS, NULL);
2131 if (client->n_objects >= MAX_OBJECTS_PER_CLIENT) {
2132 avahi_log_warn(__FILE__": Too many objects for client '%s', client request failed.", client->name);
2133 return respond_error(c, m, AVAHI_ERR_TOO_MANY_OBJECTS, NULL);
2136 i = avahi_new(AsyncAddressResolverInfo, 1);
2137 i->id = ++client->current_id;
2139 i->path = avahi_strdup_printf("/Client%u/AddressResolver%u", client->id, i->id);
2140 AVAHI_LLIST_PREPEND(AsyncAddressResolverInfo, async_address_resolvers, client->async_address_resolvers, i);
2141 client->n_objects++;
2143 if (!(i->address_resolver = avahi_s_address_resolver_new(avahi_server, (AvahiIfIndex) interface, (AvahiProtocol) protocol, &a, async_address_resolver_callback, i))) {
2144 async_address_resolver_free(i);
2145 return respond_error(c, m, avahi_server_errno(avahi_server), NULL);
2148 dbus_connection_register_object_path(c, i->path, &vtable, i);
2149 return respond_path(c, m, i->path);
2152 avahi_log_warn("Missed message %s::%s()", dbus_message_get_interface(m), dbus_message_get_member(m));
2155 if (dbus_error_is_set(&error))
2156 dbus_error_free(&error);
2158 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
2161 void dbus_protocol_server_state_changed(AvahiServerState state) {
2168 m = dbus_message_new_signal(AVAHI_DBUS_PATH_SERVER, AVAHI_DBUS_INTERFACE_SERVER, "StateChanged");
2169 t = (int32_t) state;
2170 dbus_message_append_args(m, DBUS_TYPE_INT32, &t, DBUS_TYPE_INVALID);
2171 dbus_connection_send(server->bus, m, NULL);
2172 dbus_message_unref(m);
2175 int dbus_protocol_setup(const AvahiPoll *poll_api) {
2178 static const DBusObjectPathVTable server_vtable = {
2187 dbus_error_init(&error);
2189 server = avahi_new(Server, 1);
2190 AVAHI_LLIST_HEAD_INIT(Clients, server->clients);
2191 server->current_id = 0;
2192 server->n_clients = 0;
2194 if (!(server->bus = dbus_bus_get(DBUS_BUS_SYSTEM, &error))) {
2195 assert(dbus_error_is_set(&error));
2196 avahi_log_error("dbus_bus_get(): %s", error.message);
2200 if (avahi_dbus_connection_glue(server->bus, poll_api) < 0) {
2201 avahi_log_error("avahi_dbus_connection_glue() failed");
2205 if (dbus_bus_request_name(server->bus, AVAHI_DBUS_NAME, DBUS_NAME_FLAG_PROHIBIT_REPLACEMENT, &error) != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
2206 if (dbus_error_is_set(&error)) {
2207 avahi_log_error("dbus_bus_request_name(): %s", error.message);
2211 avahi_log_error("Failed to acquire DBUS name '"AVAHI_DBUS_NAME"'");
2215 if (!(dbus_connection_add_filter(server->bus, msg_signal_filter_impl, (void*) poll_api, NULL))) {
2216 avahi_log_error("dbus_connection_add_filter() failed");
2220 dbus_bus_add_match(server->bus, "type='signal',""interface='" DBUS_INTERFACE_DBUS "'", &error);
2222 if (dbus_error_is_set(&error)) {
2223 avahi_log_error("dbus_bus_add_match(): %s", error.message);
2227 if (!(dbus_connection_register_object_path(server->bus, AVAHI_DBUS_PATH_SERVER, &server_vtable, NULL))) {
2228 avahi_log_error("dbus_connection_register_object_path() failed");
2236 dbus_connection_disconnect(server->bus);
2237 dbus_connection_unref(server->bus);
2240 if (dbus_error_is_set(&error))
2241 dbus_error_free(&error);
2248 void dbus_protocol_shutdown(void) {
2252 while (server->clients)
2253 client_free(server->clients);
2255 assert(server->n_clients == 0);
2258 dbus_connection_disconnect(server->bus);
2259 dbus_connection_unref(server->bus);