chiark / gitweb /
6c9fa763a756186841f86c088bf799041e812dec
[elogind.git] / src / systemctl / systemctl.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright 2010 Lennart Poettering
7   Copyright 2013 Marc-Antoine Perennou
8
9   systemd is free software; you can redistribute it and/or modify it
10   under the terms of the GNU Lesser General Public License as published by
11   the Free Software Foundation; either version 2.1 of the License, or
12   (at your option) any later version.
13
14   systemd is distributed in the hope that it will be useful, but
15   WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17   Lesser General Public License for more details.
18
19   You should have received a copy of the GNU Lesser General Public License
20   along with systemd; If not, see <http://www.gnu.org/licenses/>.
21 ***/
22
23 #include <sys/reboot.h>
24 #include <linux/reboot.h>
25 #include <sys/syscall.h>
26 #include <stdio.h>
27 #include <getopt.h>
28 #include <locale.h>
29 #include <stdbool.h>
30 #include <string.h>
31 #include <errno.h>
32 #include <sys/ioctl.h>
33 #include <termios.h>
34 #include <unistd.h>
35 #include <fcntl.h>
36 #include <sys/socket.h>
37 #include <sys/stat.h>
38 #include <stddef.h>
39 #include <sys/prctl.h>
40 #include <fnmatch.h>
41
42 #include "sd-daemon.h"
43 #include "sd-shutdown.h"
44 #include "sd-login.h"
45 #include "sd-bus.h"
46 #include "log.h"
47 #include "util.h"
48 #include "macro.h"
49 #include "set.h"
50 #include "utmp-wtmp.h"
51 #include "special.h"
52 #include "initreq.h"
53 #include "path-util.h"
54 #include "strv.h"
55 #include "cgroup-show.h"
56 #include "cgroup-util.h"
57 #include "list.h"
58 #include "path-lookup.h"
59 #include "conf-parser.h"
60 #include "exit-status.h"
61 #include "bus-errors.h"
62 #include "build.h"
63 #include "unit-name.h"
64 #include "pager.h"
65 #include "spawn-ask-password-agent.h"
66 #include "spawn-polkit-agent.h"
67 #include "install.h"
68 #include "logs-show.h"
69 #include "socket-util.h"
70 #include "fileio.h"
71 #include "bus-util.h"
72 #include "bus-message.h"
73 #include "bus-error.h"
74 #include "bus-errors.h"
75
76 static char **arg_types = NULL;
77 static char **arg_states = NULL;
78 static char **arg_properties = NULL;
79 static bool arg_all = false;
80 static bool original_stdout_is_tty;
81 static enum dependency {
82         DEPENDENCY_FORWARD,
83         DEPENDENCY_REVERSE,
84         DEPENDENCY_AFTER,
85         DEPENDENCY_BEFORE,
86         _DEPENDENCY_MAX
87 } arg_dependency = DEPENDENCY_FORWARD;
88 static const char *arg_job_mode = "replace";
89 static UnitFileScope arg_scope = UNIT_FILE_SYSTEM;
90 static bool arg_no_block = false;
91 static bool arg_no_legend = false;
92 static bool arg_no_pager = false;
93 static bool arg_no_wtmp = false;
94 static bool arg_no_wall = false;
95 static bool arg_no_reload = false;
96 static bool arg_show_types = false;
97 static bool arg_ignore_inhibitors = false;
98 static bool arg_dry = false;
99 static bool arg_quiet = false;
100 static bool arg_full = false;
101 static int arg_force = 0;
102 static bool arg_ask_password = true;
103 static bool arg_runtime = false;
104 static char **arg_wall = NULL;
105 static const char *arg_kill_who = NULL;
106 static int arg_signal = SIGTERM;
107 static const char *arg_root = NULL;
108 static usec_t arg_when = 0;
109 static enum action {
110         _ACTION_INVALID,
111         ACTION_SYSTEMCTL,
112         ACTION_HALT,
113         ACTION_POWEROFF,
114         ACTION_REBOOT,
115         ACTION_KEXEC,
116         ACTION_EXIT,
117         ACTION_SUSPEND,
118         ACTION_HIBERNATE,
119         ACTION_HYBRID_SLEEP,
120         ACTION_RUNLEVEL2,
121         ACTION_RUNLEVEL3,
122         ACTION_RUNLEVEL4,
123         ACTION_RUNLEVEL5,
124         ACTION_RESCUE,
125         ACTION_EMERGENCY,
126         ACTION_DEFAULT,
127         ACTION_RELOAD,
128         ACTION_REEXEC,
129         ACTION_RUNLEVEL,
130         ACTION_CANCEL_SHUTDOWN,
131         _ACTION_MAX
132 } arg_action = ACTION_SYSTEMCTL;
133 static BusTransport arg_transport = BUS_TRANSPORT_LOCAL;
134 static char *arg_host = NULL;
135 static unsigned arg_lines = 10;
136 static OutputMode arg_output = OUTPUT_SHORT;
137 static bool arg_plain = false;
138
139 static int daemon_reload(sd_bus *bus, char **args);
140 static int halt_now(enum action a);
141
142 static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet);
143
144 static char** strv_skip_first(char **strv) {
145         if (strv_length(strv) > 0)
146                 return strv + 1;
147         return NULL;
148 }
149
150 static void pager_open_if_enabled(void) {
151
152         if (arg_no_pager)
153                 return;
154
155         pager_open(false);
156 }
157
158 static void ask_password_agent_open_if_enabled(void) {
159
160         /* Open the password agent as a child process if necessary */
161
162         if (!arg_ask_password)
163                 return;
164
165         if (arg_scope != UNIT_FILE_SYSTEM)
166                 return;
167
168         if (arg_transport != BUS_TRANSPORT_LOCAL)
169                 return;
170
171         ask_password_agent_open();
172 }
173
174 #ifdef HAVE_LOGIND
175 static void polkit_agent_open_if_enabled(void) {
176
177         /* Open the polkit agent as a child process if necessary */
178
179         if (!arg_ask_password)
180                 return;
181
182         if (arg_scope != UNIT_FILE_SYSTEM)
183                 return;
184
185         if (arg_transport != BUS_TRANSPORT_LOCAL)
186                 return;
187
188         polkit_agent_open();
189 }
190 #endif
191
192 static int translate_bus_error_to_exit_status(int r, const sd_bus_error *error) {
193         assert(error);
194
195         if (!sd_bus_error_is_set(error))
196                 return r;
197
198         if (sd_bus_error_has_name(error, SD_BUS_ERROR_ACCESS_DENIED) ||
199             sd_bus_error_has_name(error, BUS_ERROR_ONLY_BY_DEPENDENCY) ||
200             sd_bus_error_has_name(error, BUS_ERROR_NO_ISOLATION) ||
201             sd_bus_error_has_name(error, BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE))
202                 return EXIT_NOPERMISSION;
203
204         if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT))
205                 return EXIT_NOTINSTALLED;
206
207         if (sd_bus_error_has_name(error, BUS_ERROR_JOB_TYPE_NOT_APPLICABLE) ||
208             sd_bus_error_has_name(error, SD_BUS_ERROR_NOT_SUPPORTED))
209                 return EXIT_NOTIMPLEMENTED;
210
211         if (sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED))
212                 return EXIT_NOTCONFIGURED;
213
214         if (r != 0)
215                 return r;
216
217         return EXIT_FAILURE;
218 }
219
220 static void warn_wall(enum action a) {
221         static const char *table[_ACTION_MAX] = {
222                 [ACTION_HALT]            = "The system is going down for system halt NOW!",
223                 [ACTION_REBOOT]          = "The system is going down for reboot NOW!",
224                 [ACTION_POWEROFF]        = "The system is going down for power-off NOW!",
225                 [ACTION_KEXEC]           = "The system is going down for kexec reboot NOW!",
226                 [ACTION_RESCUE]          = "The system is going down to rescue mode NOW!",
227                 [ACTION_EMERGENCY]       = "The system is going down to emergency mode NOW!",
228                 [ACTION_CANCEL_SHUTDOWN] = "The system shutdown has been cancelled NOW!"
229         };
230
231         if (arg_no_wall)
232                 return;
233
234         if (arg_wall) {
235                 _cleanup_free_ char *p;
236
237                 p = strv_join(arg_wall, " ");
238                 if (!p) {
239                         log_oom();
240                         return;
241                 }
242
243                 if (*p) {
244                         utmp_wall(p, NULL);
245                         return;
246                 }
247         }
248
249         if (!table[a])
250                 return;
251
252         utmp_wall(table[a], NULL);
253 }
254
255 static bool avoid_bus(void) {
256
257         if (running_in_chroot() > 0)
258                 return true;
259
260         if (sd_booted() <= 0)
261                 return true;
262
263         if (!isempty(arg_root))
264                 return true;
265
266         if (arg_scope == UNIT_FILE_GLOBAL)
267                 return true;
268
269         return false;
270 }
271
272 static int compare_unit_info(const void *a, const void *b) {
273         const UnitInfo *u = a, *v = b;
274         const char *d1, *d2;
275
276         d1 = strrchr(u->id, '.');
277         d2 = strrchr(v->id, '.');
278
279         if (d1 && d2) {
280                 int r;
281
282                 r = strcasecmp(d1, d2);
283                 if (r != 0)
284                         return r;
285         }
286
287         return strcasecmp(u->id, v->id);
288 }
289
290 static bool output_show_unit(const UnitInfo *u, char **patterns) {
291         const char *dot;
292
293         if (!strv_isempty(arg_states))
294                 return
295                         strv_contains(arg_states, u->load_state) ||
296                         strv_contains(arg_states, u->sub_state) ||
297                         strv_contains(arg_states, u->active_state);
298
299         if (!strv_isempty(patterns)) {
300                 char **pattern;
301
302                 STRV_FOREACH(pattern, patterns)
303                         if (fnmatch(*pattern, u->id, FNM_NOESCAPE) == 0)
304                                 return true;
305                 return false;
306         }
307
308         return (!arg_types || ((dot = strrchr(u->id, '.')) &&
309                                strv_find(arg_types, dot+1))) &&
310                 (arg_all || !(streq(u->active_state, "inactive")
311                               || u->following[0]) || u->job_id > 0);
312 }
313
314 static void output_units_list(const UnitInfo *unit_infos, unsigned c) {
315         unsigned id_len, max_id_len, load_len, active_len, sub_len, job_len, desc_len;
316         const UnitInfo *u;
317         unsigned n_shown = 0;
318         int job_count = 0;
319
320         max_id_len = sizeof("UNIT")-1;
321         load_len = sizeof("LOAD")-1;
322         active_len = sizeof("ACTIVE")-1;
323         sub_len = sizeof("SUB")-1;
324         job_len = sizeof("JOB")-1;
325         desc_len = 0;
326
327         for (u = unit_infos; u < unit_infos + c; u++) {
328                 max_id_len = MAX(max_id_len, strlen(u->id));
329                 load_len = MAX(load_len, strlen(u->load_state));
330                 active_len = MAX(active_len, strlen(u->active_state));
331                 sub_len = MAX(sub_len, strlen(u->sub_state));
332
333                 if (u->job_id != 0) {
334                         job_len = MAX(job_len, strlen(u->job_type));
335                         job_count++;
336                 }
337         }
338
339         if (!arg_full && original_stdout_is_tty) {
340                 unsigned basic_len;
341
342                 id_len = MIN(max_id_len, 25u);
343                 basic_len = 5 + id_len + 5 + active_len + sub_len;
344
345                 if (job_count)
346                         basic_len += job_len + 1;
347
348                 if (basic_len < (unsigned) columns()) {
349                         unsigned extra_len, incr;
350                         extra_len = columns() - basic_len;
351
352                         /* Either UNIT already got 25, or is fully satisfied.
353                          * Grant up to 25 to DESC now. */
354                         incr = MIN(extra_len, 25u);
355                         desc_len += incr;
356                         extra_len -= incr;
357
358                         /* split the remaining space between UNIT and DESC,
359                          * but do not give UNIT more than it needs. */
360                         if (extra_len > 0) {
361                                 incr = MIN(extra_len / 2, max_id_len - id_len);
362                                 id_len += incr;
363                                 desc_len += extra_len - incr;
364                         }
365                 }
366         } else
367                 id_len = max_id_len;
368
369         for (u = unit_infos; u < unit_infos + c; u++) {
370                 _cleanup_free_ char *e = NULL;
371                 const char *on_loaded, *off_loaded, *on = "";
372                 const char *on_active, *off_active, *off = "";
373
374                 if (!n_shown && !arg_no_legend) {
375                         printf("%-*s %-*s %-*s %-*s ",
376                                id_len, "UNIT",
377                                load_len, "LOAD",
378                                active_len, "ACTIVE",
379                                sub_len, "SUB");
380
381                         if (job_count)
382                                 printf("%-*s ", job_len, "JOB");
383
384                         if (!arg_full && arg_no_pager)
385                                 printf("%.*s\n", desc_len, "DESCRIPTION");
386                         else
387                                 printf("%s\n", "DESCRIPTION");
388                 }
389
390                 n_shown++;
391
392                 if (streq(u->load_state, "error") ||
393                     streq(u->load_state, "not-found")) {
394                         on_loaded = on = ansi_highlight_red();
395                         off_loaded = off = ansi_highlight_off();
396                 } else
397                         on_loaded = off_loaded = "";
398
399                 if (streq(u->active_state, "failed")) {
400                         on_active = on = ansi_highlight_red();
401                         off_active = off = ansi_highlight_off();
402                 } else
403                         on_active = off_active = "";
404
405                 e = arg_full ? NULL : ellipsize(u->id, id_len, 33);
406
407                 printf("%s%-*s%s %s%-*s%s %s%-*s %-*s%s %-*s",
408                        on, id_len, e ? e : u->id, off,
409                        on_loaded, load_len, u->load_state, off_loaded,
410                        on_active, active_len, u->active_state,
411                        sub_len, u->sub_state, off_active,
412                        job_count ? job_len + 1 : 0, u->job_id ? u->job_type : "");
413
414                 if (desc_len > 0)
415                         printf("%.*s\n", desc_len, u->description);
416                 else
417                         printf("%s\n", u->description);
418         }
419
420         if (!arg_no_legend) {
421                 const char *on, *off;
422
423                 if (n_shown) {
424                         printf("\nLOAD   = Reflects whether the unit definition was properly loaded.\n"
425                                "ACTIVE = The high-level unit activation state, i.e. generalization of SUB.\n"
426                                "SUB    = The low-level unit activation state, values depend on unit type.\n");
427                         if (job_count)
428                                 printf("JOB    = Pending job for the unit.\n");
429                         puts("");
430                         on = ansi_highlight();
431                         off = ansi_highlight_off();
432                 } else {
433                         on = ansi_highlight_red();
434                         off = ansi_highlight_off();
435                 }
436
437                 if (arg_all)
438                         printf("%s%u loaded units listed.%s\n"
439                                "To show all installed unit files use 'systemctl list-unit-files'.\n",
440                                on, n_shown, off);
441                 else
442                         printf("%s%u loaded units listed.%s Pass --all to see loaded but inactive units, too.\n"
443                                "To show all installed unit files use 'systemctl list-unit-files'.\n",
444                                on, n_shown, off);
445         }
446 }
447
448 static int get_unit_list(
449                 sd_bus *bus,
450                 sd_bus_message **_reply,
451                 UnitInfo **_unit_infos,
452                 char **patterns) {
453
454         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
455         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
456         _cleanup_free_ UnitInfo *unit_infos = NULL;
457         size_t size = 0;
458         int r, c = 0;
459         UnitInfo u;
460
461         assert(bus);
462         assert(_reply);
463         assert(_unit_infos);
464
465         r = sd_bus_call_method(
466                         bus,
467                         "org.freedesktop.systemd1",
468                         "/org/freedesktop/systemd1",
469                         "org.freedesktop.systemd1.Manager",
470                         "ListUnits",
471                         &error,
472                         &reply,
473                         NULL);
474         if (r < 0) {
475                 log_error("Failed to list units: %s", bus_error_message(&error, r));
476                 return r;
477         }
478
479         r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssssouso)");
480         if (r < 0)
481                 return bus_log_parse_error(r);
482
483         while ((r = bus_parse_unit_info(reply, &u)) > 0) {
484                 if (!output_show_unit(&u, patterns))
485                         continue;
486
487                 if (!GREEDY_REALLOC(unit_infos, size, c+1))
488                         return log_oom();
489
490                 unit_infos[c++] = u;
491         }
492         if (r < 0)
493                 return bus_log_parse_error(r);
494
495         r = sd_bus_message_exit_container(reply);
496         if (r < 0)
497                 return bus_log_parse_error(r);
498
499         *_reply = reply;
500         reply = NULL;
501
502         *_unit_infos = unit_infos;
503         unit_infos = NULL;
504
505         return c;
506 }
507
508 static int list_units(sd_bus *bus, char **args) {
509         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
510         _cleanup_free_ UnitInfo *unit_infos = NULL;
511         int r;
512
513         pager_open_if_enabled();
514
515         r = get_unit_list(bus, &reply, &unit_infos, strv_skip_first(args));
516         if (r < 0)
517                 return r;
518
519         qsort_safe(unit_infos, r, sizeof(UnitInfo), compare_unit_info);
520         output_units_list(unit_infos, r);
521
522         return 0;
523 }
524
525 static int get_triggered_units(
526                 sd_bus *bus,
527                 const char* path,
528                 char*** ret) {
529
530         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
531         int r;
532
533         r = sd_bus_get_property_strv(
534                         bus,
535                         "org.freedesktop.systemd1",
536                         path,
537                         "org.freedesktop.systemd1.Unit",
538                         "Triggers",
539                         &error,
540                         ret);
541
542         if (r < 0)
543                 log_error("Failed to determine triggers: %s", bus_error_message(&error, r));
544
545         return 0;
546 }
547
548 static int get_listening(
549                 sd_bus *bus,
550                 const char* unit_path,
551                 char*** listening) {
552
553         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
554         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
555         const char *type, *path;
556         int r, n = 0;
557
558         r = sd_bus_get_property(
559                         bus,
560                         "org.freedesktop.systemd1",
561                         unit_path,
562                         "org.freedesktop.systemd1.Socket",
563                         "Listen",
564                         &error,
565                         &reply,
566                         "a(ss)");
567         if (r < 0) {
568                 log_error("Failed to get list of listening sockets: %s", bus_error_message(&error, r));
569                 return r;
570         }
571
572         r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ss)");
573         if (r < 0)
574                 return bus_log_parse_error(r);
575
576         while ((r = sd_bus_message_read(reply, "(ss)", &type, &path)) > 0) {
577
578                 r = strv_extend(listening, type);
579                 if (r < 0)
580                         return log_oom();
581
582                 r = strv_extend(listening, path);
583                 if (r < 0)
584                         return log_oom();
585
586                 n++;
587         }
588         if (r < 0)
589                 return bus_log_parse_error(r);
590
591         r = sd_bus_message_exit_container(reply);
592         if (r < 0)
593                 return bus_log_parse_error(r);
594
595         return n;
596 }
597
598 struct socket_info {
599         const char* id;
600
601         char* type;
602         char* path;
603
604         /* Note: triggered is a list here, although it almost certainly
605          * will always be one unit. Nevertheless, dbus API allows for multiple
606          * values, so let's follow that.*/
607         char** triggered;
608
609         /* The strv above is shared. free is set only in the first one. */
610         bool own_triggered;
611 };
612
613 static int socket_info_compare(const struct socket_info *a, const struct socket_info *b) {
614         int o;
615
616         assert(a);
617         assert(b);
618
619         o = strcmp(a->path, b->path);
620         if (o == 0)
621                 o = strcmp(a->type, b->type);
622
623         return o;
624 }
625
626 static int output_sockets_list(struct socket_info *socket_infos, unsigned cs) {
627         struct socket_info *s;
628         unsigned pathlen = sizeof("LISTEN") - 1,
629                 typelen = (sizeof("TYPE") - 1) * arg_show_types,
630                 socklen = sizeof("UNIT") - 1,
631                 servlen = sizeof("ACTIVATES") - 1;
632         const char *on, *off;
633
634         for (s = socket_infos; s < socket_infos + cs; s++) {
635                 unsigned tmp = 0;
636                 char **a;
637
638                 socklen = MAX(socklen, strlen(s->id));
639                 if (arg_show_types)
640                         typelen = MAX(typelen, strlen(s->type));
641                 pathlen = MAX(pathlen, strlen(s->path));
642
643                 STRV_FOREACH(a, s->triggered)
644                         tmp += strlen(*a) + 2*(a != s->triggered);
645                 servlen = MAX(servlen, tmp);
646         }
647
648         if (cs) {
649                 if (!arg_no_legend)
650                         printf("%-*s %-*.*s%-*s %s\n",
651                                pathlen, "LISTEN",
652                                typelen + arg_show_types, typelen + arg_show_types, "TYPE ",
653                                socklen, "UNIT",
654                                "ACTIVATES");
655
656                 for (s = socket_infos; s < socket_infos + cs; s++) {
657                         char **a;
658
659                         if (arg_show_types)
660                                 printf("%-*s %-*s %-*s",
661                                        pathlen, s->path, typelen, s->type, socklen, s->id);
662                         else
663                                 printf("%-*s %-*s",
664                                        pathlen, s->path, socklen, s->id);
665                         STRV_FOREACH(a, s->triggered)
666                                 printf("%s %s",
667                                        a == s->triggered ? "" : ",", *a);
668                         printf("\n");
669                 }
670
671                 on = ansi_highlight();
672                 off = ansi_highlight_off();
673                 if (!arg_no_legend)
674                         printf("\n");
675         } else {
676                 on = ansi_highlight_red();
677                 off = ansi_highlight_off();
678         }
679
680         if (!arg_no_legend) {
681                 printf("%s%u sockets listed.%s\n", on, cs, off);
682                 if (!arg_all)
683                         printf("Pass --all to see loaded but inactive sockets, too.\n");
684         }
685
686         return 0;
687 }
688
689 static int list_sockets(sd_bus *bus, char **args) {
690         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
691         _cleanup_free_ UnitInfo *unit_infos = NULL;
692         _cleanup_free_ struct socket_info *socket_infos = NULL;
693         const UnitInfo *u;
694         struct socket_info *s;
695         unsigned cs = 0;
696         size_t size = 0;
697         int r = 0, n;
698
699         pager_open_if_enabled();
700
701         n = get_unit_list(bus, &reply, &unit_infos, strv_skip_first(args));
702         if (n < 0)
703                 return n;
704
705         for (u = unit_infos; u < unit_infos + n; u++) {
706                 _cleanup_strv_free_ char **listening = NULL, **triggered = NULL;
707                 int i, c;
708
709                 if (!endswith(u->id, ".socket"))
710                         continue;
711
712                 r = get_triggered_units(bus, u->unit_path, &triggered);
713                 if (r < 0)
714                         goto cleanup;
715
716                 c = get_listening(bus, u->unit_path, &listening);
717                 if (c < 0) {
718                         r = c;
719                         goto cleanup;
720                 }
721
722                 if (!GREEDY_REALLOC(socket_infos, size, cs + c)) {
723                         r = log_oom();
724                         goto cleanup;
725                 }
726
727                 for (i = 0; i < c; i++)
728                         socket_infos[cs + i] = (struct socket_info) {
729                                 .id = u->id,
730                                 .type = listening[i*2],
731                                 .path = listening[i*2 + 1],
732                                 .triggered = triggered,
733                                 .own_triggered = i==0,
734                         };
735
736                 /* from this point on we will cleanup those socket_infos */
737                 cs += c;
738                 free(listening);
739                 listening = triggered = NULL; /* avoid cleanup */
740         }
741
742         qsort_safe(socket_infos, cs, sizeof(struct socket_info),
743                    (__compar_fn_t) socket_info_compare);
744
745         output_sockets_list(socket_infos, cs);
746
747  cleanup:
748         assert(cs == 0 || socket_infos);
749         for (s = socket_infos; s < socket_infos + cs; s++) {
750                 free(s->type);
751                 free(s->path);
752                 if (s->own_triggered)
753                         strv_free(s->triggered);
754         }
755
756         return r;
757 }
758
759 static int get_next_elapse(
760                 sd_bus *bus,
761                 const char *path,
762                 dual_timestamp *next) {
763
764         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
765         dual_timestamp t;
766         int r;
767
768         assert(bus);
769         assert(path);
770         assert(next);
771
772         r = sd_bus_get_property_trivial(
773                         bus,
774                         "org.freedesktop.systemd1",
775                         path,
776                         "org.freedesktop.systemd1.Timer",
777                         "NextElapseUSecMonotonic",
778                         &error,
779                         't',
780                         &t.monotonic);
781         if (r < 0) {
782                 log_error("Failed to get next elapsation time: %s", bus_error_message(&error, r));
783                 return r;
784         }
785
786         r = sd_bus_get_property_trivial(
787                         bus,
788                         "org.freedesktop.systemd1",
789                         path,
790                         "org.freedesktop.systemd1.Timer",
791                         "NextElapseUSecRealtime",
792                         &error,
793                         't',
794                         &t.realtime);
795         if (r < 0) {
796                 log_error("Failed to get next elapsation time: %s", bus_error_message(&error, r));
797                 return r;
798         }
799
800         *next = t;
801         return 0;
802 }
803
804 struct timer_info {
805         const char* id;
806         usec_t next_elapse;
807         char** triggered;
808 };
809
810 static int timer_info_compare(const struct timer_info *a, const struct timer_info *b) {
811         assert(a);
812         assert(b);
813
814         if (a->next_elapse < b->next_elapse)
815                 return -1;
816         if (a->next_elapse > b->next_elapse)
817                 return 1;
818
819         return strcmp(a->id, b->id);
820 }
821
822 static int output_timers_list(struct timer_info *timer_infos, unsigned n) {
823         struct timer_info *t;
824         unsigned
825                 nextlen = sizeof("NEXT") - 1,
826                 leftlen = sizeof("LEFT") - 1,
827                 unitlen = sizeof("UNIT") - 1,
828                 activatelen = sizeof("ACTIVATES") - 1;
829
830         const char *on, *off;
831
832         assert(timer_infos || n == 0);
833
834         for (t = timer_infos; t < timer_infos + n; t++) {
835                 unsigned ul = 0;
836                 char **a;
837
838                 if (t->next_elapse > 0) {
839                         char tstamp[FORMAT_TIMESTAMP_MAX] = "", trel[FORMAT_TIMESTAMP_RELATIVE_MAX] = "";
840
841                         format_timestamp(tstamp, sizeof(tstamp), t->next_elapse);
842                         nextlen = MAX(nextlen, strlen(tstamp) + 1);
843
844                         format_timestamp_relative(trel, sizeof(trel), t->next_elapse);
845                         leftlen = MAX(leftlen, strlen(trel));
846                 }
847
848                 unitlen = MAX(unitlen, strlen(t->id));
849
850                 STRV_FOREACH(a, t->triggered)
851                         ul += strlen(*a) + 2*(a != t->triggered);
852                 activatelen = MAX(activatelen, ul);
853         }
854
855         if (n > 0) {
856                 if (!arg_no_legend)
857                         printf("%-*s %-*s %-*s %s\n",
858                                nextlen, "NEXT",
859                                leftlen, "LEFT",
860                                unitlen, "UNIT",
861                                         "ACTIVATES");
862
863                 for (t = timer_infos; t < timer_infos + n; t++) {
864                         char tstamp[FORMAT_TIMESTAMP_MAX] = "n/a", trel[FORMAT_TIMESTAMP_RELATIVE_MAX] = "n/a";
865                         char **a;
866
867                         format_timestamp(tstamp, sizeof(tstamp), t->next_elapse);
868                         format_timestamp_relative(trel, sizeof(trel), t->next_elapse);
869
870                         printf("%-*s %-*s %-*s",
871                                nextlen, tstamp, leftlen, trel, unitlen, t->id);
872
873                         STRV_FOREACH(a, t->triggered)
874                                 printf("%s %s",
875                                        a == t->triggered ? "" : ",", *a);
876                         printf("\n");
877                 }
878
879                 on = ansi_highlight();
880                 off = ansi_highlight_off();
881                 if (!arg_no_legend)
882                         printf("\n");
883         } else {
884                 on = ansi_highlight_red();
885                 off = ansi_highlight_off();
886         }
887
888         if (!arg_no_legend) {
889                 printf("%s%u timers listed.%s\n", on, n, off);
890                 if (!arg_all)
891                         printf("Pass --all to see loaded but inactive timers, too.\n");
892         }
893
894         return 0;
895 }
896
897 static int list_timers(sd_bus *bus, char **args) {
898
899         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
900         _cleanup_free_ struct timer_info *timer_infos = NULL;
901         _cleanup_free_ UnitInfo *unit_infos = NULL;
902         struct timer_info *t;
903         const UnitInfo *u;
904         size_t size = 0;
905         int n, c = 0;
906         dual_timestamp nw;
907         int r = 0;
908
909         pager_open_if_enabled();
910
911         n = get_unit_list(bus, &reply, &unit_infos, strv_skip_first(args));
912         if (n < 0)
913                 return n;
914
915         dual_timestamp_get(&nw);
916
917         for (u = unit_infos; u < unit_infos + n; u++) {
918                 _cleanup_strv_free_ char **triggered = NULL;
919                 dual_timestamp next;
920                 usec_t m;
921
922                 if (!endswith(u->id, ".timer"))
923                         continue;
924
925                 r = get_triggered_units(bus, u->unit_path, &triggered);
926                 if (r < 0)
927                         goto cleanup;
928
929                 r = get_next_elapse(bus, u->unit_path, &next);
930                 if (r < 0)
931                         goto cleanup;
932
933                 if (next.monotonic != (usec_t) -1 && next.monotonic > 0) {
934                         usec_t converted;
935
936                         if (next.monotonic > nw.monotonic)
937                                 converted = nw.realtime + (next.monotonic - nw.monotonic);
938                         else
939                                 converted = nw.realtime - (nw.monotonic - next.monotonic);
940
941                         if (next.realtime != (usec_t) -1 && next.realtime > 0)
942                                 m = MIN(converted, next.realtime);
943                         else
944                                 m = converted;
945                 } else
946                         m = next.realtime;
947
948                 if (!GREEDY_REALLOC(timer_infos, size, c+1)) {
949                         r = log_oom();
950                         goto cleanup;
951                 }
952
953                 timer_infos[c++] = (struct timer_info) {
954                         .id = u->id,
955                         .next_elapse = m,
956                         .triggered = triggered,
957                 };
958
959                 triggered = NULL; /* avoid cleanup */
960         }
961
962         qsort_safe(timer_infos, c, sizeof(struct timer_info),
963                    (__compar_fn_t) timer_info_compare);
964
965         output_timers_list(timer_infos, c);
966
967  cleanup:
968         for (t = timer_infos; t < timer_infos + c; t++)
969                 strv_free(t->triggered);
970
971         return r;
972 }
973
974 static int compare_unit_file_list(const void *a, const void *b) {
975         const char *d1, *d2;
976         const UnitFileList *u = a, *v = b;
977
978         d1 = strrchr(u->path, '.');
979         d2 = strrchr(v->path, '.');
980
981         if (d1 && d2) {
982                 int r;
983
984                 r = strcasecmp(d1, d2);
985                 if (r != 0)
986                         return r;
987         }
988
989         return strcasecmp(basename(u->path), basename(v->path));
990 }
991
992 static bool output_show_unit_file(const UnitFileList *u, char **patterns) {
993         const char *dot;
994
995         if (!strv_isempty(patterns)) {
996                 char **pattern;
997
998                 STRV_FOREACH(pattern, patterns)
999                         if (fnmatch(*pattern, basename(u->path), FNM_NOESCAPE) == 0)
1000                                 return true;
1001                 return false;
1002         }
1003
1004         return !arg_types || ((dot = strrchr(u->path, '.')) && strv_find(arg_types, dot+1));
1005 }
1006
1007 static void output_unit_file_list(const UnitFileList *units, unsigned c) {
1008         unsigned max_id_len, id_cols, state_cols, n_shown = 0;
1009         const UnitFileList *u;
1010
1011         max_id_len = sizeof("UNIT FILE")-1;
1012         state_cols = sizeof("STATE")-1;
1013
1014         for (u = units; u < units + c; u++) {
1015                 max_id_len = MAX(max_id_len, strlen(basename(u->path)));
1016                 state_cols = MAX(state_cols, strlen(unit_file_state_to_string(u->state)));
1017         }
1018
1019         if (!arg_full) {
1020                 unsigned basic_cols;
1021
1022                 id_cols = MIN(max_id_len, 25u);
1023                 basic_cols = 1 + id_cols + state_cols;
1024                 if (basic_cols < (unsigned) columns())
1025                         id_cols += MIN(columns() - basic_cols, max_id_len - id_cols);
1026         } else
1027                 id_cols = max_id_len;
1028
1029         if (!arg_no_legend)
1030                 printf("%-*s %-*s\n",
1031                        id_cols, "UNIT FILE",
1032                        state_cols, "STATE");
1033
1034         for (u = units; u < units + c; u++) {
1035                 _cleanup_free_ char *e = NULL;
1036                 const char *on, *off;
1037                 const char *id;
1038
1039                 n_shown++;
1040
1041                 if (u->state == UNIT_FILE_MASKED ||
1042                     u->state == UNIT_FILE_MASKED_RUNTIME ||
1043                     u->state == UNIT_FILE_DISABLED ||
1044                     u->state == UNIT_FILE_INVALID) {
1045                         on  = ansi_highlight_red();
1046                         off = ansi_highlight_off();
1047                 } else if (u->state == UNIT_FILE_ENABLED) {
1048                         on  = ansi_highlight_green();
1049                         off = ansi_highlight_off();
1050                 } else
1051                         on = off = "";
1052
1053                 id = basename(u->path);
1054
1055                 e = arg_full ? NULL : ellipsize(id, id_cols, 33);
1056
1057                 printf("%-*s %s%-*s%s\n",
1058                        id_cols, e ? e : id,
1059                        on, state_cols, unit_file_state_to_string(u->state), off);
1060         }
1061
1062         if (!arg_no_legend)
1063                 printf("\n%u unit files listed.\n", n_shown);
1064 }
1065
1066 static int list_unit_files(sd_bus *bus, char **args) {
1067         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1068         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1069         _cleanup_free_ UnitFileList *units = NULL;
1070         UnitFileList *unit;
1071         size_t size = 0;
1072         unsigned c = 0;
1073         const char *state;
1074         char *path;
1075         int r;
1076
1077         pager_open_if_enabled();
1078
1079         if (avoid_bus()) {
1080                 Hashmap *h;
1081                 UnitFileList *u;
1082                 Iterator i;
1083                 unsigned n_units;
1084
1085                 h = hashmap_new(string_hash_func, string_compare_func);
1086                 if (!h)
1087                         return log_oom();
1088
1089                 r = unit_file_get_list(arg_scope, arg_root, h);
1090                 if (r < 0) {
1091                         unit_file_list_free(h);
1092                         log_error("Failed to get unit file list: %s", strerror(-r));
1093                         return r;
1094                 }
1095
1096                 n_units = hashmap_size(h);
1097                 units = new(UnitFileList, n_units);
1098                 if (!units) {
1099                         unit_file_list_free(h);
1100                         return log_oom();
1101                 }
1102
1103                 HASHMAP_FOREACH(u, h, i) {
1104                         if (!output_show_unit_file(u, strv_skip_first(args)))
1105                                 continue;
1106
1107                         units[c++] = *u;
1108                         free(u);
1109                 }
1110
1111                 assert(c <= n_units);
1112                 hashmap_free(h);
1113         } else {
1114                 r = sd_bus_call_method(
1115                                 bus,
1116                                 "org.freedesktop.systemd1",
1117                                 "/org/freedesktop/systemd1",
1118                                 "org.freedesktop.systemd1.Manager",
1119                                 "ListUnitFiles",
1120                                 &error,
1121                                 &reply,
1122                                 NULL);
1123                 if (r < 0) {
1124                         log_error("Failed to list unit files: %s", bus_error_message(&error, r));
1125                         return r;
1126                 }
1127
1128                 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ss)");
1129                 if (r < 0)
1130                         return bus_log_parse_error(r);
1131
1132                 while ((r = sd_bus_message_read(reply, "(ss)", &path, &state)) > 0) {
1133
1134                         if (!GREEDY_REALLOC(units, size, c + 1))
1135                                 return log_oom();
1136
1137                         units[c] = (struct UnitFileList) {
1138                                 path,
1139                                 unit_file_state_from_string(state)
1140                         };
1141
1142                         if (output_show_unit_file(&units[c], strv_skip_first(args)))
1143                                 c ++;
1144
1145                 }
1146                 if (r < 0)
1147                         return bus_log_parse_error(r);
1148
1149                 r = sd_bus_message_exit_container(reply);
1150                 if (r < 0)
1151                         return bus_log_parse_error(r);
1152         }
1153
1154         if (c > 0) {
1155                 qsort(units, c, sizeof(UnitFileList), compare_unit_file_list);
1156                 output_unit_file_list(units, c);
1157         }
1158
1159         if (avoid_bus())
1160                 for (unit = units; unit < units + c; unit++)
1161                         free(unit->path);
1162
1163         return 0;
1164 }
1165
1166 static int list_dependencies_print(const char *name, int level, unsigned int branches, bool last) {
1167         _cleanup_free_ char *n = NULL;
1168         size_t max_len = MAX(columns(),20u);
1169         size_t len = 0;
1170         int i;
1171
1172         if (!arg_plain) {
1173
1174                 for (i = level - 1; i >= 0; i--) {
1175                         len += 2;
1176                         if (len > max_len - 3 && !arg_full) {
1177                                 printf("%s...\n",max_len % 2 ? "" : " ");
1178                                 return 0;
1179                         }
1180                         printf("%s", draw_special_char(branches & (1 << i) ? DRAW_TREE_VERT : DRAW_TREE_SPACE));
1181                 }
1182                 len += 2;
1183
1184                 if (len > max_len - 3 && !arg_full) {
1185                         printf("%s...\n",max_len % 2 ? "" : " ");
1186                         return 0;
1187                 }
1188
1189                 printf("%s", draw_special_char(last ? DRAW_TREE_RIGHT : DRAW_TREE_BRANCH));
1190         }
1191
1192         if (arg_full){
1193                 printf("%s\n", name);
1194                 return 0;
1195         }
1196
1197         n = ellipsize(name, max_len-len, 100);
1198         if (!n)
1199                 return log_oom();
1200
1201         printf("%s\n", n);
1202         return 0;
1203 }
1204
1205 static int list_dependencies_get_dependencies(sd_bus *bus, const char *name, char ***deps) {
1206
1207         static const char *dependencies[_DEPENDENCY_MAX] = {
1208                 [DEPENDENCY_FORWARD] = "Requires\0"
1209                                        "RequiresOverridable\0"
1210                                        "Requisite\0"
1211                                        "RequisiteOverridable\0"
1212                                        "Wants\0",
1213                 [DEPENDENCY_REVERSE] = "RequiredBy\0"
1214                                        "RequiredByOverridable\0"
1215                                        "WantedBy\0"
1216                                        "PartOf\0",
1217                 [DEPENDENCY_AFTER]   = "After\0",
1218                 [DEPENDENCY_BEFORE]  = "Before\0",
1219         };
1220
1221         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1222         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1223         _cleanup_strv_free_ char **ret = NULL;
1224         _cleanup_free_ char *path = NULL;
1225         int r;
1226
1227         assert(bus);
1228         assert(name);
1229         assert(deps);
1230         assert_cc(ELEMENTSOF(dependencies) == _DEPENDENCY_MAX);
1231
1232         path = unit_dbus_path_from_name(name);
1233         if (!path)
1234                 return log_oom();
1235
1236         r = sd_bus_call_method(
1237                         bus,
1238                         "org.freedesktop.systemd1",
1239                         path,
1240                         "org.freedesktop.DBus.Properties",
1241                         "GetAll",
1242                         &error,
1243                         &reply,
1244                         "s", "org.freedesktop.systemd1.Unit");
1245         if (r < 0) {
1246                 log_error("Failed to get properties of %s: %s", name, bus_error_message(&error, r));
1247                 return r;
1248         }
1249
1250         r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
1251         if (r < 0)
1252                 return bus_log_parse_error(r);
1253
1254         while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
1255                 const char *prop;
1256
1257                 r = sd_bus_message_read(reply, "s", &prop);
1258                 if (r < 0)
1259                         return bus_log_parse_error(r);
1260
1261                 if (!nulstr_contains(dependencies[arg_dependency], prop)) {
1262                         r = sd_bus_message_skip(reply, "v");
1263                         if (r < 0)
1264                                 return bus_log_parse_error(r);
1265                 } else {
1266
1267                         r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, "as");
1268                         if (r < 0)
1269                                 return bus_log_parse_error(r);
1270
1271                         r = bus_message_read_strv_extend(reply, &ret);
1272                         if (r < 0)
1273                                 return bus_log_parse_error(r);
1274
1275                         r = sd_bus_message_exit_container(reply);
1276                         if (r < 0)
1277                                 return bus_log_parse_error(r);
1278                 }
1279
1280                 r = sd_bus_message_exit_container(reply);
1281                 if (r < 0)
1282                         return bus_log_parse_error(r);
1283
1284         }
1285         if (r < 0)
1286                 return bus_log_parse_error(r);
1287
1288         r = sd_bus_message_exit_container(reply);
1289         if (r < 0)
1290                 return bus_log_parse_error(r);
1291
1292         *deps = ret;
1293         ret = NULL;
1294
1295         return 0;
1296 }
1297
1298 static int list_dependencies_compare(const void *_a, const void *_b) {
1299         const char **a = (const char**) _a, **b = (const char**) _b;
1300
1301         if (unit_name_to_type(*a) == UNIT_TARGET && unit_name_to_type(*b) != UNIT_TARGET)
1302                 return 1;
1303         if (unit_name_to_type(*a) != UNIT_TARGET && unit_name_to_type(*b) == UNIT_TARGET)
1304                 return -1;
1305
1306         return strcasecmp(*a, *b);
1307 }
1308
1309 static int list_dependencies_one(
1310                 sd_bus *bus,
1311                 const char *name,
1312                 int level,
1313                 char ***units,
1314                 unsigned int branches) {
1315
1316         _cleanup_strv_free_ char **deps = NULL, **u;
1317         char **c;
1318         int r = 0;
1319
1320         assert(bus);
1321         assert(name);
1322         assert(units);
1323
1324         u = strv_append(*units, name);
1325         if (!u)
1326                 return log_oom();
1327
1328         r = list_dependencies_get_dependencies(bus, name, &deps);
1329         if (r < 0)
1330                 return r;
1331
1332         qsort_safe(deps, strv_length(deps), sizeof (char*), list_dependencies_compare);
1333
1334         STRV_FOREACH(c, deps) {
1335                 int state;
1336
1337                 if (strv_contains(u, *c)) {
1338                         if (!arg_plain) {
1339                                 r = list_dependencies_print("...", level + 1, (branches << 1) | (c[1] == NULL ? 0 : 1), 1);
1340                                 if (r < 0)
1341                                         return r;
1342                         }
1343                         continue;
1344                 }
1345
1346                 state = check_one_unit(bus, *c, "activating\0active\0reloading\0", true);
1347                 if (state > 0)
1348                         printf("%s%s%s", ansi_highlight_green(), draw_special_char(DRAW_BLACK_CIRCLE), ansi_highlight_off());
1349                 else
1350                         printf("%s%s%s", ansi_highlight_red(), draw_special_char(DRAW_BLACK_CIRCLE), ansi_highlight_off());
1351
1352                 r = list_dependencies_print(*c, level, branches, c[1] == NULL);
1353                 if (r < 0)
1354                         return r;
1355
1356                 if (arg_all || unit_name_to_type(*c) == UNIT_TARGET) {
1357                        r = list_dependencies_one(bus, *c, level + 1, &u, (branches << 1) | (c[1] == NULL ? 0 : 1));
1358                        if (r < 0)
1359                                return r;
1360                 }
1361         }
1362
1363         if (arg_plain) {
1364                 strv_free(*units);
1365                 *units = u;
1366                 u = NULL;
1367         }
1368
1369         return 0;
1370 }
1371
1372 static int list_dependencies(sd_bus *bus, char **args) {
1373         _cleanup_strv_free_ char **units = NULL;
1374         _cleanup_free_ char *unit = NULL;
1375         const char *u;
1376
1377         assert(bus);
1378
1379         if (args[1]) {
1380                 unit = unit_name_mangle(args[1]);
1381                 if (!unit)
1382                         return log_oom();
1383                 u = unit;
1384         } else
1385                 u = SPECIAL_DEFAULT_TARGET;
1386
1387         pager_open_if_enabled();
1388
1389         puts(u);
1390
1391         return list_dependencies_one(bus, u, 0, &units, 0);
1392 }
1393
1394 static int get_default(sd_bus *bus, char **args) {
1395         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1396         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1397         _cleanup_free_ char *_path = NULL;
1398         const char *path;
1399         int r;
1400
1401         if (!bus || avoid_bus()) {
1402                 r = unit_file_get_default(arg_scope, arg_root, &_path);
1403                 if (r < 0) {
1404                         log_error("Failed to get default target: %s", strerror(-r));
1405                         return r;
1406                 }
1407                 path = _path;
1408
1409         } else {
1410                 r = sd_bus_call_method(
1411                                 bus,
1412                                 "org.freedesktop.systemd1",
1413                                 "/org/freedesktop/systemd1",
1414                                 "org.freedesktop.systemd1.Manager",
1415                                 "GetDefaultTarget",
1416                                 &error,
1417                                 &reply,
1418                                 NULL);
1419                 if (r < 0) {
1420                         log_error("Failed to get default target: %s", bus_error_message(&error, -r));
1421                         return r;
1422                 }
1423
1424                 r = sd_bus_message_read(reply, "s", &path);
1425                 if (r < 0)
1426                         return bus_log_parse_error(r);
1427         }
1428
1429         if (path)
1430                 printf("%s\n", path);
1431
1432         return 0;
1433 }
1434
1435 static void dump_unit_file_changes(const UnitFileChange *changes, unsigned n_changes) {
1436         unsigned i;
1437
1438         assert(changes || n_changes == 0);
1439
1440         for (i = 0; i < n_changes; i++) {
1441                 if (changes[i].type == UNIT_FILE_SYMLINK)
1442                         log_info("ln -s '%s' '%s'", changes[i].source, changes[i].path);
1443                 else
1444                         log_info("rm '%s'", changes[i].path);
1445         }
1446 }
1447
1448 static int deserialize_and_dump_unit_file_changes(sd_bus_message *m) {
1449         const char *type, *path, *source;
1450         int r;
1451
1452         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sss)");
1453         if (r < 0)
1454                 return bus_log_parse_error(r);
1455
1456         while ((r = sd_bus_message_read(m, "(sss)", &type, &path, &source)) > 0) {
1457                 if (!arg_quiet) {
1458                         if (streq(type, "symlink"))
1459                                 log_info("ln -s '%s' '%s'", source, path);
1460                         else
1461                                 log_info("rm '%s'", path);
1462                 }
1463         }
1464         if (r < 0)
1465                 return bus_log_parse_error(r);
1466
1467         r = sd_bus_message_exit_container(m);
1468         if (r < 0)
1469                 return bus_log_parse_error(r);
1470
1471         return 0;
1472 }
1473
1474 static int set_default(sd_bus *bus, char **args) {
1475         _cleanup_free_ char *unit = NULL;
1476         UnitFileChange *changes = NULL;
1477         unsigned n_changes = 0;
1478         int r;
1479
1480         unit = unit_name_mangle_with_suffix(args[1], ".target");
1481         if (!unit)
1482                 return log_oom();
1483
1484         if (!bus || avoid_bus()) {
1485                 r = unit_file_set_default(arg_scope, arg_root, unit, arg_force, &changes, &n_changes);
1486                 if (r < 0) {
1487                         log_error("Failed to set default target: %s", strerror(-r));
1488                         return r;
1489                 }
1490
1491                 if (!arg_quiet)
1492                         dump_unit_file_changes(changes, n_changes);
1493
1494                 r = 0;
1495         } else {
1496                 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1497                 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1498
1499                 r = sd_bus_call_method(
1500                                 bus,
1501                                 "org.freedesktop.systemd1",
1502                                 "/org/freedesktop/systemd1",
1503                                 "org.freedesktop.systemd1.Manager",
1504                                 "SetDefaultTarget",
1505                                 &error,
1506                                 &reply,
1507                                 "sb", unit, arg_force);
1508                 if (r < 0) {
1509                         log_error("Failed to set default target: %s", bus_error_message(&error, -r));
1510                         return r;
1511                 }
1512
1513                 r = deserialize_and_dump_unit_file_changes(reply);
1514                 if (r < 0)
1515                         return r;
1516
1517                 /* Try to reload if enabeld */
1518                 if (!arg_no_reload)
1519                         r = daemon_reload(bus, args);
1520                 else
1521                         r = 0;
1522         }
1523
1524         unit_file_changes_free(changes, n_changes);
1525
1526         return r;
1527 }
1528
1529 struct job_info {
1530         uint32_t id;
1531         const char *name, *type, *state;
1532 };
1533
1534 static void output_jobs_list(const struct job_info* jobs, unsigned n, bool skipped) {
1535         unsigned id_len, unit_len, type_len, state_len;
1536         const struct job_info *j;
1537         const char *on, *off;
1538         bool shorten = false;
1539
1540         assert(n == 0 || jobs);
1541
1542         if (n == 0) {
1543                 on = ansi_highlight_green();
1544                 off = ansi_highlight_off();
1545
1546                 printf("%sNo jobs %s.%s\n", on, skipped ? "listed" : "running", off);
1547                 return;
1548         }
1549
1550         pager_open_if_enabled();
1551
1552         id_len = sizeof("JOB")-1;
1553         unit_len = sizeof("UNIT")-1;
1554         type_len = sizeof("TYPE")-1;
1555         state_len = sizeof("STATE")-1;
1556
1557         for (j = jobs; j < jobs + n; j++) {
1558                 uint32_t id = j->id;
1559                 assert(j->name && j->type && j->state);
1560
1561                 id_len = MAX(id_len, DECIMAL_STR_WIDTH(id));
1562                 unit_len = MAX(unit_len, strlen(j->name));
1563                 type_len = MAX(type_len, strlen(j->type));
1564                 state_len = MAX(state_len, strlen(j->state));
1565         }
1566
1567         if (!arg_full && id_len + 1 + unit_len + type_len + 1 + state_len > columns()) {
1568                 unit_len = MAX(33u, columns() - id_len - type_len - state_len - 3);
1569                 shorten = true;
1570         }
1571
1572         if (!arg_no_legend)
1573                 printf("%*s %-*s %-*s %-*s\n",
1574                        id_len, "JOB",
1575                        unit_len, "UNIT",
1576                        type_len, "TYPE",
1577                        state_len, "STATE");
1578
1579         for (j = jobs; j < jobs + n; j++) {
1580                 _cleanup_free_ char *e = NULL;
1581
1582                 if (streq(j->state, "running")) {
1583                         on = ansi_highlight();
1584                         off = ansi_highlight_off();
1585                 } else
1586                         on = off = "";
1587
1588                 e = shorten ? ellipsize(j->name, unit_len, 33) : NULL;
1589                 printf("%*u %s%-*s%s %-*s %s%-*s%s\n",
1590                        id_len, j->id,
1591                        on, unit_len, e ? e : j->name, off,
1592                        type_len, j->type,
1593                        on, state_len, j->state, off);
1594         }
1595
1596         if (!arg_no_legend) {
1597                 on = ansi_highlight();
1598                 off = ansi_highlight_off();
1599
1600                 printf("\n%s%u jobs listed%s.\n", on, n, off);
1601         }
1602 }
1603
1604 static bool output_show_job(struct job_info *job, char **patterns) {
1605         if (!strv_isempty(patterns)) {
1606                 char **pattern;
1607
1608                 STRV_FOREACH(pattern, patterns)
1609                         if (fnmatch(*pattern, job->name, FNM_NOESCAPE) == 0)
1610                                 return true;
1611                 return false;
1612         }
1613
1614         return true;
1615 }
1616
1617 static int list_jobs(sd_bus *bus, char **args) {
1618         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1619         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1620         const char *name, *type, *state, *job_path, *unit_path;
1621         _cleanup_free_ struct job_info *jobs = NULL;
1622         size_t size = 0;
1623         unsigned c = 0;
1624         uint32_t id;
1625         int r;
1626         bool skipped = false;
1627
1628         r = sd_bus_call_method(
1629                         bus,
1630                         "org.freedesktop.systemd1",
1631                         "/org/freedesktop/systemd1",
1632                         "org.freedesktop.systemd1.Manager",
1633                         "ListJobs",
1634                         &error,
1635                         &reply,
1636                         NULL);
1637         if (r < 0) {
1638                 log_error("Failed to list jobs: %s", bus_error_message(&error, r));
1639                 return r;
1640         }
1641
1642         r = sd_bus_message_enter_container(reply, 'a', "(usssoo)");
1643         if (r < 0)
1644                 return bus_log_parse_error(r);
1645
1646         while ((r = sd_bus_message_read(reply, "(usssoo)", &id, &name, &type, &state, &job_path, &unit_path)) > 0) {
1647                 struct job_info job = { id, name, type, state };
1648
1649                 if (!output_show_job(&job, strv_skip_first(args))) {
1650                         skipped = true;
1651                         continue;
1652                 }
1653
1654                 if (!GREEDY_REALLOC(jobs, size, c + 1))
1655                         return log_oom();
1656
1657                 jobs[c++] = job;
1658         }
1659         if (r < 0)
1660                 return bus_log_parse_error(r);
1661
1662         r = sd_bus_message_exit_container(reply);
1663         if (r < 0)
1664                 return bus_log_parse_error(r);
1665
1666         output_jobs_list(jobs, c, skipped);
1667         return r;
1668 }
1669
1670 static int cancel_job(sd_bus *bus, char **args) {
1671         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1672         char **name;
1673
1674         assert(args);
1675
1676         if (strv_length(args) <= 1)
1677                 return daemon_reload(bus, args);
1678
1679         STRV_FOREACH(name, args+1) {
1680                 uint32_t id;
1681                 int r;
1682
1683                 r = safe_atou32(*name, &id);
1684                 if (r < 0) {
1685                         log_error("Failed to parse job id \"%s\": %s", *name, strerror(-r));
1686                         return r;
1687                 }
1688
1689                 r = sd_bus_call_method(
1690                                 bus,
1691                                 "org.freedesktop.systemd1",
1692                                 "/org/freedesktop/systemd1",
1693                                 "org.freedesktop.systemd1.Manager",
1694                                 "CancelJob",
1695                                 &error,
1696                                 NULL,
1697                                 "u", id);
1698                 if (r < 0) {
1699                         log_error("Failed to cancel job %u: %s", (unsigned) id, bus_error_message(&error, r));
1700                         return r;
1701                 }
1702         }
1703
1704         return 0;
1705 }
1706
1707 static int need_daemon_reload(sd_bus *bus, const char *unit) {
1708         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1709         _cleanup_free_ char *n = NULL;
1710         const char *path;
1711         int b, r;
1712
1713         /* We ignore all errors here, since this is used to show a
1714          * warning only */
1715
1716         n = unit_name_mangle(unit);
1717         if (!n)
1718                 return -ENOMEM;
1719
1720         /* We don't use unit_dbus_path_from_name() directly since we
1721          * don't want to load the unit if it isn't loaded. */
1722
1723         r = sd_bus_call_method(
1724                         bus,
1725                         "org.freedesktop.systemd1",
1726                         "/org/freedesktop/systemd1",
1727                         "org.freedesktop.systemd1.Manager",
1728                         "GetUnit",
1729                         NULL,
1730                         &reply,
1731                         "s", n);
1732         if (r < 0)
1733                 return r;
1734
1735         r = sd_bus_message_read(reply, "o", &path);
1736         if (r < 0)
1737                 return r;
1738
1739         r = sd_bus_get_property_trivial(
1740                         bus,
1741                         "org.freedesktop.systemd1",
1742                         path,
1743                         "org.freedesktop.systemd1.Unit",
1744                         "NeedDaemonReload",
1745                         NULL,
1746                         'b', &b);
1747         if (r < 0)
1748                 return r;
1749
1750         return b;
1751 }
1752
1753 typedef struct WaitData {
1754         Set *set;
1755
1756         char *name;
1757         char *result;
1758 } WaitData;
1759
1760 static int wait_filter(sd_bus *bus, sd_bus_message *m, void *data, sd_bus_error *error) {
1761         WaitData *d = data;
1762
1763         assert(bus);
1764         assert(m);
1765         assert(d);
1766
1767         log_debug("Got D-Bus request: %s.%s() on %s",
1768                   sd_bus_message_get_interface(m),
1769                   sd_bus_message_get_member(m),
1770                   sd_bus_message_get_path(m));
1771
1772         if (sd_bus_message_is_signal(m, "org.freedesktop.DBus.Local", "Disconnected")) {
1773                 log_error("Warning! D-Bus connection terminated.");
1774                 sd_bus_close(bus);
1775         } else if (sd_bus_message_is_signal(m, "org.freedesktop.systemd1.Manager", "JobRemoved")) {
1776                 uint32_t id;
1777                 const char *path, *result, *unit;
1778                 char *ret;
1779                 int r;
1780
1781                 r = sd_bus_message_read(m, "uoss", &id, &path, &unit, &result);
1782                 if (r >= 0) {
1783                         ret = set_remove(d->set, (char*) path);
1784                         if (!ret)
1785                                 return 0;
1786
1787                         free(ret);
1788
1789                         if (!isempty(result))
1790                                 d->result = strdup(result);
1791
1792                         if (!isempty(unit))
1793                                 d->name = strdup(unit);
1794
1795                         return 0;
1796                 }
1797 #ifndef NOLEGACY
1798                 r = sd_bus_message_read(m, "uos", &id, &path, &result);
1799                 if (r >= 0) {
1800                         ret = set_remove(d->set, (char*) path);
1801                         if (!ret)
1802                                 return 0;
1803
1804                         free(ret);
1805
1806                         if (*result)
1807                                 d->result = strdup(result);
1808
1809                         return 0;
1810                 }
1811 #endif
1812
1813                 bus_log_parse_error(r);
1814         }
1815
1816         return 0;
1817 }
1818
1819 static int enable_wait_for_jobs(sd_bus *bus) {
1820         int r;
1821
1822         assert(bus);
1823
1824         r = sd_bus_add_match(
1825                         bus,
1826                         "type='signal',"
1827                         "sender='org.freedesktop.systemd1',"
1828                         "interface='org.freedesktop.systemd1.Manager',"
1829                         "member='JobRemoved',"
1830                         "path='/org/freedesktop/systemd1'",
1831                         NULL, NULL);
1832         if (r < 0) {
1833                 log_error("Failed to add match");
1834                 return -EIO;
1835         }
1836
1837         /* This is slightly dirty, since we don't undo the match registrations. */
1838         return 0;
1839 }
1840
1841 static int bus_process_wait(sd_bus *bus) {
1842         int r;
1843
1844         for (;;) {
1845                 r = sd_bus_process(bus, NULL);
1846                 if (r < 0)
1847                         return r;
1848                 if (r > 0)
1849                         return 0;
1850                 r = sd_bus_wait(bus, (uint64_t) -1);
1851                 if (r < 0)
1852                         return r;
1853         }
1854 }
1855
1856 static int check_wait_response(WaitData *d) {
1857         int r = 0;
1858
1859         assert(d->result);
1860
1861         if (!arg_quiet) {
1862                 if (streq(d->result, "timeout"))
1863                         log_error("Job for %s timed out.", strna(d->name));
1864                 else if (streq(d->result, "canceled"))
1865                         log_error("Job for %s canceled.", strna(d->name));
1866                 else if (streq(d->result, "dependency"))
1867                         log_error("A dependency job for %s failed. See 'journalctl -xn' for details.", strna(d->name));
1868                 else if (!streq(d->result, "done") && !streq(d->result, "skipped"))
1869                         log_error("Job for %s failed. See 'systemctl status %s' and 'journalctl -xn' for details.", strna(d->name), strna(d->name));
1870         }
1871
1872         if (streq(d->result, "timeout"))
1873                 r = -ETIME;
1874         else if (streq(d->result, "canceled"))
1875                 r = -ECANCELED;
1876         else if (streq(d->result, "dependency"))
1877                 r = -EIO;
1878         else if (!streq(d->result, "done") && !streq(d->result, "skipped"))
1879                 r = -EIO;
1880
1881         return r;
1882 }
1883
1884 static int wait_for_jobs(sd_bus *bus, Set *s) {
1885         WaitData d = { .set = s };
1886         int r = 0, q;
1887
1888         assert(bus);
1889         assert(s);
1890
1891         q = sd_bus_add_filter(bus, wait_filter, &d);
1892         if (q < 0)
1893                 return log_oom();
1894
1895         while (!set_isempty(s)) {
1896                 q = bus_process_wait(bus);
1897                 if (q < 0)
1898                         return q;
1899
1900                 if (d.result) {
1901                         q = check_wait_response(&d);
1902                         /* Return the first error as it is most likely to be
1903                          * meaningful. */
1904                         if (q < 0 && r == 0)
1905                                 r = q;
1906                 }
1907
1908                 free(d.name);
1909                 d.name = NULL;
1910
1911                 free(d.result);
1912                 d.result = NULL;
1913         }
1914
1915         q = sd_bus_remove_filter(bus, wait_filter, &d);
1916         if (q < 0 && r == 0)
1917                 r = q;
1918
1919         return r;
1920 }
1921
1922 static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet) {
1923         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1924         _cleanup_free_ char *n = NULL, *state = NULL;
1925         const char *path;
1926         int r;
1927
1928         assert(name);
1929
1930         n = unit_name_mangle(name);
1931         if (!n)
1932                 return log_oom();
1933
1934         /* We don't use unit_dbus_path_from_name() directly since we
1935          * don't want to load the unit if it isn't loaded. */
1936
1937         r = sd_bus_call_method(
1938                         bus,
1939                         "org.freedesktop.systemd1",
1940                         "/org/freedesktop/systemd1",
1941                         "org.freedesktop.systemd1.Manager",
1942                         "GetUnit",
1943                         NULL,
1944                         &reply,
1945                         "s", n);
1946         if (r < 0) {
1947                 if (!quiet)
1948                         puts("unknown");
1949                 return 0;
1950         }
1951
1952         r = sd_bus_message_read(reply, "o", &path);
1953         if (r < 0)
1954                 return bus_log_parse_error(r);
1955
1956         r = sd_bus_get_property_string(
1957                         bus,
1958                         "org.freedesktop.systemd1",
1959                         path,
1960                         "org.freedesktop.systemd1.Unit",
1961                         "ActiveState",
1962                         NULL,
1963                         &state);
1964         if (r < 0) {
1965                 if (!quiet)
1966                         puts("unknown");
1967                 return 0;
1968         }
1969
1970         if (!quiet)
1971                 puts(state);
1972
1973         return nulstr_contains(good_states, state);
1974 }
1975
1976 static int check_triggering_units(
1977                 sd_bus *bus,
1978                 const char *name) {
1979
1980         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1981         _cleanup_free_ char *path = NULL, *n = NULL, *state = NULL;
1982         _cleanup_strv_free_ char **triggered_by = NULL;
1983         bool print_warning_label = true;
1984         char **i;
1985         int r;
1986
1987         n = unit_name_mangle(name);
1988         if (!n)
1989                 return log_oom();
1990
1991         path = unit_dbus_path_from_name(n);
1992         if (!path)
1993                 return log_oom();
1994
1995         r = sd_bus_get_property_string(
1996                         bus,
1997                         "org.freedesktop.systemd1",
1998                         path,
1999                         "org.freedesktop.systemd1.Unit",
2000                         "LoadState",
2001                         &error,
2002                         &state);
2003         if (r < 0) {
2004                 log_error("Failed to get load state of %s: %s", n, bus_error_message(&error, r));
2005                 return r;
2006         }
2007
2008         if (streq(state, "masked"))
2009                 return 0;
2010
2011         r = sd_bus_get_property_strv(
2012                         bus,
2013                         "org.freedesktop.systemd1",
2014                         path,
2015                         "org.freedesktop.systemd1.Unit",
2016                         "TriggeredBy",
2017                         &error,
2018                         &triggered_by);
2019         if (r < 0) {
2020                 log_error("Failed to get triggered by array of %s: %s", n, bus_error_message(&error, r));
2021                 return r;
2022         }
2023
2024         STRV_FOREACH(i, triggered_by) {
2025                 r = check_one_unit(bus, *i, "active\0reloading\0", true);
2026                 if (r < 0) {
2027                         log_error("Failed to check unit: %s", strerror(-r));
2028                         return r;
2029                 }
2030
2031                 if (r == 0)
2032                         continue;
2033
2034                 if (print_warning_label) {
2035                         log_warning("Warning: Stopping %s, but it can still be activated by:", n);
2036                         print_warning_label = false;
2037                 }
2038
2039                 log_warning("  %s", *i);
2040         }
2041
2042         return 0;
2043 }
2044
2045 static int start_unit_one(
2046                 sd_bus *bus,
2047                 const char *method,
2048                 const char *name,
2049                 const char *mode,
2050                 sd_bus_error *error,
2051                 Set *s) {
2052
2053         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2054         _cleanup_free_ char *n;
2055         const char *path;
2056         int r;
2057
2058         assert(method);
2059         assert(name);
2060         assert(mode);
2061         assert(error);
2062
2063         n = unit_name_mangle(name);
2064         if (!n)
2065                 return log_oom();
2066
2067         r = sd_bus_call_method(
2068                         bus,
2069                         "org.freedesktop.systemd1",
2070                         "/org/freedesktop/systemd1",
2071                         "org.freedesktop.systemd1.Manager",
2072                         method,
2073                         error,
2074                         &reply,
2075                         "ss", n, mode);
2076         if (r < 0) {
2077                 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
2078                         /* There's always a fallback possible for
2079                          * legacy actions. */
2080                         return -EADDRNOTAVAIL;
2081
2082                 log_error("Failed to start %s: %s", name, bus_error_message(error, r));
2083                 return r;
2084         }
2085
2086         r = sd_bus_message_read(reply, "o", &path);
2087         if (r < 0)
2088                 return bus_log_parse_error(r);
2089
2090         if (need_daemon_reload(bus, n) > 0)
2091                 log_warning("Warning: Unit file of %s changed on disk, 'systemctl%s daemon-reload' recommended.",
2092                             n, arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
2093
2094         if (s) {
2095                 char *p;
2096
2097                 p = strdup(path);
2098                 if (!p)
2099                         return log_oom();
2100
2101                 r = set_consume(s, p);
2102                 if (r < 0)
2103                         return log_oom();
2104         }
2105
2106         return 0;
2107 }
2108
2109 static const struct {
2110         const char *target;
2111         const char *verb;
2112         const char *mode;
2113 } action_table[_ACTION_MAX] = {
2114         [ACTION_HALT]         = { SPECIAL_HALT_TARGET,         "halt",         "replace-irreversibly" },
2115         [ACTION_POWEROFF]     = { SPECIAL_POWEROFF_TARGET,     "poweroff",     "replace-irreversibly" },
2116         [ACTION_REBOOT]       = { SPECIAL_REBOOT_TARGET,       "reboot",       "replace-irreversibly" },
2117         [ACTION_KEXEC]        = { SPECIAL_KEXEC_TARGET,        "kexec",        "replace-irreversibly" },
2118         [ACTION_RUNLEVEL2]    = { SPECIAL_RUNLEVEL2_TARGET,    NULL,           "isolate" },
2119         [ACTION_RUNLEVEL3]    = { SPECIAL_RUNLEVEL3_TARGET,    NULL,           "isolate" },
2120         [ACTION_RUNLEVEL4]    = { SPECIAL_RUNLEVEL4_TARGET,    NULL,           "isolate" },
2121         [ACTION_RUNLEVEL5]    = { SPECIAL_RUNLEVEL5_TARGET,    NULL,           "isolate" },
2122         [ACTION_RESCUE]       = { SPECIAL_RESCUE_TARGET,       "rescue",       "isolate" },
2123         [ACTION_EMERGENCY]    = { SPECIAL_EMERGENCY_TARGET,    "emergency",    "isolate" },
2124         [ACTION_DEFAULT]      = { SPECIAL_DEFAULT_TARGET,      "default",      "isolate" },
2125         [ACTION_EXIT]         = { SPECIAL_EXIT_TARGET,         "exit",         "replace-irreversibly" },
2126         [ACTION_SUSPEND]      = { SPECIAL_SUSPEND_TARGET,      "suspend",      "replace-irreversibly" },
2127         [ACTION_HIBERNATE]    = { SPECIAL_HIBERNATE_TARGET,    "hibernate",    "replace-irreversibly" },
2128         [ACTION_HYBRID_SLEEP] = { SPECIAL_HYBRID_SLEEP_TARGET, "hybrid-sleep", "replace-irreversibly" },
2129 };
2130
2131 static enum action verb_to_action(const char *verb) {
2132         enum action i;
2133
2134         for (i = _ACTION_INVALID; i < _ACTION_MAX; i++)
2135                 if (streq_ptr(action_table[i].verb, verb))
2136                         return i;
2137
2138         return _ACTION_INVALID;
2139 }
2140
2141 static int start_unit(sd_bus *bus, char **args) {
2142         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2143         _cleanup_set_free_free_ Set *s = NULL;
2144         const char *method, *mode;
2145         char **name;
2146         int r = 0;
2147         char **names, *strv[] = {NULL, NULL}; /* at most one name */
2148
2149         assert(bus);
2150
2151         ask_password_agent_open_if_enabled();
2152
2153         if (arg_action == ACTION_SYSTEMCTL) {
2154                 enum action action;
2155                 method =
2156                         streq(args[0], "stop") ||
2157                         streq(args[0], "condstop")              ? "StopUnit" :
2158                         streq(args[0], "reload")                ? "ReloadUnit" :
2159                         streq(args[0], "restart")               ? "RestartUnit" :
2160
2161                         streq(args[0], "try-restart")           ||
2162                         streq(args[0], "condrestart")           ? "TryRestartUnit" :
2163
2164                         streq(args[0], "reload-or-restart")     ? "ReloadOrRestartUnit" :
2165
2166                         streq(args[0], "reload-or-try-restart") ||
2167                         streq(args[0], "condreload")            ||
2168                         streq(args[0], "force-reload")          ? "ReloadOrTryRestartUnit" :
2169                                                                   "StartUnit";
2170                 action = verb_to_action(args[0]);
2171
2172                 mode = streq(args[0], "isolate") ? "isolate" :
2173                        action_table[action].mode ?: arg_job_mode;
2174
2175                 strv[0] = (char*) action_table[action].target;
2176         } else {
2177                 assert(arg_action < ELEMENTSOF(action_table));
2178                 assert(action_table[arg_action].target);
2179
2180                 method = "StartUnit";
2181
2182                 mode = action_table[arg_action].mode;
2183                 strv[0] = (char*) action_table[arg_action].target;
2184         }
2185
2186         if (strv[0])
2187                 names = strv;
2188         else
2189                 names = args + 1;
2190
2191         if (!arg_no_block) {
2192                 r = enable_wait_for_jobs(bus);
2193                 if (r < 0) {
2194                         log_error("Could not watch jobs: %s", strerror(-r));
2195                         return r;
2196                 }
2197
2198                 s = set_new(string_hash_func, string_compare_func);
2199                 if (!s)
2200                         return log_oom();
2201         }
2202
2203         STRV_FOREACH(name, names) {
2204                 int q;
2205
2206                 q = start_unit_one(bus, method, *name, mode, &error, s);
2207                 if (r == 0 && q < 0) {
2208                         r = translate_bus_error_to_exit_status(q, &error);
2209                         sd_bus_error_free(&error);
2210                 }
2211         }
2212
2213         if (!arg_no_block) {
2214                 int q;
2215
2216                 q = wait_for_jobs(bus, s);
2217                 if (q < 0)
2218                         return q;
2219
2220                 /* When stopping units, warn if they can still be triggered by
2221                  * another active unit (socket, path, timer) */
2222                 if (!arg_quiet && streq(method, "StopUnit"))
2223                         STRV_FOREACH(name, names)
2224                                 check_triggering_units(bus, *name);
2225         }
2226
2227         return r;
2228 }
2229
2230 /* Ask systemd-logind, which might grant access to unprivileged users
2231  * through PolicyKit */
2232 static int reboot_with_logind(sd_bus *bus, enum action a) {
2233 #ifdef HAVE_LOGIND
2234         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2235         const char *method;
2236         int r;
2237
2238         if (!bus)
2239                 return -EIO;
2240
2241         polkit_agent_open_if_enabled();
2242
2243         switch (a) {
2244
2245         case ACTION_REBOOT:
2246                 method = "Reboot";
2247                 break;
2248
2249         case ACTION_POWEROFF:
2250                 method = "PowerOff";
2251                 break;
2252
2253         case ACTION_SUSPEND:
2254                 method = "Suspend";
2255                 break;
2256
2257         case ACTION_HIBERNATE:
2258                 method = "Hibernate";
2259                 break;
2260
2261         case ACTION_HYBRID_SLEEP:
2262                 method = "HybridSleep";
2263                 break;
2264
2265         default:
2266                 return -EINVAL;
2267         }
2268
2269         r = sd_bus_call_method(
2270                         bus,
2271                         "org.freedesktop.login1",
2272                         "/org/freedesktop/login1",
2273                         "org.freedesktop.login1.Manager",
2274                         method,
2275                         &error,
2276                         NULL,
2277                         "b", true);
2278         if (r < 0)
2279                 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
2280
2281         return r;
2282 #else
2283         return -ENOSYS;
2284 #endif
2285 }
2286
2287 static int check_inhibitors(sd_bus *bus, enum action a) {
2288 #ifdef HAVE_LOGIND
2289         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2290         _cleanup_strv_free_ char **sessions = NULL;
2291         const char *what, *who, *why, *mode;
2292         uint32_t uid, pid;
2293         unsigned c = 0;
2294         char **s;
2295         int r;
2296
2297         if (!bus)
2298                 return 0;
2299
2300         if (arg_ignore_inhibitors || arg_force > 0)
2301                 return 0;
2302
2303         if (arg_when > 0)
2304                 return 0;
2305
2306         if (geteuid() == 0)
2307                 return 0;
2308
2309         if (!on_tty())
2310                 return 0;
2311
2312         r = sd_bus_call_method(
2313                         bus,
2314                         "org.freedesktop.login1",
2315                         "/org/freedesktop/login1",
2316                         "org.freedesktop.login1.Manager",
2317                         "ListInhibitors",
2318                         NULL,
2319                         &reply,
2320                         NULL);
2321         if (r < 0)
2322                 /* If logind is not around, then there are no inhibitors... */
2323                 return 0;
2324
2325         r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssuu)");
2326         if (r < 0)
2327                 return bus_log_parse_error(r);
2328
2329         while ((r = sd_bus_message_read(reply, "(ssssuu)", &what, &who, &why, &mode, &uid, &pid)) > 0) {
2330                 _cleanup_free_ char *comm = NULL, *user = NULL;
2331                 _cleanup_strv_free_ char **sv = NULL;
2332
2333                 if (!streq(mode, "block"))
2334                         continue;
2335
2336                 sv = strv_split(what, ":");
2337                 if (!sv)
2338                         return log_oom();
2339
2340                 if (!strv_contains(sv,
2341                                   a == ACTION_HALT ||
2342                                   a == ACTION_POWEROFF ||
2343                                   a == ACTION_REBOOT ||
2344                                   a == ACTION_KEXEC ? "shutdown" : "sleep"))
2345                         continue;
2346
2347                 get_process_comm(pid, &comm);
2348                 user = uid_to_name(uid);
2349
2350                 log_warning("Operation inhibited by \"%s\" (PID %lu \"%s\", user %s), reason is \"%s\".",
2351                             who, (unsigned long) pid, strna(comm), strna(user), why);
2352
2353                 c++;
2354         }
2355         if (r < 0)
2356                 return bus_log_parse_error(r);
2357
2358         r = sd_bus_message_exit_container(reply);
2359         if (r < 0)
2360                 return bus_log_parse_error(r);
2361
2362         /* Check for current sessions */
2363         sd_get_sessions(&sessions);
2364         STRV_FOREACH(s, sessions) {
2365                 _cleanup_free_ char *type = NULL, *tty = NULL, *seat = NULL, *user = NULL, *service = NULL, *class = NULL;
2366
2367                 if (sd_session_get_uid(*s, &uid) < 0 || uid == getuid())
2368                         continue;
2369
2370                 if (sd_session_get_class(*s, &class) < 0 || !streq(class, "user"))
2371                         continue;
2372
2373                 if (sd_session_get_type(*s, &type) < 0 || (!streq(type, "x11") && !streq(type, "tty")))
2374                         continue;
2375
2376                 sd_session_get_tty(*s, &tty);
2377                 sd_session_get_seat(*s, &seat);
2378                 sd_session_get_service(*s, &service);
2379                 user = uid_to_name(uid);
2380
2381                 log_warning("User %s is logged in on %s.", strna(user), isempty(tty) ? (isempty(seat) ? strna(service) : seat) : tty);
2382                 c++;
2383         }
2384
2385         if (c <= 0)
2386                 return 0;
2387
2388         log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
2389                   action_table[a].verb);
2390
2391         return -EPERM;
2392 #else
2393         return 0;
2394 #endif
2395 }
2396
2397 static int start_special(sd_bus *bus, char **args) {
2398         enum action a;
2399         int r;
2400
2401         assert(args);
2402
2403         a = verb_to_action(args[0]);
2404
2405         r = check_inhibitors(bus, a);
2406         if (r < 0)
2407                 return r;
2408
2409         if (arg_force >= 2 && geteuid() != 0) {
2410                 log_error("Must be root.");
2411                 return -EPERM;
2412         }
2413
2414         if (arg_force >= 2 &&
2415             (a == ACTION_HALT ||
2416              a == ACTION_POWEROFF ||
2417              a == ACTION_REBOOT))
2418                 return halt_now(a);
2419
2420         if (arg_force >= 1 &&
2421             (a == ACTION_HALT ||
2422              a == ACTION_POWEROFF ||
2423              a == ACTION_REBOOT ||
2424              a == ACTION_KEXEC ||
2425              a == ACTION_EXIT))
2426                 return daemon_reload(bus, args);
2427
2428         /* first try logind, to allow authentication with polkit */
2429         if (geteuid() != 0 &&
2430             (a == ACTION_POWEROFF ||
2431              a == ACTION_REBOOT ||
2432              a == ACTION_SUSPEND ||
2433              a == ACTION_HIBERNATE ||
2434              a == ACTION_HYBRID_SLEEP)) {
2435                 r = reboot_with_logind(bus, a);
2436                 if (r >= 0)
2437                         return r;
2438         }
2439
2440         r = start_unit(bus, args);
2441         if (r == EXIT_SUCCESS)
2442                 warn_wall(a);
2443
2444         return r;
2445 }
2446
2447 static int check_unit_active(sd_bus *bus, char **args) {
2448         char **name;
2449         int r = 3; /* According to LSB: "program is not running" */
2450
2451         assert(bus);
2452         assert(args);
2453
2454         STRV_FOREACH(name, args+1) {
2455                 int state;
2456
2457                 state = check_one_unit(bus, *name, "active\0reloading\0", arg_quiet);
2458                 if (state < 0)
2459                         return state;
2460                 if (state > 0)
2461                         r = 0;
2462         }
2463
2464         return r;
2465 }
2466
2467 static int check_unit_failed(sd_bus *bus, char **args) {
2468         char **name;
2469         int r = 1;
2470
2471         assert(bus);
2472         assert(args);
2473
2474         STRV_FOREACH(name, args+1) {
2475                 int state;
2476
2477                 state = check_one_unit(bus, *name, "failed\0", arg_quiet);
2478                 if (state < 0)
2479                         return state;
2480                 if (state > 0)
2481                         r = 0;
2482         }
2483
2484         return r;
2485 }
2486
2487 static int kill_unit(sd_bus *bus, char **args) {
2488         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2489         char **name;
2490         int r = 0;
2491
2492         assert(bus);
2493         assert(args);
2494
2495         if (!arg_kill_who)
2496                 arg_kill_who = "all";
2497
2498         STRV_FOREACH(name, args+1) {
2499                 _cleanup_free_ char *n = NULL;
2500
2501                 n = unit_name_mangle(*name);
2502                 if (!n)
2503                         return log_oom();
2504
2505                 r = sd_bus_call_method(
2506                                 bus,
2507                                 "org.freedesktop.systemd1",
2508                                 "/org/freedesktop/systemd1",
2509                                 "org.freedesktop.systemd1.Manager",
2510                                 "KillUnit",
2511                                 &error,
2512                                 NULL,
2513                                 "ssi", n, arg_kill_who, arg_signal);
2514                 if (r < 0) {
2515                         log_error("Failed to kill unit %s: %s", n, bus_error_message(&error, r));
2516                         return r;
2517                 }
2518         }
2519
2520         return 0;
2521 }
2522
2523 typedef struct ExecStatusInfo {
2524         char *name;
2525
2526         char *path;
2527         char **argv;
2528
2529         bool ignore;
2530
2531         usec_t start_timestamp;
2532         usec_t exit_timestamp;
2533         pid_t pid;
2534         int code;
2535         int status;
2536
2537         LIST_FIELDS(struct ExecStatusInfo, exec);
2538 } ExecStatusInfo;
2539
2540 static void exec_status_info_free(ExecStatusInfo *i) {
2541         assert(i);
2542
2543         free(i->name);
2544         free(i->path);
2545         strv_free(i->argv);
2546         free(i);
2547 }
2548
2549 static int exec_status_info_deserialize(sd_bus_message *m, ExecStatusInfo *i) {
2550         uint64_t start_timestamp, exit_timestamp, start_timestamp_monotonic, exit_timestamp_monotonic;
2551         const char *path;
2552         uint32_t pid;
2553         int32_t code, status;
2554         int ignore, r;
2555
2556         assert(m);
2557         assert(i);
2558
2559         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_STRUCT, "sasbttttuii");
2560         if (r < 0)
2561                 return bus_log_parse_error(r);
2562         else if (r == 0)
2563                 return 0;
2564
2565         r = sd_bus_message_read(m, "s", &path);
2566         if (r < 0)
2567                 return bus_log_parse_error(r);
2568
2569         i->path = strdup(path);
2570         if (!i->path)
2571                 return log_oom();
2572
2573         r = sd_bus_message_read_strv(m, &i->argv);
2574         if (r < 0)
2575                 return bus_log_parse_error(r);
2576
2577         r = sd_bus_message_read(m,
2578                                 "bttttuii",
2579                                 &ignore,
2580                                 &start_timestamp, &start_timestamp_monotonic,
2581                                 &exit_timestamp, &exit_timestamp_monotonic,
2582                                 &pid,
2583                                 &code, &status);
2584         if (r < 0)
2585                 return bus_log_parse_error(r);
2586
2587         i->ignore = ignore;
2588         i->start_timestamp = (usec_t) start_timestamp;
2589         i->exit_timestamp = (usec_t) exit_timestamp;
2590         i->pid = (pid_t) pid;
2591         i->code = code;
2592         i->status = status;
2593
2594         r = sd_bus_message_exit_container(m);
2595         if (r < 0)
2596                 return bus_log_parse_error(r);
2597
2598         return 1;
2599 }
2600
2601 typedef struct UnitStatusInfo {
2602         const char *id;
2603         const char *load_state;
2604         const char *active_state;
2605         const char *sub_state;
2606         const char *unit_file_state;
2607
2608         const char *description;
2609         const char *following;
2610
2611         char **documentation;
2612
2613         const char *fragment_path;
2614         const char *source_path;
2615         const char *control_group;
2616
2617         char **dropin_paths;
2618
2619         const char *load_error;
2620         const char *result;
2621
2622         usec_t inactive_exit_timestamp;
2623         usec_t inactive_exit_timestamp_monotonic;
2624         usec_t active_enter_timestamp;
2625         usec_t active_exit_timestamp;
2626         usec_t inactive_enter_timestamp;
2627
2628         bool need_daemon_reload;
2629
2630         /* Service */
2631         pid_t main_pid;
2632         pid_t control_pid;
2633         const char *status_text;
2634         const char *pid_file;
2635         bool running:1;
2636
2637         usec_t start_timestamp;
2638         usec_t exit_timestamp;
2639
2640         int exit_code, exit_status;
2641
2642         usec_t condition_timestamp;
2643         bool condition_result;
2644         bool failed_condition_trigger;
2645         bool failed_condition_negate;
2646         const char *failed_condition;
2647         const char *failed_condition_param;
2648
2649         /* Socket */
2650         unsigned n_accepted;
2651         unsigned n_connections;
2652         bool accept;
2653
2654         /* Pairs of type, path */
2655         char **listen;
2656
2657         /* Device */
2658         const char *sysfs_path;
2659
2660         /* Mount, Automount */
2661         const char *where;
2662
2663         /* Swap */
2664         const char *what;
2665
2666         LIST_HEAD(ExecStatusInfo, exec);
2667 } UnitStatusInfo;
2668
2669 static void print_status_info(
2670                 UnitStatusInfo *i,
2671                 bool *ellipsized) {
2672
2673         ExecStatusInfo *p;
2674         const char *on, *off, *ss;
2675         usec_t timestamp;
2676         char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
2677         char since2[FORMAT_TIMESTAMP_MAX], *s2;
2678         const char *path;
2679         int flags =
2680                 arg_all * OUTPUT_SHOW_ALL |
2681                 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
2682                 on_tty() * OUTPUT_COLOR |
2683                 !arg_quiet * OUTPUT_WARN_CUTOFF |
2684                 arg_full * OUTPUT_FULL_WIDTH;
2685         char **t, **t2;
2686
2687         assert(i);
2688
2689         /* This shows pretty information about a unit. See
2690          * print_property() for a low-level property printer */
2691
2692         printf("%s", strna(i->id));
2693
2694         if (i->description && !streq_ptr(i->id, i->description))
2695                 printf(" - %s", i->description);
2696
2697         printf("\n");
2698
2699         if (i->following)
2700                 printf("   Follow: unit currently follows state of %s\n", i->following);
2701
2702         if (streq_ptr(i->load_state, "error")) {
2703                 on = ansi_highlight_red();
2704                 off = ansi_highlight_off();
2705         } else
2706                 on = off = "";
2707
2708         path = i->source_path ? i->source_path : i->fragment_path;
2709
2710         if (i->load_error)
2711                 printf("   Loaded: %s%s%s (Reason: %s)\n",
2712                        on, strna(i->load_state), off, i->load_error);
2713         else if (path && i->unit_file_state)
2714                 printf("   Loaded: %s%s%s (%s; %s)\n",
2715                        on, strna(i->load_state), off, path, i->unit_file_state);
2716         else if (path)
2717                 printf("   Loaded: %s%s%s (%s)\n",
2718                        on, strna(i->load_state), off, path);
2719         else
2720                 printf("   Loaded: %s%s%s\n",
2721                        on, strna(i->load_state), off);
2722
2723         if (!strv_isempty(i->dropin_paths)) {
2724                 _cleanup_free_ char *dir = NULL;
2725                 bool last = false;
2726                 char ** dropin;
2727
2728                 STRV_FOREACH(dropin, i->dropin_paths) {
2729                         if (! dir || last) {
2730                                 printf(dir ? "        " : "  Drop-In: ");
2731
2732                                 free(dir);
2733                                 dir = NULL;
2734
2735                                 if (path_get_parent(*dropin, &dir) < 0) {
2736                                         log_oom();
2737                                         return;
2738                                 }
2739
2740                                 printf("%s\n           %s", dir,
2741                                        draw_special_char(DRAW_TREE_RIGHT));
2742                         }
2743
2744                         last = ! (*(dropin + 1) && startswith(*(dropin + 1), dir));
2745
2746                         printf("%s%s", basename(*dropin), last ? "\n" : ", ");
2747                 }
2748         }
2749
2750         ss = streq_ptr(i->active_state, i->sub_state) ? NULL : i->sub_state;
2751
2752         if (streq_ptr(i->active_state, "failed")) {
2753                 on = ansi_highlight_red();
2754                 off = ansi_highlight_off();
2755         } else if (streq_ptr(i->active_state, "active") || streq_ptr(i->active_state, "reloading")) {
2756                 on = ansi_highlight_green();
2757                 off = ansi_highlight_off();
2758         } else
2759                 on = off = "";
2760
2761         if (ss)
2762                 printf("   Active: %s%s (%s)%s",
2763                        on, strna(i->active_state), ss, off);
2764         else
2765                 printf("   Active: %s%s%s",
2766                        on, strna(i->active_state), off);
2767
2768         if (!isempty(i->result) && !streq(i->result, "success"))
2769                 printf(" (Result: %s)", i->result);
2770
2771         timestamp = (streq_ptr(i->active_state, "active")      ||
2772                      streq_ptr(i->active_state, "reloading"))   ? i->active_enter_timestamp :
2773                     (streq_ptr(i->active_state, "inactive")    ||
2774                      streq_ptr(i->active_state, "failed"))      ? i->inactive_enter_timestamp :
2775                     streq_ptr(i->active_state, "activating")    ? i->inactive_exit_timestamp :
2776                                                                   i->active_exit_timestamp;
2777
2778         s1 = format_timestamp_relative(since1, sizeof(since1), timestamp);
2779         s2 = format_timestamp(since2, sizeof(since2), timestamp);
2780
2781         if (s1)
2782                 printf(" since %s; %s\n", s2, s1);
2783         else if (s2)
2784                 printf(" since %s\n", s2);
2785         else
2786                 printf("\n");
2787
2788         if (!i->condition_result && i->condition_timestamp > 0) {
2789                 s1 = format_timestamp_relative(since1, sizeof(since1), i->condition_timestamp);
2790                 s2 = format_timestamp(since2, sizeof(since2), i->condition_timestamp);
2791
2792                 printf("           start condition failed at %s%s%s\n",
2793                        s2, s1 ? "; " : "", s1 ? s1 : "");
2794                 if (i->failed_condition_trigger)
2795                         printf("           none of the trigger conditions were met\n");
2796                 else if (i->failed_condition)
2797                         printf("           %s=%s%s was not met\n",
2798                                i->failed_condition,
2799                                i->failed_condition_negate ? "!" : "",
2800                                i->failed_condition_param);
2801         }
2802
2803         if (i->sysfs_path)
2804                 printf("   Device: %s\n", i->sysfs_path);
2805         if (i->where)
2806                 printf("    Where: %s\n", i->where);
2807         if (i->what)
2808                 printf("     What: %s\n", i->what);
2809
2810         STRV_FOREACH(t, i->documentation)
2811                 printf(" %*s %s\n", 9, t == i->documentation ? "Docs:" : "", *t);
2812
2813         STRV_FOREACH_PAIR(t, t2, i->listen)
2814                 printf(" %*s %s (%s)\n", 9, t == i->listen ? "Listen:" : "", *t2, *t);
2815
2816         if (i->accept)
2817                 printf(" Accepted: %u; Connected: %u\n", i->n_accepted, i->n_connections);
2818
2819         LIST_FOREACH(exec, p, i->exec) {
2820                 _cleanup_free_ char *argv = NULL;
2821                 bool good;
2822
2823                 /* Only show exited processes here */
2824                 if (p->code == 0)
2825                         continue;
2826
2827                 argv = strv_join(p->argv, " ");
2828                 printf("  Process: %u %s=%s ", p->pid, p->name, strna(argv));
2829
2830                 good = is_clean_exit_lsb(p->code, p->status, NULL);
2831                 if (!good) {
2832                         on = ansi_highlight_red();
2833                         off = ansi_highlight_off();
2834                 } else
2835                         on = off = "";
2836
2837                 printf("%s(code=%s, ", on, sigchld_code_to_string(p->code));
2838
2839                 if (p->code == CLD_EXITED) {
2840                         const char *c;
2841
2842                         printf("status=%i", p->status);
2843
2844                         c = exit_status_to_string(p->status, EXIT_STATUS_SYSTEMD);
2845                         if (c)
2846                                 printf("/%s", c);
2847
2848                 } else
2849                         printf("signal=%s", signal_to_string(p->status));
2850
2851                 printf(")%s\n", off);
2852
2853                 if (i->main_pid == p->pid &&
2854                     i->start_timestamp == p->start_timestamp &&
2855                     i->exit_timestamp == p->start_timestamp)
2856                         /* Let's not show this twice */
2857                         i->main_pid = 0;
2858
2859                 if (p->pid == i->control_pid)
2860                         i->control_pid = 0;
2861         }
2862
2863         if (i->main_pid > 0 || i->control_pid > 0) {
2864                 if (i->main_pid > 0) {
2865                         printf(" Main PID: %u", (unsigned) i->main_pid);
2866
2867                         if (i->running) {
2868                                 _cleanup_free_ char *comm = NULL;
2869                                 get_process_comm(i->main_pid, &comm);
2870                                 if (comm)
2871                                         printf(" (%s)", comm);
2872                         } else if (i->exit_code > 0) {
2873                                 printf(" (code=%s, ", sigchld_code_to_string(i->exit_code));
2874
2875                                 if (i->exit_code == CLD_EXITED) {
2876                                         const char *c;
2877
2878                                         printf("status=%i", i->exit_status);
2879
2880                                         c = exit_status_to_string(i->exit_status, EXIT_STATUS_SYSTEMD);
2881                                         if (c)
2882                                                 printf("/%s", c);
2883
2884                                 } else
2885                                         printf("signal=%s", signal_to_string(i->exit_status));
2886                                 printf(")");
2887                         }
2888
2889                         if (i->control_pid > 0)
2890                                 printf(";");
2891                 }
2892
2893                 if (i->control_pid > 0) {
2894                         _cleanup_free_ char *c = NULL;
2895
2896                         printf(" %8s: %u", i->main_pid ? "" : " Control", (unsigned) i->control_pid);
2897
2898                         get_process_comm(i->control_pid, &c);
2899                         if (c)
2900                                 printf(" (%s)", c);
2901                 }
2902
2903                 printf("\n");
2904         }
2905
2906         if (i->status_text)
2907                 printf("   Status: \"%s\"\n", i->status_text);
2908
2909         if (i->control_group &&
2910             (i->main_pid > 0 || i->control_pid > 0 || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, i->control_group, false) == 0)) {
2911                 unsigned c;
2912
2913                 printf("   CGroup: %s\n", i->control_group);
2914
2915                 if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_CONTAINER) {
2916                         unsigned k = 0;
2917                         pid_t extra[2];
2918                         char prefix[] = "           ";
2919
2920                         c = columns();
2921                         if (c > sizeof(prefix) - 1)
2922                                 c -= sizeof(prefix) - 1;
2923                         else
2924                                 c = 0;
2925
2926                         if (i->main_pid > 0)
2927                                 extra[k++] = i->main_pid;
2928
2929                         if (i->control_pid > 0)
2930                                 extra[k++] = i->control_pid;
2931
2932                         show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, i->control_group, prefix,
2933                                                       c, false, extra, k, flags);
2934                 }
2935         }
2936
2937         if (i->id && arg_transport == BUS_TRANSPORT_LOCAL) {
2938                 printf("\n");
2939                 show_journal_by_unit(stdout,
2940                                      i->id,
2941                                      arg_output,
2942                                      0,
2943                                      i->inactive_exit_timestamp_monotonic,
2944                                      arg_lines,
2945                                      getuid(),
2946                                      flags,
2947                                      arg_scope == UNIT_FILE_SYSTEM,
2948                                      ellipsized);
2949         }
2950
2951         if (i->need_daemon_reload)
2952                 printf("\n%sWarning:%s Unit file changed on disk, 'systemctl %sdaemon-reload' recommended.\n",
2953                        ansi_highlight_red(),
2954                        ansi_highlight_off(),
2955                        arg_scope == UNIT_FILE_SYSTEM ? "" : "--user ");
2956 }
2957
2958 static void show_unit_help(UnitStatusInfo *i) {
2959         char **p;
2960
2961         assert(i);
2962
2963         if (!i->documentation) {
2964                 log_info("Documentation for %s not known.", i->id);
2965                 return;
2966         }
2967
2968         STRV_FOREACH(p, i->documentation) {
2969
2970                 if (startswith(*p, "man:")) {
2971                         const char *args[4] = { "man", NULL, NULL, NULL };
2972                         _cleanup_free_ char *page = NULL, *section = NULL;
2973                         char *e = NULL;
2974                         pid_t pid;
2975                         size_t k;
2976
2977                         k = strlen(*p);
2978
2979                         if ((*p)[k-1] == ')')
2980                                 e = strrchr(*p, '(');
2981
2982                         if (e) {
2983                                 page = strndup((*p) + 4, e - *p - 4);
2984                                 section = strndup(e + 1, *p + k - e - 2);
2985                                 if (!page || !section) {
2986                                         log_oom();
2987                                         return;
2988                                 }
2989
2990                                 args[1] = section;
2991                                 args[2] = page;
2992                         } else
2993                                 args[1] = *p + 4;
2994
2995                         pid = fork();
2996                         if (pid < 0) {
2997                                 log_error("Failed to fork: %m");
2998                                 continue;
2999                         }
3000
3001                         if (pid == 0) {
3002                                 /* Child */
3003                                 execvp(args[0], (char**) args);
3004                                 log_error("Failed to execute man: %m");
3005                                 _exit(EXIT_FAILURE);
3006                         }
3007
3008                         wait_for_terminate(pid, NULL);
3009                 } else
3010                         log_info("Can't show: %s", *p);
3011         }
3012 }
3013
3014 static int status_property(const char *name, sd_bus_message *m, UnitStatusInfo *i, const char *contents) {
3015         int r;
3016
3017         assert(name);
3018         assert(m);
3019         assert(i);
3020
3021         switch (contents[0]) {
3022
3023         case SD_BUS_TYPE_STRING: {
3024                 const char *s;
3025
3026                 r = sd_bus_message_read(m, "s", &s);
3027                 if (r < 0)
3028                         return bus_log_parse_error(r);
3029
3030                 if (!isempty(s)) {
3031                         if (streq(name, "Id"))
3032                                 i->id = s;
3033                         else if (streq(name, "LoadState"))
3034                                 i->load_state = s;
3035                         else if (streq(name, "ActiveState"))
3036                                 i->active_state = s;
3037                         else if (streq(name, "SubState"))
3038                                 i->sub_state = s;
3039                         else if (streq(name, "Description"))
3040                                 i->description = s;
3041                         else if (streq(name, "FragmentPath"))
3042                                 i->fragment_path = s;
3043                         else if (streq(name, "SourcePath"))
3044                                 i->source_path = s;
3045 #ifndef NOLEGACY
3046                         else if (streq(name, "DefaultControlGroup")) {
3047                                 const char *e;
3048                                 e = startswith(s, SYSTEMD_CGROUP_CONTROLLER ":");
3049                                 if (e)
3050                                         i->control_group = e;
3051                         }
3052 #endif
3053                         else if (streq(name, "ControlGroup"))
3054                                 i->control_group = s;
3055                         else if (streq(name, "StatusText"))
3056                                 i->status_text = s;
3057                         else if (streq(name, "PIDFile"))
3058                                 i->pid_file = s;
3059                         else if (streq(name, "SysFSPath"))
3060                                 i->sysfs_path = s;
3061                         else if (streq(name, "Where"))
3062                                 i->where = s;
3063                         else if (streq(name, "What"))
3064                                 i->what = s;
3065                         else if (streq(name, "Following"))
3066                                 i->following = s;
3067                         else if (streq(name, "UnitFileState"))
3068                                 i->unit_file_state = s;
3069                         else if (streq(name, "Result"))
3070                                 i->result = s;
3071                 }
3072
3073                 break;
3074         }
3075
3076         case SD_BUS_TYPE_BOOLEAN: {
3077                 int b;
3078
3079                 r = sd_bus_message_read(m, "b", &b);
3080                 if (r < 0)
3081                         return bus_log_parse_error(r);
3082
3083                 if (streq(name, "Accept"))
3084                         i->accept = b;
3085                 else if (streq(name, "NeedDaemonReload"))
3086                         i->need_daemon_reload = b;
3087                 else if (streq(name, "ConditionResult"))
3088                         i->condition_result = b;
3089
3090                 break;
3091         }
3092
3093         case SD_BUS_TYPE_UINT32: {
3094                 uint32_t u;
3095
3096                 r = sd_bus_message_read(m, "u", &u);
3097                 if (r < 0)
3098                         return bus_log_parse_error(r);
3099
3100                 if (streq(name, "MainPID")) {
3101                         if (u > 0) {
3102                                 i->main_pid = (pid_t) u;
3103                                 i->running = true;
3104                         }
3105                 } else if (streq(name, "ControlPID"))
3106                         i->control_pid = (pid_t) u;
3107                 else if (streq(name, "ExecMainPID")) {
3108                         if (u > 0)
3109                                 i->main_pid = (pid_t) u;
3110                 } else if (streq(name, "NAccepted"))
3111                         i->n_accepted = u;
3112                 else if (streq(name, "NConnections"))
3113                         i->n_connections = u;
3114
3115                 break;
3116         }
3117
3118         case SD_BUS_TYPE_INT32: {
3119                 int32_t j;
3120
3121                 r = sd_bus_message_read(m, "i", &j);
3122                 if (r < 0)
3123                         return bus_log_parse_error(r);
3124
3125                 if (streq(name, "ExecMainCode"))
3126                         i->exit_code = (int) j;
3127                 else if (streq(name, "ExecMainStatus"))
3128                         i->exit_status = (int) j;
3129
3130                 break;
3131         }
3132
3133         case SD_BUS_TYPE_UINT64: {
3134                 uint64_t u;
3135
3136                 r = sd_bus_message_read(m, "t", &u);
3137                 if (r < 0)
3138                         return bus_log_parse_error(r);
3139
3140                 if (streq(name, "ExecMainStartTimestamp"))
3141                         i->start_timestamp = (usec_t) u;
3142                 else if (streq(name, "ExecMainExitTimestamp"))
3143                         i->exit_timestamp = (usec_t) u;
3144                 else if (streq(name, "ActiveEnterTimestamp"))
3145                         i->active_enter_timestamp = (usec_t) u;
3146                 else if (streq(name, "InactiveEnterTimestamp"))
3147                         i->inactive_enter_timestamp = (usec_t) u;
3148                 else if (streq(name, "InactiveExitTimestamp"))
3149                         i->inactive_exit_timestamp = (usec_t) u;
3150                 else if (streq(name, "InactiveExitTimestampMonotonic"))
3151                         i->inactive_exit_timestamp_monotonic = (usec_t) u;
3152                 else if (streq(name, "ActiveExitTimestamp"))
3153                         i->active_exit_timestamp = (usec_t) u;
3154                 else if (streq(name, "ConditionTimestamp"))
3155                         i->condition_timestamp = (usec_t) u;
3156
3157                 break;
3158         }
3159
3160         case SD_BUS_TYPE_ARRAY:
3161
3162                 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3163                         _cleanup_free_ ExecStatusInfo *info = NULL;
3164
3165                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3166                         if (r < 0)
3167                                 return bus_log_parse_error(r);
3168
3169                         info = new0(ExecStatusInfo, 1);
3170                         if (!info)
3171                                 return log_oom();
3172
3173                         while ((r = exec_status_info_deserialize(m, info)) > 0) {
3174
3175                                 info->name = strdup(name);
3176                                 if (!info->name)
3177                                         log_oom();
3178
3179                                 LIST_PREPEND(exec, i->exec, info);
3180
3181                                 info = new0(ExecStatusInfo, 1);
3182                                 if (!info)
3183                                         log_oom();
3184                         }
3185
3186                         if (r < 0)
3187                                 return bus_log_parse_error(r);
3188
3189                         r = sd_bus_message_exit_container(m);
3190                         if (r < 0)
3191                                 return bus_log_parse_error(r);
3192
3193                         return 0;
3194
3195                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3196                         const char *type, *path;
3197
3198                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3199                         if (r < 0)
3200                                 return bus_log_parse_error(r);
3201
3202                         while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0) {
3203
3204                                 r = strv_extend(&i->listen, type);
3205                                 if (r < 0)
3206                                         return r;
3207
3208                                 r = strv_extend(&i->listen, path);
3209                                 if (r < 0)
3210                                         return r;
3211                         }
3212                         if (r < 0)
3213                                 return bus_log_parse_error(r);
3214
3215                         r = sd_bus_message_exit_container(m);
3216                         if (r < 0)
3217                                 return bus_log_parse_error(r);
3218
3219                         return 0;
3220
3221                 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "DropInPaths")) {
3222
3223                         r = sd_bus_message_read_strv(m, &i->dropin_paths);
3224                         if (r < 0)
3225                                 return bus_log_parse_error(r);
3226
3227                 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Documentation")) {
3228
3229                         r = sd_bus_message_read_strv(m, &i->documentation);
3230                         if (r < 0)
3231                                 return bus_log_parse_error(r);
3232
3233                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Conditions")) {
3234                         const char *cond, *param;
3235                         int trigger, negate;
3236                         int32_t state;
3237
3238                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
3239                         if (r < 0)
3240                                 return bus_log_parse_error(r);
3241
3242                         while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, &param, &state)) > 0) {
3243                                 log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
3244                                 if (state < 0 && (!trigger || !i->failed_condition)) {
3245                                         i->failed_condition = cond;
3246                                         i->failed_condition_trigger = trigger;
3247                                         i->failed_condition_negate = negate;
3248                                         i->failed_condition_param = param;
3249                                 }
3250                         }
3251                         if (r < 0)
3252                                 return bus_log_parse_error(r);
3253
3254                         r = sd_bus_message_exit_container(m);
3255                         if (r < 0)
3256                                 return bus_log_parse_error(r);
3257
3258                 } else
3259                         goto skip;
3260
3261                 break;
3262
3263         case SD_BUS_TYPE_STRUCT_BEGIN:
3264
3265                 if (streq(name, "LoadError")) {
3266                         const char *n, *message;
3267
3268                         r = sd_bus_message_read(m, "(ss)", &n, &message);
3269                         if (r < 0)
3270                                 return bus_log_parse_error(r);
3271
3272                         if (!isempty(message))
3273                                 i->load_error = message;
3274                 } else
3275                         goto skip;
3276
3277                 break;
3278
3279         default:
3280                 goto skip;
3281         }
3282
3283         return 0;
3284
3285 skip:
3286         r = sd_bus_message_skip(m, contents);
3287         if (r < 0)
3288                 return bus_log_parse_error(r);
3289
3290         return 0;
3291 }
3292
3293 static int print_property(const char *name, sd_bus_message *m, const char *contents) {
3294         int r;
3295
3296         assert(name);
3297         assert(m);
3298
3299         /* This is a low-level property printer, see
3300          * print_status_info() for the nicer output */
3301
3302         if (arg_properties && !strv_find(arg_properties, name)) {
3303                 /* skip what we didn't read */
3304                 r = sd_bus_message_skip(m, contents);
3305                 return r;
3306         }
3307
3308         switch (contents[0]) {
3309
3310         case SD_BUS_TYPE_STRUCT_BEGIN:
3311
3312                 if (contents[1] == SD_BUS_TYPE_UINT32 && streq(name, "Job")) {
3313                         uint32_t u;
3314
3315                         r = sd_bus_message_read(m, "(uo)", &u, NULL);
3316                         if (r < 0)
3317                                 return bus_log_parse_error(r);
3318
3319                         if (u > 0)
3320                                 printf("%s=%u\n", name, (unsigned) u);
3321                         else if (arg_all)
3322                                 printf("%s=\n", name);
3323
3324                         return 0;
3325
3326                 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Unit")) {
3327                         const char *s;
3328
3329                         r = sd_bus_message_read(m, "(so)", &s, NULL);
3330                         if (r < 0)
3331                                 return bus_log_parse_error(r);
3332
3333                         if (arg_all || !isempty(s))
3334                                 printf("%s=%s\n", name, s);
3335
3336                         return 0;
3337
3338                 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "LoadError")) {
3339                         const char *a = NULL, *b = NULL;
3340
3341                         r = sd_bus_message_read(m, "(ss)", &a, &b);
3342                         if (r < 0)
3343                                 return bus_log_parse_error(r);
3344
3345                         if (arg_all || !isempty(a) || !isempty(b))
3346                                 printf("%s=%s \"%s\"\n", name, strempty(a), strempty(b));
3347
3348                         return 0;
3349                 }
3350
3351                 break;
3352
3353         case SD_BUS_TYPE_ARRAY:
3354
3355                 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "EnvironmentFiles")) {
3356                         const char *path;
3357                         int ignore;
3358
3359                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sb)");
3360                         if (r < 0)
3361                                 return bus_log_parse_error(r);
3362
3363                         while ((r = sd_bus_message_read(m, "(sb)", &path, &ignore)) > 0)
3364                                 printf("EnvironmentFile=%s (ignore_errors=%s)\n", path, yes_no(ignore));
3365
3366                         if (r < 0)
3367                                 return bus_log_parse_error(r);
3368
3369                         r = sd_bus_message_exit_container(m);
3370                         if (r < 0)
3371                                 return bus_log_parse_error(r);
3372
3373                         return 0;
3374
3375                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Paths")) {
3376                         const char *type, *path;
3377
3378                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3379                         if (r < 0)
3380                                 return bus_log_parse_error(r);
3381
3382                         while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
3383                                 printf("%s=%s\n", type, path);
3384                         if (r < 0)
3385                                 return bus_log_parse_error(r);
3386
3387                         r = sd_bus_message_exit_container(m);
3388                         if (r < 0)
3389                                 return bus_log_parse_error(r);
3390
3391                         return 0;
3392
3393                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3394                         const char *type, *path;
3395
3396                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3397                         if (r < 0)
3398                                 return bus_log_parse_error(r);
3399
3400                         while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
3401                                 printf("Listen%s=%s\n", type, path);
3402                         if (r < 0)
3403                                 return bus_log_parse_error(r);
3404
3405                         r = sd_bus_message_exit_container(m);
3406                         if (r < 0)
3407                                 return bus_log_parse_error(r);
3408
3409                         return 0;
3410
3411                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Timers")) {
3412                         const char *base;
3413                         uint64_t value, next_elapse;
3414
3415                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(stt)");
3416                         if (r < 0)
3417                                 return bus_log_parse_error(r);
3418
3419                         while ((r = sd_bus_message_read(m, "(stt)", &base, &value, &next_elapse)) > 0) {
3420                                 char timespan1[FORMAT_TIMESPAN_MAX], timespan2[FORMAT_TIMESPAN_MAX];
3421
3422                                 printf("%s={ value=%s ; next_elapse=%s }\n",
3423                                        base,
3424                                        format_timespan(timespan1, sizeof(timespan1), value, 0),
3425                                        format_timespan(timespan2, sizeof(timespan2), next_elapse, 0));
3426                         }
3427                         if (r < 0)
3428                                 return bus_log_parse_error(r);
3429
3430                         r = sd_bus_message_exit_container(m);
3431                         if (r < 0)
3432                                 return bus_log_parse_error(r);
3433
3434                         return 0;
3435
3436                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3437                         ExecStatusInfo info = {};
3438
3439                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3440                         if (r < 0)
3441                                 return bus_log_parse_error(r);
3442
3443                         while ((r = exec_status_info_deserialize(m, &info)) > 0) {
3444                                 char timestamp1[FORMAT_TIMESTAMP_MAX], timestamp2[FORMAT_TIMESTAMP_MAX];
3445                                 _cleanup_free_ char *tt;
3446
3447                                 tt = strv_join(info.argv, " ");
3448
3449                                 printf("%s={ path=%s ; argv[]=%s ; ignore_errors=%s ; start_time=[%s] ; stop_time=[%s] ; pid=%u ; code=%s ; status=%i%s%s }\n",
3450                                        name,
3451                                        strna(info.path),
3452                                        strna(tt),
3453                                        yes_no(info.ignore),
3454                                        strna(format_timestamp(timestamp1, sizeof(timestamp1), info.start_timestamp)),
3455                                        strna(format_timestamp(timestamp2, sizeof(timestamp2), info.exit_timestamp)),
3456                                        (unsigned) info. pid,
3457                                        sigchld_code_to_string(info.code),
3458                                        info.status,
3459                                        info.code == CLD_EXITED ? "" : "/",
3460                                        strempty(info.code == CLD_EXITED ? NULL : signal_to_string(info.status)));
3461
3462                                 free(info.path);
3463                                 strv_free(info.argv);
3464                                 zero(info);
3465                         }
3466
3467                         r = sd_bus_message_exit_container(m);
3468                         if (r < 0)
3469                                 return bus_log_parse_error(r);
3470
3471                         return 0;
3472
3473                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "DeviceAllow")) {
3474                         const char *path, *rwm;
3475
3476                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3477                         if (r < 0)
3478                                 return bus_log_parse_error(r);
3479
3480                         while ((r = sd_bus_message_read(m, "(ss)", &path, &rwm)) > 0)
3481                                 printf("%s=%s %s\n", name, strna(path), strna(rwm));
3482                         if (r < 0)
3483                                 return bus_log_parse_error(r);
3484
3485                         r = sd_bus_message_exit_container(m);
3486                         if (r < 0)
3487                                 return bus_log_parse_error(r);
3488
3489                         return 0;
3490
3491                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "BlockIODeviceWeight")) {
3492                         const char *path;
3493                         uint64_t weight;
3494
3495                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
3496                         if (r < 0)
3497                                 return bus_log_parse_error(r);
3498
3499                         while ((r = sd_bus_message_read(m, "(st)", &path, &weight)) > 0)
3500                                 printf("%s=%s %" PRIu64 "\n", name, strna(path), weight);
3501                         if (r < 0)
3502                                 return bus_log_parse_error(r);
3503
3504                         r = sd_bus_message_exit_container(m);
3505                         if (r < 0)
3506                                 return bus_log_parse_error(r);
3507
3508                         return 0;
3509
3510                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && (streq(name, "BlockIOReadBandwidth") || streq(name, "BlockIOWriteBandwidth"))) {
3511                         const char *path;
3512                         uint64_t bandwidth;
3513
3514                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
3515                         if (r < 0)
3516                                 return bus_log_parse_error(r);
3517
3518                         while ((r = sd_bus_message_read(m, "(st)", &path, &bandwidth)) > 0)
3519                                 printf("%s=%s %" PRIu64 "\n", name, strna(path), bandwidth);
3520                         if (r < 0)
3521                                 return bus_log_parse_error(r);
3522
3523                         r = sd_bus_message_exit_container(m);
3524                         if (r < 0)
3525                                 return bus_log_parse_error(r);
3526
3527                         return 0;
3528                 }
3529
3530                 break;
3531         }
3532
3533         r = bus_print_property(name, m, arg_all);
3534         if (r < 0)
3535                 return bus_log_parse_error(r);
3536
3537         if (r == 0) {
3538                 r = sd_bus_message_skip(m, contents);
3539                 if (r < 0)
3540                         return bus_log_parse_error(r);
3541
3542                 if (arg_all)
3543                         printf("%s=[unprintable]\n", name);
3544         }
3545
3546         return 0;
3547 }
3548
3549 static int show_one(
3550                 const char *verb,
3551                 sd_bus *bus,
3552             &