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