[kdbus] Add RequestName and ReleaseName to new API
[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
38 #ifdef HAVE_SYS_FILIO_H
39 # include <sys/filio.h>
40 #endif
41
42 #ifdef HAVE_SYS_UIO_H
43 #include <sys/uio.h>
44 #endif
45
46 #define KDBUS_POOL_SIZE (16 * 1024LU * 1024LU)
47 #define KDBUS_ALIGN8(l) (((l) + 7) & ~7)
48 #define KDBUS_ALIGN8_PTR(p) ((void*) (uintptr_t)(p))
49
50 #define KDBUS_ITEM_HEADER_SIZE G_STRUCT_OFFSET(struct kdbus_item, data)
51 #define KDBUS_ITEM_SIZE(s) KDBUS_ALIGN8((s) + KDBUS_ITEM_HEADER_SIZE)
52
53 #define KDBUS_ITEM_NEXT(item) \
54         (typeof(item))(((guint8 *)item) + KDBUS_ALIGN8((item)->size))
55 #define KDBUS_ITEM_FOREACH(item, head, first)                    \
56         for (item = (head)->first;                               \
57              (guint8 *)(item) < (guint8 *)(head) + (head)->size; \
58              item = KDBUS_ITEM_NEXT(item))
59
60 #define g_alloca0(x) memset(g_alloca(x), '\0', (x))
61
62 static void     g_kdbus_initable_iface_init (GInitableIface  *iface);
63 static gboolean g_kdbus_initable_init       (GInitable       *initable,
64                                              GCancellable    *cancellable,
65                                              GError         **error);
66
67 #define g_kdbus_get_type _g_kdbus_get_type
68 G_DEFINE_TYPE_WITH_CODE (GKdbus, g_kdbus, G_TYPE_OBJECT,
69                          G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
70                                                 g_kdbus_initable_iface_init));
71
72 /* GBusCredentialsFlags */
73 typedef enum
74 {
75   G_BUS_CREDS_PID              = 1,
76   G_BUS_CREDS_UID              = 2,
77   G_BUS_CREDS_UNIQUE_NAME      = 3,
78   G_BUS_CREDS_SELINUX_CONTEXT  = 4
79 } GBusCredentialsFlags;
80
81 /* GKdbusPrivate struct */
82 struct _GKdbusPrivate
83 {
84   gint               fd;
85
86   gchar             *kdbus_buffer;
87   struct kdbus_msg  *kmsg;
88
89   gchar             *unique_name;
90   guint64            unique_id;
91
92   guint64            hello_flags;
93   guint64            attach_flags;
94
95   guint              closed : 1;
96   guint              inited : 1;
97   guint              timeout;
98   guint              timed_out : 1;
99
100   guchar             bus_id[16];
101 };
102
103 /* GKdbusSource struct */
104 typedef struct {
105   GSource        source;
106   GPollFD        pollfd;
107   GKdbus        *kdbus;
108   GIOCondition   condition;
109   GCancellable  *cancellable;
110   GPollFD        cancel_pollfd;
111   gint64         timeout_time;
112 } GKdbusSource;
113
114
115 typedef gboolean (*GKdbusSourceFunc) (GKdbus *kdbus,
116                                       GIOCondition condition,
117                                       gpointer user_data);
118
119 /**
120  * g_kdbus_finalize:
121  *
122  */
123 static void
124 g_kdbus_finalize (GObject  *object)
125 {
126   GKdbus *kdbus = G_KDBUS (object);
127
128   if (kdbus->priv->kdbus_buffer != NULL)
129     munmap (kdbus->priv->kdbus_buffer, KDBUS_POOL_SIZE);
130
131   kdbus->priv->kdbus_buffer = NULL;
132
133   if (kdbus->priv->fd != -1 && !kdbus->priv->closed)
134     _g_kdbus_close (kdbus, NULL);
135
136   if (G_OBJECT_CLASS (g_kdbus_parent_class)->finalize)
137     (*G_OBJECT_CLASS (g_kdbus_parent_class)->finalize) (object);
138 }
139
140
141 /**
142  * g_kdbus_class_init:
143  *
144  */
145 static void
146 g_kdbus_class_init (GKdbusClass  *klass)
147 {
148   GObjectClass *gobject_class G_GNUC_UNUSED = G_OBJECT_CLASS (klass);
149
150   g_type_class_add_private (klass, sizeof (GKdbusPrivate));
151   gobject_class->finalize = g_kdbus_finalize;
152 }
153
154
155 /**
156  * g_kdbus_initable_iface_init:
157  *
158  */
159 static void
160 g_kdbus_initable_iface_init (GInitableIface  *iface)
161 {
162   iface->init = g_kdbus_initable_init;
163 }
164
165
166 /**
167  * g_kdbus_init:
168  *
169  */
170 static void
171 g_kdbus_init (GKdbus  *kdbus)
172 {
173   kdbus->priv = G_TYPE_INSTANCE_GET_PRIVATE (kdbus, G_TYPE_KDBUS, GKdbusPrivate);
174
175   kdbus->priv->fd = -1;
176
177   kdbus->priv->unique_id = -1;
178   kdbus->priv->unique_name = NULL;
179
180   kdbus->priv->kdbus_buffer = NULL;
181
182   kdbus->priv->hello_flags = 0; /* KDBUS_HELLO_ACCEPT_FD */
183   kdbus->priv->attach_flags = KDBUS_ATTACH_NAMES;
184 }
185
186
187 /**
188  * g_kdbus_initable_init:
189  *
190  */
191 static gboolean
192 g_kdbus_initable_init (GInitable     *initable,
193                        GCancellable  *cancellable,
194                        GError       **error)
195 {
196   GKdbus *kdbus;
197
198   g_return_val_if_fail (G_IS_KDBUS (initable), FALSE);
199
200   kdbus = G_KDBUS (initable);
201
202   if (cancellable != NULL)
203     {
204       g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
205                            _("Cancellable initialization not supported"));
206       return FALSE;
207     }
208
209   kdbus->priv->inited = TRUE;
210
211   return TRUE;
212 }
213
214
215 /**
216  * kdbus_source_prepare:
217  *
218  */
219 static gboolean
220 kdbus_source_prepare (GSource  *source,
221                       gint     *timeout)
222 {
223   GKdbusSource *kdbus_source = (GKdbusSource *)source;
224
225   if (g_cancellable_is_cancelled (kdbus_source->cancellable))
226     return TRUE;
227
228   if (kdbus_source->timeout_time)
229     {
230       gint64 now;
231
232       now = g_source_get_time (source);
233
234       *timeout = (kdbus_source->timeout_time - now + 999) / 1000;
235       if (*timeout < 0)
236         {
237           kdbus_source->kdbus->priv->timed_out = TRUE;
238           *timeout = 0;
239           return TRUE;
240         }
241     }
242   else
243     *timeout = -1;
244
245   if ((kdbus_source->condition & kdbus_source->pollfd.revents) != 0)
246     return TRUE;
247
248   return FALSE;
249 }
250
251
252 /**
253  * kdbus_source_check:
254  *
255  */
256 static gboolean
257 kdbus_source_check (GSource  *source)
258 {
259   gint timeout;
260
261   return kdbus_source_prepare (source, &timeout);
262 }
263
264
265 /**
266  * kdbus_source_dispatch
267  *
268  */
269 static gboolean
270 kdbus_source_dispatch  (GSource      *source,
271                         GSourceFunc   callback,
272                         gpointer      user_data)
273 {
274   GKdbusSourceFunc func = (GKdbusSourceFunc)callback;
275   GKdbusSource *kdbus_source = (GKdbusSource *)source;
276   GKdbus *kdbus = kdbus_source->kdbus;
277   gboolean ret;
278
279   if (kdbus_source->kdbus->priv->timed_out)
280     kdbus_source->pollfd.revents |= kdbus_source->condition & (G_IO_IN | G_IO_OUT);
281
282   ret = (*func) (kdbus,
283                  kdbus_source->pollfd.revents & kdbus_source->condition,
284                  user_data);
285
286   if (kdbus->priv->timeout)
287     kdbus_source->timeout_time = g_get_monotonic_time ()
288                                + kdbus->priv->timeout * 1000000;
289
290   else
291     kdbus_source->timeout_time = 0;
292
293   return ret;
294 }
295
296
297 /**
298  * kdbus_source_finalize
299  *
300  */
301 static void
302 kdbus_source_finalize (GSource  *source)
303 {
304   GKdbusSource *kdbus_source = (GKdbusSource *)source;
305   GKdbus *kdbus;
306
307   kdbus = kdbus_source->kdbus;
308
309   g_object_unref (kdbus);
310
311   if (kdbus_source->cancellable)
312     {
313       g_cancellable_release_fd (kdbus_source->cancellable);
314       g_object_unref (kdbus_source->cancellable);
315     }
316 }
317
318
319 /**
320  * kdbus_source_closure_callback:
321  *
322  */
323 static gboolean
324 kdbus_source_closure_callback (GKdbus        *kdbus,
325                                GIOCondition   condition,
326                                gpointer       data)
327 {
328   GClosure *closure = data;
329   GValue params[2] = { G_VALUE_INIT, G_VALUE_INIT };
330   GValue result_value = G_VALUE_INIT;
331   gboolean result;
332
333   g_value_init (&result_value, G_TYPE_BOOLEAN);
334
335   g_value_init (&params[0], G_TYPE_KDBUS);
336   g_value_set_object (&params[0], kdbus);
337   g_value_init (&params[1], G_TYPE_IO_CONDITION);
338   g_value_set_flags (&params[1], condition);
339
340   g_closure_invoke (closure, &result_value, 2, params, NULL);
341
342   result = g_value_get_boolean (&result_value);
343   g_value_unset (&result_value);
344   g_value_unset (&params[0]);
345   g_value_unset (&params[1]);
346
347   return result;
348 }
349
350
351 static GSourceFuncs kdbus_source_funcs =
352 {
353   kdbus_source_prepare,
354   kdbus_source_check,
355   kdbus_source_dispatch,
356   kdbus_source_finalize,
357   (GSourceFunc)kdbus_source_closure_callback,
358 };
359
360
361 /**
362  * kdbus_source_new:
363  *
364  */
365 static GSource *
366 kdbus_source_new (GKdbus        *kdbus,
367                   GIOCondition   condition,
368                   GCancellable  *cancellable)
369 {
370   GSource *source;
371   GKdbusSource *kdbus_source;
372
373   source = g_source_new (&kdbus_source_funcs, sizeof (GKdbusSource));
374   g_source_set_name (source, "GKdbus");
375   kdbus_source = (GKdbusSource *)source;
376
377   kdbus_source->kdbus = g_object_ref (kdbus);
378   kdbus_source->condition = condition;
379
380   if (g_cancellable_make_pollfd (cancellable,
381                                  &kdbus_source->cancel_pollfd))
382     {
383       kdbus_source->cancellable = g_object_ref (cancellable);
384       g_source_add_poll (source, &kdbus_source->cancel_pollfd);
385     }
386
387   kdbus_source->pollfd.fd = kdbus->priv->fd;
388   kdbus_source->pollfd.events = condition;
389   kdbus_source->pollfd.revents = 0;
390   g_source_add_poll (source, &kdbus_source->pollfd);
391
392   if (kdbus->priv->timeout)
393     kdbus_source->timeout_time = g_get_monotonic_time ()
394                                + kdbus->priv->timeout * 1000000;
395   else
396     kdbus_source->timeout_time = 0;
397
398   return source;
399 }
400
401
402 /**
403  * _g_kdbus_create_source:
404  *
405  */
406 GSource *
407 _g_kdbus_create_source (GKdbus        *kdbus,
408                         GIOCondition   condition,
409                         GCancellable  *cancellable)
410 {
411   g_return_val_if_fail (G_IS_KDBUS (kdbus) && (cancellable == NULL || G_IS_CANCELLABLE (cancellable)), NULL);
412
413   return kdbus_source_new (kdbus, condition, cancellable);
414 }
415
416
417 /**
418  * _g_kdbus_open:
419  *
420  */
421 gboolean
422 _g_kdbus_open (GKdbus       *kdbus,
423                const gchar  *address,
424                GError      **error)
425 {
426   g_return_val_if_fail (G_IS_KDBUS (kdbus), FALSE);
427
428   kdbus->priv->fd = open(address, O_RDWR|O_NOCTTY|O_CLOEXEC);
429   if (kdbus->priv->fd<0)
430     {
431       g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, _("Can't open kdbus endpoint"));
432       return FALSE;
433     }
434
435   kdbus->priv->closed = FALSE;
436
437   return TRUE;
438 }
439
440
441 /**
442  * g_kdbus_free_data:
443  *
444  */
445 static gboolean
446 g_kdbus_free_data (GKdbus      *kdbus,
447                    guint64      offset)
448 {
449   struct kdbus_cmd_free cmd;
450   int ret;
451
452   cmd.offset = offset;
453   cmd.flags = 0;
454
455   ret = ioctl (kdbus->priv->fd, KDBUS_CMD_FREE, &cmd);
456   if (ret < 0)
457       return FALSE;
458
459   return TRUE;
460 }
461
462
463 /**
464  * g_kdbus_translate_nameowner_flags:
465  *
466  */
467 static void
468 g_kdbus_translate_nameowner_flags (GBusNameOwnerFlags   flags,
469                                    guint64             *kdbus_flags)
470 {
471   guint64 new_flags;
472
473   new_flags = 0;
474
475   if (flags & G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT)
476     new_flags |= KDBUS_NAME_ALLOW_REPLACEMENT;
477
478   if (flags & G_BUS_NAME_OWNER_FLAGS_REPLACE)
479     new_flags |= KDBUS_NAME_REPLACE_EXISTING;
480
481   if (!(flags & G_BUS_NAME_OWNER_FLAGS_DO_NOT_QUEUE))
482     new_flags |= KDBUS_NAME_QUEUE;
483
484   *kdbus_flags = new_flags;
485 }
486
487
488 /**
489  * _g_kdbus_close:
490  *
491  */
492 gboolean
493 _g_kdbus_close (GKdbus  *kdbus,
494                 GError **error)
495 {
496   gint res;
497
498   g_return_val_if_fail (G_IS_KDBUS (kdbus), FALSE);
499
500   if (kdbus->priv->closed)
501     return TRUE;
502
503   while (1)
504     {
505       res = close (kdbus->priv->fd);
506
507       if (res == -1)
508         {
509           if (errno == EINTR)
510             continue;
511
512           g_set_error (error, G_IO_ERROR,
513                        g_io_error_from_errno (errno),
514                        _("Error closing kdbus fd: %s"),
515                        g_strerror (errno));
516           return FALSE;
517         }
518       break;
519     }
520
521   kdbus->priv->closed = TRUE;
522   kdbus->priv->fd = -1;
523
524   return TRUE;
525 }
526
527
528 /**
529  * _g_kdbus_is_closed:
530  *
531  */
532 gboolean
533 _g_kdbus_is_closed (GKdbus  *kdbus)
534 {
535   g_return_val_if_fail (G_IS_KDBUS (kdbus), FALSE);
536
537   return kdbus->priv->closed;
538 }
539
540
541 /**
542  * _g_kdbus_Hello:
543  *
544  */
545 GVariant *
546 _g_kdbus_Hello (GIOStream  *stream,
547                 GError    **error)
548 {
549   GKdbus *kdbus;
550   struct kdbus_cmd_hello *hello;
551   struct kdbus_item *item;
552
553   gchar *conn_name;
554   size_t size, conn_name_size;
555
556   kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (stream));
557
558   conn_name = "gdbus-kdbus";
559   conn_name_size = strlen (conn_name);
560
561   size = KDBUS_ALIGN8 (G_STRUCT_OFFSET (struct kdbus_cmd_hello, items)) +
562          KDBUS_ALIGN8 (G_STRUCT_OFFSET (struct kdbus_item, str) + conn_name_size + 1);
563
564   hello = g_alloca0 (size);
565   hello->conn_flags = kdbus->priv->hello_flags;
566   hello->attach_flags =  kdbus->priv->attach_flags;
567   hello->size = size;
568   hello->pool_size = KDBUS_POOL_SIZE;
569
570   item = hello->items;
571   item->size = G_STRUCT_OFFSET (struct kdbus_item, str) + conn_name_size + 1;
572   item->type = KDBUS_ITEM_CONN_NAME;
573   memcpy (item->str, conn_name, conn_name_size+1);
574   item = KDBUS_ITEM_NEXT (item);
575
576   if (ioctl(kdbus->priv->fd, KDBUS_CMD_HELLO, hello))
577     {
578       g_set_error (error, G_IO_ERROR,
579                    g_io_error_from_errno (errno),
580                    _("Failed to send HELLO: %s"),
581                    g_strerror (errno));
582       return NULL;
583     }
584
585   kdbus->priv->kdbus_buffer = mmap(NULL, KDBUS_POOL_SIZE, PROT_READ, MAP_SHARED, kdbus->priv->fd, 0);
586   if (kdbus->priv->kdbus_buffer == MAP_FAILED)
587     {
588       g_set_error (error, G_IO_ERROR,
589                    g_io_error_from_errno (errno),
590                    _("mmap error: %s"),
591                    g_strerror (errno));
592       return NULL;
593     }
594
595   if (hello->bus_flags > 0xFFFFFFFFULL)
596     {
597       g_set_error_literal (error,
598                            G_IO_ERROR,
599                            G_IO_ERROR_FAILED,
600                            _("Incompatible HELLO flags"));
601       return NULL;
602     }
603
604   memcpy (kdbus->priv->bus_id, hello->id128, 16);
605
606   kdbus->priv->unique_id = hello->id;
607   asprintf(&kdbus->priv->unique_name, ":1.%llu", (unsigned long long) hello->id);
608
609   return g_variant_new ("(s)", kdbus->priv->unique_name);
610 }
611
612
613 /*
614  * _g_kdbus_RequestName:
615  *
616  */
617 GVariant *
618 _g_kdbus_RequestName (GDBusConnection     *connection,
619                       const gchar         *name,
620                       GBusNameOwnerFlags   flags,
621                       GError             **error)
622 {
623   GKdbus *kdbus;
624   GVariant *result;
625   struct kdbus_cmd_name *kdbus_name;
626   guint64 kdbus_flags;
627   gssize len, size;
628   gint status, ret;
629
630   status = G_BUS_REQUEST_NAME_FLAGS_PRIMARY_OWNER;
631
632   kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
633   if (kdbus == NULL)
634     {
635       g_set_error_literal (error,
636                            G_DBUS_ERROR,
637                            G_DBUS_ERROR_IO_ERROR,
638                            _("The connection is closed"));
639       return NULL;
640     }
641
642   if (!g_dbus_is_name (name))
643     {
644       g_set_error (error,
645                    G_DBUS_ERROR,
646                    G_DBUS_ERROR_INVALID_ARGS,
647                    "Given bus name \"%s\" is not valid", name);
648       return NULL;
649     }
650
651   if (*name == ':')
652     {
653       g_set_error (error,
654                    G_DBUS_ERROR,
655                    G_DBUS_ERROR_INVALID_ARGS,
656                    "Cannot acquire a service starting with ':' such as \"%s\"", name);
657       return NULL;
658     }
659
660   g_kdbus_translate_nameowner_flags (flags, &kdbus_flags);
661
662   len = strlen(name) + 1;
663   size = G_STRUCT_OFFSET (struct kdbus_cmd_name, items) + KDBUS_ITEM_SIZE(len);
664   kdbus_name = g_alloca0 (size);
665   kdbus_name->size = size;
666   kdbus_name->items[0].size = KDBUS_ITEM_HEADER_SIZE + len;
667   kdbus_name->items[0].type = KDBUS_ITEM_NAME;
668   kdbus_name->flags = kdbus_flags;
669   memcpy (kdbus_name->items[0].str, name, len);
670
671   ret = ioctl(kdbus->priv->fd, KDBUS_CMD_NAME_ACQUIRE, kdbus_name);
672   if (ret < 0)
673     {
674       if (errno == EEXIST)
675         status = G_BUS_REQUEST_NAME_FLAGS_EXISTS;
676       else if (errno == EALREADY)
677         status = G_BUS_REQUEST_NAME_FLAGS_ALREADY_OWNER;
678       else
679         {
680           g_set_error (error, G_IO_ERROR,
681                        g_io_error_from_errno (errno),
682                        _("Error while acquiring name: %s"),
683                        g_strerror (errno));
684           return NULL;
685         }
686     }
687
688   if (kdbus_name->flags & KDBUS_NAME_IN_QUEUE)
689     status = G_BUS_REQUEST_NAME_FLAGS_IN_QUEUE;
690
691   result = g_variant_new ("(u)", status);
692
693   return result;
694 }
695
696
697 /*
698  * _g_kdbus_ReleaseName:
699  *
700  */
701 GVariant *
702 _g_kdbus_ReleaseName (GDBusConnection     *connection,
703                       const gchar         *name,
704                       GError             **error)
705 {
706   GKdbus *kdbus;
707   GVariant *result;
708   struct kdbus_cmd_name *kdbus_name;
709   gssize len, size;
710   gint status, ret;
711
712   status = G_BUS_RELEASE_NAME_FLAGS_RELEASED;
713
714   kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
715   if (kdbus == NULL)
716     {
717       g_set_error_literal (error,
718                            G_DBUS_ERROR,
719                            G_DBUS_ERROR_IO_ERROR,
720                            _("The connection is closed"));
721       return NULL;
722     }
723
724   if (!g_dbus_is_name (name))
725     {
726       g_set_error (error,
727                    G_DBUS_ERROR,
728                    G_DBUS_ERROR_INVALID_ARGS,
729                    "Given bus name \"%s\" is not valid", name);
730       return NULL;
731     }
732
733   if (*name == ':')
734     {
735       g_set_error (error,
736                    G_DBUS_ERROR,
737                    G_DBUS_ERROR_INVALID_ARGS,
738                    "Cannot release a service starting with ':' such as \"%s\"", name);
739       return NULL;
740     }
741
742   len = strlen(name) + 1;
743   size = G_STRUCT_OFFSET (struct kdbus_cmd_name, items) + KDBUS_ITEM_SIZE(len);
744   kdbus_name = g_alloca0 (size);
745   kdbus_name->size = size;
746   kdbus_name->items[0].size = KDBUS_ITEM_HEADER_SIZE + len;
747   kdbus_name->items[0].type = KDBUS_ITEM_NAME;
748   memcpy (kdbus_name->items[0].str, name, len);
749
750   ret = ioctl(kdbus->priv->fd, KDBUS_CMD_NAME_RELEASE, kdbus_name);
751   if (ret < 0)
752     {
753       if (errno == ESRCH)
754         status = G_BUS_RELEASE_NAME_FLAGS_NON_EXISTENT;
755       else if (errno == EADDRINUSE)
756         status = G_BUS_RELEASE_NAME_FLAGS_NOT_OWNER;
757       else
758         {
759           g_set_error (error, G_IO_ERROR,
760                        g_io_error_from_errno (errno),
761                        _("Error while releasing name: %s"),
762                        g_strerror (errno));
763           return NULL;
764         }
765     }
766
767   result = g_variant_new ("(u)", status);
768
769   return result;
770 }
771
772
773 /**
774  * _g_kdbus_GetBusId:
775  *
776  */
777 GVariant *
778 _g_kdbus_GetBusId (GDBusConnection  *connection,
779                    GError          **error)
780 {
781   GKdbus   *kdbus;
782   GVariant *result;
783   GString  *result_str;
784   guint     cnt;
785
786   result_str = g_string_new (NULL);
787   kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
788   if (kdbus == NULL)
789     {
790       g_set_error_literal (error,
791                            G_DBUS_ERROR,
792                            G_DBUS_ERROR_IO_ERROR,
793                            _("The connection is closed"));
794       g_string_free (result_str, TRUE);
795       return NULL;
796     }
797
798   for (cnt=0; cnt<16; cnt++)
799     g_string_append_printf (result_str, "%02x", kdbus->priv->bus_id[cnt]);
800
801   result = g_variant_new ("(s)", result_str->str);
802   g_string_free (result_str, TRUE);
803
804   return result;
805 }
806
807
808 /**
809  * _g_kdbus_GetListNames:
810  *
811  */
812 GVariant *
813 _g_kdbus_GetListNames (GDBusConnection  *connection,
814                        guint             list_name_type,
815                        GError          **error)
816 {
817   GKdbus *kdbus;
818   GVariant *result;
819   GVariantBuilder *builder;
820
821   struct kdbus_cmd_name_list cmd = {};
822   struct kdbus_name_list *name_list;
823   struct kdbus_cmd_name *name;
824
825   guint64 prev_id;
826   gint ret;
827
828   prev_id = 0;
829   kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
830   if (kdbus == NULL)
831     {
832       g_set_error_literal (error,
833                            G_DBUS_ERROR,
834                            G_DBUS_ERROR_IO_ERROR,
835                            _("The connection is closed"));
836       return NULL;
837     }
838
839   if (list_name_type)
840     cmd.flags = KDBUS_NAME_LIST_ACTIVATORS;                     /* ListActivatableNames */
841   else
842     cmd.flags = KDBUS_NAME_LIST_UNIQUE | KDBUS_NAME_LIST_NAMES; /* ListNames */
843
844   ret = ioctl(kdbus->priv->fd, KDBUS_CMD_NAME_LIST, &cmd);
845   if (ret < 0)
846     {
847       g_set_error (error,
848                    G_DBUS_ERROR,
849                    G_DBUS_ERROR_FAILED,
850                    _("Error listing names"));
851       return NULL;
852     }
853
854   name_list = (struct kdbus_name_list *) ((guint8 *) kdbus->priv->kdbus_buffer + cmd.offset);
855   builder = g_variant_builder_new (G_VARIANT_TYPE ("as"));
856
857   KDBUS_ITEM_FOREACH(name, name_list, names)
858     {
859       struct kdbus_item *item;
860       const gchar *item_name = "";
861
862       if ((cmd.flags & KDBUS_NAME_LIST_UNIQUE) && name->owner_id != prev_id)
863         {
864           GString *unique_name;
865
866           unique_name = g_string_new (NULL);
867           g_string_printf (unique_name, ":1.%llu", name->owner_id);
868           g_variant_builder_add (builder, "s", unique_name->str);
869           g_string_free (unique_name,TRUE);
870           prev_id = name->owner_id;
871         }
872
873        KDBUS_ITEM_FOREACH(item, name, items)
874          if (item->type == KDBUS_ITEM_NAME)
875            item_name = item->str;
876
877         if (g_dbus_is_name (item_name))
878           g_variant_builder_add (builder, "s", item_name);
879     }
880
881   result = g_variant_new ("(as)", builder);
882   g_variant_builder_unref (builder);
883
884   g_kdbus_free_data (kdbus, cmd.offset);
885   return result;
886 }
887
888
889 /**
890  * _g_kdbus_NameHasOwner_internal:
891  *
892  */
893 static gboolean
894 g_kdbus_NameHasOwner_internal (GKdbus       *kdbus,
895                                const gchar  *name,
896                                GError      **error)
897 {
898   struct kdbus_cmd_conn_info *cmd;
899   gssize size, len;
900   gint ret;
901
902   if (g_dbus_is_unique_name(name))
903     {
904        size = G_STRUCT_OFFSET (struct kdbus_cmd_conn_info, items);
905        cmd = g_alloca0 (size);
906        cmd->id = g_ascii_strtoull (name+3, NULL, 10);
907     }
908   else
909     {
910        len = strlen(name) + 1;
911        size = G_STRUCT_OFFSET (struct kdbus_cmd_conn_info, items) + KDBUS_ITEM_SIZE(len);
912        cmd = g_alloca0 (size);
913        cmd->items[0].size = KDBUS_ITEM_HEADER_SIZE + len;
914        cmd->items[0].type = KDBUS_ITEM_NAME;
915        memcpy (cmd->items[0].str, name, len);
916     }
917   cmd->size = size;
918
919   ret = ioctl(kdbus->priv->fd, KDBUS_CMD_CONN_INFO, cmd);
920   g_kdbus_free_data (kdbus, cmd->offset);
921
922   if (ret < 0)
923     return FALSE;
924   else
925     return TRUE;
926 }
927
928
929 /**
930  * _g_kdbus_GetListQueuedOwners:
931  *
932  */
933 GVariant *
934 _g_kdbus_GetListQueuedOwners (GDBusConnection  *connection,
935                               const gchar      *name,
936                               GError          **error)
937 {
938   GKdbus *kdbus;
939   GVariant *result;
940   GVariantBuilder *builder;
941   GString *unique_name;
942   gint ret;
943
944   struct kdbus_cmd_name_list cmd = {};
945   struct kdbus_name_list *name_list;
946   struct kdbus_cmd_name *kname;
947
948   kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
949   if (kdbus == NULL)
950     {
951       g_set_error_literal (error,
952                            G_DBUS_ERROR,
953                            G_DBUS_ERROR_IO_ERROR,
954                            _("The connection is closed"));
955       return NULL;
956     }
957
958   if (!g_dbus_is_name (name))
959     {
960       g_set_error (error,
961                    G_DBUS_ERROR,
962                    G_DBUS_ERROR_INVALID_ARGS,
963                    "Given bus name \"%s\" is not valid", name);
964       return NULL;
965     }
966
967   if (!g_kdbus_NameHasOwner_internal (kdbus, name, error))
968     {
969       g_set_error (error,
970                    G_DBUS_ERROR,
971                    G_DBUS_ERROR_NAME_HAS_NO_OWNER,
972                    "Could not get owner of name '%s': no such name", name);
973       return NULL;
974     }
975
976   cmd.flags = KDBUS_NAME_LIST_QUEUED;
977   ret = ioctl(kdbus->priv->fd, KDBUS_CMD_NAME_LIST, &cmd);
978   if (ret < 0)
979     {
980       g_set_error (error,
981                    G_DBUS_ERROR,
982                    G_DBUS_ERROR_FAILED,
983                    _("Error listing names"));
984       return NULL;
985     }
986
987   name_list = (struct kdbus_name_list *) ((guint8 *) kdbus->priv->kdbus_buffer + cmd.offset);
988
989   unique_name = g_string_new (NULL);
990   builder = g_variant_builder_new (G_VARIANT_TYPE ("as"));
991   KDBUS_ITEM_FOREACH(kname, name_list, names)
992     {
993       struct kdbus_item *item;
994       const char *item_name = "";
995
996       KDBUS_ITEM_FOREACH(item, kname, items)
997         if (item->type == KDBUS_ITEM_NAME)
998           item_name = item->str;
999
1000       if (strcmp(item_name, name))
1001         continue;
1002
1003       g_string_printf (unique_name, ":1.%llu", kname->owner_id);
1004       g_variant_builder_add (builder, "s", item_name);
1005     }
1006
1007   result = g_variant_new ("(as)", builder);
1008   g_variant_builder_unref (builder);
1009   g_string_free (unique_name,TRUE);
1010
1011   g_kdbus_free_data (kdbus, cmd.offset);
1012   return result;
1013 }
1014
1015
1016 /**
1017  * _g_kdbus_NameHasOwner:
1018  *
1019  */
1020 GVariant *
1021 _g_kdbus_NameHasOwner (GDBusConnection  *connection,
1022                        const gchar      *name,
1023                        GError          **error)
1024 {
1025   GKdbus *kdbus;
1026   GVariant *result;
1027
1028   kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
1029   if (kdbus == NULL)
1030     {
1031       g_set_error_literal (error,
1032                            G_DBUS_ERROR,
1033                            G_DBUS_ERROR_IO_ERROR,
1034                            _("The connection is closed"));
1035       return NULL;
1036     }
1037
1038   if (!g_dbus_is_name (name))
1039     {
1040       g_set_error (error,
1041                    G_DBUS_ERROR,
1042                    G_DBUS_ERROR_INVALID_ARGS,
1043                    "Given bus name \"%s\" is not valid", name);
1044       return NULL;
1045     }
1046
1047   if (!g_kdbus_NameHasOwner_internal (kdbus, name, error))
1048     result = g_variant_new ("(b)", FALSE);
1049   else
1050     result = g_variant_new ("(b)", TRUE);
1051
1052   return result;
1053 }
1054
1055
1056 /**
1057  * g_kdbus_GetConnInfo_internal:
1058  *
1059  */
1060 static GVariant *
1061 g_kdbus_GetConnInfo_internal (GDBusConnection  *connection,
1062                               const gchar      *name,
1063                               guint64           flag,
1064                               GError          **error)
1065 {
1066   GKdbus *kdbus;
1067   GVariant *result;
1068
1069   struct kdbus_cmd_conn_info *cmd;
1070   struct kdbus_conn_info *conn_info;
1071   struct kdbus_item *item;
1072   gssize size, len;
1073   gint ret;
1074
1075   result = NULL;
1076   kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
1077   if (kdbus == NULL)
1078     {
1079       g_set_error_literal (error,
1080                            G_DBUS_ERROR,
1081                            G_DBUS_ERROR_IO_ERROR,
1082                            _("The connection is closed"));
1083       return NULL;
1084     }
1085
1086   if (!g_dbus_is_name (name))
1087     {
1088       g_set_error (error,
1089                    G_DBUS_ERROR,
1090                    G_DBUS_ERROR_INVALID_ARGS,
1091                    "Given bus name \"%s\" is not valid", name);
1092       return NULL;
1093     }
1094
1095   if (!g_kdbus_NameHasOwner_internal (kdbus, name, error))
1096     {
1097       g_set_error (error,
1098                    G_DBUS_ERROR,
1099                    G_DBUS_ERROR_NAME_HAS_NO_OWNER,
1100                    "Could not get owner of name '%s': no such name", name);
1101       return NULL;
1102     }
1103
1104   if (g_dbus_is_unique_name(name))
1105     {
1106        size = G_STRUCT_OFFSET (struct kdbus_cmd_conn_info, items);
1107        cmd = g_alloca0 (size);
1108        cmd->id = g_ascii_strtoull (name+3, NULL, 10);
1109     }
1110   else
1111     {
1112        len = strlen(name) + 1;
1113        size = G_STRUCT_OFFSET (struct kdbus_cmd_conn_info, items) + KDBUS_ITEM_SIZE(len);
1114        cmd = g_alloca0 (size);
1115        cmd->items[0].size = KDBUS_ITEM_HEADER_SIZE + len;
1116        cmd->items[0].type = KDBUS_ITEM_NAME;
1117        memcpy (cmd->items[0].str, name, len);
1118     }
1119
1120   cmd->flags = KDBUS_ATTACH_NAMES;
1121   cmd->size = size;
1122
1123   ret = ioctl(kdbus->priv->fd, KDBUS_CMD_CONN_INFO, cmd);
1124   if (ret < 0)
1125     {
1126       g_set_error (error,
1127                    G_DBUS_ERROR,
1128                    G_DBUS_ERROR_FAILED,
1129                    _("Could not get connection info"));
1130       return NULL;
1131     }
1132
1133   conn_info = (struct kdbus_conn_info *) ((guint8 *) kdbus->priv->kdbus_buffer + cmd->offset);
1134
1135   /*
1136   if (conn_info->flags & KDBUS_HELLO_ACTIVATOR)
1137     {}
1138   */
1139
1140   if (flag == G_BUS_CREDS_UNIQUE_NAME)
1141     {
1142        GString *unique_name;
1143
1144        unique_name = g_string_new (NULL);
1145        g_string_printf (unique_name, ":1.%llu", (unsigned long long) conn_info->id);
1146        result = g_variant_new ("(s)", unique_name->str);
1147        g_string_free (unique_name,TRUE);
1148        goto exit;
1149     }
1150
1151   KDBUS_ITEM_FOREACH(item, conn_info, items)
1152    {
1153       switch (item->type)
1154         {
1155           case KDBUS_ITEM_CREDS:
1156
1157             if (flag == G_BUS_CREDS_PID)
1158               {
1159                 guint pid = item->creds.pid;
1160                 result = g_variant_new ("(u)", pid);
1161                 goto exit;
1162                }
1163
1164             if (flag == G_BUS_CREDS_UID)
1165               {
1166                 guint uid = item->creds.uid;
1167                 result = g_variant_new ("(u)", uid);
1168                 goto exit;
1169               }
1170
1171           case KDBUS_ITEM_SECLABEL:
1172           case KDBUS_ITEM_PID_COMM:
1173           case KDBUS_ITEM_TID_COMM:
1174           case KDBUS_ITEM_EXE:
1175           case KDBUS_ITEM_CMDLINE:
1176           case KDBUS_ITEM_CGROUP:
1177           case KDBUS_ITEM_CAPS:
1178           case KDBUS_ITEM_NAME:
1179           case KDBUS_ITEM_AUDIT:
1180             break;
1181         }
1182    }
1183
1184 exit:
1185   g_kdbus_free_data (kdbus, cmd->offset);
1186   return result;
1187 }
1188
1189
1190 /**
1191  * _g_kdbus_GetNameOwner:
1192  *
1193  */
1194 GVariant *
1195 _g_kdbus_GetNameOwner (GDBusConnection  *connection,
1196                        const gchar      *name,
1197                        GError          **error)
1198 {
1199   return g_kdbus_GetConnInfo_internal (connection,
1200                                        name,
1201                                        G_BUS_CREDS_UNIQUE_NAME,
1202                                        error);
1203 }
1204
1205
1206 /**
1207  * _g_kdbus_GetConnectionUnixProcessID:
1208  *
1209  */
1210 GVariant *
1211 _g_kdbus_GetConnectionUnixProcessID (GDBusConnection  *connection,
1212                                      const gchar      *name,
1213                                      GError          **error)
1214 {
1215   return g_kdbus_GetConnInfo_internal (connection,
1216                                        name,
1217                                        G_BUS_CREDS_PID,
1218                                        error);
1219 }
1220
1221
1222 /**
1223  * _g_kdbus_GetConnectionUnixUser:
1224  *
1225  */
1226 GVariant *
1227 _g_kdbus_GetConnectionUnixUser (GDBusConnection  *connection,
1228                                 const gchar      *name,
1229                                 GError          **error)
1230 {
1231   return g_kdbus_GetConnInfo_internal (connection,
1232                                        name,
1233                                        G_BUS_CREDS_UID,
1234                                        error);
1235 }
1236
1237
1238 /*
1239  * _g_kdbus_subscribe_name_acquired:
1240  *
1241  */
1242 static void
1243 _g_kdbus_subscribe_name_owner_changed (GDBusConnection  *connection,
1244                                        const gchar      *name,
1245                                        const gchar      *old_name,
1246                                        const gchar      *new_name,
1247                                        guint             cookie)
1248 {
1249   GKdbus *kdbus;
1250   struct kdbus_item *item;
1251   struct kdbus_cmd_match *cmd_match;
1252   gssize size, len;
1253   gint ret;
1254   guint64 old_id;
1255   guint64 new_id = KDBUS_MATCH_ID_ANY;
1256
1257   kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
1258
1259   len = strlen(name) + 1;
1260   size = KDBUS_ALIGN8(G_STRUCT_OFFSET (struct kdbus_cmd_match, items) +
1261                       G_STRUCT_OFFSET (struct kdbus_item, name_change) +
1262                       G_STRUCT_OFFSET (struct kdbus_notify_name_change, name) + len);
1263
1264   cmd_match = g_alloca0 (size);
1265   cmd_match->size = size;
1266   cmd_match->cookie = cookie;
1267   item = cmd_match->items;
1268
1269   if (old_name[0] == 0)
1270     {
1271       old_id = KDBUS_MATCH_ID_ANY;
1272     }
1273   else
1274     {
1275       if (g_dbus_is_unique_name(old_name))
1276         old_id = old_id+3;
1277       else
1278         return;
1279     }
1280
1281   if (new_name[0] == 0)
1282     {
1283       new_id = KDBUS_MATCH_ID_ANY;
1284     }
1285   else
1286     {
1287       if (g_dbus_is_unique_name(new_name))
1288         new_id = new_id+3;
1289       else
1290         return;
1291     }
1292
1293   cmd_match = g_alloca0 (size);
1294   cmd_match->size = size;
1295   cmd_match->cookie = cookie;
1296   item = cmd_match->items;
1297
1298   /* KDBUS_ITEM_NAME_CHANGE */
1299   item->type = KDBUS_ITEM_NAME_CHANGE;
1300   item->name_change.old_id.id = old_id;
1301   item->name_change.new_id.id = new_id;
1302   memcpy(item->name_change.name, name, len);
1303   item->size = G_STRUCT_OFFSET (struct kdbus_item, name_change) +
1304                G_STRUCT_OFFSET(struct kdbus_notify_name_change, name) + len;
1305   item = KDBUS_ITEM_NEXT(item);
1306
1307   ret = ioctl(kdbus->priv->fd, KDBUS_CMD_MATCH_ADD, cmd_match);
1308   if (ret < 0)
1309     g_warning ("ERROR - %d\n", (int) errno);
1310 }
1311
1312
1313 /*
1314  * _g_kdbus_subscribe_name_acquired:
1315  *
1316  */
1317 void
1318 _g_kdbus_subscribe_name_acquired (GDBusConnection  *connection,
1319                                   const gchar      *name)
1320 {
1321   GKdbus *kdbus;
1322   struct kdbus_item *item;
1323   struct kdbus_cmd_match *cmd_match;
1324   gssize size, len;
1325   guint64 cookie;
1326   gint ret;
1327
1328   kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
1329
1330   len = strlen(name) + 1;
1331   size = KDBUS_ALIGN8(G_STRUCT_OFFSET (struct kdbus_cmd_match, items) +
1332                       G_STRUCT_OFFSET (struct kdbus_item, name_change) +
1333                       G_STRUCT_OFFSET (struct kdbus_notify_name_change, name) + len);
1334
1335   cookie = 0xbeefbeefbeefbeef;
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_ADD */
1342   item->type = KDBUS_ITEM_NAME_ADD;
1343   item->name_change.old_id.id = KDBUS_MATCH_ID_ANY;
1344   item->name_change.new_id.id = kdbus->priv->unique_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   _g_kdbus_subscribe_name_owner_changed (connection, name, "", kdbus->priv->unique_name, cookie);
1355 }
1356
1357
1358 /*
1359  * _g_kdbus_subscribe_name_lost:
1360  *
1361  */
1362 void
1363 _g_kdbus_subscribe_name_lost (GDBusConnection  *connection,
1364                               const gchar      *name)
1365 {
1366   GKdbus *kdbus;
1367   struct kdbus_item *item;
1368   struct kdbus_cmd_match *cmd_match;
1369   gssize size, len;
1370   guint64 cookie;
1371   gint ret;
1372
1373   kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
1374
1375   len = strlen(name) + 1;
1376   size = KDBUS_ALIGN8(G_STRUCT_OFFSET (struct kdbus_cmd_match, items) +
1377                       G_STRUCT_OFFSET (struct kdbus_item, name_change) +
1378                       G_STRUCT_OFFSET (struct kdbus_notify_name_change, name) + len);
1379
1380   cookie = 0xdeafdeafdeafdeaf;
1381   cmd_match = g_alloca0 (size);
1382   cmd_match->size = size;
1383   cmd_match->cookie = cookie;
1384   item = cmd_match->items;
1385
1386   /* KDBUS_ITEM_NAME_REMOVE */
1387   item->type = KDBUS_ITEM_NAME_REMOVE;
1388   item->name_change.old_id.id = kdbus->priv->unique_id;
1389   item->name_change.new_id.id = KDBUS_MATCH_ID_ANY;
1390   memcpy(item->name_change.name, name, len);
1391   item->size = G_STRUCT_OFFSET (struct kdbus_item, name_change) +
1392                G_STRUCT_OFFSET(struct kdbus_notify_name_change, name) + len;
1393   item = KDBUS_ITEM_NEXT(item);
1394
1395   ret = ioctl(kdbus->priv->fd, KDBUS_CMD_MATCH_ADD, cmd_match);
1396   if (ret < 0)
1397     g_warning ("ERROR - %d\n", (int) errno);
1398
1399   _g_kdbus_subscribe_name_owner_changed (connection, name, kdbus->priv->unique_name, "", cookie);
1400 }
1401
1402
1403 /**
1404 * g_kdbus_decode_kernel_msg:
1405 *
1406 */
1407 static gssize
1408 g_kdbus_decode_kernel_msg (GKdbus  *kdbus)
1409 {
1410   struct kdbus_item *item = NULL;
1411   gssize size = 0;
1412
1413   KDBUS_ITEM_FOREACH(item, kdbus->priv->kmsg, items)
1414     {
1415      switch (item->type)
1416         {
1417           case KDBUS_ITEM_ID_ADD:
1418           case KDBUS_ITEM_ID_REMOVE:
1419           case KDBUS_ITEM_NAME_ADD:
1420           case KDBUS_ITEM_NAME_REMOVE:
1421           case KDBUS_ITEM_NAME_CHANGE:
1422             //size = g_kdbus_NameOwnerChanged_generate (kdbus, item);
1423             g_error ("'NameOwnerChanged'");
1424             break;
1425
1426           case KDBUS_ITEM_REPLY_TIMEOUT:
1427           case KDBUS_ITEM_REPLY_DEAD:
1428             //size = g_kdbus_KernelMethodError_generate (kdbus, item);
1429             g_error ("'KernelMethodError'");
1430             break;
1431
1432           default:
1433             g_warning ("Unknown field in kernel message - %lld", item->type);
1434        }
1435     }
1436
1437 #if 0
1438   /* Override information from the user header with data from the kernel */
1439   g_string_printf (kdbus->priv->msg_sender, "org.freedesktop.DBus");
1440
1441   /* for destination */
1442   if (kdbus->priv->kmsg->dst_id == KDBUS_DST_ID_BROADCAST)
1443     /* for broadcast messages we don't have to set destination */
1444     ;
1445   else if (kdbus->priv->kmsg->dst_id == KDBUS_DST_ID_NAME)
1446     g_string_printf (kdbus->priv->msg_destination, ":1.%" G_GUINT64_FORMAT, (guint64) kdbus->priv->unique_id);
1447   else
1448    g_string_printf (kdbus->priv->msg_destination, ":1.%" G_GUINT64_FORMAT, (guint64) kdbus->priv->kmsg->dst_id);
1449 #endif
1450
1451   return size;
1452 }
1453
1454
1455 /**
1456  * _g_kdbus_receive:
1457  *
1458  */
1459 gssize
1460 _g_kdbus_receive (GKdbus        *kdbus,
1461                   GCancellable  *cancellable,
1462                   GError       **error)
1463 {
1464   struct kdbus_cmd_recv recv = {};
1465   gssize size = 0;
1466
1467   if (g_cancellable_set_error_if_cancelled (cancellable, error))
1468     return -1;
1469
1470 again:
1471     if (ioctl(kdbus->priv->fd, KDBUS_CMD_MSG_RECV, &recv) < 0)
1472       {
1473         if (errno == EINTR || errno == EAGAIN)
1474           goto again;
1475
1476         g_set_error (error, G_IO_ERROR,
1477                      g_io_error_from_errno (errno),
1478                      _("Error while receiving message: %s"),
1479                      g_strerror (errno));
1480         return -1;
1481       }
1482
1483    kdbus->priv->kmsg = (struct kdbus_msg *)((guint8 *)kdbus->priv->kdbus_buffer + recv.offset);
1484
1485    if (kdbus->priv->kmsg->payload_type == KDBUS_PAYLOAD_DBUS)
1486      g_error ("Received standard dbus message - not supported yet");
1487    else if (kdbus->priv->kmsg->payload_type == KDBUS_PAYLOAD_KERNEL)
1488      size = g_kdbus_decode_kernel_msg (kdbus);
1489    else
1490      {
1491        g_set_error (error,
1492                     G_DBUS_ERROR,
1493                     G_DBUS_ERROR_FAILED,
1494                     _("Received unknown payload type"));
1495        return -1;
1496      }
1497
1498    return size;
1499 }