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