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
29 #define DBUS_API_SUBJECT_TO_CHANGE
30 #include <dbus/dbus.h>
31 #include <dbus/dbus-glib-lowlevel.h>
33 #include <avahi-core/llist.h>
34 #include <avahi-core/log.h>
35 #include <avahi-core/core.h>
36 #include <avahi-common/dbus.h>
38 #include "dbus-protocol.h"
41 typedef struct Server Server;
42 typedef struct Client Client;
43 typedef struct EntryGroupInfo EntryGroupInfo;
44 typedef struct HostNameResolverInfo HostNameResolverInfo;
45 typedef struct AddressResolverInfo AddressResolverInfo;
46 typedef struct DomainBrowserInfo DomainBrowserInfo;
47 typedef struct ServiceTypeBrowserInfo ServiceTypeBrowserInfo;
48 typedef struct ServiceBrowserInfo ServiceBrowserInfo;
49 typedef struct ServiceResolverInfo ServiceResolverInfo;
51 #define MAX_CLIENTS 20
52 #define MAX_OBJECTS_PER_CLIENT 50
53 #define MAX_ENTRIES_PER_ENTRY_GROUP 20
55 struct EntryGroupInfo {
58 AvahiEntryGroup *entry_group;
63 AVAHI_LLIST_FIELDS(EntryGroupInfo, entry_groups);
66 struct HostNameResolverInfo {
68 AvahiHostNameResolver *host_name_resolver;
71 AVAHI_LLIST_FIELDS(HostNameResolverInfo, host_name_resolvers);
74 struct AddressResolverInfo {
76 AvahiAddressResolver *address_resolver;
79 AVAHI_LLIST_FIELDS(AddressResolverInfo, address_resolvers);
82 struct DomainBrowserInfo {
85 AvahiDomainBrowser *domain_browser;
88 AVAHI_LLIST_FIELDS(DomainBrowserInfo, domain_browsers);
91 struct ServiceTypeBrowserInfo {
94 AvahiServiceTypeBrowser *service_type_browser;
97 AVAHI_LLIST_FIELDS(ServiceTypeBrowserInfo, service_type_browsers);
100 struct ServiceBrowserInfo {
103 AvahiServiceBrowser *service_browser;
106 AVAHI_LLIST_FIELDS(ServiceBrowserInfo, service_browsers);
109 struct ServiceResolverInfo {
111 AvahiServiceResolver *service_resolver;
112 DBusMessage *message;
114 AVAHI_LLIST_FIELDS(ServiceResolverInfo, service_resolvers);
123 AVAHI_LLIST_FIELDS(Client, clients);
124 AVAHI_LLIST_HEAD(EntryGroupInfo, entry_groups);
125 AVAHI_LLIST_HEAD(HostNameResolverInfo, host_name_resolvers);
126 AVAHI_LLIST_HEAD(AddressResolverInfo, address_resolvers);
127 AVAHI_LLIST_HEAD(DomainBrowserInfo, domain_browsers);
128 AVAHI_LLIST_HEAD(ServiceTypeBrowserInfo, service_type_browsers);
129 AVAHI_LLIST_HEAD(ServiceBrowserInfo, service_browsers);
130 AVAHI_LLIST_HEAD(ServiceResolverInfo, service_resolvers);
135 AVAHI_LLIST_HEAD(Client, clients);
140 static Server *server = NULL;
142 static void entry_group_free(EntryGroupInfo *i) {
146 avahi_entry_group_free(i->entry_group);
147 dbus_connection_unregister_object_path(server->bus, i->path);
149 AVAHI_LLIST_REMOVE(EntryGroupInfo, entry_groups, i->client->entry_groups, i);
151 i->client->n_objects--;
152 g_assert(i->client->n_objects >= 0);
157 static void host_name_resolver_free(HostNameResolverInfo *i) {
160 if (i->host_name_resolver)
161 avahi_host_name_resolver_free(i->host_name_resolver);
162 dbus_message_unref(i->message);
163 AVAHI_LLIST_REMOVE(HostNameResolverInfo, host_name_resolvers, i->client->host_name_resolvers, i);
165 i->client->n_objects--;
166 g_assert(i->client->n_objects >= 0);
171 static void address_resolver_free(AddressResolverInfo *i) {
174 if (i->address_resolver)
175 avahi_address_resolver_free(i->address_resolver);
176 dbus_message_unref(i->message);
177 AVAHI_LLIST_REMOVE(AddressResolverInfo, address_resolvers, i->client->address_resolvers, i);
179 i->client->n_objects--;
180 g_assert(i->client->n_objects >= 0);
185 static void domain_browser_free(DomainBrowserInfo *i) {
188 if (i->domain_browser)
189 avahi_domain_browser_free(i->domain_browser);
190 dbus_connection_unregister_object_path(server->bus, i->path);
192 AVAHI_LLIST_REMOVE(DomainBrowserInfo, domain_browsers, i->client->domain_browsers, i);
194 i->client->n_objects--;
195 g_assert(i->client->n_objects >= 0);
200 static void service_type_browser_free(ServiceTypeBrowserInfo *i) {
203 if (i->service_type_browser)
204 avahi_service_type_browser_free(i->service_type_browser);
205 dbus_connection_unregister_object_path(server->bus, i->path);
207 AVAHI_LLIST_REMOVE(ServiceTypeBrowserInfo, service_type_browsers, i->client->service_type_browsers, i);
209 i->client->n_objects--;
210 g_assert(i->client->n_objects >= 0);
215 static void service_browser_free(ServiceBrowserInfo *i) {
218 if (i->service_browser)
219 avahi_service_browser_free(i->service_browser);
220 dbus_connection_unregister_object_path(server->bus, i->path);
222 AVAHI_LLIST_REMOVE(ServiceBrowserInfo, service_browsers, i->client->service_browsers, i);
224 i->client->n_objects--;
225 g_assert(i->client->n_objects >= 0);
230 static void service_resolver_free(ServiceResolverInfo *i) {
233 if (i->service_resolver)
234 avahi_service_resolver_free(i->service_resolver);
235 dbus_message_unref(i->message);
236 AVAHI_LLIST_REMOVE(ServiceResolverInfo, service_resolvers, i->client->service_resolvers, i);
238 i->client->n_objects--;
239 g_assert(i->client->n_objects >= 0);
244 static void client_free(Client *c) {
249 while (c->entry_groups)
250 entry_group_free(c->entry_groups);
252 while (c->host_name_resolvers)
253 host_name_resolver_free(c->host_name_resolvers);
255 while (c->address_resolvers)
256 address_resolver_free(c->address_resolvers);
258 while (c->domain_browsers)
259 domain_browser_free(c->domain_browsers);
261 while (c->service_type_browsers)
262 service_type_browser_free(c->service_type_browsers);
264 while (c->service_browsers)
265 service_browser_free(c->service_browsers);
267 while (c->service_resolvers)
268 service_resolver_free(c->service_resolvers);
270 g_assert(c->n_objects == 0);
273 AVAHI_LLIST_REMOVE(Client, clients, server->clients, c);
276 server->n_clients --;
277 g_assert(server->n_clients >= 0);
280 static Client *client_get(const gchar *name, gboolean create) {
286 for (client = server->clients; client; client = client->clients_next)
287 if (!strcmp(name, client->name))
293 if (server->n_clients >= MAX_CLIENTS)
296 /* If not existant yet, create a new entry */
297 client = g_new(Client, 1);
298 client->id = server->current_id++;
299 client->name = g_strdup(name);
300 client->current_id = 0;
301 client->n_objects = 0;
302 AVAHI_LLIST_HEAD_INIT(EntryGroupInfo, client->entry_groups);
303 AVAHI_LLIST_HEAD_INIT(HostNameResolverInfo, client->host_name_resolvers);
304 AVAHI_LLIST_HEAD_INIT(AddressResolverInfo, client->address_resolvers);
305 AVAHI_LLIST_HEAD_INIT(DomainBrowserInfo, client->domain_browsers);
306 AVAHI_LLIST_HEAD_INIT(ServiceTypeBrowserInfo, client->service_type_browsers);
307 AVAHI_LLIST_HEAD_INIT(ServiceBrowserInfo, client->service_browsers);
308 AVAHI_LLIST_HEAD_INIT(ServiceResolverInfo, client->service_resolvers);
310 AVAHI_LLIST_PREPEND(Client, clients, server->clients, client);
313 g_assert(server->n_clients > 0);
318 static DBusHandlerResult respond_error(DBusConnection *c, DBusMessage *m, const gchar *error, const gchar *text) {
321 reply = dbus_message_new_error(m, error, text);
322 dbus_connection_send(c, reply, NULL);
323 dbus_message_unref(reply);
325 return DBUS_HANDLER_RESULT_HANDLED;
328 static DBusHandlerResult respond_string(DBusConnection *c, DBusMessage *m, const gchar *text) {
331 reply = dbus_message_new_method_return(m);
332 dbus_message_append_args(reply, DBUS_TYPE_STRING, &text, DBUS_TYPE_INVALID);
333 dbus_connection_send(c, reply, NULL);
334 dbus_message_unref(reply);
336 return DBUS_HANDLER_RESULT_HANDLED;
339 static DBusHandlerResult respond_ok(DBusConnection *c, DBusMessage *m) {
342 reply = dbus_message_new_method_return(m);
343 dbus_connection_send(c, reply, NULL);
344 dbus_message_unref(reply);
346 return DBUS_HANDLER_RESULT_HANDLED;
349 static DBusHandlerResult respond_path(DBusConnection *c, DBusMessage *m, const gchar *path) {
352 reply = dbus_message_new_method_return(m);
353 dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID);
354 dbus_connection_send(c, reply, NULL);
355 dbus_message_unref(reply);
357 return DBUS_HANDLER_RESULT_HANDLED;
360 static DBusHandlerResult handle_introspect(DBusConnection *c, DBusMessage *m, const gchar *fname) {
363 GError *gerror = NULL;
370 dbus_error_init(&error);
372 if (!dbus_message_get_args(m, &error, DBUS_TYPE_INVALID)) {
373 avahi_log_warn("Error parsing Introspect message: %s", error.message);
377 path = g_strdup_printf("%s/%s", AVAHI_DBUS_INTROSPECTION_DIR, fname);
379 if (!(g_file_get_contents(path, &contents, NULL, &gerror))) {
380 avahi_log_warn("Failed to load introspection data: %s", gerror->message);
381 g_error_free(gerror);
388 respond_string(c, m, contents);
391 return DBUS_HANDLER_RESULT_HANDLED;
394 if (dbus_error_is_set(&error))
395 dbus_error_free(&error);
397 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
401 static DBusHandlerResult msg_signal_filter_impl(DBusConnection *c, DBusMessage *m, void *userdata) {
402 GMainLoop *loop = userdata;
405 dbus_error_init(&error);
407 /* avahi_log_debug("dbus: interface=%s, path=%s, member=%s", */
408 /* dbus_message_get_interface(m), */
409 /* dbus_message_get_path(m), */
410 /* dbus_message_get_member(m)); */
412 if (dbus_message_is_signal(m, DBUS_INTERFACE_LOCAL, "Disconnected")) {
413 /* No, we shouldn't quit, but until we get somewhere
414 * usefull such that we can restore our state, we will */
415 avahi_log_warn("Disconnnected from d-bus, terminating...");
416 g_main_loop_quit (loop);
417 return DBUS_HANDLER_RESULT_HANDLED;
419 } else if (dbus_message_is_signal(m, DBUS_INTERFACE_DBUS, "NameAcquired")) {
422 if (!dbus_message_get_args(m, &error, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID)) {
423 avahi_log_warn("Error parsing NameAcquired message");
427 /* avahi_log_info("dbus: name acquired (%s)", name); */
428 return DBUS_HANDLER_RESULT_HANDLED;
430 } else if (dbus_message_is_signal(m, DBUS_INTERFACE_DBUS, "NameOwnerChanged")) {
431 gchar *name, *old, *new;
433 if (!dbus_message_get_args(m, &error, DBUS_TYPE_STRING, &name, DBUS_TYPE_STRING, &old, DBUS_TYPE_STRING, &new, DBUS_TYPE_INVALID)) {
434 avahi_log_warn("Error parsing NameOwnerChanged message");
441 if ((client = client_get(name, FALSE))) {
442 /* avahi_log_info("dbus: client %s vanished", name); */
449 if (dbus_error_is_set(&error))
450 dbus_error_free(&error);
452 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
456 static void entry_group_callback(AvahiServer *s, AvahiEntryGroup *g, AvahiEntryGroupState state, gpointer userdata) {
457 EntryGroupInfo *i = userdata;
465 m = dbus_message_new_signal(i->path, AVAHI_DBUS_INTERFACE_ENTRY_GROUP, "StateChanged");
467 dbus_message_append_args(m, DBUS_TYPE_INT32, &t, DBUS_TYPE_INVALID);
468 dbus_message_set_destination(m, i->client->name);
469 dbus_connection_send(server->bus, m, NULL);
470 dbus_message_unref(m);
473 static DBusHandlerResult msg_entry_group_impl(DBusConnection *c, DBusMessage *m, void *userdata) {
475 EntryGroupInfo *i = userdata;
481 dbus_error_init(&error);
483 avahi_log_debug("dbus: interface=%s, path=%s, member=%s",
484 dbus_message_get_interface(m),
485 dbus_message_get_path(m),
486 dbus_message_get_member(m));
489 if (dbus_message_is_method_call(m, DBUS_INTERFACE_INTROSPECTABLE, "Introspect"))
490 return handle_introspect(c, m, "EntryGroup.introspect");
493 if (strcmp(dbus_message_get_sender(m), i->client->name))
494 return respond_error(c, m, DBUS_ERROR_ACCESS_DENIED, NULL);
496 if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_ENTRY_GROUP, "Free")) {
498 if (!dbus_message_get_args(m, &error, DBUS_TYPE_INVALID)) {
499 avahi_log_warn("Error parsing EntryGroup::Free message");
504 return respond_ok(c, m);
506 } else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_ENTRY_GROUP, "Commit")) {
508 if (!dbus_message_get_args(m, &error, DBUS_TYPE_INVALID)) {
509 avahi_log_warn("Error parsing EntryGroup::Commit message");
513 avahi_entry_group_commit(i->entry_group);
514 return respond_ok(c, m);
516 } else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_ENTRY_GROUP, "GetState")) {
520 if (!dbus_message_get_args(m, &error, DBUS_TYPE_INVALID)) {
521 avahi_log_warn("Error parsing EntryGroup::GetState message");
525 t = (gint32) avahi_entry_group_get_state(i->entry_group);
526 reply = dbus_message_new_method_return(m);
527 dbus_message_append_args(reply, DBUS_TYPE_INT32, &t, DBUS_TYPE_INVALID);
528 dbus_connection_send(c, reply, NULL);
529 dbus_message_unref(reply);
531 return DBUS_HANDLER_RESULT_HANDLED;
533 } else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_ENTRY_GROUP, "AddService")) {
534 gint32 interface, protocol;
535 gchar *type, *name, *domain, *host;
539 AvahiStringList *strlst;
541 if (!dbus_message_get_args(
543 DBUS_TYPE_INT32, &interface,
544 DBUS_TYPE_INT32, &protocol,
545 DBUS_TYPE_STRING, &name,
546 DBUS_TYPE_STRING, &type,
547 DBUS_TYPE_STRING, &domain,
548 DBUS_TYPE_STRING, &host,
549 DBUS_TYPE_UINT16, &port,
550 DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &txt, &txt_len,
551 DBUS_TYPE_INVALID) || !type || !*type || !name || !*name || !port) {
552 avahi_log_warn("Error parsing EntryGroup::AddService message");
556 if (i->n_entries >= MAX_ENTRIES_PER_ENTRY_GROUP) {
557 avahi_log_warn("Too many entries per entry group, client request failed.");
558 dbus_free_string_array(txt);
559 return respond_error(c, m, AVAHI_DBUS_ERROR_TOO_MANY_ENTRIES, NULL);
562 strlst = avahi_string_list_new_from_array((const gchar**) txt, txt_len);
563 dbus_free_string_array(txt);
565 if (domain && !*domain)
571 if (avahi_server_add_service_strlst(avahi_server, i->entry_group, (AvahiIfIndex) interface, (AvahiProtocol) protocol, name, type, domain, host, port, strlst) < 0) {
572 avahi_log_warn("Failed to add service: %s", name);
573 avahi_string_list_free(strlst);
574 return respond_error(c, m, AVAHI_DBUS_ERROR_INVALID_SERVICE, NULL);
578 avahi_string_list_free(strlst);
580 return respond_ok(c, m);
582 } else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_ENTRY_GROUP, "AddAddress")) {
583 gint32 interface, protocol;
584 gchar *name, *address;
587 if (!dbus_message_get_args(
589 DBUS_TYPE_INT32, &interface,
590 DBUS_TYPE_INT32, &protocol,
591 DBUS_TYPE_STRING, &name,
592 DBUS_TYPE_STRING, &address,
593 DBUS_TYPE_INVALID) || !name || !*name || !address || !*address) {
594 avahi_log_warn("Error parsing EntryGroup::AddAddress message");
598 if (i->n_entries >= MAX_ENTRIES_PER_ENTRY_GROUP) {
599 avahi_log_warn("Too many entries per entry group, client request failed.");
600 return respond_error(c, m, AVAHI_DBUS_ERROR_TOO_MANY_ENTRIES, NULL);
603 if (!(avahi_address_parse(address, AVAHI_PROTO_UNSPEC, &a))) {
604 avahi_log_warn("Error parsing address data");
605 return respond_error(c, m, AVAHI_DBUS_ERROR_INVALID_ADDRESS, NULL);
608 if (avahi_server_add_address(avahi_server, i->entry_group, (AvahiIfIndex) interface, (AvahiProtocol) protocol, 0, name, &a) < 0) {
609 avahi_log_warn("Failed to add service: %s", name);
610 return respond_error(c, m, AVAHI_DBUS_ERROR_INVALID_ADDRESS, NULL);
614 return respond_ok(c, m);
617 avahi_log_warn("Missed message %s::%s()", dbus_message_get_interface(m), dbus_message_get_member(m));
620 if (dbus_error_is_set(&error))
621 dbus_error_free(&error);
623 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
626 static void host_name_resolver_callback(AvahiHostNameResolver *r, AvahiIfIndex interface, AvahiProtocol protocol, AvahiResolverEvent event, const gchar *host_name, const AvahiAddress *a, gpointer userdata) {
627 HostNameResolverInfo *i = userdata;
634 if (event == AVAHI_RESOLVER_FOUND) {
635 char t[256], *pt = t;
636 gint32 i_interface, i_protocol, i_aprotocol;
639 avahi_address_snprint(t, sizeof(t), a);
641 i_interface = (gint32) interface;
642 i_protocol = (gint32) protocol;
643 i_aprotocol = (gint32) a->family;
645 reply = dbus_message_new_method_return(i->message);
646 dbus_message_append_args(
648 DBUS_TYPE_INT32, &i_interface,
649 DBUS_TYPE_INT32, &i_protocol,
650 DBUS_TYPE_STRING, &host_name,
651 DBUS_TYPE_INT32, &i_aprotocol,
652 DBUS_TYPE_STRING, &pt,
656 g_assert(event == AVAHI_RESOLVER_TIMEOUT);
657 reply = dbus_message_new_error(i->message, AVAHI_DBUS_ERROR_TIMEOUT, NULL);
660 dbus_connection_send(server->bus, reply, NULL);
661 dbus_message_unref(reply);
663 host_name_resolver_free(i);
666 static void address_resolver_callback(AvahiAddressResolver *r, AvahiIfIndex interface, AvahiProtocol protocol, AvahiResolverEvent event, const AvahiAddress *address, const gchar *host_name, gpointer userdata) {
667 AddressResolverInfo *i = userdata;
674 if (event == AVAHI_RESOLVER_FOUND) {
675 char t[256], *pt = t;
676 gint32 i_interface, i_protocol, i_aprotocol;
679 avahi_address_snprint(t, sizeof(t), address);
681 i_interface = (gint32) interface;
682 i_protocol = (gint32) protocol;
683 i_aprotocol = (gint32) address->family;
685 reply = dbus_message_new_method_return(i->message);
686 dbus_message_append_args(
688 DBUS_TYPE_INT32, &i_interface,
689 DBUS_TYPE_INT32, &i_protocol,
690 DBUS_TYPE_INT32, &i_aprotocol,
691 DBUS_TYPE_STRING, &pt,
692 DBUS_TYPE_STRING, &host_name,
696 g_assert(event == AVAHI_RESOLVER_TIMEOUT);
697 reply = dbus_message_new_error(i->message, AVAHI_DBUS_ERROR_TIMEOUT, NULL);
700 dbus_connection_send(server->bus, reply, NULL);
701 dbus_message_unref(reply);
703 address_resolver_free(i);
706 static DBusHandlerResult msg_domain_browser_impl(DBusConnection *c, DBusMessage *m, void *userdata) {
708 DomainBrowserInfo *i = userdata;
714 dbus_error_init(&error);
716 avahi_log_debug("dbus: interface=%s, path=%s, member=%s",
717 dbus_message_get_interface(m),
718 dbus_message_get_path(m),
719 dbus_message_get_member(m));
722 if (dbus_message_is_method_call(m, DBUS_INTERFACE_INTROSPECTABLE, "Introspect"))
723 return handle_introspect(c, m, "DomainBrowser.introspect");
726 if (strcmp(dbus_message_get_sender(m), i->client->name))
727 return respond_error(c, m, DBUS_ERROR_ACCESS_DENIED, NULL);
729 if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_DOMAIN_BROWSER, "Free")) {
731 if (!dbus_message_get_args(m, &error, DBUS_TYPE_INVALID)) {
732 avahi_log_warn("Error parsing DomainBrowser::Free message");
736 domain_browser_free(i);
737 return respond_ok(c, m);
741 avahi_log_warn("Missed message %s::%s()", dbus_message_get_interface(m), dbus_message_get_member(m));
744 if (dbus_error_is_set(&error))
745 dbus_error_free(&error);
747 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
750 static void domain_browser_callback(AvahiDomainBrowser *b, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, const gchar *domain, gpointer userdata) {
751 DomainBrowserInfo *i = userdata;
753 gint32 i_interface, i_protocol;
759 i_interface = (gint32) interface;
760 i_protocol = (gint32) protocol;
762 m = dbus_message_new_signal(i->path, AVAHI_DBUS_INTERFACE_DOMAIN_BROWSER, event == AVAHI_BROWSER_NEW ? "ItemNew" : "ItemRemove");
763 dbus_message_append_args(
765 DBUS_TYPE_INT32, &i_interface,
766 DBUS_TYPE_INT32, &i_protocol,
767 DBUS_TYPE_STRING, &domain,
769 dbus_message_set_destination(m, i->client->name);
770 dbus_connection_send(server->bus, m, NULL);
771 dbus_message_unref(m);
774 static DBusHandlerResult msg_service_type_browser_impl(DBusConnection *c, DBusMessage *m, void *userdata) {
776 ServiceTypeBrowserInfo *i = userdata;
782 dbus_error_init(&error);
784 avahi_log_debug("dbus: interface=%s, path=%s, member=%s",
785 dbus_message_get_interface(m),
786 dbus_message_get_path(m),
787 dbus_message_get_member(m));
790 if (dbus_message_is_method_call(m, DBUS_INTERFACE_INTROSPECTABLE, "Introspect"))
791 return handle_introspect(c, m, "ServiceTypeBrowser.introspect");
794 if (strcmp(dbus_message_get_sender(m), i->client->name))
795 return respond_error(c, m, DBUS_ERROR_ACCESS_DENIED, NULL);
797 if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_SERVICE_TYPE_BROWSER, "Free")) {
799 if (!dbus_message_get_args(m, &error, DBUS_TYPE_INVALID)) {
800 avahi_log_warn("Error parsing ServiceTypeBrowser::Free message");
804 service_type_browser_free(i);
805 return respond_ok(c, m);
809 avahi_log_warn("Missed message %s::%s()", dbus_message_get_interface(m), dbus_message_get_member(m));
812 if (dbus_error_is_set(&error))
813 dbus_error_free(&error);
815 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
818 static void service_type_browser_callback(AvahiServiceTypeBrowser *b, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, const gchar *type, const gchar *domain, gpointer userdata) {
819 ServiceTypeBrowserInfo *i = userdata;
821 gint32 i_interface, i_protocol;
828 i_interface = (gint32) interface;
829 i_protocol = (gint32) protocol;
831 m = dbus_message_new_signal(i->path, AVAHI_DBUS_INTERFACE_SERVICE_TYPE_BROWSER, event == AVAHI_BROWSER_NEW ? "ItemNew" : "ItemRemove");
832 dbus_message_append_args(
834 DBUS_TYPE_INT32, &i_interface,
835 DBUS_TYPE_INT32, &i_protocol,
836 DBUS_TYPE_STRING, &type,
837 DBUS_TYPE_STRING, &domain,
839 dbus_message_set_destination(m, i->client->name);
840 dbus_connection_send(server->bus, m, NULL);
841 dbus_message_unref(m);
844 static DBusHandlerResult msg_service_browser_impl(DBusConnection *c, DBusMessage *m, void *userdata) {
846 ServiceBrowserInfo *i = userdata;
852 dbus_error_init(&error);
854 avahi_log_debug("dbus: interface=%s, path=%s, member=%s",
855 dbus_message_get_interface(m),
856 dbus_message_get_path(m),
857 dbus_message_get_member(m));
860 if (dbus_message_is_method_call(m, DBUS_INTERFACE_INTROSPECTABLE, "Introspect"))
861 return handle_introspect(c, m, "ServiceBrowser.introspect");
864 if (strcmp(dbus_message_get_sender(m), i->client->name))
865 return respond_error(c, m, DBUS_ERROR_ACCESS_DENIED, NULL);
867 if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_SERVICE_BROWSER, "Free")) {
869 if (!dbus_message_get_args(m, &error, DBUS_TYPE_INVALID)) {
870 avahi_log_warn("Error parsing ServiceBrowser::Free message");
874 service_browser_free(i);
875 return respond_ok(c, m);
879 avahi_log_warn("Missed message %s::%s()", dbus_message_get_interface(m), dbus_message_get_member(m));
882 if (dbus_error_is_set(&error))
883 dbus_error_free(&error);
885 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
888 static void service_browser_callback(AvahiServiceBrowser *b, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, const gchar *name, const gchar *type, const gchar *domain, gpointer userdata) {
889 ServiceBrowserInfo *i = userdata;
891 gint32 i_interface, i_protocol;
899 i_interface = (gint32) interface;
900 i_protocol = (gint32) protocol;
902 m = dbus_message_new_signal(i->path, AVAHI_DBUS_INTERFACE_SERVICE_BROWSER, event == AVAHI_BROWSER_NEW ? "ItemNew" : "ItemRemove");
903 dbus_message_append_args(
905 DBUS_TYPE_INT32, &i_interface,
906 DBUS_TYPE_INT32, &i_protocol,
907 DBUS_TYPE_STRING, &name,
908 DBUS_TYPE_STRING, &type,
909 DBUS_TYPE_STRING, &domain,
911 dbus_message_set_destination(m, i->client->name);
912 dbus_connection_send(server->bus, m, NULL);
913 dbus_message_unref(m);
916 static void service_resolver_callback(
917 AvahiServiceResolver *r,
918 AvahiIfIndex interface,
919 AvahiProtocol protocol,
920 AvahiResolverEvent event,
924 const gchar *host_name,
925 const AvahiAddress *a,
927 AvahiStringList *txt,
930 ServiceResolverInfo *i = userdata;
936 if (event == AVAHI_RESOLVER_FOUND) {
937 char t[256], *pt = t;
938 gint32 i_interface, i_protocol, i_aprotocol;
946 avahi_address_snprint(t, sizeof(t), a);
948 i_interface = (gint32) interface;
949 i_protocol = (gint32) protocol;
950 i_aprotocol = (gint32) a->family;
952 array = g_new(gchar*, (n = avahi_string_list_length(txt)));
954 /** FIXME: DBUS doesn't support strings that include NUL bytes (?) */
955 for (p = txt, j = n-1; p; p = p->next, j--)
956 array[j] = g_strndup((gchar*) p->text, p->size);
958 reply = dbus_message_new_method_return(i->message);
959 dbus_message_append_args(
961 DBUS_TYPE_INT32, &i_interface,
962 DBUS_TYPE_INT32, &i_protocol,
963 DBUS_TYPE_STRING, &name,
964 DBUS_TYPE_STRING, &type,
965 DBUS_TYPE_STRING, &domain,
966 DBUS_TYPE_STRING, &host_name,
967 DBUS_TYPE_INT32, &i_aprotocol,
968 DBUS_TYPE_STRING, &pt,
969 DBUS_TYPE_UINT16, &port,
970 DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &array, n,
973 for (j = 0; j < n; j++)
977 g_assert(event == AVAHI_RESOLVER_TIMEOUT);
978 reply = dbus_message_new_error(i->message, AVAHI_DBUS_ERROR_TIMEOUT, NULL);
981 dbus_connection_send(server->bus, reply, NULL);
982 dbus_message_unref(reply);
984 service_resolver_free(i);
988 static DBusHandlerResult msg_server_impl(DBusConnection *c, DBusMessage *m, void *userdata) {
991 dbus_error_init(&error);
993 avahi_log_debug("dbus: interface=%s, path=%s, member=%s",
994 dbus_message_get_interface(m),
995 dbus_message_get_path(m),
996 dbus_message_get_member(m));
998 if (dbus_message_is_method_call(m, DBUS_INTERFACE_INTROSPECTABLE, "Introspect"))
999 return handle_introspect(c, m, "Server.introspect");
1001 else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_SERVER, "GetHostName")) {
1003 if (!dbus_message_get_args(m, &error, DBUS_TYPE_INVALID)) {
1004 avahi_log_warn("Error parsing Server::GetHostName message");
1008 return respond_string(c, m, avahi_server_get_host_name(avahi_server));
1010 } else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_SERVER, "GetDomainName")) {
1012 if (!dbus_message_get_args(m, &error, DBUS_TYPE_INVALID)) {
1013 avahi_log_warn("Error parsing Server::GetDomainName message");
1017 return respond_string(c, m, avahi_server_get_domain_name(avahi_server));
1019 } else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_SERVER, "GetHostNameFqdn")) {
1021 if (!(dbus_message_get_args(m, &error, DBUS_TYPE_INVALID))) {
1022 avahi_log_warn("Error parsing Server::GetHostNameFqdn message");
1026 return respond_string(c, m, avahi_server_get_host_name_fqdn(avahi_server));
1028 } else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_SERVER, "GetVersionString")) {
1030 if (!(dbus_message_get_args(m, &error, DBUS_TYPE_INVALID))) {
1031 avahi_log_warn("Error parsing Server::GetVersionString message");
1035 return respond_string(c, m, PACKAGE_STRING);
1037 } else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_SERVER, "GetState")) {
1041 if (!(dbus_message_get_args(m, &error, DBUS_TYPE_INVALID))) {
1042 avahi_log_warn("Error parsing Server::GetState message");
1046 s = (gint32) avahi_server_get_state(avahi_server);
1048 reply = dbus_message_new_method_return(m);
1049 dbus_message_append_args(reply, DBUS_TYPE_INT32, &s, DBUS_TYPE_INVALID);
1050 dbus_connection_send(c, reply, NULL);
1051 dbus_message_unref(reply);
1053 return DBUS_HANDLER_RESULT_HANDLED;
1055 } else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_SERVER, "GetAlternativeHostName")) {
1058 if (!(dbus_message_get_args(m, &error, DBUS_TYPE_STRING, &n, DBUS_TYPE_INVALID)) || !n || !*n) {
1059 avahi_log_warn("Error parsing Server::GetAlternativeHostName message");
1063 t = avahi_alternative_host_name(n);
1064 respond_string(c, m, t);
1067 return DBUS_HANDLER_RESULT_HANDLED;
1069 } else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_SERVER, "GetAlternativeServiceName")) {
1072 if (!(dbus_message_get_args(m, &error, DBUS_TYPE_STRING, &n, DBUS_TYPE_INVALID)) || !n || !*n) {
1073 avahi_log_warn("Error parsing Server::GetAlternativeServiceName message");
1077 t = avahi_alternative_service_name(n);
1078 respond_string(c, m, t);
1081 return DBUS_HANDLER_RESULT_HANDLED;
1083 } else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_SERVER, "EntryGroupNew")) {
1086 static const DBusObjectPathVTable vtable = {
1088 msg_entry_group_impl,
1095 if (!dbus_message_get_args(m, &error, DBUS_TYPE_INVALID)) {
1096 avahi_log_warn("Error parsing Server::EntryGroupNew message");
1100 if (!(client = client_get(dbus_message_get_sender(m), TRUE))) {
1101 avahi_log_warn("Too many clients, client request failed.");
1102 return respond_error(c, m, AVAHI_DBUS_ERROR_TOO_MANY_CLIENTS, NULL);
1105 if (client->n_objects >= MAX_OBJECTS_PER_CLIENT) {
1106 avahi_log_warn("Too many objects for client '%s', client request failed.", client->name);
1107 return respond_error(c, m, AVAHI_DBUS_ERROR_TOO_MANY_OBJECTS, NULL);
1110 i = g_new(EntryGroupInfo, 1);
1111 i->id = ++client->current_id;
1113 i->path = g_strdup_printf("/Client%u/EntryGroup%u", client->id, i->id);
1115 AVAHI_LLIST_PREPEND(EntryGroupInfo, entry_groups, client->entry_groups, i);
1116 client->n_objects++;
1118 if (!(i->entry_group = avahi_entry_group_new(avahi_server, entry_group_callback, i))) {
1119 avahi_log_warn("Failed to create entry group");
1120 entry_group_free(i);
1124 dbus_connection_register_object_path(c, i->path, &vtable, i);
1125 return respond_path(c, m, i->path);
1127 } else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_SERVER, "ResolveHostName")) {
1129 gint32 interface, protocol, aprotocol;
1131 HostNameResolverInfo *i;
1133 if (!dbus_message_get_args(
1135 DBUS_TYPE_INT32, &interface,
1136 DBUS_TYPE_INT32, &protocol,
1137 DBUS_TYPE_STRING, &name,
1138 DBUS_TYPE_INT32, &aprotocol,
1139 DBUS_TYPE_INVALID) || !name || !*name) {
1140 avahi_log_warn("Error parsing Server::ResolveHostName message");
1144 if (!(client = client_get(dbus_message_get_sender(m), TRUE))) {
1145 avahi_log_warn("Too many clients, client request failed.");
1146 return respond_error(c, m, AVAHI_DBUS_ERROR_TOO_MANY_CLIENTS, NULL);
1149 if (client->n_objects >= MAX_OBJECTS_PER_CLIENT) {
1150 avahi_log_warn("Too many objects for client '%s', client request failed.", client->name);
1151 return respond_error(c, m, AVAHI_DBUS_ERROR_TOO_MANY_OBJECTS, NULL);
1154 i = g_new(HostNameResolverInfo, 1);
1156 i->message = dbus_message_ref(m);
1157 AVAHI_LLIST_PREPEND(HostNameResolverInfo, host_name_resolvers, client->host_name_resolvers, i);
1158 client->n_objects++;
1160 if (!(i->host_name_resolver = avahi_host_name_resolver_new(avahi_server, (AvahiIfIndex) interface, (AvahiProtocol) protocol, name, (AvahiProtocol) aprotocol, host_name_resolver_callback, i))) {
1161 host_name_resolver_free(i);
1162 avahi_log_warn("Failed to create host name resolver");
1166 return DBUS_HANDLER_RESULT_HANDLED;
1168 } else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_SERVER, "ResolveAddress")) {
1170 gint32 interface, protocol;
1172 AddressResolverInfo *i;
1175 if (!dbus_message_get_args(
1177 DBUS_TYPE_INT32, &interface,
1178 DBUS_TYPE_INT32, &protocol,
1179 DBUS_TYPE_STRING, &address,
1180 DBUS_TYPE_INVALID) || !address || !*address) {
1181 avahi_log_warn("Error parsing Server::ResolveAddress message");
1185 if (!avahi_address_parse(address, AVAHI_PROTO_UNSPEC, &a)) {
1186 avahi_log_warn("Error parsing address data");
1187 return respond_error(c, m, AVAHI_DBUS_ERROR_INVALID_ADDRESS, NULL);
1190 if (!(client = client_get(dbus_message_get_sender(m), TRUE))) {
1191 avahi_log_warn("Too many clients, client request failed.");
1192 return respond_error(c, m, AVAHI_DBUS_ERROR_TOO_MANY_CLIENTS, NULL);
1195 if (client->n_objects >= MAX_OBJECTS_PER_CLIENT) {
1196 avahi_log_warn("Too many objects for client '%s', client request failed.", client->name);
1197 return respond_error(c, m, AVAHI_DBUS_ERROR_TOO_MANY_OBJECTS, NULL);
1200 i = g_new(AddressResolverInfo, 1);
1202 i->message = dbus_message_ref(m);
1203 AVAHI_LLIST_PREPEND(AddressResolverInfo, address_resolvers, client->address_resolvers, i);
1204 client->n_objects++;
1206 if (!(i->address_resolver = avahi_address_resolver_new(avahi_server, (AvahiIfIndex) interface, (AvahiProtocol) protocol, &a, address_resolver_callback, i))) {
1207 address_resolver_free(i);
1208 avahi_log_warn("Failed to create address resolver");
1212 return DBUS_HANDLER_RESULT_HANDLED;
1214 } else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_SERVER, "DomainBrowserNew")) {
1216 DomainBrowserInfo *i;
1217 static const DBusObjectPathVTable vtable = {
1219 msg_domain_browser_impl,
1225 gint32 interface, protocol, type;
1229 if (!dbus_message_get_args(
1231 DBUS_TYPE_INT32, &interface,
1232 DBUS_TYPE_INT32, &protocol,
1233 DBUS_TYPE_STRING, &domain,
1234 DBUS_TYPE_INT32, &type,
1235 DBUS_TYPE_INVALID) || type < 0 || type >= AVAHI_DOMAIN_BROWSER_MAX) {
1236 avahi_log_warn("Error parsing Server::DomainBrowserNew message");
1240 if (!(client = client_get(dbus_message_get_sender(m), TRUE))) {
1241 avahi_log_warn("Too many clients, client request failed.");
1242 return respond_error(c, m, AVAHI_DBUS_ERROR_TOO_MANY_CLIENTS, NULL);
1245 if (client->n_objects >= MAX_OBJECTS_PER_CLIENT) {
1246 avahi_log_warn("Too many objects for client '%s', client request failed.", client->name);
1247 return respond_error(c, m, AVAHI_DBUS_ERROR_TOO_MANY_OBJECTS, NULL);
1253 i = g_new(DomainBrowserInfo, 1);
1254 i->id = ++client->current_id;
1256 i->path = g_strdup_printf("/Client%u/DomainBrowser%u", client->id, i->id);
1257 AVAHI_LLIST_PREPEND(DomainBrowserInfo, domain_browsers, client->domain_browsers, i);
1258 client->n_objects++;
1260 if (!(i->domain_browser = avahi_domain_browser_new(avahi_server, (AvahiIfIndex) interface, (AvahiProtocol) protocol, domain, (AvahiDomainBrowserType) type, domain_browser_callback, i))) {
1261 avahi_log_warn("Failed to create domain browser");
1262 domain_browser_free(i);
1266 dbus_connection_register_object_path(c, i->path, &vtable, i);
1267 return respond_path(c, m, i->path);
1269 } else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_SERVER, "ServiceTypeBrowserNew")) {
1271 ServiceTypeBrowserInfo *i;
1272 static const DBusObjectPathVTable vtable = {
1274 msg_service_type_browser_impl,
1280 gint32 interface, protocol;
1283 if (!dbus_message_get_args(
1285 DBUS_TYPE_INT32, &interface,
1286 DBUS_TYPE_INT32, &protocol,
1287 DBUS_TYPE_STRING, &domain,
1288 DBUS_TYPE_INVALID)) {
1289 avahi_log_warn("Error parsing Server::ServiceTypeBrowserNew message");
1293 if (!(client = client_get(dbus_message_get_sender(m), TRUE))) {
1294 avahi_log_warn("Too many clients, client request failed.");
1295 return respond_error(c, m, AVAHI_DBUS_ERROR_TOO_MANY_CLIENTS, NULL);
1299 if (client->n_objects >= MAX_OBJECTS_PER_CLIENT) {
1300 avahi_log_warn("Too many objects for client '%s', client request failed.", client->name);
1301 return respond_error(c, m, AVAHI_DBUS_ERROR_TOO_MANY_OBJECTS, NULL);
1307 i = g_new(ServiceTypeBrowserInfo, 1);
1308 i->id = ++client->current_id;
1310 i->path = g_strdup_printf("/Client%u/ServiceTypeBrowser%u", client->id, i->id);
1311 AVAHI_LLIST_PREPEND(ServiceTypeBrowserInfo, service_type_browsers, client->service_type_browsers, i);
1312 client->n_objects++;
1314 if (!(i->service_type_browser = avahi_service_type_browser_new(avahi_server, (AvahiIfIndex) interface, (AvahiProtocol) protocol, domain, service_type_browser_callback, i))) {
1315 avahi_log_warn("Failed to create service type browser");
1316 service_type_browser_free(i);
1320 dbus_connection_register_object_path(c, i->path, &vtable, i);
1321 return respond_path(c, m, i->path);
1323 } else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_SERVER, "ServiceBrowserNew")) {
1325 ServiceBrowserInfo *i;
1326 static const DBusObjectPathVTable vtable = {
1328 msg_service_browser_impl,
1334 gint32 interface, protocol;
1335 gchar *domain, *type;
1337 if (!dbus_message_get_args(
1339 DBUS_TYPE_INT32, &interface,
1340 DBUS_TYPE_INT32, &protocol,
1341 DBUS_TYPE_STRING, &type,
1342 DBUS_TYPE_STRING, &domain,
1343 DBUS_TYPE_INVALID) || !type || !*type) {
1344 avahi_log_warn("Error parsing Server::ServiceBrowserNew message");
1348 if (!(client = client_get(dbus_message_get_sender(m), TRUE))) {
1349 avahi_log_warn("Too many clients, client request failed.");
1350 return respond_error(c, m, AVAHI_DBUS_ERROR_TOO_MANY_CLIENTS, NULL);
1354 if (client->n_objects >= MAX_OBJECTS_PER_CLIENT) {
1355 avahi_log_warn("Too many objects for client '%s', client request failed.", client->name);
1356 return respond_error(c, m, AVAHI_DBUS_ERROR_TOO_MANY_OBJECTS, NULL);
1362 i = g_new(ServiceBrowserInfo, 1);
1363 i->id = ++client->current_id;
1365 i->path = g_strdup_printf("/Client%u/ServiceBrowser%u", client->id, i->id);
1366 AVAHI_LLIST_PREPEND(ServiceBrowserInfo, service_browsers, client->service_browsers, i);
1367 client->n_objects++;
1369 if (!(i->service_browser = avahi_service_browser_new(avahi_server, (AvahiIfIndex) interface, (AvahiProtocol) protocol, type, domain, service_browser_callback, i))) {
1370 avahi_log_warn("Failed to create service browser");
1371 service_browser_free(i);
1375 dbus_connection_register_object_path(c, i->path, &vtable, i);
1376 return respond_path(c, m, i->path);
1378 } else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_SERVER, "ResolveService")) {
1380 gint32 interface, protocol, aprotocol;
1381 gchar *name, *type, *domain;
1382 ServiceResolverInfo *i;
1384 if (!dbus_message_get_args(
1386 DBUS_TYPE_INT32, &interface,
1387 DBUS_TYPE_INT32, &protocol,
1388 DBUS_TYPE_STRING, &name,
1389 DBUS_TYPE_STRING, &type,
1390 DBUS_TYPE_STRING, &domain,
1391 DBUS_TYPE_INT32, &aprotocol,
1392 DBUS_TYPE_INVALID) || !name || !*name || !type || !*type) {
1393 avahi_log_warn("Error parsing Server::ResolveService message");
1397 if (!(client = client_get(dbus_message_get_sender(m), TRUE))) {
1398 avahi_log_warn("Too many clients, client request failed.");
1399 return respond_error(c, m, AVAHI_DBUS_ERROR_TOO_MANY_CLIENTS, NULL);
1402 if (client->n_objects >= MAX_OBJECTS_PER_CLIENT) {
1403 avahi_log_warn("Too many objects for client '%s', client request failed.", client->name);
1404 return respond_error(c, m, AVAHI_DBUS_ERROR_TOO_MANY_OBJECTS, NULL);
1410 i = g_new(ServiceResolverInfo, 1);
1412 i->message = dbus_message_ref(m);
1413 AVAHI_LLIST_PREPEND(ServiceResolverInfo, service_resolvers, client->service_resolvers, i);
1414 client->n_objects++;
1416 if (!(i->service_resolver = avahi_service_resolver_new(avahi_server, (AvahiIfIndex) interface, (AvahiProtocol) protocol, name, type, domain, (AvahiProtocol) aprotocol, service_resolver_callback, i))) {
1417 service_resolver_free(i);
1418 avahi_log_warn("Failed to create service resolver");
1422 return DBUS_HANDLER_RESULT_HANDLED;
1425 avahi_log_warn("Missed message %s::%s()", dbus_message_get_interface(m), dbus_message_get_member(m));
1428 if (dbus_error_is_set(&error))
1429 dbus_error_free(&error);
1431 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
1434 void dbus_protocol_server_state_changed(AvahiServerState state) {
1441 m = dbus_message_new_signal(AVAHI_DBUS_PATH_SERVER, AVAHI_DBUS_INTERFACE_SERVER, "StateChanged");
1443 dbus_message_append_args(m, DBUS_TYPE_INT32, &t, DBUS_TYPE_INVALID);
1444 dbus_connection_send(server->bus, m, NULL);
1445 dbus_message_unref(m);
1448 int dbus_protocol_setup(GMainLoop *loop) {
1451 static const DBusObjectPathVTable server_vtable = {
1460 dbus_error_init(&error);
1462 server = g_malloc(sizeof(Server));
1463 server->clients = NULL;
1464 server->current_id = 0;
1465 server->n_clients = 0;
1467 server->bus = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
1468 if (dbus_error_is_set(&error)) {
1469 avahi_log_warn("dbus_bus_get(): %s", error.message);
1473 dbus_connection_setup_with_g_main(server->bus, NULL);
1474 dbus_connection_set_exit_on_disconnect(server->bus, FALSE);
1476 dbus_bus_request_name(server->bus, AVAHI_DBUS_NAME, 0, &error);
1477 if (dbus_error_is_set(&error)) {
1478 avahi_log_warn("dbus_bus_request_name(): %s", error.message);
1482 dbus_bus_add_match(server->bus, "type='signal',""interface='" DBUS_INTERFACE_DBUS "'", &error);
1484 dbus_connection_add_filter(server->bus, msg_signal_filter_impl, loop, NULL);
1485 dbus_connection_register_object_path(server->bus, AVAHI_DBUS_PATH_SERVER, &server_vtable, NULL);
1491 dbus_connection_disconnect(server->bus);
1492 dbus_connection_unref(server->bus);
1495 dbus_error_free (&error);
1501 void dbus_protocol_shutdown(void) {
1505 while (server->clients)
1506 client_free(server->clients);
1508 g_assert(server->n_clients == 0);
1511 dbus_connection_disconnect(server->bus);
1512 dbus_connection_unref(server->bus);