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