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>
49 #include <gio/gunixfdlist.h>
52 #include "gunixfdmessage.h"
54 #define KDBUS_POOL_SIZE (16 * 1024LU * 1024LU)
55 #define KDBUS_ALIGN8(l) (((l) + 7) & ~7)
56 #define KDBUS_ALIGN8_PTR(p) ((void*) (uintptr_t)(p))
58 #define KDBUS_ITEM_HEADER_SIZE G_STRUCT_OFFSET(struct kdbus_item, data)
59 #define KDBUS_ITEM_SIZE(s) KDBUS_ALIGN8((s) + KDBUS_ITEM_HEADER_SIZE)
61 #define KDBUS_ITEM_NEXT(item) \
62 (typeof(item))(((guint8 *)item) + KDBUS_ALIGN8((item)->size))
63 #define KDBUS_ITEM_FOREACH(item, head, first) \
64 for (item = (head)->first; \
65 (guint8 *)(item) < (guint8 *)(head) + (head)->size; \
66 item = KDBUS_ITEM_NEXT(item))
68 #define g_alloca0(x) memset(g_alloca(x), '\0', (x))
70 static void g_kdbus_initable_iface_init (GInitableIface *iface);
71 static gboolean g_kdbus_initable_init (GInitable *initable,
72 GCancellable *cancellable,
75 #define g_kdbus_get_type _g_kdbus_get_type
76 G_DEFINE_TYPE_WITH_CODE (GKdbus, g_kdbus, G_TYPE_OBJECT,
77 G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
78 g_kdbus_initable_iface_init));
80 /* GBusCredentialsFlags */
85 G_BUS_CREDS_UNIQUE_NAME = 3,
86 G_BUS_CREDS_SELINUX_CONTEXT = 4
87 } GBusCredentialsFlags;
89 /* GKdbusPrivate struct */
95 struct kdbus_msg *kmsg;
101 guint64 attach_flags_send;
102 guint64 attach_flags_recv;
105 GString *msg_destination;
106 GSList *kdbus_msg_items;
122 /* GKdbusSource struct */
127 GIOCondition condition;
128 GCancellable *cancellable;
129 GPollFD cancel_pollfd;
134 typedef gboolean (*GKdbusSourceFunc) (GKdbus *kdbus,
135 GIOCondition condition,
138 /* Hash keys for bloom filters*/
139 const guint8 hash_keys[8][16] =
141 {0xb9,0x66,0x0b,0xf0,0x46,0x70,0x47,0xc1,0x88,0x75,0xc4,0x9c,0x54,0xb9,0xbd,0x15},
142 {0xaa,0xa1,0x54,0xa2,0xe0,0x71,0x4b,0x39,0xbf,0xe1,0xdd,0x2e,0x9f,0xc5,0x4a,0x3b},
143 {0x63,0xfd,0xae,0xbe,0xcd,0x82,0x48,0x12,0xa1,0x6e,0x41,0x26,0xcb,0xfa,0xa0,0xc8},
144 {0x23,0xbe,0x45,0x29,0x32,0xd2,0x46,0x2d,0x82,0x03,0x52,0x28,0xfe,0x37,0x17,0xf5},
145 {0x56,0x3b,0xbf,0xee,0x5a,0x4f,0x43,0x39,0xaf,0xaa,0x94,0x08,0xdf,0xf0,0xfc,0x10},
146 {0x31,0x80,0xc8,0x73,0xc7,0xea,0x46,0xd3,0xaa,0x25,0x75,0x0f,0x9e,0x4c,0x09,0x29},
147 {0x7d,0xf7,0x18,0x4b,0x7b,0xa4,0x44,0xd5,0x85,0x3c,0x06,0xe0,0x65,0x53,0x96,0x6d},
148 {0xf2,0x77,0xe9,0x6f,0x93,0xb5,0x4e,0x71,0x9a,0x0c,0x34,0x88,0x39,0x25,0xbf,0x35}
153 * _g_kdbus_get_last_msg_sender
157 _g_kdbus_get_last_msg_sender (GKdbus *kdbus)
159 return kdbus->priv->msg_sender->str;
164 * _g_kdbus_get_last_msg_destination
168 _g_kdbus_get_last_msg_destination (GKdbus *kdbus)
170 return kdbus->priv->msg_destination->str;
175 * _g_kdbus_get_last_msg_items:
179 _g_kdbus_get_last_msg_items (GKdbus *kdbus)
181 return kdbus->priv->kdbus_msg_items;
186 * g_kdbus_add_msg_part:
190 g_kdbus_add_msg_part (GKdbus *kdbus,
194 msg_part* part = g_new (msg_part, 1);
197 kdbus->priv->kdbus_msg_items = g_slist_append (kdbus->priv->kdbus_msg_items, part);
202 * _g_kdbus_hexdump_all_items:
206 _g_kdbus_hexdump_all_items (GSList *kdbus_msg_items)
211 ret = g_string_new (NULL);
213 while (kdbus_msg_items != NULL)
215 g_string_append_printf (ret, "\n Item %d\n", item);
216 g_string_append (ret, _g_dbus_hexdump (((msg_part*)kdbus_msg_items->data)->data, ((msg_part*)kdbus_msg_items->data)->size, 2));
218 kdbus_msg_items = g_slist_next(kdbus_msg_items);
222 return g_string_free (ret, FALSE);
231 g_kdbus_finalize (GObject *object)
233 GKdbus *kdbus = G_KDBUS (object);
235 if (kdbus->priv->kdbus_buffer != NULL)
236 munmap (kdbus->priv->kdbus_buffer, KDBUS_POOL_SIZE);
238 kdbus->priv->kdbus_buffer = NULL;
240 if (kdbus->priv->fd != -1 && !kdbus->priv->closed)
241 _g_kdbus_close (kdbus, NULL);
243 g_string_free (kdbus->priv->msg_sender, TRUE);
244 g_string_free (kdbus->priv->msg_destination, TRUE);
246 if (G_OBJECT_CLASS (g_kdbus_parent_class)->finalize)
247 (*G_OBJECT_CLASS (g_kdbus_parent_class)->finalize) (object);
252 * g_kdbus_class_init:
256 g_kdbus_class_init (GKdbusClass *klass)
258 GObjectClass *gobject_class G_GNUC_UNUSED = G_OBJECT_CLASS (klass);
260 g_type_class_add_private (klass, sizeof (GKdbusPrivate));
261 gobject_class->finalize = g_kdbus_finalize;
266 * g_kdbus_initable_iface_init:
270 g_kdbus_initable_iface_init (GInitableIface *iface)
272 iface->init = g_kdbus_initable_init;
281 g_kdbus_init (GKdbus *kdbus)
283 kdbus->priv = G_TYPE_INSTANCE_GET_PRIVATE (kdbus, G_TYPE_KDBUS, GKdbusPrivate);
285 kdbus->priv->fd = -1;
287 kdbus->priv->unique_id = -1;
288 kdbus->priv->unique_name = NULL;
290 kdbus->priv->kdbus_buffer = NULL;
291 kdbus->priv->kdbus_msg_items = NULL;
293 kdbus->priv->msg_sender = g_string_new (NULL);
294 kdbus->priv->msg_destination = g_string_new (NULL);
296 kdbus->priv->flags = 0; /* KDBUS_HELLO_ACCEPT_FD */
297 kdbus->priv->attach_flags_send = _KDBUS_ATTACH_ALL;
298 kdbus->priv->attach_flags_recv = _KDBUS_ATTACH_ALL;
300 kdbus->priv->fds = NULL;
301 kdbus->priv->num_fds = 0;
306 * g_kdbus_initable_init:
310 g_kdbus_initable_init (GInitable *initable,
311 GCancellable *cancellable,
316 g_return_val_if_fail (G_IS_KDBUS (initable), FALSE);
318 kdbus = G_KDBUS (initable);
320 if (cancellable != NULL)
322 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
323 _("Cancellable initialization not supported"));
327 kdbus->priv->inited = TRUE;
334 * kdbus_source_prepare:
338 kdbus_source_prepare (GSource *source,
341 GKdbusSource *kdbus_source = (GKdbusSource *)source;
343 if (g_cancellable_is_cancelled (kdbus_source->cancellable))
346 if (kdbus_source->timeout_time)
350 now = g_source_get_time (source);
352 *timeout = (kdbus_source->timeout_time - now + 999) / 1000;
355 kdbus_source->kdbus->priv->timed_out = TRUE;
363 if ((kdbus_source->condition & kdbus_source->pollfd.revents) != 0)
371 * kdbus_source_check:
375 kdbus_source_check (GSource *source)
379 return kdbus_source_prepare (source, &timeout);
384 * kdbus_source_dispatch
388 kdbus_source_dispatch (GSource *source,
389 GSourceFunc callback,
392 GKdbusSourceFunc func = (GKdbusSourceFunc)callback;
393 GKdbusSource *kdbus_source = (GKdbusSource *)source;
394 GKdbus *kdbus = kdbus_source->kdbus;
397 if (kdbus_source->kdbus->priv->timed_out)
398 kdbus_source->pollfd.revents |= kdbus_source->condition & (G_IO_IN | G_IO_OUT);
400 ret = (*func) (kdbus,
401 kdbus_source->pollfd.revents & kdbus_source->condition,
404 if (kdbus->priv->timeout)
405 kdbus_source->timeout_time = g_get_monotonic_time ()
406 + kdbus->priv->timeout * 1000000;
408 kdbus_source->timeout_time = 0;
415 * kdbus_source_finalize
419 kdbus_source_finalize (GSource *source)
421 GKdbusSource *kdbus_source = (GKdbusSource *)source;
424 kdbus = kdbus_source->kdbus;
426 g_object_unref (kdbus);
428 if (kdbus_source->cancellable)
430 g_cancellable_release_fd (kdbus_source->cancellable);
431 g_object_unref (kdbus_source->cancellable);
437 * kdbus_source_closure_callback:
441 kdbus_source_closure_callback (GKdbus *kdbus,
442 GIOCondition condition,
445 GClosure *closure = data;
446 GValue params[2] = { G_VALUE_INIT, G_VALUE_INIT };
447 GValue result_value = G_VALUE_INIT;
450 g_value_init (&result_value, G_TYPE_BOOLEAN);
452 g_value_init (¶ms[0], G_TYPE_KDBUS);
453 g_value_set_object (¶ms[0], kdbus);
454 g_value_init (¶ms[1], G_TYPE_IO_CONDITION);
455 g_value_set_flags (¶ms[1], condition);
457 g_closure_invoke (closure, &result_value, 2, params, NULL);
459 result = g_value_get_boolean (&result_value);
460 g_value_unset (&result_value);
461 g_value_unset (¶ms[0]);
462 g_value_unset (¶ms[1]);
468 static GSourceFuncs kdbus_source_funcs =
470 kdbus_source_prepare,
472 kdbus_source_dispatch,
473 kdbus_source_finalize,
474 (GSourceFunc)kdbus_source_closure_callback,
483 kdbus_source_new (GKdbus *kdbus,
484 GIOCondition condition,
485 GCancellable *cancellable)
488 GKdbusSource *kdbus_source;
490 source = g_source_new (&kdbus_source_funcs, sizeof (GKdbusSource));
491 g_source_set_name (source, "GKdbus");
492 kdbus_source = (GKdbusSource *)source;
494 kdbus_source->kdbus = g_object_ref (kdbus);
495 kdbus_source->condition = condition;
497 if (g_cancellable_make_pollfd (cancellable,
498 &kdbus_source->cancel_pollfd))
500 kdbus_source->cancellable = g_object_ref (cancellable);
501 g_source_add_poll (source, &kdbus_source->cancel_pollfd);
504 kdbus_source->pollfd.fd = kdbus->priv->fd;
505 kdbus_source->pollfd.events = condition;
506 kdbus_source->pollfd.revents = 0;
507 g_source_add_poll (source, &kdbus_source->pollfd);
509 if (kdbus->priv->timeout)
510 kdbus_source->timeout_time = g_get_monotonic_time ()
511 + kdbus->priv->timeout * 1000000;
513 kdbus_source->timeout_time = 0;
520 * _g_kdbus_create_source:
524 _g_kdbus_create_source (GKdbus *kdbus,
525 GIOCondition condition,
526 GCancellable *cancellable)
528 g_return_val_if_fail (G_IS_KDBUS (kdbus) && (cancellable == NULL || G_IS_CANCELLABLE (cancellable)), NULL);
530 return kdbus_source_new (kdbus, condition, cancellable);
539 _g_kdbus_open (GKdbus *kdbus,
540 const gchar *address,
543 g_return_val_if_fail (G_IS_KDBUS (kdbus), FALSE);
545 kdbus->priv->fd = open(address, O_RDWR|O_NOCTTY|O_CLOEXEC);
546 if (kdbus->priv->fd<0)
548 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, _("Can't open kdbus endpoint"));
552 kdbus->priv->closed = FALSE;
563 g_kdbus_free_data (GKdbus *kdbus,
566 struct kdbus_cmd_free cmd;
572 ret = ioctl (kdbus->priv->fd, KDBUS_CMD_FREE, &cmd);
581 * g_kdbus_translate_nameowner_flags:
585 g_kdbus_translate_nameowner_flags (GBusNameOwnerFlags flags,
586 guint64 *kdbus_flags)
592 if (flags & G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT)
593 new_flags |= KDBUS_NAME_ALLOW_REPLACEMENT;
595 if (flags & G_BUS_NAME_OWNER_FLAGS_REPLACE)
596 new_flags |= KDBUS_NAME_REPLACE_EXISTING;
598 if (!(flags & G_BUS_NAME_OWNER_FLAGS_DO_NOT_QUEUE))
599 new_flags |= KDBUS_NAME_QUEUE;
601 *kdbus_flags = new_flags;
610 _g_kdbus_close (GKdbus *kdbus,
615 g_return_val_if_fail (G_IS_KDBUS (kdbus), FALSE);
617 if (kdbus->priv->closed)
622 res = close (kdbus->priv->fd);
629 g_set_error (error, G_IO_ERROR,
630 g_io_error_from_errno (errno),
631 _("Error closing kdbus fd: %s"),
638 kdbus->priv->closed = TRUE;
639 kdbus->priv->fd = -1;
646 * _g_kdbus_is_closed:
650 _g_kdbus_is_closed (GKdbus *kdbus)
652 g_return_val_if_fail (G_IS_KDBUS (kdbus), FALSE);
654 return kdbus->priv->closed;
663 _g_kdbus_Hello (GIOStream *stream,
667 struct kdbus_cmd_hello *hello;
668 struct kdbus_item *item;
671 size_t size, conn_name_size;
673 kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (stream));
675 conn_name = "gdbus-kdbus";
676 conn_name_size = strlen (conn_name);
678 size = KDBUS_ALIGN8 (G_STRUCT_OFFSET (struct kdbus_cmd_hello, items)) +
679 KDBUS_ALIGN8 (G_STRUCT_OFFSET (struct kdbus_item, str) + conn_name_size + 1);
681 hello = g_alloca0 (size);
682 hello->flags = kdbus->priv->flags;
683 hello->attach_flags_send = kdbus->priv->attach_flags_send;
684 hello->attach_flags_recv = kdbus->priv->attach_flags_recv;
686 hello->pool_size = KDBUS_POOL_SIZE;
689 item->size = G_STRUCT_OFFSET (struct kdbus_item, str) + conn_name_size + 1;
690 item->type = KDBUS_ITEM_CONN_DESCRIPTION;
691 memcpy (item->str, conn_name, conn_name_size+1);
692 item = KDBUS_ITEM_NEXT (item);
694 if (ioctl(kdbus->priv->fd, KDBUS_CMD_HELLO, hello))
696 g_set_error (error, G_IO_ERROR,
697 g_io_error_from_errno (errno),
698 _("Failed to send HELLO: %s"),
703 kdbus->priv->kdbus_buffer = mmap(NULL, KDBUS_POOL_SIZE, PROT_READ, MAP_SHARED, kdbus->priv->fd, 0);
704 if (kdbus->priv->kdbus_buffer == MAP_FAILED)
706 g_set_error (error, G_IO_ERROR,
707 g_io_error_from_errno (errno),
713 if (hello->bus_flags > 0xFFFFFFFFULL)
715 g_set_error_literal (error,
718 _("Incompatible HELLO flags"));
722 memcpy (kdbus->priv->bus_id, hello->id128, 16);
724 kdbus->priv->unique_id = hello->id;
725 asprintf(&kdbus->priv->unique_name, ":1.%llu", (unsigned long long) hello->id);
727 /* read bloom filters parameters */
728 kdbus->priv->bloom_size = (gsize) hello->bloom.size;
729 kdbus->priv->bloom_n_hash = (guint) hello->bloom.n_hash;
731 return g_variant_new ("(s)", kdbus->priv->unique_name);
736 * _g_kdbus_RequestName:
740 _g_kdbus_RequestName (GDBusConnection *connection,
742 GBusNameOwnerFlags flags,
747 struct kdbus_cmd_name *kdbus_name;
752 status = G_BUS_REQUEST_NAME_FLAGS_PRIMARY_OWNER;
754 kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
757 g_set_error_literal (error,
759 G_DBUS_ERROR_IO_ERROR,
760 _("The connection is closed"));
764 if (!g_dbus_is_name (name))
768 G_DBUS_ERROR_INVALID_ARGS,
769 "Given bus name \"%s\" is not valid", name);
777 G_DBUS_ERROR_INVALID_ARGS,
778 "Cannot acquire a service starting with ':' such as \"%s\"", name);
782 g_kdbus_translate_nameowner_flags (flags, &kdbus_flags);
784 len = strlen(name) + 1;
785 size = G_STRUCT_OFFSET (struct kdbus_cmd_name, items) + KDBUS_ITEM_SIZE(len);
786 kdbus_name = g_alloca0 (size);
787 kdbus_name->size = size;
788 kdbus_name->items[0].size = KDBUS_ITEM_HEADER_SIZE + len;
789 kdbus_name->items[0].type = KDBUS_ITEM_NAME;
790 kdbus_name->flags = kdbus_flags;
791 memcpy (kdbus_name->items[0].str, name, len);
793 ret = ioctl(kdbus->priv->fd, KDBUS_CMD_NAME_ACQUIRE, kdbus_name);
797 status = G_BUS_REQUEST_NAME_FLAGS_EXISTS;
798 else if (errno == EALREADY)
799 status = G_BUS_REQUEST_NAME_FLAGS_ALREADY_OWNER;
802 g_set_error (error, G_IO_ERROR,
803 g_io_error_from_errno (errno),
804 _("Error while acquiring name: %s"),
810 if (kdbus_name->flags & KDBUS_NAME_IN_QUEUE)
811 status = G_BUS_REQUEST_NAME_FLAGS_IN_QUEUE;
813 result = g_variant_new ("(u)", status);
820 * _g_kdbus_ReleaseName:
824 _g_kdbus_ReleaseName (GDBusConnection *connection,
830 struct kdbus_cmd_name *kdbus_name;
834 status = G_BUS_RELEASE_NAME_FLAGS_RELEASED;
836 kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
839 g_set_error_literal (error,
841 G_DBUS_ERROR_IO_ERROR,
842 _("The connection is closed"));
846 if (!g_dbus_is_name (name))
850 G_DBUS_ERROR_INVALID_ARGS,
851 "Given bus name \"%s\" is not valid", name);
859 G_DBUS_ERROR_INVALID_ARGS,
860 "Cannot release a service starting with ':' such as \"%s\"", name);
864 len = strlen(name) + 1;
865 size = G_STRUCT_OFFSET (struct kdbus_cmd_name, items) + KDBUS_ITEM_SIZE(len);
866 kdbus_name = g_alloca0 (size);
867 kdbus_name->size = size;
868 kdbus_name->items[0].size = KDBUS_ITEM_HEADER_SIZE + len;
869 kdbus_name->items[0].type = KDBUS_ITEM_NAME;
870 memcpy (kdbus_name->items[0].str, name, len);
872 ret = ioctl(kdbus->priv->fd, KDBUS_CMD_NAME_RELEASE, kdbus_name);
876 status = G_BUS_RELEASE_NAME_FLAGS_NON_EXISTENT;
877 else if (errno == EADDRINUSE)
878 status = G_BUS_RELEASE_NAME_FLAGS_NOT_OWNER;
881 g_set_error (error, G_IO_ERROR,
882 g_io_error_from_errno (errno),
883 _("Error while releasing name: %s"),
889 result = g_variant_new ("(u)", status);
900 _g_kdbus_GetBusId (GDBusConnection *connection,
908 result_str = g_string_new (NULL);
909 kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
912 g_set_error_literal (error,
914 G_DBUS_ERROR_IO_ERROR,
915 _("The connection is closed"));
916 g_string_free (result_str, TRUE);
920 for (cnt=0; cnt<16; cnt++)
921 g_string_append_printf (result_str, "%02x", kdbus->priv->bus_id[cnt]);
923 result = g_variant_new ("(s)", result_str->str);
924 g_string_free (result_str, TRUE);
931 * _g_kdbus_GetListNames:
935 _g_kdbus_GetListNames (GDBusConnection *connection,
936 guint list_name_type,
941 GVariantBuilder *builder;
943 struct kdbus_cmd_name_list cmd = {};
944 struct kdbus_name_list *name_list;
945 struct kdbus_name_info *name;
951 kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
954 g_set_error_literal (error,
956 G_DBUS_ERROR_IO_ERROR,
957 _("The connection is closed"));
962 cmd.flags = KDBUS_NAME_LIST_ACTIVATORS; /* ListActivatableNames */
964 cmd.flags = KDBUS_NAME_LIST_UNIQUE | KDBUS_NAME_LIST_NAMES; /* ListNames */
966 ret = ioctl(kdbus->priv->fd, KDBUS_CMD_NAME_LIST, &cmd);
972 _("Error listing names"));
976 name_list = (struct kdbus_name_list *) ((guint8 *) kdbus->priv->kdbus_buffer + cmd.offset);
977 builder = g_variant_builder_new (G_VARIANT_TYPE ("as"));
979 KDBUS_ITEM_FOREACH(name, name_list, names)
981 struct kdbus_item *item;
982 const gchar *item_name = "";
984 if ((cmd.flags & KDBUS_NAME_LIST_UNIQUE) && name->owner_id != prev_id)
986 GString *unique_name;
988 unique_name = g_string_new (NULL);
989 g_string_printf (unique_name, ":1.%llu", name->owner_id);
990 g_variant_builder_add (builder, "s", unique_name->str);
991 g_string_free (unique_name,TRUE);
992 prev_id = name->owner_id;
995 KDBUS_ITEM_FOREACH(item, name, items)
996 if (item->type == KDBUS_ITEM_OWNED_NAME)
997 item_name = item->name.name;
999 if (g_dbus_is_name (item_name))
1000 g_variant_builder_add (builder, "s", item_name);
1003 result = g_variant_new ("(as)", builder);
1004 g_variant_builder_unref (builder);
1006 g_kdbus_free_data (kdbus, cmd.offset);
1012 * _g_kdbus_NameHasOwner_internal:
1016 g_kdbus_NameHasOwner_internal (GKdbus *kdbus,
1020 struct kdbus_cmd_info *cmd;
1024 if (g_dbus_is_unique_name(name))
1026 size = G_STRUCT_OFFSET (struct kdbus_cmd_info, items);
1027 cmd = g_alloca0 (size);
1028 cmd->id = g_ascii_strtoull (name+3, NULL, 10);
1032 len = strlen(name) + 1;
1033 size = G_STRUCT_OFFSET (struct kdbus_cmd_info, items) + KDBUS_ITEM_SIZE(len);
1034 cmd = g_alloca0 (size);
1035 cmd->items[0].size = KDBUS_ITEM_HEADER_SIZE + len;
1036 cmd->items[0].type = KDBUS_ITEM_NAME;
1037 memcpy (cmd->items[0].str, name, len);
1041 ret = ioctl(kdbus->priv->fd, KDBUS_CMD_CONN_INFO, cmd);
1042 g_kdbus_free_data (kdbus, cmd->offset);
1052 * _g_kdbus_GetListQueuedOwners:
1056 _g_kdbus_GetListQueuedOwners (GDBusConnection *connection,
1062 GVariantBuilder *builder;
1063 GString *unique_name;
1066 struct kdbus_cmd_name_list cmd = {};
1067 struct kdbus_name_list *name_list;
1068 struct kdbus_name_info *kname;
1070 kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
1073 g_set_error_literal (error,
1075 G_DBUS_ERROR_IO_ERROR,
1076 _("The connection is closed"));
1080 if (!g_dbus_is_name (name))
1084 G_DBUS_ERROR_INVALID_ARGS,
1085 "Given bus name \"%s\" is not valid", name);
1089 if (!g_kdbus_NameHasOwner_internal (kdbus, name, error))
1093 G_DBUS_ERROR_NAME_HAS_NO_OWNER,
1094 "Could not get owner of name '%s': no such name", name);
1098 cmd.flags = KDBUS_NAME_LIST_QUEUED;
1099 ret = ioctl(kdbus->priv->fd, KDBUS_CMD_NAME_LIST, &cmd);
1104 G_DBUS_ERROR_FAILED,
1105 _("Error listing names"));
1109 name_list = (struct kdbus_name_list *) ((guint8 *) kdbus->priv->kdbus_buffer + cmd.offset);
1111 unique_name = g_string_new (NULL);
1112 builder = g_variant_builder_new (G_VARIANT_TYPE ("as"));
1113 KDBUS_ITEM_FOREACH(kname, name_list, names)
1115 struct kdbus_item *item;
1116 const char *item_name = "";
1118 KDBUS_ITEM_FOREACH(item, kname, items)
1119 if (item->type == KDBUS_ITEM_NAME)
1120 item_name = item->str;
1122 if (strcmp(item_name, name))
1125 g_string_printf (unique_name, ":1.%llu", kname->owner_id);
1126 g_variant_builder_add (builder, "s", item_name);
1129 result = g_variant_new ("(as)", builder);
1130 g_variant_builder_unref (builder);
1131 g_string_free (unique_name,TRUE);
1133 g_kdbus_free_data (kdbus, cmd.offset);
1139 * g_kdbus_GetConnInfo_internal:
1143 g_kdbus_GetConnInfo_internal (GDBusConnection *connection,
1151 struct kdbus_cmd_info *cmd;
1152 struct kdbus_info *conn_info;
1153 struct kdbus_item *item;
1158 kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
1161 g_set_error_literal (error,
1163 G_DBUS_ERROR_IO_ERROR,
1164 _("The connection is closed"));
1168 if (!g_dbus_is_name (name))
1172 G_DBUS_ERROR_INVALID_ARGS,
1173 "Given bus name \"%s\" is not valid", name);
1177 if (!g_kdbus_NameHasOwner_internal (kdbus, name, error))
1181 G_DBUS_ERROR_NAME_HAS_NO_OWNER,
1182 "Could not get owner of name '%s': no such name", name);
1186 if (g_dbus_is_unique_name(name))
1188 size = G_STRUCT_OFFSET (struct kdbus_cmd_info, items);
1189 cmd = g_alloca0 (size);
1190 cmd->id = g_ascii_strtoull (name+3, NULL, 10);
1194 len = strlen(name) + 1;
1195 size = G_STRUCT_OFFSET (struct kdbus_cmd_info, items) + KDBUS_ITEM_SIZE(len);
1196 cmd = g_alloca0 (size);
1197 cmd->items[0].size = KDBUS_ITEM_HEADER_SIZE + len;
1198 cmd->items[0].type = KDBUS_ITEM_NAME;
1199 memcpy (cmd->items[0].str, name, len);
1202 cmd->flags = _KDBUS_ATTACH_ALL;
1205 ret = ioctl(kdbus->priv->fd, KDBUS_CMD_CONN_INFO, cmd);
1210 G_DBUS_ERROR_FAILED,
1211 _("Could not get connection info"));
1215 conn_info = (struct kdbus_info *) ((guint8 *) kdbus->priv->kdbus_buffer + cmd->offset);
1218 if (conn_info->flags & KDBUS_HELLO_ACTIVATOR)
1222 if (flag == G_BUS_CREDS_UNIQUE_NAME)
1224 GString *unique_name;
1226 unique_name = g_string_new (NULL);
1227 g_string_printf (unique_name, ":1.%llu", (unsigned long long) conn_info->id);
1228 result = g_variant_new ("(s)", unique_name->str);
1229 g_string_free (unique_name,TRUE);
1233 KDBUS_ITEM_FOREACH(item, conn_info, items)
1237 case KDBUS_ITEM_CREDS:
1239 if (flag == G_BUS_CREDS_PID)
1241 guint pid = item->creds.pid;
1242 result = g_variant_new ("(u)", pid);
1246 if (flag == G_BUS_CREDS_UID)
1248 guint uid = item->creds.uid;
1249 result = g_variant_new ("(u)", uid);
1253 case KDBUS_ITEM_SECLABEL:
1254 case KDBUS_ITEM_PID_COMM:
1255 case KDBUS_ITEM_TID_COMM:
1256 case KDBUS_ITEM_EXE:
1257 case KDBUS_ITEM_CMDLINE:
1258 case KDBUS_ITEM_CGROUP:
1259 case KDBUS_ITEM_CAPS:
1260 case KDBUS_ITEM_NAME:
1261 case KDBUS_ITEM_AUDIT:
1267 g_kdbus_free_data (kdbus, cmd->offset);
1273 * _g_kdbus_GetNameOwner:
1277 _g_kdbus_GetNameOwner (GDBusConnection *connection,
1281 return g_kdbus_GetConnInfo_internal (connection,
1283 G_BUS_CREDS_UNIQUE_NAME,
1289 * _g_kdbus_GetConnectionUnixProcessID:
1293 _g_kdbus_GetConnectionUnixProcessID (GDBusConnection *connection,
1297 return g_kdbus_GetConnInfo_internal (connection,
1305 * _g_kdbus_GetConnectionUnixUser:
1309 _g_kdbus_GetConnectionUnixUser (GDBusConnection *connection,
1313 return g_kdbus_GetConnInfo_internal (connection,
1321 * _g_kdbus_match_remove:
1325 _g_kdbus_match_remove (GDBusConnection *connection,
1329 struct kdbus_cmd_match cmd_match = {};
1332 kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
1334 cmd_match.size = sizeof (cmd_match);
1335 cmd_match.cookie = cookie;
1337 ret = ioctl(kdbus->priv->fd, KDBUS_CMD_MATCH_REMOVE, &cmd_match);
1339 g_warning ("ERROR - %d\n", (int) errno);
1344 * _g_kdbus_subscribe_name_acquired:
1348 _g_kdbus_subscribe_name_owner_changed (GDBusConnection *connection,
1350 const gchar *old_name,
1351 const gchar *new_name,
1355 struct kdbus_item *item;
1356 struct kdbus_cmd_match *cmd_match;
1360 guint64 new_id = KDBUS_MATCH_ID_ANY;
1362 kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
1364 len = strlen(name) + 1;
1365 size = KDBUS_ALIGN8(G_STRUCT_OFFSET (struct kdbus_cmd_match, items) +
1366 G_STRUCT_OFFSET (struct kdbus_item, name_change) +
1367 G_STRUCT_OFFSET (struct kdbus_notify_name_change, name) + len);
1369 cmd_match = g_alloca0 (size);
1370 cmd_match->size = size;
1371 cmd_match->cookie = cookie;
1372 item = cmd_match->items;
1374 if (old_name[0] == 0)
1376 old_id = KDBUS_MATCH_ID_ANY;
1380 if (g_dbus_is_unique_name(old_name))
1386 if (new_name[0] == 0)
1388 new_id = KDBUS_MATCH_ID_ANY;
1392 if (g_dbus_is_unique_name(new_name))
1398 cmd_match = g_alloca0 (size);
1399 cmd_match->size = size;
1400 cmd_match->cookie = cookie;
1401 item = cmd_match->items;
1403 /* KDBUS_ITEM_NAME_CHANGE */
1404 item->type = KDBUS_ITEM_NAME_CHANGE;
1405 item->name_change.old_id.id = old_id;
1406 item->name_change.new_id.id = new_id;
1407 memcpy(item->name_change.name, name, len);
1408 item->size = G_STRUCT_OFFSET (struct kdbus_item, name_change) +
1409 G_STRUCT_OFFSET(struct kdbus_notify_name_change, name) + len;
1410 item = KDBUS_ITEM_NEXT(item);
1412 ret = ioctl(kdbus->priv->fd, KDBUS_CMD_MATCH_ADD, cmd_match);
1414 g_warning ("ERROR - %d\n", (int) errno);
1419 * _g_kdbus_subscribe_name_acquired:
1423 _g_kdbus_subscribe_name_acquired (GDBusConnection *connection,
1427 struct kdbus_item *item;
1428 struct kdbus_cmd_match *cmd_match;
1433 kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
1435 len = strlen(name) + 1;
1436 size = KDBUS_ALIGN8(G_STRUCT_OFFSET (struct kdbus_cmd_match, items) +
1437 G_STRUCT_OFFSET (struct kdbus_item, name_change) +
1438 G_STRUCT_OFFSET (struct kdbus_notify_name_change, name) + len);
1440 cookie = 0xbeefbeefbeefbeef;
1441 cmd_match = g_alloca0 (size);
1442 cmd_match->size = size;
1443 cmd_match->cookie = cookie;
1444 item = cmd_match->items;
1446 /* KDBUS_ITEM_NAME_ADD */
1447 item->type = KDBUS_ITEM_NAME_ADD;
1448 item->name_change.old_id.id = KDBUS_MATCH_ID_ANY;
1449 item->name_change.new_id.id = kdbus->priv->unique_id;
1450 memcpy(item->name_change.name, name, len);
1451 item->size = G_STRUCT_OFFSET (struct kdbus_item, name_change) +
1452 G_STRUCT_OFFSET(struct kdbus_notify_name_change, name) + len;
1453 item = KDBUS_ITEM_NEXT(item);
1455 ret = ioctl(kdbus->priv->fd, KDBUS_CMD_MATCH_ADD, cmd_match);
1457 g_warning ("ERROR - %d\n", (int) errno);
1459 _g_kdbus_subscribe_name_owner_changed (connection, name, "", kdbus->priv->unique_name, cookie);
1464 * _g_kdbus_subscribe_name_lost:
1468 _g_kdbus_subscribe_name_lost (GDBusConnection *connection,
1472 struct kdbus_item *item;
1473 struct kdbus_cmd_match *cmd_match;
1478 kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
1480 len = strlen(name) + 1;
1481 size = KDBUS_ALIGN8(G_STRUCT_OFFSET (struct kdbus_cmd_match, items) +
1482 G_STRUCT_OFFSET (struct kdbus_item, name_change) +
1483 G_STRUCT_OFFSET (struct kdbus_notify_name_change, name) + len);
1485 cookie = 0xdeafdeafdeafdeaf;
1486 cmd_match = g_alloca0 (size);
1487 cmd_match->size = size;
1488 cmd_match->cookie = cookie;
1489 item = cmd_match->items;
1491 /* KDBUS_ITEM_NAME_REMOVE */
1492 item->type = KDBUS_ITEM_NAME_REMOVE;
1493 item->name_change.old_id.id = kdbus->priv->unique_id;
1494 item->name_change.new_id.id = KDBUS_MATCH_ID_ANY;
1495 memcpy(item->name_change.name, name, len);
1496 item->size = G_STRUCT_OFFSET (struct kdbus_item, name_change) +
1497 G_STRUCT_OFFSET(struct kdbus_notify_name_change, name) + len;
1498 item = KDBUS_ITEM_NEXT(item);
1500 ret = ioctl(kdbus->priv->fd, KDBUS_CMD_MATCH_ADD, cmd_match);
1502 g_warning ("ERROR - %d\n", (int) errno);
1504 _g_kdbus_subscribe_name_owner_changed (connection, name, kdbus->priv->unique_name, "", cookie);
1509 * _g_kdbus_unsubscribe_name_acquired:
1513 _g_kdbus_unsubscribe_name_acquired (GDBusConnection *connection)
1517 cookie = 0xbeefbeefbeefbeef;
1518 _g_kdbus_match_remove (connection, cookie);
1523 * _g_kdbus_unsubscribe_name_lost:
1527 _g_kdbus_unsubscribe_name_lost (GDBusConnection *connection)
1531 cookie = 0xdeafdeafdeafdeaf;
1532 _g_kdbus_match_remove (connection, cookie);
1537 * _g_kdbus_release_msg:
1541 _g_kdbus_release_kmsg (GKdbus *kdbus)
1543 struct kdbus_item *item = NULL;
1544 GSList *iterator = NULL;
1547 offset = (guint8 *)kdbus->priv->kmsg - (guint8 *)kdbus->priv->kdbus_buffer;
1548 ioctl(kdbus->priv->fd, KDBUS_CMD_FREE, &offset);
1550 for (iterator = kdbus->priv->kdbus_msg_items; iterator; iterator = iterator->next)
1551 g_free ((msg_part*)iterator->data);
1553 g_slist_free (kdbus->priv->kdbus_msg_items);
1554 kdbus->priv->kdbus_msg_items = NULL;
1556 KDBUS_ITEM_FOREACH (item, kdbus->priv->kmsg, items)
1558 if (item->type == KDBUS_ITEM_PAYLOAD_MEMFD)
1559 close(item->memfd.fd);
1560 else if (item->type == KDBUS_ITEM_FDS)
1563 gint num_fds = (item->size - G_STRUCT_OFFSET(struct kdbus_item, fds)) / sizeof(int);
1565 for (i = 0; i < num_fds; i++)
1566 close(item->fds[i]);
1573 * g_kdbus_append_payload_vec:
1577 g_kdbus_append_payload_vec (struct kdbus_item **item,
1578 const void *data_ptr,
1581 *item = KDBUS_ALIGN8_PTR(*item);
1582 (*item)->size = G_STRUCT_OFFSET (struct kdbus_item, vec) + sizeof(struct kdbus_vec);
1583 (*item)->type = KDBUS_ITEM_PAYLOAD_VEC;
1584 (*item)->vec.address = (guint64)((guintptr)data_ptr);
1585 (*item)->vec.size = size;
1586 *item = KDBUS_ITEM_NEXT(*item);
1591 * g_kdbus_append_payload_destiantion:
1595 g_kdbus_append_destination (struct kdbus_item **item,
1596 const gchar *destination,
1599 *item = KDBUS_ALIGN8_PTR(*item);
1600 (*item)->size = G_STRUCT_OFFSET (struct kdbus_item, str) + size + 1;
1601 (*item)->type = KDBUS_ITEM_DST_NAME;
1602 memcpy ((*item)->str, destination, size+1);
1603 *item = KDBUS_ITEM_NEXT(*item);
1608 * g_kdbus_append_payload_bloom:
1611 static struct kdbus_bloom_filter *
1612 g_kdbus_append_bloom (struct kdbus_item **item,
1615 struct kdbus_item *bloom_item;
1617 bloom_item = KDBUS_ALIGN8_PTR(*item);
1618 bloom_item->size = G_STRUCT_OFFSET (struct kdbus_item, bloom_filter) +
1619 G_STRUCT_OFFSET (struct kdbus_bloom_filter, data) +
1622 bloom_item->type = KDBUS_ITEM_BLOOM_FILTER;
1624 *item = KDBUS_ITEM_NEXT(bloom_item);
1625 return &bloom_item->bloom_filter;
1630 * g_kdbus_append_fds:
1634 g_kdbus_append_fds (struct kdbus_item **item,
1635 GUnixFDList *fd_list)
1637 *item = KDBUS_ALIGN8_PTR(*item);
1638 (*item)->size = G_STRUCT_OFFSET (struct kdbus_item, fds) + sizeof(int) * g_unix_fd_list_get_length(fd_list);
1639 (*item)->type = KDBUS_ITEM_FDS;
1640 memcpy ((*item)->fds, g_unix_fd_list_peek_fds(fd_list, NULL), sizeof(int) * g_unix_fd_list_get_length(fd_list));
1642 *item = KDBUS_ITEM_NEXT(*item);
1647 * _g_kdbus_attach_fds_to_msg:
1651 _g_kdbus_attach_fds_to_msg (GKdbus *kdbus,
1652 GUnixFDList **fd_list)
1654 if ((kdbus->priv->fds != NULL) && (kdbus->priv->num_fds > 0))
1658 if (*fd_list == NULL)
1659 *fd_list = g_unix_fd_list_new();
1661 for (n = 0; n < kdbus->priv->num_fds; n++)
1663 g_unix_fd_list_append (*fd_list, kdbus->priv->fds[n], NULL);
1664 (void) g_close (kdbus->priv->fds[n], NULL);
1667 g_free (kdbus->priv->fds);
1668 kdbus->priv->fds = NULL;
1669 kdbus->priv->num_fds = 0;
1674 * g_kdbus_bloom_add_data:
1675 * Based on bus-bloom.c from systemd
1676 * http://cgit.freedesktop.org/systemd/systemd/tree/src/libsystemd/sd-bus/bus-bloom.c
1679 g_kdbus_bloom_add_data (GKdbus *kdbus,
1680 guint64 bloom_data [],
1686 guint bytes_num = 0;
1692 bit_num = kdbus->priv->bloom_size * 8;
1695 bytes_num = ((__builtin_clzll(bit_num) ^ 63U) + 7) / 8;
1697 for (cnt_1 = 0; cnt_1 < (kdbus->priv->bloom_n_hash); cnt_1++)
1699 for (cnt_2 = 0; cnt_2 < bytes_num; cnt_2++)
1703 g_siphash24(hash, data, n, hash_keys[cnt_1++]);
1707 p = (p << 8ULL) | (guint64) hash[8 - c];
1712 bloom_data[p >> 6] |= 1ULL << (p & 63);
1718 * g_kdbus_bloom_add_pair:
1722 g_kdbus_bloom_add_pair (GKdbus *kdbus,
1723 guint64 bloom_data [],
1724 const gchar *parameter,
1727 GString *data = g_string_new (NULL);
1729 g_string_printf (data,"%s:%s",parameter,value);
1730 g_kdbus_bloom_add_data(kdbus, bloom_data, data->str, data->len);
1731 g_string_free (data, TRUE);
1736 * g_kdbus_bloom_add_prefixes:
1740 g_kdbus_bloom_add_prefixes (GKdbus *kdbus,
1741 guint64 bloom_data [],
1742 const gchar *parameter,
1746 GString *data = g_string_new (NULL);
1748 g_string_printf (data,"%s:%s",parameter,value);
1753 last_sep = strrchr(data->str, separator);
1754 if (!last_sep || last_sep == data->str)
1758 g_kdbus_bloom_add_data(kdbus, bloom_data, data->str, last_sep-(data->str));
1760 g_string_free (data, TRUE);
1765 * g_kdbus_setup_bloom:
1766 * Based on bus-bloom.c from systemd
1767 * http://cgit.freedesktop.org/systemd/systemd/tree/src/libsystemd/sd-bus/bus-bloom.c
1770 g_kdbus_setup_bloom (GKdbus *kdbus,
1771 GDBusMessage *dbus_msg,
1772 struct kdbus_bloom_filter *bloom_filter)
1778 const gchar *message_type;
1779 const gchar *interface;
1780 const gchar *member;
1786 body = g_dbus_message_get_body (dbus_msg);
1787 message_type = _g_dbus_enum_to_string (G_TYPE_DBUS_MESSAGE_TYPE, g_dbus_message_get_message_type (dbus_msg));
1788 interface = g_dbus_message_get_interface (dbus_msg);
1789 member = g_dbus_message_get_member (dbus_msg);
1790 path = g_dbus_message_get_path (dbus_msg);
1792 bloom_data = bloom_filter->data;
1793 memset (bloom_data, 0, kdbus->priv->bloom_size);
1794 bloom_filter->generation = 0;
1796 g_kdbus_bloom_add_pair(kdbus, bloom_data, "message-type", message_type);
1799 g_kdbus_bloom_add_pair(kdbus, bloom_data, "interface", interface);
1802 g_kdbus_bloom_add_pair(kdbus, bloom_data, "member", member);
1806 g_kdbus_bloom_add_pair(kdbus, bloom_data, "path", path);
1807 g_kdbus_bloom_add_pair(kdbus, bloom_data, "path-slash-prefix", path);
1808 g_kdbus_bloom_add_prefixes(kdbus, bloom_data, "path-slash-prefix", path, '/');
1813 g_variant_iter_init (&iter, body);
1814 while ((child = g_variant_iter_next_value (&iter)))
1816 gchar buf[sizeof("arg")-1 + 2 + sizeof("-slash-prefix")];
1817 gchar *child_string;
1820 /* Is it necessary? */
1821 //if (g_variant_is_container (child))
1822 // iterate_container_recursive (child);
1824 if (!(g_variant_is_of_type (child, G_VARIANT_TYPE_STRING)) &&
1825 !(g_variant_is_of_type (child, G_VARIANT_TYPE_OBJECT_PATH)) &&
1826 !(g_variant_is_of_type (child, G_VARIANT_TYPE_SIGNATURE)))
1829 child_string = g_variant_dup_string (child, NULL);
1831 e = stpcpy(buf, "arg");
1833 *(e++) = '0' + (char) cnt;
1836 *(e++) = '0' + (char) (cnt / 10);
1837 *(e++) = '0' + (char) (cnt % 10);
1841 g_kdbus_bloom_add_pair(kdbus, bloom_data, buf, child_string);
1843 strcpy(e, "-dot-prefix");
1844 g_kdbus_bloom_add_prefixes(kdbus, bloom_data, buf, child_string, '.');
1846 strcpy(e, "-slash-prefix");
1847 g_kdbus_bloom_add_prefixes(kdbus, bloom_data, buf, child_string, '/');
1849 g_free (child_string);
1850 g_variant_unref (child);
1858 * TODO: g_kdbus_NameOwnerChanged_generate, g_kdbus_KernelMethodError_generate
1862 * g_kdbus_decode_kernel_msg:
1866 g_kdbus_decode_kernel_msg (GKdbus *kdbus)
1868 struct kdbus_item *item = NULL;
1871 KDBUS_ITEM_FOREACH(item, kdbus->priv->kmsg, items)
1875 case KDBUS_ITEM_ID_ADD:
1876 case KDBUS_ITEM_ID_REMOVE:
1877 case KDBUS_ITEM_NAME_ADD:
1878 case KDBUS_ITEM_NAME_REMOVE:
1879 case KDBUS_ITEM_NAME_CHANGE:
1880 //size = g_kdbus_NameOwnerChanged_generate (kdbus, item);
1881 g_error ("'NameOwnerChanged'");
1884 case KDBUS_ITEM_REPLY_TIMEOUT:
1885 case KDBUS_ITEM_REPLY_DEAD:
1886 //size = g_kdbus_KernelMethodError_generate (kdbus, item);
1887 g_error ("'KernelMethodError'");
1891 g_warning ("Unknown field in kernel message - %lld", item->type);
1896 /* Override information from the user header with data from the kernel */
1897 g_string_printf (kdbus->priv->msg_sender, "org.freedesktop.DBus");
1899 /* for destination */
1900 if (kdbus->priv->kmsg->dst_id == KDBUS_DST_ID_BROADCAST)
1901 /* for broadcast messages we don't have to set destination */
1903 else if (kdbus->priv->kmsg->dst_id == KDBUS_DST_ID_NAME)
1904 g_string_printf (kdbus->priv->msg_destination, ":1.%" G_GUINT64_FORMAT, (guint64) kdbus->priv->unique_id);
1906 g_string_printf (kdbus->priv->msg_destination, ":1.%" G_GUINT64_FORMAT, (guint64) kdbus->priv->kmsg->dst_id);
1913 * g_kdbus_decode_dbus_msg:
1917 g_kdbus_decode_dbus_msg (GKdbus *kdbus)
1919 struct kdbus_item *item;
1921 gssize ret_size = 0;
1922 gssize data_size = 0;
1923 const gchar *destination = NULL;
1925 KDBUS_ITEM_FOREACH(item, kdbus->priv->kmsg, items)
1927 if (item->size <= KDBUS_ITEM_HEADER_SIZE)
1928 g_error("[KDBUS] %llu bytes - invalid data record\n", item->size);
1930 data_size = item->size - KDBUS_ITEM_HEADER_SIZE;
1935 /* KDBUS_ITEM_DST_NAME */
1936 case KDBUS_ITEM_DST_NAME:
1937 destination = item->str;
1940 /* KDBUS_ITEM_PALOAD_OFF */
1941 case KDBUS_ITEM_PAYLOAD_OFF:
1943 msg_ptr = (gchar*) kdbus->priv->kmsg + item->vec.offset;
1944 g_kdbus_add_msg_part (kdbus, msg_ptr, item->vec.size);
1945 ret_size += item->vec.size;
1949 /* KDBUS_ITEM_PAYLOAD_MEMFD */
1950 case KDBUS_ITEM_PAYLOAD_MEMFD:
1952 msg_ptr = mmap(NULL, item->memfd.size, PROT_READ, MAP_SHARED, item->memfd.fd, 0);
1954 if (msg_ptr == MAP_FAILED)
1956 g_print ("mmap() fd=%i failed:%m", item->memfd.fd);
1960 g_kdbus_add_msg_part (kdbus, msg_ptr, item->memfd.size);
1961 ret_size += item->memfd.size;
1965 /* KDBUS_ITEM_FDS */
1966 case KDBUS_ITEM_FDS:
1968 kdbus->priv->num_fds = data_size / sizeof(int);
1969 kdbus->priv->fds = g_malloc0 (sizeof(int) * kdbus->priv->num_fds);
1970 memcpy(kdbus->priv->fds, item->fds, sizeof(int) * kdbus->priv->num_fds);
1974 /* All of the following items, like CMDLINE,
1975 CGROUP, etc. need some GDBUS API extensions and
1976 should be implemented in the future */
1977 case KDBUS_ITEM_CREDS:
1978 case KDBUS_ITEM_TIMESTAMP:
1979 case KDBUS_ITEM_PID_COMM:
1980 case KDBUS_ITEM_TID_COMM:
1981 case KDBUS_ITEM_EXE:
1982 case KDBUS_ITEM_CMDLINE:
1983 case KDBUS_ITEM_CGROUP:
1984 case KDBUS_ITEM_AUDIT:
1985 case KDBUS_ITEM_CAPS:
1986 case KDBUS_ITEM_SECLABEL:
1987 case KDBUS_ITEM_CONN_DESCRIPTION:
1988 case KDBUS_ITEM_AUXGROUPS:
1989 case KDBUS_ITEM_OWNED_NAME:
1990 case KDBUS_ITEM_NAME:
1994 g_error ("[KDBUS] DBUS_PAYLOAD: Unknown filed - %lld", item->type);
1999 /* Override information from the user header with data from the kernel */
2001 if (kdbus->priv->kmsg->src_id == KDBUS_SRC_ID_KERNEL)
2002 g_string_printf (kdbus->priv->msg_sender, "org.freedesktop.DBus");
2004 g_string_printf (kdbus->priv->msg_sender, ":1.%" G_GUINT64_FORMAT, (guint64) kdbus->priv->kmsg->src_id);
2007 g_string_printf (kdbus->priv->msg_destination, "%s", destination);
2008 else if (kdbus->priv->kmsg->dst_id == KDBUS_DST_ID_BROADCAST)
2009 /* for broadcast messages we don't have to set destination */
2011 else if (kdbus->priv->kmsg->dst_id == KDBUS_DST_ID_NAME)
2012 g_string_printf (kdbus->priv->msg_destination, ":1.%" G_GUINT64_FORMAT, (guint64) kdbus->priv->unique_id);
2014 g_string_printf (kdbus->priv->msg_destination, ":1.%" G_GUINT64_FORMAT, (guint64) kdbus->priv->kmsg->dst_id);
2025 _g_kdbus_receive (GKdbus *kdbus,
2026 GCancellable *cancellable,
2029 struct kdbus_cmd_recv recv = {};
2032 if (g_cancellable_set_error_if_cancelled (cancellable, error))
2036 if (ioctl(kdbus->priv->fd, KDBUS_CMD_MSG_RECV, &recv) < 0)
2038 if (errno == EINTR || errno == EAGAIN)
2041 g_set_error (error, G_IO_ERROR,
2042 g_io_error_from_errno (errno),
2043 _("Error while receiving message: %s"),
2044 g_strerror (errno));
2048 kdbus->priv->kmsg = (struct kdbus_msg *)((guint8 *)kdbus->priv->kdbus_buffer + recv.offset);
2050 if (kdbus->priv->kmsg->payload_type == KDBUS_PAYLOAD_DBUS)
2051 size = g_kdbus_decode_dbus_msg (kdbus);
2052 else if (kdbus->priv->kmsg->payload_type == KDBUS_PAYLOAD_KERNEL)
2053 size = g_kdbus_decode_kernel_msg (kdbus);
2058 G_DBUS_ERROR_FAILED,
2059 _("Received unknown payload type"));
2069 * Returns: size of data sent or -1 when error
2072 _g_kdbus_send (GDBusWorker *worker,
2074 GDBusMessage *dbus_msg,
2077 GUnixFDList *fd_list,
2078 GCancellable *cancellable,
2081 struct kdbus_msg* kmsg;
2082 struct kdbus_item *item;
2083 guint64 kmsg_size = 0;
2085 guint64 dst_id = KDBUS_DST_ID_BROADCAST;
2087 g_return_val_if_fail (G_IS_KDBUS (kdbus), -1);
2089 if (g_cancellable_set_error_if_cancelled (cancellable, error))
2095 if ((name = g_dbus_message_get_destination(dbus_msg)))
2097 dst_id = KDBUS_DST_ID_NAME;
2098 if ((name[0] == ':') && (name[1] == '1') && (name[2] == '.'))
2100 dst_id = strtoull(&name[3], NULL, 10);
2106 * check and set message size
2108 kmsg_size = sizeof(struct kdbus_msg);
2109 kmsg_size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec)); /* header + body */
2111 if (fd_list != NULL && g_unix_fd_list_get_length (fd_list) > 0)
2112 kmsg_size += KDBUS_ALIGN8(G_STRUCT_OFFSET(struct kdbus_item, fds) + sizeof(int) * g_unix_fd_list_get_length(fd_list));
2115 kmsg_size += KDBUS_ITEM_SIZE(strlen(name) + 1);
2116 else if (dst_id == KDBUS_DST_ID_BROADCAST)
2117 kmsg_size += KDBUS_ALIGN8(G_STRUCT_OFFSET(struct kdbus_item, bloom_filter) +
2118 G_STRUCT_OFFSET(struct kdbus_bloom_filter, data) +
2119 kdbus->priv->bloom_size);
2121 kmsg = malloc(kmsg_size);
2123 g_error ("[KDBUS] kmsg malloc error");
2127 * set message header
2129 memset(kmsg, 0, kmsg_size);
2130 kmsg->size = kmsg_size;
2131 kmsg->payload_type = KDBUS_PAYLOAD_DBUS;
2132 kmsg->dst_id = name ? 0 : dst_id;
2133 kmsg->src_id = kdbus->priv->unique_id;
2134 kmsg->cookie = g_dbus_message_get_serial(dbus_msg);
2141 kmsg->flags = ((g_dbus_message_get_flags (dbus_msg) & G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED) ? 0 : KDBUS_MSG_FLAGS_EXPECT_REPLY) |
2142 ((g_dbus_message_get_flags (dbus_msg) & G_DBUS_MESSAGE_FLAGS_NO_AUTO_START) ? KDBUS_MSG_FLAGS_NO_AUTO_START : 0);
2144 if ((kmsg->flags) & KDBUS_MSG_FLAGS_EXPECT_REPLY)
2145 kmsg->timeout_ns = 2000000000;
2147 kmsg->cookie_reply = g_dbus_message_get_reply_serial(dbus_msg);
2155 /* if we don't use memfd, send whole message as a PAYLOAD_VEC item */
2156 g_kdbus_append_payload_vec (&item, blob, blob_size);
2160 * append destination or bloom filters
2163 g_kdbus_append_destination (&item, name, strlen(name));
2164 else if (dst_id == KDBUS_DST_ID_BROADCAST)
2166 struct kdbus_bloom_filter *bloom_filter;
2168 bloom_filter = g_kdbus_append_bloom (&item, kdbus->priv->bloom_size);
2169 g_kdbus_setup_bloom (kdbus, dbus_msg, bloom_filter);
2175 if (fd_list != NULL && g_unix_fd_list_get_length (fd_list) > 0)
2176 g_kdbus_append_fds (&item, fd_list);
2183 if (ioctl(kdbus->priv->fd, KDBUS_CMD_MSG_SEND, kmsg))
2186 GString *error_name;
2187 error_name = g_string_new (NULL);
2191 g_string_free (error_name,TRUE);
2194 else if (errno == ENXIO)
2196 g_string_printf (error_name, "Name %s does not exist", g_dbus_message_get_destination(dbus_msg));
2197 g_kdbus_generate_local_error (worker,
2199 g_variant_new ("(s)",error_name->str),
2200 G_DBUS_ERROR_SERVICE_UNKNOWN);
2201 g_string_free (error_name,TRUE);
2204 else if ((errno == ESRCH) || (errno == EADDRNOTAVAIL))
2206 if (kmsg->flags & KDBUS_MSG_FLAGS_NO_AUTO_START)
2208 g_string_printf (error_name, "Name %s does not exist", g_dbus_message_get_destination(dbus_msg));
2209 g_kdbus_generate_local_error (worker,
2211 g_variant_new ("(s)",error_name->str),
2212 G_DBUS_ERROR_SERVICE_UNKNOWN);
2213 g_string_free (error_name,TRUE);
2218 g_string_printf (error_name, "The name %s was not provided by any .service files", g_dbus_message_get_destination(dbus_msg));
2219 g_kdbus_generate_local_error (worker,
2221 g_variant_new ("(s)",error_name->str),
2222 G_DBUS_ERROR_SERVICE_UNKNOWN);
2223 g_string_free (error_name,TRUE);
2228 g_print ("[KDBUS] ioctl error sending kdbus message:%d (%m)\n",errno);
2229 g_set_error (error, G_IO_ERROR, g_io_error_from_errno(errno), _("Error sending message - KDBUS_CMD_MSG_SEND error"));
2231 g_error ("IOCTL SEND: %d\n",errno);