[kdbus] More detailed description for ENOBUFS errno
[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
30 #include <gio/gio.h>
31 #include <errno.h>
32 #include <string.h>
33 #include <sys/mman.h>
34 #include <sys/ioctl.h>
35 #include <stdio.h>
36 #include <stdint.h>
37
38 #ifdef HAVE_SYS_FILIO_H
39 # include <sys/filio.h>
40 #endif
41
42 #ifdef HAVE_SYS_UIO_H
43 #include <sys/uio.h>
44 #endif
45
46 #include <glib/gstdio.h>
47 #include <glib/glib-private.h>
48 #include <gio/gio.h>
49 #include <gio/gunixfdlist.h>
50
51 #include "glibintl.h"
52 #include "gunixfdmessage.h"
53
54 #define KDBUS_MSG_MAX_SIZE         8192
55 #define KDBUS_TIMEOUT_NS           2000000000LU
56 #define KDBUS_POOL_SIZE            (16 * 1024LU * 1024LU)
57 #define KDBUS_ALIGN8(l)            (((l) + 7) & ~7)
58 #define KDBUS_ALIGN8_PTR(p)        ((void*) (uintptr_t)(p))
59
60 #define KDBUS_ITEM_HEADER_SIZE G_STRUCT_OFFSET(struct kdbus_item, data)
61 #define KDBUS_ITEM_SIZE(s) KDBUS_ALIGN8((s) + KDBUS_ITEM_HEADER_SIZE)
62
63 #define KDBUS_ITEM_NEXT(item) \
64         (typeof(item))(((guint8 *)item) + KDBUS_ALIGN8((item)->size))
65 #define KDBUS_ITEM_FOREACH(item, head, first)                    \
66         for (item = (head)->first;                               \
67              (guint8 *)(item) < (guint8 *)(head) + (head)->size; \
68              item = KDBUS_ITEM_NEXT(item))
69 #define KDBUS_FOREACH(iter, first, _size)                             \
70         for (iter = (first);                                          \
71              ((guint8 *)(iter) < (guint8 *)(first) + (_size)) &&      \
72                ((guint8 *)(iter) >= (guint8 *)(first));               \
73              iter = (void*)(((guint8 *)iter) + KDBUS_ALIGN8((iter)->size)))
74
75 #define g_alloca0(x) memset(g_alloca(x), '\0', (x))
76
77 struct dbus_fixed_header {
78   guint8  endian;
79   guint8  type;
80   guint8  flags;
81   guint8  version;
82   guint32 reserved;
83   guint64 serial;
84 };
85
86 #define DBUS_FIXED_HEADER_TYPE     ((const GVariantType *) "(yyyyut)")
87 #define DBUS_EXTENDED_HEADER_TYPE  ((const GVariantType *) "a{tv}")
88 #define DBUS_MESSAGE_TYPE          ((const GVariantType *) "((yyyyut)a{tv}v)")
89
90 /*
91  * Macros for SipHash algorithm
92  */
93
94 #define ROTL(x,b) (guint64)( ((x) << (b)) | ( (x) >> (64 - (b))) )
95
96 #define U32TO8_LE(p, v)         \
97     (p)[0] = (guint8)((v)      ); (p)[1] = (guint8)((v) >>  8); \
98     (p)[2] = (guint8)((v) >> 16); (p)[3] = (guint8)((v) >> 24);
99
100 #define U64TO8_LE(p, v)         \
101   U32TO8_LE((p),     (guint32)((v)      ));   \
102   U32TO8_LE((p) + 4, (guint32)((v) >> 32));
103
104 #define U8TO64_LE(p) \
105   (((guint64)((p)[0])      ) | \
106    ((guint64)((p)[1]) <<  8) | \
107    ((guint64)((p)[2]) << 16) | \
108    ((guint64)((p)[3]) << 24) | \
109    ((guint64)((p)[4]) << 32) | \
110    ((guint64)((p)[5]) << 40) | \
111    ((guint64)((p)[6]) << 48) | \
112    ((guint64)((p)[7]) << 56))
113
114 #define SIPROUND            \
115   do {              \
116     v0 += v1; v1=ROTL(v1,13); v1 ^= v0; v0=ROTL(v0,32); \
117     v2 += v3; v3=ROTL(v3,16); v3 ^= v2;     \
118     v0 += v3; v3=ROTL(v3,21); v3 ^= v0;     \
119     v2 += v1; v1=ROTL(v1,17); v1 ^= v2; v2=ROTL(v2,32); \
120   } while(0)
121
122 typedef enum
123 {
124   G_BUS_CREDS_PID              = 1,
125   G_BUS_CREDS_UID              = 2,
126   G_BUS_CREDS_UNIQUE_NAME      = 3,
127   G_BUS_CREDS_SELINUX_CONTEXT  = 4
128 } GBusCredentialsFlags;
129
130 typedef GObjectClass GKDBusWorkerClass;
131
132 struct _GKDBusWorker
133 {
134   GObject            parent_instance;
135
136   gint               fd;
137
138   GMainContext      *context;
139   GSource           *source;
140
141   gchar             *kdbus_buffer;
142
143   gchar             *unique_name;
144   guint64            unique_id;
145
146   guint64            flags;
147   guint64            attach_flags_send;
148   guint64            attach_flags_recv;
149
150   gsize              bloom_size;
151   guint              bloom_n_hash;
152
153   guint              closed : 1;
154   guint              inited : 1;
155   guint              timeout;
156   guint              timed_out : 1;
157
158   guchar             bus_id[16];
159
160   GDBusCapabilityFlags                     capabilities;
161   GDBusWorkerMessageReceivedCallback       message_received_callback;
162   GDBusWorkerMessageAboutToBeSentCallback  message_about_to_be_sent_callback;
163   GDBusWorkerDisconnectedCallback          disconnected_callback;
164   gpointer                                 user_data;
165 };
166
167 static gssize _g_kdbus_receive (GKDBusWorker  *kdbus,
168                                 GCancellable  *cancellable,
169                                 GError       **error);
170
171 G_DEFINE_TYPE (GKDBusWorker, g_kdbus_worker, G_TYPE_OBJECT)
172
173 /* Hash keys for bloom filters*/
174 const guint8 hash_keys[8][16] =
175 {
176   {0xb9,0x66,0x0b,0xf0,0x46,0x70,0x47,0xc1,0x88,0x75,0xc4,0x9c,0x54,0xb9,0xbd,0x15},
177   {0xaa,0xa1,0x54,0xa2,0xe0,0x71,0x4b,0x39,0xbf,0xe1,0xdd,0x2e,0x9f,0xc5,0x4a,0x3b},
178   {0x63,0xfd,0xae,0xbe,0xcd,0x82,0x48,0x12,0xa1,0x6e,0x41,0x26,0xcb,0xfa,0xa0,0xc8},
179   {0x23,0xbe,0x45,0x29,0x32,0xd2,0x46,0x2d,0x82,0x03,0x52,0x28,0xfe,0x37,0x17,0xf5},
180   {0x56,0x3b,0xbf,0xee,0x5a,0x4f,0x43,0x39,0xaf,0xaa,0x94,0x08,0xdf,0xf0,0xfc,0x10},
181   {0x31,0x80,0xc8,0x73,0xc7,0xea,0x46,0xd3,0xaa,0x25,0x75,0x0f,0x9e,0x4c,0x09,0x29},
182   {0x7d,0xf7,0x18,0x4b,0x7b,0xa4,0x44,0xd5,0x85,0x3c,0x06,0xe0,0x65,0x53,0x96,0x6d},
183   {0xf2,0x77,0xe9,0x6f,0x93,0xb5,0x4e,0x71,0x9a,0x0c,0x34,0x88,0x39,0x25,0xbf,0x35}
184 };
185
186 enum {
187   MATCH_ELEMENT_TYPE,
188   MATCH_ELEMENT_SENDER,
189   MATCH_ELEMENT_INTERFACE,
190   MATCH_ELEMENT_MEMBER,
191   MATCH_ELEMENT_PATH,
192   MATCH_ELEMENT_PATH_NAMESPACE,
193   MATCH_ELEMENT_DESTINATION,
194   MATCH_ELEMENT_ARG0NAMESPACE,
195   MATCH_ELEMENT_EAVESDROP,
196   MATCH_ELEMENT_ARGN,
197   MATCH_ELEMENT_ARGNPATH,
198 };
199
200 /* MatchElement struct */
201 typedef struct {
202   guint16 type;
203   guint16 arg;
204   char *value;
205 } MatchElement;
206
207 /* Match struct */
208 typedef struct {
209   int n_elements;
210   MatchElement *elements;
211 } Match;
212
213
214 /**
215  * SipHash algorithm
216  *
217  */
218 static void
219 _g_siphash24 (guint8         out[8],
220               const void    *_in,
221               gsize          inlen,
222               const guint8   k[16])
223 {
224   /* "somepseudorandomlygeneratedbytes" */
225   guint64 v0 = 0x736f6d6570736575ULL;
226   guint64 v1 = 0x646f72616e646f6dULL;
227   guint64 v2 = 0x6c7967656e657261ULL;
228   guint64 v3 = 0x7465646279746573ULL;
229   guint64 b;
230   guint64 k0 = U8TO64_LE (k);
231   guint64 k1 = U8TO64_LE (k + 8);
232   guint64 m;
233   const guint8 *in = _in;
234   const guint8 *end = in + inlen - (inlen % sizeof(guint64));
235   const int left = inlen & 7;
236   b = ((guint64) inlen) << 56;
237   v3 ^= k1;
238   v2 ^= k0;
239   v1 ^= k1;
240   v0 ^= k0;
241
242   for (; in != end; in += 8)
243     {
244       m = U8TO64_LE (in);
245       v3 ^= m;
246       SIPROUND;
247       SIPROUND;
248       v0 ^= m;
249     }
250
251   switch (left)
252     {
253       case 7: b |= ((guint64) in[6]) << 48;
254       case 6: b |= ((guint64) in[5]) << 40;
255       case 5: b |= ((guint64) in[4]) << 32;
256       case 4: b |= ((guint64) in[3]) << 24;
257       case 3: b |= ((guint64) in[2]) << 16;
258       case 2: b |= ((guint64) in[1]) <<  8;
259       case 1: b |= ((guint64) in[0]); break;
260       case 0: break;
261     }
262
263   v3 ^= b;
264   SIPROUND;
265   SIPROUND;
266   v0 ^= b;
267
268   v2 ^= 0xff;
269   SIPROUND;
270   SIPROUND;
271   SIPROUND;
272   SIPROUND;
273   b = v0 ^ v1 ^ v2  ^ v3;
274   U64TO8_LE (out, b);
275 }
276
277
278 /**
279  * is_key()
280  *
281  */
282 static gboolean
283 is_key (const char *key_start, const char *key_end, char *value)
284 {
285   gsize len = strlen (value);
286
287   if (len != key_end - key_start)
288     return FALSE;
289
290   return strncmp (key_start, value, len) == 0;
291 }
292
293
294 /**
295  * parse_key()
296  *
297  */
298 static gboolean
299 parse_key (MatchElement *element, const char *key_start, const char *key_end)
300 {
301   gboolean res = TRUE;
302
303   if (is_key (key_start, key_end, "type"))
304     {
305       element->type = MATCH_ELEMENT_TYPE;
306     }
307   else if (is_key (key_start, key_end, "sender"))
308     {
309       element->type = MATCH_ELEMENT_SENDER;
310     }
311   else if (is_key (key_start, key_end, "interface"))
312     {
313       element->type = MATCH_ELEMENT_INTERFACE;
314     }
315   else if (is_key (key_start, key_end, "member"))
316     {
317       element->type = MATCH_ELEMENT_MEMBER;
318     }
319   else if (is_key (key_start, key_end, "path"))
320     {
321       element->type = MATCH_ELEMENT_PATH;
322     }
323   else if (is_key (key_start, key_end, "path_namespace"))
324     {
325       element->type = MATCH_ELEMENT_PATH_NAMESPACE;
326     }
327   else if (is_key (key_start, key_end, "destination"))
328     {
329       element->type = MATCH_ELEMENT_DESTINATION;
330     }
331   else if (is_key (key_start, key_end, "arg0namespace"))
332     {
333       element->type = MATCH_ELEMENT_ARG0NAMESPACE;
334     }
335   else if (is_key (key_start, key_end, "eavesdrop"))
336     {
337       element->type = MATCH_ELEMENT_EAVESDROP;
338     }
339   else if (key_end - key_start > 3 && is_key (key_start, key_start + 3, "arg"))
340     {
341       const char *digits = key_start + 3;
342       const char *end_digits = digits;
343
344       while (end_digits < key_end && g_ascii_isdigit (*end_digits))
345         end_digits++;
346
347       if (end_digits == key_end) /* argN */
348         {
349           element->type = MATCH_ELEMENT_ARGN;
350           element->arg = atoi (digits);
351         }
352       else if (is_key (end_digits, key_end, "path")) /* argNpath */
353         {
354           element->type = MATCH_ELEMENT_ARGNPATH;
355           element->arg = atoi (digits);
356         }
357       else
358         res = FALSE;
359     }
360   else
361     res = FALSE;
362
363   return res;
364 }
365
366
367 /**
368  * parse_value()
369  *
370  */
371 static const char *
372 parse_value (MatchElement *element, const char *s)
373 {
374   char quote_char;
375   GString *value;
376
377   value = g_string_new ("");
378
379   quote_char = 0;
380
381   for (;*s; s++)
382     {
383       if (quote_char == 0)
384         {
385           switch (*s)
386             {
387             case '\'':
388               quote_char = '\'';
389               break;
390
391             case ',':
392               s++;
393               goto out;
394
395             case '\\':
396               quote_char = '\\';
397               break;
398
399             default:
400               g_string_append_c (value, *s);
401               break;
402             }
403         }
404       else if (quote_char == '\\')
405         {
406           /* \ only counts as an escape if escaping a quote mark */
407           if (*s != '\'')
408             g_string_append_c (value, '\\');
409
410           g_string_append_c (value, *s);
411           quote_char = 0;
412         }
413       else /* quote_char == ' */
414         {
415           if (*s == '\'')
416             quote_char = 0;
417           else
418             g_string_append_c (value, *s);
419         }
420     }
421
422  out:
423   if (quote_char == '\\')
424     g_string_append_c (value, '\\');
425   else if (quote_char == '\'')
426     {
427       g_string_free (value, TRUE);
428       return NULL;
429     }
430
431   element->value = g_string_free (value, FALSE);
432   return s;
433 }
434
435
436 /**
437  * match_new()
438  *
439  */
440 static Match *
441 match_new (const char *str)
442 {
443   Match *match;
444   GArray *elements;
445   const char *p;
446   const char *key_start;
447   const char *key_end;
448   MatchElement element;
449   int i;
450
451   elements = g_array_new (TRUE, TRUE, sizeof (MatchElement));
452
453   p = str;
454
455   while (*p != 0)
456     {
457       memset (&element, 0, sizeof (element));
458
459       /* Skip initial whitespace */
460       while (*p && g_ascii_isspace (*p))
461         p++;
462
463       key_start = p;
464
465       /* Read non-whitespace non-equals chars */
466       while (*p && *p != '=' && !g_ascii_isspace (*p))
467         p++;
468
469       key_end = p;
470
471       /* Skip any whitespace after key */
472       while (*p && g_ascii_isspace (*p))
473         p++;
474
475       if (key_start == key_end)
476         continue; /* Allow trailing whitespace */
477       if (*p != '=')
478         goto error;
479
480       ++p;
481
482       if (!parse_key (&element, key_start, key_end))
483         goto error;
484
485       p = parse_value (&element, p);
486       if (p == NULL)
487         goto error;
488
489       g_array_append_val (elements, element);
490     }
491
492   match = g_new0 (Match, 1);
493   match->n_elements = elements->len;
494   match->elements = (MatchElement *)g_array_free (elements, FALSE);
495
496   return match;
497
498  error:
499   for (i = 0; i < elements->len; i++)
500     g_free (g_array_index (elements, MatchElement, i).value);
501   g_array_free (elements, TRUE);
502   return NULL;
503 }
504
505
506 /**
507  * match_free()
508  *
509  */
510 static void
511 match_free (Match *match)
512 {
513   int i;
514   for (i = 0; i < match->n_elements; i++)
515     g_free (match->elements[i].value);
516   g_free (match->elements);
517   g_free (match);
518 }
519
520
521 /**
522  * g_kdbus_finalize:
523  *
524  */
525 static void
526 g_kdbus_worker_finalize (GObject *object)
527 {
528   GKDBusWorker *kdbus = G_KDBUS_WORKER (object);
529
530   if (kdbus->kdbus_buffer != NULL)
531     munmap (kdbus->kdbus_buffer, KDBUS_POOL_SIZE);
532
533   kdbus->kdbus_buffer = NULL;
534
535   if (kdbus->fd != -1 && !kdbus->closed)
536     _g_kdbus_close (kdbus);
537
538   G_OBJECT_CLASS (g_kdbus_worker_parent_class)->finalize (object);
539 }
540
541 static void
542 g_kdbus_worker_class_init (GKDBusWorkerClass *class)
543 {
544   class->finalize = g_kdbus_worker_finalize;
545 }
546
547 static void
548 g_kdbus_worker_init (GKDBusWorker *kdbus)
549 {
550   kdbus->fd = -1;
551
552   kdbus->unique_id = -1;
553   kdbus->unique_name = NULL;
554
555   kdbus->kdbus_buffer = NULL;
556
557   kdbus->flags = KDBUS_HELLO_ACCEPT_FD;
558   kdbus->attach_flags_send = _KDBUS_ATTACH_ALL;
559   kdbus->attach_flags_recv = _KDBUS_ATTACH_ALL;
560 }
561
562 static gboolean
563 kdbus_ready (gint         fd,
564              GIOCondition condition,
565              gpointer     user_data)
566 {
567   GKDBusWorker *kdbus = user_data;
568   GError *error = NULL;
569
570   _g_kdbus_receive (kdbus, NULL, &error);
571   g_assert_no_error (error);
572
573   return G_SOURCE_CONTINUE;
574 }
575
576 gboolean
577 _g_kdbus_open (GKDBusWorker  *worker,
578                const gchar   *address,
579                GError       **error)
580 {
581   g_return_val_if_fail (G_IS_KDBUS_WORKER (worker), FALSE);
582
583   worker->fd = open(address, O_RDWR|O_NOCTTY|O_CLOEXEC);
584   if (worker->fd<0)
585     {
586       g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, _("Can't open kdbus endpoint"));
587       return FALSE;
588     }
589
590   worker->closed = FALSE;
591
592   return TRUE;
593 }
594
595
596 /**
597  * g_kdbus_free_data:
598  *
599  */
600 static gboolean
601 g_kdbus_free_data (GKDBusWorker      *kdbus,
602                    guint64      offset)
603 {
604   struct kdbus_cmd_free cmd = {
605     .size = sizeof(cmd),
606     .offset = offset,
607     .flags = 0
608   };
609   int ret;
610
611   ret = ioctl (kdbus->fd, KDBUS_CMD_FREE, &cmd);
612   if (ret < 0)
613     return FALSE;
614
615   return TRUE;
616 }
617
618
619 /**
620  * g_kdbus_translate_nameowner_flags:
621  *
622  */
623 static void
624 g_kdbus_translate_nameowner_flags (GBusNameOwnerFlags   flags,
625                                    guint64             *kdbus_flags)
626 {
627   guint64 new_flags;
628
629   new_flags = 0;
630
631   if (flags & G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT)
632     new_flags |= KDBUS_NAME_ALLOW_REPLACEMENT;
633
634   if (flags & G_BUS_NAME_OWNER_FLAGS_REPLACE)
635     new_flags |= KDBUS_NAME_REPLACE_EXISTING;
636
637   if (!(flags & G_BUS_NAME_OWNER_FLAGS_DO_NOT_QUEUE))
638     new_flags |= KDBUS_NAME_QUEUE;
639
640   *kdbus_flags = new_flags;
641 }
642
643
644 /**
645  * _g_kdbus_close:
646  *
647  */
648 void
649 _g_kdbus_close (GKDBusWorker *kdbus)
650 {
651   g_return_val_if_fail (G_IS_KDBUS_WORKER (kdbus), FALSE);
652
653   if (kdbus->closed)
654     return;
655
656   g_source_destroy (kdbus->source);
657   kdbus->source = 0;
658
659   g_main_context_unref (kdbus->context);
660   kdbus->context = NULL;
661
662   close (kdbus->fd);
663   kdbus->fd = -1;
664
665   kdbus->closed = TRUE;
666 }
667
668 /**
669  * _g_kdbus_is_closed:
670  *
671  */
672 gboolean
673 _g_kdbus_is_closed (GKDBusWorker  *kdbus)
674 {
675   g_return_val_if_fail (G_IS_KDBUS_WORKER (kdbus), FALSE);
676
677   return kdbus->closed;
678 }
679
680
681 /**
682  * _g_kdbus_Hello:
683  *
684  */
685 GVariant *
686 _g_kdbus_Hello (GKDBusWorker *worker,
687                 GError    **error)
688 {
689   struct kdbus_cmd_hello *cmd;
690   struct kdbus_bloom_parameter *bloom;
691   struct kdbus_item *item, *items;
692
693   gchar *conn_name;
694   size_t size, conn_name_size;
695
696   conn_name = "gdbus-kdbus";
697   conn_name_size = strlen (conn_name);
698
699   size = KDBUS_ALIGN8 (G_STRUCT_OFFSET (struct kdbus_cmd_hello, items)) +
700          KDBUS_ALIGN8 (G_STRUCT_OFFSET (struct kdbus_item, str) + conn_name_size + 1);
701
702   cmd = g_alloca0 (size);
703   cmd->flags = worker->flags;
704   cmd->attach_flags_send = worker->attach_flags_send;
705   cmd->attach_flags_recv = worker->attach_flags_recv;
706   cmd->size = size;
707   cmd->pool_size = KDBUS_POOL_SIZE;
708
709   item = cmd->items;
710   item->size = G_STRUCT_OFFSET (struct kdbus_item, str) + conn_name_size + 1;
711   item->type = KDBUS_ITEM_CONN_DESCRIPTION;
712   memcpy (item->str, conn_name, conn_name_size+1);
713   item = KDBUS_ITEM_NEXT (item);
714
715   if (ioctl(worker->fd, KDBUS_CMD_HELLO, cmd))
716     {
717       g_set_error (error, G_IO_ERROR,
718                    g_io_error_from_errno (errno),
719                    _("Failed to send HELLO: %s"),
720                    g_strerror (errno));
721       return NULL;
722     }
723
724   worker->kdbus_buffer = mmap(NULL, KDBUS_POOL_SIZE, PROT_READ, MAP_SHARED, worker->fd, 0);
725   if (worker->kdbus_buffer == MAP_FAILED)
726     {
727       g_set_error (error, G_IO_ERROR,
728                    g_io_error_from_errno (errno),
729                    _("mmap error: %s"),
730                    g_strerror (errno));
731       return NULL;
732     }
733
734   if (cmd->bus_flags > 0xFFFFFFFFULL)
735     {
736       g_set_error_literal (error,
737                            G_IO_ERROR,
738                            G_IO_ERROR_FAILED,
739                            _("Incompatible HELLO flags"));
740       return NULL;
741     }
742
743   memcpy (worker->bus_id, cmd->id128, 16);
744
745   worker->unique_id = cmd->id;
746   asprintf(&worker->unique_name, ":1.%llu", (unsigned long long) cmd->id);
747
748   /* read bloom filters parameters */
749   bloom = NULL;
750   items = (void*)(worker->kdbus_buffer + cmd->offset);
751   KDBUS_FOREACH(item, items, cmd->items_size)
752     {
753       switch (item->type)
754         {
755           case KDBUS_ITEM_BLOOM_PARAMETER:
756             bloom = &item->bloom_parameter;
757           break;
758         }
759     }
760
761   if (bloom != NULL)
762     {
763       worker->bloom_size = (gsize) bloom->size;
764       worker->bloom_n_hash = (guint) bloom->n_hash;
765     }
766   else
767     {
768       g_set_error_literal (error,
769                            G_IO_ERROR,
770                            G_IO_ERROR_FAILED,
771                            _("Can't read bloom filter parameters"));
772       return NULL;
773     }
774
775
776   return g_variant_new ("(s)", worker->unique_name);
777 }
778
779
780 /**
781  * _g_kdbus_RequestName:
782  *
783  */
784 GVariant *
785 _g_kdbus_RequestName (GKDBusWorker        *worker,
786                       const gchar         *name,
787                       GBusNameOwnerFlags   flags,
788                       GError             **error)
789 {
790   GVariant *result;
791   struct kdbus_cmd *cmd;
792   guint64 kdbus_flags;
793   gssize len, size;
794   gint status, ret;
795
796   status = G_BUS_REQUEST_NAME_FLAGS_PRIMARY_OWNER;
797
798   if (!g_dbus_is_name (name))
799     {
800       g_set_error (error,
801                    G_DBUS_ERROR,
802                    G_DBUS_ERROR_INVALID_ARGS,
803                    "Given bus name \"%s\" is not valid", name);
804       return NULL;
805     }
806
807   if (*name == ':')
808     {
809       g_set_error (error,
810                    G_DBUS_ERROR,
811                    G_DBUS_ERROR_INVALID_ARGS,
812                    "Cannot acquire a service starting with ':' such as \"%s\"", name);
813       return NULL;
814     }
815
816   g_kdbus_translate_nameowner_flags (flags, &kdbus_flags);
817
818   len = strlen(name) + 1;
819   size = G_STRUCT_OFFSET (struct kdbus_cmd, items) + KDBUS_ITEM_SIZE(len);
820   cmd = g_alloca0 (size);
821   cmd->size = size;
822   cmd->items[0].size = KDBUS_ITEM_HEADER_SIZE + len;
823   cmd->items[0].type = KDBUS_ITEM_NAME;
824   cmd->flags = kdbus_flags;
825   memcpy (cmd->items[0].str, name, len);
826
827   ret = ioctl(worker->fd, KDBUS_CMD_NAME_ACQUIRE, cmd);
828   if (ret < 0)
829     {
830       if (errno == EEXIST)
831         status = G_BUS_REQUEST_NAME_FLAGS_EXISTS;
832       else if (errno == EALREADY)
833         status = G_BUS_REQUEST_NAME_FLAGS_ALREADY_OWNER;
834       else
835         {
836           g_set_error (error, G_IO_ERROR,
837                        g_io_error_from_errno (errno),
838                        _("Error while acquiring name: %s"),
839                        g_strerror (errno));
840           return NULL;
841         }
842     }
843
844   if (cmd->return_flags & KDBUS_NAME_IN_QUEUE)
845     status = G_BUS_REQUEST_NAME_FLAGS_IN_QUEUE;
846
847   result = g_variant_new ("(u)", status);
848
849   return result;
850 }
851
852
853 /**
854  * _g_kdbus_ReleaseName:
855  *
856  */
857 GVariant *
858 _g_kdbus_ReleaseName (GKDBusWorker     *worker,
859                       const gchar         *name,
860                       GError             **error)
861 {
862   GVariant *result;
863   struct kdbus_cmd *cmd;
864   gssize len, size;
865   gint status, ret;
866
867   status = G_BUS_RELEASE_NAME_FLAGS_RELEASED;
868
869   if (!g_dbus_is_name (name))
870     {
871       g_set_error (error,
872                    G_DBUS_ERROR,
873                    G_DBUS_ERROR_INVALID_ARGS,
874                    "Given bus name \"%s\" is not valid", name);
875       return NULL;
876     }
877
878   if (*name == ':')
879     {
880       g_set_error (error,
881                    G_DBUS_ERROR,
882                    G_DBUS_ERROR_INVALID_ARGS,
883                    "Cannot release a service starting with ':' such as \"%s\"", name);
884       return NULL;
885     }
886
887   len = strlen(name) + 1;
888   size = G_STRUCT_OFFSET (struct kdbus_cmd, items) + KDBUS_ITEM_SIZE(len);
889   cmd = g_alloca0 (size);
890   cmd->size = size;
891   cmd->items[0].size = KDBUS_ITEM_HEADER_SIZE + len;
892   cmd->items[0].type = KDBUS_ITEM_NAME;
893   memcpy (cmd->items[0].str, name, len);
894
895   ret = ioctl(worker->fd, KDBUS_CMD_NAME_RELEASE, cmd);
896   if (ret < 0)
897     {
898       if (errno == ESRCH)
899         status = G_BUS_RELEASE_NAME_FLAGS_NON_EXISTENT;
900       else if (errno == EADDRINUSE)
901         status = G_BUS_RELEASE_NAME_FLAGS_NOT_OWNER;
902       else
903         {
904           g_set_error (error, G_IO_ERROR,
905                        g_io_error_from_errno (errno),
906                        _("Error while releasing name: %s"),
907                        g_strerror (errno));
908           return NULL;
909         }
910     }
911
912   result = g_variant_new ("(u)", status);
913
914   return result;
915 }
916
917
918 /**
919  * _g_kdbus_GetBusId:
920  *
921  */
922 GVariant *
923 _g_kdbus_GetBusId (GKDBusWorker  *worker,
924                    GError          **error)
925 {
926   GVariant *result;
927   GString  *result_str;
928   guint     cnt;
929
930   result_str = g_string_new (NULL);
931
932   for (cnt=0; cnt<16; cnt++)
933     g_string_append_printf (result_str, "%02x", worker->bus_id[cnt]);
934
935   result = g_variant_new ("(s)", result_str->str);
936   g_string_free (result_str, TRUE);
937
938   return result;
939 }
940
941
942 /**
943  * _g_kdbus_GetListNames:
944  *
945  */
946 GVariant *
947 _g_kdbus_GetListNames (GKDBusWorker  *worker,
948                        guint             list_name_type,
949                        GError          **error)
950 {
951   GVariant *result;
952   GVariantBuilder *builder;
953   struct kdbus_info *name_list, *name;
954   struct kdbus_cmd_list cmd = {
955     .size = sizeof(cmd)
956   };
957
958   guint64 prev_id;
959   gint ret;
960
961   prev_id = 0;
962
963   if (list_name_type)
964     cmd.flags = KDBUS_LIST_ACTIVATORS;                /* ListActivatableNames */
965   else
966     cmd.flags = KDBUS_LIST_UNIQUE | KDBUS_LIST_NAMES; /* ListNames */
967
968   ret = ioctl(worker->fd, KDBUS_CMD_LIST, &cmd);
969   if (ret < 0)
970     {
971       g_set_error (error,
972                    G_DBUS_ERROR,
973                    G_DBUS_ERROR_FAILED,
974                    _("Error listing names"));
975       return NULL;
976     }
977
978   name_list = (struct kdbus_info *) ((guint8 *) worker->kdbus_buffer + cmd.offset);
979   builder = g_variant_builder_new (G_VARIANT_TYPE ("as"));
980
981   KDBUS_FOREACH(name, name_list, cmd.list_size)
982     {
983       struct kdbus_item *item;
984       const gchar *item_name = "";
985
986       if ((cmd.flags & KDBUS_LIST_UNIQUE) && name->id != prev_id)
987         {
988           GString *unique_name;
989
990           unique_name = g_string_new (NULL);
991           g_string_printf (unique_name, ":1.%llu", name->id);
992           g_variant_builder_add (builder, "s", unique_name->str);
993           g_string_free (unique_name,TRUE);
994           prev_id = name->id;
995         }
996
997        KDBUS_ITEM_FOREACH(item, name, items)
998          if (item->type == KDBUS_ITEM_OWNED_NAME)
999            item_name = item->name.name;
1000
1001         if (g_dbus_is_name (item_name))
1002           g_variant_builder_add (builder, "s", item_name);
1003     }
1004
1005   result = g_variant_new ("(as)", builder);
1006   g_variant_builder_unref (builder);
1007
1008   g_kdbus_free_data (worker, cmd.offset);
1009   return result;
1010 }
1011
1012
1013 /**
1014  * _g_kdbus_NameHasOwner_internal:
1015  *
1016  */
1017 static gboolean
1018 g_kdbus_NameHasOwner_internal (GKDBusWorker       *worker,
1019                                const gchar  *name,
1020                                GError      **error)
1021 {
1022   struct kdbus_cmd_info *cmd;
1023   gssize size, len;
1024   gint ret;
1025
1026   if (g_dbus_is_unique_name(name))
1027     {
1028        size = G_STRUCT_OFFSET (struct kdbus_cmd_info, items);
1029        cmd = g_alloca0 (size);
1030        cmd->id = g_ascii_strtoull (name+3, NULL, 10);
1031     }
1032   else
1033     {
1034        len = strlen(name) + 1;
1035        size = G_STRUCT_OFFSET (struct kdbus_cmd_info, items) + KDBUS_ITEM_SIZE(len);
1036        cmd = g_alloca0 (size);
1037        cmd->items[0].size = KDBUS_ITEM_HEADER_SIZE + len;
1038        cmd->items[0].type = KDBUS_ITEM_NAME;
1039        memcpy (cmd->items[0].str, name, len);
1040     }
1041   cmd->size = size;
1042
1043   ret = ioctl(worker->fd, KDBUS_CMD_CONN_INFO, cmd);
1044   g_kdbus_free_data (worker, cmd->offset);
1045
1046   if (ret < 0)
1047     return FALSE;
1048   else
1049     return TRUE;
1050 }
1051
1052
1053 /**
1054  * _g_kdbus_GetListQueuedOwners:
1055  *
1056  */
1057 GVariant *
1058 _g_kdbus_GetListQueuedOwners (GKDBusWorker  *worker,
1059                               const gchar   *name,
1060                               GError       **error)
1061 {
1062   GVariant *result;
1063   GVariantBuilder *builder;
1064   GString *unique_name;
1065   gint ret;
1066
1067   struct kdbus_info *name_list, *kname;
1068   struct kdbus_cmd_list cmd = {
1069     .size = sizeof(cmd),
1070     .flags = KDBUS_LIST_QUEUED
1071   };
1072
1073   if (!g_dbus_is_name (name))
1074     {
1075       g_set_error (error,
1076                    G_DBUS_ERROR,
1077                    G_DBUS_ERROR_INVALID_ARGS,
1078                    "Given bus name \"%s\" is not valid", name);
1079       return NULL;
1080     }
1081
1082   if (!g_kdbus_NameHasOwner_internal (worker, name, error))
1083     {
1084       g_set_error (error,
1085                    G_DBUS_ERROR,
1086                    G_DBUS_ERROR_NAME_HAS_NO_OWNER,
1087                    "Could not get owner of name '%s': no such name", name);
1088       return NULL;
1089     }
1090
1091   ret = ioctl(worker->fd, KDBUS_CMD_LIST, &cmd);
1092   if (ret < 0)
1093     {
1094       g_set_error (error,
1095                    G_DBUS_ERROR,
1096                    G_DBUS_ERROR_FAILED,
1097                    _("Error listing names"));
1098       return NULL;
1099     }
1100
1101   name_list = (struct kdbus_info *) ((guint8 *) worker->kdbus_buffer + cmd.offset);
1102
1103   unique_name = g_string_new (NULL);
1104   builder = g_variant_builder_new (G_VARIANT_TYPE ("as"));
1105   KDBUS_FOREACH(kname, name_list, cmd.list_size)
1106     {
1107       struct kdbus_item *item;
1108       const char *item_name = "";
1109
1110       KDBUS_ITEM_FOREACH(item, kname, items)
1111         if (item->type == KDBUS_ITEM_NAME)
1112           item_name = item->str;
1113
1114       if (strcmp(item_name, name))
1115         continue;
1116
1117       g_string_printf (unique_name, ":1.%llu", kname->id);
1118       g_variant_builder_add (builder, "s", item_name);
1119     }
1120
1121   result = g_variant_new ("(as)", builder);
1122   g_variant_builder_unref (builder);
1123   g_string_free (unique_name,TRUE);
1124
1125   g_kdbus_free_data (worker, cmd.offset);
1126   return result;
1127 }
1128
1129
1130 /**
1131  * g_kdbus_GetConnInfo_internal:
1132  *
1133  */
1134 static GVariant *
1135 g_kdbus_GetConnInfo_internal (GKDBusWorker  *worker,
1136                               const gchar      *name,
1137                               guint64           flag,
1138                               GError          **error)
1139 {
1140   GVariant *result;
1141
1142   struct kdbus_cmd_info *cmd;
1143   struct kdbus_info *conn_info;
1144   struct kdbus_item *item;
1145   gssize size, len;
1146   gint ret;
1147
1148   result = NULL;
1149
1150   if (!g_dbus_is_name (name))
1151     {
1152       g_set_error (error,
1153                    G_DBUS_ERROR,
1154                    G_DBUS_ERROR_INVALID_ARGS,
1155                    "Given bus name \"%s\" is not valid", name);
1156       return NULL;
1157     }
1158
1159   if (!g_kdbus_NameHasOwner_internal (worker, name, error))
1160     {
1161       g_set_error (error,
1162                    G_DBUS_ERROR,
1163                    G_DBUS_ERROR_NAME_HAS_NO_OWNER,
1164                    "Could not get owner of name '%s': no such name", name);
1165       return NULL;
1166     }
1167
1168   if (g_dbus_is_unique_name(name))
1169     {
1170        size = G_STRUCT_OFFSET (struct kdbus_cmd_info, items);
1171        cmd = g_alloca0 (size);
1172        cmd->id = g_ascii_strtoull (name+3, NULL, 10);
1173     }
1174   else
1175     {
1176        len = strlen(name) + 1;
1177        size = G_STRUCT_OFFSET (struct kdbus_cmd_info, items) + KDBUS_ITEM_SIZE(len);
1178        cmd = g_alloca0 (size);
1179        cmd->items[0].size = KDBUS_ITEM_HEADER_SIZE + len;
1180        cmd->items[0].type = KDBUS_ITEM_NAME;
1181        memcpy (cmd->items[0].str, name, len);
1182     }
1183
1184   cmd->attach_flags = _KDBUS_ATTACH_ALL;
1185   cmd->size = size;
1186
1187   ret = ioctl(worker->fd, KDBUS_CMD_CONN_INFO, cmd);
1188   if (ret < 0)
1189     {
1190       g_set_error (error,
1191                    G_DBUS_ERROR,
1192                    G_DBUS_ERROR_FAILED,
1193                    _("Could not get connection info"));
1194       return NULL;
1195     }
1196
1197   conn_info = (struct kdbus_info *) ((guint8 *) worker->kdbus_buffer + cmd->offset);
1198
1199   /*
1200   if (conn_info->flags & KDBUS_HELLO_ACTIVATOR)
1201     {}
1202   */
1203
1204   if (flag == G_BUS_CREDS_UNIQUE_NAME)
1205     {
1206        GString *unique_name;
1207
1208        unique_name = g_string_new (NULL);
1209        g_string_printf (unique_name, ":1.%llu", (unsigned long long) conn_info->id);
1210        result = g_variant_new ("(s)", unique_name->str);
1211        g_string_free (unique_name,TRUE);
1212        goto exit;
1213     }
1214
1215   KDBUS_ITEM_FOREACH(item, conn_info, items)
1216    {
1217       switch (item->type)
1218         {
1219           case KDBUS_ITEM_PIDS:
1220
1221             if (flag == G_BUS_CREDS_PID)
1222               {
1223                 guint pid = item->pids.pid;
1224                 result = g_variant_new ("(u)", pid);
1225                 goto exit;
1226               }
1227
1228           case KDBUS_ITEM_CREDS:
1229
1230             if (flag == G_BUS_CREDS_UID)
1231               {
1232                 guint uid = item->creds.uid;
1233                 result = g_variant_new ("(u)", uid);
1234                 goto exit;
1235               }
1236
1237           case KDBUS_ITEM_SECLABEL:
1238           case KDBUS_ITEM_PID_COMM:
1239           case KDBUS_ITEM_TID_COMM:
1240           case KDBUS_ITEM_EXE:
1241           case KDBUS_ITEM_CMDLINE:
1242           case KDBUS_ITEM_CGROUP:
1243           case KDBUS_ITEM_CAPS:
1244           case KDBUS_ITEM_AUDIT:
1245           case KDBUS_ITEM_CONN_DESCRIPTION:
1246           case KDBUS_ITEM_AUXGROUPS:
1247           case KDBUS_ITEM_OWNED_NAME:
1248             break;
1249         }
1250    }
1251
1252 exit:
1253   g_kdbus_free_data (worker, cmd->offset);
1254   return result;
1255 }
1256
1257
1258 /**
1259  * _g_kdbus_GetNameOwner:
1260  *
1261  */
1262 GVariant *
1263 _g_kdbus_GetNameOwner (GKDBusWorker  *worker,
1264                        const gchar      *name,
1265                        GError          **error)
1266 {
1267   return g_kdbus_GetConnInfo_internal (worker,
1268                                        name,
1269                                        G_BUS_CREDS_UNIQUE_NAME,
1270                                        error);
1271 }
1272
1273
1274 /**
1275  * _g_kdbus_GetConnectionUnixProcessID:
1276  *
1277  */
1278 GVariant *
1279 _g_kdbus_GetConnectionUnixProcessID (GKDBusWorker  *worker,
1280                                      const gchar      *name,
1281                                      GError          **error)
1282 {
1283   return g_kdbus_GetConnInfo_internal (worker,
1284                                        name,
1285                                        G_BUS_CREDS_PID,
1286                                        error);
1287 }
1288
1289
1290 /**
1291  * _g_kdbus_GetConnectionUnixUser:
1292  *
1293  */
1294 GVariant *
1295 _g_kdbus_GetConnectionUnixUser (GKDBusWorker  *worker,
1296                                 const gchar      *name,
1297                                 GError          **error)
1298 {
1299   return g_kdbus_GetConnInfo_internal (worker,
1300                                        name,
1301                                        G_BUS_CREDS_UID,
1302                                        error);
1303 }
1304
1305
1306 /**
1307  * g_kdbus_bloom_add_data:
1308  * Based on bus-bloom.c from systemd
1309  * http://cgit.freedesktop.org/systemd/systemd/tree/src/libsystemd/sd-bus/bus-bloom.c
1310  */
1311 static void
1312 g_kdbus_bloom_add_data (GKDBusWorker  *worker,
1313                         guint64        bloom_data [],
1314                         const void    *data,
1315                         gsize          n)
1316 {
1317   guint8 hash[8];
1318   guint64 bit_num;
1319   guint bytes_num = 0;
1320   guint cnt_1, cnt_2;
1321   guint hash_index = 0;
1322
1323   guint c = 0;
1324   guint64 p = 0;
1325
1326   bit_num = worker->bloom_size * 8;
1327
1328   if (bit_num > 1)
1329     bytes_num = ((__builtin_clzll(bit_num) ^ 63U) + 7) / 8;
1330
1331   for (cnt_1 = 0; cnt_1 < (worker->bloom_n_hash); cnt_1++)
1332     {
1333       for (cnt_2 = 0, hash_index = 0; cnt_2 < bytes_num; cnt_2++)
1334         {
1335           if (c <= 0)
1336             {
1337               _g_siphash24(hash, data, n, hash_keys[hash_index++]);
1338               c += 8;
1339             }
1340
1341           p = (p << 8ULL) | (guint64) hash[8 - c];
1342           c--;
1343         }
1344
1345       p &= bit_num - 1;
1346       bloom_data[p >> 6] |= 1ULL << (p & 63);
1347     }
1348 }
1349
1350
1351 /**
1352  * g_kdbus_bloom_add_pair:
1353  *
1354  */
1355 static void
1356 g_kdbus_bloom_add_pair (GKDBusWorker  *worker,
1357                         guint64        bloom_data [],
1358                         const gchar   *parameter,
1359                         const gchar   *value)
1360 {
1361   gchar buf[1024];
1362   gsize size;
1363
1364   size = strlen(parameter) + strlen(value) + 1;
1365   if (size > 1024)
1366     return;
1367
1368   strcpy(stpcpy(stpcpy(buf, parameter), ":"), value);
1369   g_kdbus_bloom_add_data(worker, bloom_data, buf, size);
1370 }
1371
1372
1373 /**
1374  * g_kdbus_bloom_add_prefixes:
1375  *
1376  */
1377 static void
1378 g_kdbus_bloom_add_prefixes (GKDBusWorker  *worker,
1379                             guint64        bloom_data [],
1380                             const gchar   *parameter,
1381                             const gchar   *value,
1382                             gchar          separator)
1383 {
1384   gchar buf[1024];
1385   gsize size;
1386
1387   size = strlen(parameter) + strlen(value) + 1;
1388   if (size > 1024)
1389     return;
1390
1391   strcpy(stpcpy(stpcpy(buf, parameter), ":"), value);
1392
1393   for (;;)
1394     {
1395       gchar *last_sep;
1396       last_sep = strrchr(buf, separator);
1397       if (!last_sep || last_sep == buf)
1398         break;
1399
1400       *last_sep = 0;
1401       g_kdbus_bloom_add_data(worker, bloom_data, buf, last_sep-buf);
1402     }
1403 }
1404
1405
1406 /**
1407  * _g_kdbus_AddMatch:
1408  *
1409  */
1410 void
1411 _g_kdbus_AddMatch (GKDBusWorker  *worker,
1412                    const gchar   *match_rule,
1413                    guint64        cookie)
1414 {
1415   Match *match;
1416   MatchElement *element;
1417   const gchar *sender_name;
1418   gsize sender_len, size;
1419   struct kdbus_cmd_match *cmd;
1420   struct kdbus_item *item;
1421   guint64 *bloom;
1422   guint64 src_id;
1423   gchar *type;
1424   gint cnt, ret;
1425
1426   if (match_rule[0] == '-')
1427     return;
1428
1429   match = match_new (match_rule);
1430   if (!match)
1431     {
1432       match_free (match);
1433       return;
1434     }
1435
1436   sender_name = NULL;
1437   src_id = KDBUS_MATCH_ID_ANY;
1438
1439   bloom = g_alloca0 (worker->bloom_size);
1440   size = KDBUS_ALIGN8 (G_STRUCT_OFFSET (struct kdbus_cmd_match, items));
1441   match = match_new (match_rule);
1442
1443   for (cnt = 0; cnt < match->n_elements; cnt++)
1444     {
1445       element = &match->elements[cnt];
1446       switch (element->type)
1447         {
1448           case MATCH_ELEMENT_SENDER:
1449             if (g_dbus_is_unique_name(element->value))
1450               {
1451                 src_id = g_ascii_strtoull ((element->value)+3, NULL, 10);
1452                 size += KDBUS_ALIGN8 (G_STRUCT_OFFSET (struct kdbus_item, id) + sizeof(src_id));
1453               }
1454             else if (g_dbus_is_name (element->value))
1455               {
1456                 sender_name = element->value;
1457                 sender_len = strlen(element->value) + 1;
1458                 size += KDBUS_ALIGN8 (G_STRUCT_OFFSET (struct kdbus_item, str) + sender_len);
1459               }
1460             else
1461               {
1462                 g_critical ("Error while adding a match");
1463                 match_free (match);
1464                 return;
1465               }
1466             break;
1467
1468           case MATCH_ELEMENT_TYPE:
1469             g_kdbus_bloom_add_pair (worker, bloom, "message-type", element->value);
1470             break;
1471
1472           case MATCH_ELEMENT_INTERFACE:
1473             g_kdbus_bloom_add_pair (worker, bloom, "interface", element->value);
1474             break;
1475
1476           case MATCH_ELEMENT_MEMBER:
1477             g_kdbus_bloom_add_pair (worker, bloom, "member", element->value);
1478             break;
1479
1480           case MATCH_ELEMENT_PATH:
1481             g_kdbus_bloom_add_pair (worker, bloom, "path", element->value);
1482             break;
1483
1484           case MATCH_ELEMENT_PATH_NAMESPACE:
1485             if (g_strcmp0 (element->value, "/"))
1486               g_kdbus_bloom_add_pair (worker, bloom, "path-slash-prefix", element->value);
1487             break;
1488
1489           case MATCH_ELEMENT_ARGN:
1490             asprintf (&type, "arg%u", element->arg);
1491             g_kdbus_bloom_add_pair (worker, bloom, type, element->value);
1492             free (type);
1493             break;
1494
1495           case MATCH_ELEMENT_ARGNPATH:
1496             asprintf (&type, "arg%u-slash-prefix", element->arg);
1497             g_kdbus_bloom_add_pair (worker, bloom, type, element->value);
1498             free (type);
1499             break;
1500
1501           case MATCH_ELEMENT_ARG0NAMESPACE:
1502             g_kdbus_bloom_add_pair (worker, bloom, "arg0-dot-prefix", element->value);
1503             break;
1504
1505           case MATCH_ELEMENT_DESTINATION:
1506           case MATCH_ELEMENT_EAVESDROP:
1507             break;
1508         }
1509     }
1510
1511   size += KDBUS_ALIGN8 (G_STRUCT_OFFSET (struct kdbus_item, data64) + worker->bloom_size);
1512   cmd = g_alloca0 (size);
1513   cmd->size = size;
1514   cmd->cookie = cookie;
1515
1516   item = cmd->items;
1517   item->size = G_STRUCT_OFFSET(struct kdbus_item, data64) + worker->bloom_size;
1518   item->type = KDBUS_ITEM_BLOOM_MASK;
1519   memcpy(item->data64, bloom, worker->bloom_size);
1520   item = KDBUS_ITEM_NEXT(item);
1521
1522   if (src_id != KDBUS_MATCH_ID_ANY)
1523     {
1524       item->size = G_STRUCT_OFFSET (struct kdbus_item, id) + sizeof(src_id);
1525       item->type = KDBUS_ITEM_ID;
1526       item->id = src_id;
1527       item = KDBUS_ITEM_NEXT(item);
1528     }
1529
1530   if (sender_name)
1531     {
1532       item->size = G_STRUCT_OFFSET (struct kdbus_item, str) + sender_len;
1533       item->type = KDBUS_ITEM_NAME;
1534       memcpy (item->str, sender_name, sender_len);
1535     }
1536
1537   ret = ioctl(worker->fd, KDBUS_CMD_MATCH_ADD, cmd);
1538   if (ret < 0)
1539     g_critical ("Error while adding a match: %d", (int) errno);
1540
1541   match_free (match);
1542 }
1543
1544
1545 /**
1546  * _g_kdbus_RemoveMatch:
1547  *
1548  */
1549 void
1550 _g_kdbus_RemoveMatch (GKDBusWorker  *worker,
1551                       guint64        cookie)
1552 {
1553   struct kdbus_cmd_match cmd = {
1554     .size = sizeof(cmd),
1555     .cookie = cookie
1556   };
1557   gint ret;
1558
1559   g_print ("Unsubscribe match entry with cookie - %d\n", (int)cookie);
1560   ret = ioctl(worker->fd, KDBUS_CMD_MATCH_REMOVE, &cmd);
1561   if (ret < 0)
1562     g_warning ("Error while removing a match: %d\n", errno);
1563 }
1564
1565
1566 /**
1567  * _g_kdbus_subscribe_name_owner_changed_internal:
1568  *
1569  */
1570 static void
1571 _g_kdbus_subscribe_name_owner_changed_internal (GKDBusWorker  *worker,
1572                                                 const gchar   *name,
1573                                                 const gchar   *old_name,
1574                                                 const gchar   *new_name,
1575                                                 guint64        cookie)
1576 {
1577   struct kdbus_item *item;
1578   struct kdbus_cmd_match *cmd;
1579   gssize size, len;
1580   gint ret;
1581   guint64 old_id = 0;
1582   guint64 new_id = KDBUS_MATCH_ID_ANY;
1583
1584   if (name)
1585     len = strlen(name) + 1;
1586   else
1587     len = 0;
1588
1589   size = KDBUS_ALIGN8(G_STRUCT_OFFSET (struct kdbus_cmd_match, items) +
1590                       G_STRUCT_OFFSET (struct kdbus_item, name_change) +
1591                       G_STRUCT_OFFSET (struct kdbus_notify_name_change, name) + len);
1592
1593   cmd = g_alloca0 (size);
1594   cmd->size = size;
1595   cmd->cookie = cookie;
1596   item = cmd->items;
1597
1598   if (old_name == NULL)
1599     {
1600       old_id = KDBUS_MATCH_ID_ANY;
1601     }
1602   else
1603     {
1604       if (g_dbus_is_unique_name(old_name))
1605         old_id = strtoull (old_name + 3, NULL, 10);
1606       else
1607         return;
1608     }
1609
1610   if (new_name == NULL)
1611     {
1612       new_id = KDBUS_MATCH_ID_ANY;
1613     }
1614   else
1615     {
1616       if (g_dbus_is_unique_name(new_name))
1617         new_id = strtoull (new_name + 3, NULL, 10);
1618       else
1619         return;
1620     }
1621
1622   cmd = g_alloca0 (size);
1623   cmd->size = size;
1624   cmd->cookie = cookie;
1625   item = cmd->items;
1626
1627   /* KDBUS_ITEM_NAME_CHANGE */
1628   item->type = KDBUS_ITEM_NAME_CHANGE;
1629   item->name_change.old_id.id = old_id;
1630   item->name_change.new_id.id = new_id;
1631
1632   if (name)
1633     memcpy(item->name_change.name, name, len);
1634
1635   item->size = G_STRUCT_OFFSET (struct kdbus_item, name_change) +
1636                G_STRUCT_OFFSET(struct kdbus_notify_name_change, name) + len;
1637   item = KDBUS_ITEM_NEXT(item);
1638
1639   ret = ioctl(worker->fd, KDBUS_CMD_MATCH_ADD, cmd);
1640   if (ret < 0)
1641     g_warning ("ERROR - %d\n", (int) errno);
1642 }
1643
1644
1645 /**
1646  * _g_kdbus_subscribe_name_acquired:
1647  *
1648  */
1649 void
1650 _g_kdbus_subscribe_name_acquired (GKDBusWorker  *worker,
1651                                   const gchar   *name,
1652                                   guint64        cookie)
1653 {
1654   struct kdbus_item *item;
1655   struct kdbus_cmd_match *cmd;
1656   gssize size, len;
1657   gint ret;
1658
1659   g_print ("Subscribe 'NameAcquired': name - %s ; cookie - %d\n", name, (int)cookie);
1660   if (name)
1661     len = strlen(name) + 1;
1662   else
1663     len = 0;
1664
1665   size = KDBUS_ALIGN8(G_STRUCT_OFFSET (struct kdbus_cmd_match, items) +
1666                       G_STRUCT_OFFSET (struct kdbus_item, name_change) +
1667                       G_STRUCT_OFFSET (struct kdbus_notify_name_change, name) + len);
1668
1669   cmd = g_alloca0 (size);
1670   cmd->size = size;
1671   cmd->cookie = cookie;
1672   item = cmd->items;
1673
1674   /* KDBUS_ITEM_NAME_ADD */
1675   item->type = KDBUS_ITEM_NAME_ADD;
1676   item->name_change.old_id.id = KDBUS_MATCH_ID_ANY;
1677   item->name_change.new_id.id = worker->unique_id;
1678
1679   if (name)
1680     memcpy(item->name_change.name, name, len);
1681
1682   item->size = G_STRUCT_OFFSET (struct kdbus_item, name_change) +
1683                G_STRUCT_OFFSET(struct kdbus_notify_name_change, name) + len;
1684   item = KDBUS_ITEM_NEXT(item);
1685
1686   ret = ioctl(worker->fd, KDBUS_CMD_MATCH_ADD, cmd);
1687   if (ret < 0)
1688     g_warning ("ERROR - %d\n", (int) errno);
1689
1690   _g_kdbus_subscribe_name_owner_changed_internal (worker, name, NULL, worker->unique_name, cookie);
1691 }
1692
1693
1694 /**
1695  * _g_kdbus_subscribe_name_lost:
1696  *
1697  */
1698 void
1699 _g_kdbus_subscribe_name_lost (GKDBusWorker  *worker,
1700                               const gchar   *name,
1701                               guint64        cookie)
1702 {
1703   struct kdbus_item *item;
1704   struct kdbus_cmd_match *cmd;
1705   gssize size, len;
1706   gint ret;
1707
1708   g_print ("Subscribe 'NameLost': name - %s ; cookie - %d\n", name, (int)cookie);
1709   if (name)
1710     len = strlen(name) + 1;
1711   else
1712     len = 0;
1713
1714   size = KDBUS_ALIGN8(G_STRUCT_OFFSET (struct kdbus_cmd_match, items) +
1715                       G_STRUCT_OFFSET (struct kdbus_item, name_change) +
1716                       G_STRUCT_OFFSET (struct kdbus_notify_name_change, name) + len);
1717
1718   cmd = g_alloca0 (size);
1719   cmd->size = size;
1720   cmd->cookie = cookie;
1721   item = cmd->items;
1722
1723   /* KDBUS_ITEM_NAME_REMOVE */
1724   item->type = KDBUS_ITEM_NAME_REMOVE;
1725   item->name_change.old_id.id = worker->unique_id;
1726   item->name_change.new_id.id = KDBUS_MATCH_ID_ANY;
1727
1728   if (name)
1729     memcpy(item->name_change.name, name, len);
1730
1731   item->size = G_STRUCT_OFFSET (struct kdbus_item, name_change) +
1732                G_STRUCT_OFFSET(struct kdbus_notify_name_change, name) + len;
1733   item = KDBUS_ITEM_NEXT(item);
1734
1735   ret = ioctl(worker->fd, KDBUS_CMD_MATCH_ADD, cmd);
1736   if (ret < 0)
1737     g_warning ("ERROR - %d\n", (int) errno);
1738
1739   _g_kdbus_subscribe_name_owner_changed_internal (worker, name, worker->unique_name, NULL, cookie);
1740 }
1741
1742
1743 /**
1744  *
1745  *
1746  */
1747 void
1748 _g_kdbus_subscribe_name_owner_changed (GKDBusWorker  *worker,
1749                                        const gchar   *name,
1750                                        guint64        cookie)
1751 {
1752   g_print ("NameOwnerChanged subscription\n");
1753 }
1754
1755
1756 /**
1757  * g_kdbus_setup_bloom:
1758  * Based on bus-bloom.c from systemd
1759  * http://cgit.freedesktop.org/systemd/systemd/tree/src/libsystemd/sd-bus/bus-bloom.c
1760  */
1761 static void
1762 g_kdbus_setup_bloom (GKDBusWorker                     *worker,
1763                      GDBusMessage               *dbus_msg,
1764                      struct kdbus_bloom_filter  *bloom_filter)
1765 {
1766   GVariant *body;
1767
1768   const gchar *message_type;
1769   const gchar *interface;
1770   const gchar *member;
1771   const gchar *path;
1772
1773   void *bloom_data;
1774
1775   body = g_dbus_message_get_body (dbus_msg);
1776   message_type = _g_dbus_enum_to_string (G_TYPE_DBUS_MESSAGE_TYPE, g_dbus_message_get_message_type (dbus_msg));
1777   interface = g_dbus_message_get_interface (dbus_msg);
1778   member = g_dbus_message_get_member (dbus_msg);
1779   path = g_dbus_message_get_path (dbus_msg);
1780
1781   bloom_data = bloom_filter->data;
1782   memset (bloom_data, 0, worker->bloom_size);
1783   bloom_filter->generation = 0;
1784
1785   g_kdbus_bloom_add_pair(worker, bloom_data, "message-type", message_type);
1786
1787   if (interface)
1788     g_kdbus_bloom_add_pair(worker, bloom_data, "interface", interface);
1789
1790   if (member)
1791     g_kdbus_bloom_add_pair(worker, bloom_data, "member", member);
1792
1793   if (path)
1794     {
1795       g_kdbus_bloom_add_pair(worker, bloom_data, "path", path);
1796       g_kdbus_bloom_add_pair(worker, bloom_data, "path-slash-prefix", path);
1797       g_kdbus_bloom_add_prefixes(worker, bloom_data, "path-slash-prefix", path, '/');
1798     }
1799
1800   if (body != NULL)
1801     {
1802       const GVariantType *body_type;
1803       const GVariantType *arg_type;
1804       guint cnt;
1805
1806       body_type = g_variant_get_type (body);
1807
1808       for (arg_type = g_variant_type_first (body_type), cnt = 0;
1809            arg_type;
1810            arg_type = g_variant_type_next (arg_type), cnt++)
1811         {
1812           gchar type_char = g_variant_type_peek_string (arg_type)[0];
1813           gchar buf[sizeof("arg")-1 + 2 + sizeof("-slash-prefix")];
1814           const gchar *str;
1815           GVariant *child;
1816           gchar *e;
1817
1818           if (type_char != 's' && type_char != 'o')
1819             /* XXX: kdbus docs say "stop after first non-string" but I
1820              * think they're wrong (vs. dbus-1 compat)...
1821              */
1822             continue;
1823
1824           child = g_variant_get_child_value (body, cnt);
1825           str = g_variant_get_string (child, NULL);
1826
1827           e = stpcpy(buf, "arg");
1828           if (cnt < 10)
1829             *(e++) = '0' + (char) cnt;
1830           else
1831             {
1832               *(e++) = '0' + (char) (cnt / 10);
1833               *(e++) = '0' + (char) (cnt % 10);
1834             }
1835
1836           /* We add this one for both strings and object paths */
1837           strcpy(e, "-slash-prefix");
1838           g_kdbus_bloom_add_prefixes(worker, bloom_data, buf, str, '/');
1839
1840           /* But the others are only for strings */
1841           if (type_char == 's')
1842             {
1843               strcpy(e, "-dot-prefix");
1844               g_kdbus_bloom_add_prefixes(worker, bloom_data, buf, str, '.');
1845
1846               *e = 0;
1847               g_kdbus_bloom_add_pair(worker, bloom_data, buf, str);
1848             }
1849
1850           g_variant_unref (child);
1851         }
1852     }
1853 }
1854
1855
1856 /**
1857  *
1858  *
1859  */
1860 static void
1861 g_kdbus_translate_id_change (GKDBusWorker       *worker,
1862                              struct kdbus_item  *item)
1863 {
1864   g_error ("TODO: translate_id_change\n");
1865 }
1866
1867
1868 /**
1869  *
1870  *
1871  */
1872 static void
1873 g_kdbus_translate_name_change (GKDBusWorker       *worker,
1874                                struct kdbus_item  *item)
1875 {
1876   GDBusMessage *signal_message;
1877
1878   signal_message = NULL;
1879
1880   /* NameAcquired */
1881   if ((item->type == KDBUS_ITEM_NAME_ADD) ||
1882       (item->type == KDBUS_ITEM_NAME_CHANGE && ((guint64)item->name_change.new_id.id == worker->unique_id)))
1883     {
1884       signal_message = g_dbus_message_new_signal ("/org/freedesktop/DBus",
1885                                                   "org.freedesktop.DBus",
1886                                                   "NameAcquired");
1887
1888       g_dbus_message_set_sender (signal_message, "org.freedesktop.DBus");
1889       g_dbus_message_set_body (signal_message,
1890                                g_variant_new ("(s)", item->name_change.name));
1891
1892       (* worker->message_received_callback) (signal_message, worker->user_data);
1893       g_object_unref (signal_message);
1894     }
1895
1896   /* NameLost */
1897   if ((item->type == KDBUS_ITEM_NAME_REMOVE) ||
1898       (item->type == KDBUS_ITEM_NAME_CHANGE && ((guint64)item->name_change.old_id.id == worker->unique_id)))
1899     {
1900       GDBusMessage *signal_message;
1901
1902       signal_message = g_dbus_message_new_signal ("/org/freedesktop/DBus",
1903                                                   "org.freedesktop.DBus",
1904                                                   "NameLost");
1905
1906       g_dbus_message_set_sender (signal_message, "org.freedesktop.DBus");
1907       g_dbus_message_set_body (signal_message,
1908                                g_variant_new ("(s)", item->name_change.name));
1909
1910       (* worker->message_received_callback) (signal_message, worker->user_data);
1911       g_object_unref (signal_message);
1912     }
1913
1914   /* NameOwnerChanged */
1915   /* TODO */
1916 }
1917
1918
1919 /**
1920  *
1921  *
1922  */
1923 static void
1924 g_kdbus_translate_kernel_reply (GKDBusWorker       *worker,
1925                                 struct kdbus_item  *item)
1926 {
1927   g_error ("TODO: translate_kernel_reply\n");
1928 }
1929
1930
1931 /**
1932  * g_kdbus_decode_kernel_msg:
1933  *
1934  */
1935 static void
1936 g_kdbus_decode_kernel_msg (GKDBusWorker           *worker,
1937                            struct kdbus_msg *msg)
1938 {
1939   struct kdbus_item *item = NULL;
1940
1941   KDBUS_ITEM_FOREACH(item, msg, items)
1942     {
1943      switch (item->type)
1944         {
1945           case KDBUS_ITEM_ID_ADD:
1946           case KDBUS_ITEM_ID_REMOVE:
1947             g_kdbus_translate_id_change (worker, item);
1948             break;
1949
1950           case KDBUS_ITEM_NAME_ADD:
1951           case KDBUS_ITEM_NAME_REMOVE:
1952           case KDBUS_ITEM_NAME_CHANGE:
1953             g_kdbus_translate_name_change (worker, item);
1954             break;
1955
1956           case KDBUS_ITEM_REPLY_TIMEOUT:
1957           case KDBUS_ITEM_REPLY_DEAD:
1958             g_kdbus_translate_kernel_reply (worker, item);
1959             break;
1960
1961           case KDBUS_ITEM_TIMESTAMP:
1962             break;
1963
1964           default:
1965             g_warning ("Unknown field in kernel message - %lld", item->type);
1966        }
1967     }
1968 }
1969
1970
1971 /**
1972  * g_kdbus_decode_dbus_msg:
1973  *
1974  */
1975 static GDBusMessage *
1976 g_kdbus_decode_dbus_msg (GKDBusWorker           *worker,
1977                          struct kdbus_msg *msg)
1978 {
1979   GDBusMessage *message;
1980   struct kdbus_item *item;
1981   gssize data_size = 0;
1982   GArray *body_vectors;
1983   gsize body_size;
1984   GVariant *body;
1985   gchar *tmp;
1986   guint i;
1987   GVariant *parts[2];
1988   GVariantIter *fields_iter;
1989   guint8 endianness, type, flags, version;
1990   guint64 key;
1991   GVariant *value;
1992   guint64 serial;
1993
1994
1995   message = g_dbus_message_new ();
1996
1997   body_vectors = g_array_new (FALSE, FALSE, sizeof (GVariantVector));
1998
1999   tmp = g_strdup_printf (":1.%"G_GUINT64_FORMAT, (guint64) msg->src_id);
2000   g_dbus_message_set_sender (message, tmp);
2001   g_free (tmp);
2002
2003   item = msg->items;
2004   body_size = 0;
2005
2006   KDBUS_ITEM_FOREACH(item, msg, items)
2007     {
2008       if (item->size <= KDBUS_ITEM_HEADER_SIZE)
2009         g_error("[KDBUS] %llu bytes - invalid data record\n", item->size);
2010
2011       data_size = item->size - KDBUS_ITEM_HEADER_SIZE;
2012
2013       switch (item->type)
2014         {
2015          /* KDBUS_ITEM_DST_NAME */
2016          case KDBUS_ITEM_DST_NAME:
2017            /* Classic D-Bus doesn't make this known to the receiver, so
2018             * we don't do it here either (for compatibility with the
2019             * fallback case).
2020             */
2021            break;
2022
2023         /* KDBUS_ITEM_PALOAD_OFF */
2024         case KDBUS_ITEM_PAYLOAD_OFF:
2025           {
2026             GVariantVector vector;
2027             gsize flavour;
2028
2029             /* We want to make sure the bytes are aligned the same as
2030              * they would be if they appeared in a contiguously
2031              * allocated chunk of aligned memory.
2032              *
2033              * We decide what the alignment 'should' be by consulting
2034              * body_size, which has been tracking the total size of the
2035              * message up to this point.
2036              *
2037              * We then play around with the pointer by removing as many
2038              * bytes as required to get it to the proper alignment (and
2039              * copy extra bytes accordingly).  This means that we will
2040              * grab some extra data in the 'bytes', but it won't be
2041              * shared with GVariant (which means there is no chance of
2042              * it being accidentally retransmitted).
2043              *
2044              * The kernel does the same thing, so make sure we get the
2045              * expected result.  Because of the kernel doing the same,
2046              * the result is that we will always be rounding-down to a
2047              * multiple of 8 for the pointer, which means that the
2048              * pointer will always be valid, assuming the original
2049              * address was.
2050              *
2051              * We could fix this with a new GBytes constructor that took
2052              * 'flavour' as a parameter, but it's not worth it...
2053              */
2054             flavour = body_size & 7;
2055             g_assert ((item->vec.offset & 7) == flavour);
2056
2057             vector.gbytes = g_bytes_new (((guchar *) msg) + item->vec.offset - flavour, item->vec.size + flavour);
2058             vector.data.pointer = g_bytes_get_data (vector.gbytes, NULL);
2059             vector.data.pointer += flavour;
2060             vector.size = item->vec.size;
2061
2062             g_array_append_val (body_vectors, vector);
2063             body_size += vector.size;
2064           }
2065           break;
2066
2067         /* KDBUS_ITEM_PAYLOAD_MEMFD */
2068         case KDBUS_ITEM_PAYLOAD_MEMFD:
2069           {
2070             GVariantVector vector;
2071             const guchar *data;
2072             gsize size;
2073
2074             vector.gbytes = g_bytes_new_take_zero_copy_fd (item->memfd.fd);
2075             data = g_bytes_get_data (vector.gbytes, &size);
2076
2077             g_assert (item->memfd.start + item->memfd.size <= size);
2078
2079             vector.data.pointer = data + item->memfd.start;
2080             vector.size = item->memfd.size;
2081
2082             g_array_append_val (body_vectors, vector);
2083             body_size += vector.size;
2084           }
2085           break;
2086
2087         /* KDBUS_ITEM_FDS */
2088         case KDBUS_ITEM_FDS:
2089           {
2090             GUnixFDList *fd_list;
2091
2092             fd_list = g_unix_fd_list_new_from_array (item->fds, data_size / sizeof (int));
2093             g_dbus_message_set_unix_fd_list (message, fd_list);
2094             g_object_unref (fd_list);
2095           }
2096           break;
2097
2098         /* All of the following items, like CMDLINE,
2099            CGROUP, etc. need some GDBUS API extensions and
2100            should be implemented in the future */
2101         case KDBUS_ITEM_TIMESTAMP:
2102           {
2103             /* g_print ("time: seq %llu mon %llu real %llu\n",
2104                      item->timestamp.seqnum, item->timestamp.monotonic_ns, item->timestamp.realtime_ns); */
2105
2106             //g_dbus_message_set_timestamp (message, item->timestamp.monotonic_ns / 1000);
2107             //g_dbus_message_set_serial (message, item->timestamp.seqnum);
2108             break;
2109           }
2110
2111         case KDBUS_ITEM_CREDS:
2112           {
2113             /* g_print ("creds: u%llu eu %llu su%llu fsu%llu g%llu eg%llu sg%llu fsg%llu\n",
2114                      item->creds.uid, item->creds.euid, item->creds.suid, item->creds.fsuid,
2115                      item->creds.gid, item->creds.egid, item->creds.sgid, item->creds.fsgid); */
2116             break;
2117           }
2118
2119         case KDBUS_ITEM_PIDS:
2120         case KDBUS_ITEM_PID_COMM:
2121         case KDBUS_ITEM_TID_COMM:
2122         case KDBUS_ITEM_EXE:
2123         case KDBUS_ITEM_CMDLINE:
2124         case KDBUS_ITEM_CGROUP:
2125         case KDBUS_ITEM_AUDIT:
2126         case KDBUS_ITEM_CAPS:
2127         case KDBUS_ITEM_SECLABEL:
2128         case KDBUS_ITEM_CONN_DESCRIPTION:
2129         case KDBUS_ITEM_AUXGROUPS:
2130         case KDBUS_ITEM_OWNED_NAME:
2131         case KDBUS_ITEM_NAME:
2132           //g_print ("unhandled %04x\n", (int) item->type);
2133           break;
2134
2135         default:
2136           g_error ("[KDBUS] DBUS_PAYLOAD: Unknown filed - %lld", item->type);
2137           break;
2138         }
2139     }
2140
2141   body = GLIB_PRIVATE_CALL(g_variant_from_vectors) (G_VARIANT_TYPE ("((yyyyuta{tv})v)"),
2142                                                     (GVariantVector *) body_vectors->data,
2143                                                     body_vectors->len, body_size, FALSE);
2144   g_assert (body);
2145
2146   for (i = 0; i < body_vectors->len; i++)
2147     g_bytes_unref (g_array_index (body_vectors, GVariantVector, i).gbytes);
2148
2149   g_array_free (body_vectors, TRUE);
2150
2151   parts[0] = g_variant_get_child_value (body, 0);
2152   parts[1] = g_variant_get_child_value (body, 1);
2153   g_variant_unref (body);
2154
2155   g_variant_get (parts[0], "(yyyyuta{tv})", &endianness, &type, &flags, &version, NULL, &serial, &fields_iter);
2156   g_variant_unref (parts[0]);
2157
2158   while (g_variant_iter_loop (fields_iter, "{tv}", &key, &value))
2159     g_dbus_message_set_header (message, key, value);
2160
2161   g_dbus_message_set_flags (message, flags);
2162   g_dbus_message_set_serial (message, serial);
2163   g_dbus_message_set_message_type (message, type);
2164
2165   //if (g_dbus_message_get_header (message, G_DBUS_MESSAGE_HEADER_FIELD_SIGNATURE) != NULL)
2166   //  {
2167       body = g_variant_get_variant (parts[1]);
2168       g_dbus_message_set_body (message, body);
2169       g_variant_unref (body);
2170   //  }
2171   g_variant_unref (parts[1]);
2172
2173   //g_print ("Received:\n%s\n", g_dbus_message_print (message, 2));
2174
2175   (* worker->message_received_callback) (message, worker->user_data);
2176
2177   g_object_unref (message);
2178
2179   return 0;
2180 }
2181
2182
2183 /**
2184  * _g_kdbus_receive:
2185  *
2186  */
2187 static gssize
2188 _g_kdbus_receive (GKDBusWorker        *kdbus,
2189                   GCancellable  *cancellable,
2190                   GError       **error)
2191 {
2192   struct kdbus_cmd_recv recv;
2193   struct kdbus_msg *msg;
2194
2195   memset (&recv, 0, sizeof recv);
2196   recv.size = sizeof (recv);
2197
2198   if (g_cancellable_set_error_if_cancelled (cancellable, error))
2199     return -1;
2200
2201 again:
2202     if (ioctl(kdbus->fd, KDBUS_CMD_RECV, &recv) < 0)
2203       {
2204         if (errno == EINTR)
2205           goto again;
2206
2207         if (errno == EAGAIN)
2208           return 0;
2209
2210         g_warning ("in holding pattern over %d %d\n", kdbus->fd, errno);
2211         while (1)
2212           sleep(1);
2213
2214         g_set_error (error, G_IO_ERROR,
2215                      g_io_error_from_errno (errno),
2216                      _("Error while receiving message: %s"),
2217                      g_strerror (errno));
2218         return -1;
2219       }
2220
2221    msg = (struct kdbus_msg *)((guint8 *)kdbus->kdbus_buffer + recv.msg.offset);
2222
2223    if (msg->payload_type == KDBUS_PAYLOAD_DBUS)
2224      g_kdbus_decode_dbus_msg (kdbus, msg);
2225    else if (msg->payload_type == KDBUS_PAYLOAD_KERNEL)
2226      g_kdbus_decode_kernel_msg (kdbus, msg);
2227    else
2228      {
2229        g_set_error (error,
2230                     G_DBUS_ERROR,
2231                     G_DBUS_ERROR_FAILED,
2232                     _("Received unknown payload type"));
2233        return -1;
2234      }
2235
2236   g_kdbus_free_data (kdbus, recv.msg.offset);
2237
2238   return 0;
2239 }
2240
2241 static gboolean
2242 g_kdbus_msg_append_item (struct kdbus_msg *msg,
2243                          gsize             type,
2244                          gconstpointer     data,
2245                          gsize             size)
2246 {
2247   struct kdbus_item *item;
2248   gsize item_size;
2249
2250   item_size = size + G_STRUCT_OFFSET(struct kdbus_item, data);
2251
2252   if (msg->size + item_size > KDBUS_MSG_MAX_SIZE)
2253     return FALSE;
2254
2255   /* align */
2256   msg->size += (-msg->size) & 7;
2257   item = (struct kdbus_item *) ((guchar *) msg + msg->size);
2258   item->type = type;
2259   item->size = item_size;
2260   memcpy (item->data, data, size);
2261
2262   msg->size += item_size;
2263
2264   return TRUE;
2265 }
2266
2267 static gboolean
2268 g_kdbus_msg_append_payload_vec (struct kdbus_msg *msg,
2269                                 gconstpointer     data,
2270                                 gsize             size)
2271 {
2272   struct kdbus_vec vec = {
2273     .size = size,
2274     .address = (gsize) data
2275   };
2276
2277   return g_kdbus_msg_append_item (msg, KDBUS_ITEM_PAYLOAD_VEC, &vec, sizeof vec);
2278 }
2279
2280 static gboolean
2281 g_kdbus_msg_append_payload_memfd (struct kdbus_msg *msg,
2282                                   gint              fd,
2283                                   gsize             offset,
2284                                   gsize             size)
2285 {
2286   struct kdbus_memfd mfd = {
2287    .start = offset,
2288    .size = size,
2289    .fd = fd,
2290   };
2291
2292   return g_kdbus_msg_append_item (msg, KDBUS_ITEM_PAYLOAD_MEMFD, &mfd, sizeof mfd);
2293 }
2294
2295 static struct kdbus_bloom_filter *
2296 g_kdbus_msg_append_bloom (struct kdbus_msg *msg,
2297                           gsize             size)
2298 {
2299   struct kdbus_item *bloom_item;
2300   gsize bloom_item_size;
2301
2302   bloom_item_size = G_STRUCT_OFFSET (struct kdbus_item, bloom_filter) +
2303                     G_STRUCT_OFFSET (struct kdbus_bloom_filter, data) +
2304                     size;
2305   if (msg->size + bloom_item_size > KDBUS_MSG_MAX_SIZE)
2306     return NULL;
2307
2308   /* align */
2309   msg->size += (-msg->size) & 7;
2310   bloom_item = (struct kdbus_item *) ((guchar *) msg + msg->size);
2311
2312   /* set size and type */
2313   bloom_item->size = bloom_item_size;
2314   bloom_item->type = KDBUS_ITEM_BLOOM_FILTER;
2315
2316   msg->size += bloom_item->size;
2317   return &bloom_item->bloom_filter;
2318 }
2319
2320 #if 0
2321 #include "dbusheader.h"
2322
2323 void dump_header (gconstpointer data, gsize size) ;
2324 void
2325 dump_header (gconstpointer data,
2326              gsize size)
2327 {
2328   GDBusMessageHeaderFieldsIterator iter;
2329   GDBusMessageHeader header;
2330
2331   header = g_dbus_message_header_new (data, size);
2332   g_print ("header e/%c t/%u f/x%x v/%u s/%"G_GUINT64_FORMAT"\n",
2333            g_dbus_message_header_get_endian (header),
2334            g_dbus_message_header_get_type (header),
2335            g_dbus_message_header_get_flags (header),
2336            g_dbus_message_header_get_version (header),
2337            g_dbus_message_header_get_serial (header));
2338
2339   iter = g_dbus_message_header_iterate_fields (header);
2340
2341   while (g_dbus_message_header_fields_iterator_next (&iter))
2342     {
2343       const gchar *string;
2344       guint64 reply_to;
2345       guint64 key;
2346
2347       key = g_dbus_message_header_fields_iterator_get_key (iter);
2348
2349       switch (key)
2350         {
2351           case G_DBUS_MESSAGE_HEADER_FIELD_PATH:
2352             if (g_dbus_message_header_fields_iterator_get_value_as_object_path (iter, &string))
2353               g_print ("  path: %s\n", string);
2354             else
2355               g_print ("  path: <<invalid string>>\n");
2356             break;
2357
2358           case G_DBUS_MESSAGE_HEADER_FIELD_INTERFACE:
2359             if (g_dbus_message_header_fields_iterator_get_value_as_string (iter, &string))
2360               g_print ("  interface: %s\n", string);
2361             else
2362               g_print ("  interface: <<invalid string>>\n");
2363             break;
2364
2365           case G_DBUS_MESSAGE_HEADER_FIELD_MEMBER:
2366             if (g_dbus_message_header_fields_iterator_get_value_as_string (iter, &string))
2367               g_print ("  member: %s\n", string);
2368             else
2369               g_print ("  member: <<invalid string>>\n");
2370             break;
2371
2372           case G_DBUS_MESSAGE_HEADER_FIELD_ERROR_NAME:
2373             if (g_dbus_message_header_fields_iterator_get_value_as_string (iter, &string))
2374               g_print ("  error: %s\n", string);
2375             else
2376               g_print ("  error: <<invalid string>>\n");
2377             break;
2378
2379           case G_DBUS_MESSAGE_HEADER_FIELD_REPLY_SERIAL:
2380             if (g_dbus_message_header_fields_iterator_get_value_as_string (iter, &string))
2381               g_print ("  serial: %s\n", string);
2382             else
2383               g_print ("  serial: <<invalid string>>\n");
2384             break;
2385
2386           case G_DBUS_MESSAGE_HEADER_FIELD_DESTINATION:
2387             if (g_dbus_message_header_fields_iterator_get_value_as_string (iter, &string))
2388               g_print ("  destination: %s\n", string);
2389             else
2390               g_print ("  destination: <<invalid string>>\n");
2391             break;
2392
2393           case G_DBUS_MESSAGE_HEADER_FIELD_SENDER:
2394             if (g_dbus_message_header_fields_iterator_get_value_as_string (iter, &string))
2395               g_print ("  sender: %s\n", string);
2396             else
2397               g_print ("  sender: <<invalid string>>\n");
2398             break;
2399
2400           default:
2401             g_print ("unknown field code %"G_GUINT64_FORMAT"\n", key);
2402             g_assert_not_reached ();
2403         }
2404     }
2405
2406   g_print ("\n");
2407
2408 }
2409 #endif
2410
2411 /**
2412  * _g_kdbus_send:
2413  * Returns: size of data sent or -1 when error
2414  */
2415 static gboolean
2416 _g_kdbus_send (GKDBusWorker        *kdbus,
2417                GDBusMessage  *message,
2418                GError       **error)
2419 {
2420   struct kdbus_msg *msg = alloca (KDBUS_MSG_MAX_SIZE);
2421   GVariantVectors body_vectors;
2422   struct kdbus_cmd_send send;
2423   const gchar *dst_name;
2424
2425   g_return_val_if_fail (G_IS_KDBUS_WORKER (kdbus), -1);
2426
2427   /* fill in as we go... */
2428   memset (msg, 0, sizeof (struct kdbus_msg));
2429   msg->size = sizeof (struct kdbus_msg);
2430   msg->payload_type = KDBUS_PAYLOAD_DBUS;
2431   msg->src_id = kdbus->unique_id;
2432   msg->cookie = g_dbus_message_get_serial(message);
2433
2434   /* Message destination */
2435   {
2436     dst_name = g_dbus_message_get_destination (message);
2437
2438     if (dst_name != NULL)
2439       {
2440         if (g_dbus_is_unique_name (dst_name))
2441           {
2442             if (dst_name[1] != '1' || dst_name[2] != '.')
2443               {
2444                 g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_NAME_HAS_NO_OWNER,
2445                              "Invalid unique D-Bus name '%s'", dst_name);
2446                 return FALSE;
2447               }
2448
2449             /* We already know that it passes the checks for unique
2450              * names, so no need to perform error checking on strtoull.
2451              */
2452             msg->dst_id = strtoull (dst_name + 3, NULL, 10);
2453             dst_name = NULL;
2454           }
2455         else
2456           {
2457             g_kdbus_msg_append_item (msg, KDBUS_ITEM_DST_NAME, dst_name, strlen (dst_name) + 1);
2458             msg->dst_id = KDBUS_DST_ID_NAME;
2459           }
2460       }
2461     else
2462       msg->dst_id = KDBUS_DST_ID_BROADCAST;
2463   }
2464
2465   /* File descriptors */
2466   {
2467     GUnixFDList *fd_list;
2468
2469     fd_list = g_dbus_message_get_unix_fd_list (message);
2470
2471     if (fd_list != NULL)
2472       {
2473         const gint *fds;
2474         gint n_fds;
2475
2476         fds = g_unix_fd_list_peek_fds (fd_list, &n_fds);
2477
2478         if (n_fds)
2479           g_kdbus_msg_append_item (msg, KDBUS_ITEM_FDS, fds, sizeof (gint) * n_fds);
2480       }
2481   }
2482
2483   /* Message body */
2484   {
2485     struct dbus_fixed_header fh;
2486     GHashTableIter header_iter;
2487     GVariantBuilder builder;
2488     gpointer key, value;
2489     GVariant *parts[3];
2490     GVariant *body;
2491
2492     fh.endian = (G_BYTE_ORDER == G_LITTLE_ENDIAN) ? 'l': 'B';
2493     fh.type = g_dbus_message_get_message_type (message);
2494     fh.flags = g_dbus_message_get_flags (message);
2495     fh.version = 2;
2496     fh.reserved = 0;
2497     fh.serial = g_dbus_message_get_serial (message);
2498     parts[0] = g_variant_new_from_data (DBUS_FIXED_HEADER_TYPE, &fh, sizeof fh, TRUE, NULL, NULL);
2499
2500     g_dbus_message_init_header_iter (message, &header_iter);
2501     g_variant_builder_init (&builder, DBUS_EXTENDED_HEADER_TYPE);
2502
2503     /* We set the sender field to the correct value for ourselves */
2504     g_variant_builder_add (&builder, "{tv}",
2505                            (guint64) G_DBUS_MESSAGE_HEADER_FIELD_SENDER,
2506                            g_variant_new_printf (":1.%"G_GUINT64_FORMAT, kdbus->unique_id));
2507
2508     while (g_hash_table_iter_next (&header_iter, &key, &value))
2509       {
2510         guint64 key_int = (gsize) key;
2511
2512         switch (key_int)
2513           {
2514             /* These are the normal header fields that get passed
2515              * straight through.
2516              */
2517             case G_DBUS_MESSAGE_HEADER_FIELD_PATH:
2518             case G_DBUS_MESSAGE_HEADER_FIELD_INTERFACE:
2519             case G_DBUS_MESSAGE_HEADER_FIELD_MEMBER:
2520             case G_DBUS_MESSAGE_HEADER_FIELD_ERROR_NAME:
2521             case G_DBUS_MESSAGE_HEADER_FIELD_REPLY_SERIAL:
2522             case G_DBUS_MESSAGE_HEADER_FIELD_DESTINATION:
2523               g_variant_builder_add (&builder, "{tv}", key_int, value);
2524               /* This is a little bit gross.
2525                *
2526                * We must send the header part of the message in a single
2527                * vector as per kdbus rules, but the GVariant serialiser
2528                * code will split any item >= 128 bytes into its own
2529                * vector to save the copy.
2530                *
2531                * No header field should be that big anyway... right?
2532                */
2533               g_assert_cmpint (g_variant_get_size (value), <, 128);
2534               continue;
2535
2536             /* We send this one unconditionally, but set it ourselves */
2537             case G_DBUS_MESSAGE_HEADER_FIELD_SENDER:
2538               continue;
2539
2540             /* We don't send these at all in GVariant format */
2541             case G_DBUS_MESSAGE_HEADER_FIELD_SIGNATURE:
2542             case G_DBUS_MESSAGE_HEADER_FIELD_NUM_UNIX_FDS:
2543               continue;
2544
2545             default:
2546               g_assert_not_reached ();
2547           }
2548       }
2549     parts[1] = g_variant_builder_end (&builder);
2550
2551     body = g_dbus_message_get_body (message);
2552     if (!body)
2553       body = g_variant_new ("()");
2554     parts[2] = g_variant_new_variant (body);
2555
2556     body = g_variant_ref_sink (g_variant_new_tuple (parts, G_N_ELEMENTS (parts)));
2557     GLIB_PRIVATE_CALL(g_variant_to_vectors) (body, &body_vectors);
2558
2559     /* Sanity check to make sure the header is really contiguous:
2560      *
2561      *  - we must have at least one vector in the output
2562      *  - the first vector must completely contain at least the header
2563      */
2564     g_assert_cmpint (body_vectors.vectors->len, >, 0);
2565     g_assert_cmpint (g_array_index (body_vectors.vectors, GVariantVector, 0).size, >=,
2566                      g_variant_get_size (parts[0]) + g_variant_get_size (parts[1]));
2567
2568     g_variant_unref (body);
2569   }
2570
2571   {
2572     guint i;
2573
2574     for (i = 0; i < body_vectors.vectors->len; i++)
2575       {
2576         GVariantVector vector = g_array_index (body_vectors.vectors, GVariantVector, i);
2577
2578         if (vector.gbytes)
2579           {
2580             gint fd;
2581
2582             fd = g_bytes_get_zero_copy_fd (vector.gbytes);
2583
2584             if (fd >= 0)
2585               {
2586                 const guchar *bytes_data;
2587                 gsize bytes_size;
2588
2589                 bytes_data = g_bytes_get_data (vector.gbytes, &bytes_size);
2590
2591                 if (bytes_data <= vector.data.pointer && vector.data.pointer + vector.size <= bytes_data + bytes_size)
2592                   {
2593                     if (!g_kdbus_msg_append_payload_memfd (msg, fd, vector.data.pointer - bytes_data, vector.size))
2594                       goto need_compact;
2595                   }
2596                 else
2597                   {
2598                     if (!g_kdbus_msg_append_payload_vec (msg, vector.data.pointer, vector.size))
2599                       goto need_compact;
2600                   }
2601               }
2602             else
2603               {
2604                 if (!g_kdbus_msg_append_payload_vec (msg, vector.data.pointer, vector.size))
2605                   goto need_compact;
2606               }
2607           }
2608         else
2609           if (!g_kdbus_msg_append_payload_vec (msg, body_vectors.extra_bytes->data + vector.data.offset, vector.size))
2610             goto need_compact;
2611       }
2612   }
2613
2614   /*
2615    * set message flags
2616    */
2617   msg->flags = ((g_dbus_message_get_flags (message) & G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED) ? 0 : KDBUS_MSG_EXPECT_REPLY) |
2618                 ((g_dbus_message_get_flags (message) & G_DBUS_MESSAGE_FLAGS_NO_AUTO_START) ? KDBUS_MSG_NO_AUTO_START : 0);
2619
2620   if ((msg->flags) & KDBUS_MSG_EXPECT_REPLY)
2621     msg->timeout_ns = 1000LU * g_get_monotonic_time() + KDBUS_TIMEOUT_NS;
2622   else
2623     msg->cookie_reply = g_dbus_message_get_reply_serial(message);
2624
2625   if (g_dbus_message_get_message_type (message) == G_DBUS_MESSAGE_TYPE_SIGNAL)
2626     msg->flags |= KDBUS_MSG_SIGNAL;
2627
2628   /*
2629    * append bloom filter item for broadcast signals
2630    */
2631   if (msg->dst_id == KDBUS_DST_ID_BROADCAST)
2632     {
2633       struct kdbus_bloom_filter *bloom_filter;
2634
2635       bloom_filter = g_kdbus_msg_append_bloom (msg, kdbus->bloom_size);
2636       if (bloom_filter == NULL)
2637         goto need_compact;
2638       g_kdbus_setup_bloom (kdbus, message, bloom_filter);
2639     }
2640
2641   send.size = sizeof (send);
2642   send.flags = 0;
2643   send.msg_address = (gsize) msg;
2644
2645   /*
2646    * send message
2647    */
2648   if (ioctl(kdbus->fd, KDBUS_CMD_SEND, &send))
2649     {
2650       if (errno == ENXIO || errno == ESRCH)
2651         {
2652           g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_SERVICE_UNKNOWN,
2653                        "Destination '%s' not known", dst_name);
2654         }
2655       else if (errno == EADDRNOTAVAIL)
2656         {
2657           g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_SERVICE_UNKNOWN,
2658                        "No support for activation for name: %s", dst_name);
2659         }
2660       else if (errno == EXFULL)
2661         {
2662           g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_LIMITS_EXCEEDED,
2663                        "The memory pool of the receiver is full");
2664         }
2665       else if (errno == ENOBUFS)
2666         {
2667           g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_LIMITS_EXCEEDED,
2668                        "Too many pending messages on the receiver side");
2669         }
2670       else
2671         {
2672           g_error ("WTF? %d\n", errno);
2673           g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
2674                        "%s", strerror(errno));
2675         }
2676       return FALSE;
2677     }
2678
2679   return TRUE;
2680
2681 need_compact:
2682   /* We end up here if:
2683    *  - too many kdbus_items
2684    *  - too large kdbus_msg size
2685    *  - too much vector data
2686    *
2687    * We need to compact the message before sending it.
2688    */
2689   g_assert_not_reached ();
2690 }
2691
2692 GKDBusWorker *
2693 g_kdbus_worker_new (const gchar  *address,
2694                     GError      **error)
2695 {
2696   GKDBusWorker *worker;
2697
2698   worker = g_object_new (G_TYPE_KDBUS_WORKER, NULL);
2699   if (!_g_kdbus_open (worker, address, error))
2700     {
2701       g_object_unref (worker);
2702       return NULL;
2703     }
2704
2705   return worker;
2706 }
2707
2708 void
2709 g_kdbus_worker_associate (GKDBusWorker                            *worker,
2710                           GDBusCapabilityFlags                     capabilities,
2711                           GDBusWorkerMessageReceivedCallback       message_received_callback,
2712                           GDBusWorkerMessageAboutToBeSentCallback  message_about_to_be_sent_callback,
2713                           GDBusWorkerDisconnectedCallback          disconnected_callback,
2714                           gpointer                                 user_data)
2715 {
2716   worker->capabilities = capabilities;
2717   worker->message_received_callback = message_received_callback;
2718   worker->message_about_to_be_sent_callback = message_about_to_be_sent_callback;
2719   worker->disconnected_callback = disconnected_callback;
2720   worker->user_data = user_data;
2721 }
2722
2723 void
2724 g_kdbus_worker_unfreeze (GKDBusWorker *worker)
2725 {
2726   gchar *name;
2727
2728   if (worker->source != NULL)
2729     return;
2730
2731   worker->context = g_main_context_ref_thread_default ();
2732   worker->source = g_unix_fd_source_new (worker->fd, G_IO_IN);
2733
2734   g_source_set_callback (worker->source, (GSourceFunc) kdbus_ready, worker, NULL);
2735   name = g_strdup_printf ("kdbus worker");
2736   g_source_set_name (worker->source, name);
2737   g_free (name);
2738
2739   g_source_attach (worker->source, worker->context);
2740 }
2741
2742 gboolean
2743 g_kdbus_worker_send_message (GKDBusWorker  *worker,
2744                              GDBusMessage  *message,
2745                              GError       **error)
2746 {
2747   return _g_kdbus_send (worker, message, error);
2748 }
2749
2750 void
2751 g_kdbus_worker_stop (GKDBusWorker *worker)
2752 {
2753 }
2754
2755 void
2756 g_kdbus_worker_flush_sync (GKDBusWorker *worker)
2757 {
2758 }
2759
2760 void
2761 g_kdbus_worker_close (GKDBusWorker       *worker,
2762                       GCancellable       *cancellable,
2763                       GSimpleAsyncResult *result)
2764 {
2765 }