1 /* GIO - GLib Input, Output and Streaming Library
3 * Copyright (C) 2013 Samsung Electronics
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General
16 * Public License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18 * Boston, MA 02111-1307, USA.
20 * Author: Michal Eljasiewicz <m.eljasiewic@samsung.com>
21 * Author: Lukasz Skalski <l.skalski@samsung.com>
26 #include "glib-unix.h"
34 #include <sys/ioctl.h>
38 #ifdef HAVE_SYS_FILIO_H
39 # include <sys/filio.h>
46 #include <glib/gstdio.h>
47 #include <glib/glib-private.h>
49 #include <gio/gunixfdlist.h>
52 #include "gunixfdmessage.h"
54 #define KDBUS_TIMEOUT_NS 2000000000LU
55 #define KDBUS_POOL_SIZE (16 * 1024LU * 1024LU)
56 #define KDBUS_ALIGN8(l) (((l) + 7) & ~7)
57 #define KDBUS_ALIGN8_PTR(p) ((void*) (uintptr_t)(p))
59 #define KDBUS_ITEM_HEADER_SIZE G_STRUCT_OFFSET(struct kdbus_item, data)
60 #define KDBUS_ITEM_SIZE(s) KDBUS_ALIGN8((s) + KDBUS_ITEM_HEADER_SIZE)
62 #define KDBUS_ITEM_NEXT(item) \
63 (typeof(item))(((guint8 *)item) + KDBUS_ALIGN8((item)->size))
64 #define KDBUS_ITEM_FOREACH(item, head, first) \
65 for (item = (head)->first; \
66 (guint8 *)(item) < (guint8 *)(head) + (head)->size; \
67 item = KDBUS_ITEM_NEXT(item))
69 #define g_alloca0(x) memset(g_alloca(x), '\0', (x))
71 struct dbus_fixed_header {
80 #define DBUS_FIXED_HEADER_TYPE ((const GVariantType *) "(yyyyut)")
81 #define DBUS_EXTENDED_HEADER_TYPE ((const GVariantType *) "a{tv}")
82 #define DBUS_MESSAGE_TYPE ((const GVariantType *) "((yyyyut)a{tv}v)")
84 #define KDBUS_MSG_MAX_SIZE 8192
90 G_BUS_CREDS_UNIQUE_NAME = 3,
91 G_BUS_CREDS_SELINUX_CONTEXT = 4
92 } GBusCredentialsFlags;
94 typedef GObjectClass GKDBusWorkerClass;
98 GObject parent_instance;
102 GMainContext *context;
111 guint64 attach_flags_send;
112 guint64 attach_flags_recv;
125 static gssize _g_kdbus_receive (GKDBusWorker *kdbus,
126 GCancellable *cancellable,
129 G_DEFINE_TYPE (GKDBusWorker, g_kdbus_worker, G_TYPE_OBJECT)
131 /* Hash keys for bloom filters*/
132 const guint8 hash_keys[8][16] =
134 {0xb9,0x66,0x0b,0xf0,0x46,0x70,0x47,0xc1,0x88,0x75,0xc4,0x9c,0x54,0xb9,0xbd,0x15},
135 {0xaa,0xa1,0x54,0xa2,0xe0,0x71,0x4b,0x39,0xbf,0xe1,0xdd,0x2e,0x9f,0xc5,0x4a,0x3b},
136 {0x63,0xfd,0xae,0xbe,0xcd,0x82,0x48,0x12,0xa1,0x6e,0x41,0x26,0xcb,0xfa,0xa0,0xc8},
137 {0x23,0xbe,0x45,0x29,0x32,0xd2,0x46,0x2d,0x82,0x03,0x52,0x28,0xfe,0x37,0x17,0xf5},
138 {0x56,0x3b,0xbf,0xee,0x5a,0x4f,0x43,0x39,0xaf,0xaa,0x94,0x08,0xdf,0xf0,0xfc,0x10},
139 {0x31,0x80,0xc8,0x73,0xc7,0xea,0x46,0xd3,0xaa,0x25,0x75,0x0f,0x9e,0x4c,0x09,0x29},
140 {0x7d,0xf7,0x18,0x4b,0x7b,0xa4,0x44,0xd5,0x85,0x3c,0x06,0xe0,0x65,0x53,0x96,0x6d},
141 {0xf2,0x77,0xe9,0x6f,0x93,0xb5,0x4e,0x71,0x9a,0x0c,0x34,0x88,0x39,0x25,0xbf,0x35}
149 g_kdbus_worker_finalize (GObject *object)
151 GKDBusWorker *kdbus = G_KDBUS_WORKER (object);
153 if (kdbus->kdbus_buffer != NULL)
154 munmap (kdbus->kdbus_buffer, KDBUS_POOL_SIZE);
156 kdbus->kdbus_buffer = NULL;
158 if (kdbus->fd != -1 && !kdbus->closed)
159 _g_kdbus_close (kdbus);
161 G_OBJECT_CLASS (g_kdbus_worker_parent_class)->finalize (object);
165 g_kdbus_worker_class_init (GKDBusWorkerClass *class)
167 class->finalize = g_kdbus_worker_finalize;
171 g_kdbus_worker_init (GKDBusWorker *kdbus)
175 kdbus->unique_id = -1;
176 kdbus->unique_name = NULL;
178 kdbus->kdbus_buffer = NULL;
180 kdbus->flags = 0; /* KDBUS_HELLO_ACCEPT_FD */
181 kdbus->attach_flags_send = _KDBUS_ATTACH_ALL;
182 kdbus->attach_flags_recv = _KDBUS_ATTACH_ALL;
186 kdbus_ready (gint fd,
187 GIOCondition condition,
190 GKDBusWorker *kdbus = user_data;
191 GError *error = NULL;
193 _g_kdbus_receive (kdbus, NULL, &error);
194 g_assert_no_error (error);
196 return G_SOURCE_CONTINUE;
200 _g_kdbus_open (GKDBusWorker *worker,
201 const gchar *address,
204 g_return_val_if_fail (G_IS_KDBUS_WORKER (worker), FALSE);
206 worker->fd = open(address, O_RDWR|O_NOCTTY|O_CLOEXEC);
209 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, _("Can't open kdbus endpoint"));
213 worker->closed = FALSE;
215 worker->context = g_main_context_ref_thread_default ();
216 worker->source = g_unix_fd_source_new (worker->fd, G_IO_IN);
217 g_source_set_callback (worker->source, (GSourceFunc) kdbus_ready, worker, NULL);
218 g_source_attach (worker->source, worker->context);
229 g_kdbus_free_data (GKDBusWorker *kdbus,
232 struct kdbus_cmd_free cmd;
238 ret = ioctl (kdbus->fd, KDBUS_CMD_FREE, &cmd);
247 * g_kdbus_translate_nameowner_flags:
251 g_kdbus_translate_nameowner_flags (GBusNameOwnerFlags flags,
252 guint64 *kdbus_flags)
258 if (flags & G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT)
259 new_flags |= KDBUS_NAME_ALLOW_REPLACEMENT;
261 if (flags & G_BUS_NAME_OWNER_FLAGS_REPLACE)
262 new_flags |= KDBUS_NAME_REPLACE_EXISTING;
264 if (!(flags & G_BUS_NAME_OWNER_FLAGS_DO_NOT_QUEUE))
265 new_flags |= KDBUS_NAME_QUEUE;
267 *kdbus_flags = new_flags;
276 _g_kdbus_close (GKDBusWorker *kdbus)
278 g_return_val_if_fail (G_IS_KDBUS_WORKER (kdbus), FALSE);
283 g_source_destroy (kdbus->source);
286 g_main_context_unref (kdbus->context);
287 kdbus->context = NULL;
292 kdbus->closed = TRUE;
296 * _g_kdbus_is_closed:
300 _g_kdbus_is_closed (GKDBusWorker *kdbus)
302 g_return_val_if_fail (G_IS_KDBUS_WORKER (kdbus), FALSE);
304 return kdbus->closed;
313 _g_kdbus_Hello (GKDBusWorker *worker,
316 struct kdbus_cmd_hello *hello;
317 struct kdbus_item *item;
320 size_t size, conn_name_size;
322 conn_name = "gdbus-kdbus";
323 conn_name_size = strlen (conn_name);
325 size = KDBUS_ALIGN8 (G_STRUCT_OFFSET (struct kdbus_cmd_hello, items)) +
326 KDBUS_ALIGN8 (G_STRUCT_OFFSET (struct kdbus_item, str) + conn_name_size + 1);
328 hello = g_alloca0 (size);
329 hello->flags = worker->flags;
330 hello->attach_flags_send = worker->attach_flags_send;
331 hello->attach_flags_recv = worker->attach_flags_recv;
333 hello->pool_size = KDBUS_POOL_SIZE;
336 item->size = G_STRUCT_OFFSET (struct kdbus_item, str) + conn_name_size + 1;
337 item->type = KDBUS_ITEM_CONN_DESCRIPTION;
338 memcpy (item->str, conn_name, conn_name_size+1);
339 item = KDBUS_ITEM_NEXT (item);
341 if (ioctl(worker->fd, KDBUS_CMD_HELLO, hello))
343 g_set_error (error, G_IO_ERROR,
344 g_io_error_from_errno (errno),
345 _("Failed to send HELLO: %s"),
350 worker->kdbus_buffer = mmap(NULL, KDBUS_POOL_SIZE, PROT_READ, MAP_SHARED, worker->fd, 0);
351 if (worker->kdbus_buffer == MAP_FAILED)
353 g_set_error (error, G_IO_ERROR,
354 g_io_error_from_errno (errno),
360 if (hello->bus_flags > 0xFFFFFFFFULL)
362 g_set_error_literal (error,
365 _("Incompatible HELLO flags"));
369 memcpy (worker->bus_id, hello->id128, 16);
371 worker->unique_id = hello->id;
372 asprintf(&worker->unique_name, ":1.%llu", (unsigned long long) hello->id);
374 /* read bloom filters parameters */
375 worker->bloom_size = (gsize) hello->bloom.size;
376 worker->bloom_n_hash = (guint) hello->bloom.n_hash;
378 return g_variant_new ("(s)", worker->unique_name);
383 * _g_kdbus_RequestName:
387 _g_kdbus_RequestName (GKDBusWorker *worker,
389 GBusNameOwnerFlags flags,
393 struct kdbus_cmd_name *kdbus_name;
398 status = G_BUS_REQUEST_NAME_FLAGS_PRIMARY_OWNER;
400 if (!g_dbus_is_name (name))
404 G_DBUS_ERROR_INVALID_ARGS,
405 "Given bus name \"%s\" is not valid", name);
413 G_DBUS_ERROR_INVALID_ARGS,
414 "Cannot acquire a service starting with ':' such as \"%s\"", name);
418 g_kdbus_translate_nameowner_flags (flags, &kdbus_flags);
420 len = strlen(name) + 1;
421 size = G_STRUCT_OFFSET (struct kdbus_cmd_name, items) + KDBUS_ITEM_SIZE(len);
422 kdbus_name = g_alloca0 (size);
423 kdbus_name->size = size;
424 kdbus_name->items[0].size = KDBUS_ITEM_HEADER_SIZE + len;
425 kdbus_name->items[0].type = KDBUS_ITEM_NAME;
426 kdbus_name->flags = kdbus_flags;
427 memcpy (kdbus_name->items[0].str, name, len);
429 ret = ioctl(worker->fd, KDBUS_CMD_NAME_ACQUIRE, kdbus_name);
433 status = G_BUS_REQUEST_NAME_FLAGS_EXISTS;
434 else if (errno == EALREADY)
435 status = G_BUS_REQUEST_NAME_FLAGS_ALREADY_OWNER;
438 g_set_error (error, G_IO_ERROR,
439 g_io_error_from_errno (errno),
440 _("Error while acquiring name: %s"),
446 if (kdbus_name->flags & KDBUS_NAME_IN_QUEUE)
447 status = G_BUS_REQUEST_NAME_FLAGS_IN_QUEUE;
449 result = g_variant_new ("(u)", status);
456 * _g_kdbus_ReleaseName:
460 _g_kdbus_ReleaseName (GKDBusWorker *worker,
465 struct kdbus_cmd_name *kdbus_name;
469 status = G_BUS_RELEASE_NAME_FLAGS_RELEASED;
471 if (!g_dbus_is_name (name))
475 G_DBUS_ERROR_INVALID_ARGS,
476 "Given bus name \"%s\" is not valid", name);
484 G_DBUS_ERROR_INVALID_ARGS,
485 "Cannot release a service starting with ':' such as \"%s\"", name);
489 len = strlen(name) + 1;
490 size = G_STRUCT_OFFSET (struct kdbus_cmd_name, items) + KDBUS_ITEM_SIZE(len);
491 kdbus_name = g_alloca0 (size);
492 kdbus_name->size = size;
493 kdbus_name->items[0].size = KDBUS_ITEM_HEADER_SIZE + len;
494 kdbus_name->items[0].type = KDBUS_ITEM_NAME;
495 memcpy (kdbus_name->items[0].str, name, len);
497 ret = ioctl(worker->fd, KDBUS_CMD_NAME_RELEASE, kdbus_name);
501 status = G_BUS_RELEASE_NAME_FLAGS_NON_EXISTENT;
502 else if (errno == EADDRINUSE)
503 status = G_BUS_RELEASE_NAME_FLAGS_NOT_OWNER;
506 g_set_error (error, G_IO_ERROR,
507 g_io_error_from_errno (errno),
508 _("Error while releasing name: %s"),
514 result = g_variant_new ("(u)", status);
525 _g_kdbus_GetBusId (GKDBusWorker *worker,
532 result_str = g_string_new (NULL);
534 for (cnt=0; cnt<16; cnt++)
535 g_string_append_printf (result_str, "%02x", worker->bus_id[cnt]);
537 result = g_variant_new ("(s)", result_str->str);
538 g_string_free (result_str, TRUE);
545 * _g_kdbus_GetListNames:
549 _g_kdbus_GetListNames (GKDBusWorker *worker,
550 guint list_name_type,
554 GVariantBuilder *builder;
556 struct kdbus_cmd_name_list cmd = {};
557 struct kdbus_name_list *name_list;
558 struct kdbus_name_info *name;
566 cmd.flags = KDBUS_NAME_LIST_ACTIVATORS; /* ListActivatableNames */
568 cmd.flags = KDBUS_NAME_LIST_UNIQUE | KDBUS_NAME_LIST_NAMES; /* ListNames */
570 ret = ioctl(worker->fd, KDBUS_CMD_NAME_LIST, &cmd);
576 _("Error listing names"));
580 name_list = (struct kdbus_name_list *) ((guint8 *) worker->kdbus_buffer + cmd.offset);
581 builder = g_variant_builder_new (G_VARIANT_TYPE ("as"));
583 KDBUS_ITEM_FOREACH(name, name_list, names)
585 struct kdbus_item *item;
586 const gchar *item_name = "";
588 if ((cmd.flags & KDBUS_NAME_LIST_UNIQUE) && name->owner_id != prev_id)
590 GString *unique_name;
592 unique_name = g_string_new (NULL);
593 g_string_printf (unique_name, ":1.%llu", name->owner_id);
594 g_variant_builder_add (builder, "s", unique_name->str);
595 g_string_free (unique_name,TRUE);
596 prev_id = name->owner_id;
599 KDBUS_ITEM_FOREACH(item, name, items)
600 if (item->type == KDBUS_ITEM_OWNED_NAME)
601 item_name = item->name.name;
603 if (g_dbus_is_name (item_name))
604 g_variant_builder_add (builder, "s", item_name);
607 result = g_variant_new ("(as)", builder);
608 g_variant_builder_unref (builder);
610 g_kdbus_free_data (worker, cmd.offset);
616 * _g_kdbus_NameHasOwner_internal:
620 g_kdbus_NameHasOwner_internal (GKDBusWorker *worker,
624 struct kdbus_cmd_info *cmd;
628 if (g_dbus_is_unique_name(name))
630 size = G_STRUCT_OFFSET (struct kdbus_cmd_info, items);
631 cmd = g_alloca0 (size);
632 cmd->id = g_ascii_strtoull (name+3, NULL, 10);
636 len = strlen(name) + 1;
637 size = G_STRUCT_OFFSET (struct kdbus_cmd_info, items) + KDBUS_ITEM_SIZE(len);
638 cmd = g_alloca0 (size);
639 cmd->items[0].size = KDBUS_ITEM_HEADER_SIZE + len;
640 cmd->items[0].type = KDBUS_ITEM_NAME;
641 memcpy (cmd->items[0].str, name, len);
645 ret = ioctl(worker->fd, KDBUS_CMD_CONN_INFO, cmd);
646 g_kdbus_free_data (worker, cmd->offset);
656 * _g_kdbus_GetListQueuedOwners:
660 _g_kdbus_GetListQueuedOwners (GKDBusWorker *worker,
665 GVariantBuilder *builder;
666 GString *unique_name;
669 struct kdbus_cmd_name_list cmd = {};
670 struct kdbus_name_list *name_list;
671 struct kdbus_name_info *kname;
673 if (!g_dbus_is_name (name))
677 G_DBUS_ERROR_INVALID_ARGS,
678 "Given bus name \"%s\" is not valid", name);
682 if (!g_kdbus_NameHasOwner_internal (worker, name, error))
686 G_DBUS_ERROR_NAME_HAS_NO_OWNER,
687 "Could not get owner of name '%s': no such name", name);
691 cmd.flags = KDBUS_NAME_LIST_QUEUED;
692 ret = ioctl(worker->fd, KDBUS_CMD_NAME_LIST, &cmd);
698 _("Error listing names"));
702 name_list = (struct kdbus_name_list *) ((guint8 *) worker->kdbus_buffer + cmd.offset);
704 unique_name = g_string_new (NULL);
705 builder = g_variant_builder_new (G_VARIANT_TYPE ("as"));
706 KDBUS_ITEM_FOREACH(kname, name_list, names)
708 struct kdbus_item *item;
709 const char *item_name = "";
711 KDBUS_ITEM_FOREACH(item, kname, items)
712 if (item->type == KDBUS_ITEM_NAME)
713 item_name = item->str;
715 if (strcmp(item_name, name))
718 g_string_printf (unique_name, ":1.%llu", kname->owner_id);
719 g_variant_builder_add (builder, "s", item_name);
722 result = g_variant_new ("(as)", builder);
723 g_variant_builder_unref (builder);
724 g_string_free (unique_name,TRUE);
726 g_kdbus_free_data (worker, cmd.offset);
732 * g_kdbus_GetConnInfo_internal:
736 g_kdbus_GetConnInfo_internal (GKDBusWorker *worker,
743 struct kdbus_cmd_info *cmd;
744 struct kdbus_info *conn_info;
745 struct kdbus_item *item;
751 if (!g_dbus_is_name (name))
755 G_DBUS_ERROR_INVALID_ARGS,
756 "Given bus name \"%s\" is not valid", name);
760 if (!g_kdbus_NameHasOwner_internal (worker, name, error))
764 G_DBUS_ERROR_NAME_HAS_NO_OWNER,
765 "Could not get owner of name '%s': no such name", name);
769 if (g_dbus_is_unique_name(name))
771 size = G_STRUCT_OFFSET (struct kdbus_cmd_info, items);
772 cmd = g_alloca0 (size);
773 cmd->id = g_ascii_strtoull (name+3, NULL, 10);
777 len = strlen(name) + 1;
778 size = G_STRUCT_OFFSET (struct kdbus_cmd_info, items) + KDBUS_ITEM_SIZE(len);
779 cmd = g_alloca0 (size);
780 cmd->items[0].size = KDBUS_ITEM_HEADER_SIZE + len;
781 cmd->items[0].type = KDBUS_ITEM_NAME;
782 memcpy (cmd->items[0].str, name, len);
785 cmd->flags = _KDBUS_ATTACH_ALL;
788 ret = ioctl(worker->fd, KDBUS_CMD_CONN_INFO, cmd);
794 _("Could not get connection info"));
798 conn_info = (struct kdbus_info *) ((guint8 *) worker->kdbus_buffer + cmd->offset);
801 if (conn_info->flags & KDBUS_HELLO_ACTIVATOR)
805 if (flag == G_BUS_CREDS_UNIQUE_NAME)
807 GString *unique_name;
809 unique_name = g_string_new (NULL);
810 g_string_printf (unique_name, ":1.%llu", (unsigned long long) conn_info->id);
811 result = g_variant_new ("(s)", unique_name->str);
812 g_string_free (unique_name,TRUE);
816 KDBUS_ITEM_FOREACH(item, conn_info, items)
820 case KDBUS_ITEM_PIDS:
822 if (flag == G_BUS_CREDS_PID)
824 guint pid = item->pids.pid;
825 result = g_variant_new ("(u)", pid);
829 case KDBUS_ITEM_CREDS:
831 if (flag == G_BUS_CREDS_UID)
833 guint uid = item->creds.uid;
834 result = g_variant_new ("(u)", uid);
838 case KDBUS_ITEM_SECLABEL:
839 case KDBUS_ITEM_PID_COMM:
840 case KDBUS_ITEM_TID_COMM:
842 case KDBUS_ITEM_CMDLINE:
843 case KDBUS_ITEM_CGROUP:
844 case KDBUS_ITEM_CAPS:
845 case KDBUS_ITEM_AUDIT:
846 case KDBUS_ITEM_CONN_DESCRIPTION:
847 case KDBUS_ITEM_AUXGROUPS:
848 case KDBUS_ITEM_OWNED_NAME:
854 g_kdbus_free_data (worker, cmd->offset);
860 * _g_kdbus_GetNameOwner:
864 _g_kdbus_GetNameOwner (GKDBusWorker *worker,
868 return g_kdbus_GetConnInfo_internal (worker,
870 G_BUS_CREDS_UNIQUE_NAME,
876 * _g_kdbus_GetConnectionUnixProcessID:
880 _g_kdbus_GetConnectionUnixProcessID (GKDBusWorker *worker,
884 return g_kdbus_GetConnInfo_internal (worker,
892 * _g_kdbus_GetConnectionUnixUser:
896 _g_kdbus_GetConnectionUnixUser (GKDBusWorker *worker,
900 return g_kdbus_GetConnInfo_internal (worker,
908 * _g_kdbus_match_remove:
912 _g_kdbus_match_remove (GKDBusWorker *worker,
915 struct kdbus_cmd_match cmd_match = {};
918 cmd_match.size = sizeof (cmd_match);
919 cmd_match.cookie = cookie;
921 ret = ioctl(worker->fd, KDBUS_CMD_MATCH_REMOVE, &cmd_match);
923 g_warning ("ERROR - %d\n", (int) errno);
928 * _g_kdbus_subscribe_name_acquired:
932 _g_kdbus_subscribe_name_owner_changed (GKDBusWorker *worker,
934 const gchar *old_name,
935 const gchar *new_name,
938 struct kdbus_item *item;
939 struct kdbus_cmd_match *cmd_match;
942 guint64 old_id = 0; /* XXX why? */
943 guint64 new_id = KDBUS_MATCH_ID_ANY;
945 len = strlen(name) + 1;
946 size = KDBUS_ALIGN8(G_STRUCT_OFFSET (struct kdbus_cmd_match, items) +
947 G_STRUCT_OFFSET (struct kdbus_item, name_change) +
948 G_STRUCT_OFFSET (struct kdbus_notify_name_change, name) + len);
950 cmd_match = g_alloca0 (size);
951 cmd_match->size = size;
952 cmd_match->cookie = cookie;
953 item = cmd_match->items;
955 if (old_name[0] == 0)
957 old_id = KDBUS_MATCH_ID_ANY;
961 if (g_dbus_is_unique_name(old_name))
967 if (new_name[0] == 0)
969 new_id = KDBUS_MATCH_ID_ANY;
973 if (g_dbus_is_unique_name(new_name))
979 cmd_match = g_alloca0 (size);
980 cmd_match->size = size;
981 cmd_match->cookie = cookie;
982 item = cmd_match->items;
984 /* KDBUS_ITEM_NAME_CHANGE */
985 item->type = KDBUS_ITEM_NAME_CHANGE;
986 item->name_change.old_id.id = old_id;
987 item->name_change.new_id.id = new_id;
988 memcpy(item->name_change.name, name, len);
989 item->size = G_STRUCT_OFFSET (struct kdbus_item, name_change) +
990 G_STRUCT_OFFSET(struct kdbus_notify_name_change, name) + len;
991 item = KDBUS_ITEM_NEXT(item);
993 ret = ioctl(worker->fd, KDBUS_CMD_MATCH_ADD, cmd_match);
995 g_warning ("ERROR - %d\n", (int) errno);
1000 * _g_kdbus_subscribe_name_acquired:
1004 _g_kdbus_subscribe_name_acquired (GKDBusWorker *worker,
1007 struct kdbus_item *item;
1008 struct kdbus_cmd_match *cmd_match;
1013 len = strlen(name) + 1;
1014 size = KDBUS_ALIGN8(G_STRUCT_OFFSET (struct kdbus_cmd_match, items) +
1015 G_STRUCT_OFFSET (struct kdbus_item, name_change) +
1016 G_STRUCT_OFFSET (struct kdbus_notify_name_change, name) + len);
1018 cookie = 0xbeefbeefbeefbeef;
1019 cmd_match = g_alloca0 (size);
1020 cmd_match->size = size;
1021 cmd_match->cookie = cookie;
1022 item = cmd_match->items;
1024 /* KDBUS_ITEM_NAME_ADD */
1025 item->type = KDBUS_ITEM_NAME_ADD;
1026 item->name_change.old_id.id = KDBUS_MATCH_ID_ANY;
1027 item->name_change.new_id.id = worker->unique_id;
1028 memcpy(item->name_change.name, name, len);
1029 item->size = G_STRUCT_OFFSET (struct kdbus_item, name_change) +
1030 G_STRUCT_OFFSET(struct kdbus_notify_name_change, name) + len;
1031 item = KDBUS_ITEM_NEXT(item);
1033 ret = ioctl(worker->fd, KDBUS_CMD_MATCH_ADD, cmd_match);
1035 g_warning ("ERROR - %d\n", (int) errno);
1037 _g_kdbus_subscribe_name_owner_changed (worker, name, "", worker->unique_name, cookie);
1042 * _g_kdbus_subscribe_name_lost:
1046 _g_kdbus_subscribe_name_lost (GKDBusWorker *worker,
1049 struct kdbus_item *item;
1050 struct kdbus_cmd_match *cmd_match;
1055 len = strlen(name) + 1;
1056 size = KDBUS_ALIGN8(G_STRUCT_OFFSET (struct kdbus_cmd_match, items) +
1057 G_STRUCT_OFFSET (struct kdbus_item, name_change) +
1058 G_STRUCT_OFFSET (struct kdbus_notify_name_change, name) + len);
1060 cookie = 0xdeafdeafdeafdeaf;
1061 cmd_match = g_alloca0 (size);
1062 cmd_match->size = size;
1063 cmd_match->cookie = cookie;
1064 item = cmd_match->items;
1066 /* KDBUS_ITEM_NAME_REMOVE */
1067 item->type = KDBUS_ITEM_NAME_REMOVE;
1068 item->name_change.old_id.id = worker->unique_id;
1069 item->name_change.new_id.id = KDBUS_MATCH_ID_ANY;
1070 memcpy(item->name_change.name, name, len);
1071 item->size = G_STRUCT_OFFSET (struct kdbus_item, name_change) +
1072 G_STRUCT_OFFSET(struct kdbus_notify_name_change, name) + len;
1073 item = KDBUS_ITEM_NEXT(item);
1075 ret = ioctl(worker->fd, KDBUS_CMD_MATCH_ADD, cmd_match);
1077 g_warning ("ERROR - %d\n", (int) errno);
1079 _g_kdbus_subscribe_name_owner_changed (worker, name, worker->unique_name, "", cookie);
1084 * _g_kdbus_unsubscribe_name_acquired:
1088 _g_kdbus_unsubscribe_name_acquired (GKDBusWorker *worker)
1092 cookie = 0xbeefbeefbeefbeef;
1093 _g_kdbus_match_remove (worker, cookie);
1098 * _g_kdbus_unsubscribe_name_lost:
1102 _g_kdbus_unsubscribe_name_lost (GKDBusWorker *worker)
1106 cookie = 0xdeafdeafdeafdeaf;
1107 _g_kdbus_match_remove (worker, cookie);
1112 * g_kdbus_append_payload_bloom:
1115 static struct kdbus_bloom_filter *
1116 g_kdbus_append_bloom (struct kdbus_item **item,
1119 struct kdbus_item *bloom_item;
1121 bloom_item = KDBUS_ALIGN8_PTR(*item);
1122 bloom_item->size = G_STRUCT_OFFSET (struct kdbus_item, bloom_filter) +
1123 G_STRUCT_OFFSET (struct kdbus_bloom_filter, data) +
1126 bloom_item->type = KDBUS_ITEM_BLOOM_FILTER;
1128 *item = KDBUS_ITEM_NEXT(bloom_item);
1129 return &bloom_item->bloom_filter;
1134 * g_kdbus_bloom_add_data:
1135 * Based on bus-bloom.c from systemd
1136 * http://cgit.freedesktop.org/systemd/systemd/tree/src/libsystemd/sd-bus/bus-bloom.c
1139 g_kdbus_bloom_add_data (GKDBusWorker *worker,
1140 guint64 bloom_data [],
1146 guint bytes_num = 0;
1152 bit_num = worker->bloom_size * 8;
1155 bytes_num = ((__builtin_clzll(bit_num) ^ 63U) + 7) / 8;
1157 for (cnt_1 = 0; cnt_1 < (worker->bloom_n_hash); cnt_1++)
1159 for (cnt_2 = 0; cnt_2 < bytes_num; cnt_2++)
1163 g_siphash24(hash, data, n, hash_keys[cnt_1++]);
1167 p = (p << 8ULL) | (guint64) hash[8 - c];
1172 bloom_data[p >> 6] |= 1ULL << (p & 63);
1178 * g_kdbus_bloom_add_pair:
1182 g_kdbus_bloom_add_pair (GKDBusWorker *worker,
1183 guint64 bloom_data [],
1184 const gchar *parameter,
1187 GString *data = g_string_new (NULL);
1189 g_string_printf (data,"%s:%s",parameter,value);
1190 g_kdbus_bloom_add_data(worker, bloom_data, data->str, data->len);
1191 g_string_free (data, TRUE);
1196 * g_kdbus_bloom_add_prefixes:
1200 g_kdbus_bloom_add_prefixes (GKDBusWorker *worker,
1201 guint64 bloom_data [],
1202 const gchar *parameter,
1206 GString *data = g_string_new (NULL);
1208 g_string_printf (data,"%s:%s",parameter,value);
1213 last_sep = strrchr(data->str, separator);
1214 if (!last_sep || last_sep == data->str)
1218 g_kdbus_bloom_add_data(worker, bloom_data, data->str, last_sep-(data->str));
1220 g_string_free (data, TRUE);
1225 * g_kdbus_setup_bloom:
1226 * Based on bus-bloom.c from systemd
1227 * http://cgit.freedesktop.org/systemd/systemd/tree/src/libsystemd/sd-bus/bus-bloom.c
1230 g_kdbus_setup_bloom (GKDBusWorker *worker,
1231 GDBusMessage *dbus_msg,
1232 struct kdbus_bloom_filter *bloom_filter)
1236 const gchar *message_type;
1237 const gchar *interface;
1238 const gchar *member;
1243 body = g_dbus_message_get_body (dbus_msg);
1244 message_type = _g_dbus_enum_to_string (G_TYPE_DBUS_MESSAGE_TYPE, g_dbus_message_get_message_type (dbus_msg));
1245 interface = g_dbus_message_get_interface (dbus_msg);
1246 member = g_dbus_message_get_member (dbus_msg);
1247 path = g_dbus_message_get_path (dbus_msg);
1249 bloom_data = bloom_filter->data;
1250 memset (bloom_data, 0, worker->bloom_size);
1251 bloom_filter->generation = 0;
1253 g_kdbus_bloom_add_pair(worker, bloom_data, "message-type", message_type);
1256 g_kdbus_bloom_add_pair(worker, bloom_data, "interface", interface);
1259 g_kdbus_bloom_add_pair(worker, bloom_data, "member", member);
1263 g_kdbus_bloom_add_pair(worker, bloom_data, "path", path);
1264 g_kdbus_bloom_add_pair(worker, bloom_data, "path-slash-prefix", path);
1265 g_kdbus_bloom_add_prefixes(worker, bloom_data, "path-slash-prefix", path, '/');
1270 const GVariantType *body_type;
1271 const GVariantType *arg_type;
1274 body_type = g_variant_get_type (body);
1276 for (arg_type = g_variant_type_first (body_type), cnt = 0;
1278 arg_type = g_variant_type_next (arg_type), cnt++)
1280 gchar type_char = g_variant_type_peek_string (arg_type)[0];
1281 gchar buf[sizeof("arg")-1 + 2 + sizeof("-slash-prefix")];
1286 if (type_char != 's' && type_char != 'o')
1287 /* XXX: kdbus docs say "stop after first non-string" but I
1288 * think they're wrong (vs. dbus-1 compat)...
1292 child = g_variant_get_child_value (body, cnt);
1293 str = g_variant_get_string (child, NULL);
1295 e = stpcpy(buf, "arg");
1297 *(e++) = '0' + (char) cnt;
1300 *(e++) = '0' + (char) (cnt / 10);
1301 *(e++) = '0' + (char) (cnt % 10);
1304 /* We add this one for both strings and object paths */
1305 strcpy(e, "-slash-prefix");
1306 g_kdbus_bloom_add_prefixes(worker, bloom_data, buf, str, '/');
1308 /* But the others are only for strings */
1309 if (type_char == 's')
1311 strcpy(e, "-dot-prefix");
1312 g_kdbus_bloom_add_prefixes(worker, bloom_data, buf, str, '.');
1315 g_kdbus_bloom_add_pair(worker, bloom_data, buf, str);
1318 g_variant_unref (child);
1325 * TODO: g_kdbus_NameOwnerChanged_generate, g_kdbus_KernelMethodError_generate
1329 * g_kdbus_decode_kernel_msg:
1333 g_kdbus_decode_kernel_msg (GKDBusWorker *worker,
1334 struct kdbus_msg *msg)
1336 struct kdbus_item *item = NULL;
1338 KDBUS_ITEM_FOREACH(item, msg, items)
1342 case KDBUS_ITEM_ID_ADD:
1343 case KDBUS_ITEM_ID_REMOVE:
1344 case KDBUS_ITEM_NAME_ADD:
1345 case KDBUS_ITEM_NAME_REMOVE:
1346 case KDBUS_ITEM_NAME_CHANGE:
1347 //size = g_kdbus_NameOwnerChanged_generate (worker, item);
1348 g_error ("'NameOwnerChanged'");
1351 case KDBUS_ITEM_REPLY_TIMEOUT:
1352 case KDBUS_ITEM_REPLY_DEAD:
1353 //size = g_kdbus_KernelMethodError_generate (worker, item);
1354 g_error ("'KernelMethodError'");
1358 g_warning ("Unknown field in kernel message - %lld", item->type);
1363 /* Override information from the user header with data from the kernel */
1364 g_string_printf (worker->msg_sender, "org.freedesktop.DBus");
1366 /* for destination */
1367 if (worker->kmsg->dst_id == KDBUS_DST_ID_BROADCAST)
1368 /* for broadcast messages we don't have to set destination */
1370 else if (worker->kmsg->dst_id == KDBUS_DST_ID_NAME)
1371 g_string_printf (worker->msg_destination, ":1.%" G_GUINT64_FORMAT, (guint64) worker->unique_id);
1373 g_string_printf (worker->msg_destination, ":1.%" G_GUINT64_FORMAT, (guint64) worker->kmsg->dst_id);
1381 * g_kdbus_decode_dbus_msg:
1384 static GDBusMessage *
1385 g_kdbus_decode_dbus_msg (GKDBusWorker *worker,
1386 struct kdbus_msg *msg)
1388 GDBusMessage *message;
1389 struct kdbus_item *item;
1390 gssize data_size = 0;
1391 GArray *body_vectors;
1397 GVariantIter *fields_iter;
1398 guint8 endianness, type, flags, version;
1404 message = g_dbus_message_new ();
1406 body_vectors = g_array_new (FALSE, FALSE, sizeof (GVariantVector));
1408 tmp = g_strdup_printf (":1.%"G_GUINT64_FORMAT, (guint64) msg->src_id);
1409 g_dbus_message_set_sender (message, tmp);
1415 KDBUS_ITEM_FOREACH(item, msg, items)
1417 if (item->size <= KDBUS_ITEM_HEADER_SIZE)
1418 g_error("[KDBUS] %llu bytes - invalid data record\n", item->size);
1420 data_size = item->size - KDBUS_ITEM_HEADER_SIZE;
1424 /* KDBUS_ITEM_DST_NAME */
1425 case KDBUS_ITEM_DST_NAME:
1426 /* Classic D-Bus doesn't make this known to the receiver, so
1427 * we don't do it here either (for compatibility with the
1432 /* KDBUS_ITEM_PALOAD_OFF */
1433 case KDBUS_ITEM_PAYLOAD_OFF:
1435 GVariantVector vector;
1438 /* We want to make sure the bytes are aligned the same as
1439 * they would be if they appeared in a contiguously
1440 * allocated chunk of aligned memory.
1442 * We decide what the alignment 'should' be by consulting
1443 * body_size, which has been tracking the total size of the
1444 * message up to this point.
1446 * We then play around with the pointer by removing as many
1447 * bytes as required to get it to the proper alignment (and
1448 * copy extra bytes accordingly). This means that we will
1449 * grab some extra data in the 'bytes', but it won't be
1450 * shared with GVariant (which means there is no chance of
1451 * it being accidentally retransmitted).
1453 * The kernel does the same thing, so make sure we get the
1454 * expected result. Because of the kernel doing the same,
1455 * the result is that we will always be rounding-down to a
1456 * multiple of 8 for the pointer, which means that the
1457 * pointer will always be valid, assuming the original
1460 * We could fix this with a new GBytes constructor that took
1461 * 'flavour' as a parameter, but it's not worth it...
1463 flavour = body_size & 7;
1464 g_assert ((item->vec.offset & 7) == flavour);
1466 vector.gbytes = g_bytes_new (((guchar *) worker->kdbus_buffer) + item->vec.offset - flavour, item->vec.size + flavour);
1467 vector.data.pointer = g_bytes_get_data (vector.gbytes, NULL);
1468 vector.data.pointer += flavour;
1469 vector.size = item->vec.size;
1471 g_array_append_val (body_vectors, vector);
1472 body_size += vector.size;
1476 /* KDBUS_ITEM_PAYLOAD_MEMFD */
1477 case KDBUS_ITEM_PAYLOAD_MEMFD:
1479 GVariantVector vector;
1483 vector.gbytes = g_bytes_new_take_zero_copy_fd (item->memfd.fd);
1484 data = g_bytes_get_data (vector.gbytes, &size);
1486 g_assert (item->memfd.start + item->memfd.size <= size);
1488 vector.data.pointer = data + item->memfd.start;
1489 vector.size = item->memfd.size;
1491 g_array_append_val (body_vectors, vector);
1492 body_size += vector.size;
1496 /* KDBUS_ITEM_FDS */
1497 case KDBUS_ITEM_FDS:
1499 GUnixFDList *fd_list;
1501 fd_list = g_unix_fd_list_new_from_array (item->fds, data_size / sizeof (int));
1502 g_dbus_message_set_unix_fd_list (message, fd_list);
1503 g_object_unref (fd_list);
1507 /* All of the following items, like CMDLINE,
1508 CGROUP, etc. need some GDBUS API extensions and
1509 should be implemented in the future */
1510 case KDBUS_ITEM_TIMESTAMP:
1512 g_print ("time: seq %llu mon %llu real %llu\n",
1513 item->timestamp.seqnum, item->timestamp.monotonic_ns, item->timestamp.realtime_ns);
1514 //g_dbus_message_set_timestamp (message, item->timestamp.monotonic_ns / 1000);
1515 //g_dbus_message_set_serial (message, item->timestamp.seqnum);
1519 case KDBUS_ITEM_CREDS:
1521 g_print ("creds: u%u eu %u su%u fsu%u g%u eg%u sg%u fsg%u\n",
1522 item->creds.uid, item->creds.euid, item->creds.suid, item->creds.fsuid,
1523 item->creds.gid, item->creds.egid, item->creds.sgid, item->creds.fsgid);
1527 case KDBUS_ITEM_PIDS:
1528 case KDBUS_ITEM_PID_COMM:
1529 case KDBUS_ITEM_TID_COMM:
1530 case KDBUS_ITEM_EXE:
1531 case KDBUS_ITEM_CMDLINE:
1532 case KDBUS_ITEM_CGROUP:
1533 case KDBUS_ITEM_AUDIT:
1534 case KDBUS_ITEM_CAPS:
1535 case KDBUS_ITEM_SECLABEL:
1536 case KDBUS_ITEM_CONN_DESCRIPTION:
1537 case KDBUS_ITEM_AUXGROUPS:
1538 case KDBUS_ITEM_OWNED_NAME:
1539 case KDBUS_ITEM_NAME:
1540 g_print ("unhandled %04x\n", (int) item->type);
1544 g_error ("[KDBUS] DBUS_PAYLOAD: Unknown filed - %lld", item->type);
1549 body = GLIB_PRIVATE_CALL(g_variant_from_vectors) (G_VARIANT_TYPE ("((yyyyuta{tv})v)"),
1550 (GVariantVector *) body_vectors->data,
1551 body_vectors->len, body_size, FALSE);
1554 for (i = 0; i < body_vectors->len; i++)
1555 g_bytes_unref (g_array_index (body_vectors, GVariantVector, i).gbytes);
1557 g_array_free (body_vectors, TRUE);
1559 parts[0] = g_variant_get_child_value (body, 0);
1560 parts[1] = g_variant_get_child_value (body, 1);
1561 g_variant_unref (body);
1563 body = g_variant_get_variant (parts[1]);
1564 g_variant_unref (parts[1]);
1565 g_dbus_message_set_body (message, body);
1566 g_variant_unref (body);
1568 g_variant_get (parts[0], "(yyyyuta{tv})", &endianness, &type, &flags, &version, NULL, &serial, &fields_iter);
1569 g_variant_unref (parts[0]);
1571 while (g_variant_iter_loop (fields_iter, "{tv}", &key, &value))
1572 g_dbus_message_set_header (message, key, value);
1574 g_dbus_message_set_flags (message, flags);
1575 g_dbus_message_set_serial (message, serial);
1576 g_dbus_message_set_message_type (message, type);
1578 g_print ("Received:\n%s\n", g_dbus_message_print (message, 2));
1589 _g_kdbus_receive (GKDBusWorker *kdbus,
1590 GCancellable *cancellable,
1593 struct kdbus_cmd_recv recv;
1594 struct kdbus_msg *msg;
1596 memset (&recv, 0, sizeof recv);
1597 recv.size = sizeof (recv);
1599 if (g_cancellable_set_error_if_cancelled (cancellable, error))
1603 if (ioctl(kdbus->fd, KDBUS_CMD_RECV, &recv) < 0)
1608 if (errno == EAGAIN)
1611 g_set_error (error, G_IO_ERROR,
1612 g_io_error_from_errno (errno),
1613 _("Error while receiving message: %s"),
1614 g_strerror (errno));
1618 msg = (struct kdbus_msg *)((guint8 *)kdbus->kdbus_buffer + recv.reply.offset);
1620 if (msg->payload_type == KDBUS_PAYLOAD_DBUS)
1621 g_kdbus_decode_dbus_msg (kdbus, msg);
1622 else if (msg->payload_type == KDBUS_PAYLOAD_KERNEL)
1623 g_kdbus_decode_kernel_msg (kdbus, msg);
1628 G_DBUS_ERROR_FAILED,
1629 _("Received unknown payload type"));
1633 ioctl(kdbus->fd, KDBUS_CMD_FREE, &recv.reply.offset);
1639 g_kdbus_msg_append_item (struct kdbus_msg *msg,
1644 struct kdbus_item *item;
1647 item_size = size + G_STRUCT_OFFSET(struct kdbus_item, data);
1649 if (msg->size + item_size > KDBUS_MSG_MAX_SIZE)
1653 msg->size += (-msg->size) & 7;
1654 item = (struct kdbus_item *) ((guchar *) msg + msg->size);
1656 item->size = item_size;
1657 memcpy (item->data, data, size);
1659 msg->size += item_size;
1665 g_kdbus_msg_append_payload_vec (struct kdbus_msg *msg,
1669 struct kdbus_vec vec = {
1671 .address = (gsize) data
1674 return g_kdbus_msg_append_item (msg, KDBUS_ITEM_PAYLOAD_VEC, &vec, sizeof vec);
1678 g_kdbus_msg_append_payload_memfd (struct kdbus_msg *msg,
1683 struct kdbus_memfd mfd = {
1689 return g_kdbus_msg_append_item (msg, KDBUS_ITEM_PAYLOAD_MEMFD, &mfd, sizeof mfd);
1693 #include "dbusheader.h"
1695 void dump_header (gconstpointer data, gsize size) ;
1697 dump_header (gconstpointer data,
1700 GDBusMessageHeaderFieldsIterator iter;
1701 GDBusMessageHeader header;
1703 header = g_dbus_message_header_new (data, size);
1704 g_print ("header e/%c t/%u f/x%x v/%u s/%"G_GUINT64_FORMAT"\n",
1705 g_dbus_message_header_get_endian (header),
1706 g_dbus_message_header_get_type (header),
1707 g_dbus_message_header_get_flags (header),
1708 g_dbus_message_header_get_version (header),
1709 g_dbus_message_header_get_serial (header));
1711 iter = g_dbus_message_header_iterate_fields (header);
1713 while (g_dbus_message_header_fields_iterator_next (&iter))
1715 const gchar *string;
1719 key = g_dbus_message_header_fields_iterator_get_key (iter);
1723 case G_DBUS_MESSAGE_HEADER_FIELD_PATH:
1724 if (g_dbus_message_header_fields_iterator_get_value_as_object_path (iter, &string))
1725 g_print (" path: %s\n", string);
1727 g_print (" path: <<invalid string>>\n");
1730 case G_DBUS_MESSAGE_HEADER_FIELD_INTERFACE:
1731 if (g_dbus_message_header_fields_iterator_get_value_as_string (iter, &string))
1732 g_print (" interface: %s\n", string);
1734 g_print (" interface: <<invalid string>>\n");
1737 case G_DBUS_MESSAGE_HEADER_FIELD_MEMBER:
1738 if (g_dbus_message_header_fields_iterator_get_value_as_string (iter, &string))
1739 g_print (" member: %s\n", string);
1741 g_print (" member: <<invalid string>>\n");
1744 case G_DBUS_MESSAGE_HEADER_FIELD_ERROR_NAME:
1745 if (g_dbus_message_header_fields_iterator_get_value_as_string (iter, &string))
1746 g_print (" error: %s\n", string);
1748 g_print (" error: <<invalid string>>\n");
1751 case G_DBUS_MESSAGE_HEADER_FIELD_REPLY_SERIAL:
1752 if (g_dbus_message_header_fields_iterator_get_value_as_string (iter, &string))
1753 g_print (" serial: %s\n", string);
1755 g_print (" serial: <<invalid string>>\n");
1758 case G_DBUS_MESSAGE_HEADER_FIELD_DESTINATION:
1759 if (g_dbus_message_header_fields_iterator_get_value_as_string (iter, &string))
1760 g_print (" destination: %s\n", string);
1762 g_print (" destination: <<invalid string>>\n");
1765 case G_DBUS_MESSAGE_HEADER_FIELD_SENDER:
1766 if (g_dbus_message_header_fields_iterator_get_value_as_string (iter, &string))
1767 g_print (" sender: %s\n", string);
1769 g_print (" sender: <<invalid string>>\n");
1773 g_print ("unknown field code %"G_GUINT64_FORMAT"\n", key);
1774 g_assert_not_reached ();
1785 * Returns: size of data sent or -1 when error
1788 _g_kdbus_send (GKDBusWorker *kdbus,
1789 GDBusMessage *message,
1792 struct kdbus_msg *msg = alloca (KDBUS_MSG_MAX_SIZE);
1793 GVariantVectors body_vectors;
1794 struct kdbus_cmd_send send;
1796 g_return_val_if_fail (G_IS_KDBUS_WORKER (kdbus), -1);
1798 /* fill in as we go... */
1799 memset (msg, 0, sizeof (struct kdbus_msg));
1800 msg->size = sizeof (struct kdbus_msg);
1801 msg->payload_type = KDBUS_PAYLOAD_DBUS;
1802 msg->src_id = kdbus->unique_id;
1803 msg->cookie = g_dbus_message_get_serial(message);
1805 /* Message destination */
1807 const gchar *dst_name;
1809 dst_name = g_dbus_message_get_destination (message);
1811 if (dst_name != NULL)
1813 if (g_dbus_is_unique_name (dst_name))
1815 if (dst_name[1] != '1' || dst_name[2] != '.')
1817 g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_NAME_HAS_NO_OWNER,
1818 "Invalid unique D-Bus name '%s'", dst_name);
1822 /* We already know that it passes the checks for unique
1823 * names, so no need to perform error checking on strtoull.
1825 msg->dst_id = strtoull (dst_name + 3, NULL, 10);
1830 g_kdbus_msg_append_item (msg, KDBUS_ITEM_DST_NAME, dst_name, strlen (dst_name) + 1);
1831 msg->dst_id = KDBUS_DST_ID_NAME;
1835 msg->dst_id = KDBUS_DST_ID_BROADCAST;
1838 /* File descriptors */
1840 GUnixFDList *fd_list;
1842 fd_list = g_dbus_message_get_unix_fd_list (message);
1844 if (fd_list != NULL)
1849 fds = g_unix_fd_list_peek_fds (fd_list, &n_fds);
1852 g_kdbus_msg_append_item (msg, KDBUS_ITEM_FDS, fds, sizeof (gint) * n_fds);
1858 struct dbus_fixed_header fh;
1859 GHashTableIter header_iter;
1860 GVariantBuilder builder;
1861 gpointer key, value;
1865 fh.endian = (G_BYTE_ORDER == G_LITTLE_ENDIAN) ? 'l': 'B';
1866 fh.type = g_dbus_message_get_message_type (message);
1867 fh.flags = g_dbus_message_get_flags (message);
1870 fh.serial = g_dbus_message_get_serial (message);
1871 parts[0] = g_variant_new_from_data (DBUS_FIXED_HEADER_TYPE, &fh, sizeof fh, TRUE, NULL, NULL);
1873 g_dbus_message_init_header_iter (message, &header_iter);
1874 g_variant_builder_init (&builder, DBUS_EXTENDED_HEADER_TYPE);
1876 /* We set the sender field to the correct value for ourselves */
1877 g_variant_builder_add (&builder, "{tv}",
1878 (guint64) G_DBUS_MESSAGE_HEADER_FIELD_SENDER,
1879 g_variant_new_printf (":1.%"G_GUINT64_FORMAT, kdbus->unique_id));
1881 while (g_hash_table_iter_next (&header_iter, &key, &value))
1883 guint64 key_int = (gsize) key;
1887 /* These are the normal header fields that get passed
1890 case G_DBUS_MESSAGE_HEADER_FIELD_PATH:
1891 case G_DBUS_MESSAGE_HEADER_FIELD_INTERFACE:
1892 case G_DBUS_MESSAGE_HEADER_FIELD_MEMBER:
1893 case G_DBUS_MESSAGE_HEADER_FIELD_ERROR_NAME:
1894 case G_DBUS_MESSAGE_HEADER_FIELD_REPLY_SERIAL:
1895 case G_DBUS_MESSAGE_HEADER_FIELD_DESTINATION:
1896 g_variant_builder_add (&builder, "{tv}", key_int, value);
1897 /* This is a little bit gross.
1899 * We must send the header part of the message in a single
1900 * vector as per kdbus rules, but the GVariant serialiser
1901 * code will split any item >= 128 bytes into its own
1902 * vector to save the copy.
1904 * No header field should be that big anyway... right?
1906 g_assert_cmpint (g_variant_get_size (value), <, 128);
1909 /* We send this one unconditionally, but set it ourselves */
1910 case G_DBUS_MESSAGE_HEADER_FIELD_SENDER:
1913 /* We don't send these at all in GVariant format */
1914 case G_DBUS_MESSAGE_HEADER_FIELD_SIGNATURE:
1915 case G_DBUS_MESSAGE_HEADER_FIELD_NUM_UNIX_FDS:
1919 g_assert_not_reached ();
1922 parts[1] = g_variant_builder_end (&builder);
1924 body = g_dbus_message_get_body (message);
1926 body = g_variant_new ("()");
1927 parts[2] = g_variant_new_variant (body);
1929 body = g_variant_ref_sink (g_variant_new_tuple (parts, G_N_ELEMENTS (parts)));
1930 GLIB_PRIVATE_CALL(g_variant_to_vectors) (body, &body_vectors);
1932 /* Sanity check to make sure the header is really contiguous:
1934 * - we must have at least one vector in the output
1935 * - the first vector must completely contain at least the header
1937 g_assert_cmpint (body_vectors.vectors->len, >, 0);
1938 g_assert_cmpint (g_array_index (body_vectors.vectors, GVariantVector, 0).size, >=,
1939 g_variant_get_size (parts[0]) + g_variant_get_size (parts[1]));
1941 g_variant_unref (body);
1947 for (i = 0; i < body_vectors.vectors->len; i++)
1949 GVariantVector vector = g_array_index (body_vectors.vectors, GVariantVector, i);
1955 fd = g_bytes_get_zero_copy_fd (vector.gbytes);
1959 const guchar *bytes_data;
1962 bytes_data = g_bytes_get_data (vector.gbytes, &bytes_size);
1964 if (bytes_data <= vector.data.pointer && vector.data.pointer + vector.size <= bytes_data + bytes_size)
1966 if (!g_kdbus_msg_append_payload_memfd (msg, fd, vector.data.pointer - bytes_data, vector.size))
1971 if (!g_kdbus_msg_append_payload_vec (msg, vector.data.pointer, vector.size))
1977 if (!g_kdbus_msg_append_payload_vec (msg, vector.data.pointer, vector.size))
1982 if (!g_kdbus_msg_append_payload_vec (msg, body_vectors.extra_bytes->data + vector.data.offset, vector.size))
1990 msg->flags = ((g_dbus_message_get_flags (message) & G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED) ? 0 : KDBUS_MSG_EXPECT_REPLY) |
1991 ((g_dbus_message_get_flags (message) & G_DBUS_MESSAGE_FLAGS_NO_AUTO_START) ? KDBUS_MSG_NO_AUTO_START : 0);
1993 if ((msg->flags) & KDBUS_MSG_EXPECT_REPLY)
1994 msg->timeout_ns = 1000LU * g_get_monotonic_time() + KDBUS_TIMEOUT_NS;
1996 msg->cookie_reply = g_dbus_message_get_reply_serial(message);
2000 if (dst_id == KDBUS_DST_ID_BROADCAST)
2002 struct kdbus_bloom_filter *bloom_filter;
2004 bloom_filter = g_kdbus_append_bloom (&item, kdbus->bloom_size);
2005 g_kdbus_setup_bloom (kdbus, message, bloom_filter);
2009 send.size = sizeof (send);
2011 send.msg_address = (gsize) msg;
2017 if (ioctl(kdbus->fd, KDBUS_CMD_SEND, &send))
2020 GString *error_name;
2021 error_name = g_string_new (NULL);
2025 g_string_free (error_name,TRUE);
2028 else if (errno == ENXIO)
2030 g_string_printf (error_name, "Name %s does not exist", g_dbus_message_get_destination(dbus_msg));
2031 g_kdbus_generate_local_error (worker,
2033 g_variant_new ("(s)",error_name->str),
2034 G_DBUS_ERROR_SERVICE_UNKNOWN);
2035 g_string_free (error_name,TRUE);
2038 else if ((errno == ESRCH) || (errno == EADDRNOTAVAIL))
2040 if (kmsg->flags & KDBUS_MSG_FLAGS_NO_AUTO_START)
2042 g_string_printf (error_name, "Name %s does not exist", g_dbus_message_get_destination(dbus_msg));
2043 g_kdbus_generate_local_error (worker,
2045 g_variant_new ("(s)",error_name->str),
2046 G_DBUS_ERROR_SERVICE_UNKNOWN);
2047 g_string_free (error_name,TRUE);
2052 g_string_printf (error_name, "The name %s was not provided by any .service files", g_dbus_message_get_destination(dbus_msg));
2053 g_kdbus_generate_local_error (worker,
2055 g_variant_new ("(s)",error_name->str),
2056 G_DBUS_ERROR_SERVICE_UNKNOWN);
2057 g_string_free (error_name,TRUE);
2062 g_print ("[KDBUS] ioctl error sending kdbus message:%d (%m)\n",errno);
2063 g_set_error (error, G_IO_ERROR, g_io_error_from_errno(errno), _("Error sending message - KDBUS_CMD_MSG_SEND error"));
2065 perror("ioctl send");
2066 g_error ("IOCTL SEND: %d\n",errno);
2073 /* We end up here if:
2074 * - too many kdbus_items
2075 * - too large kdbus_msg size
2076 * - too much vector data
2078 * We need to compact the message before sending it.
2080 g_assert_not_reached ();
2084 g_kdbus_worker_new (const gchar *address,
2087 GDBusCapabilityFlags capabilities,
2088 gboolean initially_frozen,
2089 GDBusWorkerMessageReceivedCallback message_received_callback,
2090 GDBusWorkerMessageAboutToBeSentCallback message_about_to_be_sent_callback,
2091 GDBusWorkerDisconnectedCallback disconnected_callback,
2095 GKDBusWorker *worker;
2097 worker = g_object_new (G_TYPE_KDBUS_WORKER, NULL);
2098 if (!_g_kdbus_open (worker, address, error))
2100 g_object_unref (worker);
2108 g_kdbus_worker_unfreeze (GKDBusWorker *worker)
2113 g_kdbus_worker_send_message (GKDBusWorker *worker,
2114 GDBusMessage *message,
2117 return _g_kdbus_send (worker, message, error);
2121 g_kdbus_worker_stop (GKDBusWorker *worker)
2126 g_kdbus_worker_flush_sync (GKDBusWorker *worker)
2131 g_kdbus_worker_close (GKDBusWorker *worker,
2132 GCancellable *cancellable,
2133 GSimpleAsyncResult *result)