[kdbus] Add support for 'ReleaseName' on kdbus
[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   gchar             *unique_name;
105   guint64            unique_id;
106
107   guint64            hello_flags;
108   guint64            attach_flags;
109
110   guint              closed : 1;
111   guint              inited : 1;
112   guint              timeout;
113   guint              timed_out : 1;
114
115   guchar             bus_id[16];
116 };
117
118 /* GKdbusSource struct */
119 typedef struct {
120   GSource        source;
121   GPollFD        pollfd;
122   GKdbus        *kdbus;
123   GIOCondition   condition;
124   GCancellable  *cancellable;
125   GPollFD        cancel_pollfd;
126   gint64         timeout_time;
127 } GKdbusSource;
128
129
130 typedef gboolean (*GKdbusSourceFunc) (GKdbus *kdbus,
131                                       GIOCondition condition,
132                                       gpointer user_data);
133
134 /**
135  * g_kdbus_finalize:
136  *
137  */
138 static void
139 g_kdbus_finalize (GObject  *object)
140 {
141   GKdbus *kdbus = G_KDBUS (object);
142
143   if (kdbus->priv->kdbus_buffer != NULL)
144     munmap (kdbus->priv->kdbus_buffer, KDBUS_POOL_SIZE);
145
146   kdbus->priv->kdbus_buffer = NULL;
147
148   if (kdbus->priv->fd != -1 && !kdbus->priv->closed)
149     _g_kdbus_close (kdbus, NULL);
150
151   if (G_OBJECT_CLASS (g_kdbus_parent_class)->finalize)
152     (*G_OBJECT_CLASS (g_kdbus_parent_class)->finalize) (object);
153 }
154
155
156 /**
157  * g_kdbus_class_init:
158  *
159  */
160 static void
161 g_kdbus_class_init (GKdbusClass  *klass)
162 {
163   GObjectClass *gobject_class G_GNUC_UNUSED = G_OBJECT_CLASS (klass);
164
165   g_type_class_add_private (klass, sizeof (GKdbusPrivate));
166   gobject_class->finalize = g_kdbus_finalize;
167 }
168
169
170 /**
171  * g_kdbus_initable_iface_init:
172  *
173  */
174 static void
175 g_kdbus_initable_iface_init (GInitableIface  *iface)
176 {
177   iface->init = g_kdbus_initable_init;
178 }
179
180
181 /**
182  * g_kdbus_init:
183  *
184  */
185 static void
186 g_kdbus_init (GKdbus  *kdbus)
187 {
188   kdbus->priv = G_TYPE_INSTANCE_GET_PRIVATE (kdbus, G_TYPE_KDBUS, GKdbusPrivate);
189
190   kdbus->priv->fd = -1;
191
192   kdbus->priv->unique_id = -1;
193   kdbus->priv->unique_name = NULL;
194
195   kdbus->priv->kdbus_buffer = NULL;
196
197   kdbus->priv->hello_flags = 0; /* KDBUS_HELLO_ACCEPT_FD */
198   kdbus->priv->attach_flags = KDBUS_ATTACH_NAMES;
199 }
200
201
202 /**
203  * g_kdbus_initable_init:
204  *
205  */
206 static gboolean
207 g_kdbus_initable_init (GInitable     *initable,
208                        GCancellable  *cancellable,
209                        GError       **error)
210 {
211   GKdbus *kdbus;
212
213   g_return_val_if_fail (G_IS_KDBUS (initable), FALSE);
214
215   kdbus = G_KDBUS (initable);
216
217   if (cancellable != NULL)
218     {
219       g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
220                            _("Cancellable initialization not supported"));
221       return FALSE;
222     }
223
224   kdbus->priv->inited = TRUE;
225
226   return TRUE;
227 }
228
229
230 /**
231  * kdbus_source_prepare:
232  *
233  */
234 static gboolean
235 kdbus_source_prepare (GSource  *source,
236                       gint     *timeout)
237 {
238   GKdbusSource *kdbus_source = (GKdbusSource *)source;
239
240   if (g_cancellable_is_cancelled (kdbus_source->cancellable))
241     return TRUE;
242
243   if (kdbus_source->timeout_time)
244     {
245       gint64 now;
246
247       now = g_source_get_time (source);
248
249       *timeout = (kdbus_source->timeout_time - now + 999) / 1000;
250       if (*timeout < 0)
251         {
252           kdbus_source->kdbus->priv->timed_out = TRUE;
253           *timeout = 0;
254           return TRUE;
255         }
256     }
257   else
258     *timeout = -1;
259
260   if ((kdbus_source->condition & kdbus_source->pollfd.revents) != 0)
261     return TRUE;
262
263   return FALSE;
264 }
265
266
267 /**
268  * kdbus_source_check:
269  *
270  */
271 static gboolean
272 kdbus_source_check (GSource  *source)
273 {
274   gint timeout;
275
276   return kdbus_source_prepare (source, &timeout);
277 }
278
279
280 /**
281  * kdbus_source_dispatch
282  *
283  */
284 static gboolean
285 kdbus_source_dispatch  (GSource      *source,
286                         GSourceFunc   callback,
287                         gpointer      user_data)
288 {
289   GKdbusSourceFunc func = (GKdbusSourceFunc)callback;
290   GKdbusSource *kdbus_source = (GKdbusSource *)source;
291   GKdbus *kdbus = kdbus_source->kdbus;
292   gboolean ret;
293
294   if (kdbus_source->kdbus->priv->timed_out)
295     kdbus_source->pollfd.revents |= kdbus_source->condition & (G_IO_IN | G_IO_OUT);
296
297   ret = (*func) (kdbus,
298                  kdbus_source->pollfd.revents & kdbus_source->condition,
299                  user_data);
300
301   if (kdbus->priv->timeout)
302     kdbus_source->timeout_time = g_get_monotonic_time ()
303                                + kdbus->priv->timeout * 1000000;
304
305   else
306     kdbus_source->timeout_time = 0;
307
308   return ret;
309 }
310
311
312 /**
313  * kdbus_source_finalize
314  *
315  */
316 static void
317 kdbus_source_finalize (GSource  *source)
318 {
319   GKdbusSource *kdbus_source = (GKdbusSource *)source;
320   GKdbus *kdbus;
321
322   kdbus = kdbus_source->kdbus;
323
324   g_object_unref (kdbus);
325
326   if (kdbus_source->cancellable)
327     {
328       g_cancellable_release_fd (kdbus_source->cancellable);
329       g_object_unref (kdbus_source->cancellable);
330     }
331 }
332
333
334 /**
335  * kdbus_source_closure_callback:
336  *
337  */
338 static gboolean
339 kdbus_source_closure_callback (GKdbus        *kdbus,
340                                GIOCondition   condition,
341                                gpointer       data)
342 {
343   GClosure *closure = data;
344   GValue params[2] = { G_VALUE_INIT, G_VALUE_INIT };
345   GValue result_value = G_VALUE_INIT;
346   gboolean result;
347
348   g_value_init (&result_value, G_TYPE_BOOLEAN);
349
350   g_value_init (&params[0], G_TYPE_KDBUS);
351   g_value_set_object (&params[0], kdbus);
352   g_value_init (&params[1], G_TYPE_IO_CONDITION);
353   g_value_set_flags (&params[1], condition);
354
355   g_closure_invoke (closure, &result_value, 2, params, NULL);
356
357   result = g_value_get_boolean (&result_value);
358   g_value_unset (&result_value);
359   g_value_unset (&params[0]);
360   g_value_unset (&params[1]);
361
362   return result;
363 }
364
365
366 static GSourceFuncs kdbus_source_funcs =
367 {
368   kdbus_source_prepare,
369   kdbus_source_check,
370   kdbus_source_dispatch,
371   kdbus_source_finalize,
372   (GSourceFunc)kdbus_source_closure_callback,
373 };
374
375
376 /**
377  * kdbus_source_new:
378  *
379  */
380 static GSource *
381 kdbus_source_new (GKdbus        *kdbus,
382                   GIOCondition   condition,
383                   GCancellable  *cancellable)
384 {
385   GSource *source;
386   GKdbusSource *kdbus_source;
387
388   source = g_source_new (&kdbus_source_funcs, sizeof (GKdbusSource));
389   g_source_set_name (source, "GKdbus");
390   kdbus_source = (GKdbusSource *)source;
391
392   kdbus_source->kdbus = g_object_ref (kdbus);
393   kdbus_source->condition = condition;
394
395   if (g_cancellable_make_pollfd (cancellable,
396                                  &kdbus_source->cancel_pollfd))
397     {
398       kdbus_source->cancellable = g_object_ref (cancellable);
399       g_source_add_poll (source, &kdbus_source->cancel_pollfd);
400     }
401
402   kdbus_source->pollfd.fd = kdbus->priv->fd;
403   kdbus_source->pollfd.events = condition;
404   kdbus_source->pollfd.revents = 0;
405   g_source_add_poll (source, &kdbus_source->pollfd);
406
407   if (kdbus->priv->timeout)
408     kdbus_source->timeout_time = g_get_monotonic_time ()
409                                + kdbus->priv->timeout * 1000000;
410   else
411     kdbus_source->timeout_time = 0;
412
413   return source;
414 }
415
416
417 /**
418  * _g_kdbus_create_source:
419  *
420  */
421 GSource *
422 _g_kdbus_create_source (GKdbus        *kdbus,
423                         GIOCondition   condition,
424                         GCancellable  *cancellable)
425 {
426   g_return_val_if_fail (G_IS_KDBUS (kdbus) && (cancellable == NULL || G_IS_CANCELLABLE (cancellable)), NULL);
427
428   return kdbus_source_new (kdbus, condition, cancellable);
429 }
430
431
432 /**
433  * _g_kdbus_open:
434  *
435  */
436 gboolean
437 _g_kdbus_open (GKdbus       *kdbus,
438                const gchar  *address,
439                GError      **error)
440 {
441   g_return_val_if_fail (G_IS_KDBUS (kdbus), FALSE);
442
443   kdbus->priv->fd = open(address, O_RDWR|O_NOCTTY|O_CLOEXEC);
444   if (kdbus->priv->fd<0)
445     {
446       g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, _("Can't open kdbus endpoint"));
447       return FALSE;
448     }
449
450   kdbus->priv->closed = FALSE;
451
452   return TRUE;
453 }
454
455
456 /**
457  * g_kdbus_free_data:
458  *
459  */
460 static gboolean
461 g_kdbus_free_data (GKdbus      *kdbus,
462                    guint64      offset)
463 {
464   struct kdbus_cmd_free cmd;
465   int ret;
466
467   cmd.offset = offset;
468   cmd.flags = 0;
469
470   ret = ioctl (kdbus->priv->fd, KDBUS_CMD_FREE, &cmd);
471   if (ret < 0)
472       return FALSE;
473
474   return TRUE;
475 }
476
477
478 /**
479  * g_kdbus_translate_nameowner_flags:
480  *
481  */
482 static void
483 g_kdbus_translate_nameowner_flags (GBusNameOwnerFlags   flags,
484                                    guint64             *kdbus_flags)
485 {
486   guint64 new_flags;
487
488   new_flags = 0;
489
490   if (flags & G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT)
491     new_flags |= KDBUS_NAME_ALLOW_REPLACEMENT;
492
493   if (flags & G_BUS_NAME_OWNER_FLAGS_REPLACE)
494     new_flags |= KDBUS_NAME_REPLACE_EXISTING;
495
496   if (!(flags & G_BUS_NAME_OWNER_FLAGS_DO_NOT_QUEUE))
497     new_flags |= KDBUS_NAME_QUEUE;
498
499   *kdbus_flags = new_flags;
500 }
501
502
503 /**
504  * _g_kdbus_close:
505  *
506  */
507 gboolean
508 _g_kdbus_close (GKdbus  *kdbus,
509                 GError **error)
510 {
511   gint res;
512
513   g_return_val_if_fail (G_IS_KDBUS (kdbus), FALSE);
514
515   if (kdbus->priv->closed)
516     return TRUE;
517
518   while (1)
519     {
520       res = close (kdbus->priv->fd);
521
522       if (res == -1)
523         {
524           if (errno == EINTR)
525             continue;
526
527           g_set_error (error, G_IO_ERROR,
528                        g_io_error_from_errno (errno),
529                        _("Error closing kdbus fd: %s"),
530                        g_strerror (errno));
531           return FALSE;
532         }
533       break;
534     }
535
536   kdbus->priv->closed = TRUE;
537   kdbus->priv->fd = -1;
538
539   return TRUE;
540 }
541
542
543 /**
544  * _g_kdbus_is_closed:
545  *
546  */
547 gboolean
548 _g_kdbus_is_closed (GKdbus  *kdbus)
549 {
550   g_return_val_if_fail (G_IS_KDBUS (kdbus), FALSE);
551
552   return kdbus->priv->closed;
553 }
554
555
556 /**
557  * _g_kdbus_Hello:
558  *
559  */
560 GVariant *
561 _g_kdbus_Hello (GIOStream  *stream,
562                 GError    **error)
563 {
564   GKdbus *kdbus;
565   struct kdbus_cmd_hello *hello;
566   struct kdbus_item *item;
567
568   gchar *conn_name;
569   size_t size, conn_name_size;
570
571   kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (stream));
572
573   conn_name = "gdbus-kdbus";
574   conn_name_size = strlen (conn_name);
575
576   size = KDBUS_ALIGN8 (G_STRUCT_OFFSET (struct kdbus_cmd_hello, items)) +
577          KDBUS_ALIGN8 (G_STRUCT_OFFSET (struct kdbus_item, str) + conn_name_size + 1);
578
579   hello = g_alloca0 (size);
580   hello->conn_flags = kdbus->priv->hello_flags;
581   hello->attach_flags =  kdbus->priv->attach_flags;
582   hello->size = size;
583   hello->pool_size = KDBUS_POOL_SIZE;
584
585   item = hello->items;
586   item->size = G_STRUCT_OFFSET (struct kdbus_item, str) + conn_name_size + 1;
587   item->type = KDBUS_ITEM_CONN_NAME;
588   memcpy (item->str, conn_name, conn_name_size+1);
589   item = KDBUS_ITEM_NEXT (item);
590
591   if (ioctl(kdbus->priv->fd, KDBUS_CMD_HELLO, hello))
592     {
593       g_set_error (error, G_IO_ERROR,
594                    g_io_error_from_errno (errno),
595                    _("Failed to send HELLO: %s"),
596                    g_strerror (errno));
597       return NULL;
598     }
599
600   kdbus->priv->kdbus_buffer = mmap(NULL, KDBUS_POOL_SIZE, PROT_READ, MAP_SHARED, kdbus->priv->fd, 0);
601   if (kdbus->priv->kdbus_buffer == MAP_FAILED)
602     {
603       g_set_error (error, G_IO_ERROR,
604                    g_io_error_from_errno (errno),
605                    _("mmap error: %s"),
606                    g_strerror (errno));
607       return NULL;
608     }
609
610   if (hello->bus_flags > 0xFFFFFFFFULL)
611     {
612       g_set_error_literal (error,
613                            G_IO_ERROR,
614                            G_IO_ERROR_FAILED,
615                            _("Incompatible HELLO flags"));
616       return NULL;
617     }
618
619   memcpy (kdbus->priv->bus_id, hello->id128, 16);
620
621   kdbus->priv->unique_id = hello->id;
622   asprintf(&kdbus->priv->unique_name, ":1.%llu", (unsigned long long) hello->id);
623
624   return g_variant_new ("(s)", kdbus->priv->unique_name);
625 }
626
627
628 /*
629  * _g_kdbus_RequestName:
630  *
631  */
632 GVariant *
633 _g_kdbus_RequestName (GDBusConnection     *connection,
634                       const gchar         *name,
635                       GBusNameOwnerFlags   flags,
636                       GError             **error)
637 {
638   GKdbus *kdbus;
639   GVariant *result;
640   struct kdbus_cmd_name *kdbus_name;
641   guint64 kdbus_flags;
642   gssize len, size;
643   gint status, ret;
644
645   status = G_BUS_REQUEST_NAME_REPLY_PRIMARY_OWNER;
646
647   kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
648   if (kdbus == NULL)
649     {
650       g_set_error_literal (error,
651                            G_DBUS_ERROR,
652                            G_DBUS_ERROR_IO_ERROR,
653                            _("The connection is closed"));
654       return NULL;
655     }
656
657   if (!g_dbus_is_name (name))
658     {
659       g_set_error (error,
660                    G_DBUS_ERROR,
661                    G_DBUS_ERROR_INVALID_ARGS,
662                    "Given bus name \"%s\" is not valid", name);
663       return NULL;
664     }
665
666   if (*name == ':')
667     {
668       g_set_error (error,
669                    G_DBUS_ERROR,
670                    G_DBUS_ERROR_INVALID_ARGS,
671                    "Cannot acquire a service starting with ':' such as \"%s\"", name);
672       return NULL;
673     }
674
675   g_kdbus_translate_nameowner_flags (flags, &kdbus_flags);
676
677   len = strlen(name) + 1;
678   size = G_STRUCT_OFFSET (struct kdbus_cmd_name, items) + KDBUS_ITEM_SIZE(len);
679   kdbus_name = g_alloca0 (size);
680   kdbus_name->items[0].size = KDBUS_ITEM_HEADER_SIZE + len;
681   kdbus_name->items[0].type = KDBUS_ITEM_NAME;
682   kdbus_name->flags = kdbus_flags;
683   memcpy (kdbus_name->items[0].str, name, len);
684
685   ret = ioctl(kdbus->priv->fd, KDBUS_CMD_NAME_ACQUIRE, kdbus_name);
686   if (ret < 0)
687     {
688       if (errno == EEXIST)
689         status = G_BUS_REQUEST_NAME_REPLY_EXISTS;
690       else if (errno == EALREADY)
691         status = G_BUS_REQUEST_NAME_REPLY_ALREADY_OWNER;
692       else
693         return FALSE;
694     }
695
696   if (kdbus_name->flags & KDBUS_NAME_IN_QUEUE)
697     status = G_BUS_REQUEST_NAME_REPLY_IN_QUEUE;
698
699   result = g_variant_new ("(u)", status);
700
701   return result;
702 }
703
704
705 /*
706  * _g_kdbus_ReleaseName:
707  *
708  */
709 GVariant *
710 _g_kdbus_ReleaseName (GDBusConnection     *connection,
711                       const gchar         *name,
712                       GError             **error)
713 {
714   GKdbus *kdbus;
715   GVariant *result;
716   struct kdbus_cmd_name *kdbus_name;
717   gssize len, size;
718   gint status, ret;
719
720   status = G_BUS_RELEASE_NAME_REPLY_RELEASED;
721
722   kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
723   if (kdbus == NULL)
724     {
725       g_set_error_literal (error,
726                            G_DBUS_ERROR,
727                            G_DBUS_ERROR_IO_ERROR,
728                            _("The connection is closed"));
729       return NULL;
730     }
731
732   if (!g_dbus_is_name (name))
733     {
734       g_set_error (error,
735                    G_DBUS_ERROR,
736                    G_DBUS_ERROR_INVALID_ARGS,
737                    "Given bus name \"%s\" is not valid", name);
738       return NULL;
739     }
740
741   if (*name == ':')
742     {
743       g_set_error (error,
744                    G_DBUS_ERROR,
745                    G_DBUS_ERROR_INVALID_ARGS,
746                    "Cannot release a service starting with ':' such as \"%s\"", name);
747       return NULL;
748     }
749
750   len = strlen(name) + 1;
751   size = G_STRUCT_OFFSET (struct kdbus_cmd_name, items) + KDBUS_ITEM_SIZE(len);
752   kdbus_name = g_alloca0 (size);
753   kdbus_name->items[0].size = KDBUS_ITEM_HEADER_SIZE + len;
754   kdbus_name->items[0].type = KDBUS_ITEM_NAME;
755   memcpy (kdbus_name->items[0].str, name, len);
756
757   ret = ioctl(kdbus->priv->fd, KDBUS_CMD_NAME_RELEASE, kdbus_name);
758   if (ret < 0)
759     {
760       if (errno == ESRCH)
761         status = G_BUS_RELEASE_NAME_REPLY_NON_EXISTENT;
762       else if (errno == EADDRINUSE)
763         status = G_BUS_RELEASE_NAME_REPLY_NOT_OWNER;
764       else
765         return FALSE;
766     }
767
768   result = g_variant_new ("(u)", status);
769
770   return result;
771 }
772
773
774 /**
775  * _g_kdbus_GetBusId:
776  *
777  */
778 GVariant *
779 _g_kdbus_GetBusId (GDBusConnection  *connection,
780                    GError          **error)
781 {
782   GKdbus   *kdbus;
783   GVariant *result;
784   GString  *result_str;
785   guint     cnt;
786
787   result_str = g_string_new (NULL);
788   kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
789   if (kdbus == NULL)
790     {
791       g_set_error_literal (error,
792                            G_DBUS_ERROR,
793                            G_DBUS_ERROR_IO_ERROR,
794                            _("The connection is closed"));
795       g_string_free (result_str, TRUE);
796       return NULL;
797     }
798
799   for (cnt=0; cnt<16; cnt++)
800     g_string_append_printf (result_str, "%02x", kdbus->priv->bus_id[cnt]);
801
802   result = g_variant_new ("(s)", result_str->str);
803   g_string_free (result_str, TRUE);
804
805   return result;
806 }
807
808
809 /**
810  * _g_kdbus_GetListNames:
811  *
812  */
813 GVariant *
814 _g_kdbus_GetListNames (GDBusConnection  *connection,
815                        guint             list_name_type,
816                        GError          **error)
817 {
818   GKdbus *kdbus;
819   GVariant *result;
820   GVariantBuilder *builder;
821
822   struct kdbus_cmd_name_list cmd = {};
823   struct kdbus_name_list *name_list;
824   struct kdbus_cmd_name *name;
825
826   guint64 prev_id;
827   gint ret;
828
829   prev_id = 0;
830   kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
831   if (kdbus == NULL)
832     {
833       g_set_error_literal (error,
834                            G_DBUS_ERROR,
835                            G_DBUS_ERROR_IO_ERROR,
836                            _("The connection is closed"));
837       return NULL;
838     }
839
840   if (list_name_type)
841     cmd.flags = KDBUS_NAME_LIST_ACTIVATORS;                     /* ListActivatableNames */
842   else
843     cmd.flags = KDBUS_NAME_LIST_UNIQUE | KDBUS_NAME_LIST_NAMES; /* ListNames */
844
845   ret = ioctl(kdbus->priv->fd, KDBUS_CMD_NAME_LIST, &cmd);
846   if (ret < 0)
847     {
848       g_set_error (error,
849                    G_DBUS_ERROR,
850                    G_DBUS_ERROR_FAILED,
851                    _("Error listing names"));
852       return NULL;
853     }
854
855   name_list = (struct kdbus_name_list *) ((guint8 *) kdbus->priv->kdbus_buffer + cmd.offset);
856   builder = g_variant_builder_new (G_VARIANT_TYPE ("as"));
857
858   KDBUS_ITEM_FOREACH(name, name_list, names)
859     {
860       struct kdbus_item *item;
861       const gchar *item_name = "";
862
863       if ((cmd.flags & KDBUS_NAME_LIST_UNIQUE) && name->owner_id != prev_id)
864         {
865           GString *unique_name;
866
867           unique_name = g_string_new (NULL);
868           g_string_printf (unique_name, ":1.%llu", name->owner_id);
869           g_variant_builder_add (builder, "s", unique_name->str);
870           g_string_free (unique_name,TRUE);
871           prev_id = name->owner_id;
872         }
873
874        KDBUS_ITEM_FOREACH(item, name, items)
875          if (item->type == KDBUS_ITEM_NAME)
876            item_name = item->str;
877
878         if (g_dbus_is_name (item_name))
879           g_variant_builder_add (builder, "s", item_name);
880     }
881
882   result = g_variant_new ("(as)", builder);
883   g_variant_builder_unref (builder);
884
885   g_kdbus_free_data (kdbus, cmd.offset);
886   return result;
887 }
888
889
890 /**
891  * _g_kdbus_NameHasOwner_internal:
892  *
893  */
894 static gboolean
895 g_kdbus_NameHasOwner_internal (GKdbus       *kdbus,
896                                const gchar  *name,
897                                GError      **error)
898 {
899   struct kdbus_cmd_conn_info *cmd;
900   gssize size, len;
901   gint ret;
902
903   if (g_dbus_is_unique_name(name))
904     {
905        size = G_STRUCT_OFFSET (struct kdbus_cmd_conn_info, items);
906        cmd = g_alloca0 (size);
907        cmd->id = g_ascii_strtoull (name+3, NULL, 10);
908     }
909   else
910     {
911        len = strlen(name) + 1;
912        size = G_STRUCT_OFFSET (struct kdbus_cmd_conn_info, items) + KDBUS_ITEM_SIZE(len);
913        cmd = g_alloca0 (size);
914        cmd->items[0].size = KDBUS_ITEM_HEADER_SIZE + len;
915        cmd->items[0].type = KDBUS_ITEM_NAME;
916        memcpy (cmd->items[0].str, name, len);
917     }
918   cmd->size = size;
919
920   ret = ioctl(kdbus->priv->fd, KDBUS_CMD_CONN_INFO, cmd);
921   g_kdbus_free_data (kdbus, cmd->offset);
922
923   if (ret < 0)
924     return FALSE;
925   else
926     return TRUE;
927 }
928
929
930 /**
931  * _g_kdbus_GetListQueuedOwners:
932  *
933  */
934 GVariant *
935 _g_kdbus_GetListQueuedOwners (GDBusConnection  *connection,
936                               const gchar      *name,
937                               GError          **error)
938 {
939   GKdbus *kdbus;
940   GVariant *result;
941   GVariantBuilder *builder;
942   GString *unique_name;
943   gint ret;
944
945   struct kdbus_cmd_name_list cmd = {};
946   struct kdbus_name_list *name_list;
947   struct kdbus_cmd_name *kname;
948
949   kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
950   if (kdbus == NULL)
951     {
952       g_set_error_literal (error,
953                            G_DBUS_ERROR,
954                            G_DBUS_ERROR_IO_ERROR,
955                            _("The connection is closed"));
956       return NULL;
957     }
958
959   if (!g_dbus_is_name (name))
960     {
961       g_set_error (error,
962                    G_DBUS_ERROR,
963                    G_DBUS_ERROR_INVALID_ARGS,
964                    "Given bus name \"%s\" is not valid", name);
965       return NULL;
966     }
967
968   if (!g_kdbus_NameHasOwner_internal (kdbus, name, error))
969     {
970       g_set_error (error,
971                    G_DBUS_ERROR,
972                    G_DBUS_ERROR_NAME_HAS_NO_OWNER,
973                    "Could not get owner of name '%s': no such name", name);
974       return NULL;
975     }
976
977   cmd.flags = KDBUS_NAME_LIST_QUEUED;
978   ret = ioctl(kdbus->priv->fd, KDBUS_CMD_NAME_LIST, &cmd);
979   if (ret < 0)
980     {
981       g_set_error (error,
982                    G_DBUS_ERROR,
983                    G_DBUS_ERROR_FAILED,
984                    _("Error listing names"));
985       return NULL;
986     }
987
988   name_list = (struct kdbus_name_list *) ((guint8 *) kdbus->priv->kdbus_buffer + cmd.offset);
989
990   unique_name = g_string_new (NULL);
991   builder = g_variant_builder_new (G_VARIANT_TYPE ("as"));
992   KDBUS_ITEM_FOREACH(kname, name_list, names)
993     {
994       struct kdbus_item *item;
995       const char *item_name = "";
996
997       KDBUS_ITEM_FOREACH(item, kname, items)
998         if (item->type == KDBUS_ITEM_NAME)
999           item_name = item->str;
1000
1001       if (strcmp(item_name, name))
1002         continue;
1003
1004       g_string_printf (unique_name, ":1.%llu", kname->owner_id);
1005       g_variant_builder_add (builder, "s", item_name);
1006     }
1007
1008   result = g_variant_new ("(as)", builder);
1009   g_variant_builder_unref (builder);
1010   g_string_free (unique_name,TRUE);
1011
1012   g_kdbus_free_data (kdbus, cmd.offset);
1013   return result;
1014 }
1015
1016
1017 /**
1018  * _g_kdbus_NameHasOwner:
1019  *
1020  */
1021 GVariant *
1022 _g_kdbus_NameHasOwner (GDBusConnection  *connection,
1023                        const gchar      *name,
1024                        GError          **error)
1025 {
1026   GKdbus *kdbus;
1027   GVariant *result;
1028
1029   kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
1030   if (kdbus == NULL)
1031     {
1032       g_set_error_literal (error,
1033                            G_DBUS_ERROR,
1034                            G_DBUS_ERROR_IO_ERROR,
1035                            _("The connection is closed"));
1036       return NULL;
1037     }
1038
1039   if (!g_dbus_is_name (name))
1040     {
1041       g_set_error (error,
1042                    G_DBUS_ERROR,
1043                    G_DBUS_ERROR_INVALID_ARGS,
1044                    "Given bus name \"%s\" is not valid", name);
1045       return NULL;
1046     }
1047
1048   if (!g_kdbus_NameHasOwner_internal (kdbus, name, error))
1049     result = g_variant_new ("(b)", FALSE);
1050   else
1051     result = g_variant_new ("(b)", TRUE);
1052
1053   return result;
1054 }
1055
1056
1057 /**
1058  * g_kdbus_GetConnInfo_internal:
1059  *
1060  */
1061 static GVariant *
1062 g_kdbus_GetConnInfo_internal (GDBusConnection  *connection,
1063                               const gchar      *name,
1064                               guint64           flag,
1065                               GError          **error)
1066 {
1067   GKdbus *kdbus;
1068   GVariant *result;
1069
1070   struct kdbus_cmd_conn_info *cmd;
1071   struct kdbus_conn_info *conn_info;
1072   struct kdbus_item *item;
1073   gssize size, len;
1074   gint ret;
1075
1076   result = NULL;
1077   kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
1078   if (kdbus == NULL)
1079     {
1080       g_set_error_literal (error,
1081                            G_DBUS_ERROR,
1082                            G_DBUS_ERROR_IO_ERROR,
1083                            _("The connection is closed"));
1084       return NULL;
1085     }
1086
1087   if (!g_dbus_is_name (name))
1088     {
1089       g_set_error (error,
1090                    G_DBUS_ERROR,
1091                    G_DBUS_ERROR_INVALID_ARGS,
1092                    "Given bus name \"%s\" is not valid", name);
1093       return NULL;
1094     }
1095
1096   if (!g_kdbus_NameHasOwner_internal (kdbus, name, error))
1097     {
1098       g_set_error (error,
1099                    G_DBUS_ERROR,
1100                    G_DBUS_ERROR_NAME_HAS_NO_OWNER,
1101                    "Could not get owner of name '%s': no such name", name);
1102       return NULL;
1103     }
1104
1105   if (g_dbus_is_unique_name(name))
1106     {
1107        size = G_STRUCT_OFFSET (struct kdbus_cmd_conn_info, items);
1108        cmd = g_alloca0 (size);
1109        cmd->id = g_ascii_strtoull (name+3, NULL, 10);
1110     }
1111   else
1112     {
1113        len = strlen(name) + 1;
1114        size = G_STRUCT_OFFSET (struct kdbus_cmd_conn_info, items) + KDBUS_ITEM_SIZE(len);
1115        cmd = g_alloca0 (size);
1116        cmd->items[0].size = KDBUS_ITEM_HEADER_SIZE + len;
1117        cmd->items[0].type = KDBUS_ITEM_NAME;
1118        memcpy (cmd->items[0].str, name, len);
1119     }
1120
1121   cmd->flags = KDBUS_ATTACH_NAMES;
1122   cmd->size = size;
1123
1124   ret = ioctl(kdbus->priv->fd, KDBUS_CMD_CONN_INFO, cmd);
1125   if (ret < 0)
1126     {
1127       g_set_error (error,
1128                    G_DBUS_ERROR,
1129                    G_DBUS_ERROR_FAILED,
1130                    _("Could not get connection info"));
1131       return NULL;
1132     }
1133
1134   conn_info = (struct kdbus_conn_info *) ((guint8 *) kdbus->priv->kdbus_buffer + cmd->offset);
1135
1136   /*
1137   if (conn_info->flags & KDBUS_HELLO_ACTIVATOR)
1138     {}
1139   */
1140
1141   if (flag == G_BUS_CREDS_UNIQUE_NAME)
1142     {
1143        GString *unique_name;
1144
1145        unique_name = g_string_new (NULL);
1146        g_string_printf (unique_name, ":1.%llu", (unsigned long long) conn_info->id);
1147        result = g_variant_new ("(s)", unique_name->str);
1148        g_string_free (unique_name,TRUE);
1149        goto exit;
1150     }
1151
1152   KDBUS_ITEM_FOREACH(item, conn_info, items)
1153    {
1154       switch (item->type)
1155         {
1156           case KDBUS_ITEM_CREDS:
1157
1158             if (flag == G_BUS_CREDS_PID)
1159               {
1160                 guint pid = item->creds.pid;
1161                 result = g_variant_new ("(u)", pid);
1162                 goto exit;
1163                }
1164
1165             if (flag == G_BUS_CREDS_UID)
1166               {
1167                 guint uid = item->creds.uid;
1168                 result = g_variant_new ("(u)", uid);
1169                 goto exit;
1170               }
1171
1172           case KDBUS_ITEM_SECLABEL:
1173           case KDBUS_ITEM_PID_COMM:
1174           case KDBUS_ITEM_TID_COMM:
1175           case KDBUS_ITEM_EXE:
1176           case KDBUS_ITEM_CMDLINE:
1177           case KDBUS_ITEM_CGROUP:
1178           case KDBUS_ITEM_CAPS:
1179           case KDBUS_ITEM_NAME:
1180           case KDBUS_ITEM_AUDIT:
1181             break;
1182         }
1183    }
1184
1185 exit:
1186   g_kdbus_free_data (kdbus, cmd->offset);
1187   return result;
1188 }
1189
1190
1191 /**
1192  * _g_kdbus_GetNameOwner:
1193  *
1194  */
1195 GVariant *
1196 _g_kdbus_GetNameOwner (GDBusConnection  *connection,
1197                        const gchar      *name,
1198                        GError          **error)
1199 {
1200   return g_kdbus_GetConnInfo_internal (connection,
1201                                        name,
1202                                        G_BUS_CREDS_UNIQUE_NAME,
1203                                        error);
1204 }
1205
1206
1207 /**
1208  * _g_kdbus_GetConnectionUnixProcessID:
1209  *
1210  */
1211 GVariant *
1212 _g_kdbus_GetConnectionUnixProcessID (GDBusConnection  *connection,
1213                                      const gchar      *name,
1214                                      GError          **error)
1215 {
1216   return g_kdbus_GetConnInfo_internal (connection,
1217                                        name,
1218                                        G_BUS_CREDS_PID,
1219                                        error);
1220 }
1221
1222
1223 /**
1224  * _g_kdbus_GetConnectionUnixUser:
1225  *
1226  */
1227 GVariant *
1228 _g_kdbus_GetConnectionUnixUser (GDBusConnection  *connection,
1229                                 const gchar      *name,
1230                                 GError          **error)
1231 {
1232   return g_kdbus_GetConnInfo_internal (connection,
1233                                        name,
1234                                        G_BUS_CREDS_UID,
1235                                        error);
1236 }