[kdbus] Import gio/gkdbus* files from previous patchset.
[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
26 #include "gkdbus.h"
27 #include "glib-unix.h"
28
29 #include <errno.h>
30 #include <string.h>
31 #include <sys/mman.h>
32 #include <stdio.h>
33
34 #ifdef HAVE_SYS_FILIO_H
35 # include <sys/filio.h>
36 #endif
37
38 #ifdef HAVE_SYS_UIO_H
39 #include <sys/uio.h>
40 #endif
41
42 #include <glib/gstdio.h>
43 #include <gio/gio.h>
44 #include <gio/gunixfdlist.h>
45
46 #include "glibintl.h"
47 #include "gunixfdmessage.h"
48 #include "gdbusprivate.h"
49 #include "kdbus.h"
50
51
52 /**
53  * SECTION:gkdbus
54  * @short_description: Low-level kdbus object
55  * @include: gio/gio.h
56  *
57  * A #GKdbus is a lowlevel adapter for kdbus IPC solution. It is meant
58  * to replace DBUS  as fundamental IPC solution for  Linux, however it
59  * is  still experimental  work in  progress.  You  may  find detailed
60  * description in kdbus.txt at https://github.com/gregkh/kdbus
61  *
62  */
63
64
65 /* Size of memory registered with kdbus for receiving messages */
66 #define KDBUS_POOL_SIZE (16 * 1024 * 1024)
67
68 #define ALIGN8(l) (((l) + 7) & ~7)
69 #define ALIGN8_PTR(p) ((void*) ALIGN8((gulong) p))
70
71 #define KDBUS_ITEM_HEADER_SIZE G_STRUCT_OFFSET(struct kdbus_item, data)
72 #define KDBUS_ITEM_SIZE(s) ALIGN8((s) + KDBUS_ITEM_HEADER_SIZE)
73
74 #define KDBUS_ITEM_NEXT(item) \
75         (typeof(item))(((guint8 *)item) + ALIGN8((item)->size))
76
77 #define KDBUS_ITEM_FOREACH(item, head, first)                           \
78         for (item = (head)->first;                                      \
79              ((guint8 *)(item) < (guint8 *)(head) + (head)->size) &&    \
80              ((guint8 *)(item) >= (guint8 *)(head));                    \
81              item = KDBUS_ITEM_NEXT(item))
82
83 #define g_alloca0(x) memset(g_alloca(x), '\0', (x))
84
85 /**
86  * use systemd-bus-drvierd (from systemd) which implements the all
87  * org.freedesktop.DBus methods on kdbus
88  */
89
90 #define SYSTEMD_BUS_DRIVERD
91
92
93 /* GBusNameOwnerReturnFlags */
94 typedef enum
95 {
96   G_BUS_REQUEST_NAME_REPLY_PRIMARY_OWNER = 1, /* Caller is now the primary owner of the name, replacing any previous owner */
97   G_BUS_REQUEST_NAME_REPLY_IN_QUEUE = 2,      /* The name already had an owner, the application will be placed in a queue */
98   G_BUS_REQUEST_NAME_REPLY_EXISTS = 3,        /* The name already has an owner */
99   G_BUS_REQUEST_NAME_REPLY_ALREADY_OWNER = 4  /* The application trying to request ownership of a name is already the owner of it */
100 } GBusNameOwnerReturnFlags;
101
102
103 /* GBusReleaseNameReturnFlags */
104 typedef enum
105 {
106   G_BUS_RELEASE_NAME_REPLY_RELEASED = 1,     /* The caller has released his claim on the given name */
107   G_BUS_RELEASE_NAME_REPLY_NON_EXISTENT = 2, /* The given name does not exist on this bus*/
108   G_BUS_RELEASE_NAME_REPLY_NOT_OWNER = 3     /* The caller not waiting in the queue to own this name*/
109 } GBusReleaseNameReturnFlags;
110
111
112 /* GBusStartServiceReturnFlags */
113 typedef enum
114 {
115   G_BUS_START_REPLY_SUCCESS = 1,             /* The service was successfully started */
116   G_BUS_START_REPLY_ALREADY_RUNNING = 2,     /* A connection already owns the given name */
117 } GBusStartServiceReturnFlags;
118
119
120 /* GBusCredentialsFlags */
121 typedef enum
122 {
123   G_BUS_CREDS_PID              = 1,
124   G_BUS_CREDS_UID              = 2,
125   G_BUS_CREDS_UNIQUE_NAME      = 3,
126   G_BUS_CREDS_SELINUX_CONTEXT  = 4
127 } GBusCredentialsFlags;
128
129
130 static void     g_kdbus_initable_iface_init (GInitableIface  *iface);
131 static gboolean g_kdbus_initable_init       (GInitable       *initable,
132                                              GCancellable    *cancellable,
133                                              GError         **error);
134
135 #define g_kdbus_get_type _g_kdbus_get_type
136 G_DEFINE_TYPE_WITH_CODE (GKdbus, g_kdbus, G_TYPE_OBJECT,
137                          G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
138                                                 g_kdbus_initable_iface_init));
139
140
141 struct _GKdbusPrivate
142 {
143   gint               fd;
144   gchar             *path;
145   gchar             *kdbus_buffer;
146   GSList            *kdbus_msg_items;
147   guint64            unique_id;
148   guint64            hello_flags;
149   guint64            attach_flags;
150   guint              closed : 1;
151   guint              inited : 1;
152   guint              timeout;
153   guint              timed_out : 1;
154   guchar             bus_id[16];
155   struct kdbus_msg  *kmsg;
156   GString           *msg_sender;
157   GString           *msg_destination;
158
159   gsize              bloom_size;
160   guint              bloom_n_hash;
161
162   gint              *fds;
163   gint               num_fds;
164
165   gint               memfd;
166 };
167
168
169 typedef struct {
170   GSource        source;
171   GPollFD        pollfd;
172   GKdbus        *kdbus;
173   GIOCondition   condition;
174   GCancellable  *cancellable;
175   GPollFD        cancel_pollfd;
176   gint64         timeout_time;
177 } GKdbusSource;
178
179
180 typedef gboolean (*GKdbusSourceFunc) (GKdbus *kdbus,
181                                       GIOCondition condition,
182                                       gpointer user_data);
183
184
185 /* Hash keys for bloom filters*/
186 const guint8 hash_keys[8][16] =
187 {
188   {0xb9,0x66,0x0b,0xf0,0x46,0x70,0x47,0xc1,0x88,0x75,0xc4,0x9c,0x54,0xb9,0xbd,0x15},
189   {0xaa,0xa1,0x54,0xa2,0xe0,0x71,0x4b,0x39,0xbf,0xe1,0xdd,0x2e,0x9f,0xc5,0x4a,0x3b},
190   {0x63,0xfd,0xae,0xbe,0xcd,0x82,0x48,0x12,0xa1,0x6e,0x41,0x26,0xcb,0xfa,0xa0,0xc8},
191   {0x23,0xbe,0x45,0x29,0x32,0xd2,0x46,0x2d,0x82,0x03,0x52,0x28,0xfe,0x37,0x17,0xf5},
192   {0x56,0x3b,0xbf,0xee,0x5a,0x4f,0x43,0x39,0xaf,0xaa,0x94,0x08,0xdf,0xf0,0xfc,0x10},
193   {0x31,0x80,0xc8,0x73,0xc7,0xea,0x46,0xd3,0xaa,0x25,0x75,0x0f,0x9e,0x4c,0x09,0x29},
194   {0x7d,0xf7,0x18,0x4b,0x7b,0xa4,0x44,0xd5,0x85,0x3c,0x06,0xe0,0x65,0x53,0x96,0x6d},
195   {0xf2,0x77,0xe9,0x6f,0x93,0xb5,0x4e,0x71,0x9a,0x0c,0x34,0x88,0x39,0x25,0xbf,0x35}
196 };
197
198
199 /**
200  * _g_kdbus_get_last_msg_sender
201  *
202  */
203 gchar *
204 _g_kdbus_get_last_msg_sender (GKdbus  *kdbus)
205 {
206   return kdbus->priv->msg_sender->str;
207 }
208
209
210 /**
211  * _g_kdbus_get_last_msg_destination
212  *
213  */
214 gchar *
215 _g_kdbus_get_last_msg_destination (GKdbus  *kdbus)
216 {
217   return kdbus->priv->msg_destination->str;
218 }
219
220
221 /**
222  * _g_kdbus_get_last_msg_items:
223  *
224  */
225 GSList *
226 _g_kdbus_get_last_msg_items (GKdbus  *kdbus)
227 {
228   return kdbus->priv->kdbus_msg_items;
229 }
230
231
232 /**
233  * g_kdbus_add_msg_part:
234  *
235  */
236 static void
237 g_kdbus_add_msg_part (GKdbus  *kdbus,
238                       gchar   *data,
239                       gsize    size)
240 {
241   msg_part* part = g_new (msg_part, 1);
242   part->data = data;
243   part->size = size;
244   kdbus->priv->kdbus_msg_items = g_slist_append(kdbus->priv->kdbus_msg_items, part);
245 }
246
247
248 /**
249  * _g_kdbus_hexdump_all_items:
250  *
251  */
252 gchar *
253 _g_kdbus_hexdump_all_items (GSList  *kdbus_msg_items)
254 {
255
256   GString *ret;
257   gint item = 1;
258   ret = g_string_new (NULL);
259
260   while (kdbus_msg_items != NULL)
261     {
262       g_string_append_printf (ret, "\n  Item %d\n", item);
263       g_string_append (ret, _g_dbus_hexdump (((msg_part*)kdbus_msg_items->data)->data, ((msg_part*)kdbus_msg_items->data)->size, 2));
264
265       kdbus_msg_items = g_slist_next(kdbus_msg_items);
266       item++;
267     }
268
269   return g_string_free (ret, FALSE);
270 }
271
272
273 /**
274  * g_kdbus_finalize:
275  *
276  */
277 static void
278 g_kdbus_finalize (GObject  *object)
279 {
280   GKdbus *kdbus = G_KDBUS (object);
281
282   if (kdbus->priv->kdbus_buffer != NULL)
283     munmap (kdbus->priv->kdbus_buffer, KDBUS_POOL_SIZE);
284
285   kdbus->priv->kdbus_buffer = NULL;
286
287   if (kdbus->priv->fd != -1 && !kdbus->priv->closed)
288     _g_kdbus_close (kdbus, NULL);
289
290   g_string_free (kdbus->priv->msg_sender, TRUE);
291   g_string_free (kdbus->priv->msg_destination, TRUE);
292
293   if (G_OBJECT_CLASS (g_kdbus_parent_class)->finalize)
294     (*G_OBJECT_CLASS (g_kdbus_parent_class)->finalize) (object);
295 }
296
297
298 /**
299  * g_kdbus_class_init:
300  *
301  */
302 static void
303 g_kdbus_class_init (GKdbusClass  *klass)
304 {
305   GObjectClass *gobject_class G_GNUC_UNUSED = G_OBJECT_CLASS (klass);
306
307   g_type_class_add_private (klass, sizeof (GKdbusPrivate));
308   gobject_class->finalize = g_kdbus_finalize;
309 }
310
311
312 /**
313  * g_kdbus_initable_iface_init:
314  *
315  */
316 static void
317 g_kdbus_initable_iface_init (GInitableIface  *iface)
318 {
319   iface->init = g_kdbus_initable_init;
320 }
321
322
323 /**
324  * g_kdbus_init:
325  *
326  */
327 static void
328 g_kdbus_init (GKdbus  *kdbus)
329 {
330   kdbus->priv = G_TYPE_INSTANCE_GET_PRIVATE (kdbus, G_TYPE_KDBUS, GKdbusPrivate);
331
332   kdbus->priv->fd = -1;
333   kdbus->priv->unique_id = -1;
334   kdbus->priv->memfd = -1;
335
336   kdbus->priv->path = NULL;
337   kdbus->priv->kdbus_buffer = NULL;
338   kdbus->priv->kdbus_msg_items = NULL;
339
340   kdbus->priv->msg_sender = g_string_new (NULL);
341   kdbus->priv->msg_destination = g_string_new (NULL);
342
343   kdbus->priv->fds = NULL;
344   kdbus->priv->num_fds = 0;
345
346   kdbus->priv->hello_flags = KDBUS_HELLO_ACCEPT_FD;
347   kdbus->priv->attach_flags = KDBUS_ATTACH_NAMES;
348 }
349
350
351 /**
352  * g_kdbus_initable_init:
353  *
354  */
355 static gboolean
356 g_kdbus_initable_init (GInitable     *initable,
357                        GCancellable  *cancellable,
358                        GError       **error)
359 {
360   GKdbus *kdbus;
361
362   g_return_val_if_fail (G_IS_KDBUS (initable), FALSE);
363
364   kdbus = G_KDBUS (initable);
365
366   if (cancellable != NULL)
367     {
368       g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
369                            _("Cancellable initialization not supported"));
370       return FALSE;
371     }
372
373   kdbus->priv->inited = TRUE;
374
375   return TRUE;
376 }
377
378
379 /**
380  * kdbus_source_prepare:
381  *
382  */
383 static gboolean
384 kdbus_source_prepare (GSource  *source,
385                       gint     *timeout)
386 {
387   GKdbusSource *kdbus_source = (GKdbusSource *)source;
388
389   if (g_cancellable_is_cancelled (kdbus_source->cancellable))
390     return TRUE;
391
392   if (kdbus_source->timeout_time)
393     {
394       gint64 now;
395
396       now = g_source_get_time (source);
397
398       *timeout = (kdbus_source->timeout_time - now + 999) / 1000;
399       if (*timeout < 0)
400         {
401           kdbus_source->kdbus->priv->timed_out = TRUE;
402           *timeout = 0;
403           return TRUE;
404         }
405     }
406   else
407     *timeout = -1;
408
409   if ((kdbus_source->condition & kdbus_source->pollfd.revents) != 0)
410     return TRUE;
411
412   return FALSE;
413 }
414
415
416 /**
417  * kdbus_source_check:
418  *
419  */
420 static gboolean
421 kdbus_source_check (GSource  *source)
422 {
423   gint timeout;
424
425   return kdbus_source_prepare (source, &timeout);
426 }
427
428
429 /**
430  * kdbus_source_dispatch
431  *
432  */
433 static gboolean
434 kdbus_source_dispatch  (GSource      *source,
435                         GSourceFunc   callback,
436                         gpointer      user_data)
437 {
438   GKdbusSourceFunc func = (GKdbusSourceFunc)callback;
439   GKdbusSource *kdbus_source = (GKdbusSource *)source;
440   GKdbus *kdbus = kdbus_source->kdbus;
441   gboolean ret;
442
443   if (kdbus_source->kdbus->priv->timed_out)
444     kdbus_source->pollfd.revents |= kdbus_source->condition & (G_IO_IN | G_IO_OUT);
445
446   ret = (*func) (kdbus,
447                  kdbus_source->pollfd.revents & kdbus_source->condition,
448                  user_data);
449
450   if (kdbus->priv->timeout)
451     kdbus_source->timeout_time = g_get_monotonic_time ()
452                                + kdbus->priv->timeout * 1000000;
453
454   else
455     kdbus_source->timeout_time = 0;
456
457   return ret;
458 }
459
460
461 /**
462  * kdbus_source_finalize
463  *
464  */
465 static void
466 kdbus_source_finalize (GSource  *source)
467 {
468   GKdbusSource *kdbus_source = (GKdbusSource *)source;
469   GKdbus *kdbus;
470
471   kdbus = kdbus_source->kdbus;
472
473   g_object_unref (kdbus);
474
475   if (kdbus_source->cancellable)
476     {
477       g_cancellable_release_fd (kdbus_source->cancellable);
478       g_object_unref (kdbus_source->cancellable);
479     }
480 }
481
482
483 /**
484  * kdbus_source_closure_callback:
485  *
486  */
487 static gboolean
488 kdbus_source_closure_callback (GKdbus        *kdbus,
489                                GIOCondition   condition,
490                                gpointer       data)
491 {
492   GClosure *closure = data;
493   GValue params[2] = { G_VALUE_INIT, G_VALUE_INIT };
494   GValue result_value = G_VALUE_INIT;
495   gboolean result;
496
497   g_value_init (&result_value, G_TYPE_BOOLEAN);
498
499   g_value_init (&params[0], G_TYPE_KDBUS);
500   g_value_set_object (&params[0], kdbus);
501   g_value_init (&params[1], G_TYPE_IO_CONDITION);
502   g_value_set_flags (&params[1], condition);
503
504   g_closure_invoke (closure, &result_value, 2, params, NULL);
505
506   result = g_value_get_boolean (&result_value);
507   g_value_unset (&result_value);
508   g_value_unset (&params[0]);
509   g_value_unset (&params[1]);
510
511   return result;
512 }
513
514
515 static GSourceFuncs kdbus_source_funcs =
516 {
517   kdbus_source_prepare,
518   kdbus_source_check,
519   kdbus_source_dispatch,
520   kdbus_source_finalize,
521   (GSourceFunc)kdbus_source_closure_callback,
522 };
523
524
525 /**
526  * kdbus_source_new:
527  *
528  */
529 static GSource *
530 kdbus_source_new (GKdbus        *kdbus,
531                   GIOCondition   condition,
532                   GCancellable  *cancellable)
533 {
534   GSource *source;
535   GKdbusSource *kdbus_source;
536
537   source = g_source_new (&kdbus_source_funcs, sizeof (GKdbusSource));
538   g_source_set_name (source, "GKdbus");
539   kdbus_source = (GKdbusSource *)source;
540
541   kdbus_source->kdbus = g_object_ref (kdbus);
542   kdbus_source->condition = condition;
543
544   if (g_cancellable_make_pollfd (cancellable,
545                                  &kdbus_source->cancel_pollfd))
546     {
547       kdbus_source->cancellable = g_object_ref (cancellable);
548       g_source_add_poll (source, &kdbus_source->cancel_pollfd);
549     }
550
551   kdbus_source->pollfd.fd = kdbus->priv->fd;
552   kdbus_source->pollfd.events = condition;
553   kdbus_source->pollfd.revents = 0;
554   g_source_add_poll (source, &kdbus_source->pollfd);
555
556   if (kdbus->priv->timeout)
557     kdbus_source->timeout_time = g_get_monotonic_time ()
558                                + kdbus->priv->timeout * 1000000;
559   else
560     kdbus_source->timeout_time = 0;
561
562   return source;
563 }
564
565
566 /**
567  * _g_kdbus_create_source:
568  *
569  */
570 GSource *
571 _g_kdbus_create_source (GKdbus        *kdbus,
572                         GIOCondition   condition,
573                         GCancellable  *cancellable)
574 {
575   g_return_val_if_fail (G_IS_KDBUS (kdbus) && (cancellable == NULL || G_IS_CANCELLABLE (cancellable)), NULL);
576
577   return kdbus_source_new (kdbus, condition, cancellable);
578 }
579
580
581 /**
582  * _g_kdbus_open:
583  * @kdbus: a #GKdbus.
584  * @address: path to kdbus bus file.
585  * @error: #GError for error reporting, or %NULL to ignore.
586  *
587  * Opens file descriptor to kdbus bus control.
588  * It is located in /dev/kdbus/uid-name/bus.
589  *
590  * Returns: TRUE on success.
591  */
592 gboolean
593 _g_kdbus_open (GKdbus       *kdbus,
594                const gchar  *address,
595                GError      **error)
596 {
597   g_return_val_if_fail (G_IS_KDBUS (kdbus), FALSE);
598
599   kdbus->priv->fd = open(address, O_RDWR|O_NOCTTY|O_CLOEXEC);
600
601   if (kdbus->priv->fd<0)
602     {
603       g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, _("Can't open kdbus endpoint"));
604       return FALSE;
605     }
606
607   kdbus->priv->closed = FALSE;
608
609   return TRUE;
610 }
611
612
613 /**
614  * _g_kdbus_close:
615  * @kdbus: a #GKdbus.
616  * @error: #GError for error reporting, or %NULL to ignore.
617  *
618  * Closes file descriptor to kdbus bus.
619  * Disconnect a connection. If the connection's message list is empty,
620  * the calls succeeds, closes file descriptor to kdbus bus. Otherwise
621  * FALSE is returned without any further side-effects.
622  *
623  * Returns: TRUE on success.
624  *
625  */
626 gboolean
627 _g_kdbus_close (GKdbus  *kdbus,
628                 GError **error)
629 {
630   gint res;
631
632   if (kdbus->priv->closed)
633     return TRUE; /* Multiple close not an error */
634
635   g_return_val_if_fail (G_IS_KDBUS (kdbus), FALSE);
636
637   if (ioctl(kdbus->priv->fd, KDBUS_CMD_BYEBYE) < 0)
638     return FALSE;
639
640   while (1)
641     {
642       res = close (kdbus->priv->fd);
643
644       if (res == -1)
645         {
646           if (errno == EINTR)
647             continue;
648
649           g_set_error (error, G_IO_ERROR,
650                        g_io_error_from_errno (errno),
651                        _("Error closing kdbus fd: %s"),
652                        g_strerror (errno));
653           return FALSE;
654         }
655       break;
656     }
657
658   kdbus->priv->closed = TRUE;
659   kdbus->priv->fd = -1;
660
661   return TRUE;
662 }
663
664
665 /**
666  * _g_kdbus_is_closed:
667  * @kdbus: a #GKdbus.
668  *
669  * checks whether a kdbus is closed.
670  *
671  */
672 gboolean
673 _g_kdbus_is_closed (GKdbus  *kdbus)
674 {
675   g_return_val_if_fail (G_IS_KDBUS (kdbus), FALSE);
676
677   return kdbus->priv->closed;
678 }
679
680
681 /**
682  * g_kdbus_generate_local_reply:
683  *
684  */
685 static GDBusMessage *
686 g_kdbus_generate_local_reply (GDBusMessage       *message,
687                               GDBusMessageType    message_type,
688                               GDBusMessageFlags   message_flags,
689                               guint32             message_reply_serial,
690                               GVariant           *message_body,
691                               const gchar        *error_name)
692 {
693   GDBusMessage *reply;
694
695   reply = g_dbus_message_new ();
696
697   g_dbus_message_set_sender (reply, "org.freedesktop.DBus");
698   g_dbus_message_set_message_type (reply, message_type);
699   g_dbus_message_set_flags (reply, message_flags);
700   g_dbus_message_set_reply_serial (reply, message_reply_serial);
701
702   g_dbus_message_set_body (reply, message_body);
703
704   if (message != NULL)
705     g_dbus_message_set_destination (reply, g_dbus_message_get_sender (message));
706
707   if (message_type == G_DBUS_MESSAGE_TYPE_ERROR)
708     g_dbus_message_set_error_name (reply, error_name);
709
710   if (G_UNLIKELY (_g_dbus_debug_message ()))
711     {
712       gchar *s;
713       _g_dbus_debug_print_lock ();
714       g_print ("========================================================================\n"
715                "GDBus-debug:Message:\n"
716                "  <<<< RECEIVED LOCAL D-Bus message (N/A bytes)\n");
717
718       s = g_dbus_message_print (reply, 2);
719       g_print ("%s", s);
720       g_free (s);
721       _g_dbus_debug_print_unlock ();
722     }
723
724   return reply;
725 }
726
727
728 /**
729  * g_kdbus_generate_local_error:
730  *
731  */
732 static void
733 g_kdbus_generate_local_error (GDBusWorker   *worker,
734                               GDBusMessage  *dbus_msg,
735                               GVariant      *message_body,
736                               gint           error_code)
737 {
738   GDBusMessage *reply;
739   GError *error = NULL;
740   gchar *dbus_error_name;
741
742   error = g_error_new_literal (G_DBUS_ERROR, error_code, "");
743   dbus_error_name = g_dbus_error_encode_gerror (error);
744
745   reply = g_kdbus_generate_local_reply (dbus_msg,
746                                         G_DBUS_MESSAGE_TYPE_ERROR,
747                                         G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED,
748                                         g_dbus_message_get_serial (dbus_msg),
749                                         message_body,
750                                         dbus_error_name);
751   _g_dbus_worker_queue_or_deliver_received_message (worker, reply);
752 }
753
754
755 /**
756  * g_kdbus_check_signature:
757  * Returns: TRUE on success.
758  */
759 static gboolean
760 g_kdbus_check_signature (GDBusWorker         *worker,
761                          GDBusMessage        *dbus_msg,
762                          const gchar         *method_name,
763                          GVariant            *body,
764                          const GVariantType  *type)
765 {
766
767   if (!g_variant_is_of_type (body, type))
768     {
769       GString *error_name = g_string_new (NULL);
770       g_string_printf (error_name, "Call to %s has wrong args (expected %s)", method_name, g_variant_type_peek_string (type));
771       g_kdbus_generate_local_error (worker,
772                                     dbus_msg,
773                                     g_variant_new ("(s)",error_name->str),
774                                     G_DBUS_ERROR_INVALID_ARGS);
775       g_string_free (error_name,TRUE);
776       return FALSE;
777     }
778   else
779     return TRUE;
780 }
781
782
783 /**
784  * g_kdbus_check_name:
785  * Returns: TRUE on success.
786  */
787 static gboolean
788 g_kdbus_check_name (GDBusWorker   *worker,
789                     GDBusMessage  *dbus_msg,
790                     const gchar   *name)
791 {
792   if (!g_dbus_is_name (name))
793     {
794       GString *error_name = g_string_new (NULL);
795       g_string_printf (error_name, "Name \"%s\" is not valid", name);
796       g_kdbus_generate_local_error (worker,
797                                     dbus_msg,
798                                     g_variant_new ("(s)",error_name->str),
799                                     G_DBUS_ERROR_INVALID_ARGS);
800       g_string_free (error_name,TRUE);
801       return FALSE;
802     }
803   else
804     return TRUE;
805 }
806
807
808 /**
809  * g_kdbus_translate_request_name_flags:
810  *
811  */
812 static void
813 g_kdbus_translate_request_name_flags (GBusNameOwnerFlags   flags,
814                                       guint64             *kdbus_flags)
815 {
816   guint64 new_flags = 0;
817
818   if (flags & G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT)
819     new_flags |= KDBUS_NAME_ALLOW_REPLACEMENT;
820
821   if (flags & G_BUS_NAME_OWNER_FLAGS_REPLACE)
822     new_flags |= KDBUS_NAME_REPLACE_EXISTING;
823
824   *kdbus_flags = new_flags;
825 }
826
827
828 /**
829  * g_kdbus_NameHasOwner:
830  * Returns: TRUE on success.
831  */
832 static gboolean
833 g_kdbus_NameHasOwner (GKdbus *kdbus, const gchar *name)
834 {
835   struct kdbus_cmd_conn_info *cmd;
836   gssize size;
837   gint ret;
838
839   if (g_dbus_is_unique_name(name))
840     {
841        size = G_STRUCT_OFFSET (struct kdbus_cmd_conn_info, name);
842        cmd = g_alloca0 (size);
843        cmd->id = g_ascii_strtoull (name+3,NULL,10);
844     }
845   else
846     {
847        size = G_STRUCT_OFFSET (struct kdbus_cmd_conn_info, name) + strlen(name) + 1;
848        cmd = g_alloca0 (size);
849        strcpy(cmd->name, name);
850     }
851
852   cmd->flags = KDBUS_ATTACH_NAMES;
853   cmd->size = size;
854
855   ret = ioctl(kdbus->priv->fd, KDBUS_CMD_CONN_INFO, cmd);
856
857   if (ret<0)
858     return FALSE;
859   else
860     return TRUE;
861 }
862
863
864 /**
865  * g_kdbus_take_fd:
866  *
867  */
868 static void
869 g_kdbus_take_fd (GKdbus  *kdbus)
870 {
871   struct kdbus_cmd_hello *hello;
872   struct kdbus_item *item;
873   gchar *conn_name;
874   size_t size, conn_name_size;
875
876   conn_name = "gdbus-kdbus";
877   conn_name_size = strlen (conn_name);
878
879   size = ALIGN8(G_STRUCT_OFFSET(struct kdbus_cmd_hello, items)) +
880          ALIGN8(G_STRUCT_OFFSET(struct kdbus_item, str) + conn_name_size + 1);
881
882   hello = g_alloca0(size);
883   hello->conn_flags = kdbus->priv->hello_flags;
884   hello->attach_flags =  kdbus->priv->attach_flags;
885   hello->size = size;
886   hello->pool_size = KDBUS_POOL_SIZE;
887
888   /* connection's human-readable name (only for debugging purposes)*/
889   item = hello->items;
890   item->size = G_STRUCT_OFFSET(struct kdbus_item, str) + conn_name_size + 1;
891   item->type = KDBUS_ITEM_CONN_NAME;
892   memcpy(item->str, conn_name, conn_name_size+1);
893   item = KDBUS_ITEM_NEXT(item);
894
895   if (ioctl(kdbus->priv->fd, KDBUS_CMD_HELLO, hello))
896     g_error("[KDBUS] fd=%d failed to send hello: %m, %d", kdbus->priv->fd,errno);
897
898   kdbus->priv->kdbus_buffer = mmap(NULL, KDBUS_POOL_SIZE, PROT_READ, MAP_SHARED, kdbus->priv->fd, 0);
899
900   if (kdbus->priv->kdbus_buffer == MAP_FAILED)
901     g_error("[KDBUS] error when mmap: %m, %d", errno);
902
903   if (hello->bus_flags > 0xFFFFFFFFULL || hello->conn_flags > 0xFFFFFFFFULL)
904     g_error("[KDBUS] incompatible flags");
905
906   /* read bloom filters parameters */
907   kdbus->priv->bloom_size = (gsize) hello->bloom.size;
908   kdbus->priv->bloom_n_hash = (guint) hello->bloom.n_hash;
909
910   /* validate bloom filters parameters here? */
911
912   kdbus->priv->unique_id = hello->id;
913   memcpy (kdbus->priv->bus_id, hello->id128, 16);
914 }
915
916
917 /**
918  * g_kdbus_Hello_reply:
919  * Returns: TRUE on success.
920  */
921 static gboolean
922 g_kdbus_Hello_reply (GDBusWorker   *worker,
923                      GKdbus        *kdbus,
924                      GDBusMessage  *dbus_msg)
925 {
926   GString *unique_name;
927   GDBusMessage *reply;
928
929   unique_name = g_string_new(NULL);
930   g_string_printf (unique_name,":1.%" G_GUINT64_FORMAT, kdbus->priv->unique_id);
931
932   reply = g_kdbus_generate_local_reply (dbus_msg,
933                                         G_DBUS_MESSAGE_TYPE_METHOD_RETURN,
934                                         G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED,
935                                         g_dbus_message_get_serial (dbus_msg),
936                                         g_variant_new ("(s)",unique_name->str),
937                                         NULL);
938   _g_dbus_worker_queue_or_deliver_received_message (worker, reply);
939
940   g_string_free (unique_name,TRUE);
941   return TRUE;
942 }
943
944
945 /**
946  * g_kdbus_RequestName_handler:
947  * Returns: TRUE on success.
948  */
949 static gboolean
950 g_kdbus_RequestName_handler (GDBusWorker   *worker,
951                              GKdbus        *kdbus,
952                              GDBusMessage  *dbus_msg)
953 {
954   GDBusMessage *reply;
955   GBusNameOwnerFlags flags;
956   struct kdbus_cmd_name *kdbus_name;
957   const gchar *name;
958   guint64 kdbus_flags;
959   guint64 size;
960   gint ret;
961   gint status = G_BUS_REQUEST_NAME_REPLY_PRIMARY_OWNER;
962
963   /* read and validate message */
964   GVariant *body = g_dbus_message_get_body (dbus_msg);
965
966   if (!g_kdbus_check_signature (worker, dbus_msg, "RequestName", body, G_VARIANT_TYPE("(su)")))
967     return TRUE;
968
969   g_variant_get (body, "(&su)", &name, &flags);
970
971   if (!g_kdbus_check_name (worker, dbus_msg, name))
972     return TRUE;
973
974   if (*name == ':')
975     {
976       GString *error_name = g_string_new (NULL);
977       g_string_printf (error_name, "Cannot acquire a service starting with ':' such as \"%s\"", name);
978       g_kdbus_generate_local_error (worker,
979                                     dbus_msg,
980                                     g_variant_new ("(s)",error_name->str),
981                                     G_DBUS_ERROR_INVALID_ARGS);
982       g_string_free (error_name,TRUE);
983       return TRUE;
984     }
985
986   g_kdbus_translate_request_name_flags (flags, &kdbus_flags);
987
988   /* calculate size */
989   size = sizeof(*kdbus_name) + strlen(name) + 1;
990   kdbus_name = g_alloca(size);
991
992   /* set message header */
993   memset(kdbus_name, 0, size);
994   strcpy(kdbus_name->name, name);
995   kdbus_name->size = size;
996   kdbus_name->flags = kdbus_flags;
997
998   /* send message */
999   ret = ioctl(kdbus->priv->fd, KDBUS_CMD_NAME_ACQUIRE, kdbus_name);
1000   if (ret < 0)
1001     {
1002       if (errno == EEXIST)
1003         status = G_BUS_REQUEST_NAME_REPLY_EXISTS;
1004       else if (errno == EALREADY)
1005         status = G_BUS_REQUEST_NAME_REPLY_ALREADY_OWNER;
1006       else
1007         return FALSE;
1008     }
1009
1010   if (kdbus_name->flags & KDBUS_NAME_IN_QUEUE)
1011     status = G_BUS_REQUEST_NAME_REPLY_IN_QUEUE;
1012
1013   /* generate local reply */
1014   reply = g_kdbus_generate_local_reply (dbus_msg,
1015                                         G_DBUS_MESSAGE_TYPE_METHOD_RETURN,
1016                                         G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED,
1017                                         g_dbus_message_get_serial (dbus_msg),
1018                                         g_variant_new ("(u)",status),
1019                                         NULL);
1020   _g_dbus_worker_queue_or_deliver_received_message (worker, reply);
1021
1022   return TRUE;
1023 }
1024
1025
1026 /**
1027  * g_kdbus_ReleaseName_handler:
1028  * Returns: TRUE on success.
1029  */
1030 static gboolean
1031 g_kdbus_ReleaseName_handler (GDBusWorker   *worker,
1032                              GKdbus        *kdbus,
1033                              GDBusMessage  *dbus_msg)
1034 {
1035   GDBusMessage *reply;
1036   struct kdbus_cmd_name *kdbus_name;
1037   const gchar *name;
1038   guint64 size;
1039   gint ret;
1040   gint status = G_BUS_RELEASE_NAME_REPLY_RELEASED;
1041
1042   /* read and validate message */
1043   GVariant *body = g_dbus_message_get_body (dbus_msg);
1044
1045   if (!g_kdbus_check_signature (worker, dbus_msg, "ReleaseName", body, G_VARIANT_TYPE("(s)")))
1046     return TRUE;
1047
1048   g_variant_get (body, "(&s)", &name);
1049
1050   if (!g_kdbus_check_name (worker, dbus_msg, name))
1051     return TRUE;
1052
1053   if (*name == ':')
1054     {
1055       GString *error_name = g_string_new (NULL);
1056       g_string_printf (error_name, "Cannot release a service starting with ':' such as \"%s\"", name);
1057       g_kdbus_generate_local_error (worker,
1058                                     dbus_msg,
1059                                     g_variant_new ("(s)",error_name->str),
1060                                     G_DBUS_ERROR_INVALID_ARGS);
1061       g_string_free (error_name,TRUE);
1062       return TRUE;
1063     }
1064
1065   /* calculate size */
1066   size = sizeof(*kdbus_name) + strlen(name) + 1;
1067   kdbus_name = g_alloca(size);
1068
1069   /* set message header */
1070   memset(kdbus_name, 0, size);
1071   strcpy(kdbus_name->name, name);
1072   kdbus_name->size = size;
1073
1074   /* send message */
1075   ret = ioctl(kdbus->priv->fd, KDBUS_CMD_NAME_RELEASE, kdbus_name);
1076   if (ret < 0)
1077     {
1078       if (errno == ESRCH)
1079         status = G_BUS_RELEASE_NAME_REPLY_NON_EXISTENT;
1080       else if (errno == EADDRINUSE)
1081         status = G_BUS_RELEASE_NAME_REPLY_NOT_OWNER;
1082       else
1083         return FALSE;
1084     }
1085
1086   /* generate local reply */
1087   reply = g_kdbus_generate_local_reply (dbus_msg,
1088                                         G_DBUS_MESSAGE_TYPE_METHOD_RETURN,
1089                                         G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED,
1090                                         g_dbus_message_get_serial (dbus_msg),
1091                                         g_variant_new ("(u)",status),
1092                                         NULL);
1093   _g_dbus_worker_queue_or_deliver_received_message (worker, reply);
1094
1095   return TRUE;
1096 }
1097
1098
1099 /**
1100  * g_kdbus_ListNames_handler:
1101  * Returns: TRUE on success.
1102  */
1103 static gboolean
1104 g_kdbus_ListNames_handler (GDBusWorker   *worker,
1105                            GKdbus        *kdbus,
1106                            GDBusMessage  *dbus_msg,
1107                            guint64        flags)
1108 {
1109   GDBusMessage *reply;
1110   GVariantBuilder *builder;
1111   struct kdbus_cmd_name_list cmd = {};
1112   struct kdbus_name_list *name_list;
1113   struct kdbus_cmd_name *name;
1114   guint64 prev_id = 0;
1115   gint ret;
1116
1117   cmd.flags = flags;
1118
1119   ret = ioctl(kdbus->priv->fd, KDBUS_CMD_NAME_LIST, &cmd);
1120   if (ret < 0)
1121     return FALSE;
1122
1123   /* get name list */
1124   name_list = (struct kdbus_name_list *) ((guint8 *) kdbus->priv->kdbus_buffer + cmd.offset);
1125
1126   builder = g_variant_builder_new (G_VARIANT_TYPE ("as"));
1127   KDBUS_ITEM_FOREACH(name, name_list, names)
1128     {
1129       if ((flags & KDBUS_NAME_LIST_UNIQUE) && name->owner_id != prev_id)
1130         {
1131           GString *unique_name = g_string_new (NULL);
1132
1133           g_string_printf (unique_name, ":1.%llu", name->owner_id);
1134
1135           g_variant_builder_add (builder, "s", unique_name->str);
1136           g_string_free (unique_name,TRUE);
1137           prev_id = name->owner_id;
1138         }
1139
1140         if (g_dbus_is_name (name->name))
1141           g_variant_builder_add (builder, "s", name->name);
1142     }
1143
1144   /* generate local reply */
1145   reply = g_kdbus_generate_local_reply (dbus_msg,
1146                                         G_DBUS_MESSAGE_TYPE_METHOD_RETURN,
1147                                         G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED,
1148                                         g_dbus_message_get_serial (dbus_msg),
1149                                         g_variant_new ("(as)", builder),
1150                                         NULL);
1151   _g_dbus_worker_queue_or_deliver_received_message (worker, reply);
1152
1153   g_variant_builder_unref (builder);
1154   ret = ioctl(kdbus->priv->fd, KDBUS_CMD_FREE, &cmd.offset);
1155   if (ret < 0)
1156     return FALSE;
1157
1158   return TRUE;
1159 }
1160
1161
1162 /**
1163  * g_kdbus_ListQueuedOwners_handler:
1164  * Returns: TRUE on success.
1165  */
1166 static gboolean
1167 g_kdbus_ListQueuedOwners_handler (GDBusWorker   *worker,
1168                                   GKdbus        *kdbus,
1169                                   GDBusMessage  *dbus_msg)
1170 {
1171   GDBusMessage *reply;
1172   GString *unique_name;
1173   GVariantBuilder *builder;
1174   struct kdbus_cmd_name_list cmd = {};
1175   struct kdbus_name_list *name_list;
1176   struct kdbus_cmd_name *name;
1177   const gchar *service;
1178   gint ret;
1179
1180   /* read and validate message */
1181   GVariant *body = g_dbus_message_get_body (dbus_msg);
1182
1183   if (!g_kdbus_check_signature (worker, dbus_msg, "ListQueuedOwners", body, G_VARIANT_TYPE("(s)")))
1184     return TRUE;
1185
1186   g_variant_get (body, "(&s)", &service);
1187
1188   if (!g_kdbus_check_name (worker, dbus_msg, service))
1189     return TRUE;
1190
1191   if (!g_kdbus_NameHasOwner (kdbus, service))
1192     {
1193       GString *error_name = g_string_new (NULL);
1194       g_string_printf (error_name, "Could not get owners of name \'%s\': no such name", service);
1195       g_kdbus_generate_local_error (worker,
1196                                     dbus_msg,
1197                                     g_variant_new ("(s)",error_name->str),
1198                                     G_DBUS_ERROR_NAME_HAS_NO_OWNER);
1199       g_string_free (error_name,TRUE);
1200       return TRUE;
1201     }
1202
1203   /* get queued name list */
1204   cmd.flags = KDBUS_NAME_LIST_QUEUED;
1205
1206   ret = ioctl(kdbus->priv->fd, KDBUS_CMD_NAME_LIST, &cmd);
1207   if (ret < 0)
1208     return FALSE;
1209
1210   name_list = (struct kdbus_name_list *) ((guint8 *) kdbus->priv->kdbus_buffer + cmd.offset);
1211
1212   unique_name = g_string_new (NULL);
1213   builder = g_variant_builder_new (G_VARIANT_TYPE ("as"));
1214   KDBUS_ITEM_FOREACH(name, name_list, names)
1215     {
1216       if (name->size <= sizeof(*name))
1217         continue;
1218
1219       if (strcmp(name->name, service))
1220         continue;
1221
1222       g_string_printf (unique_name, ":1.%llu", name->owner_id);
1223       g_variant_builder_add (builder, "s", unique_name);
1224
1225     }
1226
1227   /* generate reply */
1228   reply = g_kdbus_generate_local_reply (dbus_msg,
1229                                         G_DBUS_MESSAGE_TYPE_METHOD_RETURN,
1230                                         G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED,
1231                                         g_dbus_message_get_serial (dbus_msg),
1232                                         g_variant_new ("(as)", builder),
1233                                         NULL);
1234   _g_dbus_worker_queue_or_deliver_received_message (worker, reply);
1235
1236   g_variant_builder_unref (builder);
1237   g_string_free (unique_name,TRUE);
1238
1239   ret = ioctl(kdbus->priv->fd, KDBUS_CMD_FREE, &cmd.offset);
1240   if (ret < 0)
1241     return FALSE;
1242
1243   return TRUE;
1244 }
1245
1246
1247 /**
1248  * g_kdbus_GetOwner_handler:
1249  * Returns: TRUE on success.
1250  */
1251 static gboolean
1252 g_kdbus_GetOwner_handler (GDBusWorker   *worker,
1253                           GKdbus        *kdbus,
1254                           GDBusMessage  *dbus_msg,
1255                           guint64        flag)
1256 {
1257   GVariant *result = NULL;
1258   GDBusMessage *reply;
1259   struct kdbus_cmd_conn_info *cmd;
1260   struct kdbus_conn_info *conn_info;
1261   struct kdbus_item *item;
1262   const gchar *name;
1263   gssize size;
1264   gint ret;
1265
1266   /* read and validate message */
1267   GVariant *body = g_dbus_message_get_body (dbus_msg);
1268
1269   if (!g_kdbus_check_signature (worker, dbus_msg, "GetOwner", body, G_VARIANT_TYPE("(s)")))
1270     return TRUE;
1271
1272   g_variant_get (body, "(&s)", &name);
1273
1274   if (!g_kdbus_check_name (worker, dbus_msg, name))
1275     return TRUE;
1276
1277   /* setup kmsg for ioctl */
1278   if (g_dbus_is_unique_name(name))
1279     {
1280        size = G_STRUCT_OFFSET (struct kdbus_cmd_conn_info, name);
1281        cmd = g_alloca0 (size);
1282        cmd->id = g_ascii_strtoull (name+3,NULL,10);
1283     }
1284   else
1285     {
1286        size = G_STRUCT_OFFSET (struct kdbus_cmd_conn_info, name) + strlen(name) + 1;
1287        cmd = g_alloca0 (size);
1288        strcpy(cmd->name, name);
1289     }
1290
1291   cmd->flags = KDBUS_ATTACH_NAMES;
1292   cmd->size = size;
1293
1294   /* get info about connection */
1295   ret = ioctl(kdbus->priv->fd, KDBUS_CMD_CONN_INFO, cmd);
1296   if (ret < 0)
1297     {
1298       GString *error_name = g_string_new (NULL);
1299       g_string_printf (error_name, "Could not get owners of name \'%s\': no such name", name);
1300       g_kdbus_generate_local_error (worker,
1301                                     dbus_msg,
1302                                     g_variant_new ("(s)",error_name->str),
1303                                     G_DBUS_ERROR_NAME_HAS_NO_OWNER);
1304       g_string_free (error_name, TRUE);
1305       return TRUE;
1306     }
1307
1308   conn_info = (struct kdbus_conn_info *) ((guint8 *) kdbus->priv->kdbus_buffer + cmd->offset);
1309
1310   if (conn_info->flags & KDBUS_HELLO_ACTIVATOR)
1311     return FALSE;
1312
1313   if (flag == G_BUS_CREDS_UNIQUE_NAME)
1314     {
1315        GString *unique_name = g_string_new (NULL);
1316
1317        g_string_printf (unique_name, ":1.%llu", (unsigned long long) conn_info->id);
1318
1319        result = g_variant_new ("(s)", unique_name);
1320        g_string_free (unique_name,TRUE);
1321        goto send_reply;
1322     }
1323
1324   /* read creds info */
1325   KDBUS_ITEM_FOREACH(item, conn_info, items)
1326    {
1327
1328       switch (item->type)
1329         {
1330
1331           case KDBUS_ITEM_CREDS:
1332
1333             if (flag == G_BUS_CREDS_PID)
1334               {
1335                 guint pid = item->creds.pid;
1336                 result = g_variant_new ("(u)", pid);
1337                 goto send_reply;
1338               }
1339
1340             if (flag == G_BUS_CREDS_UID)
1341               {
1342                 guint uid = item->creds.uid;
1343                 result = g_variant_new ("(u)", uid);
1344                 goto send_reply;
1345               }
1346
1347           case KDBUS_ITEM_SECLABEL:
1348             if (flag == G_BUS_CREDS_SELINUX_CONTEXT)
1349               {
1350                 gint counter;
1351                 gchar *label;
1352                 GVariantBuilder *builder = g_variant_builder_new (G_VARIANT_TYPE ("ay"));
1353
1354                 label = g_strdup (item->str);
1355                 if (!label)
1356                   goto exit;
1357
1358                 for (counter = 0 ; counter < strlen (label) ; counter++)
1359                   {
1360                     g_variant_builder_add (builder, "y", label);
1361                     label++;
1362                   }
1363
1364                 result = g_variant_new ("(ay)", builder);
1365                 g_variant_builder_unref (builder);
1366                 g_free (label);
1367                 goto send_reply;
1368
1369               }
1370             break;
1371
1372           case KDBUS_ITEM_PID_COMM:
1373           case KDBUS_ITEM_TID_COMM:
1374           case KDBUS_ITEM_EXE:
1375           case KDBUS_ITEM_CMDLINE:
1376           case KDBUS_ITEM_CGROUP:
1377           case KDBUS_ITEM_CAPS:
1378           case KDBUS_ITEM_NAME:
1379           case KDBUS_ITEM_AUDIT:
1380             break;
1381
1382         }
1383    }
1384
1385 send_reply:
1386   if (result == NULL)
1387     goto exit;
1388
1389   /* generate local reply */
1390   reply = g_kdbus_generate_local_reply (dbus_msg,
1391                                         G_DBUS_MESSAGE_TYPE_METHOD_RETURN,
1392                                         G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED,
1393                                         g_dbus_message_get_serial (dbus_msg),
1394                                         result,
1395                                         NULL);
1396   _g_dbus_worker_queue_or_deliver_received_message (worker, reply);
1397
1398 exit:
1399   ioctl(kdbus->priv->fd, KDBUS_CMD_FREE, &cmd->offset);
1400   return TRUE;
1401
1402 }
1403
1404
1405 /**
1406  * g_kdbus_NameHasOwner_handler:
1407  * Returns: TRUE on success.
1408  */
1409 static gboolean
1410 g_kdbus_NameHasOwner_handler (GDBusWorker   *worker,
1411                               GKdbus        *kdbus,
1412                               GDBusMessage  *dbus_msg)
1413 {
1414   GDBusMessage *reply;
1415   GVariant *result = NULL;
1416   const gchar *name;
1417
1418   /* read and validate message */
1419   GVariant *body = g_dbus_message_get_body (dbus_msg);
1420
1421   if (!g_kdbus_check_signature (worker, dbus_msg, "NameHasOwner", body, G_VARIANT_TYPE("(s)")))
1422     return TRUE;
1423
1424   g_variant_get (body, "(&s)", &name);
1425
1426   if (!g_kdbus_check_name (worker, dbus_msg, name))
1427     return TRUE;
1428
1429   /* check whether name has owner */
1430   if (!g_kdbus_NameHasOwner (kdbus, name))
1431     result = g_variant_new ("(b)", FALSE);
1432   else
1433     result = g_variant_new ("(b)", TRUE);
1434
1435   /* generate local reply */
1436   reply = g_kdbus_generate_local_reply (dbus_msg,
1437                                         G_DBUS_MESSAGE_TYPE_METHOD_RETURN,
1438                                         G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED,
1439                                         g_dbus_message_get_serial (dbus_msg),
1440                                         result,
1441                                         NULL);
1442   _g_dbus_worker_queue_or_deliver_received_message (worker, reply);
1443   return TRUE;
1444 }
1445
1446
1447 /**
1448  * g_kdbus_GetId_handler:
1449  * Returns: TRUE on success.
1450  */
1451 static gboolean
1452 g_kdbus_GetId_handler (GDBusWorker   *worker,
1453                        GKdbus        *kdbus,
1454                        GDBusMessage  *dbus_msg)
1455 {
1456   GDBusMessage *reply;
1457   GString *result = g_string_new (NULL);
1458   gint i;
1459
1460   for (i=0; i<16; i++)
1461     g_string_append_printf (result, "%02x", kdbus->priv->bus_id[i]);
1462
1463   /* generate local reply */
1464   reply = g_kdbus_generate_local_reply (dbus_msg,
1465                                         G_DBUS_MESSAGE_TYPE_METHOD_RETURN,
1466                                         G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED,
1467                                         g_dbus_message_get_serial (dbus_msg),
1468                                         g_variant_new ("(s)", result->str),
1469                                         NULL);
1470   _g_dbus_worker_queue_or_deliver_received_message (worker, reply);
1471
1472   g_string_free (result,TRUE);
1473   return TRUE;
1474 }
1475
1476
1477 /**
1478  * g_kdbus_StartServiceByName_handler:
1479  * Returns: TRUE on success.
1480  *
1481  */
1482 static gboolean
1483 g_kdbus_StartServiceByName_handler (GDBusWorker   *worker,
1484                                     GKdbus        *kdbus,
1485                                     GDBusMessage  *dbus_msg)
1486 {
1487   GDBusMessage *reply;
1488   GVariant *body;
1489   const gchar *name;
1490   guint64 flags;
1491
1492   body = g_dbus_message_get_body (dbus_msg);
1493
1494   if (!g_kdbus_check_signature (worker, dbus_msg, "StartServiceByName", body, G_VARIANT_TYPE("(su)")))
1495     return TRUE;
1496
1497   g_variant_get (body, "(&su)", &name, &flags);
1498
1499   if (!g_kdbus_check_name (worker, dbus_msg, name))
1500     return TRUE;
1501
1502   if (g_kdbus_NameHasOwner (kdbus, name))
1503     {
1504       reply = g_kdbus_generate_local_reply (dbus_msg,
1505                                             G_DBUS_MESSAGE_TYPE_METHOD_RETURN,
1506                                             G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED,
1507                                             g_dbus_message_get_serial (dbus_msg),
1508                                             g_variant_new ("(u)", G_BUS_START_REPLY_ALREADY_RUNNING),
1509                                             NULL);
1510       _g_dbus_worker_queue_or_deliver_received_message (worker, reply);
1511       return TRUE;
1512     }
1513
1514   /* TODO */
1515   g_error ("[KDBUS] StartServiceByName method is not implemented yet");
1516
1517   return TRUE;
1518 }
1519
1520
1521 /**
1522  * g_kdbus_AddMatch_handler:
1523  * Returns: TRUE on success.
1524  *
1525  */
1526 static gboolean
1527 g_kdbus_AddMatch_handler (GDBusWorker   *worker,
1528                           GKdbus        *kdbus,
1529                           GDBusMessage  *dbus_msg)
1530 {
1531   GVariant *body;
1532   const gchar *rule;
1533
1534   body = g_dbus_message_get_body (dbus_msg);
1535
1536   if (!g_kdbus_check_signature (worker, dbus_msg, "AddMatch", body, G_VARIANT_TYPE("(s)")))
1537     return TRUE;
1538
1539   g_variant_get (body, "(&s)", &rule);
1540
1541   /* TODO */
1542   g_error ("[KDBUS] AddMatch method is not implemented yet");
1543
1544   return TRUE;
1545 }
1546
1547
1548 /**
1549  * g_kdbus_RemoveMatch_handler:
1550  * Returns: TRUE on success.
1551  *
1552  */
1553 static gboolean
1554 g_kdbus_RemoveMatch_handler (GDBusWorker   *worker,
1555                              GKdbus        *kdbus,
1556                              GDBusMessage  *dbus_msg)
1557 {
1558   GVariant *body;
1559   const gchar *rule;
1560
1561   body = g_dbus_message_get_body (dbus_msg);
1562
1563   if (!g_kdbus_check_signature (worker, dbus_msg, "RemoveMatch", body, G_VARIANT_TYPE("(s)")))
1564     return TRUE;
1565
1566   g_variant_get (body, "(&s)", &rule);
1567
1568   /* TODO */
1569   g_error ("[KDBUS] RemoveMatch method is not implemented yet");
1570
1571   return TRUE;
1572 }
1573
1574
1575 /**
1576  * g_kdbus_UnsupportedMethod_handler:
1577  * Returns: TRUE on success.
1578  */
1579 static gboolean
1580 g_kdbus_UnsupportedMethod_handler (GDBusWorker   *worker,
1581                                    GKdbus        *kdbus,
1582                                    GDBusMessage  *dbus_msg,
1583                                    const gchar   *method_name)
1584 {
1585   GString *error_name = g_string_new (NULL);
1586   g_string_printf (error_name, "Method \"%s\" is not supported", method_name);
1587   g_kdbus_generate_local_error (worker,
1588                                 dbus_msg,
1589                                 g_variant_new ("(s)",error_name->str),
1590                                 G_DBUS_ERROR_UNKNOWN_METHOD);
1591   g_string_free (error_name,TRUE);
1592   return TRUE;
1593 }
1594
1595
1596 /**
1597  * g_kdbus_bus_driver:
1598  *
1599  */
1600 static gboolean
1601 g_kdbus_bus_driver (GDBusWorker   *worker,
1602                     GKdbus        *kdbus,
1603                     GDBusMessage  *dbus_msg)
1604 {
1605   gboolean ret = FALSE;
1606
1607   /* Hello */
1608   if (g_strcmp0(g_dbus_message_get_member(dbus_msg), "Hello") == 0)
1609     {
1610       g_kdbus_take_fd (kdbus);
1611       ret = g_kdbus_Hello_reply (worker, kdbus, dbus_msg);
1612     }
1613
1614   /* RequestName and ReleaseName */
1615   else if (g_strcmp0(g_dbus_message_get_member(dbus_msg), "RequestName") == 0)
1616     ret = g_kdbus_RequestName_handler (worker, kdbus, dbus_msg);
1617   else if (g_strcmp0(g_dbus_message_get_member(dbus_msg), "ReleaseName") == 0)
1618     ret = g_kdbus_ReleaseName_handler (worker, kdbus, dbus_msg);
1619
1620   /* All List* Methods */
1621   else if (g_strcmp0(g_dbus_message_get_member(dbus_msg), "ListNames") == 0)
1622     ret = g_kdbus_ListNames_handler (worker, kdbus, dbus_msg, KDBUS_NAME_LIST_UNIQUE | KDBUS_NAME_LIST_NAMES);
1623   else if (g_strcmp0(g_dbus_message_get_member(dbus_msg), "ListActivatableNames") == 0)
1624     ret = g_kdbus_ListNames_handler (worker, kdbus, dbus_msg, KDBUS_NAME_LIST_ACTIVATORS);
1625   else if (g_strcmp0(g_dbus_message_get_member(dbus_msg), "ListQueuedOwners") == 0)
1626     ret = g_kdbus_ListQueuedOwners_handler (worker, kdbus, dbus_msg);
1627
1628   /* All Get* Methods */
1629   else if (g_strcmp0(g_dbus_message_get_member(dbus_msg), "GetNameOwner") == 0)
1630     ret = g_kdbus_GetOwner_handler (worker, kdbus, dbus_msg, G_BUS_CREDS_UNIQUE_NAME);
1631   else if (g_strcmp0(g_dbus_message_get_member(dbus_msg), "GetConnectionUnixProcessID") == 0)
1632     ret = g_kdbus_GetOwner_handler (worker, kdbus, dbus_msg, G_BUS_CREDS_PID);
1633   else if (g_strcmp0(g_dbus_message_get_member(dbus_msg), "GetConnectionUnixUser") == 0)
1634     ret = g_kdbus_GetOwner_handler (worker, kdbus, dbus_msg, G_BUS_CREDS_UID);
1635   else if (g_strcmp0(g_dbus_message_get_member(dbus_msg), "GetConnectionSELinuxSecurityContext") == 0)
1636     ret = g_kdbus_GetOwner_handler (worker, kdbus, dbus_msg, G_BUS_CREDS_SELINUX_CONTEXT);
1637   else if (g_strcmp0(g_dbus_message_get_member(dbus_msg), "GetId") == 0)
1638     ret = g_kdbus_GetId_handler (worker, kdbus, dbus_msg);
1639
1640   /* NameHasOwner nad StartServiceByName methods */
1641   else if (g_strcmp0(g_dbus_message_get_member(dbus_msg), "NameHasOwner") == 0)
1642     ret = g_kdbus_NameHasOwner_handler (worker, kdbus, dbus_msg);
1643   else if (g_strcmp0(g_dbus_message_get_member(dbus_msg), "StartServiceByName") == 0)
1644     ret = g_kdbus_StartServiceByName_handler (worker, kdbus, dbus_msg);
1645
1646   /* AddMatch and RemoveMatch */
1647   else if (g_strcmp0(g_dbus_message_get_member(dbus_msg), "AddMatch") == 0)
1648     ret = g_kdbus_AddMatch_handler (worker, kdbus, dbus_msg);
1649   else if (g_strcmp0(g_dbus_message_get_member(dbus_msg), "RemoveMatch") == 0)
1650     ret = g_kdbus_RemoveMatch_handler (worker, kdbus, dbus_msg);
1651
1652   /* Unsupported Methods */
1653   else if (g_strcmp0(g_dbus_message_get_member(dbus_msg), "ReloadConfig") == 0)
1654     ret = g_kdbus_UnsupportedMethod_handler (worker, kdbus, dbus_msg, "ReloadConfig");
1655   else if (g_strcmp0(g_dbus_message_get_member(dbus_msg), "UpdateActivationEnvironment") == 0)
1656     ret = g_kdbus_UnsupportedMethod_handler (worker, kdbus, dbus_msg, "UpdateActivationEnvironment");
1657
1658   else
1659     {
1660       GString *error_name;
1661
1662       error_name = g_string_new (NULL);
1663       g_string_printf (error_name, "org.freedesktop.DBus does not understand message %s", g_dbus_message_get_member(dbus_msg));
1664
1665       g_kdbus_generate_local_error (worker,
1666                                     dbus_msg,
1667                                     g_variant_new ("(s)",error_name->str),
1668                                     G_DBUS_ERROR_UNKNOWN_METHOD);
1669       g_string_free (error_name,TRUE);
1670     }
1671
1672   return ret;
1673 }
1674
1675
1676 /**
1677  * g_kdbus_alloc_memfd:
1678  *
1679  */
1680 static gboolean
1681 g_kdbus_alloc_memfd (GKdbus  *kdbus)
1682 {
1683   struct kdbus_cmd_memfd_make *memfd;
1684   struct kdbus_item *item;
1685   gssize size;
1686   gchar *name = "gdbus-memfd";
1687
1688   size = ALIGN8(G_STRUCT_OFFSET(struct kdbus_cmd_memfd_make, items)) +
1689          ALIGN8(G_STRUCT_OFFSET(struct kdbus_item, str)) +
1690          strlen(name) + 1;
1691
1692   memfd = g_alloca0 (size);
1693   memfd->size = size;
1694
1695   item = memfd->items;
1696   item->size = ALIGN8(offsetof(struct kdbus_item, str)) + strlen(name) + 1;
1697   item->type = KDBUS_ITEM_MEMFD_NAME;
1698   memcpy(item->str, name, strlen(name) + 1);
1699
1700   if (ioctl(kdbus->priv->fd, KDBUS_CMD_MEMFD_NEW, memfd) < 0)
1701     return FALSE;
1702
1703   kdbus->priv->memfd = memfd->fd;
1704
1705   return TRUE;
1706 }
1707
1708
1709 /**
1710  * _g_kdbus_release_msg:
1711  * Release memory occupied by kdbus_msg.
1712  * Use after DBUS message is extracted.
1713  */
1714 void
1715 _g_kdbus_release_kmsg (GKdbus  *kdbus)
1716 {
1717   struct kdbus_item *item = NULL;
1718   GSList *iterator = NULL;
1719   guint64 offset;
1720
1721   offset = (guint8 *)kdbus->priv->kmsg - (guint8 *)kdbus->priv->kdbus_buffer;
1722   ioctl(kdbus->priv->fd, KDBUS_CMD_FREE, &offset);
1723
1724   for (iterator = kdbus->priv->kdbus_msg_items; iterator; iterator = iterator->next)
1725     g_free ((msg_part*)iterator->data);
1726
1727   g_slist_free (kdbus->priv->kdbus_msg_items);
1728   kdbus->priv->kdbus_msg_items = NULL;
1729
1730   KDBUS_ITEM_FOREACH (item, kdbus->priv->kmsg, items)
1731     {
1732       if (item->type == KDBUS_ITEM_PAYLOAD_MEMFD)
1733         close(item->memfd.fd);
1734       else if (item->type == KDBUS_ITEM_FDS)
1735         {
1736           gint i;
1737           gint num_fds = (item->size - G_STRUCT_OFFSET(struct kdbus_item, fds)) / sizeof(int);
1738
1739           for (i = 0; i < num_fds; i++)
1740             close(item->fds[i]);
1741         }
1742     }
1743 }
1744
1745
1746 /**
1747  * g_kdbus_append_payload_vec:
1748  *
1749  */
1750 static void
1751 g_kdbus_append_payload_vec (struct kdbus_item **item,
1752                             const void         *data_ptr,
1753                             gssize              size)
1754 {
1755   *item = ALIGN8_PTR(*item);
1756   (*item)->size = G_STRUCT_OFFSET (struct kdbus_item, vec) + sizeof(struct kdbus_vec);
1757   (*item)->type = KDBUS_ITEM_PAYLOAD_VEC;
1758   (*item)->vec.address = (guint64)((guintptr)data_ptr);
1759   (*item)->vec.size = size;
1760   *item = KDBUS_ITEM_NEXT(*item);
1761 }
1762
1763
1764 /**
1765  * g_kdbus_append_payload_memfd:
1766  *
1767  */
1768 static void
1769 g_kdbus_append_payload_memfd (struct kdbus_item **item,
1770                               int                 fd,
1771                               gssize              size)
1772 {
1773   *item = ALIGN8_PTR(*item);
1774   (*item)->size = G_STRUCT_OFFSET (struct kdbus_item, memfd) + sizeof(struct kdbus_memfd);
1775   (*item)->type = KDBUS_ITEM_PAYLOAD_MEMFD;
1776   (*item)->memfd.fd = fd;
1777   (*item)->memfd.size = size;
1778   *item = KDBUS_ITEM_NEXT(*item);
1779 }
1780
1781
1782 /**
1783  * g_kdbus_append_payload_destiantion:
1784  *
1785  */
1786 static void
1787 g_kdbus_append_destination (struct kdbus_item **item,
1788                             const gchar        *destination,
1789                             gsize               size)
1790 {
1791   *item = ALIGN8_PTR(*item);
1792   (*item)->size = G_STRUCT_OFFSET (struct kdbus_item, str) + size + 1;
1793   (*item)->type = KDBUS_ITEM_DST_NAME;
1794   memcpy ((*item)->str, destination, size+1);
1795   *item = KDBUS_ITEM_NEXT(*item);
1796 }
1797
1798
1799 /**
1800  * g_kdbus_append_payload_bloom:
1801  *
1802  */
1803 static struct kdbus_bloom_filter *
1804 g_kdbus_append_bloom (struct kdbus_item **item,
1805                       gsize               size)
1806 {
1807   struct kdbus_item *bloom_item;
1808
1809   bloom_item = ALIGN8_PTR(*item);
1810   bloom_item->size = G_STRUCT_OFFSET (struct kdbus_item, bloom_filter) +
1811                      G_STRUCT_OFFSET (struct kdbus_bloom_filter, data) +
1812                      size;
1813
1814   bloom_item->type = KDBUS_ITEM_BLOOM_FILTER;
1815
1816   *item = KDBUS_ITEM_NEXT(bloom_item);
1817   return &bloom_item->bloom_filter;
1818 }
1819
1820
1821 /**
1822  * g_kdbus_append_fds:
1823  *
1824  */
1825 static void
1826 g_kdbus_append_fds (struct kdbus_item **item,
1827                     GUnixFDList        *fd_list)
1828 {
1829   *item = ALIGN8_PTR(*item);
1830   (*item)->size = G_STRUCT_OFFSET (struct kdbus_item, fds) + sizeof(int) * g_unix_fd_list_get_length(fd_list);
1831   (*item)->type = KDBUS_ITEM_FDS;
1832   memcpy ((*item)->fds, g_unix_fd_list_peek_fds(fd_list, NULL), sizeof(int) * g_unix_fd_list_get_length(fd_list));
1833
1834   *item = KDBUS_ITEM_NEXT(*item);
1835 }
1836
1837
1838 /**
1839  * _g_kdbus_attach_fds_to_msg:
1840  *
1841  */
1842 void
1843 _g_kdbus_attach_fds_to_msg (GKdbus       *kdbus,
1844                             GUnixFDList **fd_list)
1845 {
1846   if ((kdbus->priv->fds != NULL) && (kdbus->priv->num_fds > 0))
1847     {
1848       gint n;
1849
1850       if (*fd_list == NULL)
1851         *fd_list = g_unix_fd_list_new();
1852
1853       for (n = 0; n < kdbus->priv->num_fds; n++)
1854         {
1855           g_unix_fd_list_append (*fd_list, kdbus->priv->fds[n], NULL);
1856           (void) g_close (kdbus->priv->fds[n], NULL);
1857         }
1858
1859       g_free (kdbus->priv->fds);
1860       kdbus->priv->fds = NULL;
1861       kdbus->priv->num_fds = 0;
1862     }
1863 }
1864
1865
1866 /**
1867  * g_kdbus_bloom_add_data:
1868  * Based on bus-bloom.c from systemd
1869  * http://cgit.freedesktop.org/systemd/systemd/tree/src/libsystemd/sd-bus/bus-bloom.c
1870  */
1871 static void
1872 g_kdbus_bloom_add_data (GKdbus      *kdbus,
1873                         guint64      bloom_data [],
1874                         const void  *data,
1875                         gsize        n)
1876 {
1877   guint8 hash[8];
1878   guint64 bit_num;
1879   guint bytes_num = 0;
1880   guint cnt_1, cnt_2;
1881
1882   guint c = 0;
1883   guint64 p = 0;
1884
1885   bit_num = kdbus->priv->bloom_size * 8;
1886
1887   if (bit_num > 1)
1888     bytes_num = ((__builtin_clzll(bit_num) ^ 63U) + 7) / 8;
1889
1890   for (cnt_1 = 0; cnt_1 < (kdbus->priv->bloom_n_hash); cnt_1++)
1891     {
1892       for (cnt_2 = 0; cnt_2 < bytes_num; cnt_2++)
1893         {
1894           if (c <= 0)
1895             {
1896               g_siphash24(hash, data, n, hash_keys[cnt_1++]);
1897               c += 8;
1898             }
1899
1900           p = (p << 8ULL) | (guint64) hash[8 - c];
1901           c--;
1902         }
1903
1904       p &= bit_num - 1;
1905       bloom_data[p >> 6] |= 1ULL << (p & 63);
1906     }
1907 }
1908
1909
1910 /**
1911  * g_kdbus_bloom_add_pair:
1912  *
1913  */
1914 static void
1915 g_kdbus_bloom_add_pair (GKdbus       *kdbus,
1916                         guint64       bloom_data [],
1917                         const gchar  *parameter,
1918                         const gchar  *value)
1919 {
1920   GString *data = g_string_new (NULL);
1921
1922   g_string_printf (data,"%s:%s",parameter,value);
1923   g_kdbus_bloom_add_data(kdbus, bloom_data, data->str, data->len);
1924   g_string_free (data, TRUE);
1925 }
1926
1927
1928 /**
1929  * g_kdbus_bloom_add_prefixes:
1930  *
1931  */
1932 static void
1933 g_kdbus_bloom_add_prefixes (GKdbus       *kdbus,
1934                             guint64       bloom_data [],
1935                             const gchar  *parameter,
1936                             const gchar  *value,
1937                             gchar         separator)
1938 {
1939   GString *data = g_string_new (NULL);
1940
1941   g_string_printf (data,"%s:%s",parameter,value);
1942
1943   for (;;)
1944     {
1945       gchar *last_sep;
1946       last_sep = strrchr(data->str, separator);
1947       if (!last_sep || last_sep == data->str)
1948         break;
1949
1950       *last_sep = 0;
1951       g_kdbus_bloom_add_data(kdbus, bloom_data, data->str, last_sep-(data->str));
1952     }
1953   g_string_free (data, TRUE);
1954 }
1955
1956
1957 /**
1958  * g_kdbus_setup_bloom:
1959  * Based on bus-bloom.c from systemd
1960  * http://cgit.freedesktop.org/systemd/systemd/tree/src/libsystemd/sd-bus/bus-bloom.c
1961  */
1962 static void
1963 g_kdbus_setup_bloom (GKdbus                     *kdbus,
1964                      GDBusMessage               *dbus_msg,
1965                      struct kdbus_bloom_filter  *bloom_filter)
1966 {
1967   GVariant *body;
1968   GVariantIter iter;
1969   GVariant *child;
1970
1971   const gchar *message_type;
1972   const gchar *interface;
1973   const gchar *member;
1974   const gchar *path;
1975
1976   void *bloom_data;
1977   gint cnt = 0;
1978
1979   body = g_dbus_message_get_body (dbus_msg);
1980   message_type = _g_dbus_enum_to_string (G_TYPE_DBUS_MESSAGE_TYPE, g_dbus_message_get_message_type (dbus_msg));
1981   interface = g_dbus_message_get_interface (dbus_msg);
1982   member = g_dbus_message_get_member (dbus_msg);
1983   path = g_dbus_message_get_path (dbus_msg);
1984
1985   bloom_data = bloom_filter->data;
1986   memset (bloom_data, 0, kdbus->priv->bloom_size);
1987   bloom_filter->generation = 0;
1988
1989   g_kdbus_bloom_add_pair(kdbus, bloom_data, "message-type", message_type);
1990
1991   if (interface)
1992     g_kdbus_bloom_add_pair(kdbus, bloom_data, "interface", interface);
1993
1994   if (member)
1995     g_kdbus_bloom_add_pair(kdbus, bloom_data, "member", member);
1996
1997   if (path)
1998     {
1999       g_kdbus_bloom_add_pair(kdbus, bloom_data, "path", path);
2000       g_kdbus_bloom_add_pair(kdbus, bloom_data, "path-slash-prefix", path);
2001       g_kdbus_bloom_add_prefixes(kdbus, bloom_data, "path-slash-prefix", path, '/');
2002     }
2003
2004   if (body != NULL)
2005     {
2006       g_variant_iter_init (&iter, body);
2007       while ((child = g_variant_iter_next_value (&iter)))
2008         {
2009           gchar buf[sizeof("arg")-1 + 2 + sizeof("-slash-prefix")];
2010           gchar *child_string;
2011           gchar *e;
2012
2013           /* Is it necessary? */
2014           //if (g_variant_is_container (child))
2015           //  iterate_container_recursive (child);
2016
2017           if (!(g_variant_is_of_type (child, G_VARIANT_TYPE_STRING)) &&
2018               !(g_variant_is_of_type (child, G_VARIANT_TYPE_OBJECT_PATH)) &&
2019               !(g_variant_is_of_type (child, G_VARIANT_TYPE_SIGNATURE)))
2020             break;
2021
2022           child_string = g_variant_dup_string (child, NULL);
2023
2024           e = stpcpy(buf, "arg");
2025           if (cnt < 10)
2026             *(e++) = '0' + (char) cnt;
2027           else
2028             {
2029               *(e++) = '0' + (char) (cnt / 10);
2030               *(e++) = '0' + (char) (cnt % 10);
2031             }
2032
2033           *e = 0;
2034           g_kdbus_bloom_add_pair(kdbus, bloom_data, buf, child_string);
2035
2036           strcpy(e, "-dot-prefix");
2037           g_kdbus_bloom_add_prefixes(kdbus, bloom_data, buf, child_string, '.');
2038
2039           strcpy(e, "-slash-prefix");
2040           g_kdbus_bloom_add_prefixes(kdbus, bloom_data, buf, child_string, '/');
2041
2042           g_free (child_string);
2043           g_variant_unref (child);
2044           cnt++;
2045         }
2046     }
2047 }
2048
2049
2050 /**
2051  * g_kdbus_NameOwnerChanged_generate:
2052  * TODO: Not tesed yet
2053  */
2054 static gssize
2055 g_kdbus_NameOwnerChanged_generate (GKdbus             *kdbus,
2056                                    struct kdbus_item  *item)
2057 {
2058   GVariant *result = NULL;
2059   GDBusMessage *reply;
2060   GError *error;
2061   guchar *blob;
2062   gssize reply_size = 0;
2063
2064   gchar *owner;
2065   gchar *old_owner;
2066   gchar *new_owner;
2067
2068   /* ID change */
2069   if (item->type == KDBUS_ITEM_ID_ADD || item->type == KDBUS_ITEM_ID_REMOVE)
2070     {
2071       owner = "";
2072
2073       if (item->type == KDBUS_ITEM_ID_ADD)
2074         {
2075           old_owner = NULL;
2076           new_owner = owner;
2077         }
2078       else
2079         {
2080           old_owner = owner;
2081           new_owner = NULL;
2082         }
2083     }
2084
2085   /* name change */
2086   if (item->type == KDBUS_ITEM_NAME_ADD ||
2087       item->type == KDBUS_ITEM_NAME_REMOVE ||
2088       item->type == KDBUS_ITEM_NAME_CHANGE )
2089     {
2090      g_error ("[KDBUS] 'NameChange' is not implemented yet");
2091     }
2092
2093   result = g_variant_new ("(sss)", owner, old_owner, new_owner);
2094   reply = g_kdbus_generate_local_reply (NULL,
2095                                         G_DBUS_MESSAGE_TYPE_SIGNAL,
2096                                         G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED,
2097                                         -1,
2098                                         result,
2099                                         NULL);
2100
2101   //_g_dbus_message_set_protocol_ver (reply,2);
2102   blob =  g_dbus_message_to_blob (reply, (gsize*) &reply_size, 0, &error);
2103   if (blob == NULL)
2104
2105     g_error ("[KDBUS] NameOwnerChanged: %s\n",error->message);
2106
2107   ((guint32 *) blob)[2] = GUINT32_TO_LE (-1);
2108   g_kdbus_add_msg_part (kdbus, (gchar*)blob, reply_size);
2109
2110   return reply_size;
2111
2112 }
2113
2114
2115 /**
2116  * g_kdbus_KernelMethodError_generate:
2117  *
2118  */
2119 static gssize
2120 g_kdbus_KernelMethodError_generate (GKdbus             *kdbus,
2121                                     struct kdbus_item  *item)
2122 {
2123   GVariant *error_name;
2124   GDBusMessage *reply;
2125   GError *error;
2126   guchar *blob;
2127   gssize reply_size = 0;
2128
2129   if (item->type == KDBUS_ITEM_REPLY_TIMEOUT)
2130     error_name = g_variant_new ("(s)", "Method call timed out");
2131   else
2132     error_name = g_variant_new ("(s)", "Method call peer died");
2133
2134   error = NULL;
2135   reply = g_kdbus_generate_local_reply (NULL,
2136                                         G_DBUS_MESSAGE_TYPE_ERROR,
2137                                         G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED,
2138                                         -1,
2139                                         error_name,
2140                                         "org.freedesktop.DBus.Error.NoReply");
2141
2142   //_g_dbus_message_set_protocol_ver (reply,2);
2143   blob =  g_dbus_message_to_blob (reply, (gsize*) &reply_size, 0, &error);
2144
2145   if (blob == NULL)
2146     g_error ("[KDBUS] KernelMethodError: %s\n",error->message);
2147
2148   ((guint32 *) blob)[2] = GUINT32_TO_LE (-1);
2149   g_kdbus_add_msg_part (kdbus, (gchar*)blob, reply_size);
2150
2151   return reply_size;
2152 }
2153
2154
2155 /**
2156  * g_kdbus_decode_kernel_msg:
2157  *
2158  */
2159 static gssize
2160 g_kdbus_decode_kernel_msg (GKdbus  *kdbus)
2161 {
2162   struct kdbus_item *item = NULL;
2163   gssize size = 0;
2164
2165   KDBUS_ITEM_FOREACH(item, kdbus->priv->kmsg, items)
2166     {
2167       switch (item->type)
2168         {
2169           case KDBUS_ITEM_ID_ADD:
2170           case KDBUS_ITEM_ID_REMOVE:
2171           case KDBUS_ITEM_NAME_ADD:
2172           case KDBUS_ITEM_NAME_REMOVE:
2173           case KDBUS_ITEM_NAME_CHANGE:
2174             size = g_kdbus_NameOwnerChanged_generate (kdbus, item);
2175             break;
2176
2177           case KDBUS_ITEM_REPLY_TIMEOUT:
2178           case KDBUS_ITEM_REPLY_DEAD:
2179             size = g_kdbus_KernelMethodError_generate (kdbus, item);
2180             break;
2181
2182           default:
2183             g_error ("[KDBUS] KERNEL: Unknown filed - %lld", item->type);
2184         }
2185     }
2186
2187   /* Override information from the user header with data from the kernel */
2188   g_string_printf (kdbus->priv->msg_sender, "org.freedesktop.DBus");
2189
2190   /* for destination */
2191   if (kdbus->priv->kmsg->dst_id == KDBUS_DST_ID_BROADCAST)
2192     /* for broadcast messages we don't have to set destination */
2193     ;
2194   else if (kdbus->priv->kmsg->dst_id == KDBUS_DST_ID_NAME)
2195     g_string_printf (kdbus->priv->msg_destination, ":1.%" G_GUINT64_FORMAT, (guint64) kdbus->priv->unique_id);
2196   else
2197     g_string_printf (kdbus->priv->msg_destination, ":1.%" G_GUINT64_FORMAT, (guint64) kdbus->priv->kmsg->dst_id);
2198
2199
2200   return size;
2201 }
2202
2203
2204 /**
2205  * g_kdbus_decode_dbus_msg:
2206  *
2207  */
2208 static gssize
2209 g_kdbus_decode_dbus_msg (GKdbus  *kdbus)
2210 {
2211   struct kdbus_item *item;
2212   gchar *msg_ptr;
2213   gssize ret_size = 0;
2214   gssize data_size = 0;
2215   const gchar *destination = NULL;
2216
2217   KDBUS_ITEM_FOREACH(item, kdbus->priv->kmsg, items)
2218     {
2219       if (item->size <= KDBUS_ITEM_HEADER_SIZE)
2220         g_error("[KDBUS] %llu bytes - invalid data record\n", item->size);
2221
2222       data_size = item->size - KDBUS_ITEM_HEADER_SIZE;
2223
2224       switch (item->type)
2225         {
2226
2227          /* KDBUS_ITEM_DST_NAME */
2228          case KDBUS_ITEM_DST_NAME:
2229            destination = item->str;
2230            break;
2231
2232         /* KDBUS_ITEM_PALOAD_OFF */
2233         case KDBUS_ITEM_PAYLOAD_OFF:
2234
2235           msg_ptr = (gchar*) kdbus->priv->kmsg + item->vec.offset;
2236           g_kdbus_add_msg_part (kdbus, msg_ptr, item->vec.size);
2237           ret_size += item->vec.size;
2238
2239           break;
2240
2241         /* KDBUS_ITEM_PAYLOAD_MEMFD */
2242         case KDBUS_ITEM_PAYLOAD_MEMFD:
2243
2244           msg_ptr = mmap(NULL, item->memfd.size, PROT_READ, MAP_SHARED, item->memfd.fd, 0);
2245
2246           if (msg_ptr == MAP_FAILED)
2247             {
2248               g_print ("mmap() fd=%i failed:%m", item->memfd.fd);
2249               break;
2250             }
2251
2252           g_kdbus_add_msg_part (kdbus, msg_ptr, item->memfd.size);
2253           ret_size += item->memfd.size;
2254
2255           break;
2256
2257         /* KDBUS_ITEM_FDS */
2258         case KDBUS_ITEM_FDS:
2259
2260           kdbus->priv->num_fds = data_size / sizeof(int);
2261           kdbus->priv->fds = g_malloc0 (sizeof(int) * kdbus->priv->num_fds);
2262           memcpy(kdbus->priv->fds, item->fds, sizeof(int) * kdbus->priv->num_fds);
2263
2264           break;
2265
2266         /* All of the following items, like CMDLINE,
2267            CGROUP, etc. need some GDBUS API extensions and
2268            should be implemented in the future */
2269         case KDBUS_ITEM_CREDS:
2270         case KDBUS_ITEM_TIMESTAMP:
2271         case KDBUS_ITEM_PID_COMM:
2272         case KDBUS_ITEM_TID_COMM:
2273         case KDBUS_ITEM_EXE:
2274         case KDBUS_ITEM_CMDLINE:
2275         case KDBUS_ITEM_CGROUP:
2276         case KDBUS_ITEM_AUDIT:
2277         case KDBUS_ITEM_CAPS:
2278         case KDBUS_ITEM_SECLABEL:
2279         case KDBUS_ITEM_CONN_NAME:
2280         case KDBUS_ITEM_NAME:
2281           break;
2282
2283         default:
2284           g_error ("[KDBUS] DBUS_PAYLOAD: Unknown filed - %lld", item->type);
2285           break;
2286         }
2287     }
2288
2289   /* Override information from the user header with data from the kernel */
2290
2291   if (kdbus->priv->kmsg->src_id == KDBUS_SRC_ID_KERNEL)
2292     g_string_printf (kdbus->priv->msg_sender, "org.freedesktop.DBus");
2293   else
2294     g_string_printf (kdbus->priv->msg_sender, ":1.%" G_GUINT64_FORMAT, (guint64) kdbus->priv->kmsg->src_id);
2295
2296   if (destination)
2297     g_string_printf (kdbus->priv->msg_destination, "%s", destination);
2298   else if (kdbus->priv->kmsg->dst_id == KDBUS_DST_ID_BROADCAST)
2299     /* for broadcast messages we don't have to set destination */
2300     ;
2301   else if (kdbus->priv->kmsg->dst_id == KDBUS_DST_ID_NAME)
2302     g_string_printf (kdbus->priv->msg_destination, ":1.%" G_GUINT64_FORMAT, (guint64) kdbus->priv->unique_id);
2303   else
2304     g_string_printf (kdbus->priv->msg_destination, ":1.%" G_GUINT64_FORMAT, (guint64) kdbus->priv->kmsg->dst_id);
2305
2306   return ret_size;
2307 }
2308
2309
2310 /**
2311  * _g_kdbus_receive:
2312  *
2313  */
2314 gssize
2315 _g_kdbus_receive (GKdbus        *kdbus,
2316                   GCancellable  *cancellable,
2317                   GError       **error)
2318 {
2319   struct kdbus_cmd_recv recv = {};
2320   gssize size = 0;
2321
2322   if (g_cancellable_set_error_if_cancelled (cancellable, error))
2323     return -1;
2324
2325   again:
2326     if (ioctl(kdbus->priv->fd, KDBUS_CMD_MSG_RECV, &recv) < 0)
2327       {
2328         if (errno == EINTR || errno == EAGAIN)
2329           goto again;
2330
2331         g_set_error (error, G_IO_ERROR, g_io_error_from_errno(errno),_("Error receiving message - KDBUS_CMD_MSG_RECV error"));
2332         return -1;
2333       }
2334
2335     kdbus->priv->kmsg = (struct kdbus_msg *)((guint8 *)kdbus->priv->kdbus_buffer + recv.offset);
2336
2337     if (kdbus->priv->kmsg->payload_type == KDBUS_PAYLOAD_DBUS)
2338       size = g_kdbus_decode_dbus_msg (kdbus);
2339     else if (kdbus->priv->kmsg->payload_type == KDBUS_PAYLOAD_KERNEL)
2340       size = g_kdbus_decode_kernel_msg (kdbus);
2341     else
2342       g_error ("[KDBUS] Unknown payload type: %llu", kdbus->priv->kmsg->payload_type);
2343
2344     return size;
2345 }
2346
2347
2348 /**
2349  * _g_kdbus_send:
2350  * Returns: size of data sent or -1 when error
2351  */
2352 gsize
2353 _g_kdbus_send (GDBusWorker   *worker,
2354                GKdbus        *kdbus,
2355                GDBusMessage  *dbus_msg,
2356                gchar         *blob,
2357                gsize          blob_size,
2358                GUnixFDList   *fd_list,
2359                GCancellable  *cancellable,
2360                GError       **error)
2361 {
2362   struct kdbus_msg* kmsg;
2363   struct kdbus_item *item;
2364   guint64 kmsg_size = 0;
2365   const gchar *name;
2366   gboolean use_memfd = FALSE;
2367   guint64 dst_id = KDBUS_DST_ID_BROADCAST;
2368
2369   g_return_val_if_fail (G_IS_KDBUS (kdbus), -1);
2370
2371   if (g_cancellable_set_error_if_cancelled (cancellable, error))
2372     return -1;
2373
2374
2375   /*
2376    * If systemd-bus-driverd from systemd isn't available
2377    * try to process the bus driver messages locally
2378    */
2379 #ifndef SYSTEMD_BUS_DRIVERD
2380   if (g_strcmp0(g_dbus_message_get_destination(dbus_msg), "org.freedesktop.DBus") == 0)
2381     {
2382       if (g_kdbus_bus_driver (worker, kdbus, dbus_msg))
2383         return blob_size;
2384       else
2385         return -1;
2386     }
2387 #else
2388     if ((g_strcmp0(g_dbus_message_get_destination(dbus_msg), "org.freedesktop.DBus") == 0) &&
2389         (g_strcmp0(g_dbus_message_get_member(dbus_msg), "Hello") == 0))
2390       {
2391         g_kdbus_take_fd (kdbus);
2392       }
2393 #endif
2394
2395
2396   /*
2397    * check destination
2398    */
2399   if ((name = g_dbus_message_get_destination(dbus_msg)))
2400     {
2401       dst_id = KDBUS_DST_ID_NAME;
2402       if ((name[0] == ':') && (name[1] == '1') && (name[2] == '.'))
2403         {
2404           dst_id = strtoull(&name[3], NULL, 10);
2405           name=NULL;
2406         }
2407     }
2408
2409
2410   /*
2411    * check whether we should use memfd transport (for messages > 512K)
2412    */
2413   if (name && (blob_size > 524288))
2414     use_memfd = TRUE;
2415
2416
2417   /*
2418    * check and set message size
2419    */
2420   kmsg_size = sizeof(struct kdbus_msg);
2421   if (use_memfd)
2422     {
2423       kmsg_size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec));   /* header */
2424       kmsg_size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_memfd)); /* body */
2425     }
2426   else
2427     kmsg_size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec));   /* header + body */
2428
2429   if (fd_list != NULL && g_unix_fd_list_get_length (fd_list) > 0)
2430     kmsg_size += ALIGN8(G_STRUCT_OFFSET(struct kdbus_item, fds) + sizeof(int) * g_unix_fd_list_get_length(fd_list));
2431
2432   if (name)
2433     kmsg_size += KDBUS_ITEM_SIZE(strlen(name) + 1);
2434   else if (dst_id == KDBUS_DST_ID_BROADCAST)
2435     kmsg_size += ALIGN8(G_STRUCT_OFFSET(struct kdbus_item, bloom_filter) +
2436                         G_STRUCT_OFFSET(struct kdbus_bloom_filter, data) +
2437                         kdbus->priv->bloom_size);
2438
2439   kmsg = malloc(kmsg_size);
2440   if (!kmsg)
2441     g_error ("[KDBUS] kmsg malloc error");
2442
2443
2444   /*
2445    * set message header
2446    */
2447   memset(kmsg, 0, kmsg_size);
2448   kmsg->size = kmsg_size;
2449   kmsg->payload_type = KDBUS_PAYLOAD_DBUS;
2450   kmsg->dst_id = name ? 0 : dst_id;
2451   kmsg->src_id = kdbus->priv->unique_id;
2452   kmsg->cookie = g_dbus_message_get_serial(dbus_msg);
2453   kmsg->priority = 0;
2454
2455
2456   /*
2457    * set message flags
2458    */
2459   kmsg->flags = ((g_dbus_message_get_flags (dbus_msg) & G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED) ? 0 : KDBUS_MSG_FLAGS_EXPECT_REPLY) |
2460                 ((g_dbus_message_get_flags (dbus_msg) & G_DBUS_MESSAGE_FLAGS_NO_AUTO_START) ? KDBUS_MSG_FLAGS_NO_AUTO_START : 0);
2461
2462   if ((kmsg->flags) & KDBUS_MSG_FLAGS_EXPECT_REPLY)
2463     kmsg->timeout_ns = 2000000000;
2464   else
2465     kmsg->cookie_reply = g_dbus_message_get_reply_serial(dbus_msg);
2466
2467
2468   /*
2469    * append payload
2470    */
2471   item = kmsg->items;
2472   if (use_memfd)
2473     {
2474       gint32 body_size;
2475
2476       if (!g_kdbus_alloc_memfd (kdbus))
2477         g_error ("Can't alloc memfd");
2478
2479       /* split blob to header and body */
2480       memcpy (&body_size, blob+4, 4);
2481       body_size = GINT32_FROM_LE (body_size);
2482
2483       /*
2484        * write blob and seal
2485        * We should build up whole messsage directly in memfd object without
2486        * making copy but memfd will be completly reworked soon [1],
2487        * so we're still waiting for this:
2488        *
2489        * [1] https://code.google.com/p/d-bus/source/browse/TODO
2490        */
2491
2492       if (write(kdbus->priv->memfd, blob + (blob_size-body_size), body_size) <= 0)
2493         g_error ("Can't write data to memfd object");
2494
2495       if (ioctl(kdbus->priv->memfd, KDBUS_CMD_MEMFD_SEAL_SET, 1) < 0)
2496         g_error ("Can't seal memfd object");
2497
2498       /* message header in its entirety must be contained in a single PAYLOAD_VEC item */
2499       g_kdbus_append_payload_vec (&item, blob, blob_size - body_size);
2500       /* send body as as PAYLOAD_MEMFD item */
2501       g_kdbus_append_payload_memfd (&item, kdbus->priv->memfd, body_size);
2502     }
2503   else
2504     {
2505       /* if we don't use memfd, send whole message as a PAYLOAD_VEC item */
2506       g_kdbus_append_payload_vec (&item, blob, blob_size);
2507     }
2508
2509
2510   /*
2511    * append destination or bloom filters
2512    */
2513   if (name)
2514     g_kdbus_append_destination (&item, name, strlen(name));
2515   else if (dst_id == KDBUS_DST_ID_BROADCAST)
2516     {
2517       struct kdbus_bloom_filter *bloom_filter;
2518
2519       bloom_filter = g_kdbus_append_bloom (&item, kdbus->priv->bloom_size);
2520       g_kdbus_setup_bloom (kdbus, dbus_msg, bloom_filter);
2521     }
2522
2523
2524   /*
2525    * append fds if any
2526    */
2527   if (fd_list != NULL && g_unix_fd_list_get_length (fd_list) > 0)
2528     g_kdbus_append_fds (&item, fd_list);
2529
2530
2531   /*
2532    * send message
2533    */
2534 again:
2535   if (ioctl(kdbus->priv->fd, KDBUS_CMD_MSG_SEND, kmsg))
2536     {
2537       GString *error_name;
2538       error_name = g_string_new (NULL);
2539
2540       if(errno == EINTR)
2541         {
2542           g_string_free (error_name,TRUE);
2543           goto again;
2544         }
2545       else if (errno == ENXIO)
2546         {
2547           g_string_printf (error_name, "Name %s does not exist", g_dbus_message_get_destination(dbus_msg));
2548           g_kdbus_generate_local_error (worker,
2549                                         dbus_msg,
2550                                         g_variant_new ("(s)",error_name->str),
2551                                         G_DBUS_ERROR_SERVICE_UNKNOWN);
2552           g_string_free (error_name,TRUE);
2553           return 0;
2554         }
2555       else if ((errno == ESRCH) || (errno == EADDRNOTAVAIL))
2556         {
2557           if (kmsg->flags & KDBUS_MSG_FLAGS_NO_AUTO_START)
2558             {
2559               g_string_printf (error_name, "Name %s does not exist", g_dbus_message_get_destination(dbus_msg));
2560               g_kdbus_generate_local_error (worker,
2561                                             dbus_msg,
2562                                             g_variant_new ("(s)",error_name->str),
2563                                             G_DBUS_ERROR_SERVICE_UNKNOWN);
2564               g_string_free (error_name,TRUE);
2565               return 0;
2566             }
2567           else
2568             {
2569               g_string_printf (error_name, "The name %s was not provided by any .service files", g_dbus_message_get_destination(dbus_msg));
2570               g_kdbus_generate_local_error (worker,
2571                                             dbus_msg,
2572                                             g_variant_new ("(s)",error_name->str),
2573                                             G_DBUS_ERROR_SERVICE_UNKNOWN);
2574               g_string_free (error_name,TRUE);
2575               return 0;
2576             }
2577         }
2578
2579       g_print ("[KDBUS] ioctl error sending kdbus message:%d (%m)\n",errno);
2580       g_set_error (error, G_IO_ERROR, g_io_error_from_errno(errno), _("Error sending message - KDBUS_CMD_MSG_SEND error"));
2581       return -1;
2582     }
2583
2584   if (kdbus->priv->memfd >= 0)
2585     close(kdbus->priv->memfd);
2586
2587   free(kmsg);
2588
2589   return blob_size;
2590 }