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