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"
29 #include "gkdbusconnection.h"
35 #include <sys/ioctl.h>
39 #ifdef HAVE_SYS_FILIO_H
40 # include <sys/filio.h>
47 #include <glib/gstdio.h>
48 #include <glib/glib-private.h>
50 #include <gio/gunixfdlist.h>
53 #include "gunixfdmessage.h"
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 static void g_kdbus_initable_iface_init (GInitableIface *iface);
72 static gboolean g_kdbus_initable_init (GInitable *initable,
73 GCancellable *cancellable,
76 #define g_kdbus_get_type _g_kdbus_get_type
77 G_DEFINE_TYPE_WITH_CODE (GKdbus, g_kdbus, G_TYPE_OBJECT,
78 G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
79 g_kdbus_initable_iface_init));
81 /* GBusCredentialsFlags */
86 G_BUS_CREDS_UNIQUE_NAME = 3,
87 G_BUS_CREDS_SELINUX_CONTEXT = 4
88 } GBusCredentialsFlags;
90 /* GKdbusPrivate struct */
101 guint64 attach_flags_send;
102 guint64 attach_flags_recv;
115 /* GKdbusSource struct */
120 GIOCondition condition;
121 GCancellable *cancellable;
122 GPollFD cancel_pollfd;
127 typedef gboolean (*GKdbusSourceFunc) (GKdbus *kdbus,
128 GIOCondition condition,
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}
146 * _g_kdbus_hexdump_all_items:
150 _g_kdbus_hexdump_all_items (GSList *kdbus_msg_items)
155 ret = g_string_new (NULL);
157 while (kdbus_msg_items != NULL)
159 g_string_append_printf (ret, "\n Item %d\n", item);
160 g_string_append (ret, _g_dbus_hexdump (((msg_part*)kdbus_msg_items->data)->data, ((msg_part*)kdbus_msg_items->data)->size, 2));
162 kdbus_msg_items = g_slist_next(kdbus_msg_items);
166 return g_string_free (ret, FALSE);
175 g_kdbus_finalize (GObject *object)
177 GKdbus *kdbus = G_KDBUS (object);
179 if (kdbus->priv->kdbus_buffer != NULL)
180 munmap (kdbus->priv->kdbus_buffer, KDBUS_POOL_SIZE);
182 kdbus->priv->kdbus_buffer = NULL;
184 if (kdbus->priv->fd != -1 && !kdbus->priv->closed)
185 _g_kdbus_close (kdbus, NULL);
187 if (G_OBJECT_CLASS (g_kdbus_parent_class)->finalize)
188 (*G_OBJECT_CLASS (g_kdbus_parent_class)->finalize) (object);
193 * g_kdbus_class_init:
197 g_kdbus_class_init (GKdbusClass *klass)
199 GObjectClass *gobject_class G_GNUC_UNUSED = G_OBJECT_CLASS (klass);
201 g_type_class_add_private (klass, sizeof (GKdbusPrivate));
202 gobject_class->finalize = g_kdbus_finalize;
207 * g_kdbus_initable_iface_init:
211 g_kdbus_initable_iface_init (GInitableIface *iface)
213 iface->init = g_kdbus_initable_init;
222 g_kdbus_init (GKdbus *kdbus)
224 kdbus->priv = G_TYPE_INSTANCE_GET_PRIVATE (kdbus, G_TYPE_KDBUS, GKdbusPrivate);
226 kdbus->priv->fd = -1;
228 kdbus->priv->unique_id = -1;
229 kdbus->priv->unique_name = NULL;
231 kdbus->priv->kdbus_buffer = NULL;
233 kdbus->priv->flags = 0; /* KDBUS_HELLO_ACCEPT_FD */
234 kdbus->priv->attach_flags_send = _KDBUS_ATTACH_ALL;
235 kdbus->priv->attach_flags_recv = _KDBUS_ATTACH_ALL;
240 * g_kdbus_initable_init:
244 g_kdbus_initable_init (GInitable *initable,
245 GCancellable *cancellable,
250 g_return_val_if_fail (G_IS_KDBUS (initable), FALSE);
252 kdbus = G_KDBUS (initable);
254 if (cancellable != NULL)
256 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
257 _("Cancellable initialization not supported"));
261 kdbus->priv->inited = TRUE;
268 * kdbus_source_prepare:
272 kdbus_source_prepare (GSource *source,
275 GKdbusSource *kdbus_source = (GKdbusSource *)source;
277 if (g_cancellable_is_cancelled (kdbus_source->cancellable))
280 if (kdbus_source->timeout_time)
284 now = g_source_get_time (source);
286 *timeout = (kdbus_source->timeout_time - now + 999) / 1000;
289 kdbus_source->kdbus->priv->timed_out = TRUE;
297 if ((kdbus_source->condition & kdbus_source->pollfd.revents) != 0)
305 * kdbus_source_check:
309 kdbus_source_check (GSource *source)
313 return kdbus_source_prepare (source, &timeout);
318 * kdbus_source_dispatch
322 kdbus_source_dispatch (GSource *source,
323 GSourceFunc callback,
326 GKdbusSourceFunc func = (GKdbusSourceFunc)callback;
327 GKdbusSource *kdbus_source = (GKdbusSource *)source;
328 GKdbus *kdbus = kdbus_source->kdbus;
331 if (kdbus_source->kdbus->priv->timed_out)
332 kdbus_source->pollfd.revents |= kdbus_source->condition & (G_IO_IN | G_IO_OUT);
334 ret = (*func) (kdbus,
335 kdbus_source->pollfd.revents & kdbus_source->condition,
338 if (kdbus->priv->timeout)
339 kdbus_source->timeout_time = g_get_monotonic_time ()
340 + kdbus->priv->timeout * 1000000;
342 kdbus_source->timeout_time = 0;
349 * kdbus_source_finalize
353 kdbus_source_finalize (GSource *source)
355 GKdbusSource *kdbus_source = (GKdbusSource *)source;
358 kdbus = kdbus_source->kdbus;
360 g_object_unref (kdbus);
362 if (kdbus_source->cancellable)
364 g_cancellable_release_fd (kdbus_source->cancellable);
365 g_object_unref (kdbus_source->cancellable);
371 * kdbus_source_closure_callback:
375 kdbus_source_closure_callback (GKdbus *kdbus,
376 GIOCondition condition,
379 GClosure *closure = data;
380 GValue params[2] = { G_VALUE_INIT, G_VALUE_INIT };
381 GValue result_value = G_VALUE_INIT;
384 g_value_init (&result_value, G_TYPE_BOOLEAN);
386 g_value_init (¶ms[0], G_TYPE_KDBUS);
387 g_value_set_object (¶ms[0], kdbus);
388 g_value_init (¶ms[1], G_TYPE_IO_CONDITION);
389 g_value_set_flags (¶ms[1], condition);
391 g_closure_invoke (closure, &result_value, 2, params, NULL);
393 result = g_value_get_boolean (&result_value);
394 g_value_unset (&result_value);
395 g_value_unset (¶ms[0]);
396 g_value_unset (¶ms[1]);
402 static GSourceFuncs kdbus_source_funcs =
404 kdbus_source_prepare,
406 kdbus_source_dispatch,
407 kdbus_source_finalize,
408 (GSourceFunc)kdbus_source_closure_callback,
417 kdbus_source_new (GKdbus *kdbus,
418 GIOCondition condition,
419 GCancellable *cancellable)
422 GKdbusSource *kdbus_source;
424 source = g_source_new (&kdbus_source_funcs, sizeof (GKdbusSource));
425 g_source_set_name (source, "GKdbus");
426 kdbus_source = (GKdbusSource *)source;
428 kdbus_source->kdbus = g_object_ref (kdbus);
429 kdbus_source->condition = condition;
431 if (g_cancellable_make_pollfd (cancellable,
432 &kdbus_source->cancel_pollfd))
434 kdbus_source->cancellable = g_object_ref (cancellable);
435 g_source_add_poll (source, &kdbus_source->cancel_pollfd);
438 kdbus_source->pollfd.fd = kdbus->priv->fd;
439 kdbus_source->pollfd.events = condition;
440 kdbus_source->pollfd.revents = 0;
441 g_source_add_poll (source, &kdbus_source->pollfd);
443 if (kdbus->priv->timeout)
444 kdbus_source->timeout_time = g_get_monotonic_time ()
445 + kdbus->priv->timeout * 1000000;
447 kdbus_source->timeout_time = 0;
454 * _g_kdbus_create_source:
458 _g_kdbus_create_source (GKdbus *kdbus,
459 GIOCondition condition,
460 GCancellable *cancellable)
462 g_return_val_if_fail (G_IS_KDBUS (kdbus) && (cancellable == NULL || G_IS_CANCELLABLE (cancellable)), NULL);
464 return kdbus_source_new (kdbus, condition, cancellable);
473 _g_kdbus_open (GKdbus *kdbus,
474 const gchar *address,
477 g_return_val_if_fail (G_IS_KDBUS (kdbus), FALSE);
479 kdbus->priv->fd = open(address, O_RDWR|O_NOCTTY|O_CLOEXEC);
480 if (kdbus->priv->fd<0)
482 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, _("Can't open kdbus endpoint"));
486 kdbus->priv->closed = FALSE;
497 g_kdbus_free_data (GKdbus *kdbus,
500 struct kdbus_cmd_free cmd;
506 ret = ioctl (kdbus->priv->fd, KDBUS_CMD_FREE, &cmd);
515 * g_kdbus_translate_nameowner_flags:
519 g_kdbus_translate_nameowner_flags (GBusNameOwnerFlags flags,
520 guint64 *kdbus_flags)
526 if (flags & G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT)
527 new_flags |= KDBUS_NAME_ALLOW_REPLACEMENT;
529 if (flags & G_BUS_NAME_OWNER_FLAGS_REPLACE)
530 new_flags |= KDBUS_NAME_REPLACE_EXISTING;
532 if (!(flags & G_BUS_NAME_OWNER_FLAGS_DO_NOT_QUEUE))
533 new_flags |= KDBUS_NAME_QUEUE;
535 *kdbus_flags = new_flags;
544 _g_kdbus_close (GKdbus *kdbus,
549 g_return_val_if_fail (G_IS_KDBUS (kdbus), FALSE);
551 if (kdbus->priv->closed)
556 res = close (kdbus->priv->fd);
563 g_set_error (error, G_IO_ERROR,
564 g_io_error_from_errno (errno),
565 _("Error closing kdbus fd: %s"),
572 kdbus->priv->closed = TRUE;
573 kdbus->priv->fd = -1;
580 * _g_kdbus_is_closed:
584 _g_kdbus_is_closed (GKdbus *kdbus)
586 g_return_val_if_fail (G_IS_KDBUS (kdbus), FALSE);
588 return kdbus->priv->closed;
597 _g_kdbus_Hello (GIOStream *stream,
601 struct kdbus_cmd_hello *hello;
602 struct kdbus_item *item;
605 size_t size, conn_name_size;
607 kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (stream));
609 conn_name = "gdbus-kdbus";
610 conn_name_size = strlen (conn_name);
612 size = KDBUS_ALIGN8 (G_STRUCT_OFFSET (struct kdbus_cmd_hello, items)) +
613 KDBUS_ALIGN8 (G_STRUCT_OFFSET (struct kdbus_item, str) + conn_name_size + 1);
615 hello = g_alloca0 (size);
616 hello->flags = kdbus->priv->flags;
617 hello->attach_flags_send = kdbus->priv->attach_flags_send;
618 hello->attach_flags_recv = kdbus->priv->attach_flags_recv;
620 hello->pool_size = KDBUS_POOL_SIZE;
623 item->size = G_STRUCT_OFFSET (struct kdbus_item, str) + conn_name_size + 1;
624 item->type = KDBUS_ITEM_CONN_DESCRIPTION;
625 memcpy (item->str, conn_name, conn_name_size+1);
626 item = KDBUS_ITEM_NEXT (item);
628 if (ioctl(kdbus->priv->fd, KDBUS_CMD_HELLO, hello))
630 g_set_error (error, G_IO_ERROR,
631 g_io_error_from_errno (errno),
632 _("Failed to send HELLO: %s"),
637 kdbus->priv->kdbus_buffer = mmap(NULL, KDBUS_POOL_SIZE, PROT_READ, MAP_SHARED, kdbus->priv->fd, 0);
638 if (kdbus->priv->kdbus_buffer == MAP_FAILED)
640 g_set_error (error, G_IO_ERROR,
641 g_io_error_from_errno (errno),
647 if (hello->bus_flags > 0xFFFFFFFFULL)
649 g_set_error_literal (error,
652 _("Incompatible HELLO flags"));
656 memcpy (kdbus->priv->bus_id, hello->id128, 16);
658 kdbus->priv->unique_id = hello->id;
659 asprintf(&kdbus->priv->unique_name, ":1.%llu", (unsigned long long) hello->id);
661 /* read bloom filters parameters */
662 kdbus->priv->bloom_size = (gsize) hello->bloom.size;
663 kdbus->priv->bloom_n_hash = (guint) hello->bloom.n_hash;
665 return g_variant_new ("(s)", kdbus->priv->unique_name);
670 * _g_kdbus_RequestName:
674 _g_kdbus_RequestName (GDBusConnection *connection,
676 GBusNameOwnerFlags flags,
681 struct kdbus_cmd_name *kdbus_name;
686 status = G_BUS_REQUEST_NAME_FLAGS_PRIMARY_OWNER;
688 kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
691 g_set_error_literal (error,
693 G_DBUS_ERROR_IO_ERROR,
694 _("The connection is closed"));
698 if (!g_dbus_is_name (name))
702 G_DBUS_ERROR_INVALID_ARGS,
703 "Given bus name \"%s\" is not valid", name);
711 G_DBUS_ERROR_INVALID_ARGS,
712 "Cannot acquire a service starting with ':' such as \"%s\"", name);
716 g_kdbus_translate_nameowner_flags (flags, &kdbus_flags);
718 len = strlen(name) + 1;
719 size = G_STRUCT_OFFSET (struct kdbus_cmd_name, items) + KDBUS_ITEM_SIZE(len);
720 kdbus_name = g_alloca0 (size);
721 kdbus_name->size = size;
722 kdbus_name->items[0].size = KDBUS_ITEM_HEADER_SIZE + len;
723 kdbus_name->items[0].type = KDBUS_ITEM_NAME;
724 kdbus_name->flags = kdbus_flags;
725 memcpy (kdbus_name->items[0].str, name, len);
727 ret = ioctl(kdbus->priv->fd, KDBUS_CMD_NAME_ACQUIRE, kdbus_name);
731 status = G_BUS_REQUEST_NAME_FLAGS_EXISTS;
732 else if (errno == EALREADY)
733 status = G_BUS_REQUEST_NAME_FLAGS_ALREADY_OWNER;
736 g_set_error (error, G_IO_ERROR,
737 g_io_error_from_errno (errno),
738 _("Error while acquiring name: %s"),
744 if (kdbus_name->flags & KDBUS_NAME_IN_QUEUE)
745 status = G_BUS_REQUEST_NAME_FLAGS_IN_QUEUE;
747 result = g_variant_new ("(u)", status);
754 * _g_kdbus_ReleaseName:
758 _g_kdbus_ReleaseName (GDBusConnection *connection,
764 struct kdbus_cmd_name *kdbus_name;
768 status = G_BUS_RELEASE_NAME_FLAGS_RELEASED;
770 kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
773 g_set_error_literal (error,
775 G_DBUS_ERROR_IO_ERROR,
776 _("The connection is closed"));
780 if (!g_dbus_is_name (name))
784 G_DBUS_ERROR_INVALID_ARGS,
785 "Given bus name \"%s\" is not valid", name);
793 G_DBUS_ERROR_INVALID_ARGS,
794 "Cannot release a service starting with ':' such as \"%s\"", name);
798 len = strlen(name) + 1;
799 size = G_STRUCT_OFFSET (struct kdbus_cmd_name, items) + KDBUS_ITEM_SIZE(len);
800 kdbus_name = g_alloca0 (size);
801 kdbus_name->size = size;
802 kdbus_name->items[0].size = KDBUS_ITEM_HEADER_SIZE + len;
803 kdbus_name->items[0].type = KDBUS_ITEM_NAME;
804 memcpy (kdbus_name->items[0].str, name, len);
806 ret = ioctl(kdbus->priv->fd, KDBUS_CMD_NAME_RELEASE, kdbus_name);
810 status = G_BUS_RELEASE_NAME_FLAGS_NON_EXISTENT;
811 else if (errno == EADDRINUSE)
812 status = G_BUS_RELEASE_NAME_FLAGS_NOT_OWNER;
815 g_set_error (error, G_IO_ERROR,
816 g_io_error_from_errno (errno),
817 _("Error while releasing name: %s"),
823 result = g_variant_new ("(u)", status);
834 _g_kdbus_GetBusId (GDBusConnection *connection,
842 result_str = g_string_new (NULL);
843 kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
846 g_set_error_literal (error,
848 G_DBUS_ERROR_IO_ERROR,
849 _("The connection is closed"));
850 g_string_free (result_str, TRUE);
854 for (cnt=0; cnt<16; cnt++)
855 g_string_append_printf (result_str, "%02x", kdbus->priv->bus_id[cnt]);
857 result = g_variant_new ("(s)", result_str->str);
858 g_string_free (result_str, TRUE);
865 * _g_kdbus_GetListNames:
869 _g_kdbus_GetListNames (GDBusConnection *connection,
870 guint list_name_type,
875 GVariantBuilder *builder;
877 struct kdbus_cmd_name_list cmd = {};
878 struct kdbus_name_list *name_list;
879 struct kdbus_name_info *name;
885 kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
888 g_set_error_literal (error,
890 G_DBUS_ERROR_IO_ERROR,
891 _("The connection is closed"));
896 cmd.flags = KDBUS_NAME_LIST_ACTIVATORS; /* ListActivatableNames */
898 cmd.flags = KDBUS_NAME_LIST_UNIQUE | KDBUS_NAME_LIST_NAMES; /* ListNames */
900 ret = ioctl(kdbus->priv->fd, KDBUS_CMD_NAME_LIST, &cmd);
906 _("Error listing names"));
910 name_list = (struct kdbus_name_list *) ((guint8 *) kdbus->priv->kdbus_buffer + cmd.offset);
911 builder = g_variant_builder_new (G_VARIANT_TYPE ("as"));
913 KDBUS_ITEM_FOREACH(name, name_list, names)
915 struct kdbus_item *item;
916 const gchar *item_name = "";
918 if ((cmd.flags & KDBUS_NAME_LIST_UNIQUE) && name->owner_id != prev_id)
920 GString *unique_name;
922 unique_name = g_string_new (NULL);
923 g_string_printf (unique_name, ":1.%llu", name->owner_id);
924 g_variant_builder_add (builder, "s", unique_name->str);
925 g_string_free (unique_name,TRUE);
926 prev_id = name->owner_id;
929 KDBUS_ITEM_FOREACH(item, name, items)
930 if (item->type == KDBUS_ITEM_OWNED_NAME)
931 item_name = item->name.name;
933 if (g_dbus_is_name (item_name))
934 g_variant_builder_add (builder, "s", item_name);
937 result = g_variant_new ("(as)", builder);
938 g_variant_builder_unref (builder);
940 g_kdbus_free_data (kdbus, cmd.offset);
946 * _g_kdbus_NameHasOwner_internal:
950 g_kdbus_NameHasOwner_internal (GKdbus *kdbus,
954 struct kdbus_cmd_info *cmd;
958 if (g_dbus_is_unique_name(name))
960 size = G_STRUCT_OFFSET (struct kdbus_cmd_info, items);
961 cmd = g_alloca0 (size);
962 cmd->id = g_ascii_strtoull (name+3, NULL, 10);
966 len = strlen(name) + 1;
967 size = G_STRUCT_OFFSET (struct kdbus_cmd_info, items) + KDBUS_ITEM_SIZE(len);
968 cmd = g_alloca0 (size);
969 cmd->items[0].size = KDBUS_ITEM_HEADER_SIZE + len;
970 cmd->items[0].type = KDBUS_ITEM_NAME;
971 memcpy (cmd->items[0].str, name, len);
975 ret = ioctl(kdbus->priv->fd, KDBUS_CMD_CONN_INFO, cmd);
976 g_kdbus_free_data (kdbus, cmd->offset);
986 * _g_kdbus_GetListQueuedOwners:
990 _g_kdbus_GetListQueuedOwners (GDBusConnection *connection,
996 GVariantBuilder *builder;
997 GString *unique_name;
1000 struct kdbus_cmd_name_list cmd = {};
1001 struct kdbus_name_list *name_list;
1002 struct kdbus_name_info *kname;
1004 kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
1007 g_set_error_literal (error,
1009 G_DBUS_ERROR_IO_ERROR,
1010 _("The connection is closed"));
1014 if (!g_dbus_is_name (name))
1018 G_DBUS_ERROR_INVALID_ARGS,
1019 "Given bus name \"%s\" is not valid", name);
1023 if (!g_kdbus_NameHasOwner_internal (kdbus, name, error))
1027 G_DBUS_ERROR_NAME_HAS_NO_OWNER,
1028 "Could not get owner of name '%s': no such name", name);
1032 cmd.flags = KDBUS_NAME_LIST_QUEUED;
1033 ret = ioctl(kdbus->priv->fd, KDBUS_CMD_NAME_LIST, &cmd);
1038 G_DBUS_ERROR_FAILED,
1039 _("Error listing names"));
1043 name_list = (struct kdbus_name_list *) ((guint8 *) kdbus->priv->kdbus_buffer + cmd.offset);
1045 unique_name = g_string_new (NULL);
1046 builder = g_variant_builder_new (G_VARIANT_TYPE ("as"));
1047 KDBUS_ITEM_FOREACH(kname, name_list, names)
1049 struct kdbus_item *item;
1050 const char *item_name = "";
1052 KDBUS_ITEM_FOREACH(item, kname, items)
1053 if (item->type == KDBUS_ITEM_NAME)
1054 item_name = item->str;
1056 if (strcmp(item_name, name))
1059 g_string_printf (unique_name, ":1.%llu", kname->owner_id);
1060 g_variant_builder_add (builder, "s", item_name);
1063 result = g_variant_new ("(as)", builder);
1064 g_variant_builder_unref (builder);
1065 g_string_free (unique_name,TRUE);
1067 g_kdbus_free_data (kdbus, cmd.offset);
1073 * g_kdbus_GetConnInfo_internal:
1077 g_kdbus_GetConnInfo_internal (GDBusConnection *connection,
1085 struct kdbus_cmd_info *cmd;
1086 struct kdbus_info *conn_info;
1087 struct kdbus_item *item;
1092 kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
1095 g_set_error_literal (error,
1097 G_DBUS_ERROR_IO_ERROR,
1098 _("The connection is closed"));
1102 if (!g_dbus_is_name (name))
1106 G_DBUS_ERROR_INVALID_ARGS,
1107 "Given bus name \"%s\" is not valid", name);
1111 if (!g_kdbus_NameHasOwner_internal (kdbus, name, error))
1115 G_DBUS_ERROR_NAME_HAS_NO_OWNER,
1116 "Could not get owner of name '%s': no such name", name);
1120 if (g_dbus_is_unique_name(name))
1122 size = G_STRUCT_OFFSET (struct kdbus_cmd_info, items);
1123 cmd = g_alloca0 (size);
1124 cmd->id = g_ascii_strtoull (name+3, NULL, 10);
1128 len = strlen(name) + 1;
1129 size = G_STRUCT_OFFSET (struct kdbus_cmd_info, items) + KDBUS_ITEM_SIZE(len);
1130 cmd = g_alloca0 (size);
1131 cmd->items[0].size = KDBUS_ITEM_HEADER_SIZE + len;
1132 cmd->items[0].type = KDBUS_ITEM_NAME;
1133 memcpy (cmd->items[0].str, name, len);
1136 cmd->flags = _KDBUS_ATTACH_ALL;
1139 ret = ioctl(kdbus->priv->fd, KDBUS_CMD_CONN_INFO, cmd);
1144 G_DBUS_ERROR_FAILED,
1145 _("Could not get connection info"));
1149 conn_info = (struct kdbus_info *) ((guint8 *) kdbus->priv->kdbus_buffer + cmd->offset);
1152 if (conn_info->flags & KDBUS_HELLO_ACTIVATOR)
1156 if (flag == G_BUS_CREDS_UNIQUE_NAME)
1158 GString *unique_name;
1160 unique_name = g_string_new (NULL);
1161 g_string_printf (unique_name, ":1.%llu", (unsigned long long) conn_info->id);
1162 result = g_variant_new ("(s)", unique_name->str);
1163 g_string_free (unique_name,TRUE);
1167 KDBUS_ITEM_FOREACH(item, conn_info, items)
1171 case KDBUS_ITEM_PIDS:
1173 if (flag == G_BUS_CREDS_PID)
1175 guint pid = item->pids.pid;
1176 result = g_variant_new ("(u)", pid);
1180 case KDBUS_ITEM_CREDS:
1182 if (flag == G_BUS_CREDS_UID)
1184 guint uid = item->creds.uid;
1185 result = g_variant_new ("(u)", uid);
1189 case KDBUS_ITEM_SECLABEL:
1190 case KDBUS_ITEM_PID_COMM:
1191 case KDBUS_ITEM_TID_COMM:
1192 case KDBUS_ITEM_EXE:
1193 case KDBUS_ITEM_CMDLINE:
1194 case KDBUS_ITEM_CGROUP:
1195 case KDBUS_ITEM_CAPS:
1196 case KDBUS_ITEM_AUDIT:
1197 case KDBUS_ITEM_CONN_DESCRIPTION:
1198 case KDBUS_ITEM_AUXGROUPS:
1199 case KDBUS_ITEM_OWNED_NAME:
1205 g_kdbus_free_data (kdbus, cmd->offset);
1211 * _g_kdbus_GetNameOwner:
1215 _g_kdbus_GetNameOwner (GDBusConnection *connection,
1219 return g_kdbus_GetConnInfo_internal (connection,
1221 G_BUS_CREDS_UNIQUE_NAME,
1227 * _g_kdbus_GetConnectionUnixProcessID:
1231 _g_kdbus_GetConnectionUnixProcessID (GDBusConnection *connection,
1235 return g_kdbus_GetConnInfo_internal (connection,
1243 * _g_kdbus_GetConnectionUnixUser:
1247 _g_kdbus_GetConnectionUnixUser (GDBusConnection *connection,
1251 return g_kdbus_GetConnInfo_internal (connection,
1259 * _g_kdbus_match_remove:
1263 _g_kdbus_match_remove (GDBusConnection *connection,
1267 struct kdbus_cmd_match cmd_match = {};
1270 kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
1272 cmd_match.size = sizeof (cmd_match);
1273 cmd_match.cookie = cookie;
1275 ret = ioctl(kdbus->priv->fd, KDBUS_CMD_MATCH_REMOVE, &cmd_match);
1277 g_warning ("ERROR - %d\n", (int) errno);
1282 * _g_kdbus_subscribe_name_acquired:
1286 _g_kdbus_subscribe_name_owner_changed (GDBusConnection *connection,
1288 const gchar *old_name,
1289 const gchar *new_name,
1293 struct kdbus_item *item;
1294 struct kdbus_cmd_match *cmd_match;
1297 guint64 old_id = 0; /* XXX why? */
1298 guint64 new_id = KDBUS_MATCH_ID_ANY;
1300 kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
1302 len = strlen(name) + 1;
1303 size = KDBUS_ALIGN8(G_STRUCT_OFFSET (struct kdbus_cmd_match, items) +
1304 G_STRUCT_OFFSET (struct kdbus_item, name_change) +
1305 G_STRUCT_OFFSET (struct kdbus_notify_name_change, name) + len);
1307 cmd_match = g_alloca0 (size);
1308 cmd_match->size = size;
1309 cmd_match->cookie = cookie;
1310 item = cmd_match->items;
1312 if (old_name[0] == 0)
1314 old_id = KDBUS_MATCH_ID_ANY;
1318 if (g_dbus_is_unique_name(old_name))
1324 if (new_name[0] == 0)
1326 new_id = KDBUS_MATCH_ID_ANY;
1330 if (g_dbus_is_unique_name(new_name))
1336 cmd_match = g_alloca0 (size);
1337 cmd_match->size = size;
1338 cmd_match->cookie = cookie;
1339 item = cmd_match->items;
1341 /* KDBUS_ITEM_NAME_CHANGE */
1342 item->type = KDBUS_ITEM_NAME_CHANGE;
1343 item->name_change.old_id.id = old_id;
1344 item->name_change.new_id.id = new_id;
1345 memcpy(item->name_change.name, name, len);
1346 item->size = G_STRUCT_OFFSET (struct kdbus_item, name_change) +
1347 G_STRUCT_OFFSET(struct kdbus_notify_name_change, name) + len;
1348 item = KDBUS_ITEM_NEXT(item);
1350 ret = ioctl(kdbus->priv->fd, KDBUS_CMD_MATCH_ADD, cmd_match);
1352 g_warning ("ERROR - %d\n", (int) errno);
1357 * _g_kdbus_subscribe_name_acquired:
1361 _g_kdbus_subscribe_name_acquired (GDBusConnection *connection,
1365 struct kdbus_item *item;
1366 struct kdbus_cmd_match *cmd_match;
1371 kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
1373 len = strlen(name) + 1;
1374 size = KDBUS_ALIGN8(G_STRUCT_OFFSET (struct kdbus_cmd_match, items) +
1375 G_STRUCT_OFFSET (struct kdbus_item, name_change) +
1376 G_STRUCT_OFFSET (struct kdbus_notify_name_change, name) + len);
1378 cookie = 0xbeefbeefbeefbeef;
1379 cmd_match = g_alloca0 (size);
1380 cmd_match->size = size;
1381 cmd_match->cookie = cookie;
1382 item = cmd_match->items;
1384 /* KDBUS_ITEM_NAME_ADD */
1385 item->type = KDBUS_ITEM_NAME_ADD;
1386 item->name_change.old_id.id = KDBUS_MATCH_ID_ANY;
1387 item->name_change.new_id.id = kdbus->priv->unique_id;
1388 memcpy(item->name_change.name, name, len);
1389 item->size = G_STRUCT_OFFSET (struct kdbus_item, name_change) +
1390 G_STRUCT_OFFSET(struct kdbus_notify_name_change, name) + len;
1391 item = KDBUS_ITEM_NEXT(item);
1393 ret = ioctl(kdbus->priv->fd, KDBUS_CMD_MATCH_ADD, cmd_match);
1395 g_warning ("ERROR - %d\n", (int) errno);
1397 _g_kdbus_subscribe_name_owner_changed (connection, name, "", kdbus->priv->unique_name, cookie);
1402 * _g_kdbus_subscribe_name_lost:
1406 _g_kdbus_subscribe_name_lost (GDBusConnection *connection,
1410 struct kdbus_item *item;
1411 struct kdbus_cmd_match *cmd_match;
1416 kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
1418 len = strlen(name) + 1;
1419 size = KDBUS_ALIGN8(G_STRUCT_OFFSET (struct kdbus_cmd_match, items) +
1420 G_STRUCT_OFFSET (struct kdbus_item, name_change) +
1421 G_STRUCT_OFFSET (struct kdbus_notify_name_change, name) + len);
1423 cookie = 0xdeafdeafdeafdeaf;
1424 cmd_match = g_alloca0 (size);
1425 cmd_match->size = size;
1426 cmd_match->cookie = cookie;
1427 item = cmd_match->items;
1429 /* KDBUS_ITEM_NAME_REMOVE */
1430 item->type = KDBUS_ITEM_NAME_REMOVE;
1431 item->name_change.old_id.id = kdbus->priv->unique_id;
1432 item->name_change.new_id.id = KDBUS_MATCH_ID_ANY;
1433 memcpy(item->name_change.name, name, len);
1434 item->size = G_STRUCT_OFFSET (struct kdbus_item, name_change) +
1435 G_STRUCT_OFFSET(struct kdbus_notify_name_change, name) + len;
1436 item = KDBUS_ITEM_NEXT(item);
1438 ret = ioctl(kdbus->priv->fd, KDBUS_CMD_MATCH_ADD, cmd_match);
1440 g_warning ("ERROR - %d\n", (int) errno);
1442 _g_kdbus_subscribe_name_owner_changed (connection, name, kdbus->priv->unique_name, "", cookie);
1447 * _g_kdbus_unsubscribe_name_acquired:
1451 _g_kdbus_unsubscribe_name_acquired (GDBusConnection *connection)
1455 cookie = 0xbeefbeefbeefbeef;
1456 _g_kdbus_match_remove (connection, cookie);
1461 * _g_kdbus_unsubscribe_name_lost:
1465 _g_kdbus_unsubscribe_name_lost (GDBusConnection *connection)
1469 cookie = 0xdeafdeafdeafdeaf;
1470 _g_kdbus_match_remove (connection, cookie);
1475 * g_kdbus_append_payload_bloom:
1478 static struct kdbus_bloom_filter *
1479 g_kdbus_append_bloom (struct kdbus_item **item,
1482 struct kdbus_item *bloom_item;
1484 bloom_item = KDBUS_ALIGN8_PTR(*item);
1485 bloom_item->size = G_STRUCT_OFFSET (struct kdbus_item, bloom_filter) +
1486 G_STRUCT_OFFSET (struct kdbus_bloom_filter, data) +
1489 bloom_item->type = KDBUS_ITEM_BLOOM_FILTER;
1491 *item = KDBUS_ITEM_NEXT(bloom_item);
1492 return &bloom_item->bloom_filter;
1497 * g_kdbus_bloom_add_data:
1498 * Based on bus-bloom.c from systemd
1499 * http://cgit.freedesktop.org/systemd/systemd/tree/src/libsystemd/sd-bus/bus-bloom.c
1502 g_kdbus_bloom_add_data (GKdbus *kdbus,
1503 guint64 bloom_data [],
1509 guint bytes_num = 0;
1515 bit_num = kdbus->priv->bloom_size * 8;
1518 bytes_num = ((__builtin_clzll(bit_num) ^ 63U) + 7) / 8;
1520 for (cnt_1 = 0; cnt_1 < (kdbus->priv->bloom_n_hash); cnt_1++)
1522 for (cnt_2 = 0; cnt_2 < bytes_num; cnt_2++)
1526 g_siphash24(hash, data, n, hash_keys[cnt_1++]);
1530 p = (p << 8ULL) | (guint64) hash[8 - c];
1535 bloom_data[p >> 6] |= 1ULL << (p & 63);
1541 * g_kdbus_bloom_add_pair:
1545 g_kdbus_bloom_add_pair (GKdbus *kdbus,
1546 guint64 bloom_data [],
1547 const gchar *parameter,
1550 GString *data = g_string_new (NULL);
1552 g_string_printf (data,"%s:%s",parameter,value);
1553 g_kdbus_bloom_add_data(kdbus, bloom_data, data->str, data->len);
1554 g_string_free (data, TRUE);
1559 * g_kdbus_bloom_add_prefixes:
1563 g_kdbus_bloom_add_prefixes (GKdbus *kdbus,
1564 guint64 bloom_data [],
1565 const gchar *parameter,
1569 GString *data = g_string_new (NULL);
1571 g_string_printf (data,"%s:%s",parameter,value);
1576 last_sep = strrchr(data->str, separator);
1577 if (!last_sep || last_sep == data->str)
1581 g_kdbus_bloom_add_data(kdbus, bloom_data, data->str, last_sep-(data->str));
1583 g_string_free (data, TRUE);
1588 * g_kdbus_setup_bloom:
1589 * Based on bus-bloom.c from systemd
1590 * http://cgit.freedesktop.org/systemd/systemd/tree/src/libsystemd/sd-bus/bus-bloom.c
1593 g_kdbus_setup_bloom (GKdbus *kdbus,
1594 GDBusMessage *dbus_msg,
1595 struct kdbus_bloom_filter *bloom_filter)
1601 const gchar *message_type;
1602 const gchar *interface;
1603 const gchar *member;
1609 body = g_dbus_message_get_body (dbus_msg);
1610 message_type = _g_dbus_enum_to_string (G_TYPE_DBUS_MESSAGE_TYPE, g_dbus_message_get_message_type (dbus_msg));
1611 interface = g_dbus_message_get_interface (dbus_msg);
1612 member = g_dbus_message_get_member (dbus_msg);
1613 path = g_dbus_message_get_path (dbus_msg);
1615 bloom_data = bloom_filter->data;
1616 memset (bloom_data, 0, kdbus->priv->bloom_size);
1617 bloom_filter->generation = 0;
1619 g_kdbus_bloom_add_pair(kdbus, bloom_data, "message-type", message_type);
1622 g_kdbus_bloom_add_pair(kdbus, bloom_data, "interface", interface);
1625 g_kdbus_bloom_add_pair(kdbus, bloom_data, "member", member);
1629 g_kdbus_bloom_add_pair(kdbus, bloom_data, "path", path);
1630 g_kdbus_bloom_add_pair(kdbus, bloom_data, "path-slash-prefix", path);
1631 g_kdbus_bloom_add_prefixes(kdbus, bloom_data, "path-slash-prefix", path, '/');
1636 g_variant_iter_init (&iter, body);
1637 while ((child = g_variant_iter_next_value (&iter)))
1639 gchar buf[sizeof("arg")-1 + 2 + sizeof("-slash-prefix")];
1640 gchar *child_string;
1643 /* Is it necessary? */
1644 //if (g_variant_is_container (child))
1645 // iterate_container_recursive (child);
1647 if (!(g_variant_is_of_type (child, G_VARIANT_TYPE_STRING)) &&
1648 !(g_variant_is_of_type (child, G_VARIANT_TYPE_OBJECT_PATH)) &&
1649 !(g_variant_is_of_type (child, G_VARIANT_TYPE_SIGNATURE)))
1652 child_string = g_variant_dup_string (child, NULL);
1654 e = stpcpy(buf, "arg");
1656 *(e++) = '0' + (char) cnt;
1659 *(e++) = '0' + (char) (cnt / 10);
1660 *(e++) = '0' + (char) (cnt % 10);
1664 g_kdbus_bloom_add_pair(kdbus, bloom_data, buf, child_string);
1666 strcpy(e, "-dot-prefix");
1667 g_kdbus_bloom_add_prefixes(kdbus, bloom_data, buf, child_string, '.');
1669 strcpy(e, "-slash-prefix");
1670 g_kdbus_bloom_add_prefixes(kdbus, bloom_data, buf, child_string, '/');
1672 g_free (child_string);
1673 g_variant_unref (child);
1681 * TODO: g_kdbus_NameOwnerChanged_generate, g_kdbus_KernelMethodError_generate
1685 * g_kdbus_decode_kernel_msg:
1689 g_kdbus_decode_kernel_msg (GKdbus *kdbus,
1690 struct kdbus_msg *msg)
1692 struct kdbus_item *item = NULL;
1694 KDBUS_ITEM_FOREACH(item, msg, items)
1698 case KDBUS_ITEM_ID_ADD:
1699 case KDBUS_ITEM_ID_REMOVE:
1700 case KDBUS_ITEM_NAME_ADD:
1701 case KDBUS_ITEM_NAME_REMOVE:
1702 case KDBUS_ITEM_NAME_CHANGE:
1703 //size = g_kdbus_NameOwnerChanged_generate (kdbus, item);
1704 g_error ("'NameOwnerChanged'");
1707 case KDBUS_ITEM_REPLY_TIMEOUT:
1708 case KDBUS_ITEM_REPLY_DEAD:
1709 //size = g_kdbus_KernelMethodError_generate (kdbus, item);
1710 g_error ("'KernelMethodError'");
1714 g_warning ("Unknown field in kernel message - %lld", item->type);
1719 /* Override information from the user header with data from the kernel */
1720 g_string_printf (kdbus->priv->msg_sender, "org.freedesktop.DBus");
1722 /* for destination */
1723 if (kdbus->priv->kmsg->dst_id == KDBUS_DST_ID_BROADCAST)
1724 /* for broadcast messages we don't have to set destination */
1726 else if (kdbus->priv->kmsg->dst_id == KDBUS_DST_ID_NAME)
1727 g_string_printf (kdbus->priv->msg_destination, ":1.%" G_GUINT64_FORMAT, (guint64) kdbus->priv->unique_id);
1729 g_string_printf (kdbus->priv->msg_destination, ":1.%" G_GUINT64_FORMAT, (guint64) kdbus->priv->kmsg->dst_id);
1737 * g_kdbus_decode_dbus_msg:
1740 static GDBusMessage *
1741 g_kdbus_decode_dbus_msg (GKdbus *kdbus,
1742 struct kdbus_msg *msg)
1744 GDBusMessage *message;
1745 struct kdbus_item *item;
1746 gssize data_size = 0;
1747 GArray *body_vectors;
1753 message = g_dbus_message_new ();
1755 tmp = g_strdup_printf (":1.%"G_GUINT64_FORMAT, (guint64) msg->src_id);
1756 g_dbus_message_set_sender (message, tmp);
1759 body_vectors = g_array_new (FALSE, FALSE, sizeof (GVariantVector));
1762 KDBUS_ITEM_FOREACH(item, msg, items)
1764 if (item->size <= KDBUS_ITEM_HEADER_SIZE)
1765 g_error("[KDBUS] %llu bytes - invalid data record\n", item->size);
1767 data_size = item->size - KDBUS_ITEM_HEADER_SIZE;
1771 /* KDBUS_ITEM_DST_NAME */
1772 case KDBUS_ITEM_DST_NAME:
1773 /* Classic D-Bus doesn't make this known to the receiver, so
1774 * we don't do it here either (for compatibility with the
1779 /* KDBUS_ITEM_PALOAD_OFF */
1780 case KDBUS_ITEM_PAYLOAD_OFF:
1782 GVariantVector vector;
1785 /* We want to make sure the bytes are aligned the same as
1786 * they would be if they appeared in a contiguously
1787 * allocated chunk of aligned memory.
1789 * We decide what the alignment 'should' be by consulting
1790 * body_size, which has been tracking the total size of the
1791 * message up to this point.
1793 * We then play around with the pointer by removing as many
1794 * bytes as required to get it to the proper alignment (and
1795 * copy extra bytes accordingly). This means that we will
1796 * grab some extra data in the 'bytes', but it won't be
1797 * shared with GVariant (which means there is no chance of
1798 * it being accidentally retransmitted).
1800 * The kernel does the same thing, so make sure we get the
1801 * expected result. Because of the kernel doing the same,
1802 * the result is that we will always be rounding-down to a
1803 * multiple of 8 for the pointer, which means that the
1804 * pointer will always be valid, assuming the original
1807 * We could fix this with a new GBytes constructor that took
1808 * 'flavour' as a parameter, but it's not worth it...
1810 flavour = body_size & 7;
1811 //g_assert ((item->vec.offset & 7) == flavour); FIXME: kdbus bug doesn't count memfd in flavouring
1813 vector.gbytes = g_bytes_new (((guchar *) msg) + item->vec.offset - flavour, item->vec.size + flavour);
1814 vector.data.pointer = g_bytes_get_data (vector.gbytes, NULL);
1815 vector.data.pointer += flavour;
1816 vector.size = item->vec.size;
1818 g_array_append_val (body_vectors, vector);
1819 body_size += vector.size;
1823 /* KDBUS_ITEM_PAYLOAD_MEMFD */
1824 case KDBUS_ITEM_PAYLOAD_MEMFD:
1826 GVariantVector vector;
1828 vector.gbytes = g_bytes_new_take_zero_copy_fd (item->memfd.fd);
1829 vector.data.pointer = g_bytes_get_data (vector.gbytes, &vector.size);
1830 g_print ("GB was %p/%d\n", vector.data.pointer, (guint) vector.size);
1832 g_array_append_val (body_vectors, vector);
1833 body_size += vector.size;
1837 /* KDBUS_ITEM_FDS */
1838 case KDBUS_ITEM_FDS:
1840 GUnixFDList *fd_list;
1842 fd_list = g_unix_fd_list_new_from_array (item->fds, data_size / sizeof (int));
1843 g_dbus_message_set_unix_fd_list (message, fd_list);
1844 g_object_unref (fd_list);
1848 /* All of the following items, like CMDLINE,
1849 CGROUP, etc. need some GDBUS API extensions and
1850 should be implemented in the future */
1851 case KDBUS_ITEM_TIMESTAMP:
1853 g_print ("time: seq %llu mon %llu real %llu\n",
1854 item->timestamp.seqnum, item->timestamp.monotonic_ns, item->timestamp.realtime_ns);
1855 //g_dbus_message_set_timestamp (message, item->timestamp.monotonic_ns / 1000);
1856 //g_dbus_message_set_serial (message, item->timestamp.seqnum);
1860 case KDBUS_ITEM_CREDS:
1862 g_print ("creds: u%u eu %u su%u fsu%u g%u eg%u sg%u fsg%u\n",
1863 item->creds.uid, item->creds.euid, item->creds.suid, item->creds.fsuid,
1864 item->creds.gid, item->creds.egid, item->creds.sgid, item->creds.fsgid);
1868 case KDBUS_ITEM_PIDS:
1869 case KDBUS_ITEM_PID_COMM:
1870 case KDBUS_ITEM_TID_COMM:
1871 case KDBUS_ITEM_EXE:
1872 case KDBUS_ITEM_CMDLINE:
1873 case KDBUS_ITEM_CGROUP:
1874 case KDBUS_ITEM_AUDIT:
1875 case KDBUS_ITEM_CAPS:
1876 case KDBUS_ITEM_SECLABEL:
1877 case KDBUS_ITEM_CONN_DESCRIPTION:
1878 case KDBUS_ITEM_AUXGROUPS:
1879 case KDBUS_ITEM_OWNED_NAME:
1880 case KDBUS_ITEM_NAME:
1881 g_print ("unhandled %04x\n", (int) item->type);
1885 g_error ("[KDBUS] DBUS_PAYLOAD: Unknown filed - %lld", item->type);
1890 body = GLIB_PRIVATE_CALL(g_variant_from_vectors) (G_VARIANT_TYPE ("(ssa{sv})"),
1891 (GVariantVector *) body_vectors->data,
1892 body_vectors->len, body_size, FALSE);
1895 for (i = 0; i < body_vectors->len; i++)
1896 g_bytes_unref (g_array_index (body_vectors, GVariantVector, i).gbytes);
1898 g_array_free (body_vectors, TRUE);
1900 g_dbus_message_set_body (message, body);
1901 g_variant_unref (body);
1912 _g_kdbus_receive (GKdbus *kdbus,
1913 GCancellable *cancellable,
1916 struct kdbus_cmd_recv recv = {};
1917 struct kdbus_msg *msg;
1919 if (g_cancellable_set_error_if_cancelled (cancellable, error))
1923 if (ioctl(kdbus->priv->fd, KDBUS_CMD_MSG_RECV, &recv) < 0)
1925 if (errno == EINTR || errno == EAGAIN)
1928 g_set_error (error, G_IO_ERROR,
1929 g_io_error_from_errno (errno),
1930 _("Error while receiving message: %s"),
1931 g_strerror (errno));
1935 msg = (struct kdbus_msg *)((guint8 *)kdbus->priv->kdbus_buffer + recv.offset);
1937 if (msg->payload_type == KDBUS_PAYLOAD_DBUS)
1938 g_kdbus_decode_dbus_msg (kdbus, msg);
1939 else if (msg->payload_type == KDBUS_PAYLOAD_KERNEL)
1940 g_kdbus_decode_kernel_msg (kdbus, msg);
1945 G_DBUS_ERROR_FAILED,
1946 _("Received unknown payload type"));
1950 ioctl(kdbus->priv->fd, KDBUS_CMD_FREE, &recv.offset);
1955 struct dbus_fixed_header {
1964 #define DBUS_FIXED_HEADER_TYPE ((const GVariantType *) "(yyyyut)")
1965 #define DBUS_EXTENDED_HEADER_TYPE ((const GVariantType *) "a{tv}")
1966 #define DBUS_MESSAGE_TYPE ((const GVariantType *) "((yyyyut)a{tv}v)")
1968 #define KDBUS_MSG_MAX_SIZE 8192
1971 g_kdbus_msg_append_item (struct kdbus_msg *msg,
1976 struct kdbus_item *item;
1979 item_size = size + sizeof (struct kdbus_item);
1981 if (msg->size + item_size > KDBUS_MSG_MAX_SIZE)
1984 item = (struct kdbus_item *) ((guchar *) msg) + msg->size;
1986 item->size = item_size;
1987 memcpy (item->data, data, size);
1989 msg->size += (item_size + 7) & ~7ull;
1995 g_kdbus_msg_append_payload_vec (struct kdbus_msg *msg,
1999 struct kdbus_vec vec = {
2001 .address = (gsize) data
2004 return g_kdbus_msg_append_item (msg, KDBUS_ITEM_PAYLOAD_VEC, &vec, sizeof vec);
2008 g_kdbus_msg_append_payload_memfd (struct kdbus_msg *msg,
2013 struct kdbus_memfd mfd = {
2019 return g_kdbus_msg_append_item (msg, KDBUS_ITEM_PAYLOAD_MEMFD, &mfd, sizeof mfd);
2024 * Returns: size of data sent or -1 when error
2027 _g_kdbus_send (GKdbus *kdbus,
2028 GDBusMessage *message,
2029 GCancellable *cancellable,
2032 struct kdbus_msg *msg = alloca (KDBUS_MSG_MAX_SIZE);
2033 GVariantVectors body_vectors;
2035 g_return_val_if_fail (G_IS_KDBUS (kdbus), -1);
2037 if (g_cancellable_set_error_if_cancelled (cancellable, error))
2040 /* fill in as we go... */
2041 memset (msg, 0, sizeof (struct kdbus_msg));
2042 msg->size = sizeof (struct kdbus_msg);
2043 msg->payload_type = KDBUS_PAYLOAD_DBUS;
2044 msg->src_id = kdbus->priv->unique_id;
2045 msg->cookie = g_dbus_message_get_serial(message);
2047 /* Message destination */
2049 const gchar *dst_name;
2051 dst_name = g_dbus_message_get_destination (message);
2053 if (dst_name != NULL)
2055 if (g_dbus_is_unique_name (dst_name))
2057 if (dst_name[1] != '1' || dst_name[2] != '.')
2059 g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_NAME_HAS_NO_OWNER,
2060 "Invalid unique D-Bus name '%s'", dst_name);
2064 /* We already know that it passes the checks for unique
2065 * names, so no need to perform error checking on strtoull.
2067 msg->dst_id = strtoull (dst_name + 3, NULL, 10);
2072 g_kdbus_msg_append_item (msg, KDBUS_ITEM_DST_NAME, dst_name, strlen (dst_name) + 1);
2073 msg->dst_id = KDBUS_DST_ID_NAME;
2077 msg->dst_id = KDBUS_DST_ID_BROADCAST;
2080 /* File descriptors */
2082 GUnixFDList *fd_list;
2084 fd_list = g_dbus_message_get_unix_fd_list (message);
2086 if (fd_list != NULL)
2091 fds = g_unix_fd_list_peek_fds (fd_list, &n_fds);
2094 g_kdbus_msg_append_item (msg, KDBUS_ITEM_FDS, fds, sizeof (gint) * n_fds);
2100 struct dbus_fixed_header fh;
2101 GHashTableIter header_iter;
2102 GVariantBuilder builder;
2103 gpointer key, value;
2107 fh.endian = (G_BYTE_ORDER == G_LITTLE_ENDIAN) ? 'l': 'B';
2108 fh.type = g_dbus_message_get_message_type (message);
2109 fh.flags = g_dbus_message_get_flags (message);
2112 fh.serial = g_dbus_message_get_serial (message);
2113 parts[0] = g_variant_new_from_data (DBUS_FIXED_HEADER_TYPE, &fh, sizeof fh, TRUE, NULL, NULL);
2115 g_dbus_message_init_header_iter (message, &header_iter);
2116 g_variant_builder_init (&builder, DBUS_EXTENDED_HEADER_TYPE);
2117 while (g_hash_table_iter_next (&header_iter, &key, &value))
2119 guint64 key_int = (gsize) key;
2121 /* We don't send these in GVariant format */
2122 if (key_int == G_DBUS_MESSAGE_HEADER_FIELD_SIGNATURE ||
2123 key_int == G_DBUS_MESSAGE_HEADER_FIELD_NUM_UNIX_FDS)
2126 g_variant_builder_add (&builder, "{tv}", key_int, value);
2128 parts[1] = g_variant_builder_end (&builder);
2130 body = g_dbus_message_get_body (message);
2132 body = g_variant_new ("()");
2133 parts[2] = g_variant_new_variant (body);
2135 body = g_variant_ref_sink (g_variant_new_tuple (parts, G_N_ELEMENTS (parts)));
2136 GLIB_PRIVATE_CALL(g_variant_to_vectors) (body, &body_vectors);
2137 g_variant_unref (body);
2143 for (i = 0; i < body_vectors.vectors->len; i++)
2145 GVariantVector vector = g_array_index (body_vectors.vectors, GVariantVector, i);
2151 fd = g_bytes_get_zero_copy_fd (vector.gbytes);
2155 const guchar *bytes_data;
2158 bytes_data = g_bytes_get_data (vector.gbytes, &bytes_size);
2160 if (bytes_data <= vector.data.pointer && vector.data.pointer + vector.size <= bytes_data + bytes_size)
2162 if (!g_kdbus_msg_append_payload_memfd (msg, fd, vector.data.pointer - bytes_data, vector.size))
2167 if (!g_kdbus_msg_append_payload_vec (msg, vector.data.pointer, vector.size))
2173 if (!g_kdbus_msg_append_payload_vec (msg, vector.data.pointer, vector.size))
2178 if (!g_kdbus_msg_append_payload_vec (msg, body_vectors.extra_bytes->data + vector.data.offset, vector.size))
2186 msg->flags = ((g_dbus_message_get_flags (message) & G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED) ? 0 : KDBUS_MSG_FLAGS_EXPECT_REPLY) |
2187 ((g_dbus_message_get_flags (message) & G_DBUS_MESSAGE_FLAGS_NO_AUTO_START) ? KDBUS_MSG_FLAGS_NO_AUTO_START : 0);
2189 if ((msg->flags) & KDBUS_MSG_FLAGS_EXPECT_REPLY)
2190 msg->timeout_ns = 2000000000;
2192 msg->cookie_reply = g_dbus_message_get_reply_serial(message);
2196 if (dst_id == KDBUS_DST_ID_BROADCAST)
2198 struct kdbus_bloom_filter *bloom_filter;
2200 bloom_filter = g_kdbus_append_bloom (&item, kdbus->priv->bloom_size);
2201 g_kdbus_setup_bloom (kdbus, message, bloom_filter);
2209 if (ioctl(kdbus->priv->fd, KDBUS_CMD_MSG_SEND, msg))
2212 GString *error_name;
2213 error_name = g_string_new (NULL);
2217 g_string_free (error_name,TRUE);
2220 else if (errno == ENXIO)
2222 g_string_printf (error_name, "Name %s does not exist", g_dbus_message_get_destination(dbus_msg));
2223 g_kdbus_generate_local_error (worker,
2225 g_variant_new ("(s)",error_name->str),
2226 G_DBUS_ERROR_SERVICE_UNKNOWN);
2227 g_string_free (error_name,TRUE);
2230 else if ((errno == ESRCH) || (errno == EADDRNOTAVAIL))
2232 if (kmsg->flags & KDBUS_MSG_FLAGS_NO_AUTO_START)
2234 g_string_printf (error_name, "Name %s does not exist", g_dbus_message_get_destination(dbus_msg));
2235 g_kdbus_generate_local_error (worker,
2237 g_variant_new ("(s)",error_name->str),
2238 G_DBUS_ERROR_SERVICE_UNKNOWN);
2239 g_string_free (error_name,TRUE);
2244 g_string_printf (error_name, "The name %s was not provided by any .service files", g_dbus_message_get_destination(dbus_msg));
2245 g_kdbus_generate_local_error (worker,
2247 g_variant_new ("(s)",error_name->str),
2248 G_DBUS_ERROR_SERVICE_UNKNOWN);
2249 g_string_free (error_name,TRUE);
2254 g_print ("[KDBUS] ioctl error sending kdbus message:%d (%m)\n",errno);
2255 g_set_error (error, G_IO_ERROR, g_io_error_from_errno(errno), _("Error sending message - KDBUS_CMD_MSG_SEND error"));
2257 perror("ioctl send");
2258 g_error ("IOCTL SEND: %d\n",errno);
2265 /* We end up here if:
2266 * - too many kdbus_items
2267 * - too large kdbus_msg size
2268 * - too much vector data
2270 * We need to compact the message before sending it.
2272 g_assert_not_reached ();