[kdbus] sync with kdbus (kdbus.h - commit: b024fb43c66b)
[platform/upstream/glib.git] / gio / gkdbus.c
1 /*  GIO - GLib Input, Output and Streaming Library
2  *
3  * Copyright (C) 2013 Samsung Electronics
4  *
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.
9  *
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.
14  *
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.
19  *
20  * Author: Michal Eljasiewicz   <m.eljasiewic@samsung.com>
21  * Author: Lukasz Skalski       <l.skalski@samsung.com>
22  */
23
24 #include "config.h"
25 #include "gkdbus.h"
26 #include "glib-unix.h"
27 #include "glibintl.h"
28 #include "kdbus.h"
29 #include "gkdbusconnection.h"
30
31 #include <gio/gio.h>
32 #include <errno.h>
33 #include <string.h>
34 #include <sys/mman.h>
35 #include <sys/ioctl.h>
36 #include <stdio.h>
37 #include <stdint.h>
38
39 #ifdef HAVE_SYS_FILIO_H
40 # include <sys/filio.h>
41 #endif
42
43 #ifdef HAVE_SYS_UIO_H
44 #include <sys/uio.h>
45 #endif
46
47 #include <glib/gstdio.h>
48 #include <gio/gio.h>
49 #include <gio/gunixfdlist.h>
50
51 #include "glibintl.h"
52 #include "gunixfdmessage.h"
53
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))
57
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)
60
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))
67
68 #define g_alloca0(x) memset(g_alloca(x), '\0', (x))
69
70 static void     g_kdbus_initable_iface_init (GInitableIface  *iface);
71 static gboolean g_kdbus_initable_init       (GInitable       *initable,
72                                              GCancellable    *cancellable,
73                                              GError         **error);
74
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));
79
80 /* GBusCredentialsFlags */
81 typedef enum
82 {
83   G_BUS_CREDS_PID              = 1,
84   G_BUS_CREDS_UID              = 2,
85   G_BUS_CREDS_UNIQUE_NAME      = 3,
86   G_BUS_CREDS_SELINUX_CONTEXT  = 4
87 } GBusCredentialsFlags;
88
89 /* GKdbusPrivate struct */
90 struct _GKdbusPrivate
91 {
92   gint               fd;
93
94   gchar             *kdbus_buffer;
95   struct kdbus_msg  *kmsg;
96
97   gchar             *unique_name;
98   guint64            unique_id;
99
100   guint64            flags;
101   guint64            attach_flags_send;
102   guint64            attach_flags_recv;
103
104   GString           *msg_sender;
105   GString           *msg_destination;
106   GSList            *kdbus_msg_items;
107
108   gint              *fds;
109   gint               num_fds;
110
111   gsize              bloom_size;
112   guint              bloom_n_hash;
113
114   guint              closed : 1;
115   guint              inited : 1;
116   guint              timeout;
117   guint              timed_out : 1;
118
119   guchar             bus_id[16];
120 };
121
122 /* GKdbusSource struct */
123 typedef struct {
124   GSource        source;
125   GPollFD        pollfd;
126   GKdbus        *kdbus;
127   GIOCondition   condition;
128   GCancellable  *cancellable;
129   GPollFD        cancel_pollfd;
130   gint64         timeout_time;
131 } GKdbusSource;
132
133
134 typedef gboolean (*GKdbusSourceFunc) (GKdbus *kdbus,
135                                       GIOCondition condition,
136                                       gpointer user_data);
137
138 /* Hash keys for bloom filters*/
139 const guint8 hash_keys[8][16] =
140 {
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}
149 };
150
151
152 /**
153  * _g_kdbus_get_last_msg_sender
154  *
155  */
156 gchar *
157 _g_kdbus_get_last_msg_sender (GKdbus  *kdbus)
158 {
159   return kdbus->priv->msg_sender->str;
160 }
161
162
163 /**
164  * _g_kdbus_get_last_msg_destination
165  *
166  */
167 gchar *
168 _g_kdbus_get_last_msg_destination (GKdbus  *kdbus)
169 {
170   return kdbus->priv->msg_destination->str;
171 }
172
173
174 /**
175  * _g_kdbus_get_last_msg_items:
176  *
177  */
178 GSList *
179 _g_kdbus_get_last_msg_items (GKdbus  *kdbus)
180 {
181   return kdbus->priv->kdbus_msg_items;
182 }
183
184
185 /**
186  * g_kdbus_add_msg_part:
187  *
188  */
189 static void
190 g_kdbus_add_msg_part (GKdbus  *kdbus,
191                       gchar   *data,
192                       gsize    size)
193 {
194   msg_part* part = g_new (msg_part, 1);
195   part->data = data;
196   part->size = size;
197   kdbus->priv->kdbus_msg_items = g_slist_append (kdbus->priv->kdbus_msg_items, part);
198 }
199
200
201 /**
202  * _g_kdbus_hexdump_all_items:
203  *
204  */
205 gchar *
206 _g_kdbus_hexdump_all_items (GSList  *kdbus_msg_items)
207 {
208
209   GString *ret;
210   gint item = 1;
211   ret = g_string_new (NULL);
212
213   while (kdbus_msg_items != NULL)
214     {
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));
217
218       kdbus_msg_items = g_slist_next(kdbus_msg_items);
219       item++;
220     }
221
222   return g_string_free (ret, FALSE);
223 }
224
225
226 /**
227  * g_kdbus_finalize:
228  *
229  */
230 static void
231 g_kdbus_finalize (GObject  *object)
232 {
233   GKdbus *kdbus = G_KDBUS (object);
234
235   if (kdbus->priv->kdbus_buffer != NULL)
236     munmap (kdbus->priv->kdbus_buffer, KDBUS_POOL_SIZE);
237
238   kdbus->priv->kdbus_buffer = NULL;
239
240   if (kdbus->priv->fd != -1 && !kdbus->priv->closed)
241     _g_kdbus_close (kdbus, NULL);
242
243   g_string_free (kdbus->priv->msg_sender, TRUE);
244   g_string_free (kdbus->priv->msg_destination, TRUE);
245
246   if (G_OBJECT_CLASS (g_kdbus_parent_class)->finalize)
247     (*G_OBJECT_CLASS (g_kdbus_parent_class)->finalize) (object);
248 }
249
250
251 /**
252  * g_kdbus_class_init:
253  *
254  */
255 static void
256 g_kdbus_class_init (GKdbusClass  *klass)
257 {
258   GObjectClass *gobject_class G_GNUC_UNUSED = G_OBJECT_CLASS (klass);
259
260   g_type_class_add_private (klass, sizeof (GKdbusPrivate));
261   gobject_class->finalize = g_kdbus_finalize;
262 }
263
264
265 /**
266  * g_kdbus_initable_iface_init:
267  *
268  */
269 static void
270 g_kdbus_initable_iface_init (GInitableIface  *iface)
271 {
272   iface->init = g_kdbus_initable_init;
273 }
274
275
276 /**
277  * g_kdbus_init:
278  *
279  */
280 static void
281 g_kdbus_init (GKdbus  *kdbus)
282 {
283   kdbus->priv = G_TYPE_INSTANCE_GET_PRIVATE (kdbus, G_TYPE_KDBUS, GKdbusPrivate);
284
285   kdbus->priv->fd = -1;
286
287   kdbus->priv->unique_id = -1;
288   kdbus->priv->unique_name = NULL;
289
290   kdbus->priv->kdbus_buffer = NULL;
291   kdbus->priv->kdbus_msg_items = NULL;
292
293   kdbus->priv->msg_sender = g_string_new (NULL);
294   kdbus->priv->msg_destination = g_string_new (NULL);
295
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;
299
300   kdbus->priv->fds = NULL;
301   kdbus->priv->num_fds = 0;
302 }
303
304
305 /**
306  * g_kdbus_initable_init:
307  *
308  */
309 static gboolean
310 g_kdbus_initable_init (GInitable     *initable,
311                        GCancellable  *cancellable,
312                        GError       **error)
313 {
314   GKdbus *kdbus;
315
316   g_return_val_if_fail (G_IS_KDBUS (initable), FALSE);
317
318   kdbus = G_KDBUS (initable);
319
320   if (cancellable != NULL)
321     {
322       g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
323                            _("Cancellable initialization not supported"));
324       return FALSE;
325     }
326
327   kdbus->priv->inited = TRUE;
328
329   return TRUE;
330 }
331
332
333 /**
334  * kdbus_source_prepare:
335  *
336  */
337 static gboolean
338 kdbus_source_prepare (GSource  *source,
339                       gint     *timeout)
340 {
341   GKdbusSource *kdbus_source = (GKdbusSource *)source;
342
343   if (g_cancellable_is_cancelled (kdbus_source->cancellable))
344     return TRUE;
345
346   if (kdbus_source->timeout_time)
347     {
348       gint64 now;
349
350       now = g_source_get_time (source);
351
352       *timeout = (kdbus_source->timeout_time - now + 999) / 1000;
353       if (*timeout < 0)
354         {
355           kdbus_source->kdbus->priv->timed_out = TRUE;
356           *timeout = 0;
357           return TRUE;
358         }
359     }
360   else
361     *timeout = -1;
362
363   if ((kdbus_source->condition & kdbus_source->pollfd.revents) != 0)
364     return TRUE;
365
366   return FALSE;
367 }
368
369
370 /**
371  * kdbus_source_check:
372  *
373  */
374 static gboolean
375 kdbus_source_check (GSource  *source)
376 {
377   gint timeout;
378
379   return kdbus_source_prepare (source, &timeout);
380 }
381
382
383 /**
384  * kdbus_source_dispatch
385  *
386  */
387 static gboolean
388 kdbus_source_dispatch  (GSource      *source,
389                         GSourceFunc   callback,
390                         gpointer      user_data)
391 {
392   GKdbusSourceFunc func = (GKdbusSourceFunc)callback;
393   GKdbusSource *kdbus_source = (GKdbusSource *)source;
394   GKdbus *kdbus = kdbus_source->kdbus;
395   gboolean ret;
396
397   if (kdbus_source->kdbus->priv->timed_out)
398     kdbus_source->pollfd.revents |= kdbus_source->condition & (G_IO_IN | G_IO_OUT);
399
400   ret = (*func) (kdbus,
401                  kdbus_source->pollfd.revents & kdbus_source->condition,
402                  user_data);
403
404   if (kdbus->priv->timeout)
405     kdbus_source->timeout_time = g_get_monotonic_time ()
406                                + kdbus->priv->timeout * 1000000;
407   else
408     kdbus_source->timeout_time = 0;
409
410   return ret;
411 }
412
413
414 /**
415  * kdbus_source_finalize
416  *
417  */
418 static void
419 kdbus_source_finalize (GSource  *source)
420 {
421   GKdbusSource *kdbus_source = (GKdbusSource *)source;
422   GKdbus *kdbus;
423
424   kdbus = kdbus_source->kdbus;
425
426   g_object_unref (kdbus);
427
428   if (kdbus_source->cancellable)
429     {
430       g_cancellable_release_fd (kdbus_source->cancellable);
431       g_object_unref (kdbus_source->cancellable);
432     }
433 }
434
435
436 /**
437  * kdbus_source_closure_callback:
438  *
439  */
440 static gboolean
441 kdbus_source_closure_callback (GKdbus        *kdbus,
442                                GIOCondition   condition,
443                                gpointer       data)
444 {
445   GClosure *closure = data;
446   GValue params[2] = { G_VALUE_INIT, G_VALUE_INIT };
447   GValue result_value = G_VALUE_INIT;
448   gboolean result;
449
450   g_value_init (&result_value, G_TYPE_BOOLEAN);
451
452   g_value_init (&params[0], G_TYPE_KDBUS);
453   g_value_set_object (&params[0], kdbus);
454   g_value_init (&params[1], G_TYPE_IO_CONDITION);
455   g_value_set_flags (&params[1], condition);
456
457   g_closure_invoke (closure, &result_value, 2, params, NULL);
458
459   result = g_value_get_boolean (&result_value);
460   g_value_unset (&result_value);
461   g_value_unset (&params[0]);
462   g_value_unset (&params[1]);
463
464   return result;
465 }
466
467
468 static GSourceFuncs kdbus_source_funcs =
469 {
470   kdbus_source_prepare,
471   kdbus_source_check,
472   kdbus_source_dispatch,
473   kdbus_source_finalize,
474   (GSourceFunc)kdbus_source_closure_callback,
475 };
476
477
478 /**
479  * kdbus_source_new:
480  *
481  */
482 static GSource *
483 kdbus_source_new (GKdbus        *kdbus,
484                   GIOCondition   condition,
485                   GCancellable  *cancellable)
486 {
487   GSource *source;
488   GKdbusSource *kdbus_source;
489
490   source = g_source_new (&kdbus_source_funcs, sizeof (GKdbusSource));
491   g_source_set_name (source, "GKdbus");
492   kdbus_source = (GKdbusSource *)source;
493
494   kdbus_source->kdbus = g_object_ref (kdbus);
495   kdbus_source->condition = condition;
496
497   if (g_cancellable_make_pollfd (cancellable,
498                                  &kdbus_source->cancel_pollfd))
499     {
500       kdbus_source->cancellable = g_object_ref (cancellable);
501       g_source_add_poll (source, &kdbus_source->cancel_pollfd);
502     }
503
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);
508
509   if (kdbus->priv->timeout)
510     kdbus_source->timeout_time = g_get_monotonic_time ()
511                                + kdbus->priv->timeout * 1000000;
512   else
513     kdbus_source->timeout_time = 0;
514
515   return source;
516 }
517
518
519 /**
520  * _g_kdbus_create_source:
521  *
522  */
523 GSource *
524 _g_kdbus_create_source (GKdbus        *kdbus,
525                         GIOCondition   condition,
526                         GCancellable  *cancellable)
527 {
528   g_return_val_if_fail (G_IS_KDBUS (kdbus) && (cancellable == NULL || G_IS_CANCELLABLE (cancellable)), NULL);
529
530   return kdbus_source_new (kdbus, condition, cancellable);
531 }
532
533
534 /**
535  * _g_kdbus_open:
536  *
537  */
538 gboolean
539 _g_kdbus_open (GKdbus       *kdbus,
540                const gchar  *address,
541                GError      **error)
542 {
543   g_return_val_if_fail (G_IS_KDBUS (kdbus), FALSE);
544
545   kdbus->priv->fd = open(address, O_RDWR|O_NOCTTY|O_CLOEXEC);
546   if (kdbus->priv->fd<0)
547     {
548       g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, _("Can't open kdbus endpoint"));
549       return FALSE;
550     }
551
552   kdbus->priv->closed = FALSE;
553
554   return TRUE;
555 }
556
557
558 /**
559  * g_kdbus_free_data:
560  *
561  */
562 static gboolean
563 g_kdbus_free_data (GKdbus      *kdbus,
564                    guint64      offset)
565 {
566   struct kdbus_cmd_free cmd;
567   int ret;
568
569   cmd.offset = offset;
570   cmd.flags = 0;
571
572   ret = ioctl (kdbus->priv->fd, KDBUS_CMD_FREE, &cmd);
573   if (ret < 0)
574       return FALSE;
575
576   return TRUE;
577 }
578
579
580 /**
581  * g_kdbus_translate_nameowner_flags:
582  *
583  */
584 static void
585 g_kdbus_translate_nameowner_flags (GBusNameOwnerFlags   flags,
586                                    guint64             *kdbus_flags)
587 {
588   guint64 new_flags;
589
590   new_flags = 0;
591
592   if (flags & G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT)
593     new_flags |= KDBUS_NAME_ALLOW_REPLACEMENT;
594
595   if (flags & G_BUS_NAME_OWNER_FLAGS_REPLACE)
596     new_flags |= KDBUS_NAME_REPLACE_EXISTING;
597
598   if (!(flags & G_BUS_NAME_OWNER_FLAGS_DO_NOT_QUEUE))
599     new_flags |= KDBUS_NAME_QUEUE;
600
601   *kdbus_flags = new_flags;
602 }
603
604
605 /**
606  * _g_kdbus_close:
607  *
608  */
609 gboolean
610 _g_kdbus_close (GKdbus  *kdbus,
611                 GError **error)
612 {
613   gint res;
614
615   g_return_val_if_fail (G_IS_KDBUS (kdbus), FALSE);
616
617   if (kdbus->priv->closed)
618     return TRUE;
619
620   while (1)
621     {
622       res = close (kdbus->priv->fd);
623
624       if (res == -1)
625         {
626           if (errno == EINTR)
627             continue;
628
629           g_set_error (error, G_IO_ERROR,
630                        g_io_error_from_errno (errno),
631                        _("Error closing kdbus fd: %s"),
632                        g_strerror (errno));
633           return FALSE;
634         }
635       break;
636     }
637
638   kdbus->priv->closed = TRUE;
639   kdbus->priv->fd = -1;
640
641   return TRUE;
642 }
643
644
645 /**
646  * _g_kdbus_is_closed:
647  *
648  */
649 gboolean
650 _g_kdbus_is_closed (GKdbus  *kdbus)
651 {
652   g_return_val_if_fail (G_IS_KDBUS (kdbus), FALSE);
653
654   return kdbus->priv->closed;
655 }
656
657
658 /**
659  * _g_kdbus_Hello:
660  *
661  */
662 GVariant *
663 _g_kdbus_Hello (GIOStream  *stream,
664                 GError    **error)
665 {
666   GKdbus *kdbus;
667   struct kdbus_cmd_hello *hello;
668   struct kdbus_item *item;
669
670   gchar *conn_name;
671   size_t size, conn_name_size;
672
673   kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (stream));
674
675   conn_name = "gdbus-kdbus";
676   conn_name_size = strlen (conn_name);
677
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);
680
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;
685   hello->size = size;
686   hello->pool_size = KDBUS_POOL_SIZE;
687
688   item = hello->items;
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);
693
694   if (ioctl(kdbus->priv->fd, KDBUS_CMD_HELLO, hello))
695     {
696       g_set_error (error, G_IO_ERROR,
697                    g_io_error_from_errno (errno),
698                    _("Failed to send HELLO: %s"),
699                    g_strerror (errno));
700       return NULL;
701     }
702
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)
705     {
706       g_set_error (error, G_IO_ERROR,
707                    g_io_error_from_errno (errno),
708                    _("mmap error: %s"),
709                    g_strerror (errno));
710       return NULL;
711     }
712
713   if (hello->bus_flags > 0xFFFFFFFFULL)
714     {
715       g_set_error_literal (error,
716                            G_IO_ERROR,
717                            G_IO_ERROR_FAILED,
718                            _("Incompatible HELLO flags"));
719       return NULL;
720     }
721
722   memcpy (kdbus->priv->bus_id, hello->id128, 16);
723
724   kdbus->priv->unique_id = hello->id;
725   asprintf(&kdbus->priv->unique_name, ":1.%llu", (unsigned long long) hello->id);
726
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;
730
731   return g_variant_new ("(s)", kdbus->priv->unique_name);
732 }
733
734
735 /**
736  * _g_kdbus_RequestName:
737  *
738  */
739 GVariant *
740 _g_kdbus_RequestName (GDBusConnection     *connection,
741                       const gchar         *name,
742                       GBusNameOwnerFlags   flags,
743                       GError             **error)
744 {
745   GKdbus *kdbus;
746   GVariant *result;
747   struct kdbus_cmd_name *kdbus_name;
748   guint64 kdbus_flags;
749   gssize len, size;
750   gint status, ret;
751
752   status = G_BUS_REQUEST_NAME_FLAGS_PRIMARY_OWNER;
753
754   kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
755   if (kdbus == NULL)
756     {
757       g_set_error_literal (error,
758                            G_DBUS_ERROR,
759                            G_DBUS_ERROR_IO_ERROR,
760                            _("The connection is closed"));
761       return NULL;
762     }
763
764   if (!g_dbus_is_name (name))
765     {
766       g_set_error (error,
767                    G_DBUS_ERROR,
768                    G_DBUS_ERROR_INVALID_ARGS,
769                    "Given bus name \"%s\" is not valid", name);
770       return NULL;
771     }
772
773   if (*name == ':')
774     {
775       g_set_error (error,
776                    G_DBUS_ERROR,
777                    G_DBUS_ERROR_INVALID_ARGS,
778                    "Cannot acquire a service starting with ':' such as \"%s\"", name);
779       return NULL;
780     }
781
782   g_kdbus_translate_nameowner_flags (flags, &kdbus_flags);
783
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);
792
793   ret = ioctl(kdbus->priv->fd, KDBUS_CMD_NAME_ACQUIRE, kdbus_name);
794   if (ret < 0)
795     {
796       if (errno == EEXIST)
797         status = G_BUS_REQUEST_NAME_FLAGS_EXISTS;
798       else if (errno == EALREADY)
799         status = G_BUS_REQUEST_NAME_FLAGS_ALREADY_OWNER;
800       else
801         {
802           g_set_error (error, G_IO_ERROR,
803                        g_io_error_from_errno (errno),
804                        _("Error while acquiring name: %s"),
805                        g_strerror (errno));
806           return NULL;
807         }
808     }
809
810   if (kdbus_name->flags & KDBUS_NAME_IN_QUEUE)
811     status = G_BUS_REQUEST_NAME_FLAGS_IN_QUEUE;
812
813   result = g_variant_new ("(u)", status);
814
815   return result;
816 }
817
818
819 /**
820  * _g_kdbus_ReleaseName:
821  *
822  */
823 GVariant *
824 _g_kdbus_ReleaseName (GDBusConnection     *connection,
825                       const gchar         *name,
826                       GError             **error)
827 {
828   GKdbus *kdbus;
829   GVariant *result;
830   struct kdbus_cmd_name *kdbus_name;
831   gssize len, size;
832   gint status, ret;
833
834   status = G_BUS_RELEASE_NAME_FLAGS_RELEASED;
835
836   kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
837   if (kdbus == NULL)
838     {
839       g_set_error_literal (error,
840                            G_DBUS_ERROR,
841                            G_DBUS_ERROR_IO_ERROR,
842                            _("The connection is closed"));
843       return NULL;
844     }
845
846   if (!g_dbus_is_name (name))
847     {
848       g_set_error (error,
849                    G_DBUS_ERROR,
850                    G_DBUS_ERROR_INVALID_ARGS,
851                    "Given bus name \"%s\" is not valid", name);
852       return NULL;
853     }
854
855   if (*name == ':')
856     {
857       g_set_error (error,
858                    G_DBUS_ERROR,
859                    G_DBUS_ERROR_INVALID_ARGS,
860                    "Cannot release a service starting with ':' such as \"%s\"", name);
861       return NULL;
862     }
863
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);
871
872   ret = ioctl(kdbus->priv->fd, KDBUS_CMD_NAME_RELEASE, kdbus_name);
873   if (ret < 0)
874     {
875       if (errno == ESRCH)
876         status = G_BUS_RELEASE_NAME_FLAGS_NON_EXISTENT;
877       else if (errno == EADDRINUSE)
878         status = G_BUS_RELEASE_NAME_FLAGS_NOT_OWNER;
879       else
880         {
881           g_set_error (error, G_IO_ERROR,
882                        g_io_error_from_errno (errno),
883                        _("Error while releasing name: %s"),
884                        g_strerror (errno));
885           return NULL;
886         }
887     }
888
889   result = g_variant_new ("(u)", status);
890
891   return result;
892 }
893
894
895 /**
896  * _g_kdbus_GetBusId:
897  *
898  */
899 GVariant *
900 _g_kdbus_GetBusId (GDBusConnection  *connection,
901                    GError          **error)
902 {
903   GKdbus   *kdbus;
904   GVariant *result;
905   GString  *result_str;
906   guint     cnt;
907
908   result_str = g_string_new (NULL);
909   kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
910   if (kdbus == NULL)
911     {
912       g_set_error_literal (error,
913                            G_DBUS_ERROR,
914                            G_DBUS_ERROR_IO_ERROR,
915                            _("The connection is closed"));
916       g_string_free (result_str, TRUE);
917       return NULL;
918     }
919
920   for (cnt=0; cnt<16; cnt++)
921     g_string_append_printf (result_str, "%02x", kdbus->priv->bus_id[cnt]);
922
923   result = g_variant_new ("(s)", result_str->str);
924   g_string_free (result_str, TRUE);
925
926   return result;
927 }
928
929
930 /**
931  * _g_kdbus_GetListNames:
932  *
933  */
934 GVariant *
935 _g_kdbus_GetListNames (GDBusConnection  *connection,
936                        guint             list_name_type,
937                        GError          **error)
938 {
939   GKdbus *kdbus;
940   GVariant *result;
941   GVariantBuilder *builder;
942
943   struct kdbus_cmd_name_list cmd = {};
944   struct kdbus_name_list *name_list;
945   struct kdbus_name_info *name;
946
947   guint64 prev_id;
948   gint ret;
949
950   prev_id = 0;
951   kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
952   if (kdbus == NULL)
953     {
954       g_set_error_literal (error,
955                            G_DBUS_ERROR,
956                            G_DBUS_ERROR_IO_ERROR,
957                            _("The connection is closed"));
958       return NULL;
959     }
960
961   if (list_name_type)
962     cmd.flags = KDBUS_NAME_LIST_ACTIVATORS;                     /* ListActivatableNames */
963   else
964     cmd.flags = KDBUS_NAME_LIST_UNIQUE | KDBUS_NAME_LIST_NAMES; /* ListNames */
965
966   ret = ioctl(kdbus->priv->fd, KDBUS_CMD_NAME_LIST, &cmd);
967   if (ret < 0)
968     {
969       g_set_error (error,
970                    G_DBUS_ERROR,
971                    G_DBUS_ERROR_FAILED,
972                    _("Error listing names"));
973       return NULL;
974     }
975
976   name_list = (struct kdbus_name_list *) ((guint8 *) kdbus->priv->kdbus_buffer + cmd.offset);
977   builder = g_variant_builder_new (G_VARIANT_TYPE ("as"));
978
979   KDBUS_ITEM_FOREACH(name, name_list, names)
980     {
981       struct kdbus_item *item;
982       const gchar *item_name = "";
983
984       if ((cmd.flags & KDBUS_NAME_LIST_UNIQUE) && name->owner_id != prev_id)
985         {
986           GString *unique_name;
987
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;
993         }
994
995        KDBUS_ITEM_FOREACH(item, name, items)
996          if (item->type == KDBUS_ITEM_OWNED_NAME)
997            item_name = item->name.name;
998
999         if (g_dbus_is_name (item_name))
1000           g_variant_builder_add (builder, "s", item_name);
1001     }
1002
1003   result = g_variant_new ("(as)", builder);
1004   g_variant_builder_unref (builder);
1005
1006   g_kdbus_free_data (kdbus, cmd.offset);
1007   return result;
1008 }
1009
1010
1011 /**
1012  * _g_kdbus_NameHasOwner_internal:
1013  *
1014  */
1015 static gboolean
1016 g_kdbus_NameHasOwner_internal (GKdbus       *kdbus,
1017                                const gchar  *name,
1018                                GError      **error)
1019 {
1020   struct kdbus_cmd_info *cmd;
1021   gssize size, len;
1022   gint ret;
1023
1024   if (g_dbus_is_unique_name(name))
1025     {
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);
1029     }
1030   else
1031     {
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);
1038     }
1039   cmd->size = size;
1040
1041   ret = ioctl(kdbus->priv->fd, KDBUS_CMD_CONN_INFO, cmd);
1042   g_kdbus_free_data (kdbus, cmd->offset);
1043
1044   if (ret < 0)
1045     return FALSE;
1046   else
1047     return TRUE;
1048 }
1049
1050
1051 /**
1052  * _g_kdbus_GetListQueuedOwners:
1053  *
1054  */
1055 GVariant *
1056 _g_kdbus_GetListQueuedOwners (GDBusConnection  *connection,
1057                               const gchar      *name,
1058                               GError          **error)
1059 {
1060   GKdbus *kdbus;
1061   GVariant *result;
1062   GVariantBuilder *builder;
1063   GString *unique_name;
1064   gint ret;
1065
1066   struct kdbus_cmd_name_list cmd = {};
1067   struct kdbus_name_list *name_list;
1068   struct kdbus_name_info *kname;
1069
1070   kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
1071   if (kdbus == NULL)
1072     {
1073       g_set_error_literal (error,
1074                            G_DBUS_ERROR,
1075                            G_DBUS_ERROR_IO_ERROR,
1076                            _("The connection is closed"));
1077       return NULL;
1078     }
1079
1080   if (!g_dbus_is_name (name))
1081     {
1082       g_set_error (error,
1083                    G_DBUS_ERROR,
1084                    G_DBUS_ERROR_INVALID_ARGS,
1085                    "Given bus name \"%s\" is not valid", name);
1086       return NULL;
1087     }
1088
1089   if (!g_kdbus_NameHasOwner_internal (kdbus, name, error))
1090     {
1091       g_set_error (error,
1092                    G_DBUS_ERROR,
1093                    G_DBUS_ERROR_NAME_HAS_NO_OWNER,
1094                    "Could not get owner of name '%s': no such name", name);
1095       return NULL;
1096     }
1097
1098   cmd.flags = KDBUS_NAME_LIST_QUEUED;
1099   ret = ioctl(kdbus->priv->fd, KDBUS_CMD_NAME_LIST, &cmd);
1100   if (ret < 0)
1101     {
1102       g_set_error (error,
1103                    G_DBUS_ERROR,
1104                    G_DBUS_ERROR_FAILED,
1105                    _("Error listing names"));
1106       return NULL;
1107     }
1108
1109   name_list = (struct kdbus_name_list *) ((guint8 *) kdbus->priv->kdbus_buffer + cmd.offset);
1110
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)
1114     {
1115       struct kdbus_item *item;
1116       const char *item_name = "";
1117
1118       KDBUS_ITEM_FOREACH(item, kname, items)
1119         if (item->type == KDBUS_ITEM_NAME)
1120           item_name = item->str;
1121
1122       if (strcmp(item_name, name))
1123         continue;
1124
1125       g_string_printf (unique_name, ":1.%llu", kname->owner_id);
1126       g_variant_builder_add (builder, "s", item_name);
1127     }
1128
1129   result = g_variant_new ("(as)", builder);
1130   g_variant_builder_unref (builder);
1131   g_string_free (unique_name,TRUE);
1132
1133   g_kdbus_free_data (kdbus, cmd.offset);
1134   return result;
1135 }
1136
1137
1138 /**
1139  * g_kdbus_GetConnInfo_internal:
1140  *
1141  */
1142 static GVariant *
1143 g_kdbus_GetConnInfo_internal (GDBusConnection  *connection,
1144                               const gchar      *name,
1145                               guint64           flag,
1146                               GError          **error)
1147 {
1148   GKdbus *kdbus;
1149   GVariant *result;
1150
1151   struct kdbus_cmd_info *cmd;
1152   struct kdbus_info *conn_info;
1153   struct kdbus_item *item;
1154   gssize size, len;
1155   gint ret;
1156
1157   result = NULL;
1158   kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
1159   if (kdbus == NULL)
1160     {
1161       g_set_error_literal (error,
1162                            G_DBUS_ERROR,
1163                            G_DBUS_ERROR_IO_ERROR,
1164                            _("The connection is closed"));
1165       return NULL;
1166     }
1167
1168   if (!g_dbus_is_name (name))
1169     {
1170       g_set_error (error,
1171                    G_DBUS_ERROR,
1172                    G_DBUS_ERROR_INVALID_ARGS,
1173                    "Given bus name \"%s\" is not valid", name);
1174       return NULL;
1175     }
1176
1177   if (!g_kdbus_NameHasOwner_internal (kdbus, name, error))
1178     {
1179       g_set_error (error,
1180                    G_DBUS_ERROR,
1181                    G_DBUS_ERROR_NAME_HAS_NO_OWNER,
1182                    "Could not get owner of name '%s': no such name", name);
1183       return NULL;
1184     }
1185
1186   if (g_dbus_is_unique_name(name))
1187     {
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);
1191     }
1192   else
1193     {
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);
1200     }
1201
1202   cmd->flags = _KDBUS_ATTACH_ALL;
1203   cmd->size = size;
1204
1205   ret = ioctl(kdbus->priv->fd, KDBUS_CMD_CONN_INFO, cmd);
1206   if (ret < 0)
1207     {
1208       g_set_error (error,
1209                    G_DBUS_ERROR,
1210                    G_DBUS_ERROR_FAILED,
1211                    _("Could not get connection info"));
1212       return NULL;
1213     }
1214
1215   conn_info = (struct kdbus_info *) ((guint8 *) kdbus->priv->kdbus_buffer + cmd->offset);
1216
1217   /*
1218   if (conn_info->flags & KDBUS_HELLO_ACTIVATOR)
1219     {}
1220   */
1221
1222   if (flag == G_BUS_CREDS_UNIQUE_NAME)
1223     {
1224        GString *unique_name;
1225
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);
1230        goto exit;
1231     }
1232
1233   KDBUS_ITEM_FOREACH(item, conn_info, items)
1234    {
1235       switch (item->type)
1236         {
1237           case KDBUS_ITEM_PIDS:
1238
1239             if (flag == G_BUS_CREDS_PID)
1240               {
1241                 guint pid = item->pids.pid;
1242                 result = g_variant_new ("(u)", pid);
1243                 goto exit;
1244               }
1245
1246           case KDBUS_ITEM_CREDS:
1247
1248             if (flag == G_BUS_CREDS_UID)
1249               {
1250                 guint uid = item->creds.uid;
1251                 result = g_variant_new ("(u)", uid);
1252                 goto exit;
1253               }
1254
1255           case KDBUS_ITEM_SECLABEL:
1256           case KDBUS_ITEM_PID_COMM:
1257           case KDBUS_ITEM_TID_COMM:
1258           case KDBUS_ITEM_EXE:
1259           case KDBUS_ITEM_CMDLINE:
1260           case KDBUS_ITEM_CGROUP:
1261           case KDBUS_ITEM_CAPS:
1262           case KDBUS_ITEM_AUDIT:
1263           case KDBUS_ITEM_CONN_DESCRIPTION:
1264           case KDBUS_ITEM_AUXGROUPS:
1265           case KDBUS_ITEM_OWNED_NAME:
1266             break;
1267         }
1268    }
1269
1270 exit:
1271   g_kdbus_free_data (kdbus, cmd->offset);
1272   return result;
1273 }
1274
1275
1276 /**
1277  * _g_kdbus_GetNameOwner:
1278  *
1279  */
1280 GVariant *
1281 _g_kdbus_GetNameOwner (GDBusConnection  *connection,
1282                        const gchar      *name,
1283                        GError          **error)
1284 {
1285   return g_kdbus_GetConnInfo_internal (connection,
1286                                        name,
1287                                        G_BUS_CREDS_UNIQUE_NAME,
1288                                        error);
1289 }
1290
1291
1292 /**
1293  * _g_kdbus_GetConnectionUnixProcessID:
1294  *
1295  */
1296 GVariant *
1297 _g_kdbus_GetConnectionUnixProcessID (GDBusConnection  *connection,
1298                                      const gchar      *name,
1299                                      GError          **error)
1300 {
1301   return g_kdbus_GetConnInfo_internal (connection,
1302                                        name,
1303                                        G_BUS_CREDS_PID,
1304                                        error);
1305 }
1306
1307
1308 /**
1309  * _g_kdbus_GetConnectionUnixUser:
1310  *
1311  */
1312 GVariant *
1313 _g_kdbus_GetConnectionUnixUser (GDBusConnection  *connection,
1314                                 const gchar      *name,
1315                                 GError          **error)
1316 {
1317   return g_kdbus_GetConnInfo_internal (connection,
1318                                        name,
1319                                        G_BUS_CREDS_UID,
1320                                        error);
1321 }
1322
1323
1324 /**
1325  * _g_kdbus_match_remove:
1326  *
1327  */
1328 static void
1329 _g_kdbus_match_remove (GDBusConnection  *connection,
1330                        guint             cookie)
1331 {
1332   GKdbus *kdbus;
1333   struct kdbus_cmd_match cmd_match = {};
1334   gint ret;
1335
1336   kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
1337
1338   cmd_match.size = sizeof (cmd_match);
1339   cmd_match.cookie = cookie;
1340
1341   ret = ioctl(kdbus->priv->fd, KDBUS_CMD_MATCH_REMOVE, &cmd_match);
1342   if (ret < 0)
1343     g_warning ("ERROR - %d\n", (int) errno);
1344 }
1345
1346
1347 /**
1348  * _g_kdbus_subscribe_name_acquired:
1349  *
1350  */
1351 static void
1352 _g_kdbus_subscribe_name_owner_changed (GDBusConnection  *connection,
1353                                        const gchar      *name,
1354                                        const gchar      *old_name,
1355                                        const gchar      *new_name,
1356                                        guint             cookie)
1357 {
1358   GKdbus *kdbus;
1359   struct kdbus_item *item;
1360   struct kdbus_cmd_match *cmd_match;
1361   gssize size, len;
1362   gint ret;
1363   guint64 old_id;
1364   guint64 new_id = KDBUS_MATCH_ID_ANY;
1365
1366   kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
1367
1368   len = strlen(name) + 1;
1369   size = KDBUS_ALIGN8(G_STRUCT_OFFSET (struct kdbus_cmd_match, items) +
1370                       G_STRUCT_OFFSET (struct kdbus_item, name_change) +
1371                       G_STRUCT_OFFSET (struct kdbus_notify_name_change, name) + len);
1372
1373   cmd_match = g_alloca0 (size);
1374   cmd_match->size = size;
1375   cmd_match->cookie = cookie;
1376   item = cmd_match->items;
1377
1378   if (old_name[0] == 0)
1379     {
1380       old_id = KDBUS_MATCH_ID_ANY;
1381     }
1382   else
1383     {
1384       if (g_dbus_is_unique_name(old_name))
1385         old_id = old_id+3;
1386       else
1387         return;
1388     }
1389
1390   if (new_name[0] == 0)
1391     {
1392       new_id = KDBUS_MATCH_ID_ANY;
1393     }
1394   else
1395     {
1396       if (g_dbus_is_unique_name(new_name))
1397         new_id = new_id+3;
1398       else
1399         return;
1400     }
1401
1402   cmd_match = g_alloca0 (size);
1403   cmd_match->size = size;
1404   cmd_match->cookie = cookie;
1405   item = cmd_match->items;
1406
1407   /* KDBUS_ITEM_NAME_CHANGE */
1408   item->type = KDBUS_ITEM_NAME_CHANGE;
1409   item->name_change.old_id.id = old_id;
1410   item->name_change.new_id.id = new_id;
1411   memcpy(item->name_change.name, name, len);
1412   item->size = G_STRUCT_OFFSET (struct kdbus_item, name_change) +
1413                G_STRUCT_OFFSET(struct kdbus_notify_name_change, name) + len;
1414   item = KDBUS_ITEM_NEXT(item);
1415
1416   ret = ioctl(kdbus->priv->fd, KDBUS_CMD_MATCH_ADD, cmd_match);
1417   if (ret < 0)
1418     g_warning ("ERROR - %d\n", (int) errno);
1419 }
1420
1421
1422 /**
1423  * _g_kdbus_subscribe_name_acquired:
1424  *
1425  */
1426 void
1427 _g_kdbus_subscribe_name_acquired (GDBusConnection  *connection,
1428                                   const gchar      *name)
1429 {
1430   GKdbus *kdbus;
1431   struct kdbus_item *item;
1432   struct kdbus_cmd_match *cmd_match;
1433   gssize size, len;
1434   guint64 cookie;
1435   gint ret;
1436
1437   kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
1438
1439   len = strlen(name) + 1;
1440   size = KDBUS_ALIGN8(G_STRUCT_OFFSET (struct kdbus_cmd_match, items) +
1441                       G_STRUCT_OFFSET (struct kdbus_item, name_change) +
1442                       G_STRUCT_OFFSET (struct kdbus_notify_name_change, name) + len);
1443
1444   cookie = 0xbeefbeefbeefbeef;
1445   cmd_match = g_alloca0 (size);
1446   cmd_match->size = size;
1447   cmd_match->cookie = cookie;
1448   item = cmd_match->items;
1449
1450   /* KDBUS_ITEM_NAME_ADD */
1451   item->type = KDBUS_ITEM_NAME_ADD;
1452   item->name_change.old_id.id = KDBUS_MATCH_ID_ANY;
1453   item->name_change.new_id.id = kdbus->priv->unique_id;
1454   memcpy(item->name_change.name, name, len);
1455   item->size = G_STRUCT_OFFSET (struct kdbus_item, name_change) +
1456                G_STRUCT_OFFSET(struct kdbus_notify_name_change, name) + len;
1457   item = KDBUS_ITEM_NEXT(item);
1458
1459   ret = ioctl(kdbus->priv->fd, KDBUS_CMD_MATCH_ADD, cmd_match);
1460   if (ret < 0)
1461     g_warning ("ERROR - %d\n", (int) errno);
1462
1463   _g_kdbus_subscribe_name_owner_changed (connection, name, "", kdbus->priv->unique_name, cookie);
1464 }
1465
1466
1467 /**
1468  * _g_kdbus_subscribe_name_lost:
1469  *
1470  */
1471 void
1472 _g_kdbus_subscribe_name_lost (GDBusConnection  *connection,
1473                               const gchar      *name)
1474 {
1475   GKdbus *kdbus;
1476   struct kdbus_item *item;
1477   struct kdbus_cmd_match *cmd_match;
1478   gssize size, len;
1479   guint64 cookie;
1480   gint ret;
1481
1482   kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
1483
1484   len = strlen(name) + 1;
1485   size = KDBUS_ALIGN8(G_STRUCT_OFFSET (struct kdbus_cmd_match, items) +
1486                       G_STRUCT_OFFSET (struct kdbus_item, name_change) +
1487                       G_STRUCT_OFFSET (struct kdbus_notify_name_change, name) + len);
1488
1489   cookie = 0xdeafdeafdeafdeaf;
1490   cmd_match = g_alloca0 (size);
1491   cmd_match->size = size;
1492   cmd_match->cookie = cookie;
1493   item = cmd_match->items;
1494
1495   /* KDBUS_ITEM_NAME_REMOVE */
1496   item->type = KDBUS_ITEM_NAME_REMOVE;
1497   item->name_change.old_id.id = kdbus->priv->unique_id;
1498   item->name_change.new_id.id = KDBUS_MATCH_ID_ANY;
1499   memcpy(item->name_change.name, name, len);
1500   item->size = G_STRUCT_OFFSET (struct kdbus_item, name_change) +
1501                G_STRUCT_OFFSET(struct kdbus_notify_name_change, name) + len;
1502   item = KDBUS_ITEM_NEXT(item);
1503
1504   ret = ioctl(kdbus->priv->fd, KDBUS_CMD_MATCH_ADD, cmd_match);
1505   if (ret < 0)
1506     g_warning ("ERROR - %d\n", (int) errno);
1507
1508   _g_kdbus_subscribe_name_owner_changed (connection, name, kdbus->priv->unique_name, "", cookie);
1509 }
1510
1511
1512 /**
1513  * _g_kdbus_unsubscribe_name_acquired:
1514  *
1515  */
1516 void
1517 _g_kdbus_unsubscribe_name_acquired (GDBusConnection  *connection)
1518 {
1519   guint64 cookie;
1520
1521   cookie = 0xbeefbeefbeefbeef;
1522   _g_kdbus_match_remove (connection, cookie);
1523 }
1524
1525
1526 /**
1527  * _g_kdbus_unsubscribe_name_lost:
1528  *
1529  */
1530 void
1531 _g_kdbus_unsubscribe_name_lost (GDBusConnection  *connection)
1532 {
1533   guint64 cookie;
1534
1535   cookie = 0xdeafdeafdeafdeaf;
1536   _g_kdbus_match_remove (connection, cookie);
1537 }
1538
1539
1540 /**
1541  * _g_kdbus_release_msg:
1542  *
1543  */
1544 void
1545 _g_kdbus_release_kmsg (GKdbus  *kdbus)
1546 {
1547   struct kdbus_item *item = NULL;
1548   GSList *iterator = NULL;
1549   guint64 offset;
1550
1551   offset = (guint8 *)kdbus->priv->kmsg - (guint8 *)kdbus->priv->kdbus_buffer;
1552   ioctl(kdbus->priv->fd, KDBUS_CMD_FREE, &offset);
1553
1554   for (iterator = kdbus->priv->kdbus_msg_items; iterator; iterator = iterator->next)
1555     g_free ((msg_part*)iterator->data);
1556
1557   g_slist_free (kdbus->priv->kdbus_msg_items);
1558   kdbus->priv->kdbus_msg_items = NULL;
1559
1560   KDBUS_ITEM_FOREACH (item, kdbus->priv->kmsg, items)
1561     {
1562       if (item->type == KDBUS_ITEM_PAYLOAD_MEMFD)
1563         close(item->memfd.fd);
1564       else if (item->type == KDBUS_ITEM_FDS)
1565         {
1566           gint i;
1567           gint num_fds = (item->size - G_STRUCT_OFFSET(struct kdbus_item, fds)) / sizeof(int);
1568
1569           for (i = 0; i < num_fds; i++)
1570             close(item->fds[i]);
1571         }
1572     }
1573 }
1574
1575
1576 /**
1577  * g_kdbus_append_payload_vec:
1578  *
1579  */
1580 static void
1581 g_kdbus_append_payload_vec (struct kdbus_item **item,
1582                             const void         *data_ptr,
1583                             gssize              size)
1584 {
1585   *item = KDBUS_ALIGN8_PTR(*item);
1586   (*item)->size = G_STRUCT_OFFSET (struct kdbus_item, vec) + sizeof(struct kdbus_vec);
1587   (*item)->type = KDBUS_ITEM_PAYLOAD_VEC;
1588   (*item)->vec.address = (guint64)((guintptr)data_ptr);
1589   (*item)->vec.size = size;
1590   *item = KDBUS_ITEM_NEXT(*item);
1591 }
1592
1593
1594 /**
1595  * g_kdbus_append_payload_destiantion:
1596  *
1597  */
1598 static void
1599 g_kdbus_append_destination (struct kdbus_item **item,
1600                             const gchar        *destination,
1601                             gsize               size)
1602 {
1603   *item = KDBUS_ALIGN8_PTR(*item);
1604   (*item)->size = G_STRUCT_OFFSET (struct kdbus_item, str) + size + 1;
1605   (*item)->type = KDBUS_ITEM_DST_NAME;
1606   memcpy ((*item)->str, destination, size+1);
1607   *item = KDBUS_ITEM_NEXT(*item);
1608 }
1609
1610
1611 /**
1612  * g_kdbus_append_payload_bloom:
1613  *
1614  */
1615 static struct kdbus_bloom_filter *
1616 g_kdbus_append_bloom (struct kdbus_item **item,
1617                       gsize               size)
1618 {
1619   struct kdbus_item *bloom_item;
1620
1621   bloom_item = KDBUS_ALIGN8_PTR(*item);
1622   bloom_item->size = G_STRUCT_OFFSET (struct kdbus_item, bloom_filter) +
1623                      G_STRUCT_OFFSET (struct kdbus_bloom_filter, data) +
1624                      size;
1625
1626   bloom_item->type = KDBUS_ITEM_BLOOM_FILTER;
1627
1628   *item = KDBUS_ITEM_NEXT(bloom_item);
1629   return &bloom_item->bloom_filter;
1630 }
1631
1632
1633 /**
1634  * g_kdbus_append_fds:
1635  *
1636  */
1637 static void
1638 g_kdbus_append_fds (struct kdbus_item **item,
1639                     GUnixFDList        *fd_list)
1640 {
1641   *item = KDBUS_ALIGN8_PTR(*item);
1642   (*item)->size = G_STRUCT_OFFSET (struct kdbus_item, fds) + sizeof(int) * g_unix_fd_list_get_length(fd_list);
1643   (*item)->type = KDBUS_ITEM_FDS;
1644   memcpy ((*item)->fds, g_unix_fd_list_peek_fds(fd_list, NULL), sizeof(int) * g_unix_fd_list_get_length(fd_list));
1645
1646   *item = KDBUS_ITEM_NEXT(*item);
1647 }
1648
1649
1650 /**
1651  * _g_kdbus_attach_fds_to_msg:
1652  *
1653  */
1654 void
1655 _g_kdbus_attach_fds_to_msg (GKdbus       *kdbus,
1656                             GUnixFDList **fd_list)
1657 {
1658   if ((kdbus->priv->fds != NULL) && (kdbus->priv->num_fds > 0))
1659     {
1660       gint n;
1661
1662       if (*fd_list == NULL)
1663         *fd_list = g_unix_fd_list_new();
1664
1665       for (n = 0; n < kdbus->priv->num_fds; n++)
1666         {
1667           g_unix_fd_list_append (*fd_list, kdbus->priv->fds[n], NULL);
1668           (void) g_close (kdbus->priv->fds[n], NULL);
1669         }
1670
1671       g_free (kdbus->priv->fds);
1672       kdbus->priv->fds = NULL;
1673       kdbus->priv->num_fds = 0;
1674     }
1675 }
1676
1677 /**
1678  * g_kdbus_bloom_add_data:
1679  * Based on bus-bloom.c from systemd
1680  * http://cgit.freedesktop.org/systemd/systemd/tree/src/libsystemd/sd-bus/bus-bloom.c
1681  */
1682 static void
1683 g_kdbus_bloom_add_data (GKdbus      *kdbus,
1684                         guint64      bloom_data [],
1685                         const void  *data,
1686                         gsize        n)
1687 {
1688   guint8 hash[8];
1689   guint64 bit_num;
1690   guint bytes_num = 0;
1691   guint cnt_1, cnt_2;
1692
1693   guint c = 0;
1694   guint64 p = 0;
1695
1696   bit_num = kdbus->priv->bloom_size * 8;
1697
1698   if (bit_num > 1)
1699     bytes_num = ((__builtin_clzll(bit_num) ^ 63U) + 7) / 8;
1700
1701   for (cnt_1 = 0; cnt_1 < (kdbus->priv->bloom_n_hash); cnt_1++)
1702     {
1703       for (cnt_2 = 0; cnt_2 < bytes_num; cnt_2++)
1704         {
1705           if (c <= 0)
1706             {
1707               g_siphash24(hash, data, n, hash_keys[cnt_1++]);
1708               c += 8;
1709             }
1710
1711           p = (p << 8ULL) | (guint64) hash[8 - c];
1712           c--;
1713         }
1714
1715       p &= bit_num - 1;
1716       bloom_data[p >> 6] |= 1ULL << (p & 63);
1717     }
1718 }
1719
1720
1721 /**
1722  * g_kdbus_bloom_add_pair:
1723  *
1724  */
1725 static void
1726 g_kdbus_bloom_add_pair (GKdbus       *kdbus,
1727                         guint64       bloom_data [],
1728                         const gchar  *parameter,
1729                         const gchar  *value)
1730 {
1731   GString *data = g_string_new (NULL);
1732
1733   g_string_printf (data,"%s:%s",parameter,value);
1734   g_kdbus_bloom_add_data(kdbus, bloom_data, data->str, data->len);
1735   g_string_free (data, TRUE);
1736 }
1737
1738
1739 /**
1740  * g_kdbus_bloom_add_prefixes:
1741  *
1742  */
1743 static void
1744 g_kdbus_bloom_add_prefixes (GKdbus       *kdbus,
1745                             guint64       bloom_data [],
1746                             const gchar  *parameter,
1747                             const gchar  *value,
1748                             gchar         separator)
1749 {
1750   GString *data = g_string_new (NULL);
1751
1752   g_string_printf (data,"%s:%s",parameter,value);
1753
1754   for (;;)
1755     {
1756       gchar *last_sep;
1757       last_sep = strrchr(data->str, separator);
1758       if (!last_sep || last_sep == data->str)
1759         break;
1760
1761       *last_sep = 0;
1762       g_kdbus_bloom_add_data(kdbus, bloom_data, data->str, last_sep-(data->str));
1763     }
1764   g_string_free (data, TRUE);
1765 }
1766
1767
1768 /**
1769  * g_kdbus_setup_bloom:
1770  * Based on bus-bloom.c from systemd
1771  * http://cgit.freedesktop.org/systemd/systemd/tree/src/libsystemd/sd-bus/bus-bloom.c
1772  */
1773 static void
1774 g_kdbus_setup_bloom (GKdbus                     *kdbus,
1775                      GDBusMessage               *dbus_msg,
1776                      struct kdbus_bloom_filter  *bloom_filter)
1777 {
1778   GVariant *body;
1779   GVariantIter iter;
1780   GVariant *child;
1781
1782   const gchar *message_type;
1783   const gchar *interface;
1784   const gchar *member;
1785   const gchar *path;
1786
1787   void *bloom_data;
1788   gint cnt = 0;
1789
1790   body = g_dbus_message_get_body (dbus_msg);
1791   message_type = _g_dbus_enum_to_string (G_TYPE_DBUS_MESSAGE_TYPE, g_dbus_message_get_message_type (dbus_msg));
1792   interface = g_dbus_message_get_interface (dbus_msg);
1793   member = g_dbus_message_get_member (dbus_msg);
1794   path = g_dbus_message_get_path (dbus_msg);
1795
1796   bloom_data = bloom_filter->data;
1797   memset (bloom_data, 0, kdbus->priv->bloom_size);
1798   bloom_filter->generation = 0;
1799
1800   g_kdbus_bloom_add_pair(kdbus, bloom_data, "message-type", message_type);
1801
1802   if (interface)
1803     g_kdbus_bloom_add_pair(kdbus, bloom_data, "interface", interface);
1804
1805   if (member)
1806     g_kdbus_bloom_add_pair(kdbus, bloom_data, "member", member);
1807
1808   if (path)
1809     {
1810       g_kdbus_bloom_add_pair(kdbus, bloom_data, "path", path);
1811       g_kdbus_bloom_add_pair(kdbus, bloom_data, "path-slash-prefix", path);
1812       g_kdbus_bloom_add_prefixes(kdbus, bloom_data, "path-slash-prefix", path, '/');
1813     }
1814
1815   if (body != NULL)
1816     {
1817       g_variant_iter_init (&iter, body);
1818       while ((child = g_variant_iter_next_value (&iter)))
1819         {
1820           gchar buf[sizeof("arg")-1 + 2 + sizeof("-slash-prefix")];
1821           gchar *child_string;
1822           gchar *e;
1823
1824           /* Is it necessary? */
1825           //if (g_variant_is_container (child))
1826           //  iterate_container_recursive (child);
1827
1828           if (!(g_variant_is_of_type (child, G_VARIANT_TYPE_STRING)) &&
1829               !(g_variant_is_of_type (child, G_VARIANT_TYPE_OBJECT_PATH)) &&
1830               !(g_variant_is_of_type (child, G_VARIANT_TYPE_SIGNATURE)))
1831             break;
1832
1833           child_string = g_variant_dup_string (child, NULL);
1834
1835           e = stpcpy(buf, "arg");
1836           if (cnt < 10)
1837             *(e++) = '0' + (char) cnt;
1838           else
1839             {
1840               *(e++) = '0' + (char) (cnt / 10);
1841               *(e++) = '0' + (char) (cnt % 10);
1842             }
1843
1844           *e = 0;
1845           g_kdbus_bloom_add_pair(kdbus, bloom_data, buf, child_string);
1846
1847           strcpy(e, "-dot-prefix");
1848           g_kdbus_bloom_add_prefixes(kdbus, bloom_data, buf, child_string, '.');
1849
1850           strcpy(e, "-slash-prefix");
1851           g_kdbus_bloom_add_prefixes(kdbus, bloom_data, buf, child_string, '/');
1852
1853           g_free (child_string);
1854           g_variant_unref (child);
1855           cnt++;
1856         }
1857     }
1858 }
1859
1860
1861 /*
1862  * TODO: g_kdbus_NameOwnerChanged_generate, g_kdbus_KernelMethodError_generate
1863  */
1864
1865 /**
1866  * g_kdbus_decode_kernel_msg:
1867  *
1868  */
1869 static gssize
1870 g_kdbus_decode_kernel_msg (GKdbus  *kdbus)
1871 {
1872   struct kdbus_item *item = NULL;
1873   gssize size = 0;
1874
1875   KDBUS_ITEM_FOREACH(item, kdbus->priv->kmsg, items)
1876     {
1877      switch (item->type)
1878         {
1879           case KDBUS_ITEM_ID_ADD:
1880           case KDBUS_ITEM_ID_REMOVE:
1881           case KDBUS_ITEM_NAME_ADD:
1882           case KDBUS_ITEM_NAME_REMOVE:
1883           case KDBUS_ITEM_NAME_CHANGE:
1884             //size = g_kdbus_NameOwnerChanged_generate (kdbus, item);
1885             g_error ("'NameOwnerChanged'");
1886             break;
1887
1888           case KDBUS_ITEM_REPLY_TIMEOUT:
1889           case KDBUS_ITEM_REPLY_DEAD:
1890             //size = g_kdbus_KernelMethodError_generate (kdbus, item);
1891             g_error ("'KernelMethodError'");
1892             break;
1893
1894           default:
1895             g_warning ("Unknown field in kernel message - %lld", item->type);
1896        }
1897     }
1898
1899
1900   /* Override information from the user header with data from the kernel */
1901   g_string_printf (kdbus->priv->msg_sender, "org.freedesktop.DBus");
1902
1903   /* for destination */
1904   if (kdbus->priv->kmsg->dst_id == KDBUS_DST_ID_BROADCAST)
1905     /* for broadcast messages we don't have to set destination */
1906     ;
1907   else if (kdbus->priv->kmsg->dst_id == KDBUS_DST_ID_NAME)
1908     g_string_printf (kdbus->priv->msg_destination, ":1.%" G_GUINT64_FORMAT, (guint64) kdbus->priv->unique_id);
1909   else
1910    g_string_printf (kdbus->priv->msg_destination, ":1.%" G_GUINT64_FORMAT, (guint64) kdbus->priv->kmsg->dst_id);
1911
1912   return size;
1913 }
1914
1915
1916 /**
1917  * g_kdbus_decode_dbus_msg:
1918  *
1919  */
1920 static gssize
1921 g_kdbus_decode_dbus_msg (GKdbus  *kdbus)
1922 {
1923   struct kdbus_item *item;
1924   gchar *msg_ptr;
1925   gssize ret_size = 0;
1926   gssize data_size = 0;
1927   const gchar *destination = NULL;
1928
1929   KDBUS_ITEM_FOREACH(item, kdbus->priv->kmsg, items)
1930     {
1931       if (item->size <= KDBUS_ITEM_HEADER_SIZE)
1932         g_error("[KDBUS] %llu bytes - invalid data record\n", item->size);
1933
1934       data_size = item->size - KDBUS_ITEM_HEADER_SIZE;
1935
1936       switch (item->type)
1937         {
1938
1939          /* KDBUS_ITEM_DST_NAME */
1940          case KDBUS_ITEM_DST_NAME:
1941            destination = item->str;
1942            break;
1943
1944         /* KDBUS_ITEM_PALOAD_OFF */
1945         case KDBUS_ITEM_PAYLOAD_OFF:
1946
1947           msg_ptr = (gchar*) kdbus->priv->kmsg + item->vec.offset;
1948           g_kdbus_add_msg_part (kdbus, msg_ptr, item->vec.size);
1949           ret_size += item->vec.size;
1950
1951           break;
1952
1953         /* KDBUS_ITEM_PAYLOAD_MEMFD */
1954         case KDBUS_ITEM_PAYLOAD_MEMFD:
1955
1956           msg_ptr = mmap(NULL, item->memfd.size, PROT_READ, MAP_SHARED, item->memfd.fd, 0);
1957
1958           if (msg_ptr == MAP_FAILED)
1959             {
1960               g_print ("mmap() fd=%i failed:%m", item->memfd.fd);
1961               break;
1962             }
1963
1964           g_kdbus_add_msg_part (kdbus, msg_ptr, item->memfd.size);
1965           ret_size += item->memfd.size;
1966
1967           break;
1968
1969         /* KDBUS_ITEM_FDS */
1970         case KDBUS_ITEM_FDS:
1971
1972           kdbus->priv->num_fds = data_size / sizeof(int);
1973           kdbus->priv->fds = g_malloc0 (sizeof(int) * kdbus->priv->num_fds);
1974           memcpy(kdbus->priv->fds, item->fds, sizeof(int) * kdbus->priv->num_fds);
1975
1976           break;
1977
1978         /* All of the following items, like CMDLINE,
1979            CGROUP, etc. need some GDBUS API extensions and
1980            should be implemented in the future */
1981         case KDBUS_ITEM_CREDS:
1982         case KDBUS_ITEM_TIMESTAMP:
1983         case KDBUS_ITEM_PID_COMM:
1984         case KDBUS_ITEM_TID_COMM:
1985         case KDBUS_ITEM_EXE:
1986         case KDBUS_ITEM_CMDLINE:
1987         case KDBUS_ITEM_CGROUP:
1988         case KDBUS_ITEM_AUDIT:
1989         case KDBUS_ITEM_CAPS:
1990         case KDBUS_ITEM_SECLABEL:
1991         case KDBUS_ITEM_CONN_DESCRIPTION:
1992         case KDBUS_ITEM_AUXGROUPS:
1993         case KDBUS_ITEM_OWNED_NAME:
1994         case KDBUS_ITEM_NAME:
1995         case KDBUS_ITEM_PIDS:
1996           break;
1997
1998         default:
1999           g_error ("[KDBUS] DBUS_PAYLOAD: Unknown filed - %lld", item->type);
2000           break;
2001         }
2002     }
2003
2004   /* Override information from the user header with data from the kernel */
2005
2006   if (kdbus->priv->kmsg->src_id == KDBUS_SRC_ID_KERNEL)
2007     g_string_printf (kdbus->priv->msg_sender, "org.freedesktop.DBus");
2008   else
2009     g_string_printf (kdbus->priv->msg_sender, ":1.%" G_GUINT64_FORMAT, (guint64) kdbus->priv->kmsg->src_id);
2010
2011   if (destination)
2012     g_string_printf (kdbus->priv->msg_destination, "%s", destination);
2013   else if (kdbus->priv->kmsg->dst_id == KDBUS_DST_ID_BROADCAST)
2014     /* for broadcast messages we don't have to set destination */
2015     ;
2016   else if (kdbus->priv->kmsg->dst_id == KDBUS_DST_ID_NAME)
2017     g_string_printf (kdbus->priv->msg_destination, ":1.%" G_GUINT64_FORMAT, (guint64) kdbus->priv->unique_id);
2018   else
2019     g_string_printf (kdbus->priv->msg_destination, ":1.%" G_GUINT64_FORMAT, (guint64) kdbus->priv->kmsg->dst_id);
2020
2021   return ret_size;
2022 }
2023
2024
2025 /**
2026  * _g_kdbus_receive:
2027  *
2028  */
2029 gssize
2030 _g_kdbus_receive (GKdbus        *kdbus,
2031                   GCancellable  *cancellable,
2032                   GError       **error)
2033 {
2034   struct kdbus_cmd_recv recv = {};
2035   gssize size = 0;
2036
2037   if (g_cancellable_set_error_if_cancelled (cancellable, error))
2038     return -1;
2039
2040 again:
2041     if (ioctl(kdbus->priv->fd, KDBUS_CMD_MSG_RECV, &recv) < 0)
2042       {
2043         if (errno == EINTR || errno == EAGAIN)
2044           goto again;
2045
2046         g_set_error (error, G_IO_ERROR,
2047                      g_io_error_from_errno (errno),
2048                      _("Error while receiving message: %s"),
2049                      g_strerror (errno));
2050         return -1;
2051       }
2052
2053    kdbus->priv->kmsg = (struct kdbus_msg *)((guint8 *)kdbus->priv->kdbus_buffer + recv.offset);
2054
2055    if (kdbus->priv->kmsg->payload_type == KDBUS_PAYLOAD_DBUS)
2056      size = g_kdbus_decode_dbus_msg (kdbus);
2057    else if (kdbus->priv->kmsg->payload_type == KDBUS_PAYLOAD_KERNEL)
2058      size = g_kdbus_decode_kernel_msg (kdbus);
2059    else
2060      {
2061        g_set_error (error,
2062                     G_DBUS_ERROR,
2063                     G_DBUS_ERROR_FAILED,
2064                     _("Received unknown payload type"));
2065        return -1;
2066      }
2067
2068    return size;
2069 }
2070
2071
2072 /**
2073  * _g_kdbus_send:
2074  * Returns: size of data sent or -1 when error
2075  */
2076 gsize
2077 _g_kdbus_send (GDBusWorker   *worker,
2078                GKdbus        *kdbus,
2079                GDBusMessage  *dbus_msg,
2080                gchar         *blob,
2081                gsize          blob_size,
2082                GUnixFDList   *fd_list,
2083                GCancellable  *cancellable,
2084                GError       **error)
2085 {
2086   struct kdbus_msg* kmsg;
2087   struct kdbus_item *item;
2088   guint64 kmsg_size = 0;
2089   const gchar *name;
2090   guint64 dst_id = KDBUS_DST_ID_BROADCAST;
2091
2092   g_return_val_if_fail (G_IS_KDBUS (kdbus), -1);
2093
2094   if (g_cancellable_set_error_if_cancelled (cancellable, error))
2095     return -1;
2096
2097   /*
2098    * check destination
2099    */
2100   if ((name = g_dbus_message_get_destination(dbus_msg)))
2101     {
2102       dst_id = KDBUS_DST_ID_NAME;
2103       if ((name[0] == ':') && (name[1] == '1') && (name[2] == '.'))
2104         {
2105           dst_id = strtoull(&name[3], NULL, 10);
2106           name=NULL;
2107         }
2108     }
2109
2110   /*
2111    * check and set message size
2112    */
2113   kmsg_size = sizeof(struct kdbus_msg);
2114   kmsg_size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec));   /* header + body */
2115
2116   if (fd_list != NULL && g_unix_fd_list_get_length (fd_list) > 0)
2117     kmsg_size += KDBUS_ALIGN8(G_STRUCT_OFFSET(struct kdbus_item, fds) + sizeof(int) * g_unix_fd_list_get_length(fd_list));
2118
2119   if (name)
2120     kmsg_size += KDBUS_ITEM_SIZE(strlen(name) + 1);
2121   else if (dst_id == KDBUS_DST_ID_BROADCAST)
2122     kmsg_size += KDBUS_ALIGN8(G_STRUCT_OFFSET(struct kdbus_item, bloom_filter) +
2123                         G_STRUCT_OFFSET(struct kdbus_bloom_filter, data) +
2124                         kdbus->priv->bloom_size);
2125
2126   kmsg = malloc(kmsg_size);
2127   if (!kmsg)
2128     g_error ("[KDBUS] kmsg malloc error");
2129
2130
2131   /*
2132    * set message header
2133    */
2134   memset(kmsg, 0, kmsg_size);
2135   kmsg->size = kmsg_size;
2136   kmsg->payload_type = KDBUS_PAYLOAD_DBUS;
2137   kmsg->dst_id = name ? 0 : dst_id;
2138   kmsg->src_id = kdbus->priv->unique_id;
2139   kmsg->cookie = g_dbus_message_get_serial(dbus_msg);
2140   kmsg->priority = 0;
2141
2142
2143   /*
2144    * set message flags
2145    */
2146   kmsg->flags = ((g_dbus_message_get_flags (dbus_msg) & G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED) ? 0 : KDBUS_MSG_FLAGS_EXPECT_REPLY) |
2147                 ((g_dbus_message_get_flags (dbus_msg) & G_DBUS_MESSAGE_FLAGS_NO_AUTO_START) ? KDBUS_MSG_FLAGS_NO_AUTO_START : 0);
2148
2149   if ((kmsg->flags) & KDBUS_MSG_FLAGS_EXPECT_REPLY)
2150     kmsg->timeout_ns = 2000000000;
2151   else
2152     kmsg->cookie_reply = g_dbus_message_get_reply_serial(dbus_msg);
2153
2154
2155   /*
2156    * append payload
2157    */
2158   item = kmsg->items;
2159
2160   /* if we don't use memfd, send whole message as a PAYLOAD_VEC item */
2161   g_kdbus_append_payload_vec (&item, blob, blob_size);
2162
2163
2164   /*
2165    * append destination or bloom filters
2166    */
2167   if (name)
2168     g_kdbus_append_destination (&item, name, strlen(name));
2169   else if (dst_id == KDBUS_DST_ID_BROADCAST)
2170     {
2171       struct kdbus_bloom_filter *bloom_filter;
2172
2173       bloom_filter = g_kdbus_append_bloom (&item, kdbus->priv->bloom_size);
2174       g_kdbus_setup_bloom (kdbus, dbus_msg, bloom_filter);
2175     }
2176
2177   /*
2178    * append fds if any
2179    */
2180   if (fd_list != NULL && g_unix_fd_list_get_length (fd_list) > 0)
2181     g_kdbus_append_fds (&item, fd_list);
2182
2183
2184   /*
2185    * send message
2186    */
2187 //again:
2188   if (ioctl(kdbus->priv->fd, KDBUS_CMD_MSG_SEND, kmsg))
2189     {
2190 /*
2191       GString *error_name;
2192       error_name = g_string_new (NULL);
2193
2194       if(errno == EINTR)
2195         {
2196           g_string_free (error_name,TRUE);
2197           goto again;
2198         }
2199       else if (errno == ENXIO)
2200         {
2201           g_string_printf (error_name, "Name %s does not exist", g_dbus_message_get_destination(dbus_msg));
2202           g_kdbus_generate_local_error (worker,
2203                                         dbus_msg,
2204                                         g_variant_new ("(s)",error_name->str),
2205                                         G_DBUS_ERROR_SERVICE_UNKNOWN);
2206           g_string_free (error_name,TRUE);
2207           return 0;
2208         }
2209       else if ((errno == ESRCH) || (errno == EADDRNOTAVAIL))
2210         {
2211           if (kmsg->flags & KDBUS_MSG_FLAGS_NO_AUTO_START)
2212             {
2213               g_string_printf (error_name, "Name %s does not exist", g_dbus_message_get_destination(dbus_msg));
2214               g_kdbus_generate_local_error (worker,
2215                                             dbus_msg,
2216                                             g_variant_new ("(s)",error_name->str),
2217                                             G_DBUS_ERROR_SERVICE_UNKNOWN);
2218               g_string_free (error_name,TRUE);
2219               return 0;
2220             }
2221           else
2222             {
2223               g_string_printf (error_name, "The name %s was not provided by any .service files", g_dbus_message_get_destination(dbus_msg));
2224               g_kdbus_generate_local_error (worker,
2225                                             dbus_msg,
2226                                             g_variant_new ("(s)",error_name->str),
2227                                             G_DBUS_ERROR_SERVICE_UNKNOWN);
2228               g_string_free (error_name,TRUE);
2229               return 0;
2230             }
2231         }
2232
2233       g_print ("[KDBUS] ioctl error sending kdbus message:%d (%m)\n",errno);
2234       g_set_error (error, G_IO_ERROR, g_io_error_from_errno(errno), _("Error sending message - KDBUS_CMD_MSG_SEND error"));
2235 */
2236       g_error ("IOCTL SEND: %d\n",errno);
2237       return -1;
2238     }
2239
2240   free(kmsg);
2241   return blob_size;
2242 }