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