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