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 */
96 struct kdbus_msg *kmsg;
102 guint64 attach_flags_send;
103 guint64 attach_flags_recv;
106 GString *msg_destination;
107 GSList *kdbus_msg_items;
123 /* GKdbusSource struct */
128 GIOCondition condition;
129 GCancellable *cancellable;
130 GPollFD cancel_pollfd;
135 typedef gboolean (*GKdbusSourceFunc) (GKdbus *kdbus,
136 GIOCondition condition,
139 /* Hash keys for bloom filters*/
140 const guint8 hash_keys[8][16] =
142 {0xb9,0x66,0x0b,0xf0,0x46,0x70,0x47,0xc1,0x88,0x75,0xc4,0x9c,0x54,0xb9,0xbd,0x15},
143 {0xaa,0xa1,0x54,0xa2,0xe0,0x71,0x4b,0x39,0xbf,0xe1,0xdd,0x2e,0x9f,0xc5,0x4a,0x3b},
144 {0x63,0xfd,0xae,0xbe,0xcd,0x82,0x48,0x12,0xa1,0x6e,0x41,0x26,0xcb,0xfa,0xa0,0xc8},
145 {0x23,0xbe,0x45,0x29,0x32,0xd2,0x46,0x2d,0x82,0x03,0x52,0x28,0xfe,0x37,0x17,0xf5},
146 {0x56,0x3b,0xbf,0xee,0x5a,0x4f,0x43,0x39,0xaf,0xaa,0x94,0x08,0xdf,0xf0,0xfc,0x10},
147 {0x31,0x80,0xc8,0x73,0xc7,0xea,0x46,0xd3,0xaa,0x25,0x75,0x0f,0x9e,0x4c,0x09,0x29},
148 {0x7d,0xf7,0x18,0x4b,0x7b,0xa4,0x44,0xd5,0x85,0x3c,0x06,0xe0,0x65,0x53,0x96,0x6d},
149 {0xf2,0x77,0xe9,0x6f,0x93,0xb5,0x4e,0x71,0x9a,0x0c,0x34,0x88,0x39,0x25,0xbf,0x35}
154 * _g_kdbus_get_last_msg_sender
158 _g_kdbus_get_last_msg_sender (GKdbus *kdbus)
160 return kdbus->priv->msg_sender->str;
165 * _g_kdbus_get_last_msg_destination
169 _g_kdbus_get_last_msg_destination (GKdbus *kdbus)
171 return kdbus->priv->msg_destination->str;
176 * _g_kdbus_get_last_msg_items:
180 _g_kdbus_get_last_msg_items (GKdbus *kdbus)
182 return kdbus->priv->kdbus_msg_items;
187 * g_kdbus_add_msg_part:
191 g_kdbus_add_msg_part (GKdbus *kdbus,
195 msg_part* part = g_new (msg_part, 1);
198 kdbus->priv->kdbus_msg_items = g_slist_append (kdbus->priv->kdbus_msg_items, part);
203 * _g_kdbus_hexdump_all_items:
207 _g_kdbus_hexdump_all_items (GSList *kdbus_msg_items)
212 ret = g_string_new (NULL);
214 while (kdbus_msg_items != NULL)
216 g_string_append_printf (ret, "\n Item %d\n", item);
217 g_string_append (ret, _g_dbus_hexdump (((msg_part*)kdbus_msg_items->data)->data, ((msg_part*)kdbus_msg_items->data)->size, 2));
219 kdbus_msg_items = g_slist_next(kdbus_msg_items);
223 return g_string_free (ret, FALSE);
232 g_kdbus_finalize (GObject *object)
234 GKdbus *kdbus = G_KDBUS (object);
236 if (kdbus->priv->kdbus_buffer != NULL)
237 munmap (kdbus->priv->kdbus_buffer, KDBUS_POOL_SIZE);
239 kdbus->priv->kdbus_buffer = NULL;
241 if (kdbus->priv->fd != -1 && !kdbus->priv->closed)
242 _g_kdbus_close (kdbus, NULL);
244 g_string_free (kdbus->priv->msg_sender, TRUE);
245 g_string_free (kdbus->priv->msg_destination, TRUE);
247 if (G_OBJECT_CLASS (g_kdbus_parent_class)->finalize)
248 (*G_OBJECT_CLASS (g_kdbus_parent_class)->finalize) (object);
253 * g_kdbus_class_init:
257 g_kdbus_class_init (GKdbusClass *klass)
259 GObjectClass *gobject_class G_GNUC_UNUSED = G_OBJECT_CLASS (klass);
261 g_type_class_add_private (klass, sizeof (GKdbusPrivate));
262 gobject_class->finalize = g_kdbus_finalize;
267 * g_kdbus_initable_iface_init:
271 g_kdbus_initable_iface_init (GInitableIface *iface)
273 iface->init = g_kdbus_initable_init;
282 g_kdbus_init (GKdbus *kdbus)
284 kdbus->priv = G_TYPE_INSTANCE_GET_PRIVATE (kdbus, G_TYPE_KDBUS, GKdbusPrivate);
286 kdbus->priv->fd = -1;
288 kdbus->priv->unique_id = -1;
289 kdbus->priv->unique_name = NULL;
291 kdbus->priv->kdbus_buffer = NULL;
292 kdbus->priv->kdbus_msg_items = NULL;
294 kdbus->priv->msg_sender = g_string_new (NULL);
295 kdbus->priv->msg_destination = g_string_new (NULL);
297 kdbus->priv->flags = 0; /* KDBUS_HELLO_ACCEPT_FD */
298 kdbus->priv->attach_flags_send = _KDBUS_ATTACH_ALL;
299 kdbus->priv->attach_flags_recv = _KDBUS_ATTACH_ALL;
301 kdbus->priv->fds = NULL;
302 kdbus->priv->num_fds = 0;
307 * g_kdbus_initable_init:
311 g_kdbus_initable_init (GInitable *initable,
312 GCancellable *cancellable,
317 g_return_val_if_fail (G_IS_KDBUS (initable), FALSE);
319 kdbus = G_KDBUS (initable);
321 if (cancellable != NULL)
323 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
324 _("Cancellable initialization not supported"));
328 kdbus->priv->inited = TRUE;
335 * kdbus_source_prepare:
339 kdbus_source_prepare (GSource *source,
342 GKdbusSource *kdbus_source = (GKdbusSource *)source;
344 if (g_cancellable_is_cancelled (kdbus_source->cancellable))
347 if (kdbus_source->timeout_time)
351 now = g_source_get_time (source);
353 *timeout = (kdbus_source->timeout_time - now + 999) / 1000;
356 kdbus_source->kdbus->priv->timed_out = TRUE;
364 if ((kdbus_source->condition & kdbus_source->pollfd.revents) != 0)
372 * kdbus_source_check:
376 kdbus_source_check (GSource *source)
380 return kdbus_source_prepare (source, &timeout);
385 * kdbus_source_dispatch
389 kdbus_source_dispatch (GSource *source,
390 GSourceFunc callback,
393 GKdbusSourceFunc func = (GKdbusSourceFunc)callback;
394 GKdbusSource *kdbus_source = (GKdbusSource *)source;
395 GKdbus *kdbus = kdbus_source->kdbus;
398 if (kdbus_source->kdbus->priv->timed_out)
399 kdbus_source->pollfd.revents |= kdbus_source->condition & (G_IO_IN | G_IO_OUT);
401 ret = (*func) (kdbus,
402 kdbus_source->pollfd.revents & kdbus_source->condition,
405 if (kdbus->priv->timeout)
406 kdbus_source->timeout_time = g_get_monotonic_time ()
407 + kdbus->priv->timeout * 1000000;
409 kdbus_source->timeout_time = 0;
416 * kdbus_source_finalize
420 kdbus_source_finalize (GSource *source)
422 GKdbusSource *kdbus_source = (GKdbusSource *)source;
425 kdbus = kdbus_source->kdbus;
427 g_object_unref (kdbus);
429 if (kdbus_source->cancellable)
431 g_cancellable_release_fd (kdbus_source->cancellable);
432 g_object_unref (kdbus_source->cancellable);
438 * kdbus_source_closure_callback:
442 kdbus_source_closure_callback (GKdbus *kdbus,
443 GIOCondition condition,
446 GClosure *closure = data;
447 GValue params[2] = { G_VALUE_INIT, G_VALUE_INIT };
448 GValue result_value = G_VALUE_INIT;
451 g_value_init (&result_value, G_TYPE_BOOLEAN);
453 g_value_init (¶ms[0], G_TYPE_KDBUS);
454 g_value_set_object (¶ms[0], kdbus);
455 g_value_init (¶ms[1], G_TYPE_IO_CONDITION);
456 g_value_set_flags (¶ms[1], condition);
458 g_closure_invoke (closure, &result_value, 2, params, NULL);
460 result = g_value_get_boolean (&result_value);
461 g_value_unset (&result_value);
462 g_value_unset (¶ms[0]);
463 g_value_unset (¶ms[1]);
469 static GSourceFuncs kdbus_source_funcs =
471 kdbus_source_prepare,
473 kdbus_source_dispatch,
474 kdbus_source_finalize,
475 (GSourceFunc)kdbus_source_closure_callback,
484 kdbus_source_new (GKdbus *kdbus,
485 GIOCondition condition,
486 GCancellable *cancellable)
489 GKdbusSource *kdbus_source;
491 source = g_source_new (&kdbus_source_funcs, sizeof (GKdbusSource));
492 g_source_set_name (source, "GKdbus");
493 kdbus_source = (GKdbusSource *)source;
495 kdbus_source->kdbus = g_object_ref (kdbus);
496 kdbus_source->condition = condition;
498 if (g_cancellable_make_pollfd (cancellable,
499 &kdbus_source->cancel_pollfd))
501 kdbus_source->cancellable = g_object_ref (cancellable);
502 g_source_add_poll (source, &kdbus_source->cancel_pollfd);
505 kdbus_source->pollfd.fd = kdbus->priv->fd;
506 kdbus_source->pollfd.events = condition;
507 kdbus_source->pollfd.revents = 0;
508 g_source_add_poll (source, &kdbus_source->pollfd);
510 if (kdbus->priv->timeout)
511 kdbus_source->timeout_time = g_get_monotonic_time ()
512 + kdbus->priv->timeout * 1000000;
514 kdbus_source->timeout_time = 0;
521 * _g_kdbus_create_source:
525 _g_kdbus_create_source (GKdbus *kdbus,
526 GIOCondition condition,
527 GCancellable *cancellable)
529 g_return_val_if_fail (G_IS_KDBUS (kdbus) && (cancellable == NULL || G_IS_CANCELLABLE (cancellable)), NULL);
531 return kdbus_source_new (kdbus, condition, cancellable);
540 _g_kdbus_open (GKdbus *kdbus,
541 const gchar *address,
544 g_return_val_if_fail (G_IS_KDBUS (kdbus), FALSE);
546 kdbus->priv->fd = open(address, O_RDWR|O_NOCTTY|O_CLOEXEC);
547 if (kdbus->priv->fd<0)
549 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, _("Can't open kdbus endpoint"));
553 kdbus->priv->closed = FALSE;
564 g_kdbus_free_data (GKdbus *kdbus,
567 struct kdbus_cmd_free cmd;
573 ret = ioctl (kdbus->priv->fd, KDBUS_CMD_FREE, &cmd);
582 * g_kdbus_translate_nameowner_flags:
586 g_kdbus_translate_nameowner_flags (GBusNameOwnerFlags flags,
587 guint64 *kdbus_flags)
593 if (flags & G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT)
594 new_flags |= KDBUS_NAME_ALLOW_REPLACEMENT;
596 if (flags & G_BUS_NAME_OWNER_FLAGS_REPLACE)
597 new_flags |= KDBUS_NAME_REPLACE_EXISTING;
599 if (!(flags & G_BUS_NAME_OWNER_FLAGS_DO_NOT_QUEUE))
600 new_flags |= KDBUS_NAME_QUEUE;
602 *kdbus_flags = new_flags;
611 _g_kdbus_close (GKdbus *kdbus,
616 g_return_val_if_fail (G_IS_KDBUS (kdbus), FALSE);
618 if (kdbus->priv->closed)
623 res = close (kdbus->priv->fd);
630 g_set_error (error, G_IO_ERROR,
631 g_io_error_from_errno (errno),
632 _("Error closing kdbus fd: %s"),
639 kdbus->priv->closed = TRUE;
640 kdbus->priv->fd = -1;
647 * _g_kdbus_is_closed:
651 _g_kdbus_is_closed (GKdbus *kdbus)
653 g_return_val_if_fail (G_IS_KDBUS (kdbus), FALSE);
655 return kdbus->priv->closed;
664 _g_kdbus_Hello (GIOStream *stream,
668 struct kdbus_cmd_hello *hello;
669 struct kdbus_item *item;
672 size_t size, conn_name_size;
674 kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (stream));
676 conn_name = "gdbus-kdbus";
677 conn_name_size = strlen (conn_name);
679 size = KDBUS_ALIGN8 (G_STRUCT_OFFSET (struct kdbus_cmd_hello, items)) +
680 KDBUS_ALIGN8 (G_STRUCT_OFFSET (struct kdbus_item, str) + conn_name_size + 1);
682 hello = g_alloca0 (size);
683 hello->flags = kdbus->priv->flags;
684 hello->attach_flags_send = kdbus->priv->attach_flags_send;
685 hello->attach_flags_recv = kdbus->priv->attach_flags_recv;
687 hello->pool_size = KDBUS_POOL_SIZE;
690 item->size = G_STRUCT_OFFSET (struct kdbus_item, str) + conn_name_size + 1;
691 item->type = KDBUS_ITEM_CONN_DESCRIPTION;
692 memcpy (item->str, conn_name, conn_name_size+1);
693 item = KDBUS_ITEM_NEXT (item);
695 if (ioctl(kdbus->priv->fd, KDBUS_CMD_HELLO, hello))
697 g_set_error (error, G_IO_ERROR,
698 g_io_error_from_errno (errno),
699 _("Failed to send HELLO: %s"),
704 kdbus->priv->kdbus_buffer = mmap(NULL, KDBUS_POOL_SIZE, PROT_READ, MAP_SHARED, kdbus->priv->fd, 0);
705 if (kdbus->priv->kdbus_buffer == MAP_FAILED)
707 g_set_error (error, G_IO_ERROR,
708 g_io_error_from_errno (errno),
714 if (hello->bus_flags > 0xFFFFFFFFULL)
716 g_set_error_literal (error,
719 _("Incompatible HELLO flags"));
723 memcpy (kdbus->priv->bus_id, hello->id128, 16);
725 kdbus->priv->unique_id = hello->id;
726 asprintf(&kdbus->priv->unique_name, ":1.%llu", (unsigned long long) hello->id);
728 /* read bloom filters parameters */
729 kdbus->priv->bloom_size = (gsize) hello->bloom.size;
730 kdbus->priv->bloom_n_hash = (guint) hello->bloom.n_hash;
732 return g_variant_new ("(s)", kdbus->priv->unique_name);
737 * _g_kdbus_RequestName:
741 _g_kdbus_RequestName (GDBusConnection *connection,
743 GBusNameOwnerFlags flags,
748 struct kdbus_cmd_name *kdbus_name;
753 status = G_BUS_REQUEST_NAME_FLAGS_PRIMARY_OWNER;
755 kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
758 g_set_error_literal (error,
760 G_DBUS_ERROR_IO_ERROR,
761 _("The connection is closed"));
765 if (!g_dbus_is_name (name))
769 G_DBUS_ERROR_INVALID_ARGS,
770 "Given bus name \"%s\" is not valid", name);
778 G_DBUS_ERROR_INVALID_ARGS,
779 "Cannot acquire a service starting with ':' such as \"%s\"", name);
783 g_kdbus_translate_nameowner_flags (flags, &kdbus_flags);
785 len = strlen(name) + 1;
786 size = G_STRUCT_OFFSET (struct kdbus_cmd_name, items) + KDBUS_ITEM_SIZE(len);
787 kdbus_name = g_alloca0 (size);
788 kdbus_name->size = size;
789 kdbus_name->items[0].size = KDBUS_ITEM_HEADER_SIZE + len;
790 kdbus_name->items[0].type = KDBUS_ITEM_NAME;
791 kdbus_name->flags = kdbus_flags;
792 memcpy (kdbus_name->items[0].str, name, len);
794 ret = ioctl(kdbus->priv->fd, KDBUS_CMD_NAME_ACQUIRE, kdbus_name);
798 status = G_BUS_REQUEST_NAME_FLAGS_EXISTS;
799 else if (errno == EALREADY)
800 status = G_BUS_REQUEST_NAME_FLAGS_ALREADY_OWNER;
803 g_set_error (error, G_IO_ERROR,
804 g_io_error_from_errno (errno),
805 _("Error while acquiring name: %s"),
811 if (kdbus_name->flags & KDBUS_NAME_IN_QUEUE)
812 status = G_BUS_REQUEST_NAME_FLAGS_IN_QUEUE;
814 result = g_variant_new ("(u)", status);
821 * _g_kdbus_ReleaseName:
825 _g_kdbus_ReleaseName (GDBusConnection *connection,
831 struct kdbus_cmd_name *kdbus_name;
835 status = G_BUS_RELEASE_NAME_FLAGS_RELEASED;
837 kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
840 g_set_error_literal (error,
842 G_DBUS_ERROR_IO_ERROR,
843 _("The connection is closed"));
847 if (!g_dbus_is_name (name))
851 G_DBUS_ERROR_INVALID_ARGS,
852 "Given bus name \"%s\" is not valid", name);
860 G_DBUS_ERROR_INVALID_ARGS,
861 "Cannot release a service starting with ':' such as \"%s\"", name);
865 len = strlen(name) + 1;
866 size = G_STRUCT_OFFSET (struct kdbus_cmd_name, items) + KDBUS_ITEM_SIZE(len);
867 kdbus_name = g_alloca0 (size);
868 kdbus_name->size = size;
869 kdbus_name->items[0].size = KDBUS_ITEM_HEADER_SIZE + len;
870 kdbus_name->items[0].type = KDBUS_ITEM_NAME;
871 memcpy (kdbus_name->items[0].str, name, len);
873 ret = ioctl(kdbus->priv->fd, KDBUS_CMD_NAME_RELEASE, kdbus_name);
877 status = G_BUS_RELEASE_NAME_FLAGS_NON_EXISTENT;
878 else if (errno == EADDRINUSE)
879 status = G_BUS_RELEASE_NAME_FLAGS_NOT_OWNER;
882 g_set_error (error, G_IO_ERROR,
883 g_io_error_from_errno (errno),
884 _("Error while releasing name: %s"),
890 result = g_variant_new ("(u)", status);
901 _g_kdbus_GetBusId (GDBusConnection *connection,
909 result_str = g_string_new (NULL);
910 kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
913 g_set_error_literal (error,
915 G_DBUS_ERROR_IO_ERROR,
916 _("The connection is closed"));
917 g_string_free (result_str, TRUE);
921 for (cnt=0; cnt<16; cnt++)
922 g_string_append_printf (result_str, "%02x", kdbus->priv->bus_id[cnt]);
924 result = g_variant_new ("(s)", result_str->str);
925 g_string_free (result_str, TRUE);
932 * _g_kdbus_GetListNames:
936 _g_kdbus_GetListNames (GDBusConnection *connection,
937 guint list_name_type,
942 GVariantBuilder *builder;
944 struct kdbus_cmd_name_list cmd = {};
945 struct kdbus_name_list *name_list;
946 struct kdbus_name_info *name;
952 kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
955 g_set_error_literal (error,
957 G_DBUS_ERROR_IO_ERROR,
958 _("The connection is closed"));
963 cmd.flags = KDBUS_NAME_LIST_ACTIVATORS; /* ListActivatableNames */
965 cmd.flags = KDBUS_NAME_LIST_UNIQUE | KDBUS_NAME_LIST_NAMES; /* ListNames */
967 ret = ioctl(kdbus->priv->fd, KDBUS_CMD_NAME_LIST, &cmd);
973 _("Error listing names"));
977 name_list = (struct kdbus_name_list *) ((guint8 *) kdbus->priv->kdbus_buffer + cmd.offset);
978 builder = g_variant_builder_new (G_VARIANT_TYPE ("as"));
980 KDBUS_ITEM_FOREACH(name, name_list, names)
982 struct kdbus_item *item;
983 const gchar *item_name = "";
985 if ((cmd.flags & KDBUS_NAME_LIST_UNIQUE) && name->owner_id != prev_id)
987 GString *unique_name;
989 unique_name = g_string_new (NULL);
990 g_string_printf (unique_name, ":1.%llu", name->owner_id);
991 g_variant_builder_add (builder, "s", unique_name->str);
992 g_string_free (unique_name,TRUE);
993 prev_id = name->owner_id;
996 KDBUS_ITEM_FOREACH(item, name, items)
997 if (item->type == KDBUS_ITEM_OWNED_NAME)
998 item_name = item->name.name;
1000 if (g_dbus_is_name (item_name))
1001 g_variant_builder_add (builder, "s", item_name);
1004 result = g_variant_new ("(as)", builder);
1005 g_variant_builder_unref (builder);
1007 g_kdbus_free_data (kdbus, cmd.offset);
1013 * _g_kdbus_NameHasOwner_internal:
1017 g_kdbus_NameHasOwner_internal (GKdbus *kdbus,
1021 struct kdbus_cmd_info *cmd;
1025 if (g_dbus_is_unique_name(name))
1027 size = G_STRUCT_OFFSET (struct kdbus_cmd_info, items);
1028 cmd = g_alloca0 (size);
1029 cmd->id = g_ascii_strtoull (name+3, NULL, 10);
1033 len = strlen(name) + 1;
1034 size = G_STRUCT_OFFSET (struct kdbus_cmd_info, items) + KDBUS_ITEM_SIZE(len);
1035 cmd = g_alloca0 (size);
1036 cmd->items[0].size = KDBUS_ITEM_HEADER_SIZE + len;
1037 cmd->items[0].type = KDBUS_ITEM_NAME;
1038 memcpy (cmd->items[0].str, name, len);
1042 ret = ioctl(kdbus->priv->fd, KDBUS_CMD_CONN_INFO, cmd);
1043 g_kdbus_free_data (kdbus, cmd->offset);
1053 * _g_kdbus_GetListQueuedOwners:
1057 _g_kdbus_GetListQueuedOwners (GDBusConnection *connection,
1063 GVariantBuilder *builder;
1064 GString *unique_name;
1067 struct kdbus_cmd_name_list cmd = {};
1068 struct kdbus_name_list *name_list;
1069 struct kdbus_name_info *kname;
1071 kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
1074 g_set_error_literal (error,
1076 G_DBUS_ERROR_IO_ERROR,
1077 _("The connection is closed"));
1081 if (!g_dbus_is_name (name))
1085 G_DBUS_ERROR_INVALID_ARGS,
1086 "Given bus name \"%s\" is not valid", name);
1090 if (!g_kdbus_NameHasOwner_internal (kdbus, name, error))
1094 G_DBUS_ERROR_NAME_HAS_NO_OWNER,
1095 "Could not get owner of name '%s': no such name", name);
1099 cmd.flags = KDBUS_NAME_LIST_QUEUED;
1100 ret = ioctl(kdbus->priv->fd, KDBUS_CMD_NAME_LIST, &cmd);
1105 G_DBUS_ERROR_FAILED,
1106 _("Error listing names"));
1110 name_list = (struct kdbus_name_list *) ((guint8 *) kdbus->priv->kdbus_buffer + cmd.offset);
1112 unique_name = g_string_new (NULL);
1113 builder = g_variant_builder_new (G_VARIANT_TYPE ("as"));
1114 KDBUS_ITEM_FOREACH(kname, name_list, names)
1116 struct kdbus_item *item;
1117 const char *item_name = "";
1119 KDBUS_ITEM_FOREACH(item, kname, items)
1120 if (item->type == KDBUS_ITEM_NAME)
1121 item_name = item->str;
1123 if (strcmp(item_name, name))
1126 g_string_printf (unique_name, ":1.%llu", kname->owner_id);
1127 g_variant_builder_add (builder, "s", item_name);
1130 result = g_variant_new ("(as)", builder);
1131 g_variant_builder_unref (builder);
1132 g_string_free (unique_name,TRUE);
1134 g_kdbus_free_data (kdbus, cmd.offset);
1140 * g_kdbus_GetConnInfo_internal:
1144 g_kdbus_GetConnInfo_internal (GDBusConnection *connection,
1152 struct kdbus_cmd_info *cmd;
1153 struct kdbus_info *conn_info;
1154 struct kdbus_item *item;
1159 kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
1162 g_set_error_literal (error,
1164 G_DBUS_ERROR_IO_ERROR,
1165 _("The connection is closed"));
1169 if (!g_dbus_is_name (name))
1173 G_DBUS_ERROR_INVALID_ARGS,
1174 "Given bus name \"%s\" is not valid", name);
1178 if (!g_kdbus_NameHasOwner_internal (kdbus, name, error))
1182 G_DBUS_ERROR_NAME_HAS_NO_OWNER,
1183 "Could not get owner of name '%s': no such name", name);
1187 if (g_dbus_is_unique_name(name))
1189 size = G_STRUCT_OFFSET (struct kdbus_cmd_info, items);
1190 cmd = g_alloca0 (size);
1191 cmd->id = g_ascii_strtoull (name+3, NULL, 10);
1195 len = strlen(name) + 1;
1196 size = G_STRUCT_OFFSET (struct kdbus_cmd_info, items) + KDBUS_ITEM_SIZE(len);
1197 cmd = g_alloca0 (size);
1198 cmd->items[0].size = KDBUS_ITEM_HEADER_SIZE + len;
1199 cmd->items[0].type = KDBUS_ITEM_NAME;
1200 memcpy (cmd->items[0].str, name, len);
1203 cmd->flags = _KDBUS_ATTACH_ALL;
1206 ret = ioctl(kdbus->priv->fd, KDBUS_CMD_CONN_INFO, cmd);
1211 G_DBUS_ERROR_FAILED,
1212 _("Could not get connection info"));
1216 conn_info = (struct kdbus_info *) ((guint8 *) kdbus->priv->kdbus_buffer + cmd->offset);
1219 if (conn_info->flags & KDBUS_HELLO_ACTIVATOR)
1223 if (flag == G_BUS_CREDS_UNIQUE_NAME)
1225 GString *unique_name;
1227 unique_name = g_string_new (NULL);
1228 g_string_printf (unique_name, ":1.%llu", (unsigned long long) conn_info->id);
1229 result = g_variant_new ("(s)", unique_name->str);
1230 g_string_free (unique_name,TRUE);
1234 KDBUS_ITEM_FOREACH(item, conn_info, items)
1238 case KDBUS_ITEM_PIDS:
1240 if (flag == G_BUS_CREDS_PID)
1242 guint pid = item->pids.pid;
1243 result = g_variant_new ("(u)", pid);
1247 case KDBUS_ITEM_CREDS:
1249 if (flag == G_BUS_CREDS_UID)
1251 guint uid = item->creds.uid;
1252 result = g_variant_new ("(u)", uid);
1256 case KDBUS_ITEM_SECLABEL:
1257 case KDBUS_ITEM_PID_COMM:
1258 case KDBUS_ITEM_TID_COMM:
1259 case KDBUS_ITEM_EXE:
1260 case KDBUS_ITEM_CMDLINE:
1261 case KDBUS_ITEM_CGROUP:
1262 case KDBUS_ITEM_CAPS:
1263 case KDBUS_ITEM_AUDIT:
1264 case KDBUS_ITEM_CONN_DESCRIPTION:
1265 case KDBUS_ITEM_AUXGROUPS:
1266 case KDBUS_ITEM_OWNED_NAME:
1272 g_kdbus_free_data (kdbus, cmd->offset);
1278 * _g_kdbus_GetNameOwner:
1282 _g_kdbus_GetNameOwner (GDBusConnection *connection,
1286 return g_kdbus_GetConnInfo_internal (connection,
1288 G_BUS_CREDS_UNIQUE_NAME,
1294 * _g_kdbus_GetConnectionUnixProcessID:
1298 _g_kdbus_GetConnectionUnixProcessID (GDBusConnection *connection,
1302 return g_kdbus_GetConnInfo_internal (connection,
1310 * _g_kdbus_GetConnectionUnixUser:
1314 _g_kdbus_GetConnectionUnixUser (GDBusConnection *connection,
1318 return g_kdbus_GetConnInfo_internal (connection,
1326 * _g_kdbus_match_remove:
1330 _g_kdbus_match_remove (GDBusConnection *connection,
1334 struct kdbus_cmd_match cmd_match = {};
1337 kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
1339 cmd_match.size = sizeof (cmd_match);
1340 cmd_match.cookie = cookie;
1342 ret = ioctl(kdbus->priv->fd, KDBUS_CMD_MATCH_REMOVE, &cmd_match);
1344 g_warning ("ERROR - %d\n", (int) errno);
1349 * _g_kdbus_subscribe_name_acquired:
1353 _g_kdbus_subscribe_name_owner_changed (GDBusConnection *connection,
1355 const gchar *old_name,
1356 const gchar *new_name,
1360 struct kdbus_item *item;
1361 struct kdbus_cmd_match *cmd_match;
1365 guint64 new_id = KDBUS_MATCH_ID_ANY;
1367 kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
1369 len = strlen(name) + 1;
1370 size = KDBUS_ALIGN8(G_STRUCT_OFFSET (struct kdbus_cmd_match, items) +
1371 G_STRUCT_OFFSET (struct kdbus_item, name_change) +
1372 G_STRUCT_OFFSET (struct kdbus_notify_name_change, name) + len);
1374 cmd_match = g_alloca0 (size);
1375 cmd_match->size = size;
1376 cmd_match->cookie = cookie;
1377 item = cmd_match->items;
1379 if (old_name[0] == 0)
1381 old_id = KDBUS_MATCH_ID_ANY;
1385 if (g_dbus_is_unique_name(old_name))
1391 if (new_name[0] == 0)
1393 new_id = KDBUS_MATCH_ID_ANY;
1397 if (g_dbus_is_unique_name(new_name))
1403 cmd_match = g_alloca0 (size);
1404 cmd_match->size = size;
1405 cmd_match->cookie = cookie;
1406 item = cmd_match->items;
1408 /* KDBUS_ITEM_NAME_CHANGE */
1409 item->type = KDBUS_ITEM_NAME_CHANGE;
1410 item->name_change.old_id.id = old_id;
1411 item->name_change.new_id.id = new_id;
1412 memcpy(item->name_change.name, name, len);
1413 item->size = G_STRUCT_OFFSET (struct kdbus_item, name_change) +
1414 G_STRUCT_OFFSET(struct kdbus_notify_name_change, name) + len;
1415 item = KDBUS_ITEM_NEXT(item);
1417 ret = ioctl(kdbus->priv->fd, KDBUS_CMD_MATCH_ADD, cmd_match);
1419 g_warning ("ERROR - %d\n", (int) errno);
1424 * _g_kdbus_subscribe_name_acquired:
1428 _g_kdbus_subscribe_name_acquired (GDBusConnection *connection,
1432 struct kdbus_item *item;
1433 struct kdbus_cmd_match *cmd_match;
1438 kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
1440 len = strlen(name) + 1;
1441 size = KDBUS_ALIGN8(G_STRUCT_OFFSET (struct kdbus_cmd_match, items) +
1442 G_STRUCT_OFFSET (struct kdbus_item, name_change) +
1443 G_STRUCT_OFFSET (struct kdbus_notify_name_change, name) + len);
1445 cookie = 0xbeefbeefbeefbeef;
1446 cmd_match = g_alloca0 (size);
1447 cmd_match->size = size;
1448 cmd_match->cookie = cookie;
1449 item = cmd_match->items;
1451 /* KDBUS_ITEM_NAME_ADD */
1452 item->type = KDBUS_ITEM_NAME_ADD;
1453 item->name_change.old_id.id = KDBUS_MATCH_ID_ANY;
1454 item->name_change.new_id.id = kdbus->priv->unique_id;
1455 memcpy(item->name_change.name, name, len);
1456 item->size = G_STRUCT_OFFSET (struct kdbus_item, name_change) +
1457 G_STRUCT_OFFSET(struct kdbus_notify_name_change, name) + len;
1458 item = KDBUS_ITEM_NEXT(item);
1460 ret = ioctl(kdbus->priv->fd, KDBUS_CMD_MATCH_ADD, cmd_match);
1462 g_warning ("ERROR - %d\n", (int) errno);
1464 _g_kdbus_subscribe_name_owner_changed (connection, name, "", kdbus->priv->unique_name, cookie);
1469 * _g_kdbus_subscribe_name_lost:
1473 _g_kdbus_subscribe_name_lost (GDBusConnection *connection,
1477 struct kdbus_item *item;
1478 struct kdbus_cmd_match *cmd_match;
1483 kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
1485 len = strlen(name) + 1;
1486 size = KDBUS_ALIGN8(G_STRUCT_OFFSET (struct kdbus_cmd_match, items) +
1487 G_STRUCT_OFFSET (struct kdbus_item, name_change) +
1488 G_STRUCT_OFFSET (struct kdbus_notify_name_change, name) + len);
1490 cookie = 0xdeafdeafdeafdeaf;
1491 cmd_match = g_alloca0 (size);
1492 cmd_match->size = size;
1493 cmd_match->cookie = cookie;
1494 item = cmd_match->items;
1496 /* KDBUS_ITEM_NAME_REMOVE */
1497 item->type = KDBUS_ITEM_NAME_REMOVE;
1498 item->name_change.old_id.id = kdbus->priv->unique_id;
1499 item->name_change.new_id.id = KDBUS_MATCH_ID_ANY;
1500 memcpy(item->name_change.name, name, len);
1501 item->size = G_STRUCT_OFFSET (struct kdbus_item, name_change) +
1502 G_STRUCT_OFFSET(struct kdbus_notify_name_change, name) + len;
1503 item = KDBUS_ITEM_NEXT(item);
1505 ret = ioctl(kdbus->priv->fd, KDBUS_CMD_MATCH_ADD, cmd_match);
1507 g_warning ("ERROR - %d\n", (int) errno);
1509 _g_kdbus_subscribe_name_owner_changed (connection, name, kdbus->priv->unique_name, "", cookie);
1514 * _g_kdbus_unsubscribe_name_acquired:
1518 _g_kdbus_unsubscribe_name_acquired (GDBusConnection *connection)
1522 cookie = 0xbeefbeefbeefbeef;
1523 _g_kdbus_match_remove (connection, cookie);
1528 * _g_kdbus_unsubscribe_name_lost:
1532 _g_kdbus_unsubscribe_name_lost (GDBusConnection *connection)
1536 cookie = 0xdeafdeafdeafdeaf;
1537 _g_kdbus_match_remove (connection, cookie);
1542 * _g_kdbus_release_msg:
1546 _g_kdbus_release_kmsg (GKdbus *kdbus)
1548 struct kdbus_item *item = NULL;
1549 GSList *iterator = NULL;
1552 offset = (guint8 *)kdbus->priv->kmsg - (guint8 *)kdbus->priv->kdbus_buffer;
1553 ioctl(kdbus->priv->fd, KDBUS_CMD_FREE, &offset);
1555 for (iterator = kdbus->priv->kdbus_msg_items; iterator; iterator = iterator->next)
1556 g_free ((msg_part*)iterator->data);
1558 g_slist_free (kdbus->priv->kdbus_msg_items);
1559 kdbus->priv->kdbus_msg_items = NULL;
1561 KDBUS_ITEM_FOREACH (item, kdbus->priv->kmsg, items)
1563 if (item->type == KDBUS_ITEM_PAYLOAD_MEMFD)
1564 close(item->memfd.fd);
1565 else if (item->type == KDBUS_ITEM_FDS)
1568 gint num_fds = (item->size - G_STRUCT_OFFSET(struct kdbus_item, fds)) / sizeof(int);
1570 for (i = 0; i < num_fds; i++)
1571 close(item->fds[i]);
1578 * g_kdbus_append_payload_vec:
1582 g_kdbus_append_payload_vec (struct kdbus_item **item,
1583 const void *data_ptr,
1586 *item = KDBUS_ALIGN8_PTR(*item);
1587 (*item)->size = G_STRUCT_OFFSET (struct kdbus_item, vec) + sizeof(struct kdbus_vec);
1588 (*item)->type = KDBUS_ITEM_PAYLOAD_VEC;
1589 (*item)->vec.address = (guint64)((guintptr)data_ptr);
1590 (*item)->vec.size = size;
1591 *item = KDBUS_ITEM_NEXT(*item);
1595 * g_kdbus_append_payload_memfd:
1599 g_kdbus_append_payload_memfd (struct kdbus_item **item,
1603 *item = KDBUS_ALIGN8_PTR(*item);
1604 (*item)->size = G_STRUCT_OFFSET (struct kdbus_item, memfd) + sizeof(struct kdbus_memfd);
1605 (*item)->type = KDBUS_ITEM_PAYLOAD_MEMFD;
1606 (*item)->memfd.fd = fd;
1607 (*item)->memfd.size = size;
1608 *item = KDBUS_ITEM_NEXT(*item);
1613 * g_kdbus_append_payload_destiantion:
1617 g_kdbus_append_destination (struct kdbus_item **item,
1618 const gchar *destination,
1621 *item = KDBUS_ALIGN8_PTR(*item);
1622 (*item)->size = G_STRUCT_OFFSET (struct kdbus_item, str) + size + 1;
1623 (*item)->type = KDBUS_ITEM_DST_NAME;
1624 memcpy ((*item)->str, destination, size+1);
1625 *item = KDBUS_ITEM_NEXT(*item);
1630 * g_kdbus_append_payload_bloom:
1633 static struct kdbus_bloom_filter *
1634 g_kdbus_append_bloom (struct kdbus_item **item,
1637 struct kdbus_item *bloom_item;
1639 bloom_item = KDBUS_ALIGN8_PTR(*item);
1640 bloom_item->size = G_STRUCT_OFFSET (struct kdbus_item, bloom_filter) +
1641 G_STRUCT_OFFSET (struct kdbus_bloom_filter, data) +
1644 bloom_item->type = KDBUS_ITEM_BLOOM_FILTER;
1646 *item = KDBUS_ITEM_NEXT(bloom_item);
1647 return &bloom_item->bloom_filter;
1652 * g_kdbus_append_fds:
1656 g_kdbus_append_fds (struct kdbus_item **item,
1657 GUnixFDList *fd_list)
1659 *item = KDBUS_ALIGN8_PTR(*item);
1660 (*item)->size = G_STRUCT_OFFSET (struct kdbus_item, fds) + sizeof(int) * g_unix_fd_list_get_length(fd_list);
1661 (*item)->type = KDBUS_ITEM_FDS;
1662 memcpy ((*item)->fds, g_unix_fd_list_peek_fds(fd_list, NULL), sizeof(int) * g_unix_fd_list_get_length(fd_list));
1664 *item = KDBUS_ITEM_NEXT(*item);
1669 * _g_kdbus_attach_fds_to_msg:
1673 _g_kdbus_attach_fds_to_msg (GKdbus *kdbus,
1674 GUnixFDList **fd_list)
1676 if ((kdbus->priv->fds != NULL) && (kdbus->priv->num_fds > 0))
1680 if (*fd_list == NULL)
1681 *fd_list = g_unix_fd_list_new();
1683 for (n = 0; n < kdbus->priv->num_fds; n++)
1685 g_unix_fd_list_append (*fd_list, kdbus->priv->fds[n], NULL);
1686 (void) g_close (kdbus->priv->fds[n], NULL);
1689 g_free (kdbus->priv->fds);
1690 kdbus->priv->fds = NULL;
1691 kdbus->priv->num_fds = 0;
1696 * g_kdbus_bloom_add_data:
1697 * Based on bus-bloom.c from systemd
1698 * http://cgit.freedesktop.org/systemd/systemd/tree/src/libsystemd/sd-bus/bus-bloom.c
1701 g_kdbus_bloom_add_data (GKdbus *kdbus,
1702 guint64 bloom_data [],
1708 guint bytes_num = 0;
1714 bit_num = kdbus->priv->bloom_size * 8;
1717 bytes_num = ((__builtin_clzll(bit_num) ^ 63U) + 7) / 8;
1719 for (cnt_1 = 0; cnt_1 < (kdbus->priv->bloom_n_hash); cnt_1++)
1721 for (cnt_2 = 0; cnt_2 < bytes_num; cnt_2++)
1725 g_siphash24(hash, data, n, hash_keys[cnt_1++]);
1729 p = (p << 8ULL) | (guint64) hash[8 - c];
1734 bloom_data[p >> 6] |= 1ULL << (p & 63);
1740 * g_kdbus_bloom_add_pair:
1744 g_kdbus_bloom_add_pair (GKdbus *kdbus,
1745 guint64 bloom_data [],
1746 const gchar *parameter,
1749 GString *data = g_string_new (NULL);
1751 g_string_printf (data,"%s:%s",parameter,value);
1752 g_kdbus_bloom_add_data(kdbus, bloom_data, data->str, data->len);
1753 g_string_free (data, TRUE);
1758 * g_kdbus_bloom_add_prefixes:
1762 g_kdbus_bloom_add_prefixes (GKdbus *kdbus,
1763 guint64 bloom_data [],
1764 const gchar *parameter,
1768 GString *data = g_string_new (NULL);
1770 g_string_printf (data,"%s:%s",parameter,value);
1775 last_sep = strrchr(data->str, separator);
1776 if (!last_sep || last_sep == data->str)
1780 g_kdbus_bloom_add_data(kdbus, bloom_data, data->str, last_sep-(data->str));
1782 g_string_free (data, TRUE);
1787 * g_kdbus_setup_bloom:
1788 * Based on bus-bloom.c from systemd
1789 * http://cgit.freedesktop.org/systemd/systemd/tree/src/libsystemd/sd-bus/bus-bloom.c
1792 g_kdbus_setup_bloom (GKdbus *kdbus,
1793 GDBusMessage *dbus_msg,
1794 struct kdbus_bloom_filter *bloom_filter)
1800 const gchar *message_type;
1801 const gchar *interface;
1802 const gchar *member;
1808 body = g_dbus_message_get_body (dbus_msg);
1809 message_type = _g_dbus_enum_to_string (G_TYPE_DBUS_MESSAGE_TYPE, g_dbus_message_get_message_type (dbus_msg));
1810 interface = g_dbus_message_get_interface (dbus_msg);
1811 member = g_dbus_message_get_member (dbus_msg);
1812 path = g_dbus_message_get_path (dbus_msg);
1814 bloom_data = bloom_filter->data;
1815 memset (bloom_data, 0, kdbus->priv->bloom_size);
1816 bloom_filter->generation = 0;
1818 g_kdbus_bloom_add_pair(kdbus, bloom_data, "message-type", message_type);
1821 g_kdbus_bloom_add_pair(kdbus, bloom_data, "interface", interface);
1824 g_kdbus_bloom_add_pair(kdbus, bloom_data, "member", member);
1828 g_kdbus_bloom_add_pair(kdbus, bloom_data, "path", path);
1829 g_kdbus_bloom_add_pair(kdbus, bloom_data, "path-slash-prefix", path);
1830 g_kdbus_bloom_add_prefixes(kdbus, bloom_data, "path-slash-prefix", path, '/');
1835 g_variant_iter_init (&iter, body);
1836 while ((child = g_variant_iter_next_value (&iter)))
1838 gchar buf[sizeof("arg")-1 + 2 + sizeof("-slash-prefix")];
1839 gchar *child_string;
1842 /* Is it necessary? */
1843 //if (g_variant_is_container (child))
1844 // iterate_container_recursive (child);
1846 if (!(g_variant_is_of_type (child, G_VARIANT_TYPE_STRING)) &&
1847 !(g_variant_is_of_type (child, G_VARIANT_TYPE_OBJECT_PATH)) &&
1848 !(g_variant_is_of_type (child, G_VARIANT_TYPE_SIGNATURE)))
1851 child_string = g_variant_dup_string (child, NULL);
1853 e = stpcpy(buf, "arg");
1855 *(e++) = '0' + (char) cnt;
1858 *(e++) = '0' + (char) (cnt / 10);
1859 *(e++) = '0' + (char) (cnt % 10);
1863 g_kdbus_bloom_add_pair(kdbus, bloom_data, buf, child_string);
1865 strcpy(e, "-dot-prefix");
1866 g_kdbus_bloom_add_prefixes(kdbus, bloom_data, buf, child_string, '.');
1868 strcpy(e, "-slash-prefix");
1869 g_kdbus_bloom_add_prefixes(kdbus, bloom_data, buf, child_string, '/');
1871 g_free (child_string);
1872 g_variant_unref (child);
1880 * TODO: g_kdbus_NameOwnerChanged_generate, g_kdbus_KernelMethodError_generate
1884 * g_kdbus_decode_kernel_msg:
1888 g_kdbus_decode_kernel_msg (GKdbus *kdbus)
1890 struct kdbus_item *item = NULL;
1893 KDBUS_ITEM_FOREACH(item, kdbus->priv->kmsg, items)
1897 case KDBUS_ITEM_ID_ADD:
1898 case KDBUS_ITEM_ID_REMOVE:
1899 case KDBUS_ITEM_NAME_ADD:
1900 case KDBUS_ITEM_NAME_REMOVE:
1901 case KDBUS_ITEM_NAME_CHANGE:
1902 //size = g_kdbus_NameOwnerChanged_generate (kdbus, item);
1903 g_error ("'NameOwnerChanged'");
1906 case KDBUS_ITEM_REPLY_TIMEOUT:
1907 case KDBUS_ITEM_REPLY_DEAD:
1908 //size = g_kdbus_KernelMethodError_generate (kdbus, item);
1909 g_error ("'KernelMethodError'");
1913 g_warning ("Unknown field in kernel message - %lld", item->type);
1918 /* Override information from the user header with data from the kernel */
1919 g_string_printf (kdbus->priv->msg_sender, "org.freedesktop.DBus");
1921 /* for destination */
1922 if (kdbus->priv->kmsg->dst_id == KDBUS_DST_ID_BROADCAST)
1923 /* for broadcast messages we don't have to set destination */
1925 else if (kdbus->priv->kmsg->dst_id == KDBUS_DST_ID_NAME)
1926 g_string_printf (kdbus->priv->msg_destination, ":1.%" G_GUINT64_FORMAT, (guint64) kdbus->priv->unique_id);
1928 g_string_printf (kdbus->priv->msg_destination, ":1.%" G_GUINT64_FORMAT, (guint64) kdbus->priv->kmsg->dst_id);
1935 * g_kdbus_decode_dbus_msg:
1938 static GDBusMessage *
1939 g_kdbus_decode_dbus_msg (GKdbus *kdbus,
1940 struct kdbus_cmd_recv *recv)
1942 struct kdbus_item *item;
1943 gssize data_size = 0;
1944 const gchar *destination = NULL;
1945 GArray *body_vectors;
1950 body_vectors = g_array_new (FALSE, FALSE, sizeof (GVariantVector));
1953 KDBUS_ITEM_FOREACH(item, (struct kdbus_msg *)((guint8 *)kdbus->priv->kdbus_buffer + recv->offset), items)
1955 if (item->size <= KDBUS_ITEM_HEADER_SIZE)
1956 g_error("[KDBUS] %llu bytes - invalid data record\n", item->size);
1958 data_size = item->size - KDBUS_ITEM_HEADER_SIZE;
1962 /* KDBUS_ITEM_DST_NAME */
1963 case KDBUS_ITEM_DST_NAME:
1964 destination = item->str;
1967 /* KDBUS_ITEM_PALOAD_OFF */
1968 case KDBUS_ITEM_PAYLOAD_OFF:
1970 GVariantVector vector;
1973 /* We want to make sure the bytes are aligned the same as
1974 * they would be if they appeared in a contiguously
1975 * allocated chunk of aligned memory.
1977 * We decide what the alignment 'should' be by consulting
1978 * body_size, which has been tracking the total size of the
1979 * message up to this point.
1981 * We then play around with the pointer by removing as many
1982 * bytes as required to get it to the proper alignment (and
1983 * copy extra bytes accordingly). This means that we will
1984 * grab some extra data in the 'bytes', but it won't be
1985 * shared with GVariant (which means there is no chance of
1986 * it being accidentally retransmitted).
1988 * The kernel does the same thing, so make sure we get the
1989 * expected result. Because of the kernel doing the same,
1990 * the result is that we will always be rounding-down to a
1991 * multiple of 8 for the pointer, which means that the
1992 * pointer will always be valid, assuming the original
1995 * We could fix this with a new GBytes constructor that took
1996 * 'flavour' as a parameter, but it's not worth it...
1998 flavour = body_size & 7;
1999 //g_assert ((item->vec.offset & 7) == flavour); FIXME: kdbus bug doesn't count memfd in flavouring
2001 vector.gbytes = g_bytes_new (((guchar *) kdbus->priv->kmsg) + item->vec.offset - flavour,
2002 item->vec.size + flavour);
2003 vector.data.pointer = g_bytes_get_data (vector.gbytes, NULL);
2004 vector.data.pointer += flavour;
2005 vector.size = item->vec.size;
2007 g_array_append_val (body_vectors, vector);
2008 body_size += vector.size;
2012 /* KDBUS_ITEM_PAYLOAD_MEMFD */
2013 case KDBUS_ITEM_PAYLOAD_MEMFD:
2015 GVariantVector vector;
2017 vector.gbytes = g_bytes_new_take_zero_copy_fd (item->memfd.fd);
2018 vector.data.pointer = g_bytes_get_data (vector.gbytes, &vector.size);
2019 g_print ("GB was %p/%d\n", vector.data.pointer, (guint) vector.size);
2021 g_array_append_val (body_vectors, vector);
2022 body_size += vector.size;
2026 /* KDBUS_ITEM_FDS */
2027 case KDBUS_ITEM_FDS:
2029 kdbus->priv->num_fds = data_size / sizeof(int);
2030 kdbus->priv->fds = g_malloc0 (sizeof(int) * kdbus->priv->num_fds);
2031 memcpy(kdbus->priv->fds, item->fds, sizeof(int) * kdbus->priv->num_fds);
2035 /* All of the following items, like CMDLINE,
2036 CGROUP, etc. need some GDBUS API extensions and
2037 should be implemented in the future */
2038 case KDBUS_ITEM_TIMESTAMP:
2040 g_print ("time: seq %llu mon %llu real %llu\n",
2041 item->timestamp.seqnum, item->timestamp.monotonic_ns, item->timestamp.realtime_ns);
2042 //g_dbus_message_set_timestamp (message, item->timestamp.monotonic_ns / 1000);
2043 //g_dbus_message_set_serial (message, item->timestamp.seqnum);
2047 case KDBUS_ITEM_CREDS:
2049 g_print ("creds: u%u eu %u su%u fsu%u g%u eg%u sg%u fsg%u\n",
2050 item->creds.uid, item->creds.euid, item->creds.suid, item->creds.fsuid,
2051 item->creds.gid, item->creds.egid, item->creds.sgid, item->creds.fsgid);
2055 case KDBUS_ITEM_PIDS:
2059 case KDBUS_ITEM_PID_COMM:
2060 case KDBUS_ITEM_TID_COMM:
2061 case KDBUS_ITEM_EXE:
2062 case KDBUS_ITEM_CMDLINE:
2063 case KDBUS_ITEM_CGROUP:
2064 case KDBUS_ITEM_AUDIT:
2065 case KDBUS_ITEM_CAPS:
2066 case KDBUS_ITEM_SECLABEL:
2067 case KDBUS_ITEM_CONN_DESCRIPTION:
2068 case KDBUS_ITEM_AUXGROUPS:
2069 case KDBUS_ITEM_OWNED_NAME:
2070 case KDBUS_ITEM_NAME:
2071 g_print ("unhandled %04x\n", (int) item->type);
2075 g_error ("[KDBUS] DBUS_PAYLOAD: Unknown filed - %lld", item->type);
2080 body = GLIB_PRIVATE_CALL(g_variant_from_vectors) (G_VARIANT_TYPE ("(ssa{sv})"),
2081 (GVariantVector *) body_vectors->data,
2082 body_vectors->len, body_size, FALSE);
2085 for (i = 0; i < body_vectors->len; i++)
2086 g_bytes_unref (g_array_index (body_vectors, GVariantVector, i).gbytes);
2088 g_array_free (body_vectors, TRUE);
2090 g_print ("body is %s\n", g_variant_print (body, TRUE));
2092 /* Override information from the user header with data from the kernel */
2094 if (kdbus->priv->kmsg->src_id == KDBUS_SRC_ID_KERNEL)
2095 g_string_printf (kdbus->priv->msg_sender, "org.freedesktop.DBus");
2097 g_string_printf (kdbus->priv->msg_sender, ":1.%" G_GUINT64_FORMAT, (guint64) kdbus->priv->kmsg->src_id);
2100 g_string_printf (kdbus->priv->msg_destination, "%s", destination);
2101 else if (kdbus->priv->kmsg->dst_id == KDBUS_DST_ID_BROADCAST)
2102 /* for broadcast messages we don't have to set destination */
2104 else if (kdbus->priv->kmsg->dst_id == KDBUS_DST_ID_NAME)
2105 g_string_printf (kdbus->priv->msg_destination, ":1.%" G_GUINT64_FORMAT, (guint64) kdbus->priv->unique_id);
2107 g_string_printf (kdbus->priv->msg_destination, ":1.%" G_GUINT64_FORMAT, (guint64) kdbus->priv->kmsg->dst_id);
2118 _g_kdbus_receive (GKdbus *kdbus,
2119 GCancellable *cancellable,
2122 struct kdbus_cmd_recv recv = {};
2124 if (g_cancellable_set_error_if_cancelled (cancellable, error))
2128 if (ioctl(kdbus->priv->fd, KDBUS_CMD_MSG_RECV, &recv) < 0)
2130 if (errno == EINTR || errno == EAGAIN)
2133 g_set_error (error, G_IO_ERROR,
2134 g_io_error_from_errno (errno),
2135 _("Error while receiving message: %s"),
2136 g_strerror (errno));
2140 kdbus->priv->kmsg = (struct kdbus_msg *)((guint8 *)kdbus->priv->kdbus_buffer + recv.offset);
2142 if (kdbus->priv->kmsg->payload_type == KDBUS_PAYLOAD_DBUS)
2143 g_kdbus_decode_dbus_msg (kdbus, &recv);
2144 else if (kdbus->priv->kmsg->payload_type == KDBUS_PAYLOAD_KERNEL)
2145 g_kdbus_decode_kernel_msg (kdbus);
2150 G_DBUS_ERROR_FAILED,
2151 _("Received unknown payload type"));
2160 * Returns: size of data sent or -1 when error
2163 _g_kdbus_send (GDBusWorker *worker,
2165 GDBusMessage *dbus_msg,
2166 GUnixFDList *fd_list,
2167 GCancellable *cancellable,
2170 GVariantVectors body_vectors;
2172 struct kdbus_msg* kmsg;
2173 struct kdbus_item *item;
2174 guint64 kmsg_size = 0;
2176 guint64 dst_id = KDBUS_DST_ID_BROADCAST;
2179 g_return_val_if_fail (G_IS_KDBUS (kdbus), -1);
2181 if (g_cancellable_set_error_if_cancelled (cancellable, error))
2184 body = g_dbus_message_get_body (dbus_msg);
2187 g_warning ("no body!");
2188 body = g_variant_new ("()");
2189 g_variant_ref_sink (body);
2192 g_variant_ref (body);
2193 GLIB_PRIVATE_CALL(g_variant_to_vectors) (body, &body_vectors);
2198 if ((name = g_dbus_message_get_destination(dbus_msg)))
2200 dst_id = KDBUS_DST_ID_NAME;
2201 if ((name[0] == ':') && (name[1] == '1') && (name[2] == '.'))
2203 dst_id = strtoull(&name[3], NULL, 10);
2209 * check and set message size
2211 kmsg_size = sizeof(struct kdbus_msg);
2213 { G_STATIC_ASSERT (sizeof (struct kdbus_vec) == sizeof (struct kdbus_memfd)); }
2214 kmsg_size += KDBUS_ITEM_SIZE(sizeof (struct kdbus_vec)) * body_vectors.vectors->len;
2216 if (fd_list != NULL && g_unix_fd_list_get_length (fd_list) > 0)
2217 kmsg_size += KDBUS_ALIGN8(G_STRUCT_OFFSET(struct kdbus_item, fds) + sizeof(int) * g_unix_fd_list_get_length(fd_list));
2220 kmsg_size += KDBUS_ITEM_SIZE(strlen(name) + 1);
2221 else if (dst_id == KDBUS_DST_ID_BROADCAST)
2222 kmsg_size += KDBUS_ALIGN8(G_STRUCT_OFFSET(struct kdbus_item, bloom_filter) +
2223 G_STRUCT_OFFSET(struct kdbus_bloom_filter, data) +
2224 kdbus->priv->bloom_size);
2226 kmsg = malloc(kmsg_size);
2228 g_error ("[KDBUS] kmsg malloc error");
2232 * set message header
2234 memset(kmsg, 0, kmsg_size);
2235 kmsg->size = kmsg_size;
2236 kmsg->payload_type = KDBUS_PAYLOAD_DBUS;
2237 kmsg->dst_id = name ? 0 : dst_id;
2238 kmsg->src_id = kdbus->priv->unique_id;
2239 kmsg->cookie = g_dbus_message_get_serial(dbus_msg);
2246 kmsg->flags = ((g_dbus_message_get_flags (dbus_msg) & G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED) ? 0 : KDBUS_MSG_FLAGS_EXPECT_REPLY) |
2247 ((g_dbus_message_get_flags (dbus_msg) & G_DBUS_MESSAGE_FLAGS_NO_AUTO_START) ? KDBUS_MSG_FLAGS_NO_AUTO_START : 0);
2249 if ((kmsg->flags) & KDBUS_MSG_FLAGS_EXPECT_REPLY)
2250 kmsg->timeout_ns = 2000000000;
2252 kmsg->cookie_reply = g_dbus_message_get_reply_serial(dbus_msg);
2259 for (i = 0; i < body_vectors.vectors->len; i++)
2261 GVariantVector vector = g_array_index (body_vectors.vectors, GVariantVector, i);
2267 fd = g_bytes_get_zero_copy_fd (vector.gbytes);
2271 gconstpointer bytes_data;
2274 bytes_data = g_bytes_get_data (vector.gbytes, &bytes_size);
2276 if (bytes_data == vector.data.pointer && bytes_size == vector.size)
2277 g_kdbus_append_payload_memfd (&item, fd, vector.size);
2279 g_kdbus_append_payload_vec (&item, vector.data.pointer, vector.size);
2282 g_kdbus_append_payload_vec (&item, vector.data.pointer, vector.size);
2285 g_kdbus_append_payload_vec (&item, body_vectors.extra_bytes->data + vector.data.offset, vector.size);
2288 /* if we don't use memfd, send whole message as a PAYLOAD_VEC item */
2292 * append destination or bloom filters
2295 g_kdbus_append_destination (&item, name, strlen(name));
2296 else if (dst_id == KDBUS_DST_ID_BROADCAST)
2298 struct kdbus_bloom_filter *bloom_filter;
2300 bloom_filter = g_kdbus_append_bloom (&item, kdbus->priv->bloom_size);
2301 g_kdbus_setup_bloom (kdbus, dbus_msg, bloom_filter);
2307 if (fd_list != NULL && g_unix_fd_list_get_length (fd_list) > 0)
2308 g_kdbus_append_fds (&item, fd_list);
2315 if (ioctl(kdbus->priv->fd, KDBUS_CMD_MSG_SEND, kmsg))
2318 GString *error_name;
2319 error_name = g_string_new (NULL);
2323 g_string_free (error_name,TRUE);
2326 else if (errno == ENXIO)
2328 g_string_printf (error_name, "Name %s does not exist", g_dbus_message_get_destination(dbus_msg));
2329 g_kdbus_generate_local_error (worker,
2331 g_variant_new ("(s)",error_name->str),
2332 G_DBUS_ERROR_SERVICE_UNKNOWN);
2333 g_string_free (error_name,TRUE);
2336 else if ((errno == ESRCH) || (errno == EADDRNOTAVAIL))
2338 if (kmsg->flags & KDBUS_MSG_FLAGS_NO_AUTO_START)
2340 g_string_printf (error_name, "Name %s does not exist", g_dbus_message_get_destination(dbus_msg));
2341 g_kdbus_generate_local_error (worker,
2343 g_variant_new ("(s)",error_name->str),
2344 G_DBUS_ERROR_SERVICE_UNKNOWN);
2345 g_string_free (error_name,TRUE);
2350 g_string_printf (error_name, "The name %s was not provided by any .service files", g_dbus_message_get_destination(dbus_msg));
2351 g_kdbus_generate_local_error (worker,
2353 g_variant_new ("(s)",error_name->str),
2354 G_DBUS_ERROR_SERVICE_UNKNOWN);
2355 g_string_free (error_name,TRUE);
2360 g_print ("[KDBUS] ioctl error sending kdbus message:%d (%m)\n",errno);
2361 g_set_error (error, G_IO_ERROR, g_io_error_from_errno(errno), _("Error sending message - KDBUS_CMD_MSG_SEND error"));
2363 perror("ioctl send");
2364 g_error ("IOCTL SEND: %d\n",errno);