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