[kdbus] sync with kdbus (kdbus.h - commit: 5ae1ecac44cb)
[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_NameHasOwner:
1021  *
1022  */
1023 GVariant *
1024 _g_kdbus_NameHasOwner (GDBusConnection  *connection,
1025                        const gchar      *name,
1026                        GError          **error)
1027 {
1028   GKdbus *kdbus;
1029   GVariant *result;
1030
1031   kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
1032   if (kdbus == NULL)
1033     {
1034       g_set_error_literal (error,
1035                            G_DBUS_ERROR,
1036                            G_DBUS_ERROR_IO_ERROR,
1037                            _("The connection is closed"));
1038       return NULL;
1039     }
1040
1041   if (!g_dbus_is_name (name))
1042     {
1043       g_set_error (error,
1044                    G_DBUS_ERROR,
1045                    G_DBUS_ERROR_INVALID_ARGS,
1046                    "Given bus name \"%s\" is not valid", name);
1047       return NULL;
1048     }
1049
1050   if (!g_kdbus_NameHasOwner_internal (kdbus, name, error))
1051     result = g_variant_new ("(b)", FALSE);
1052   else
1053     result = g_variant_new ("(b)", TRUE);
1054
1055   return result;
1056 }
1057
1058
1059 /**
1060  * g_kdbus_GetConnInfo_internal:
1061  *
1062  */
1063 static GVariant *
1064 g_kdbus_GetConnInfo_internal (GDBusConnection  *connection,
1065                               const gchar      *name,
1066                               guint64           flag,
1067                               GError          **error)
1068 {
1069   GKdbus *kdbus;
1070   GVariant *result;
1071
1072   struct kdbus_cmd_info *cmd;
1073   struct kdbus_info *conn_info;
1074   struct kdbus_item *item;
1075   gssize size, len;
1076   gint ret;
1077
1078   result = NULL;
1079   kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
1080   if (kdbus == NULL)
1081     {
1082       g_set_error_literal (error,
1083                            G_DBUS_ERROR,
1084                            G_DBUS_ERROR_IO_ERROR,
1085                            _("The connection is closed"));
1086       return NULL;
1087     }
1088
1089   if (!g_dbus_is_name (name))
1090     {
1091       g_set_error (error,
1092                    G_DBUS_ERROR,
1093                    G_DBUS_ERROR_INVALID_ARGS,
1094                    "Given bus name \"%s\" is not valid", name);
1095       return NULL;
1096     }
1097
1098   if (!g_kdbus_NameHasOwner_internal (kdbus, name, error))
1099     {
1100       g_set_error (error,
1101                    G_DBUS_ERROR,
1102                    G_DBUS_ERROR_NAME_HAS_NO_OWNER,
1103                    "Could not get owner of name '%s': no such name", name);
1104       return NULL;
1105     }
1106
1107   if (g_dbus_is_unique_name(name))
1108     {
1109        size = G_STRUCT_OFFSET (struct kdbus_cmd_info, items);
1110        cmd = g_alloca0 (size);
1111        cmd->id = g_ascii_strtoull (name+3, NULL, 10);
1112     }
1113   else
1114     {
1115        len = strlen(name) + 1;
1116        size = G_STRUCT_OFFSET (struct kdbus_cmd_info, items) + KDBUS_ITEM_SIZE(len);
1117        cmd = g_alloca0 (size);
1118        cmd->items[0].size = KDBUS_ITEM_HEADER_SIZE + len;
1119        cmd->items[0].type = KDBUS_ITEM_NAME;
1120        memcpy (cmd->items[0].str, name, len);
1121     }
1122
1123   cmd->flags = _KDBUS_ATTACH_ALL;
1124   cmd->size = size;
1125
1126   ret = ioctl(kdbus->priv->fd, KDBUS_CMD_CONN_INFO, cmd);
1127   if (ret < 0)
1128     {
1129       g_set_error (error,
1130                    G_DBUS_ERROR,
1131                    G_DBUS_ERROR_FAILED,
1132                    _("Could not get connection info"));
1133       return NULL;
1134     }
1135
1136   conn_info = (struct kdbus_info *) ((guint8 *) kdbus->priv->kdbus_buffer + cmd->offset);
1137
1138   /*
1139   if (conn_info->flags & KDBUS_HELLO_ACTIVATOR)
1140     {}
1141   */
1142
1143   if (flag == G_BUS_CREDS_UNIQUE_NAME)
1144     {
1145        GString *unique_name;
1146
1147        unique_name = g_string_new (NULL);
1148        g_string_printf (unique_name, ":1.%llu", (unsigned long long) conn_info->id);
1149        result = g_variant_new ("(s)", unique_name->str);
1150        g_string_free (unique_name,TRUE);
1151        goto exit;
1152     }
1153
1154   KDBUS_ITEM_FOREACH(item, conn_info, items)
1155    {
1156       switch (item->type)
1157         {
1158           case KDBUS_ITEM_CREDS:
1159
1160             if (flag == G_BUS_CREDS_PID)
1161               {
1162                 guint pid = item->creds.pid;
1163                 result = g_variant_new ("(u)", pid);
1164                 goto exit;
1165                }
1166
1167             if (flag == G_BUS_CREDS_UID)
1168               {
1169                 guint uid = item->creds.uid;
1170                 result = g_variant_new ("(u)", uid);
1171                 goto exit;
1172               }
1173
1174           case KDBUS_ITEM_SECLABEL:
1175           case KDBUS_ITEM_PID_COMM:
1176           case KDBUS_ITEM_TID_COMM:
1177           case KDBUS_ITEM_EXE:
1178           case KDBUS_ITEM_CMDLINE:
1179           case KDBUS_ITEM_CGROUP:
1180           case KDBUS_ITEM_CAPS:
1181           case KDBUS_ITEM_NAME:
1182           case KDBUS_ITEM_AUDIT:
1183             break;
1184         }
1185    }
1186
1187 exit:
1188   g_kdbus_free_data (kdbus, cmd->offset);
1189   return result;
1190 }
1191
1192
1193 /**
1194  * _g_kdbus_GetNameOwner:
1195  *
1196  */
1197 GVariant *
1198 _g_kdbus_GetNameOwner (GDBusConnection  *connection,
1199                        const gchar      *name,
1200                        GError          **error)
1201 {
1202   return g_kdbus_GetConnInfo_internal (connection,
1203                                        name,
1204                                        G_BUS_CREDS_UNIQUE_NAME,
1205                                        error);
1206 }
1207
1208
1209 /**
1210  * _g_kdbus_GetConnectionUnixProcessID:
1211  *
1212  */
1213 GVariant *
1214 _g_kdbus_GetConnectionUnixProcessID (GDBusConnection  *connection,
1215                                      const gchar      *name,
1216                                      GError          **error)
1217 {
1218   return g_kdbus_GetConnInfo_internal (connection,
1219                                        name,
1220                                        G_BUS_CREDS_PID,
1221                                        error);
1222 }
1223
1224
1225 /**
1226  * _g_kdbus_GetConnectionUnixUser:
1227  *
1228  */
1229 GVariant *
1230 _g_kdbus_GetConnectionUnixUser (GDBusConnection  *connection,
1231                                 const gchar      *name,
1232                                 GError          **error)
1233 {
1234   return g_kdbus_GetConnInfo_internal (connection,
1235                                        name,
1236                                        G_BUS_CREDS_UID,
1237                                        error);
1238 }
1239
1240
1241 /*
1242  * _g_kdbus_match_remove:
1243  *
1244  */
1245 static void
1246 _g_kdbus_match_remove (GDBusConnection  *connection,
1247                        guint             cookie)
1248 {
1249   GKdbus *kdbus;
1250   struct kdbus_cmd_match cmd_match = {};
1251   gint ret;
1252
1253   kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
1254
1255   cmd_match.size = sizeof (cmd_match);
1256   cmd_match.cookie = cookie;
1257
1258   ret = ioctl(kdbus->priv->fd, KDBUS_CMD_MATCH_REMOVE, &cmd_match);
1259   if (ret < 0)
1260     g_warning ("ERROR - %d\n", (int) errno);
1261 }
1262
1263
1264 /*
1265  * _g_kdbus_subscribe_name_acquired:
1266  *
1267  */
1268 static void
1269 _g_kdbus_subscribe_name_owner_changed (GDBusConnection  *connection,
1270                                        const gchar      *name,
1271                                        const gchar      *old_name,
1272                                        const gchar      *new_name,
1273                                        guint             cookie)
1274 {
1275   GKdbus *kdbus;
1276   struct kdbus_item *item;
1277   struct kdbus_cmd_match *cmd_match;
1278   gssize size, len;
1279   gint ret;
1280   guint64 old_id;
1281   guint64 new_id = KDBUS_MATCH_ID_ANY;
1282
1283   kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
1284
1285   len = strlen(name) + 1;
1286   size = KDBUS_ALIGN8(G_STRUCT_OFFSET (struct kdbus_cmd_match, items) +
1287                       G_STRUCT_OFFSET (struct kdbus_item, name_change) +
1288                       G_STRUCT_OFFSET (struct kdbus_notify_name_change, name) + len);
1289
1290   cmd_match = g_alloca0 (size);
1291   cmd_match->size = size;
1292   cmd_match->cookie = cookie;
1293   item = cmd_match->items;
1294
1295   if (old_name[0] == 0)
1296     {
1297       old_id = KDBUS_MATCH_ID_ANY;
1298     }
1299   else
1300     {
1301       if (g_dbus_is_unique_name(old_name))
1302         old_id = old_id+3;
1303       else
1304         return;
1305     }
1306
1307   if (new_name[0] == 0)
1308     {
1309       new_id = KDBUS_MATCH_ID_ANY;
1310     }
1311   else
1312     {
1313       if (g_dbus_is_unique_name(new_name))
1314         new_id = new_id+3;
1315       else
1316         return;
1317     }
1318
1319   cmd_match = g_alloca0 (size);
1320   cmd_match->size = size;
1321   cmd_match->cookie = cookie;
1322   item = cmd_match->items;
1323
1324   /* KDBUS_ITEM_NAME_CHANGE */
1325   item->type = KDBUS_ITEM_NAME_CHANGE;
1326   item->name_change.old_id.id = old_id;
1327   item->name_change.new_id.id = new_id;
1328   memcpy(item->name_change.name, name, len);
1329   item->size = G_STRUCT_OFFSET (struct kdbus_item, name_change) +
1330                G_STRUCT_OFFSET(struct kdbus_notify_name_change, name) + len;
1331   item = KDBUS_ITEM_NEXT(item);
1332
1333   ret = ioctl(kdbus->priv->fd, KDBUS_CMD_MATCH_ADD, cmd_match);
1334   if (ret < 0)
1335     g_warning ("ERROR - %d\n", (int) errno);
1336 }
1337
1338
1339 /*
1340  * _g_kdbus_subscribe_name_acquired:
1341  *
1342  */
1343 void
1344 _g_kdbus_subscribe_name_acquired (GDBusConnection  *connection,
1345                                   const gchar      *name)
1346 {
1347   GKdbus *kdbus;
1348   struct kdbus_item *item;
1349   struct kdbus_cmd_match *cmd_match;
1350   gssize size, len;
1351   guint64 cookie;
1352   gint ret;
1353
1354   kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
1355
1356   len = strlen(name) + 1;
1357   size = KDBUS_ALIGN8(G_STRUCT_OFFSET (struct kdbus_cmd_match, items) +
1358                       G_STRUCT_OFFSET (struct kdbus_item, name_change) +
1359                       G_STRUCT_OFFSET (struct kdbus_notify_name_change, name) + len);
1360
1361   cookie = 0xbeefbeefbeefbeef;
1362   cmd_match = g_alloca0 (size);
1363   cmd_match->size = size;
1364   cmd_match->cookie = cookie;
1365   item = cmd_match->items;
1366
1367   /* KDBUS_ITEM_NAME_ADD */
1368   item->type = KDBUS_ITEM_NAME_ADD;
1369   item->name_change.old_id.id = KDBUS_MATCH_ID_ANY;
1370   item->name_change.new_id.id = kdbus->priv->unique_id;
1371   memcpy(item->name_change.name, name, len);
1372   item->size = G_STRUCT_OFFSET (struct kdbus_item, name_change) +
1373                G_STRUCT_OFFSET(struct kdbus_notify_name_change, name) + len;
1374   item = KDBUS_ITEM_NEXT(item);
1375
1376   ret = ioctl(kdbus->priv->fd, KDBUS_CMD_MATCH_ADD, cmd_match);
1377   if (ret < 0)
1378     g_warning ("ERROR - %d\n", (int) errno);
1379
1380   _g_kdbus_subscribe_name_owner_changed (connection, name, "", kdbus->priv->unique_name, cookie);
1381 }
1382
1383
1384 /*
1385  * _g_kdbus_subscribe_name_lost:
1386  *
1387  */
1388 void
1389 _g_kdbus_subscribe_name_lost (GDBusConnection  *connection,
1390                               const gchar      *name)
1391 {
1392   GKdbus *kdbus;
1393   struct kdbus_item *item;
1394   struct kdbus_cmd_match *cmd_match;
1395   gssize size, len;
1396   guint64 cookie;
1397   gint ret;
1398
1399   kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
1400
1401   len = strlen(name) + 1;
1402   size = KDBUS_ALIGN8(G_STRUCT_OFFSET (struct kdbus_cmd_match, items) +
1403                       G_STRUCT_OFFSET (struct kdbus_item, name_change) +
1404                       G_STRUCT_OFFSET (struct kdbus_notify_name_change, name) + len);
1405
1406   cookie = 0xdeafdeafdeafdeaf;
1407   cmd_match = g_alloca0 (size);
1408   cmd_match->size = size;
1409   cmd_match->cookie = cookie;
1410   item = cmd_match->items;
1411
1412   /* KDBUS_ITEM_NAME_REMOVE */
1413   item->type = KDBUS_ITEM_NAME_REMOVE;
1414   item->name_change.old_id.id = kdbus->priv->unique_id;
1415   item->name_change.new_id.id = KDBUS_MATCH_ID_ANY;
1416   memcpy(item->name_change.name, name, len);
1417   item->size = G_STRUCT_OFFSET (struct kdbus_item, name_change) +
1418                G_STRUCT_OFFSET(struct kdbus_notify_name_change, name) + len;
1419   item = KDBUS_ITEM_NEXT(item);
1420
1421   ret = ioctl(kdbus->priv->fd, KDBUS_CMD_MATCH_ADD, cmd_match);
1422   if (ret < 0)
1423     g_warning ("ERROR - %d\n", (int) errno);
1424
1425   _g_kdbus_subscribe_name_owner_changed (connection, name, kdbus->priv->unique_name, "", cookie);
1426 }
1427
1428
1429 /*
1430  * _g_kdbus_unsubscribe_name_acquired:
1431  *
1432  */
1433 void
1434 _g_kdbus_unsubscribe_name_acquired (GDBusConnection  *connection)
1435 {
1436   guint64 cookie;
1437
1438   cookie = 0xbeefbeefbeefbeef;
1439   _g_kdbus_match_remove (connection, cookie);
1440 }
1441
1442
1443 /*
1444  * _g_kdbus_unsubscribe_name_lost:
1445  *
1446  */
1447 void
1448 _g_kdbus_unsubscribe_name_lost (GDBusConnection  *connection)
1449 {
1450   guint64 cookie;
1451
1452   cookie = 0xdeafdeafdeafdeaf;
1453   _g_kdbus_match_remove (connection, cookie);
1454 }
1455
1456
1457 /**
1458 * g_kdbus_decode_kernel_msg:
1459 *
1460 */
1461 static gssize
1462 g_kdbus_decode_kernel_msg (GKdbus  *kdbus)
1463 {
1464   struct kdbus_item *item = NULL;
1465   gssize size = 0;
1466
1467   KDBUS_ITEM_FOREACH(item, kdbus->priv->kmsg, items)
1468     {
1469      switch (item->type)
1470         {
1471           case KDBUS_ITEM_ID_ADD:
1472           case KDBUS_ITEM_ID_REMOVE:
1473           case KDBUS_ITEM_NAME_ADD:
1474           case KDBUS_ITEM_NAME_REMOVE:
1475           case KDBUS_ITEM_NAME_CHANGE:
1476             //size = g_kdbus_NameOwnerChanged_generate (kdbus, item);
1477             g_error ("'NameOwnerChanged'");
1478             break;
1479
1480           case KDBUS_ITEM_REPLY_TIMEOUT:
1481           case KDBUS_ITEM_REPLY_DEAD:
1482             //size = g_kdbus_KernelMethodError_generate (kdbus, item);
1483             g_error ("'KernelMethodError'");
1484             break;
1485
1486           default:
1487             g_warning ("Unknown field in kernel message - %lld", item->type);
1488        }
1489     }
1490
1491 #if 0
1492   /* Override information from the user header with data from the kernel */
1493   g_string_printf (kdbus->priv->msg_sender, "org.freedesktop.DBus");
1494
1495   /* for destination */
1496   if (kdbus->priv->kmsg->dst_id == KDBUS_DST_ID_BROADCAST)
1497     /* for broadcast messages we don't have to set destination */
1498     ;
1499   else if (kdbus->priv->kmsg->dst_id == KDBUS_DST_ID_NAME)
1500     g_string_printf (kdbus->priv->msg_destination, ":1.%" G_GUINT64_FORMAT, (guint64) kdbus->priv->unique_id);
1501   else
1502    g_string_printf (kdbus->priv->msg_destination, ":1.%" G_GUINT64_FORMAT, (guint64) kdbus->priv->kmsg->dst_id);
1503 #endif
1504
1505   return size;
1506 }
1507
1508
1509 /**
1510  * _g_kdbus_receive:
1511  *
1512  */
1513 gssize
1514 _g_kdbus_receive (GKdbus        *kdbus,
1515                   GCancellable  *cancellable,
1516                   GError       **error)
1517 {
1518   struct kdbus_cmd_recv recv = {};
1519   gssize size = 0;
1520
1521   if (g_cancellable_set_error_if_cancelled (cancellable, error))
1522     return -1;
1523
1524 again:
1525     if (ioctl(kdbus->priv->fd, KDBUS_CMD_MSG_RECV, &recv) < 0)
1526       {
1527         if (errno == EINTR || errno == EAGAIN)
1528           goto again;
1529
1530         g_set_error (error, G_IO_ERROR,
1531                      g_io_error_from_errno (errno),
1532                      _("Error while receiving message: %s"),
1533                      g_strerror (errno));
1534         return -1;
1535       }
1536
1537    kdbus->priv->kmsg = (struct kdbus_msg *)((guint8 *)kdbus->priv->kdbus_buffer + recv.offset);
1538
1539    if (kdbus->priv->kmsg->payload_type == KDBUS_PAYLOAD_DBUS)
1540      g_error ("Received standard dbus message - not supported yet");
1541    else if (kdbus->priv->kmsg->payload_type == KDBUS_PAYLOAD_KERNEL)
1542      size = g_kdbus_decode_kernel_msg (kdbus);
1543    else
1544      {
1545        g_set_error (error,
1546                     G_DBUS_ERROR,
1547                     G_DBUS_ERROR_FAILED,
1548                     _("Received unknown payload type"));
1549        return -1;
1550      }
1551
1552    return size;
1553 }