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