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