Tests: add session_bus_run() and use it where possible
[glib.git] / gio / gdbusdaemon.c
blob3631a903050826ce6171ed5165931280192c30af
1 #include "config.h"
3 #include <string.h>
4 #include <stdlib.h>
6 #include <gstdio.h>
7 #include <gio/gio.h>
8 #include <gio/gunixsocketaddress.h>
9 #include "gdbusdaemon.h"
11 #include "gdbus-daemon-generated.h"
13 #define DBUS_SERVICE_NAME "org.freedesktop.DBus"
15 /* Owner flags */
16 #define DBUS_NAME_FLAG_ALLOW_REPLACEMENT 0x1 /**< Allow another service to become the primary owner if requested */
17 #define DBUS_NAME_FLAG_REPLACE_EXISTING 0x2 /**< Request to replace the current primary owner */
18 #define DBUS_NAME_FLAG_DO_NOT_QUEUE 0x4 /**< If we can not become the primary owner do not place us in the queue */
20 /* Replies to request for a name */
21 #define DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER 1 /**< Service has become the primary owner of the requested name */
22 #define DBUS_REQUEST_NAME_REPLY_IN_QUEUE 2 /**< Service could not become the primary owner and has been placed in the queue */
23 #define DBUS_REQUEST_NAME_REPLY_EXISTS 3 /**< Service is already in the queue */
24 #define DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER 4 /**< Service is already the primary owner */
26 /* Replies to releasing a name */
27 #define DBUS_RELEASE_NAME_REPLY_RELEASED 1 /**< Service was released from the given name */
28 #define DBUS_RELEASE_NAME_REPLY_NON_EXISTENT 2 /**< The given name does not exist on the bus */
29 #define DBUS_RELEASE_NAME_REPLY_NOT_OWNER 3 /**< Service is not an owner of the given name */
31 /* Replies to service starts */
32 #define DBUS_START_REPLY_SUCCESS 1 /**< Service was auto started */
33 #define DBUS_START_REPLY_ALREADY_RUNNING 2 /**< Service was already running */
35 #define IDLE_TIMEOUT_MSEC 3000
37 struct _GDBusDaemon
39 _GFreedesktopDBusSkeleton parent_instance;
41 gchar *address;
42 guint timeout;
43 gchar *tmpdir;
44 GDBusServer *server;
45 gchar *guid;
46 GHashTable *clients;
47 GHashTable *names;
48 guint32 next_major_id;
49 guint32 next_minor_id;
52 struct _GDBusDaemonClass
54 _GFreedesktopDBusSkeletonClass parent_class;
57 enum {
58 PROP_0,
59 PROP_ADDRESS,
62 enum
64 SIGNAL_IDLE_TIMEOUT,
65 NR_SIGNALS
68 static guint g_dbus_daemon_signals[NR_SIGNALS];
71 static void initable_iface_init (GInitableIface *initable_iface);
72 static void g_dbus_daemon_iface_init (_GFreedesktopDBusIface *iface);
74 #define g_dbus_daemon_get_type _g_dbus_daemon_get_type
75 G_DEFINE_TYPE_WITH_CODE (GDBusDaemon, g_dbus_daemon, _G_TYPE_FREEDESKTOP_DBUS_SKELETON,
76 G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, initable_iface_init)
77 G_IMPLEMENT_INTERFACE (_G_TYPE_FREEDESKTOP_DBUS, g_dbus_daemon_iface_init));
79 typedef struct {
80 GDBusDaemon *daemon;
81 char *id;
82 GDBusConnection *connection;
83 GList *matches;
84 } Client;
86 typedef struct {
87 Client *client;
88 guint32 flags;
89 } NameOwner;
91 typedef struct {
92 int refcount;
94 char *name;
95 GDBusDaemon *daemon;
97 NameOwner *owner;
98 GList *queue;
99 } Name;
101 enum {
102 MATCH_ELEMENT_TYPE,
103 MATCH_ELEMENT_SENDER,
104 MATCH_ELEMENT_INTERFACE,
105 MATCH_ELEMENT_MEMBER,
106 MATCH_ELEMENT_PATH,
107 MATCH_ELEMENT_PATH_NAMESPACE,
108 MATCH_ELEMENT_DESTINATION,
109 MATCH_ELEMENT_ARG0NAMESPACE,
110 MATCH_ELEMENT_EAVESDROP,
111 MATCH_ELEMENT_ARGN,
112 MATCH_ELEMENT_ARGNPATH,
115 typedef struct {
116 guint16 type;
117 guint16 arg;
118 char *value;
119 } MatchElement;
121 typedef struct {
122 gboolean eavesdrop;
123 GDBusMessageType type;
124 int n_elements;
125 MatchElement *elements;
126 } Match;
128 static GDBusMessage *filter_function (GDBusConnection *connection,
129 GDBusMessage *message,
130 gboolean incoming,
131 gpointer user_data);
132 static void connection_closed (GDBusConnection *connection,
133 gboolean remote_peer_vanished,
134 GError *error,
135 Client *client);
137 static NameOwner *
138 name_owner_new (Client *client, guint32 flags)
140 NameOwner *owner;
142 owner = g_new0 (NameOwner, 1);
143 owner->client = client;
144 owner->flags = flags;
145 return owner;
148 static void
149 name_owner_free (NameOwner *owner)
151 g_free (owner);
154 static Name *
155 name_new (GDBusDaemon *daemon, const char *str)
157 Name *name;
159 name = g_new0 (Name, 1);
160 name->refcount = 1;
161 name->daemon = daemon;
162 name->name = g_strdup (str);
164 g_hash_table_insert (daemon->names, name->name, name);
166 return name;
169 static Name *
170 name_ref (Name *name)
172 name->refcount++;
173 return name;
176 static void
177 name_unref (Name *name)
179 if (--name->refcount == 0)
181 g_hash_table_remove (name->daemon->names, name->name);
182 g_free (name->name);
183 g_free (name);
187 static Name *
188 name_ensure (GDBusDaemon *daemon, const char *str)
190 Name *name;
192 name = g_hash_table_lookup (daemon->names, str);
194 if (name != NULL)
195 return name_ref (name);
196 return name_new (daemon, str);
199 static Name *
200 name_lookup (GDBusDaemon *daemon, const char *str)
202 return g_hash_table_lookup (daemon->names, str);
205 static gboolean
206 is_key (const char *key_start, const char *key_end, char *value)
208 gsize len = strlen (value);
210 if (len != key_end - key_start)
211 return FALSE;
213 return strncmp (key_start, value, len) == 0;
216 static gboolean
217 parse_key (MatchElement *element, const char *key_start, const char *key_end)
219 gboolean res = TRUE;
221 if (is_key (key_start, key_end, "type"))
223 element->type = MATCH_ELEMENT_TYPE;
225 else if (is_key (key_start, key_end, "sender"))
227 element->type = MATCH_ELEMENT_SENDER;
229 else if (is_key (key_start, key_end, "interface"))
231 element->type = MATCH_ELEMENT_INTERFACE;
233 else if (is_key (key_start, key_end, "member"))
235 element->type = MATCH_ELEMENT_MEMBER;
237 else if (is_key (key_start, key_end, "path"))
239 element->type = MATCH_ELEMENT_PATH;
241 else if (is_key (key_start, key_end, "path_namespace"))
243 element->type = MATCH_ELEMENT_PATH_NAMESPACE;
245 else if (is_key (key_start, key_end, "destination"))
247 element->type = MATCH_ELEMENT_DESTINATION;
249 else if (is_key (key_start, key_end, "arg0namespace"))
251 element->type = MATCH_ELEMENT_ARG0NAMESPACE;
253 else if (is_key (key_start, key_end, "eavesdrop"))
255 element->type = MATCH_ELEMENT_EAVESDROP;
257 else if (key_end - key_start > 3 && is_key (key_start, key_start + 3, "arg"))
259 const char *digits = key_start + 3;
260 const char *end_digits = digits;
262 while (end_digits < key_end && g_ascii_isdigit (*end_digits))
263 end_digits++;
265 if (end_digits == key_end) /* argN */
267 element->type = MATCH_ELEMENT_ARGN;
268 element->arg = atoi (digits);
270 else if (is_key (end_digits, key_end, "path")) /* argNpath */
272 element->type = MATCH_ELEMENT_ARGNPATH;
273 element->arg = atoi (digits);
275 else
276 res = FALSE;
278 else
279 res = FALSE;
281 return res;
284 static const char *
285 parse_value (MatchElement *element, const char *s)
287 char quote_char;
288 GString *value;
290 value = g_string_new ("");
292 quote_char = 0;
294 for (;*s; s++)
296 if (quote_char == 0)
298 switch (*s)
300 case '\'':
301 quote_char = '\'';
302 break;
304 case ',':
305 s++;
306 goto out;
308 case '\\':
309 quote_char = '\\';
310 break;
312 default:
313 g_string_append_c (value, *s);
314 break;
317 else if (quote_char == '\\')
319 /* \ only counts as an escape if escaping a quote mark */
320 if (*s != '\'')
321 g_string_append_c (value, '\\');
323 g_string_append_c (value, *s);
324 quote_char = 0;
326 else /* quote_char == ' */
328 if (*s == '\'')
329 quote_char = 0;
330 else
331 g_string_append_c (value, *s);
335 out:
337 if (quote_char == '\\')
338 g_string_append_c (value, '\\');
339 else if (quote_char == '\'')
341 g_string_free (value, TRUE);
342 return NULL;
345 element->value = g_string_free (value, FALSE);
346 return s;
349 static Match *
350 match_new (const char *str)
352 Match *match;
353 GArray *elements;
354 const char *p;
355 const char *key_start;
356 const char *key_end;
357 MatchElement element;
358 gboolean eavesdrop;
359 GDBusMessageType type;
360 int i;
362 eavesdrop = FALSE;
363 type = G_DBUS_MESSAGE_TYPE_INVALID;
364 elements = g_array_new (TRUE, TRUE, sizeof (MatchElement));
366 p = str;
368 while (*p != 0)
370 memset (&element, 0, sizeof (element));
372 /* Skip initial whitespace */
373 while (*p && g_ascii_isspace (*p))
374 p++;
376 key_start = p;
378 /* Read non-whitespace non-equals chars */
379 while (*p && *p != '=' && !g_ascii_isspace (*p))
380 p++;
382 key_end = p;
384 /* Skip any whitespace after key */
385 while (*p && g_ascii_isspace (*p))
386 p++;
388 if (key_start == key_end)
389 continue; /* Allow trailing whitespace */
391 if (*p != '=')
392 goto error;
394 ++p;
396 if (!parse_key (&element, key_start, key_end))
397 goto error;
399 p = parse_value (&element, p);
400 if (p == NULL)
401 goto error;
403 if (element.type == MATCH_ELEMENT_EAVESDROP)
405 if (strcmp (element.value, "true") == 0)
406 eavesdrop = TRUE;
407 else if (strcmp (element.value, "false") == 0)
408 eavesdrop = FALSE;
409 else
411 g_free (element.value);
412 goto error;
414 g_free (element.value);
416 else if (element.type == MATCH_ELEMENT_TYPE)
418 if (strcmp (element.value, "signal") == 0)
419 type = G_DBUS_MESSAGE_TYPE_SIGNAL;
420 else if (strcmp (element.value, "method_call") == 0)
421 type = G_DBUS_MESSAGE_TYPE_METHOD_CALL;
422 else if (strcmp (element.value, "method_return") == 0)
423 type = G_DBUS_MESSAGE_TYPE_METHOD_RETURN;
424 else if (strcmp (element.value, "error") == 0)
425 type = G_DBUS_MESSAGE_TYPE_ERROR;
426 else
428 g_free (element.value);
429 goto error;
431 g_free (element.value);
433 else
434 g_array_append_val (elements, element);
437 match = g_new0 (Match, 1);
438 match->n_elements = elements->len;
439 match->elements = (MatchElement *)g_array_free (elements, FALSE);
440 match->eavesdrop = eavesdrop;
441 match->type = type;
443 return match;
445 error:
446 for (i = 0; i < elements->len; i++)
447 g_free (g_array_index (elements, MatchElement, i).value);
448 g_array_free (elements, TRUE);
449 return NULL;
452 static void
453 match_free (Match *match)
455 int i;
456 for (i = 0; i < match->n_elements; i++)
457 g_free (match->elements[i].value);
458 g_free (match->elements);
459 g_free (match);
462 static gboolean
463 match_equal (Match *a, Match *b)
465 int i;
467 if (a->eavesdrop != b->eavesdrop)
468 return FALSE;
469 if (a->type != b->type)
470 return FALSE;
471 if (a->n_elements != b->n_elements)
472 return FALSE;
473 for (i = 0; i < a->n_elements; i++)
475 if (a->elements[i].type != b->elements[i].type ||
476 a->elements[i].arg != b->elements[i].arg ||
477 strcmp (a->elements[i].value, b->elements[i].value) != 0)
478 return FALSE;
480 return TRUE;
483 static const gchar *
484 message_get_argN (GDBusMessage *message, int n, gboolean allow_path)
486 const gchar *ret;
487 GVariant *body;
489 ret = NULL;
491 body = g_dbus_message_get_body (message);
493 if (body != NULL && g_variant_is_of_type (body, G_VARIANT_TYPE_TUPLE))
495 GVariant *item;
496 item = g_variant_get_child_value (body, n);
497 if (g_variant_is_of_type (item, G_VARIANT_TYPE_STRING) ||
498 (allow_path && g_variant_is_of_type (item, G_VARIANT_TYPE_OBJECT_PATH)))
499 ret = g_variant_get_string (item, NULL);
500 g_variant_unref (item);
503 return ret;
506 enum {
507 CHECK_TYPE_STRING,
508 CHECK_TYPE_NAME,
509 CHECK_TYPE_PATH_PREFIX,
510 CHECK_TYPE_PATH_RELATED,
511 CHECK_TYPE_NAMESPACE_PREFIX
514 static gboolean
515 match_matches (GDBusDaemon *daemon,
516 Match *match, GDBusMessage *message,
517 gboolean has_destination)
519 MatchElement *element;
520 Name *name;
521 int i, len, len2;
522 const char *value;
523 int check_type;
525 if (has_destination && !match->eavesdrop)
526 return FALSE;
528 if (match->type != G_DBUS_MESSAGE_TYPE_INVALID &&
529 g_dbus_message_get_message_type (message) != match->type)
530 return FALSE;
532 for (i = 0; i < match->n_elements; i++)
534 element = &match->elements[i];
535 check_type = CHECK_TYPE_STRING;
536 switch (element->type)
538 case MATCH_ELEMENT_SENDER:
539 check_type = CHECK_TYPE_NAME;
540 value = g_dbus_message_get_sender (message);
541 if (value == NULL)
542 value = DBUS_SERVICE_NAME;
543 break;
544 case MATCH_ELEMENT_DESTINATION:
545 check_type = CHECK_TYPE_NAME;
546 value = g_dbus_message_get_destination (message);
547 break;
548 case MATCH_ELEMENT_INTERFACE:
549 value = g_dbus_message_get_interface (message);
550 break;
551 case MATCH_ELEMENT_MEMBER:
552 value = g_dbus_message_get_member (message);
553 break;
554 case MATCH_ELEMENT_PATH:
555 value = g_dbus_message_get_path (message);
556 break;
557 case MATCH_ELEMENT_PATH_NAMESPACE:
558 check_type = CHECK_TYPE_PATH_PREFIX;
559 value = g_dbus_message_get_path (message);
560 break;
561 case MATCH_ELEMENT_ARG0NAMESPACE:
562 check_type = CHECK_TYPE_NAMESPACE_PREFIX;
563 value = message_get_argN (message, 0, FALSE);
564 break;
565 case MATCH_ELEMENT_ARGN:
566 value = message_get_argN (message, element->arg, FALSE);
567 break;
568 case MATCH_ELEMENT_ARGNPATH:
569 check_type = CHECK_TYPE_PATH_RELATED;
570 value = message_get_argN (message, element->arg, TRUE);
571 break;
572 default:
573 case MATCH_ELEMENT_TYPE:
574 case MATCH_ELEMENT_EAVESDROP:
575 g_assert_not_reached ();
578 if (value == NULL)
579 return FALSE;
581 switch (check_type)
583 case CHECK_TYPE_STRING:
584 if (strcmp (element->value, value) != 0)
585 return FALSE;
586 break;
587 case CHECK_TYPE_NAME:
588 name = name_lookup (daemon, element->value);
589 if (name != NULL && name->owner != NULL)
591 if (strcmp (name->owner->client->id, value) != 0)
592 return FALSE;
594 else if (strcmp (element->value, value) != 0)
595 return FALSE;
596 break;
597 case CHECK_TYPE_PATH_PREFIX:
598 len = strlen (element->value);
600 /* Make sure to handle the case of element->value == '/'. */
601 if (len == 1)
602 break;
604 /* Fail if there's no prefix match, or if the prefix match doesn't
605 * finish at the end of or at a separator in the @value. */
606 if (!g_str_has_prefix (value, element->value))
607 return FALSE;
608 if (value[len] != 0 && value[len] != '/')
609 return FALSE;
611 break;
612 case CHECK_TYPE_PATH_RELATED:
613 len = strlen (element->value);
614 len2 = strlen (value);
616 if (!(strcmp (value, element->value) == 0 ||
617 (len2 > 0 && value[len2-1] == '/' && g_str_has_prefix (element->value, value)) ||
618 (len > 0 && element->value[len-1] == '/' && g_str_has_prefix (value, element->value))))
619 return FALSE;
620 break;
621 case CHECK_TYPE_NAMESPACE_PREFIX:
622 len = strlen (element->value);
623 if (!(g_str_has_prefix (value, element->value) &&
624 (value[len] == 0 || value[len] == '.')))
625 return FALSE;
626 break;
627 default:
628 g_assert_not_reached ();
632 return TRUE;
635 static void
636 broadcast_message (GDBusDaemon *daemon,
637 GDBusMessage *message,
638 gboolean has_destination,
639 gboolean preserve_serial,
640 Client *not_to)
642 GList *clients, *l, *ll;
643 GDBusMessage *copy;
645 clients = g_hash_table_get_values (daemon->clients);
646 for (l = clients; l != NULL; l = l->next)
648 Client *client = l->data;
650 if (client == not_to)
651 continue;
653 for (ll = client->matches; ll != NULL; ll = ll->next)
655 Match *match = ll->data;
657 if (match_matches (daemon, match, message, has_destination))
658 break;
661 if (ll != NULL)
663 copy = g_dbus_message_copy (message, NULL);
664 if (copy)
666 g_dbus_connection_send_message (client->connection, copy,
667 preserve_serial?G_DBUS_SEND_MESSAGE_FLAGS_PRESERVE_SERIAL:0, NULL, NULL);
668 g_object_unref (copy);
673 g_list_free (clients);
676 static void
677 send_name_owner_changed (GDBusDaemon *daemon,
678 const char *name,
679 const char *old_owner,
680 const char *new_owner)
682 GDBusMessage *signal_message;
684 signal_message = g_dbus_message_new_signal ("/org/freedesktop/DBus",
685 "org.freedesktop.DBus",
686 "NameOwnerChanged");
687 g_dbus_message_set_body (signal_message,
688 g_variant_new ("(sss)",
689 name,
690 old_owner ? old_owner : "",
691 new_owner ? new_owner : ""));
693 broadcast_message (daemon, signal_message, FALSE, FALSE, NULL);
694 g_object_unref (signal_message);
698 static gboolean
699 name_unqueue_owner (Name *name, Client *client)
701 GList *l;
703 for (l = name->queue; l != NULL; l = l->next)
705 NameOwner *other = l->data;
707 if (other->client == client)
709 name->queue = g_list_delete_link (name->queue, l);
710 name_unref (name);
711 name_owner_free (other);
712 return TRUE;
716 return FALSE;
719 static void
720 name_replace_owner (Name *name, NameOwner *owner)
722 GDBusDaemon *daemon = name->daemon;
723 NameOwner *old_owner;
724 char *old_name = NULL, *new_name = NULL;
725 Client *new_client = NULL;
727 if (owner)
728 new_client = owner->client;
730 name_ref (name);
732 old_owner = name->owner;
733 if (old_owner)
735 Client *old_client = old_owner->client;
737 g_assert (old_owner->client != new_client);
739 g_dbus_connection_emit_signal (old_client->connection,
740 NULL, "/org/freedesktop/DBus",
741 "org.freedesktop.DBus", "NameLost",
742 g_variant_new ("(s)",
743 name->name), NULL);
745 old_name = g_strdup (old_client->id);
746 if (old_owner->flags & DBUS_NAME_FLAG_DO_NOT_QUEUE)
748 name_unref (name);
749 name_owner_free (old_owner);
751 else
752 name->queue = g_list_prepend (name->queue, old_owner);
755 name->owner = owner;
756 if (owner)
758 name_unqueue_owner (name, owner->client);
759 name_ref (name);
760 new_name = new_client->id;
762 g_dbus_connection_emit_signal (new_client->connection,
763 NULL, "/org/freedesktop/DBus",
764 "org.freedesktop.DBus", "NameAcquired",
765 g_variant_new ("(s)",
766 name->name), NULL);
769 send_name_owner_changed (daemon, name->name, old_name, new_name);
771 g_free (old_name);
773 name_unref (name);
776 static void
777 name_release_owner (Name *name)
779 NameOwner *next_owner = NULL;
781 name_ref (name);
783 /* Will someone else take over? */
784 if (name->queue)
786 next_owner = name->queue->data;
787 name_unref (name);
788 name->queue = g_list_delete_link (name->queue, name->queue);
791 name->owner->flags |= DBUS_NAME_FLAG_DO_NOT_QUEUE;
792 name_replace_owner (name, next_owner);
794 name_unref (name);
797 static void
798 name_queue_owner (Name *name, NameOwner *owner)
800 GList *l;
802 for (l = name->queue; l != NULL; l = l->next)
804 NameOwner *other = l->data;
806 if (other->client == owner->client)
808 other->flags = owner->flags;
809 name_owner_free (owner);
810 return;
814 name->queue = g_list_append (name->queue, owner);
815 name_ref (name);
818 static Client *
819 client_new (GDBusDaemon *daemon, GDBusConnection *connection)
821 Client *client;
822 GError *error = NULL;
824 client = g_new0 (Client, 1);
825 client->daemon = daemon;
826 client->id = g_strdup_printf (":%d.%d", daemon->next_major_id, daemon->next_minor_id);
827 client->connection = g_object_ref (connection);
829 if (daemon->next_minor_id == G_MAXUINT32)
831 daemon->next_minor_id = 0;
832 daemon->next_major_id++;
834 else
835 daemon->next_minor_id++;
837 g_object_set_data (G_OBJECT (connection), "client", client);
838 g_hash_table_insert (daemon->clients, client->id, client);
840 g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (daemon), connection,
841 "/org/freedesktop/DBus", &error);
842 g_assert_no_error (error);
844 g_signal_connect (connection, "closed", G_CALLBACK (connection_closed), client);
845 g_dbus_connection_add_filter (connection,
846 filter_function,
847 client, NULL);
849 send_name_owner_changed (daemon, client->id, NULL, client->id);
851 return client;
854 static void
855 client_free (Client *client)
857 GDBusDaemon *daemon = client->daemon;
858 GList *l, *names;
860 g_dbus_interface_skeleton_unexport_from_connection (G_DBUS_INTERFACE_SKELETON (daemon),
861 client->connection);
863 g_hash_table_remove (daemon->clients, client->id);
865 names = g_hash_table_get_values (daemon->names);
866 for (l = names; l != NULL; l = l->next)
868 Name *name = l->data;
870 name_ref (name);
872 if (name->owner && name->owner->client == client)
873 name_release_owner (name);
875 name_unqueue_owner (name, client);
877 name_unref (name);
879 g_list_free (names);
881 send_name_owner_changed (daemon, client->id, client->id, NULL);
883 g_object_unref (client->connection);
885 for (l = client->matches; l != NULL; l = l->next)
886 match_free (l->data);
887 g_list_free (client->matches);
889 g_free (client->id);
890 g_free (client);
893 static gboolean
894 idle_timeout_cb (gpointer user_data)
896 GDBusDaemon *daemon = user_data;
898 daemon->timeout = 0;
900 g_signal_emit (daemon,
901 g_dbus_daemon_signals[SIGNAL_IDLE_TIMEOUT],
904 return G_SOURCE_REMOVE;
907 static void
908 connection_closed (GDBusConnection *connection,
909 gboolean remote_peer_vanished,
910 GError *error,
911 Client *client)
913 GDBusDaemon *daemon = client->daemon;
915 client_free (client);
917 if (g_hash_table_size (daemon->clients) == 0)
918 daemon->timeout = g_timeout_add (IDLE_TIMEOUT_MSEC,
919 idle_timeout_cb,
920 daemon);
923 static gboolean
924 handle_add_match (_GFreedesktopDBus *object,
925 GDBusMethodInvocation *invocation,
926 const gchar *arg_rule)
928 Client *client = g_object_get_data (G_OBJECT (g_dbus_method_invocation_get_connection (invocation)), "client");
929 Match *match;
931 match = match_new (arg_rule);
933 if (match == NULL)
934 g_dbus_method_invocation_return_error (invocation,
935 G_DBUS_ERROR, G_DBUS_ERROR_MATCH_RULE_INVALID,
936 "Invalid rule: %s", arg_rule);
937 else
939 client->matches = g_list_prepend (client->matches, match);
940 _g_freedesktop_dbus_complete_add_match (object, invocation);
942 return TRUE;
945 static gboolean
946 handle_get_connection_selinux_security_context (_GFreedesktopDBus *object,
947 GDBusMethodInvocation *invocation,
948 const gchar *arg_name)
950 g_dbus_method_invocation_return_error (invocation,
951 G_DBUS_ERROR, G_DBUS_ERROR_SELINUX_SECURITY_CONTEXT_UNKNOWN,
952 "selinux context not supported");
953 _g_freedesktop_dbus_complete_get_connection_selinux_security_context (object, invocation, "");
954 return TRUE;
957 static gboolean
958 handle_get_connection_unix_process_id (_GFreedesktopDBus *object,
959 GDBusMethodInvocation *invocation,
960 const gchar *arg_name)
962 g_dbus_method_invocation_return_error (invocation,
963 G_DBUS_ERROR, G_DBUS_ERROR_UNIX_PROCESS_ID_UNKNOWN,
964 "connection pid not supported");
965 return TRUE;
968 static gboolean
969 handle_get_connection_unix_user (_GFreedesktopDBus *object,
970 GDBusMethodInvocation *invocation,
971 const gchar *arg_name)
973 g_dbus_method_invocation_return_error (invocation,
974 G_DBUS_ERROR, G_DBUS_ERROR_UNIX_PROCESS_ID_UNKNOWN,
975 "connection user not supported");
976 return TRUE;
979 static gboolean
980 handle_get_id (_GFreedesktopDBus *object,
981 GDBusMethodInvocation *invocation)
983 GDBusDaemon *daemon = G_DBUS_DAEMON (object);
984 _g_freedesktop_dbus_complete_get_id (object, invocation,
985 daemon->guid);
986 return TRUE;
989 static gboolean
990 handle_get_name_owner (_GFreedesktopDBus *object,
991 GDBusMethodInvocation *invocation,
992 const gchar *arg_name)
994 GDBusDaemon *daemon = G_DBUS_DAEMON (object);
995 Name *name;
997 if (strcmp (arg_name, DBUS_SERVICE_NAME) == 0)
999 _g_freedesktop_dbus_complete_get_name_owner (object, invocation, DBUS_SERVICE_NAME);
1000 return TRUE;
1003 if (arg_name[0] == ':')
1005 if (g_hash_table_lookup (daemon->clients, arg_name) == NULL)
1006 g_dbus_method_invocation_return_error (invocation,
1007 G_DBUS_ERROR, G_DBUS_ERROR_NAME_HAS_NO_OWNER,
1008 "Could not get owner of name '%s': no such name", arg_name);
1009 else
1010 _g_freedesktop_dbus_complete_get_name_owner (object, invocation, arg_name);
1011 return TRUE;
1014 name = name_lookup (daemon, arg_name);
1015 if (name == NULL || name->owner == NULL)
1017 g_dbus_method_invocation_return_error (invocation,
1018 G_DBUS_ERROR, G_DBUS_ERROR_NAME_HAS_NO_OWNER,
1019 "Could not get owner of name '%s': no such name", arg_name);
1020 return TRUE;
1023 _g_freedesktop_dbus_complete_get_name_owner (object, invocation, name->owner->client->id);
1024 return TRUE;
1027 static gboolean
1028 handle_hello (_GFreedesktopDBus *object,
1029 GDBusMethodInvocation *invocation)
1031 Client *client = g_object_get_data (G_OBJECT (g_dbus_method_invocation_get_connection (invocation)), "client");
1032 _g_freedesktop_dbus_complete_hello (object, invocation, client->id);
1034 g_dbus_connection_emit_signal (client->connection,
1035 NULL, "/org/freedesktop/DBus",
1036 "org.freedesktop.DBus", "NameAcquired",
1037 g_variant_new ("(s)",
1038 client->id), NULL);
1040 return TRUE;
1043 static gboolean
1044 handle_list_activatable_names (_GFreedesktopDBus *object,
1045 GDBusMethodInvocation *invocation)
1047 const char *names[] = { NULL };
1049 _g_freedesktop_dbus_complete_list_activatable_names (object,
1050 invocation,
1051 names);
1052 return TRUE;
1055 static gboolean
1056 handle_list_names (_GFreedesktopDBus *object,
1057 GDBusMethodInvocation *invocation)
1059 GDBusDaemon *daemon = G_DBUS_DAEMON (object);
1060 GPtrArray *array;
1061 GList *clients, *names, *l;
1063 array = g_ptr_array_new ();
1065 clients = g_hash_table_get_values (daemon->clients);
1066 for (l = clients; l != NULL; l = l->next)
1068 Client *client = l->data;
1070 g_ptr_array_add (array, client->id);
1073 g_list_free (clients);
1075 names = g_hash_table_get_values (daemon->names);
1076 for (l = names; l != NULL; l = l->next)
1078 Name *name = l->data;
1080 g_ptr_array_add (array, name->name);
1083 g_list_free (names);
1085 g_ptr_array_add (array, NULL);
1087 _g_freedesktop_dbus_complete_list_names (object,
1088 invocation,
1089 (const gchar * const*)array->pdata);
1090 g_ptr_array_free (array, TRUE);
1091 return TRUE;
1094 static gboolean
1095 handle_list_queued_owners (_GFreedesktopDBus *object,
1096 GDBusMethodInvocation *invocation,
1097 const gchar *arg_name)
1099 GDBusDaemon *daemon = G_DBUS_DAEMON (object);
1100 GPtrArray *array;
1101 Name *name;
1102 GList *l;
1104 array = g_ptr_array_new ();
1106 name = name_lookup (daemon, arg_name);
1107 if (name && name->owner)
1109 for (l = name->queue; l != NULL; l = l->next)
1111 Client *client = l->data;
1113 g_ptr_array_add (array, client->id);
1117 g_ptr_array_add (array, NULL);
1119 _g_freedesktop_dbus_complete_list_queued_owners (object,
1120 invocation,
1121 (const gchar * const*)array->pdata);
1122 g_ptr_array_free (array, TRUE);
1123 return TRUE;
1126 static gboolean
1127 handle_name_has_owner (_GFreedesktopDBus *object,
1128 GDBusMethodInvocation *invocation,
1129 const gchar *arg_name)
1131 GDBusDaemon *daemon = G_DBUS_DAEMON (object);
1132 Name *name;
1133 Client *client;
1135 name = name_lookup (daemon, arg_name);
1136 client = g_hash_table_lookup (daemon->clients, arg_name);
1138 _g_freedesktop_dbus_complete_name_has_owner (object, invocation,
1139 name != NULL || client != NULL);
1140 return TRUE;
1143 static gboolean
1144 handle_release_name (_GFreedesktopDBus *object,
1145 GDBusMethodInvocation *invocation,
1146 const gchar *arg_name)
1148 Client *client = g_object_get_data (G_OBJECT (g_dbus_method_invocation_get_connection (invocation)), "client");
1149 GDBusDaemon *daemon = G_DBUS_DAEMON (object);
1150 Name *name;
1151 guint32 result;
1153 if (!g_dbus_is_name (arg_name))
1155 g_dbus_method_invocation_return_error (invocation,
1156 G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
1157 "Given bus name \"%s\" is not valid", arg_name);
1158 return TRUE;
1161 if (*arg_name == ':')
1163 g_dbus_method_invocation_return_error (invocation,
1164 G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
1165 "Cannot release a service starting with ':' such as \"%s\"", arg_name);
1166 return TRUE;
1169 if (strcmp (arg_name, DBUS_SERVICE_NAME) == 0)
1171 g_dbus_method_invocation_return_error (invocation,
1172 G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
1173 "Cannot release a service named " DBUS_SERVICE_NAME ", because that is owned by the bus");
1174 return TRUE;
1177 name = name_lookup (daemon, arg_name);
1179 if (name == NULL)
1180 result = DBUS_RELEASE_NAME_REPLY_NON_EXISTENT;
1181 else if (name->owner && name->owner->client == client)
1183 name_release_owner (name);
1184 result = DBUS_RELEASE_NAME_REPLY_RELEASED;
1186 else if (name_unqueue_owner (name, client))
1187 result = DBUS_RELEASE_NAME_REPLY_RELEASED;
1188 else
1189 result = DBUS_RELEASE_NAME_REPLY_NOT_OWNER;
1191 _g_freedesktop_dbus_complete_release_name (object, invocation, result);
1192 return TRUE;
1195 static gboolean
1196 handle_reload_config (_GFreedesktopDBus *object,
1197 GDBusMethodInvocation *invocation)
1199 _g_freedesktop_dbus_complete_reload_config (object, invocation);
1200 return TRUE;
1203 static gboolean
1204 handle_update_activation_environment (_GFreedesktopDBus *object,
1205 GDBusMethodInvocation *invocation,
1206 GVariant *arg_environment)
1208 g_dbus_method_invocation_return_error (invocation,
1209 G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
1210 "UpdateActivationEnvironment not implemented");
1211 return TRUE;
1214 static gboolean
1215 handle_remove_match (_GFreedesktopDBus *object,
1216 GDBusMethodInvocation *invocation,
1217 const gchar *arg_rule)
1219 Client *client = g_object_get_data (G_OBJECT (g_dbus_method_invocation_get_connection (invocation)), "client");
1220 Match *match, *other_match;
1221 GList *l;
1223 match = match_new (arg_rule);
1225 if (match == NULL)
1226 g_dbus_method_invocation_return_error (invocation,
1227 G_DBUS_ERROR, G_DBUS_ERROR_MATCH_RULE_INVALID,
1228 "Invalid rule: %s", arg_rule);
1229 else
1231 for (l = client->matches; l != NULL; l = l->next)
1233 other_match = l->data;
1234 if (match_equal (match, other_match))
1236 match_free (other_match);
1237 client->matches = g_list_delete_link (client->matches, l);
1238 break;
1242 if (l == NULL)
1243 g_dbus_method_invocation_return_error (invocation,
1244 G_DBUS_ERROR, G_DBUS_ERROR_MATCH_RULE_NOT_FOUND,
1245 "The given match rule wasn't found and can't be removed");
1246 else
1247 _g_freedesktop_dbus_complete_remove_match (object, invocation);
1250 match_free (match);
1252 return TRUE;
1255 static gboolean
1256 handle_request_name (_GFreedesktopDBus *object,
1257 GDBusMethodInvocation *invocation,
1258 const gchar *arg_name,
1259 guint flags)
1261 Client *client = g_object_get_data (G_OBJECT (g_dbus_method_invocation_get_connection (invocation)), "client");
1262 GDBusDaemon *daemon = G_DBUS_DAEMON (object);
1263 Name *name;
1264 NameOwner *owner;
1265 guint32 result;
1267 if (!g_dbus_is_name (arg_name))
1269 g_dbus_method_invocation_return_error (invocation,
1270 G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
1271 "Requested bus name \"%s\" is not valid", arg_name);
1272 return TRUE;
1275 if (*arg_name == ':')
1277 g_dbus_method_invocation_return_error (invocation,
1278 G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
1279 "Cannot acquire a service starting with ':' such as \"%s\"", arg_name);
1280 return TRUE;
1283 if (strcmp (arg_name, DBUS_SERVICE_NAME) == 0)
1285 g_dbus_method_invocation_return_error (invocation,
1286 G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
1287 "Cannot acquire a service named " DBUS_SERVICE_NAME ", because that is reserved");
1288 return TRUE;
1291 name = name_ensure (daemon, arg_name);
1292 if (name->owner == NULL)
1294 owner = name_owner_new (client, flags);
1295 name_replace_owner (name, owner);
1297 result = DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER;
1299 else if (name->owner && name->owner->client == client)
1301 name->owner->flags = flags;
1302 result = DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER;
1304 else if ((flags & DBUS_NAME_FLAG_DO_NOT_QUEUE) &&
1305 (!(flags & DBUS_NAME_FLAG_REPLACE_EXISTING) ||
1306 !(name->owner->flags & DBUS_NAME_FLAG_ALLOW_REPLACEMENT)))
1308 /* Unqueue if queued */
1309 name_unqueue_owner (name, client);
1310 result = DBUS_REQUEST_NAME_REPLY_EXISTS;
1312 else if (!(flags & DBUS_NAME_FLAG_DO_NOT_QUEUE) &&
1313 (!(flags & DBUS_NAME_FLAG_REPLACE_EXISTING) ||
1314 !(name->owner->flags & DBUS_NAME_FLAG_ALLOW_REPLACEMENT)))
1316 /* Queue the connection */
1317 owner = name_owner_new (client, flags);
1318 name_queue_owner (name, owner);
1319 result = DBUS_REQUEST_NAME_REPLY_IN_QUEUE;
1321 else
1323 /* Replace the current owner */
1325 owner = name_owner_new (client, flags);
1326 name_replace_owner (name, owner);
1328 result = DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER;
1331 name_unref (name);
1333 _g_freedesktop_dbus_complete_request_name (object, invocation, result);
1334 return TRUE;
1337 static gboolean
1338 handle_start_service_by_name (_GFreedesktopDBus *object,
1339 GDBusMethodInvocation *invocation,
1340 const gchar *arg_name,
1341 guint arg_flags)
1343 GDBusDaemon *daemon = G_DBUS_DAEMON (object);
1344 Name *name;
1346 name = name_lookup (daemon, arg_name);
1347 if (name)
1348 _g_freedesktop_dbus_complete_start_service_by_name (object, invocation,
1349 DBUS_START_REPLY_ALREADY_RUNNING);
1350 else
1351 g_dbus_method_invocation_return_error (invocation,
1352 G_DBUS_ERROR, G_DBUS_ERROR_SERVICE_UNKNOWN,
1353 "No support for activation for name: %s", arg_name);
1355 return TRUE;
1358 G_GNUC_PRINTF(5, 6)
1359 static void
1360 return_error (Client *client, GDBusMessage *message,
1361 GQuark domain,
1362 gint code,
1363 const gchar *format,
1364 ...)
1366 GDBusMessage *reply;
1367 va_list var_args;
1368 char *error_message;
1369 GError *error;
1370 gchar *dbus_error_name;
1372 va_start (var_args, format);
1373 error_message = g_strdup_vprintf (format, var_args);
1374 va_end (var_args);
1376 error = g_error_new_literal (domain, code, "");
1377 dbus_error_name = g_dbus_error_encode_gerror (error);
1379 reply = g_dbus_message_new_method_error_literal (message,
1380 dbus_error_name,
1381 error_message);
1383 g_error_free (error);
1384 g_free (dbus_error_name);
1385 g_free (error_message);
1387 if (!g_dbus_connection_send_message (client->connection, reply, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL))
1388 g_warning ("Error sending reply");
1389 g_object_unref (reply);
1392 static GDBusMessage *
1393 route_message (Client *source_client, GDBusMessage *message)
1395 const char *dest;
1396 Client *dest_client;
1397 GDBusDaemon *daemon;
1399 daemon = source_client->daemon;
1401 dest_client = NULL;
1402 dest = g_dbus_message_get_destination (message);
1403 if (dest != NULL && strcmp (dest, DBUS_SERVICE_NAME) != 0)
1405 dest_client = g_hash_table_lookup (daemon->clients, dest);
1407 if (dest_client == NULL)
1409 Name *name;
1410 name = name_lookup (daemon, dest);
1411 if (name && name->owner)
1412 dest_client = name->owner->client;
1415 if (dest_client == NULL)
1417 if (g_dbus_message_get_message_type (message) == G_DBUS_MESSAGE_TYPE_METHOD_CALL)
1418 return_error (source_client, message,
1419 G_DBUS_ERROR, G_DBUS_ERROR_SERVICE_UNKNOWN,
1420 "The name %s is unknown", dest);
1422 else
1424 GError *error = NULL;
1426 if (!g_dbus_connection_send_message (dest_client->connection, message, G_DBUS_SEND_MESSAGE_FLAGS_PRESERVE_SERIAL, NULL, &error))
1428 g_warning ("Error forwarding message: %s", error->message);
1429 g_error_free (error);
1434 broadcast_message (daemon, message, dest_client != NULL, TRUE, dest_client);
1436 /* Swallow messages not for the bus */
1437 if (dest == NULL || strcmp (dest, DBUS_SERVICE_NAME) != 0)
1439 g_object_unref (message);
1440 message = NULL;
1443 return message;
1446 static GDBusMessage *
1447 copy_if_locked (GDBusMessage *message)
1449 if (g_dbus_message_get_locked (message))
1451 GDBusMessage *copy = g_dbus_message_copy (message, NULL);
1452 g_object_unref (message);
1453 message = copy;
1455 return message;
1458 static GDBusMessage *
1459 filter_function (GDBusConnection *connection,
1460 GDBusMessage *message,
1461 gboolean incoming,
1462 gpointer user_data)
1464 Client *client = user_data;
1465 char *types[] = {"invalid", "method_call", "method_return", "error", "signal" };
1467 if (0)
1468 g_printerr ("%s%s %s %d(%d) sender: %s destination: %s %s %s.%s\n",
1469 client->id,
1470 incoming? "->" : "<-",
1471 types[g_dbus_message_get_message_type (message)],
1472 g_dbus_message_get_serial (message),
1473 g_dbus_message_get_reply_serial (message),
1474 g_dbus_message_get_sender (message),
1475 g_dbus_message_get_destination (message),
1476 g_dbus_message_get_path (message),
1477 g_dbus_message_get_interface (message),
1478 g_dbus_message_get_member (message));
1480 if (incoming)
1482 /* Ensure its not locked so we can set the sender */
1483 message = copy_if_locked (message);
1484 if (message == NULL)
1486 g_warning ("Failed to copy incoming message");
1487 return NULL;
1489 g_dbus_message_set_sender (message, client->id);
1491 return route_message (client, message);
1493 else
1495 if (g_dbus_message_get_sender (message) == NULL)
1497 message = copy_if_locked (message);
1498 g_dbus_message_set_sender (message, DBUS_SERVICE_NAME);
1500 if (g_dbus_message_get_destination (message) == NULL)
1502 message = copy_if_locked (message);
1503 g_dbus_message_set_destination (message, client->id);
1507 return message;
1510 static gboolean
1511 on_new_connection (GDBusServer *server,
1512 GDBusConnection *connection,
1513 gpointer user_data)
1515 GDBusDaemon *daemon = user_data;
1517 g_dbus_connection_set_exit_on_close (connection, FALSE);
1519 if (daemon->timeout)
1521 g_source_remove (daemon->timeout);
1522 daemon->timeout = 0;
1525 client_new (daemon, connection);
1527 return TRUE;
1530 static gboolean
1531 on_authorize_authenticated_peer (GDBusAuthObserver *observer,
1532 GIOStream *stream,
1533 GCredentials *credentials,
1534 gpointer user_data)
1536 gboolean authorized = TRUE;
1538 if (credentials != NULL)
1540 GCredentials *own_credentials;
1542 own_credentials = g_credentials_new ();
1543 authorized = g_credentials_is_same_user (credentials, own_credentials, NULL);
1544 g_object_unref (own_credentials);
1547 return authorized;
1550 static void
1551 g_dbus_daemon_finalize (GObject *object)
1553 GDBusDaemon *daemon = G_DBUS_DAEMON (object);
1554 GList *clients, *l;
1556 if (daemon->timeout)
1557 g_source_remove (daemon->timeout);
1559 clients = g_hash_table_get_values (daemon->clients);
1560 for (l = clients; l != NULL; l = l->next)
1561 client_free (l->data);
1562 g_list_free (clients);
1564 g_assert (g_hash_table_size (daemon->clients) == 0);
1565 g_assert (g_hash_table_size (daemon->names) == 0);
1567 g_hash_table_destroy (daemon->clients);
1568 g_hash_table_destroy (daemon->names);
1570 g_object_unref (daemon->server);
1572 if (daemon->tmpdir)
1574 g_rmdir (daemon->tmpdir);
1575 g_free (daemon->tmpdir);
1578 g_free (daemon->guid);
1579 g_free (daemon->address);
1581 G_OBJECT_CLASS (g_dbus_daemon_parent_class)->finalize (object);
1584 static void
1585 g_dbus_daemon_init (GDBusDaemon *daemon)
1587 daemon->next_major_id = 1;
1588 daemon->clients = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL);
1589 daemon->names = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL);
1590 daemon->guid = g_dbus_generate_guid ();
1593 static gboolean
1594 initable_init (GInitable *initable,
1595 GCancellable *cancellable,
1596 GError **error)
1598 GDBusDaemon *daemon = G_DBUS_DAEMON (initable);
1599 GDBusAuthObserver *observer;
1600 GDBusServerFlags flags;
1602 flags = G_DBUS_SERVER_FLAGS_NONE;
1603 if (daemon->address == NULL)
1605 #ifdef G_OS_UNIX
1606 if (g_unix_socket_address_abstract_names_supported ())
1607 daemon->address = g_strdup ("unix:tmpdir=/tmp/gdbus-daemon");
1608 else
1610 daemon->tmpdir = g_dir_make_tmp ("gdbus-daemon-XXXXXX", NULL);
1611 daemon->address = g_strdup_printf ("unix:tmpdir=%s", daemon->tmpdir);
1613 #else
1614 daemon->address = g_strdup ("nonce-tcp:");
1615 flags |= G_DBUS_SERVER_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS;
1616 #endif
1619 observer = g_dbus_auth_observer_new ();
1620 daemon->server = g_dbus_server_new_sync (daemon->address,
1621 flags,
1622 daemon->guid,
1623 observer,
1624 cancellable,
1625 error);
1626 if (daemon->server == NULL)
1628 g_object_unref (observer);
1629 return FALSE;
1633 g_dbus_server_start (daemon->server);
1635 g_signal_connect (daemon->server, "new-connection",
1636 G_CALLBACK (on_new_connection),
1637 daemon);
1638 g_signal_connect (observer,
1639 "authorize-authenticated-peer",
1640 G_CALLBACK (on_authorize_authenticated_peer),
1641 daemon);
1643 g_object_unref (observer);
1645 return TRUE;
1648 static void
1649 g_dbus_daemon_set_property (GObject *object,
1650 guint prop_id,
1651 const GValue *value,
1652 GParamSpec *pspec)
1654 GDBusDaemon *daemon = G_DBUS_DAEMON (object);
1656 switch (prop_id)
1658 case PROP_ADDRESS:
1659 g_free (daemon->address);
1660 daemon->address = g_value_dup_string (value);
1661 break;
1663 default:
1664 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1668 static void
1669 g_dbus_daemon_get_property (GObject *object,
1670 guint prop_id,
1671 GValue *value,
1672 GParamSpec *pspec)
1674 GDBusDaemon *daemon = G_DBUS_DAEMON (object);
1676 switch (prop_id)
1678 case PROP_ADDRESS:
1679 g_value_set_string (value, daemon->address);
1680 break;
1682 default:
1683 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1687 static void
1688 g_dbus_daemon_class_init (GDBusDaemonClass *klass)
1690 GObjectClass *gobject_class;
1692 gobject_class = G_OBJECT_CLASS (klass);
1693 gobject_class->finalize = g_dbus_daemon_finalize;
1694 gobject_class->set_property = g_dbus_daemon_set_property;
1695 gobject_class->get_property = g_dbus_daemon_get_property;
1697 g_dbus_daemon_signals[SIGNAL_IDLE_TIMEOUT] =
1698 g_signal_new ("idle-timeout",
1699 G_TYPE_DBUS_DAEMON,
1700 G_SIGNAL_RUN_LAST,
1702 NULL, NULL,
1703 g_cclosure_marshal_VOID__VOID,
1704 G_TYPE_NONE, 0);
1706 g_object_class_install_property (gobject_class,
1707 PROP_ADDRESS,
1708 g_param_spec_string ("address",
1709 "Bus Address",
1710 "The address the bus should use",
1711 NULL,
1712 G_PARAM_READWRITE |
1713 G_PARAM_CONSTRUCT_ONLY |
1714 G_PARAM_STATIC_STRINGS));
1717 static void
1718 g_dbus_daemon_iface_init (_GFreedesktopDBusIface *iface)
1720 iface->handle_add_match = handle_add_match;
1721 iface->handle_get_connection_selinux_security_context = handle_get_connection_selinux_security_context;
1722 iface->handle_get_connection_unix_process_id = handle_get_connection_unix_process_id;
1723 iface->handle_get_connection_unix_user = handle_get_connection_unix_user;
1724 iface->handle_get_id = handle_get_id;
1725 iface->handle_get_name_owner = handle_get_name_owner;
1726 iface->handle_hello = handle_hello;
1727 iface->handle_list_activatable_names = handle_list_activatable_names;
1728 iface->handle_list_names = handle_list_names;
1729 iface->handle_list_queued_owners = handle_list_queued_owners;
1730 iface->handle_name_has_owner = handle_name_has_owner;
1731 iface->handle_release_name = handle_release_name;
1732 iface->handle_reload_config = handle_reload_config;
1733 iface->handle_update_activation_environment = handle_update_activation_environment;
1734 iface->handle_remove_match = handle_remove_match;
1735 iface->handle_request_name = handle_request_name;
1736 iface->handle_start_service_by_name = handle_start_service_by_name;
1739 static void
1740 initable_iface_init (GInitableIface *initable_iface)
1742 initable_iface->init = initable_init;
1745 GDBusDaemon *
1746 _g_dbus_daemon_new (const char *address,
1747 GCancellable *cancellable,
1748 GError **error)
1750 return g_initable_new (G_TYPE_DBUS_DAEMON,
1751 cancellable,
1752 error,
1753 "address", address,
1754 NULL);
1757 const char *
1758 _g_dbus_daemon_get_address (GDBusDaemon *daemon)
1760 return g_dbus_server_get_client_address (daemon->server);