cb614c2802ef9918895ae9aa5e7d38550f458c50
[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   GVariantIter iter;
1236   GVariant *child;
1237
1238   const gchar *message_type;
1239   const gchar *interface;
1240   const gchar *member;
1241   const gchar *path;
1242
1243   void *bloom_data;
1244   gint cnt = 0;
1245
1246   body = g_dbus_message_get_body (dbus_msg);
1247   message_type = _g_dbus_enum_to_string (G_TYPE_DBUS_MESSAGE_TYPE, g_dbus_message_get_message_type (dbus_msg));
1248   interface = g_dbus_message_get_interface (dbus_msg);
1249   member = g_dbus_message_get_member (dbus_msg);
1250   path = g_dbus_message_get_path (dbus_msg);
1251
1252   bloom_data = bloom_filter->data;
1253   memset (bloom_data, 0, worker->bloom_size);
1254   bloom_filter->generation = 0;
1255
1256   g_kdbus_bloom_add_pair(worker, bloom_data, "message-type", message_type);
1257
1258   if (interface)
1259     g_kdbus_bloom_add_pair(worker, bloom_data, "interface", interface);
1260
1261   if (member)
1262     g_kdbus_bloom_add_pair(worker, bloom_data, "member", member);
1263
1264   if (path)
1265     {
1266       g_kdbus_bloom_add_pair(worker, bloom_data, "path", path);
1267       g_kdbus_bloom_add_pair(worker, bloom_data, "path-slash-prefix", path);
1268       g_kdbus_bloom_add_prefixes(worker, bloom_data, "path-slash-prefix", path, '/');
1269     }
1270
1271   if (body != NULL)
1272     {
1273       g_variant_iter_init (&iter, body);
1274       while ((child = g_variant_iter_next_value (&iter)))
1275         {
1276           gchar buf[sizeof("arg")-1 + 2 + sizeof("-slash-prefix")];
1277           gchar *child_string;
1278           gchar *e;
1279
1280           /* Is it necessary? */
1281           //if (g_variant_is_container (child))
1282           //  iterate_container_recursive (child);
1283
1284           if (!(g_variant_is_of_type (child, G_VARIANT_TYPE_STRING)) &&
1285               !(g_variant_is_of_type (child, G_VARIANT_TYPE_OBJECT_PATH)) &&
1286               !(g_variant_is_of_type (child, G_VARIANT_TYPE_SIGNATURE)))
1287             break;
1288
1289           child_string = g_variant_dup_string (child, NULL);
1290
1291           e = stpcpy(buf, "arg");
1292           if (cnt < 10)
1293             *(e++) = '0' + (char) cnt;
1294           else
1295             {
1296               *(e++) = '0' + (char) (cnt / 10);
1297               *(e++) = '0' + (char) (cnt % 10);
1298             }
1299
1300           *e = 0;
1301           g_kdbus_bloom_add_pair(worker, bloom_data, buf, child_string);
1302
1303           strcpy(e, "-dot-prefix");
1304           g_kdbus_bloom_add_prefixes(worker, bloom_data, buf, child_string, '.');
1305
1306           strcpy(e, "-slash-prefix");
1307           g_kdbus_bloom_add_prefixes(worker, bloom_data, buf, child_string, '/');
1308
1309           g_free (child_string);
1310           g_variant_unref (child);
1311           cnt++;
1312         }
1313     }
1314 }
1315
1316
1317 /*
1318  * TODO: g_kdbus_NameOwnerChanged_generate, g_kdbus_KernelMethodError_generate
1319  */
1320
1321 /**
1322  * g_kdbus_decode_kernel_msg:
1323  *
1324  */
1325 static void
1326 g_kdbus_decode_kernel_msg (GKDBusWorker           *worker,
1327                            struct kdbus_msg *msg)
1328 {
1329   struct kdbus_item *item = NULL;
1330
1331   KDBUS_ITEM_FOREACH(item, msg, items)
1332     {
1333      switch (item->type)
1334         {
1335           case KDBUS_ITEM_ID_ADD:
1336           case KDBUS_ITEM_ID_REMOVE:
1337           case KDBUS_ITEM_NAME_ADD:
1338           case KDBUS_ITEM_NAME_REMOVE:
1339           case KDBUS_ITEM_NAME_CHANGE:
1340             //size = g_kdbus_NameOwnerChanged_generate (worker, item);
1341             g_error ("'NameOwnerChanged'");
1342             break;
1343
1344           case KDBUS_ITEM_REPLY_TIMEOUT:
1345           case KDBUS_ITEM_REPLY_DEAD:
1346             //size = g_kdbus_KernelMethodError_generate (worker, item);
1347             g_error ("'KernelMethodError'");
1348             break;
1349
1350           default:
1351             g_warning ("Unknown field in kernel message - %lld", item->type);
1352        }
1353     }
1354
1355 #if 0
1356   /* Override information from the user header with data from the kernel */
1357   g_string_printf (worker->msg_sender, "org.freedesktop.DBus");
1358
1359   /* for destination */
1360   if (worker->kmsg->dst_id == KDBUS_DST_ID_BROADCAST)
1361     /* for broadcast messages we don't have to set destination */
1362     ;
1363   else if (worker->kmsg->dst_id == KDBUS_DST_ID_NAME)
1364     g_string_printf (worker->msg_destination, ":1.%" G_GUINT64_FORMAT, (guint64) worker->unique_id);
1365   else
1366    g_string_printf (worker->msg_destination, ":1.%" G_GUINT64_FORMAT, (guint64) worker->kmsg->dst_id);
1367
1368   return size;
1369 #endif
1370 }
1371
1372
1373 /**
1374  * g_kdbus_decode_dbus_msg:
1375  *
1376  */
1377 static GDBusMessage *
1378 g_kdbus_decode_dbus_msg (GKDBusWorker           *worker,
1379                          struct kdbus_msg *msg)
1380 {
1381   GDBusMessage *message;
1382   struct kdbus_item *item;
1383   gssize data_size = 0;
1384   GArray *body_vectors;
1385   gsize body_size;
1386   GVariant *body;
1387   gchar *tmp;
1388   guint i;
1389   GVariant *parts[2];
1390   GVariantIter *fields_iter;
1391   guint8 endianness, type, flags, version;
1392   guint64 key;
1393   GVariant *value;
1394   guint64 serial;
1395
1396
1397   message = g_dbus_message_new ();
1398
1399   body_vectors = g_array_new (FALSE, FALSE, sizeof (GVariantVector));
1400
1401   tmp = g_strdup_printf (":1.%"G_GUINT64_FORMAT, (guint64) msg->src_id);
1402   g_dbus_message_set_sender (message, tmp);
1403   g_free (tmp);
1404
1405   item = msg->items;
1406   body_size = 0;
1407
1408   KDBUS_ITEM_FOREACH(item, msg, items)
1409     {
1410       if (item->size <= KDBUS_ITEM_HEADER_SIZE)
1411         g_error("[KDBUS] %llu bytes - invalid data record\n", item->size);
1412
1413       data_size = item->size - KDBUS_ITEM_HEADER_SIZE;
1414
1415       switch (item->type)
1416         {
1417          /* KDBUS_ITEM_DST_NAME */
1418          case KDBUS_ITEM_DST_NAME:
1419            /* Classic D-Bus doesn't make this known to the receiver, so
1420             * we don't do it here either (for compatibility with the
1421             * fallback case).
1422             */
1423            break;
1424
1425         /* KDBUS_ITEM_PALOAD_OFF */
1426         case KDBUS_ITEM_PAYLOAD_OFF:
1427           {
1428             GVariantVector vector;
1429             gsize flavour;
1430
1431             /* We want to make sure the bytes are aligned the same as
1432              * they would be if they appeared in a contiguously
1433              * allocated chunk of aligned memory.
1434              *
1435              * We decide what the alignment 'should' be by consulting
1436              * body_size, which has been tracking the total size of the
1437              * message up to this point.
1438              *
1439              * We then play around with the pointer by removing as many
1440              * bytes as required to get it to the proper alignment (and
1441              * copy extra bytes accordingly).  This means that we will
1442              * grab some extra data in the 'bytes', but it won't be
1443              * shared with GVariant (which means there is no chance of
1444              * it being accidentally retransmitted).
1445              *
1446              * The kernel does the same thing, so make sure we get the
1447              * expected result.  Because of the kernel doing the same,
1448              * the result is that we will always be rounding-down to a
1449              * multiple of 8 for the pointer, which means that the
1450              * pointer will always be valid, assuming the original
1451              * address was.
1452              *
1453              * We could fix this with a new GBytes constructor that took
1454              * 'flavour' as a parameter, but it's not worth it...
1455              */
1456             flavour = body_size & 7;
1457             g_assert ((item->vec.offset & 7) == flavour);
1458
1459             vector.gbytes = g_bytes_new (((guchar *) worker->kdbus_buffer) + item->vec.offset - flavour, item->vec.size + flavour);
1460             vector.data.pointer = g_bytes_get_data (vector.gbytes, NULL);
1461             vector.data.pointer += flavour;
1462             vector.size = item->vec.size;
1463
1464             g_array_append_val (body_vectors, vector);
1465             body_size += vector.size;
1466           }
1467           break;
1468
1469         /* KDBUS_ITEM_PAYLOAD_MEMFD */
1470         case KDBUS_ITEM_PAYLOAD_MEMFD:
1471           {
1472             GVariantVector vector;
1473             const guchar *data;
1474             gsize size;
1475
1476             vector.gbytes = g_bytes_new_take_zero_copy_fd (item->memfd.fd);
1477             data = g_bytes_get_data (vector.gbytes, &size);
1478
1479             g_assert (item->memfd.start + item->memfd.size <= size);
1480
1481             vector.data.pointer = data + item->memfd.start;
1482             vector.size = item->memfd.size;
1483
1484             g_array_append_val (body_vectors, vector);
1485             body_size += vector.size;
1486           }
1487           break;
1488
1489         /* KDBUS_ITEM_FDS */
1490         case KDBUS_ITEM_FDS:
1491           {
1492             GUnixFDList *fd_list;
1493
1494             fd_list = g_unix_fd_list_new_from_array (item->fds, data_size / sizeof (int));
1495             g_dbus_message_set_unix_fd_list (message, fd_list);
1496             g_object_unref (fd_list);
1497           }
1498           break;
1499
1500         /* All of the following items, like CMDLINE,
1501            CGROUP, etc. need some GDBUS API extensions and
1502            should be implemented in the future */
1503         case KDBUS_ITEM_TIMESTAMP:
1504           {
1505             g_print ("time: seq %llu mon %llu real %llu\n",
1506                      item->timestamp.seqnum, item->timestamp.monotonic_ns, item->timestamp.realtime_ns);
1507             //g_dbus_message_set_timestamp (message, item->timestamp.monotonic_ns / 1000);
1508             //g_dbus_message_set_serial (message, item->timestamp.seqnum);
1509             break;
1510           }
1511
1512         case KDBUS_ITEM_CREDS:
1513           {
1514             g_print ("creds: u%u eu %u su%u fsu%u g%u eg%u sg%u fsg%u\n",
1515                      item->creds.uid, item->creds.euid, item->creds.suid, item->creds.fsuid,
1516                      item->creds.gid, item->creds.egid, item->creds.sgid, item->creds.fsgid);
1517             break;
1518           }
1519
1520         case KDBUS_ITEM_PIDS:
1521         case KDBUS_ITEM_PID_COMM:
1522         case KDBUS_ITEM_TID_COMM:
1523         case KDBUS_ITEM_EXE:
1524         case KDBUS_ITEM_CMDLINE:
1525         case KDBUS_ITEM_CGROUP:
1526         case KDBUS_ITEM_AUDIT:
1527         case KDBUS_ITEM_CAPS:
1528         case KDBUS_ITEM_SECLABEL:
1529         case KDBUS_ITEM_CONN_DESCRIPTION:
1530         case KDBUS_ITEM_AUXGROUPS:
1531         case KDBUS_ITEM_OWNED_NAME:
1532         case KDBUS_ITEM_NAME:
1533           g_print ("unhandled %04x\n", (int) item->type);
1534           break;
1535
1536         default:
1537           g_error ("[KDBUS] DBUS_PAYLOAD: Unknown filed - %lld", item->type);
1538           break;
1539         }
1540     }
1541
1542   body = GLIB_PRIVATE_CALL(g_variant_from_vectors) (G_VARIANT_TYPE ("((yyyyuta{tv})v)"),
1543                                                     (GVariantVector *) body_vectors->data,
1544                                                     body_vectors->len, body_size, FALSE);
1545   g_assert (body);
1546
1547   for (i = 0; i < body_vectors->len; i++)
1548     g_bytes_unref (g_array_index (body_vectors, GVariantVector, i).gbytes);
1549
1550   g_array_free (body_vectors, TRUE);
1551
1552   parts[0] = g_variant_get_child_value (body, 0);
1553   parts[1] = g_variant_get_child_value (body, 1);
1554   g_variant_unref (body);
1555
1556   body = g_variant_get_variant (parts[1]);
1557   g_variant_unref (parts[1]);
1558   g_dbus_message_set_body (message, body);
1559   g_variant_unref (body);
1560
1561   g_variant_get (parts[0], "(yyyyuta{tv})", &endianness, &type, &flags, &version, NULL, &serial, &fields_iter);
1562   g_variant_unref (parts[0]);
1563
1564   while (g_variant_iter_loop (fields_iter, "{tv}", &key, &value))
1565     g_dbus_message_set_header (message, key, value);
1566
1567   g_dbus_message_set_flags (message, flags);
1568   g_dbus_message_set_serial (message, serial);
1569   g_dbus_message_set_message_type (message, type);
1570
1571   g_print ("Received:\n%s\n", g_dbus_message_print (message, 2));
1572
1573   return message;
1574 }
1575
1576
1577 /**
1578  * _g_kdbus_receive:
1579  *
1580  */
1581 static gssize
1582 _g_kdbus_receive (GKDBusWorker        *kdbus,
1583                   GCancellable  *cancellable,
1584                   GError       **error)
1585 {
1586   struct kdbus_cmd_recv recv;
1587   struct kdbus_msg *msg;
1588
1589   memset (&recv, 0, sizeof recv);
1590   recv.size = sizeof (recv);
1591
1592   if (g_cancellable_set_error_if_cancelled (cancellable, error))
1593     return -1;
1594
1595 again:
1596     if (ioctl(kdbus->fd, KDBUS_CMD_RECV, &recv) < 0)
1597       {
1598         if (errno == EINTR)
1599           goto again;
1600
1601         if (errno == EAGAIN)
1602           return 0;
1603
1604         g_set_error (error, G_IO_ERROR,
1605                      g_io_error_from_errno (errno),
1606                      _("Error while receiving message: %s"),
1607                      g_strerror (errno));
1608         return -1;
1609       }
1610
1611    msg = (struct kdbus_msg *)((guint8 *)kdbus->kdbus_buffer + recv.reply.offset);
1612
1613    if (msg->payload_type == KDBUS_PAYLOAD_DBUS)
1614      g_kdbus_decode_dbus_msg (kdbus, msg);
1615    else if (msg->payload_type == KDBUS_PAYLOAD_KERNEL)
1616      g_kdbus_decode_kernel_msg (kdbus, msg);
1617    else
1618      {
1619        g_set_error (error,
1620                     G_DBUS_ERROR,
1621                     G_DBUS_ERROR_FAILED,
1622                     _("Received unknown payload type"));
1623        return -1;
1624      }
1625
1626   ioctl(kdbus->fd, KDBUS_CMD_FREE, &recv.reply.offset);
1627
1628    return 0;
1629 }
1630
1631 static gboolean
1632 g_kdbus_msg_append_item (struct kdbus_msg *msg,
1633                          gsize             type,
1634                          gconstpointer     data,
1635                          gsize             size)
1636 {
1637   struct kdbus_item *item;
1638   gsize item_size;
1639
1640   item_size = size + G_STRUCT_OFFSET(struct kdbus_item, data);
1641
1642   if (msg->size + item_size > KDBUS_MSG_MAX_SIZE)
1643     return FALSE;
1644
1645   /* align */
1646   msg->size += (-msg->size) & 7;
1647   item = (struct kdbus_item *) ((guchar *) msg + msg->size);
1648   item->type = type;
1649   item->size = item_size;
1650   memcpy (item->data, data, size);
1651
1652   msg->size += item_size;
1653
1654   return TRUE;
1655 }
1656
1657 static gboolean
1658 g_kdbus_msg_append_payload_vec (struct kdbus_msg *msg,
1659                                 gconstpointer     data,
1660                                 gsize             size)
1661 {
1662   struct kdbus_vec vec = {
1663     .size = size,
1664     .address = (gsize) data
1665   };
1666
1667   return g_kdbus_msg_append_item (msg, KDBUS_ITEM_PAYLOAD_VEC, &vec, sizeof vec);
1668 }
1669
1670 static gboolean
1671 g_kdbus_msg_append_payload_memfd (struct kdbus_msg *msg,
1672                                   gint              fd,
1673                                   gsize             offset,
1674                                   gsize             size)
1675 {
1676   struct kdbus_memfd mfd = {
1677    .start = offset,
1678    .size = size,
1679    .fd = fd,
1680   };
1681
1682   return g_kdbus_msg_append_item (msg, KDBUS_ITEM_PAYLOAD_MEMFD, &mfd, sizeof mfd);
1683 }
1684
1685 #if 0
1686 #include "dbusheader.h"
1687
1688 void dump_header (gconstpointer data, gsize size) ;
1689 void
1690 dump_header (gconstpointer data,
1691              gsize size)
1692 {
1693   GDBusMessageHeaderFieldsIterator iter;
1694   GDBusMessageHeader header;
1695
1696   header = g_dbus_message_header_new (data, size);
1697   g_print ("header e/%c t/%u f/x%x v/%u s/%"G_GUINT64_FORMAT"\n",
1698            g_dbus_message_header_get_endian (header),
1699            g_dbus_message_header_get_type (header),
1700            g_dbus_message_header_get_flags (header),
1701            g_dbus_message_header_get_version (header),
1702            g_dbus_message_header_get_serial (header));
1703
1704   iter = g_dbus_message_header_iterate_fields (header);
1705
1706   while (g_dbus_message_header_fields_iterator_next (&iter))
1707     {
1708       const gchar *string;
1709       guint64 reply_to;
1710       guint64 key;
1711
1712       key = g_dbus_message_header_fields_iterator_get_key (iter);
1713
1714       switch (key)
1715         {
1716           case G_DBUS_MESSAGE_HEADER_FIELD_PATH:
1717             if (g_dbus_message_header_fields_iterator_get_value_as_object_path (iter, &string))
1718               g_print ("  path: %s\n", string);
1719             else
1720               g_print ("  path: <<invalid string>>\n");
1721             break;
1722
1723           case G_DBUS_MESSAGE_HEADER_FIELD_INTERFACE:
1724             if (g_dbus_message_header_fields_iterator_get_value_as_string (iter, &string))
1725               g_print ("  interface: %s\n", string);
1726             else
1727               g_print ("  interface: <<invalid string>>\n");
1728             break;
1729
1730           case G_DBUS_MESSAGE_HEADER_FIELD_MEMBER:
1731             if (g_dbus_message_header_fields_iterator_get_value_as_string (iter, &string))
1732               g_print ("  member: %s\n", string);
1733             else
1734               g_print ("  member: <<invalid string>>\n");
1735             break;
1736
1737           case G_DBUS_MESSAGE_HEADER_FIELD_ERROR_NAME:
1738             if (g_dbus_message_header_fields_iterator_get_value_as_string (iter, &string))
1739               g_print ("  error: %s\n", string);
1740             else
1741               g_print ("  error: <<invalid string>>\n");
1742             break;
1743
1744           case G_DBUS_MESSAGE_HEADER_FIELD_REPLY_SERIAL:
1745             if (g_dbus_message_header_fields_iterator_get_value_as_string (iter, &string))
1746               g_print ("  serial: %s\n", string);
1747             else
1748               g_print ("  serial: <<invalid string>>\n");
1749             break;
1750
1751           case G_DBUS_MESSAGE_HEADER_FIELD_DESTINATION:
1752             if (g_dbus_message_header_fields_iterator_get_value_as_string (iter, &string))
1753               g_print ("  destination: %s\n", string);
1754             else
1755               g_print ("  destination: <<invalid string>>\n");
1756             break;
1757
1758           case G_DBUS_MESSAGE_HEADER_FIELD_SENDER:
1759             if (g_dbus_message_header_fields_iterator_get_value_as_string (iter, &string))
1760               g_print ("  sender: %s\n", string);
1761             else
1762               g_print ("  sender: <<invalid string>>\n");
1763             break;
1764
1765           default:
1766             g_print ("unknown field code %"G_GUINT64_FORMAT"\n", key);
1767             g_assert_not_reached ();
1768         }
1769     }
1770
1771   g_print ("\n");
1772
1773 }
1774 #endif
1775
1776 /**
1777  * _g_kdbus_send:
1778  * Returns: size of data sent or -1 when error
1779  */
1780 static gboolean
1781 _g_kdbus_send (GKDBusWorker        *kdbus,
1782                GDBusMessage  *message,
1783                GError       **error)
1784 {
1785   struct kdbus_msg *msg = alloca (KDBUS_MSG_MAX_SIZE);
1786   GVariantVectors body_vectors;
1787   struct kdbus_cmd_send send;
1788
1789   g_return_val_if_fail (G_IS_KDBUS_WORKER (kdbus), -1);
1790
1791   /* fill in as we go... */
1792   memset (msg, 0, sizeof (struct kdbus_msg));
1793   msg->size = sizeof (struct kdbus_msg);
1794   msg->payload_type = KDBUS_PAYLOAD_DBUS;
1795   msg->src_id = kdbus->unique_id;
1796   msg->cookie = g_dbus_message_get_serial(message);
1797
1798   /* Message destination */
1799   {
1800     const gchar *dst_name;
1801
1802     dst_name = g_dbus_message_get_destination (message);
1803
1804     if (dst_name != NULL)
1805       {
1806         if (g_dbus_is_unique_name (dst_name))
1807           {
1808             if (dst_name[1] != '1' || dst_name[2] != '.')
1809               {
1810                 g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_NAME_HAS_NO_OWNER,
1811                              "Invalid unique D-Bus name '%s'", dst_name);
1812                 return FALSE;
1813               }
1814
1815             /* We already know that it passes the checks for unique
1816              * names, so no need to perform error checking on strtoull.
1817              */
1818             msg->dst_id = strtoull (dst_name + 3, NULL, 10);
1819             dst_name = NULL;
1820           }
1821         else
1822           {
1823             g_kdbus_msg_append_item (msg, KDBUS_ITEM_DST_NAME, dst_name, strlen (dst_name) + 1);
1824             msg->dst_id = KDBUS_DST_ID_NAME;
1825           }
1826       }
1827     else
1828       msg->dst_id = KDBUS_DST_ID_BROADCAST;
1829   }
1830
1831   /* File descriptors */
1832   {
1833     GUnixFDList *fd_list;
1834
1835     fd_list = g_dbus_message_get_unix_fd_list (message);
1836
1837     if (fd_list != NULL)
1838       {
1839         const gint *fds;
1840         gint n_fds;
1841
1842         fds = g_unix_fd_list_peek_fds (fd_list, &n_fds);
1843
1844         if (n_fds)
1845           g_kdbus_msg_append_item (msg, KDBUS_ITEM_FDS, fds, sizeof (gint) * n_fds);
1846       }
1847   }
1848
1849   /* Message body */
1850   {
1851     struct dbus_fixed_header fh;
1852     GHashTableIter header_iter;
1853     GVariantBuilder builder;
1854     gpointer key, value;
1855     GVariant *parts[3];
1856     GVariant *body;
1857
1858     fh.endian = (G_BYTE_ORDER == G_LITTLE_ENDIAN) ? 'l': 'B';
1859     fh.type = g_dbus_message_get_message_type (message);
1860     fh.flags = g_dbus_message_get_flags (message);
1861     fh.version = 2;
1862     fh.reserved = 0;
1863     fh.serial = g_dbus_message_get_serial (message);
1864     parts[0] = g_variant_new_from_data (DBUS_FIXED_HEADER_TYPE, &fh, sizeof fh, TRUE, NULL, NULL);
1865
1866     g_dbus_message_init_header_iter (message, &header_iter);
1867     g_variant_builder_init (&builder, DBUS_EXTENDED_HEADER_TYPE);
1868
1869     /* We set the sender field to the correct value for ourselves */
1870     g_variant_builder_add (&builder, "{tv}",
1871                            (guint64) G_DBUS_MESSAGE_HEADER_FIELD_SENDER,
1872                            g_variant_new_printf (":1.%"G_GUINT64_FORMAT, kdbus->unique_id));
1873
1874     while (g_hash_table_iter_next (&header_iter, &key, &value))
1875       {
1876         guint64 key_int = (gsize) key;
1877
1878         switch (key_int)
1879           {
1880             /* These are the normal header fields that get passed
1881              * straight through.
1882              */
1883             case G_DBUS_MESSAGE_HEADER_FIELD_PATH:
1884             case G_DBUS_MESSAGE_HEADER_FIELD_INTERFACE:
1885             case G_DBUS_MESSAGE_HEADER_FIELD_MEMBER:
1886             case G_DBUS_MESSAGE_HEADER_FIELD_ERROR_NAME:
1887             case G_DBUS_MESSAGE_HEADER_FIELD_REPLY_SERIAL:
1888             case G_DBUS_MESSAGE_HEADER_FIELD_DESTINATION:
1889               g_variant_builder_add (&builder, "{tv}", key_int, value);
1890               /* This is a little bit gross.
1891                *
1892                * We must send the header part of the message in a single
1893                * vector as per kdbus rules, but the GVariant serialiser
1894                * code will split any item >= 128 bytes into its own
1895                * vector to save the copy.
1896                *
1897                * No header field should be that big anyway... right?
1898                */
1899               g_assert_cmpint (g_variant_get_size (value), <, 128);
1900               continue;
1901
1902             /* We send this one unconditionally, but set it ourselves */
1903             case G_DBUS_MESSAGE_HEADER_FIELD_SENDER:
1904               continue;
1905
1906             /* We don't send these at all in GVariant format */
1907             case G_DBUS_MESSAGE_HEADER_FIELD_SIGNATURE:
1908             case G_DBUS_MESSAGE_HEADER_FIELD_NUM_UNIX_FDS:
1909               continue;
1910
1911             default:
1912               g_assert_not_reached ();
1913           }
1914       }
1915     parts[1] = g_variant_builder_end (&builder);
1916
1917     body = g_dbus_message_get_body (message);
1918     if (!body)
1919       body = g_variant_new ("()");
1920     parts[2] = g_variant_new_variant (body);
1921
1922     body = g_variant_ref_sink (g_variant_new_tuple (parts, G_N_ELEMENTS (parts)));
1923     GLIB_PRIVATE_CALL(g_variant_to_vectors) (body, &body_vectors);
1924
1925     /* Sanity check to make sure the header is really contiguous:
1926      *
1927      *  - we must have at least one vector in the output
1928      *  - the first vector must completely contain at least the header
1929      */
1930     g_assert_cmpint (body_vectors.vectors->len, >, 0);
1931     g_assert_cmpint (g_array_index (body_vectors.vectors, GVariantVector, 0).size, >=,
1932                      g_variant_get_size (parts[0]) + g_variant_get_size (parts[1]));
1933
1934     g_variant_unref (body);
1935   }
1936
1937   {
1938     guint i;
1939
1940     for (i = 0; i < body_vectors.vectors->len; i++)
1941       {
1942         GVariantVector vector = g_array_index (body_vectors.vectors, GVariantVector, i);
1943
1944         if (vector.gbytes)
1945           {
1946             gint fd;
1947
1948             fd = g_bytes_get_zero_copy_fd (vector.gbytes);
1949
1950             if (fd >= 0)
1951               {
1952                 const guchar *bytes_data;
1953                 gsize bytes_size;
1954
1955                 bytes_data = g_bytes_get_data (vector.gbytes, &bytes_size);
1956
1957                 if (bytes_data <= vector.data.pointer && vector.data.pointer + vector.size <= bytes_data + bytes_size)
1958                   {
1959                     if (!g_kdbus_msg_append_payload_memfd (msg, fd, vector.data.pointer - bytes_data, vector.size))
1960                       goto need_compact;
1961                   }
1962                 else
1963                   {
1964                     if (!g_kdbus_msg_append_payload_vec (msg, vector.data.pointer, vector.size))
1965                       goto need_compact;
1966                   }
1967               }
1968             else
1969               {
1970                 if (!g_kdbus_msg_append_payload_vec (msg, vector.data.pointer, vector.size))
1971                   goto need_compact;
1972               }
1973           }
1974         else
1975           if (!g_kdbus_msg_append_payload_vec (msg, body_vectors.extra_bytes->data + vector.data.offset, vector.size))
1976             goto need_compact;
1977       }
1978   }
1979
1980   /*
1981    * set message flags
1982    */
1983   msg->flags = ((g_dbus_message_get_flags (message) & G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED) ? 0 : KDBUS_MSG_EXPECT_REPLY) |
1984                 ((g_dbus_message_get_flags (message) & G_DBUS_MESSAGE_FLAGS_NO_AUTO_START) ? KDBUS_MSG_NO_AUTO_START : 0);
1985
1986   if ((msg->flags) & KDBUS_MSG_EXPECT_REPLY)
1987     msg->timeout_ns = 1000LU * g_get_monotonic_time() + KDBUS_TIMEOUT_NS;
1988   else
1989     msg->cookie_reply = g_dbus_message_get_reply_serial(message);
1990
1991
1992   /*
1993   if (dst_id == KDBUS_DST_ID_BROADCAST)
1994     {
1995       struct kdbus_bloom_filter *bloom_filter;
1996
1997       bloom_filter = g_kdbus_append_bloom (&item, kdbus->bloom_size);
1998       g_kdbus_setup_bloom (kdbus, message, bloom_filter);
1999     }
2000     */
2001
2002   send.size = sizeof (send);
2003   send.flags = 0;
2004   send.msg_address = (gsize) msg;
2005
2006   /*
2007    * send message
2008    */
2009 //again:
2010   if (ioctl(kdbus->fd, KDBUS_CMD_SEND, &send))
2011     {
2012 /*
2013       GString *error_name;
2014       error_name = g_string_new (NULL);
2015
2016       if(errno == EINTR)
2017         {
2018           g_string_free (error_name,TRUE);
2019           goto again;
2020         }
2021       else if (errno == ENXIO)
2022         {
2023           g_string_printf (error_name, "Name %s does not exist", g_dbus_message_get_destination(dbus_msg));
2024           g_kdbus_generate_local_error (worker,
2025                                         dbus_msg,
2026                                         g_variant_new ("(s)",error_name->str),
2027                                         G_DBUS_ERROR_SERVICE_UNKNOWN);
2028           g_string_free (error_name,TRUE);
2029           return 0;
2030         }
2031       else if ((errno == ESRCH) || (errno == EADDRNOTAVAIL))
2032         {
2033           if (kmsg->flags & KDBUS_MSG_FLAGS_NO_AUTO_START)
2034             {
2035               g_string_printf (error_name, "Name %s does not exist", g_dbus_message_get_destination(dbus_msg));
2036               g_kdbus_generate_local_error (worker,
2037                                             dbus_msg,
2038                                             g_variant_new ("(s)",error_name->str),
2039                                             G_DBUS_ERROR_SERVICE_UNKNOWN);
2040               g_string_free (error_name,TRUE);
2041               return 0;
2042             }
2043           else
2044             {
2045               g_string_printf (error_name, "The name %s was not provided by any .service files", g_dbus_message_get_destination(dbus_msg));
2046               g_kdbus_generate_local_error (worker,
2047                                             dbus_msg,
2048                                             g_variant_new ("(s)",error_name->str),
2049                                             G_DBUS_ERROR_SERVICE_UNKNOWN);
2050               g_string_free (error_name,TRUE);
2051               return 0;
2052             }
2053         }
2054
2055       g_print ("[KDBUS] ioctl error sending kdbus message:%d (%m)\n",errno);
2056       g_set_error (error, G_IO_ERROR, g_io_error_from_errno(errno), _("Error sending message - KDBUS_CMD_MSG_SEND error"));
2057 */
2058       perror("ioctl send");
2059       g_error ("IOCTL SEND: %d\n",errno);
2060       return FALSE;
2061     }
2062
2063   return TRUE;
2064
2065 need_compact:
2066   /* We end up here if:
2067    *  - too many kdbus_items
2068    *  - too large kdbus_msg size
2069    *  - too much vector data
2070    *
2071    * We need to compact the message before sending it.
2072    */
2073   g_assert_not_reached ();
2074 }
2075
2076 GKDBusWorker *
2077 g_kdbus_worker_new (const gchar  *address,
2078                     GError      **error)
2079 #if 0
2080                     GDBusCapabilityFlags                     capabilities,
2081                     gboolean                                 initially_frozen,
2082                     GDBusWorkerMessageReceivedCallback       message_received_callback,
2083                     GDBusWorkerMessageAboutToBeSentCallback  message_about_to_be_sent_callback,
2084                     GDBusWorkerDisconnectedCallback          disconnected_callback,
2085                     gpointer                                 user_data)
2086 #endif
2087 {
2088   GKDBusWorker *worker;
2089
2090   worker = g_object_new (G_TYPE_KDBUS_WORKER, NULL);
2091   if (!_g_kdbus_open (worker, address, error))
2092     {
2093       g_object_unref (worker);
2094       return NULL;
2095     }
2096
2097   return worker;
2098 }
2099
2100 void
2101 g_kdbus_worker_unfreeze (GKDBusWorker *worker)
2102 {
2103 }
2104
2105 gboolean
2106 g_kdbus_worker_send_message (GKDBusWorker  *worker,
2107                              GDBusMessage  *message,
2108                              GError       **error)
2109 {
2110   return _g_kdbus_send (worker, message, error);
2111 }
2112
2113 void
2114 g_kdbus_worker_stop (GKDBusWorker *worker)
2115 {
2116 }
2117
2118 void
2119 g_kdbus_worker_flush_sync (GKDBusWorker *worker)
2120 {
2121 }
2122
2123 void
2124 g_kdbus_worker_close (GKDBusWorker       *worker,
2125                       GCancellable       *cancellable,
2126                       GSimpleAsyncResult *result)
2127 {
2128 }