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