b96bc68ce691a0d39261a2d9fdc23acfc83f1d16
[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_GetBusId:
707  *
708  */
709 GVariant *
710 _g_kdbus_GetBusId (GDBusConnection  *connection,
711                    GError          **error)
712 {
713   GKdbus   *kdbus;
714   GVariant *result;
715   GString  *result_str;
716   guint     cnt;
717
718   result_str = g_string_new (NULL);
719   kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
720   if (kdbus == NULL)
721     {
722       g_set_error_literal (error,
723                            G_DBUS_ERROR,
724                            G_DBUS_ERROR_IO_ERROR,
725                            _("The connection is closed"));
726       g_string_free (result_str, TRUE);
727       return NULL;
728     }
729
730   for (cnt=0; cnt<16; cnt++)
731     g_string_append_printf (result_str, "%02x", kdbus->priv->bus_id[cnt]);
732
733   result = g_variant_new ("(s)", result_str->str);
734   g_string_free (result_str, TRUE);
735
736   return result;
737 }
738
739
740 /**
741  * _g_kdbus_GetListNames:
742  *
743  */
744 GVariant *
745 _g_kdbus_GetListNames (GDBusConnection  *connection,
746                        guint             list_name_type,
747                        GError          **error)
748 {
749   GKdbus *kdbus;
750   GVariant *result;
751   GVariantBuilder *builder;
752
753   struct kdbus_cmd_name_list cmd = {};
754   struct kdbus_name_list *name_list;
755   struct kdbus_cmd_name *name;
756
757   guint64 prev_id;
758   gint ret;
759
760   prev_id = 0;
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 (list_name_type)
772     cmd.flags = KDBUS_NAME_LIST_ACTIVATORS;                     /* ListActivatableNames */
773   else
774     cmd.flags = KDBUS_NAME_LIST_UNIQUE | KDBUS_NAME_LIST_NAMES; /* ListNames */
775
776   ret = ioctl(kdbus->priv->fd, KDBUS_CMD_NAME_LIST, &cmd);
777   if (ret < 0)
778     {
779       g_set_error (error,
780                    G_DBUS_ERROR,
781                    G_DBUS_ERROR_FAILED,
782                    _("Error listing names"));
783       return NULL;
784     }
785
786   name_list = (struct kdbus_name_list *) ((guint8 *) kdbus->priv->kdbus_buffer + cmd.offset);
787   builder = g_variant_builder_new (G_VARIANT_TYPE ("as"));
788
789   KDBUS_ITEM_FOREACH(name, name_list, names)
790     {
791       struct kdbus_item *item;
792       const gchar *item_name = "";
793
794       if ((cmd.flags & KDBUS_NAME_LIST_UNIQUE) && name->owner_id != prev_id)
795         {
796           GString *unique_name;
797
798           unique_name = g_string_new (NULL);
799           g_string_printf (unique_name, ":1.%llu", name->owner_id);
800           g_variant_builder_add (builder, "s", unique_name->str);
801           g_string_free (unique_name,TRUE);
802           prev_id = name->owner_id;
803         }
804
805        KDBUS_ITEM_FOREACH(item, name, items)
806          if (item->type == KDBUS_ITEM_NAME)
807            item_name = item->str;
808
809         if (g_dbus_is_name (item_name))
810           g_variant_builder_add (builder, "s", item_name);
811     }
812
813   result = g_variant_new ("(as)", builder);
814   g_variant_builder_unref (builder);
815
816   g_kdbus_free_data (kdbus, cmd.offset);
817   return result;
818 }
819
820
821 /**
822  * _g_kdbus_NameHasOwner_internal:
823  *
824  */
825 static gboolean
826 g_kdbus_NameHasOwner_internal (GKdbus       *kdbus,
827                                const gchar  *name,
828                                GError      **error)
829 {
830   struct kdbus_cmd_conn_info *cmd;
831   gssize size, len;
832   gint ret;
833
834   if (g_dbus_is_unique_name(name))
835     {
836        size = G_STRUCT_OFFSET (struct kdbus_cmd_conn_info, items);
837        cmd = g_alloca0 (size);
838        cmd->id = g_ascii_strtoull (name+3, NULL, 10);
839     }
840   else
841     {
842        len = strlen(name) + 1;
843        size = G_STRUCT_OFFSET (struct kdbus_cmd_conn_info, items) + KDBUS_ITEM_SIZE(len);
844        cmd = g_alloca0 (size);
845        cmd->items[0].size = KDBUS_ITEM_HEADER_SIZE + len;
846        cmd->items[0].type = KDBUS_ITEM_NAME;
847        memcpy (cmd->items[0].str, name, len);
848     }
849   cmd->size = size;
850
851   ret = ioctl(kdbus->priv->fd, KDBUS_CMD_CONN_INFO, cmd);
852   g_kdbus_free_data (kdbus, cmd->offset);
853
854   if (ret < 0)
855     return FALSE;
856   else
857     return TRUE;
858 }
859
860
861 /**
862  * _g_kdbus_GetListQueuedOwners:
863  *
864  */
865 GVariant *
866 _g_kdbus_GetListQueuedOwners (GDBusConnection  *connection,
867                               const gchar      *name,
868                               GError          **error)
869 {
870   GKdbus *kdbus;
871   GVariant *result;
872   GVariantBuilder *builder;
873   GString *unique_name;
874   gint ret;
875
876   struct kdbus_cmd_name_list cmd = {};
877   struct kdbus_name_list *name_list;
878   struct kdbus_cmd_name *kname;
879
880   kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
881   if (kdbus == NULL)
882     {
883       g_set_error_literal (error,
884                            G_DBUS_ERROR,
885                            G_DBUS_ERROR_IO_ERROR,
886                            _("The connection is closed"));
887       return NULL;
888     }
889
890   if (!g_dbus_is_name (name))
891     {
892       g_set_error (error,
893                    G_DBUS_ERROR,
894                    G_DBUS_ERROR_INVALID_ARGS,
895                    "Given bus name \"%s\" is not valid", name);
896       return NULL;
897     }
898
899   if (!g_kdbus_NameHasOwner_internal (kdbus, name, error))
900     {
901       g_set_error (error,
902                    G_DBUS_ERROR,
903                    G_DBUS_ERROR_NAME_HAS_NO_OWNER,
904                    "Could not get owner of name '%s': no such name", name);
905       return NULL;
906     }
907
908   cmd.flags = KDBUS_NAME_LIST_QUEUED;
909   ret = ioctl(kdbus->priv->fd, KDBUS_CMD_NAME_LIST, &cmd);
910   if (ret < 0)
911     {
912       g_set_error (error,
913                    G_DBUS_ERROR,
914                    G_DBUS_ERROR_FAILED,
915                    _("Error listing names"));
916       return NULL;
917     }
918
919   name_list = (struct kdbus_name_list *) ((guint8 *) kdbus->priv->kdbus_buffer + cmd.offset);
920
921   unique_name = g_string_new (NULL);
922   builder = g_variant_builder_new (G_VARIANT_TYPE ("as"));
923   KDBUS_ITEM_FOREACH(kname, name_list, names)
924     {
925       struct kdbus_item *item;
926       const char *item_name = "";
927
928       KDBUS_ITEM_FOREACH(item, kname, items)
929         if (item->type == KDBUS_ITEM_NAME)
930           item_name = item->str;
931
932       if (strcmp(item_name, name))
933         continue;
934
935       g_string_printf (unique_name, ":1.%llu", kname->owner_id);
936       g_variant_builder_add (builder, "s", item_name);
937     }
938
939   result = g_variant_new ("(as)", builder);
940   g_variant_builder_unref (builder);
941   g_string_free (unique_name,TRUE);
942
943   g_kdbus_free_data (kdbus, cmd.offset);
944   return result;
945 }
946
947
948 /**
949  * _g_kdbus_NameHasOwner:
950  *
951  */
952 GVariant *
953 _g_kdbus_NameHasOwner (GDBusConnection  *connection,
954                        const gchar      *name,
955                        GError          **error)
956 {
957   GKdbus *kdbus;
958   GVariant *result;
959
960   kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
961   if (kdbus == NULL)
962     {
963       g_set_error_literal (error,
964                            G_DBUS_ERROR,
965                            G_DBUS_ERROR_IO_ERROR,
966                            _("The connection is closed"));
967       return NULL;
968     }
969
970   if (!g_dbus_is_name (name))
971     {
972       g_set_error (error,
973                    G_DBUS_ERROR,
974                    G_DBUS_ERROR_INVALID_ARGS,
975                    "Given bus name \"%s\" is not valid", name);
976       return NULL;
977     }
978
979   if (!g_kdbus_NameHasOwner_internal (kdbus, name, error))
980     result = g_variant_new ("(b)", FALSE);
981   else
982     result = g_variant_new ("(b)", TRUE);
983
984   return result;
985 }
986
987
988 /**
989  * g_kdbus_GetConnInfo_internal:
990  *
991  */
992 static GVariant *
993 g_kdbus_GetConnInfo_internal (GDBusConnection  *connection,
994                               const gchar      *name,
995                               guint64           flag,
996                               GError          **error)
997 {
998   GKdbus *kdbus;
999   GVariant *result;
1000
1001   struct kdbus_cmd_conn_info *cmd;
1002   struct kdbus_conn_info *conn_info;
1003   struct kdbus_item *item;
1004   gssize size, len;
1005   gint ret;
1006
1007   result = NULL;
1008   kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
1009   if (kdbus == NULL)
1010     {
1011       g_set_error_literal (error,
1012                            G_DBUS_ERROR,
1013                            G_DBUS_ERROR_IO_ERROR,
1014                            _("The connection is closed"));
1015       return NULL;
1016     }
1017
1018   if (!g_dbus_is_name (name))
1019     {
1020       g_set_error (error,
1021                    G_DBUS_ERROR,
1022                    G_DBUS_ERROR_INVALID_ARGS,
1023                    "Given bus name \"%s\" is not valid", name);
1024       return NULL;
1025     }
1026
1027   if (!g_kdbus_NameHasOwner_internal (kdbus, name, error))
1028     {
1029       g_set_error (error,
1030                    G_DBUS_ERROR,
1031                    G_DBUS_ERROR_NAME_HAS_NO_OWNER,
1032                    "Could not get owner of name '%s': no such name", name);
1033       return NULL;
1034     }
1035
1036   if (g_dbus_is_unique_name(name))
1037     {
1038        size = G_STRUCT_OFFSET (struct kdbus_cmd_conn_info, items);
1039        cmd = g_alloca0 (size);
1040        cmd->id = g_ascii_strtoull (name+3, NULL, 10);
1041     }
1042   else
1043     {
1044        len = strlen(name) + 1;
1045        size = G_STRUCT_OFFSET (struct kdbus_cmd_conn_info, items) + KDBUS_ITEM_SIZE(len);
1046        cmd = g_alloca0 (size);
1047        cmd->items[0].size = KDBUS_ITEM_HEADER_SIZE + len;
1048        cmd->items[0].type = KDBUS_ITEM_NAME;
1049        memcpy (cmd->items[0].str, name, len);
1050     }
1051
1052   cmd->flags = KDBUS_ATTACH_NAMES;
1053   cmd->size = size;
1054
1055   ret = ioctl(kdbus->priv->fd, KDBUS_CMD_CONN_INFO, cmd);
1056   if (ret < 0)
1057     {
1058       g_set_error (error,
1059                    G_DBUS_ERROR,
1060                    G_DBUS_ERROR_FAILED,
1061                    _("Could not get connection info"));
1062       return NULL;
1063     }
1064
1065   conn_info = (struct kdbus_conn_info *) ((guint8 *) kdbus->priv->kdbus_buffer + cmd->offset);
1066
1067   /*
1068   if (conn_info->flags & KDBUS_HELLO_ACTIVATOR)
1069     {}
1070   */
1071
1072   if (flag == G_BUS_CREDS_UNIQUE_NAME)
1073     {
1074        GString *unique_name;
1075
1076        unique_name = g_string_new (NULL);
1077        g_string_printf (unique_name, ":1.%llu", (unsigned long long) conn_info->id);
1078        result = g_variant_new ("(s)", unique_name->str);
1079        g_string_free (unique_name,TRUE);
1080        goto exit;
1081     }
1082
1083   KDBUS_ITEM_FOREACH(item, conn_info, items)
1084    {
1085       switch (item->type)
1086         {
1087           case KDBUS_ITEM_CREDS:
1088
1089             if (flag == G_BUS_CREDS_PID)
1090               {
1091                 guint pid = item->creds.pid;
1092                 result = g_variant_new ("(u)", pid);
1093                 goto exit;
1094                }
1095
1096             if (flag == G_BUS_CREDS_UID)
1097               {
1098                 guint uid = item->creds.uid;
1099                 result = g_variant_new ("(u)", uid);
1100                 goto exit;
1101               }
1102
1103           case KDBUS_ITEM_SECLABEL:
1104           case KDBUS_ITEM_PID_COMM:
1105           case KDBUS_ITEM_TID_COMM:
1106           case KDBUS_ITEM_EXE:
1107           case KDBUS_ITEM_CMDLINE:
1108           case KDBUS_ITEM_CGROUP:
1109           case KDBUS_ITEM_CAPS:
1110           case KDBUS_ITEM_NAME:
1111           case KDBUS_ITEM_AUDIT:
1112             break;
1113         }
1114    }
1115
1116 exit:
1117   g_kdbus_free_data (kdbus, cmd->offset);
1118   return result;
1119 }
1120
1121
1122 /**
1123  * _g_kdbus_GetNameOwner:
1124  *
1125  */
1126 GVariant *
1127 _g_kdbus_GetNameOwner (GDBusConnection  *connection,
1128                        const gchar      *name,
1129                        GError          **error)
1130 {
1131   return g_kdbus_GetConnInfo_internal (connection,
1132                                        name,
1133                                        G_BUS_CREDS_UNIQUE_NAME,
1134                                        error);
1135 }
1136
1137
1138 /**
1139  * _g_kdbus_GetConnectionUnixProcessID:
1140  *
1141  */
1142 GVariant *
1143 _g_kdbus_GetConnectionUnixProcessID (GDBusConnection  *connection,
1144                                      const gchar      *name,
1145                                      GError          **error)
1146 {
1147   return g_kdbus_GetConnInfo_internal (connection,
1148                                        name,
1149                                        G_BUS_CREDS_PID,
1150                                        error);
1151 }
1152
1153
1154 /**
1155  * _g_kdbus_GetConnectionUnixUser:
1156  *
1157  */
1158 GVariant *
1159 _g_kdbus_GetConnectionUnixUser (GDBusConnection  *connection,
1160                                 const gchar      *name,
1161                                 GError          **error)
1162 {
1163   return g_kdbus_GetConnInfo_internal (connection,
1164                                        name,
1165                                        G_BUS_CREDS_UID,
1166                                        error);
1167 }