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