chiark / gitweb /
32ffbce66875f833e5837cfa6ccc56b54b6b5dec
[elogind.git] / src / libsystemd / sd-bus / busctl.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright 2013 Lennart Poettering
7
8   systemd is free software; you can redistribute it and/or modify it
9   under the terms of the GNU Lesser General Public License as published by
10   the Free Software Foundation; either version 2.1 of the License, or
11   (at your option) any later version.
12
13   systemd is distributed in the hope that it will be useful, but
14   WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16   Lesser General Public License for more details.
17
18   You should have received a copy of the GNU Lesser General Public License
19   along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <getopt.h>
23
24 #include "strv.h"
25 #include "util.h"
26 #include "log.h"
27 #include "build.h"
28 #include "pager.h"
29 #include "xml.h"
30 #include "path-util.h"
31
32 #include "sd-bus.h"
33 #include "bus-message.h"
34 #include "bus-internal.h"
35 #include "bus-util.h"
36 #include "bus-dump.h"
37 #include "bus-signature.h"
38 #include "busctl-introspect.h"
39
40 static bool arg_no_pager = false;
41 static bool arg_legend = true;
42 static char *arg_address = NULL;
43 static bool arg_unique = false;
44 static bool arg_acquired = false;
45 static bool arg_activatable = false;
46 static bool arg_show_machine = false;
47 static char **arg_matches = NULL;
48 static BusTransport arg_transport = BUS_TRANSPORT_LOCAL;
49 static char *arg_host = NULL;
50 static bool arg_user = false;
51 static size_t arg_snaplen = 4096;
52 static bool arg_list = false;
53 static bool arg_quiet = false;
54
55 static void pager_open_if_enabled(void) {
56
57         /* Cache result before we open the pager */
58         if (arg_no_pager)
59                 return;
60
61         pager_open(false);
62 }
63
64 static int list_bus_names(sd_bus *bus, char **argv) {
65         _cleanup_strv_free_ char **acquired = NULL, **activatable = NULL;
66         _cleanup_free_ char **merged = NULL;
67         _cleanup_hashmap_free_ Hashmap *names = NULL;
68         char **i;
69         int r;
70         size_t max_i = 0;
71         unsigned n = 0;
72         void *v;
73         char *k;
74         Iterator iterator;
75
76         assert(bus);
77
78         if (!arg_unique && !arg_acquired && !arg_activatable)
79                 arg_unique = arg_acquired = arg_activatable = true;
80
81         r = sd_bus_list_names(bus, (arg_acquired || arg_unique) ? &acquired : NULL, arg_activatable ? &activatable : NULL);
82         if (r < 0) {
83                 log_error("Failed to list names: %s", strerror(-r));
84                 return r;
85         }
86
87         pager_open_if_enabled();
88
89         names = hashmap_new(&string_hash_ops);
90         if (!names)
91                 return log_oom();
92
93         STRV_FOREACH(i, acquired) {
94                 max_i = MAX(max_i, strlen(*i));
95
96                 r = hashmap_put(names, *i, INT_TO_PTR(1));
97                 if (r < 0) {
98                         log_error("Failed to add to hashmap: %s", strerror(-r));
99                         return r;
100                 }
101         }
102
103         STRV_FOREACH(i, activatable) {
104                 max_i = MAX(max_i, strlen(*i));
105
106                 r = hashmap_put(names, *i, INT_TO_PTR(2));
107                 if (r < 0 && r != -EEXIST) {
108                         log_error("Failed to add to hashmap: %s", strerror(-r));
109                         return r;
110                 }
111         }
112
113         merged = new(char*, hashmap_size(names) + 1);
114         HASHMAP_FOREACH_KEY(v, k, names, iterator)
115                 merged[n++] = k;
116
117         merged[n] = NULL;
118         strv_sort(merged);
119
120         if (arg_legend) {
121                 printf("%-*s %*s %-*s %-*s %-*s %-*s %-*s %-*s",
122                        (int) max_i, "NAME", 10, "PID", 15, "PROCESS", 16, "USER", 13, "CONNECTION", 25, "UNIT", 10, "SESSION", 19, "DESCRIPTION");
123
124                 if (arg_show_machine)
125                         puts(" MACHINE");
126                 else
127                         putchar('\n');
128         }
129
130         STRV_FOREACH(i, merged) {
131                 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
132                 sd_id128_t mid;
133
134                 if (hashmap_get(names, *i) == INT_TO_PTR(2)) {
135                         /* Activatable */
136
137                         printf("%-*s", (int) max_i, *i);
138                         printf("          - -               -                (activatable) -                         -         ");
139                         if (arg_show_machine)
140                                 puts(" -");
141                         else
142                                 putchar('\n');
143                         continue;
144
145                 }
146
147                 if (!arg_unique && (*i)[0] == ':')
148                         continue;
149
150                 if (!arg_acquired && (*i)[0] != ':')
151                         continue;
152
153                 printf("%-*s", (int) max_i, *i);
154
155                 r = sd_bus_get_name_creds(bus, *i,
156                                      SD_BUS_CREDS_UID|SD_BUS_CREDS_PID|SD_BUS_CREDS_COMM|
157                                      SD_BUS_CREDS_UNIQUE_NAME|SD_BUS_CREDS_UNIT|SD_BUS_CREDS_SESSION|
158                                      SD_BUS_CREDS_DESCRIPTION, &creds);
159                 if (r >= 0) {
160                         const char *unique, *session, *unit, *cn;
161                         pid_t pid;
162                         uid_t uid;
163
164                         r = sd_bus_creds_get_pid(creds, &pid);
165                         if (r >= 0) {
166                                 const char *comm = NULL;
167
168                                 sd_bus_creds_get_comm(creds, &comm);
169
170                                 printf(" %10lu %-15s", (unsigned long) pid, strna(comm));
171                         } else
172                                 fputs("          - -              ", stdout);
173
174                         r = sd_bus_creds_get_uid(creds, &uid);
175                         if (r >= 0) {
176                                 _cleanup_free_ char *u = NULL;
177
178                                 u = uid_to_name(uid);
179                                 if (!u)
180                                         return log_oom();
181
182                                 if (strlen(u) > 16)
183                                         u[16] = 0;
184
185                                 printf(" %-16s", u);
186                         } else
187                                 fputs(" -               ", stdout);
188
189                         r = sd_bus_creds_get_unique_name(creds, &unique);
190                         if (r >= 0)
191                                 printf(" %-13s", unique);
192                         else
193                                 fputs(" -            ", stdout);
194
195                         r = sd_bus_creds_get_unit(creds, &unit);
196                         if (r >= 0) {
197                                 _cleanup_free_ char *e;
198
199                                 e = ellipsize(unit, 25, 100);
200                                 if (!e)
201                                         return log_oom();
202
203                                 printf(" %-25s", e);
204                         } else
205                                 fputs(" -                        ", stdout);
206
207                         r = sd_bus_creds_get_session(creds, &session);
208                         if (r >= 0)
209                                 printf(" %-10s", session);
210                         else
211                                 fputs(" -         ", stdout);
212
213                         r = sd_bus_creds_get_description(creds, &cn);
214                         if (r >= 0)
215                                 printf(" %-19s", cn);
216                         else
217                                 fputs(" -                  ", stdout);
218
219                 } else
220                         printf("          - -               -                -             -                         -          -                  ");
221
222                 if (arg_show_machine) {
223                         r = sd_bus_get_name_machine_id(bus, *i, &mid);
224                         if (r >= 0) {
225                                 char m[SD_ID128_STRING_MAX];
226                                 printf(" %s\n", sd_id128_to_string(mid, m));
227                         } else
228                                 puts(" -");
229                 } else
230                         putchar('\n');
231         }
232
233         return 0;
234 }
235
236 static void print_subtree(const char *prefix, const char *path, char **l) {
237         const char *vertical, *space;
238         char **n;
239
240         /* We assume the list is sorted. Let's first skip over the
241          * entry we are looking at. */
242         for (;;) {
243                 if (!*l)
244                         return;
245
246                 if (!streq(*l, path))
247                         break;
248
249                 l++;
250         }
251
252         vertical = strappenda(prefix, draw_special_char(DRAW_TREE_VERTICAL));
253         space = strappenda(prefix, draw_special_char(DRAW_TREE_SPACE));
254
255         for (;;) {
256                 bool has_more = false;
257
258                 if (!*l || !path_startswith(*l, path))
259                         break;
260
261                 n = l + 1;
262                 for (;;) {
263                         if (!*n || !path_startswith(*n, path))
264                                 break;
265
266                         if (!path_startswith(*n, *l)) {
267                                 has_more = true;
268                                 break;
269                         }
270
271                         n++;
272                 }
273
274                 printf("%s%s%s\n", prefix, draw_special_char(has_more ? DRAW_TREE_BRANCH : DRAW_TREE_RIGHT), *l);
275
276                 print_subtree(has_more ? vertical : space, *l, l);
277                 l = n;
278         }
279 }
280
281 static void print_tree(const char *prefix, char **l) {
282
283         pager_open_if_enabled();
284
285         prefix = strempty(prefix);
286
287         if (arg_list) {
288                 char **i;
289
290                 STRV_FOREACH(i, l)
291                         printf("%s%s\n", prefix, *i);
292                 return;
293         }
294
295         if (strv_isempty(l)) {
296                 printf("No objects discovered.\n");
297                 return;
298         }
299
300         if (streq(l[0], "/") && !l[1]) {
301                 printf("Only root object discovered.\n");
302                 return;
303         }
304
305         print_subtree(prefix, "/", l);
306 }
307
308 static int on_path(const char *path, void *userdata) {
309         Set *paths = userdata;
310         int r;
311
312         assert(paths);
313
314         r = set_put_strdup(paths, path);
315         if (r < 0)
316                 return log_oom();
317
318         return 0;
319 }
320
321 static int find_nodes(sd_bus *bus, const char *service, const char *path, Set *paths) {
322         static const XMLIntrospectOps ops = {
323                 .on_path = on_path,
324         };
325
326         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
327         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
328         const char *xml;
329         int r;
330
331         r = sd_bus_call_method(bus, service, path, "org.freedesktop.DBus.Introspectable", "Introspect", &error, &reply, "");
332         if (r < 0) {
333                 log_error("Failed to introspect object %s of service %s: %s", path, service, bus_error_message(&error, r));
334                 return r;
335         }
336
337         r = sd_bus_message_read(reply, "s", &xml);
338         if (r < 0)
339                 return bus_log_parse_error(r);
340
341         return parse_xml_introspect(path, xml, &ops, paths);
342 }
343
344 static int tree_one(sd_bus *bus, const char *service, const char *prefix) {
345         _cleanup_set_free_free_ Set *paths = NULL, *done = NULL, *failed = NULL;
346         _cleanup_free_ char **l = NULL;
347         char *m;
348         int r;
349
350         paths = set_new(&string_hash_ops);
351         if (!paths)
352                 return log_oom();
353
354         done = set_new(&string_hash_ops);
355         if (!done)
356                 return log_oom();
357
358         failed = set_new(&string_hash_ops);
359         if (!failed)
360                 return log_oom();
361
362         m = strdup("/");
363         if (!m)
364                 return log_oom();
365
366         r = set_put(paths, m);
367         if (r < 0) {
368                 free(m);
369                 return log_oom();
370         }
371
372         for (;;) {
373                 _cleanup_free_ char *p = NULL;
374                 int q;
375
376                 p = set_steal_first(paths);
377                 if (!p)
378                         break;
379
380                 if (set_contains(done, p) ||
381                     set_contains(failed, p))
382                         continue;
383
384                 q = find_nodes(bus, service, p, paths);
385                 if (q < 0) {
386                         if (r >= 0)
387                                 r = q;
388
389                         q = set_put(failed, p);
390                 } else
391                         q = set_put(done, p);
392
393                 if (q < 0)
394                         return log_oom();
395
396                 assert(q != 0);
397                 p = NULL;
398         }
399
400         l = set_get_strv(done);
401         if (!l)
402                 return log_oom();
403
404         strv_sort(l);
405         print_tree(prefix, l);
406
407         fflush(stdout);
408
409         return r;
410 }
411
412 static int tree(sd_bus *bus, char **argv) {
413         char **i;
414         int r = 0;
415
416         if (!arg_unique && !arg_acquired)
417                 arg_acquired = true;
418
419         if (strv_length(argv) <= 1) {
420                 _cleanup_strv_free_ char **names = NULL;
421                 bool not_first = false;
422
423                 r = sd_bus_list_names(bus, &names, NULL);
424                 if (r < 0) {
425                         log_error("Failed to get name list: %s", strerror(-r));
426                         return r;
427                 }
428
429                 pager_open_if_enabled();
430
431                 STRV_FOREACH(i, names) {
432                         int q;
433
434                         if (!arg_unique && (*i)[0] == ':')
435                                 continue;
436
437                         if (!arg_acquired && (*i)[0] == ':')
438                                 continue;
439
440                         if (not_first)
441                                 printf("\n");
442
443                         printf("Service %s%s%s:\n", ansi_highlight(), *i, ansi_highlight_off());
444
445                         q = tree_one(bus, *i, NULL);
446                         if (q < 0 && r >= 0)
447                                 r = q;
448
449                         not_first = true;
450                 }
451         } else {
452                 pager_open_if_enabled();
453
454                 STRV_FOREACH(i, argv+1) {
455                         int q;
456
457                         if (i > argv+1)
458                                 printf("\n");
459
460                         if (argv[2])
461                                 printf("Service %s%s%s:\n", ansi_highlight(), *i, ansi_highlight_off());
462
463                         q = tree_one(bus, *i, NULL);
464                         if (q < 0 && r >= 0)
465                                 r = q;
466                 }
467         }
468
469         return r;
470 }
471
472 typedef struct Member {
473         const char *type;
474         char *interface;
475         char *name;
476         char *signature;
477         char *result;
478         bool writable;
479         uint64_t flags;
480 } Member;
481
482 static unsigned long member_hash_func(const void *p, const uint8_t hash_key[]) {
483         const Member *m = p;
484         unsigned long ul;
485
486         assert(m);
487         assert(m->type);
488
489         ul = string_hash_func(m->type, hash_key);
490
491         if (m->name)
492                 ul ^= string_hash_func(m->name, hash_key);
493
494         if (m->interface)
495                 ul ^= string_hash_func(m->interface, hash_key);
496
497         return ul;
498 }
499
500 static int member_compare_func(const void *a, const void *b) {
501         const Member *x = a, *y = b;
502         int d;
503
504         assert(x);
505         assert(y);
506         assert(x->type);
507         assert(y->type);
508
509         if (!x->interface && y->interface)
510                 return -1;
511         if (x->interface && !y->interface)
512                 return 1;
513         if (x->interface && y->interface) {
514                 d = strcmp(x->interface, y->interface);
515                 if (d != 0)
516                         return d;
517         }
518
519         d = strcmp(x->type, y->type);
520         if (d != 0)
521                 return d;
522
523         if (!x->name && y->name)
524                 return -1;
525         if (x->name && !y->name)
526                 return 1;
527         if (x->name && y->name)
528                 return strcmp(x->name, y->name);
529
530         return 0;
531 }
532
533 static int member_compare_funcp(const void *a, const void *b) {
534         const Member *const * x = (const Member *const *) a, * const *y = (const Member *const *) b;
535
536         return member_compare_func(*x, *y);
537 }
538
539 static void member_free(Member *m) {
540         if (!m)
541                 return;
542
543         free(m->interface);
544         free(m->name);
545         free(m->signature);
546         free(m->result);
547         free(m);
548 }
549
550 DEFINE_TRIVIAL_CLEANUP_FUNC(Member*, member_free);
551
552 static void member_set_free(Set *s) {
553         Member *m;
554
555         while ((m = set_steal_first(s)))
556                 member_free(m);
557
558         set_free(s);
559 }
560
561 DEFINE_TRIVIAL_CLEANUP_FUNC(Set*, member_set_free);
562
563 static int on_interface(const char *interface, uint64_t flags, void *userdata) {
564         _cleanup_(member_freep) Member *m;
565         Set *members = userdata;
566         int r;
567
568         assert(interface);
569         assert(members);
570
571         m = new0(Member, 1);
572         if (!m)
573                 return log_oom();
574
575         m->type = "interface";
576         m->flags = flags;
577
578         r = free_and_strdup(&m->interface, interface);
579         if (r < 0)
580                 return log_oom();
581
582         r = set_put(members, m);
583         if (r <= 0) {
584                 log_error("Duplicate interface");
585                 return -EINVAL;
586         }
587
588         m = NULL;
589         return 0;
590 }
591
592 static int on_method(const char *interface, const char *name, const char *signature, const char *result, uint64_t flags, void *userdata) {
593         _cleanup_(member_freep) Member *m;
594         Set *members = userdata;
595         int r;
596
597         assert(interface);
598         assert(name);
599
600         m = new0(Member, 1);
601         if (!m)
602                 return log_oom();
603
604         m->type = "method";
605         m->flags = flags;
606
607         r = free_and_strdup(&m->interface, interface);
608         if (r < 0)
609                 return log_oom();
610
611         r = free_and_strdup(&m->name, name);
612         if (r < 0)
613                 return log_oom();
614
615         r = free_and_strdup(&m->signature, signature);
616         if (r < 0)
617                 return log_oom();
618
619         r = free_and_strdup(&m->result, result);
620         if (r < 0)
621                 return log_oom();
622
623         r = set_put(members, m);
624         if (r <= 0) {
625                 log_error("Duplicate method");
626                 return -EINVAL;
627         }
628
629         m = NULL;
630         return 0;
631 }
632
633 static int on_signal(const char *interface, const char *name, const char *signature, uint64_t flags, void *userdata) {
634         _cleanup_(member_freep) Member *m;
635         Set *members = userdata;
636         int r;
637
638         assert(interface);
639         assert(name);
640
641         m = new0(Member, 1);
642         if (!m)
643                 return log_oom();
644
645         m->type = "signal";
646         m->flags = flags;
647
648         r = free_and_strdup(&m->interface, interface);
649         if (r < 0)
650                 return log_oom();
651
652         r = free_and_strdup(&m->name, name);
653         if (r < 0)
654                 return log_oom();
655
656         r = free_and_strdup(&m->signature, signature);
657         if (r < 0)
658                 return log_oom();
659
660         r = set_put(members, m);
661         if (r <= 0) {
662                 log_error("Duplicate signal");
663                 return -EINVAL;
664         }
665
666         m = NULL;
667         return 0;
668 }
669
670 static int on_property(const char *interface, const char *name, const char *signature, bool writable, uint64_t flags, void *userdata) {
671         _cleanup_(member_freep) Member *m;
672         Set *members = userdata;
673         int r;
674
675         assert(interface);
676         assert(name);
677
678         m = new0(Member, 1);
679         if (!m)
680                 return log_oom();
681
682         m->type = "property";
683         m->flags = flags;
684         m->writable = writable;
685
686         r = free_and_strdup(&m->interface, interface);
687         if (r < 0)
688                 return log_oom();
689
690         r = free_and_strdup(&m->name, name);
691         if (r < 0)
692                 return log_oom();
693
694         r = free_and_strdup(&m->signature, signature);
695         if (r < 0)
696                 return log_oom();
697
698         r = set_put(members, m);
699         if (r <= 0) {
700                 log_error("Duplicate property");
701                 return -EINVAL;
702         }
703
704         m = NULL;
705         return 0;
706 }
707
708 static const char *strdash(const char *x) {
709         return isempty(x) ? "-" : x;
710 }
711
712 static int introspect(sd_bus *bus, char **argv) {
713         static const struct hash_ops member_hash_ops = {
714                 .hash = member_hash_func,
715                 .compare = member_compare_func,
716         };
717
718         static const XMLIntrospectOps ops = {
719                 .on_interface = on_interface,
720                 .on_method = on_method,
721                 .on_signal = on_signal,
722                 .on_property = on_property,
723         };
724
725         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
726         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
727         _cleanup_(member_set_freep) Set *members = NULL;
728         Iterator i;
729         Member *m;
730         const char *xml;
731         int r;
732         unsigned name_width,  type_width, signature_width, result_width;
733         Member **sorted = NULL;
734         unsigned k = 0, j;
735
736         if (strv_length(argv) != 3) {
737                 log_error("Requires service and object path argument.");
738                 return -EINVAL;
739         }
740
741         members = set_new(&member_hash_ops);
742         if (!members)
743                 return log_oom();
744
745         r = sd_bus_call_method(bus, argv[1], argv[2], "org.freedesktop.DBus.Introspectable", "Introspect", &error, &reply, "");
746         if (r < 0) {
747                 log_error("Failed to introspect object %s of service %s: %s", argv[2], argv[1], bus_error_message(&error, r));
748                 return r;
749         }
750
751         r = sd_bus_message_read(reply, "s", &xml);
752         if (r < 0)
753                 return bus_log_parse_error(r);
754
755         r = parse_xml_introspect(argv[2], xml, &ops, members);
756         if (r < 0)
757                 return r;
758
759         pager_open_if_enabled();
760
761         name_width = strlen("NAME");
762         type_width = strlen("TYPE");
763         signature_width = strlen("SIGNATURE");
764         result_width = strlen("RESULT");
765
766         sorted = newa(Member*, set_size(members));
767
768         SET_FOREACH(m, members, i) {
769                 if (m->interface)
770                         name_width = MAX(name_width, strlen(m->interface));
771                 if (m->name)
772                         name_width = MAX(name_width, strlen(m->name) + 1);
773                 if (m->type)
774                         type_width = MAX(type_width, strlen(m->type));
775                 if (m->signature)
776                         signature_width = MAX(signature_width, strlen(m->signature));
777                 if (m->result)
778                         result_width = MAX(result_width, strlen(m->result));
779
780                 sorted[k++] = m;
781         }
782
783         assert(k == set_size(members));
784         qsort(sorted, k, sizeof(Member*), member_compare_funcp);
785
786         printf("%-*s %-*s %-*s %-*s %s\n",
787                (int) name_width, "NAME",
788                (int) type_width, "TYPE",
789                (int) signature_width, "SIGNATURE",
790                (int) result_width, "RESULT",
791                "FLAGS");
792
793         for (j = 0; j < k; j++) {
794                 bool is_interface;
795
796                 m = sorted[j];
797
798                 is_interface = streq(m->type, "interface");
799
800                 printf("%s%s%-*s%s %-*s %-*s %-*s%s%s%s%s%s%s\n",
801                        is_interface ? ansi_highlight() : "",
802                        is_interface ? "" : ".",
803                        - !is_interface + (int) name_width, strdash(streq_ptr(m->type, "interface") ? m->interface : m->name),
804                        is_interface ? ansi_highlight_off() : "",
805                        (int) type_width, strdash(m->type),
806                        (int) signature_width, strdash(m->signature),
807                        (int) result_width, strdash(m->result),
808                        (m->flags & SD_BUS_VTABLE_DEPRECATED) ? " deprecated" : (m->flags || m->writable ? "" : " -"),
809                        (m->flags & SD_BUS_VTABLE_METHOD_NO_REPLY) ? " no-reply" : "",
810                        (m->flags & SD_BUS_VTABLE_PROPERTY_CONST) ? " const" : "",
811                        (m->flags & SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE) ? " emits-change" : "",
812                        (m->flags & SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION) ? " emits-invalidation" : "",
813                        m->writable ? " writable" : "");
814         }
815
816         return 0;
817 }
818
819 static int message_dump(sd_bus_message *m, FILE *f) {
820         return bus_message_dump(m, f, BUS_MESSAGE_DUMP_WITH_HEADER);
821 }
822
823 static int message_pcap(sd_bus_message *m, FILE *f) {
824         return bus_message_pcap_frame(m, arg_snaplen, f);
825 }
826
827 static int monitor(sd_bus *bus, char *argv[], int (*dump)(sd_bus_message *m, FILE *f)) {
828         bool added_something = false;
829         char **i;
830         int r;
831
832         STRV_FOREACH(i, argv+1) {
833                 _cleanup_free_ char *m = NULL;
834
835                 if (!service_name_is_valid(*i)) {
836                         log_error("Invalid service name '%s'", *i);
837                         return -EINVAL;
838                 }
839
840                 m = strjoin("sender='", *i, "'", NULL);
841                 if (!m)
842                         return log_oom();
843
844                 r = sd_bus_add_match(bus, NULL, m, NULL, NULL);
845                 if (r < 0) {
846                         log_error("Failed to add match: %s", strerror(-r));
847                         return r;
848                 }
849
850                 added_something = true;
851         }
852
853         STRV_FOREACH(i, arg_matches) {
854                 r = sd_bus_add_match(bus, NULL, *i, NULL, NULL);
855                 if (r < 0) {
856                         log_error("Failed to add match: %s", strerror(-r));
857                         return r;
858                 }
859
860                 added_something = true;
861         }
862
863         if (!added_something) {
864                 r = sd_bus_add_match(bus, NULL, "", NULL, NULL);
865                 if (r < 0) {
866                         log_error("Failed to add match: %s", strerror(-r));
867                         return r;
868                 }
869         }
870
871         for (;;) {
872                 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
873
874                 r = sd_bus_process(bus, &m);
875                 if (r < 0) {
876                         log_error("Failed to process bus: %s", strerror(-r));
877                         return r;
878                 }
879
880                 if (m) {
881                         dump(m, stdout);
882                         continue;
883                 }
884
885                 if (r > 0)
886                         continue;
887
888                 r = sd_bus_wait(bus, (uint64_t) -1);
889                 if (r < 0) {
890                         log_error("Failed to wait for bus: %s", strerror(-r));
891                         return r;
892                 }
893         }
894 }
895
896 static int capture(sd_bus *bus, char *argv[]) {
897         int r;
898
899         if (isatty(fileno(stdout)) > 0) {
900                 log_error("Refusing to write message data to console, please redirect output to a file.");
901                 return -EINVAL;
902         }
903
904         bus_pcap_header(arg_snaplen, stdout);
905
906         r = monitor(bus, argv, message_pcap);
907         if (r < 0)
908                 return r;
909
910         if (ferror(stdout)) {
911                 log_error("Couldn't write capture file.");
912                 return -EIO;
913         }
914
915         return r;
916 }
917
918 static int status(sd_bus *bus, char *argv[]) {
919         _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
920         pid_t pid;
921         int r;
922
923         assert(bus);
924
925         if (strv_length(argv) != 2) {
926                 log_error("Expects one argument.");
927                 return -EINVAL;
928         }
929
930         r = parse_pid(argv[1], &pid);
931         if (r < 0)
932                 r = sd_bus_get_name_creds(bus, argv[1], _SD_BUS_CREDS_ALL, &creds);
933         else
934                 r = sd_bus_creds_new_from_pid(&creds, pid, _SD_BUS_CREDS_ALL);
935
936         if (r < 0) {
937                 log_error("Failed to get credentials: %s", strerror(-r));
938                 return r;
939         }
940
941         bus_creds_dump(creds, NULL, false);
942         return 0;
943 }
944
945 static int message_append_cmdline(sd_bus_message *m, const char *signature, char ***x) {
946         char **p;
947         int r;
948
949         assert(m);
950         assert(signature);
951         assert(x);
952
953         p = *x;
954
955         for (;;) {
956                 const char *v;
957                 char t;
958
959                 t = *signature;
960                 v = *p;
961
962                 if (t == 0)
963                         break;
964                 if (!v) {
965                         log_error("Too few parameters for signature.");
966                         return -EINVAL;
967                 }
968
969                 signature++;
970                 p++;
971
972                 switch (t) {
973
974                 case SD_BUS_TYPE_BOOLEAN:
975
976                         r = parse_boolean(v);
977                         if (r < 0) {
978                                 log_error("Failed to parse as boolean: %s", v);
979                                 return r;
980                         }
981
982                         r = sd_bus_message_append_basic(m, t, &r);
983                         break;
984
985                 case SD_BUS_TYPE_BYTE: {
986                         uint8_t z;
987
988                         r = safe_atou8(v, &z);
989                         if (r < 0) {
990                                 log_error("Failed to parse as byte (unsigned 8bit integer): %s", v);
991                                 return r;
992                         }
993
994                         r = sd_bus_message_append_basic(m, t, &z);
995                         break;
996                 }
997
998                 case SD_BUS_TYPE_INT16: {
999                         int16_t z;
1000
1001                         r = safe_atoi16(v, &z);
1002                         if (r < 0) {
1003                                 log_error("Failed to parse as signed 16bit integer: %s", v);
1004                                 return r;
1005                         }
1006
1007                         r = sd_bus_message_append_basic(m, t, &z);
1008                         break;
1009                 }
1010
1011                 case SD_BUS_TYPE_UINT16: {
1012                         uint16_t z;
1013
1014                         r = safe_atou16(v, &z);
1015                         if (r < 0) {
1016                                 log_error("Failed to parse as unsigned 16bit integer: %s", v);
1017                                 return r;
1018                         }
1019
1020                         r = sd_bus_message_append_basic(m, t, &z);
1021                         break;
1022                 }
1023
1024                 case SD_BUS_TYPE_INT32: {
1025                         int32_t z;
1026
1027                         r = safe_atoi32(v, &z);
1028                         if (r < 0) {
1029                                 log_error("Failed to parse as signed 32bit integer: %s", v);
1030                                 return r;
1031                         }
1032
1033                         r = sd_bus_message_append_basic(m, t, &z);
1034                         break;
1035                 }
1036
1037                 case SD_BUS_TYPE_UINT32: {
1038                         uint32_t z;
1039
1040                         r = safe_atou32(v, &z);
1041                         if (r < 0) {
1042                                 log_error("Failed to parse as unsigned 32bit integer: %s", v);
1043                                 return r;
1044                         }
1045
1046                         r = sd_bus_message_append_basic(m, t, &z);
1047                         break;
1048                 }
1049
1050                 case SD_BUS_TYPE_INT64: {
1051                         int64_t z;
1052
1053                         r = safe_atoi64(v, &z);
1054                         if (r < 0) {
1055                                 log_error("Failed to parse as signed 64bit integer: %s", v);
1056                                 return r;
1057                         }
1058
1059                         r = sd_bus_message_append_basic(m, t, &z);
1060                         break;
1061                 }
1062
1063                 case SD_BUS_TYPE_UINT64: {
1064                         uint64_t z;
1065
1066                         r = safe_atou64(v, &z);
1067                         if (r < 0) {
1068                                 log_error("Failed to parse as unsigned 64bit integer: %s", v);
1069                                 return r;
1070                         }
1071
1072                         r = sd_bus_message_append_basic(m, t, &z);
1073                         break;
1074                 }
1075
1076
1077                 case SD_BUS_TYPE_DOUBLE: {
1078                         double z;
1079
1080                         r = safe_atod(v, &z);
1081                         if (r < 0) {
1082                                 log_error("Failed to parse as double precision floating point: %s", v);
1083                                 return r;
1084                         }
1085
1086                         r = sd_bus_message_append_basic(m, t, &z);
1087                         break;
1088                 }
1089
1090                 case SD_BUS_TYPE_STRING:
1091                 case SD_BUS_TYPE_OBJECT_PATH:
1092                 case SD_BUS_TYPE_SIGNATURE:
1093
1094                         r = sd_bus_message_append_basic(m, t, v);
1095                         break;
1096
1097                 case SD_BUS_TYPE_ARRAY: {
1098                         uint32_t n;
1099                         size_t k;
1100
1101                         r = safe_atou32(v, &n);
1102                         if (r < 0) {
1103                                 log_error("Failed to parse number of array entries: %s", v);
1104                                 return r;
1105                         }
1106
1107                         r = signature_element_length(signature, &k);
1108                         if (r < 0) {
1109                                 log_error("Invalid array signature.");
1110                                 return r;
1111                         }
1112
1113                         {
1114                                 unsigned i;
1115                                 char s[k + 1];
1116                                 memcpy(s, signature, k);
1117                                 s[k] = 0;
1118
1119                                 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
1120                                 if (r < 0)
1121                                         return bus_log_create_error(r);
1122
1123                                 for (i = 0; i < n; i++) {
1124                                         r = message_append_cmdline(m, s, &p);
1125                                         if (r < 0)
1126                                                 return r;
1127                                 }
1128                         }
1129
1130                         signature += k;
1131
1132                         r = sd_bus_message_close_container(m);
1133                         break;
1134                 }
1135
1136                 case SD_BUS_TYPE_VARIANT:
1137                         r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, v);
1138                         if (r < 0)
1139                                 return bus_log_create_error(r);
1140
1141                         r = message_append_cmdline(m, v, &p);
1142                         if (r < 0)
1143                                 return r;
1144
1145                         r = sd_bus_message_close_container(m);
1146                         break;
1147
1148                 case SD_BUS_TYPE_STRUCT_BEGIN:
1149                 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
1150                         size_t k;
1151
1152                         signature--;
1153                         p--;
1154
1155                         r = signature_element_length(signature, &k);
1156                         if (r < 0) {
1157                                 log_error("Invalid struct/dict entry signature.");
1158                                 return r;
1159                         }
1160
1161                         {
1162                                 char s[k-1];
1163                                 memcpy(s, signature + 1, k - 2);
1164                                 s[k - 2] = 0;
1165
1166                                 r = sd_bus_message_open_container(m, t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
1167                                 if (r < 0)
1168                                         return bus_log_create_error(r);
1169
1170                                 r = message_append_cmdline(m, s, &p);
1171                                 if (r < 0)
1172                                         return r;
1173                         }
1174
1175                         signature += k;
1176
1177                         r = sd_bus_message_close_container(m);
1178                         break;
1179                 }
1180
1181                 case SD_BUS_TYPE_UNIX_FD:
1182                         log_error("UNIX file descriptor not supported as type.");
1183                         return -EINVAL;
1184
1185                 default:
1186                         log_error("Unknown signature type %c.", t);
1187                         return -EINVAL;
1188                 }
1189
1190                 if (r < 0)
1191                         return bus_log_create_error(r);
1192         }
1193
1194         *x = p;
1195         return 0;
1196 }
1197
1198 static int call(sd_bus *bus, char *argv[]) {
1199         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1200         _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
1201         int r;
1202
1203         assert(bus);
1204
1205         if (strv_length(argv) < 5) {
1206                 log_error("Expects at least four arguments.");
1207                 return -EINVAL;
1208         }
1209
1210         r = sd_bus_message_new_method_call(bus, &m, argv[1], argv[2], argv[3], argv[4]);
1211         if (r < 0) {
1212                 log_error("Failed to prepare bus message: %s", strerror(-r));
1213                 return r;
1214         }
1215
1216         if (!isempty(argv[5])) {
1217                 char **p;
1218
1219                 p = argv+6;
1220
1221                 r = message_append_cmdline(m, argv[5], &p);
1222                 if (r < 0)
1223                         return r;
1224
1225                 if (*p) {
1226                         log_error("Too many parameters for signature.");
1227                         return -EINVAL;
1228                 }
1229         }
1230
1231         r = sd_bus_call(bus, m, 0, &error, &reply);
1232         if (r < 0) {
1233                 log_error("%s", bus_error_message(&error, r));
1234                 return r;
1235         }
1236
1237         r = sd_bus_message_is_empty(reply);
1238         if (r < 0)
1239                 return bus_log_parse_error(r);
1240         if (r == 0 && !arg_quiet) {
1241                 pager_open_if_enabled();
1242                 bus_message_dump(reply, stdout, 0);
1243         }
1244
1245         return 0;
1246 }
1247
1248 static int get_property(sd_bus *bus, char *argv[]) {
1249         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1250         unsigned n;
1251         int r;
1252
1253         assert(bus);
1254
1255         n = strv_length(argv);
1256         if (n < 3) {
1257                 log_error("Expects at least three arguments.");
1258                 return -EINVAL;
1259         }
1260
1261         if (n < 5) {
1262                 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1263                 bool not_first = false;
1264
1265                 r = sd_bus_call_method(bus, argv[1], argv[2], "org.freedesktop.DBus.Properties", "GetAll", &error, &reply, "s", strempty(argv[3]));
1266                 if (r < 0) {
1267                         log_error("%s", bus_error_message(&error, r));
1268                         return r;
1269                 }
1270
1271                 r = sd_bus_message_enter_container(reply, 'a', "{sv}");
1272                 if (r < 0)
1273                         return bus_log_parse_error(r);
1274
1275                 for (;;) {
1276                         const char *name;
1277
1278                         r = sd_bus_message_enter_container(reply, 'e', "sv");
1279                         if (r < 0)
1280                                 return bus_log_parse_error(r);
1281
1282                         if (r == 0)
1283                                 break;
1284
1285                         r = sd_bus_message_read(reply, "s", &name);
1286                         if (r < 0)
1287                                 return bus_log_parse_error(r);
1288
1289                         if (not_first)
1290                                 printf("\n");
1291
1292                         printf("Property %s:\n", name);
1293
1294                         r = sd_bus_message_enter_container(reply, 'v', NULL);
1295                         if (r < 0)
1296                                 return bus_log_parse_error(r);
1297
1298                         pager_open_if_enabled();
1299                         bus_message_dump(reply, stdout, BUS_MESSAGE_DUMP_SUBTREE_ONLY);
1300
1301                         r = sd_bus_message_exit_container(reply);
1302                         if (r < 0)
1303                                 return bus_log_parse_error(r);
1304
1305                         r = sd_bus_message_exit_container(reply);
1306                         if (r < 0)
1307                                 return bus_log_parse_error(r);
1308
1309                         not_first = true;
1310                 }
1311
1312                 r = sd_bus_message_exit_container(reply);
1313                 if (r < 0)
1314                         return bus_log_parse_error(r);
1315         } else {
1316                 char **i;
1317
1318                 STRV_FOREACH(i, argv + 4) {
1319                         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1320
1321                         r = sd_bus_call_method(bus, argv[1], argv[2], "org.freedesktop.DBus.Properties", "Get", &error, &reply, "ss", argv[3], *i);
1322                         if (r < 0) {
1323                                 log_error("%s", bus_error_message(&error, r));
1324                                 return r;
1325                         }
1326
1327                         r = sd_bus_message_enter_container(reply, 'v', NULL);
1328                         if (r < 0)
1329                                 return bus_log_parse_error(r);
1330
1331                         if (i > argv + 4)
1332                                 printf("\n");
1333
1334                         if (argv[5])
1335                                 printf("Property %s:\n", *i);
1336
1337                         pager_open_if_enabled();
1338                         bus_message_dump(reply, stdout, BUS_MESSAGE_DUMP_SUBTREE_ONLY);
1339
1340                         r = sd_bus_message_exit_container(reply);
1341                         if (r < 0)
1342                                 return bus_log_parse_error(r);
1343                 }
1344         }
1345
1346         return 0;
1347 }
1348
1349 static int help(void) {
1350         printf("%s [OPTIONS...] {COMMAND} ...\n\n"
1351                "Introspect the bus.\n\n"
1352                "  -h --help               Show this help\n"
1353                "     --version            Show package version\n"
1354                "     --no-pager           Do not pipe output into a pager\n"
1355                "     --no-legend          Do not show the headers and footers\n"
1356                "     --system             Connect to system bus\n"
1357                "     --user               Connect to user bus\n"
1358                "  -H --host=[USER@]HOST   Operate on remote host\n"
1359                "  -M --machine=CONTAINER  Operate on local container\n"
1360                "     --address=ADDRESS    Connect to bus specified by address\n"
1361                "     --show-machine       Show machine ID column in list\n"
1362                "     --unique             Only show unique names\n"
1363                "     --acquired           Only show acquired names\n"
1364                "     --activatable        Only show activatable names\n"
1365                "     --match=MATCH        Only show matching messages\n"
1366                "     --list               Don't show tree, but simple object path list\n"
1367                "     --quiet              Don't show method call reply\n\n"
1368                "Commands:\n"
1369                "  list                    List bus names\n"
1370                "  status SERVICE          Show service name status\n"
1371                "  monitor [SERVICE...]    Show bus traffic\n"
1372                "  capture [SERVICE...]    Capture bus traffic as pcap\n"
1373                "  tree [SERVICE...]       Show object tree of service\n"
1374                "  introspect SERVICE PATH\n"
1375                "  call SERVICE OBJECT INTERFACE METHOD [SIGNATURE [ARGUMENT...]]\n"
1376                "                          Call a method\n"
1377                "  get-property SERVICE OBJECT [INTERFACE [PROPERTY...]]\n"
1378                "                          Get property value\n"
1379                "  help                    Show this help\n"
1380                , program_invocation_short_name);
1381
1382         return 0;
1383 }
1384
1385 static int parse_argv(int argc, char *argv[]) {
1386
1387         enum {
1388                 ARG_VERSION = 0x100,
1389                 ARG_NO_PAGER,
1390                 ARG_NO_LEGEND,
1391                 ARG_SYSTEM,
1392                 ARG_USER,
1393                 ARG_ADDRESS,
1394                 ARG_MATCH,
1395                 ARG_SHOW_MACHINE,
1396                 ARG_UNIQUE,
1397                 ARG_ACQUIRED,
1398                 ARG_ACTIVATABLE,
1399                 ARG_SIZE,
1400                 ARG_LIST,
1401         };
1402
1403         static const struct option options[] = {
1404                 { "help",         no_argument,       NULL, 'h'              },
1405                 { "version",      no_argument,       NULL, ARG_VERSION      },
1406                 { "no-pager",     no_argument,       NULL, ARG_NO_PAGER     },
1407                 { "no-legend",    no_argument,       NULL, ARG_NO_LEGEND    },
1408                 { "system",       no_argument,       NULL, ARG_SYSTEM       },
1409                 { "user",         no_argument,       NULL, ARG_USER         },
1410                 { "address",      required_argument, NULL, ARG_ADDRESS      },
1411                 { "show-machine", no_argument,       NULL, ARG_SHOW_MACHINE },
1412                 { "unique",       no_argument,       NULL, ARG_UNIQUE       },
1413                 { "acquired",     no_argument,       NULL, ARG_ACQUIRED     },
1414                 { "activatable",  no_argument,       NULL, ARG_ACTIVATABLE  },
1415                 { "match",        required_argument, NULL, ARG_MATCH        },
1416                 { "host",         required_argument, NULL, 'H'              },
1417                 { "machine",      required_argument, NULL, 'M'              },
1418                 { "size",         required_argument, NULL, ARG_SIZE         },
1419                 { "list",         no_argument,       NULL, ARG_LIST         },
1420                 { "quiet",        no_argument,       NULL, 'q'              },
1421                 {},
1422         };
1423
1424         int c, r;
1425
1426         assert(argc >= 0);
1427         assert(argv);
1428
1429         while ((c = getopt_long(argc, argv, "hH:M:q", options, NULL)) >= 0)
1430
1431                 switch (c) {
1432
1433                 case 'h':
1434                         return help();
1435
1436                 case ARG_VERSION:
1437                         puts(PACKAGE_STRING);
1438                         puts(SYSTEMD_FEATURES);
1439                         return 0;
1440
1441                 case ARG_NO_PAGER:
1442                         arg_no_pager = true;
1443                         break;
1444
1445                 case ARG_NO_LEGEND:
1446                         arg_legend = false;
1447                         break;
1448
1449                 case ARG_USER:
1450                         arg_user = true;
1451                         break;
1452
1453                 case ARG_SYSTEM:
1454                         arg_user = false;
1455                         break;
1456
1457                 case ARG_ADDRESS:
1458                         arg_address = optarg;
1459                         break;
1460
1461                 case ARG_SHOW_MACHINE:
1462                         arg_show_machine = true;
1463                         break;
1464
1465                 case ARG_UNIQUE:
1466                         arg_unique = true;
1467                         break;
1468
1469                 case ARG_ACQUIRED:
1470                         arg_acquired = true;
1471                         break;
1472
1473                 case ARG_ACTIVATABLE:
1474                         arg_activatable = true;
1475                         break;
1476
1477                 case ARG_MATCH:
1478                         if (strv_extend(&arg_matches, optarg) < 0)
1479                                 return log_oom();
1480                         break;
1481
1482                 case ARG_SIZE: {
1483                         off_t o;
1484
1485                         r = parse_size(optarg, 0, &o);
1486                         if (r < 0) {
1487                                 log_error("Failed to parse size: %s", optarg);
1488                                 return r;
1489                         }
1490
1491                         if ((off_t) (size_t) o !=  o) {
1492                                 log_error("Size out of range.");
1493                                 return -E2BIG;
1494                         }
1495
1496                         arg_snaplen = (size_t) o;
1497                         break;
1498                 }
1499
1500                 case ARG_LIST:
1501                         arg_list = true;
1502                         break;
1503
1504                 case 'H':
1505                         arg_transport = BUS_TRANSPORT_REMOTE;
1506                         arg_host = optarg;
1507                         break;
1508
1509                 case 'M':
1510                         arg_transport = BUS_TRANSPORT_CONTAINER;
1511                         arg_host = optarg;
1512                         break;
1513
1514                 case 'q':
1515                         arg_quiet = true;
1516                         break;
1517
1518                 case '?':
1519                         return -EINVAL;
1520
1521                 default:
1522                         assert_not_reached("Unhandled option");
1523                 }
1524
1525         return 1;
1526 }
1527
1528 static int busctl_main(sd_bus *bus, int argc, char *argv[]) {
1529         assert(bus);
1530
1531         if (optind >= argc ||
1532             streq(argv[optind], "list"))
1533                 return list_bus_names(bus, argv + optind);
1534
1535         if (streq(argv[optind], "monitor"))
1536                 return monitor(bus, argv + optind, message_dump);
1537
1538         if (streq(argv[optind], "capture"))
1539                 return capture(bus, argv + optind);
1540
1541         if (streq(argv[optind], "status"))
1542                 return status(bus, argv + optind);
1543
1544         if (streq(argv[optind], "tree"))
1545                 return tree(bus, argv + optind);
1546
1547         if (streq(argv[optind], "introspect"))
1548                 return introspect(bus, argv + optind);
1549
1550         if (streq(argv[optind], "call"))
1551                 return call(bus, argv + optind);
1552
1553         if (streq(argv[optind], "get-property"))
1554                 return get_property(bus, argv + optind);
1555
1556         if (streq(argv[optind], "help"))
1557                 return help();
1558
1559         log_error("Unknown command '%s'", argv[optind]);
1560         return -EINVAL;
1561 }
1562
1563 int main(int argc, char *argv[]) {
1564         _cleanup_bus_close_unref_ sd_bus *bus = NULL;
1565         int r;
1566
1567         log_parse_environment();
1568         log_open();
1569
1570         r = parse_argv(argc, argv);
1571         if (r <= 0)
1572                 goto finish;
1573
1574         r = sd_bus_new(&bus);
1575         if (r < 0) {
1576                 log_error("Failed to allocate bus: %s", strerror(-r));
1577                 goto finish;
1578         }
1579
1580         if (streq_ptr(argv[optind], "monitor") ||
1581             streq_ptr(argv[optind], "capture")) {
1582
1583                 r = sd_bus_set_monitor(bus, true);
1584                 if (r < 0) {
1585                         log_error("Failed to set monitor mode: %s", strerror(-r));
1586                         goto finish;
1587                 }
1588
1589                 r = sd_bus_negotiate_creds(bus, _SD_BUS_CREDS_ALL);
1590                 if (r < 0) {
1591                         log_error("Failed to enable credentials: %s", strerror(-r));
1592                         goto finish;
1593                 }
1594
1595                 r = sd_bus_negotiate_timestamp(bus, true);
1596                 if (r < 0) {
1597                         log_error("Failed to enable timestamps: %s", strerror(-r));
1598                         goto finish;
1599                 }
1600
1601                 r = sd_bus_negotiate_fds(bus, true);
1602                 if (r < 0) {
1603                         log_error("Failed to enable fds: %s", strerror(-r));
1604                         goto finish;
1605                 }
1606         }
1607
1608         if (arg_address)
1609                 r = sd_bus_set_address(bus, arg_address);
1610         else {
1611                 switch (arg_transport) {
1612
1613                 case BUS_TRANSPORT_LOCAL:
1614                         if (arg_user)
1615                                 r = bus_set_address_user(bus);
1616                         else
1617                                 r = bus_set_address_system(bus);
1618                         break;
1619
1620                 case BUS_TRANSPORT_REMOTE:
1621                         r = bus_set_address_system_remote(bus, arg_host);
1622                         break;
1623
1624                 case BUS_TRANSPORT_CONTAINER:
1625                         r = bus_set_address_system_container(bus, arg_host);
1626                         break;
1627
1628                 default:
1629                         assert_not_reached("Hmm, unknown transport type.");
1630                 }
1631         }
1632         if (r < 0) {
1633                 log_error("Failed to set address: %s", strerror(-r));
1634                 goto finish;
1635         }
1636
1637         r = sd_bus_set_bus_client(bus, true);
1638         if (r < 0) {
1639                 log_error("Failed to set bus client: %s", strerror(-r));
1640                 goto finish;
1641         }
1642
1643         r = sd_bus_start(bus);
1644         if (r < 0) {
1645                 log_error("Failed to connect to bus: %s", strerror(-r));
1646                 goto finish;
1647         }
1648
1649         r = busctl_main(bus, argc, argv);
1650
1651 finish:
1652         pager_close();
1653
1654         strv_free(arg_matches);
1655
1656         return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
1657 }