chiark / gitweb /
d4c71f561f3338a7d32df82d54a9e703aa248341
[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;
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                 if (u->state == UNIT_FILE_MASKED ||
1066                     u->state == UNIT_FILE_MASKED_RUNTIME ||
1067                     u->state == UNIT_FILE_DISABLED ||
1068                     u->state == UNIT_FILE_INVALID) {
1069                         on  = ansi_highlight_red();
1070                         off = ansi_highlight_off();
1071                 } else if (u->state == UNIT_FILE_ENABLED) {
1072                         on  = ansi_highlight_green();
1073                         off = ansi_highlight_off();
1074                 } else
1075                         on = off = "";
1076
1077                 id = basename(u->path);
1078
1079                 e = arg_full ? NULL : ellipsize(id, id_cols, 33);
1080
1081                 printf("%-*s %s%-*s%s\n",
1082                        id_cols, e ? e : id,
1083                        on, state_cols, unit_file_state_to_string(u->state), off);
1084         }
1085
1086         if (!arg_no_legend)
1087                 printf("\n%u unit files listed.\n", c);
1088 }
1089
1090 static int list_unit_files(sd_bus *bus, char **args) {
1091         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1092         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1093         _cleanup_free_ UnitFileList *units = NULL;
1094         UnitFileList *unit;
1095         size_t size = 0;
1096         unsigned c = 0;
1097         const char *state;
1098         char *path;
1099         int r;
1100
1101         pager_open_if_enabled();
1102
1103         if (avoid_bus()) {
1104                 Hashmap *h;
1105                 UnitFileList *u;
1106                 Iterator i;
1107                 unsigned n_units;
1108
1109                 h = hashmap_new(string_hash_func, string_compare_func);
1110                 if (!h)
1111                         return log_oom();
1112
1113                 r = unit_file_get_list(arg_scope, arg_root, h);
1114                 if (r < 0) {
1115                         unit_file_list_free(h);
1116                         log_error("Failed to get unit file list: %s", strerror(-r));
1117                         return r;
1118                 }
1119
1120                 n_units = hashmap_size(h);
1121                 units = new(UnitFileList, n_units);
1122                 if (!units) {
1123                         unit_file_list_free(h);
1124                         return log_oom();
1125                 }
1126
1127                 HASHMAP_FOREACH(u, h, i) {
1128                         if (!output_show_unit_file(u, strv_skip_first(args)))
1129                                 continue;
1130
1131                         units[c++] = *u;
1132                         free(u);
1133                 }
1134
1135                 assert(c <= n_units);
1136                 hashmap_free(h);
1137         } else {
1138                 r = sd_bus_call_method(
1139                                 bus,
1140                                 "org.freedesktop.systemd1",
1141                                 "/org/freedesktop/systemd1",
1142                                 "org.freedesktop.systemd1.Manager",
1143                                 "ListUnitFiles",
1144                                 &error,
1145                                 &reply,
1146                                 NULL);
1147                 if (r < 0) {
1148                         log_error("Failed to list unit files: %s", bus_error_message(&error, r));
1149                         return r;
1150                 }
1151
1152                 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ss)");
1153                 if (r < 0)
1154                         return bus_log_parse_error(r);
1155
1156                 while ((r = sd_bus_message_read(reply, "(ss)", &path, &state)) > 0) {
1157
1158                         if (!GREEDY_REALLOC(units, size, c + 1))
1159                                 return log_oom();
1160
1161                         units[c] = (struct UnitFileList) {
1162                                 path,
1163                                 unit_file_state_from_string(state)
1164                         };
1165
1166                         if (output_show_unit_file(&units[c], strv_skip_first(args)))
1167                                 c ++;
1168
1169                 }
1170                 if (r < 0)
1171                         return bus_log_parse_error(r);
1172
1173                 r = sd_bus_message_exit_container(reply);
1174                 if (r < 0)
1175                         return bus_log_parse_error(r);
1176         }
1177
1178         if (c > 0) {
1179                 qsort(units, c, sizeof(UnitFileList), compare_unit_file_list);
1180                 output_unit_file_list(units, c);
1181         }
1182
1183         if (avoid_bus())
1184                 for (unit = units; unit < units + c; unit++)
1185                         free(unit->path);
1186
1187         return 0;
1188 }
1189
1190 static int list_dependencies_print(const char *name, int level, unsigned int branches, bool last) {
1191         _cleanup_free_ char *n = NULL;
1192         size_t max_len = MAX(columns(),20u);
1193         size_t len = 0;
1194         int i;
1195
1196         if (!arg_plain) {
1197
1198                 for (i = level - 1; i >= 0; i--) {
1199                         len += 2;
1200                         if (len > max_len - 3 && !arg_full) {
1201                                 printf("%s...\n",max_len % 2 ? "" : " ");
1202                                 return 0;
1203                         }
1204                         printf("%s", draw_special_char(branches & (1 << i) ? DRAW_TREE_VERT : DRAW_TREE_SPACE));
1205                 }
1206                 len += 2;
1207
1208                 if (len > max_len - 3 && !arg_full) {
1209                         printf("%s...\n",max_len % 2 ? "" : " ");
1210                         return 0;
1211                 }
1212
1213                 printf("%s", draw_special_char(last ? DRAW_TREE_RIGHT : DRAW_TREE_BRANCH));
1214         }
1215
1216         if (arg_full){
1217                 printf("%s\n", name);
1218                 return 0;
1219         }
1220
1221         n = ellipsize(name, max_len-len, 100);
1222         if (!n)
1223                 return log_oom();
1224
1225         printf("%s\n", n);
1226         return 0;
1227 }
1228
1229 static int list_dependencies_get_dependencies(sd_bus *bus, const char *name, char ***deps) {
1230
1231         static const char *dependencies[_DEPENDENCY_MAX] = {
1232                 [DEPENDENCY_FORWARD] = "Requires\0"
1233                                        "RequiresOverridable\0"
1234                                        "Requisite\0"
1235                                        "RequisiteOverridable\0"
1236                                        "Wants\0",
1237                 [DEPENDENCY_REVERSE] = "RequiredBy\0"
1238                                        "RequiredByOverridable\0"
1239                                        "WantedBy\0"
1240                                        "PartOf\0",
1241                 [DEPENDENCY_AFTER]   = "After\0",
1242                 [DEPENDENCY_BEFORE]  = "Before\0",
1243         };
1244
1245         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1246         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1247         _cleanup_strv_free_ char **ret = NULL;
1248         _cleanup_free_ char *path = NULL;
1249         int r;
1250
1251         assert(bus);
1252         assert(name);
1253         assert(deps);
1254         assert_cc(ELEMENTSOF(dependencies) == _DEPENDENCY_MAX);
1255
1256         path = unit_dbus_path_from_name(name);
1257         if (!path)
1258                 return log_oom();
1259
1260         r = sd_bus_call_method(
1261                         bus,
1262                         "org.freedesktop.systemd1",
1263                         path,
1264                         "org.freedesktop.DBus.Properties",
1265                         "GetAll",
1266                         &error,
1267                         &reply,
1268                         "s", "org.freedesktop.systemd1.Unit");
1269         if (r < 0) {
1270                 log_error("Failed to get properties of %s: %s", name, bus_error_message(&error, r));
1271                 return r;
1272         }
1273
1274         r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
1275         if (r < 0)
1276                 return bus_log_parse_error(r);
1277
1278         while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
1279                 const char *prop;
1280
1281                 r = sd_bus_message_read(reply, "s", &prop);
1282                 if (r < 0)
1283                         return bus_log_parse_error(r);
1284
1285                 if (!nulstr_contains(dependencies[arg_dependency], prop)) {
1286                         r = sd_bus_message_skip(reply, "v");
1287                         if (r < 0)
1288                                 return bus_log_parse_error(r);
1289                 } else {
1290
1291                         r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, "as");
1292                         if (r < 0)
1293                                 return bus_log_parse_error(r);
1294
1295                         r = bus_message_read_strv_extend(reply, &ret);
1296                         if (r < 0)
1297                                 return bus_log_parse_error(r);
1298
1299                         r = sd_bus_message_exit_container(reply);
1300                         if (r < 0)
1301                                 return bus_log_parse_error(r);
1302                 }
1303
1304                 r = sd_bus_message_exit_container(reply);
1305                 if (r < 0)
1306                         return bus_log_parse_error(r);
1307
1308         }
1309         if (r < 0)
1310                 return bus_log_parse_error(r);
1311
1312         r = sd_bus_message_exit_container(reply);
1313         if (r < 0)
1314                 return bus_log_parse_error(r);
1315
1316         *deps = ret;
1317         ret = NULL;
1318
1319         return 0;
1320 }
1321
1322 static int list_dependencies_compare(const void *_a, const void *_b) {
1323         const char **a = (const char**) _a, **b = (const char**) _b;
1324
1325         if (unit_name_to_type(*a) == UNIT_TARGET && unit_name_to_type(*b) != UNIT_TARGET)
1326                 return 1;
1327         if (unit_name_to_type(*a) != UNIT_TARGET && unit_name_to_type(*b) == UNIT_TARGET)
1328                 return -1;
1329
1330         return strcasecmp(*a, *b);
1331 }
1332
1333 static int list_dependencies_one(
1334                 sd_bus *bus,
1335                 const char *name,
1336                 int level,
1337                 char ***units,
1338                 unsigned int branches) {
1339
1340         _cleanup_strv_free_ char **deps = NULL;
1341         char **c;
1342         int r = 0;
1343
1344         assert(bus);
1345         assert(name);
1346         assert(units);
1347
1348         r = strv_extend(units, name);
1349         if (r < 0)
1350                 return log_oom();
1351
1352         r = list_dependencies_get_dependencies(bus, name, &deps);
1353         if (r < 0)
1354                 return r;
1355
1356         qsort_safe(deps, strv_length(deps), sizeof (char*), list_dependencies_compare);
1357
1358         STRV_FOREACH(c, deps) {
1359                 int state;
1360
1361                 if (strv_contains(*units, *c)) {
1362                         if (!arg_plain) {
1363                                 r = list_dependencies_print("...", level + 1, (branches << 1) | (c[1] == NULL ? 0 : 1), 1);
1364                                 if (r < 0)
1365                                         return r;
1366                         }
1367                         continue;
1368                 }
1369
1370                 state = check_one_unit(bus, *c, "activating\0active\0reloading\0", true);
1371                 if (state > 0)
1372                         printf("%s%s%s", ansi_highlight_green(), draw_special_char(DRAW_BLACK_CIRCLE), ansi_highlight_off());
1373                 else
1374                         printf("%s%s%s", ansi_highlight_red(), draw_special_char(DRAW_BLACK_CIRCLE), ansi_highlight_off());
1375
1376                 r = list_dependencies_print(*c, level, branches, c[1] == NULL);
1377                 if (r < 0)
1378                         return r;
1379
1380                 if (arg_all || unit_name_to_type(*c) == UNIT_TARGET) {
1381                        r = list_dependencies_one(bus, *c, level + 1, units, (branches << 1) | (c[1] == NULL ? 0 : 1));
1382                        if (r < 0)
1383                                return r;
1384                 }
1385         }
1386
1387         if (!arg_plain)
1388                 strv_remove(*units, name);
1389
1390         return 0;
1391 }
1392
1393 static int list_dependencies(sd_bus *bus, char **args) {
1394         _cleanup_strv_free_ char **units = NULL;
1395         _cleanup_free_ char *unit = NULL;
1396         const char *u;
1397
1398         assert(bus);
1399
1400         if (args[1]) {
1401                 unit = unit_name_mangle(args[1], MANGLE_NOGLOB);
1402                 if (!unit)
1403                         return log_oom();
1404                 u = unit;
1405         } else
1406                 u = SPECIAL_DEFAULT_TARGET;
1407
1408         pager_open_if_enabled();
1409
1410         puts(u);
1411
1412         return list_dependencies_one(bus, u, 0, &units, 0);
1413 }
1414
1415 struct machine_info {
1416         bool is_host;
1417         char *name;
1418         unsigned n_failed_units;
1419         unsigned n_jobs;
1420         char *state;
1421 };
1422
1423 static void free_machines_list(struct machine_info *machine_infos, int n) {
1424         int i;
1425
1426         if (!machine_infos)
1427                 return;
1428
1429         for (i = 0; i < n; i++) {
1430                 free(machine_infos[i].name);
1431                 free(machine_infos[i].state);
1432         }
1433
1434         free(machine_infos);
1435 }
1436
1437 static int compare_machine_info(const void *a, const void *b) {
1438         const struct machine_info *u = a, *v = b;
1439
1440         if (u->is_host != v->is_host)
1441                 return u->is_host > v->is_host ? 1 : -1;
1442
1443         return strcasecmp(u->name, v->name);
1444 }
1445
1446 static int get_machine_properties(sd_bus *bus, struct machine_info *mi) {
1447         static const struct bus_properties_map map[] = {
1448                 { "SystemState",  "s", NULL, offsetof(struct machine_info, state)          },
1449                 { "NJobs",        "u", NULL, offsetof(struct machine_info, n_jobs)         },
1450                 { "NFailedUnits", "u", NULL, offsetof(struct machine_info, n_failed_units) },
1451                 {}
1452         };
1453
1454         _cleanup_bus_unref_ sd_bus *container = NULL;
1455         int r;
1456
1457         assert(mi);
1458
1459         if (!bus) {
1460                 r = sd_bus_open_system_container(&container, mi->name);
1461                 if (r < 0)
1462                         return r;
1463
1464                 bus = container;
1465         }
1466
1467         r = bus_map_all_properties(bus, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", map, mi);
1468         if (r < 0)
1469                 return r;
1470
1471         return 0;
1472 }
1473
1474 static bool output_show_machine(const char *name, char **patterns) {
1475         char **i;
1476
1477         assert(name);
1478
1479         if (strv_isempty(patterns))
1480                 return true;
1481
1482         STRV_FOREACH(i, patterns)
1483                 if (fnmatch(*i, name, FNM_NOESCAPE) == 0)
1484                         return true;
1485
1486         return false;
1487 }
1488
1489 static int get_machine_list(
1490                 sd_bus *bus,
1491                 struct machine_info **_machine_infos,
1492                 char **patterns) {
1493
1494         struct machine_info *machine_infos = NULL;
1495         _cleanup_strv_free_ char **m = NULL;
1496         _cleanup_free_ char *hn = NULL;
1497         size_t sz = 0;
1498         char **i;
1499         int c = 0;
1500
1501         hn = gethostname_malloc();
1502         if (!hn)
1503                 return log_oom();
1504
1505         if (output_show_machine(hn, patterns)) {
1506                 if (!GREEDY_REALLOC0(machine_infos, sz, c+1))
1507                         return log_oom();
1508
1509                 machine_infos[c].is_host = true;
1510                 machine_infos[c].name = hn;
1511                 hn = NULL;
1512
1513                 get_machine_properties(bus, &machine_infos[c]);
1514                 c++;
1515         }
1516
1517         sd_get_machine_names(&m);
1518         STRV_FOREACH(i, m) {
1519                 _cleanup_free_ char *class = NULL;
1520
1521                 if (!output_show_machine(*i, patterns))
1522                         continue;
1523
1524                 sd_machine_get_class(*i, &class);
1525                 if (!streq_ptr(class, "container"))
1526                         continue;
1527
1528                 if (!GREEDY_REALLOC0(machine_infos, sz, c+1)) {
1529                         free_machines_list(machine_infos, c);
1530                         return log_oom();
1531                 }
1532
1533                 machine_infos[c].is_host = false;
1534                 machine_infos[c].name = strdup(*i);
1535                 if (!machine_infos[c].name) {
1536                         free_machines_list(machine_infos, c);
1537                         return log_oom();
1538                 }
1539
1540                 get_machine_properties(NULL, &machine_infos[c]);
1541                 c++;
1542         }
1543
1544         *_machine_infos = machine_infos;
1545         return c;
1546 }
1547
1548 static void output_machines_list(struct machine_info *machine_infos, unsigned n) {
1549         struct machine_info *m;
1550         unsigned
1551                 namelen = sizeof("NAME") - 1,
1552                 statelen = sizeof("STATE") - 1,
1553                 failedlen = sizeof("FAILED") - 1,
1554                 jobslen = sizeof("JOBS") - 1;
1555
1556         assert(machine_infos || n == 0);
1557
1558         for (m = machine_infos; m < machine_infos + n; m++) {
1559                 namelen = MAX(namelen, strlen(m->name) + (m->is_host ? sizeof(" (host)") - 1 : 0));
1560                 statelen = MAX(statelen, m->state ? strlen(m->state) : 0);
1561                 failedlen = MAX(failedlen, DECIMAL_STR_WIDTH(m->n_failed_units));
1562                 jobslen = MAX(jobslen, DECIMAL_STR_WIDTH(m->n_jobs));
1563         }
1564
1565         if (!arg_no_legend)
1566                 printf("%-*s %-*s %-*s %-*s\n",
1567                          namelen, "NAME",
1568                         statelen, "STATE",
1569                        failedlen, "FAILED",
1570                          jobslen, "JOBS");
1571
1572         for (m = machine_infos; m < machine_infos + n; m++) {
1573                 const char *on_state, *off_state, *on_failed, *off_failed;
1574
1575                 if (streq_ptr(m->state, "degraded")) {
1576                         on_state = ansi_highlight_red();
1577                         off_state = ansi_highlight_off();
1578                 } else if (!streq_ptr(m->state, "running")) {
1579                         on_state = ansi_highlight_yellow();
1580                         off_state = ansi_highlight_off();
1581                 } else
1582                         on_state = off_state = "";
1583
1584                 if (m->n_failed_units > 0) {
1585                         on_failed = ansi_highlight_red();
1586                         off_failed = ansi_highlight_off();
1587                 } else
1588                         on_failed = off_failed = "";
1589
1590                 if (m->is_host)
1591                         printf("%-*s (host) %s%-*s%s %s%*u%s %*u\n",
1592                                (int) (namelen - (sizeof(" (host)")-1)), strna(m->name),
1593                                on_state, statelen, strna(m->state), off_state,
1594                                on_failed, failedlen, m->n_failed_units, off_failed,
1595                                jobslen, m->n_jobs);
1596                 else
1597                         printf("%-*s %s%-*s%s %s%*u%s %*u\n",
1598                                namelen, strna(m->name),
1599                                on_state, statelen, strna(m->state), off_state,
1600                                on_failed, failedlen, m->n_failed_units, off_failed,
1601                                jobslen, m->n_jobs);
1602         }
1603
1604         if (!arg_no_legend)
1605                 printf("\n%u machines listed.\n", n);
1606 }
1607
1608 static int list_machines(sd_bus *bus, char **args) {
1609         struct machine_info *machine_infos = NULL;
1610         int r;
1611
1612         assert(bus);
1613
1614         if (geteuid() != 0) {
1615                 log_error("Must be root.");
1616                 return -EPERM;
1617         }
1618
1619         pager_open_if_enabled();
1620
1621         r = get_machine_list(bus, &machine_infos, strv_skip_first(args));
1622         if (r < 0)
1623                 return r;
1624
1625         qsort_safe(machine_infos, r, sizeof(struct machine_info), compare_machine_info);
1626         output_machines_list(machine_infos, r);
1627         free_machines_list(machine_infos, r);
1628
1629         return 0;
1630 }
1631
1632 static int get_default(sd_bus *bus, char **args) {
1633         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1634         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1635         _cleanup_free_ char *_path = NULL;
1636         const char *path;
1637         int r;
1638
1639         if (!bus || avoid_bus()) {
1640                 r = unit_file_get_default(arg_scope, arg_root, &_path);
1641                 if (r < 0) {
1642                         log_error("Failed to get default target: %s", strerror(-r));
1643                         return r;
1644                 }
1645                 path = _path;
1646
1647         } else {
1648                 r = sd_bus_call_method(
1649                                 bus,
1650                                 "org.freedesktop.systemd1",
1651                                 "/org/freedesktop/systemd1",
1652                                 "org.freedesktop.systemd1.Manager",
1653                                 "GetDefaultTarget",
1654                                 &error,
1655                                 &reply,
1656                                 NULL);
1657                 if (r < 0) {
1658                         log_error("Failed to get default target: %s", bus_error_message(&error, -r));
1659                         return r;
1660                 }
1661
1662                 r = sd_bus_message_read(reply, "s", &path);
1663                 if (r < 0)
1664                         return bus_log_parse_error(r);
1665         }
1666
1667         if (path)
1668                 printf("%s\n", path);
1669
1670         return 0;
1671 }
1672
1673 static void dump_unit_file_changes(const UnitFileChange *changes, unsigned n_changes) {
1674         unsigned i;
1675
1676         assert(changes || n_changes == 0);
1677
1678         for (i = 0; i < n_changes; i++) {
1679                 if (changes[i].type == UNIT_FILE_SYMLINK)
1680                         log_info("ln -s '%s' '%s'", changes[i].source, changes[i].path);
1681                 else
1682                         log_info("rm '%s'", changes[i].path);
1683         }
1684 }
1685
1686 static int deserialize_and_dump_unit_file_changes(sd_bus_message *m) {
1687         const char *type, *path, *source;
1688         int r;
1689
1690         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sss)");
1691         if (r < 0)
1692                 return bus_log_parse_error(r);
1693
1694         while ((r = sd_bus_message_read(m, "(sss)", &type, &path, &source)) > 0) {
1695                 if (!arg_quiet) {
1696                         if (streq(type, "symlink"))
1697                                 log_info("ln -s '%s' '%s'", source, path);
1698                         else
1699                                 log_info("rm '%s'", path);
1700                 }
1701         }
1702         if (r < 0)
1703                 return bus_log_parse_error(r);
1704
1705         r = sd_bus_message_exit_container(m);
1706         if (r < 0)
1707                 return bus_log_parse_error(r);
1708
1709         return 0;
1710 }
1711
1712 static int set_default(sd_bus *bus, char **args) {
1713         _cleanup_free_ char *unit = NULL;
1714         UnitFileChange *changes = NULL;
1715         unsigned n_changes = 0;
1716         int r;
1717
1718         unit = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".target");
1719         if (!unit)
1720                 return log_oom();
1721
1722         if (!bus || avoid_bus()) {
1723                 r = unit_file_set_default(arg_scope, arg_root, unit, arg_force, &changes, &n_changes);
1724                 if (r < 0) {
1725                         log_error("Failed to set default target: %s", strerror(-r));
1726                         return r;
1727                 }
1728
1729                 if (!arg_quiet)
1730                         dump_unit_file_changes(changes, n_changes);
1731
1732                 r = 0;
1733         } else {
1734                 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1735                 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1736
1737                 r = sd_bus_call_method(
1738                                 bus,
1739                                 "org.freedesktop.systemd1",
1740                                 "/org/freedesktop/systemd1",
1741                                 "org.freedesktop.systemd1.Manager",
1742                                 "SetDefaultTarget",
1743                                 &error,
1744                                 &reply,
1745                                 "sb", unit, arg_force);
1746                 if (r < 0) {
1747                         log_error("Failed to set default target: %s", bus_error_message(&error, -r));
1748                         return r;
1749                 }
1750
1751                 r = deserialize_and_dump_unit_file_changes(reply);
1752                 if (r < 0)
1753                         return r;
1754
1755                 /* Try to reload if enabeld */
1756                 if (!arg_no_reload)
1757                         r = daemon_reload(bus, args);
1758                 else
1759                         r = 0;
1760         }
1761
1762         unit_file_changes_free(changes, n_changes);
1763
1764         return r;
1765 }
1766
1767 struct job_info {
1768         uint32_t id;
1769         const char *name, *type, *state;
1770 };
1771
1772 static void output_jobs_list(const struct job_info* jobs, unsigned n, bool skipped) {
1773         unsigned id_len, unit_len, type_len, state_len;
1774         const struct job_info *j;
1775         const char *on, *off;
1776         bool shorten = false;
1777
1778         assert(n == 0 || jobs);
1779
1780         if (n == 0) {
1781                 on = ansi_highlight_green();
1782                 off = ansi_highlight_off();
1783
1784                 printf("%sNo jobs %s.%s\n", on, skipped ? "listed" : "running", off);
1785                 return;
1786         }
1787
1788         pager_open_if_enabled();
1789
1790         id_len = sizeof("JOB")-1;
1791         unit_len = sizeof("UNIT")-1;
1792         type_len = sizeof("TYPE")-1;
1793         state_len = sizeof("STATE")-1;
1794
1795         for (j = jobs; j < jobs + n; j++) {
1796                 uint32_t id = j->id;
1797                 assert(j->name && j->type && j->state);
1798
1799                 id_len = MAX(id_len, DECIMAL_STR_WIDTH(id));
1800                 unit_len = MAX(unit_len, strlen(j->name));
1801                 type_len = MAX(type_len, strlen(j->type));
1802                 state_len = MAX(state_len, strlen(j->state));
1803         }
1804
1805         if (!arg_full && id_len + 1 + unit_len + type_len + 1 + state_len > columns()) {
1806                 unit_len = MAX(33u, columns() - id_len - type_len - state_len - 3);
1807                 shorten = true;
1808         }
1809
1810         if (!arg_no_legend)
1811                 printf("%*s %-*s %-*s %-*s\n",
1812                        id_len, "JOB",
1813                        unit_len, "UNIT",
1814                        type_len, "TYPE",
1815                        state_len, "STATE");
1816
1817         for (j = jobs; j < jobs + n; j++) {
1818                 _cleanup_free_ char *e = NULL;
1819
1820                 if (streq(j->state, "running")) {
1821                         on = ansi_highlight();
1822                         off = ansi_highlight_off();
1823                 } else
1824                         on = off = "";
1825
1826                 e = shorten ? ellipsize(j->name, unit_len, 33) : NULL;
1827                 printf("%*u %s%-*s%s %-*s %s%-*s%s\n",
1828                        id_len, j->id,
1829                        on, unit_len, e ? e : j->name, off,
1830                        type_len, j->type,
1831                        on, state_len, j->state, off);
1832         }
1833
1834         if (!arg_no_legend) {
1835                 on = ansi_highlight();
1836                 off = ansi_highlight_off();
1837
1838                 printf("\n%s%u jobs listed%s.\n", on, n, off);
1839         }
1840 }
1841
1842 static bool output_show_job(struct job_info *job, char **patterns) {
1843         char **pattern;
1844
1845         assert(job);
1846
1847         if (strv_isempty(patterns))
1848                 return true;
1849
1850         STRV_FOREACH(pattern, patterns)
1851                 if (fnmatch(*pattern, job->name, FNM_NOESCAPE) == 0)
1852                         return true;
1853         return false;
1854 }
1855
1856 static int list_jobs(sd_bus *bus, char **args) {
1857         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1858         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1859         const char *name, *type, *state, *job_path, *unit_path;
1860         _cleanup_free_ struct job_info *jobs = NULL;
1861         size_t size = 0;
1862         unsigned c = 0;
1863         uint32_t id;
1864         int r;
1865         bool skipped = false;
1866
1867         r = sd_bus_call_method(
1868                         bus,
1869                         "org.freedesktop.systemd1",
1870                         "/org/freedesktop/systemd1",
1871                         "org.freedesktop.systemd1.Manager",
1872                         "ListJobs",
1873                         &error,
1874                         &reply,
1875                         NULL);
1876         if (r < 0) {
1877                 log_error("Failed to list jobs: %s", bus_error_message(&error, r));
1878                 return r;
1879         }
1880
1881         r = sd_bus_message_enter_container(reply, 'a', "(usssoo)");
1882         if (r < 0)
1883                 return bus_log_parse_error(r);
1884
1885         while ((r = sd_bus_message_read(reply, "(usssoo)", &id, &name, &type, &state, &job_path, &unit_path)) > 0) {
1886                 struct job_info job = { id, name, type, state };
1887
1888                 if (!output_show_job(&job, strv_skip_first(args))) {
1889                         skipped = true;
1890                         continue;
1891                 }
1892
1893                 if (!GREEDY_REALLOC(jobs, size, c + 1))
1894                         return log_oom();
1895
1896                 jobs[c++] = job;
1897         }
1898         if (r < 0)
1899                 return bus_log_parse_error(r);
1900
1901         r = sd_bus_message_exit_container(reply);
1902         if (r < 0)
1903                 return bus_log_parse_error(r);
1904
1905         output_jobs_list(jobs, c, skipped);
1906         return r;
1907 }
1908
1909 static int cancel_job(sd_bus *bus, char **args) {
1910         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1911         char **name;
1912
1913         assert(args);
1914
1915         if (strv_length(args) <= 1)
1916                 return daemon_reload(bus, args);
1917
1918         STRV_FOREACH(name, args+1) {
1919                 uint32_t id;
1920                 int r;
1921
1922                 r = safe_atou32(*name, &id);
1923                 if (r < 0) {
1924                         log_error("Failed to parse job id \"%s\": %s", *name, strerror(-r));
1925                         return r;
1926                 }
1927
1928                 r = sd_bus_call_method(
1929                                 bus,
1930                                 "org.freedesktop.systemd1",
1931                                 "/org/freedesktop/systemd1",
1932                                 "org.freedesktop.systemd1.Manager",
1933                                 "CancelJob",
1934                                 &error,
1935                                 NULL,
1936                                 "u", id);
1937                 if (r < 0) {
1938                         log_error("Failed to cancel job %u: %s", (unsigned) id, bus_error_message(&error, r));
1939                         return r;
1940                 }
1941         }
1942
1943         return 0;
1944 }
1945
1946 static int need_daemon_reload(sd_bus *bus, const char *unit) {
1947         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1948         const char *path;
1949         int b, r;
1950
1951         /* We ignore all errors here, since this is used to show a
1952          * warning only */
1953
1954         /* We don't use unit_dbus_path_from_name() directly since we
1955          * don't want to load the unit if it isn't loaded. */
1956
1957         r = sd_bus_call_method(
1958                         bus,
1959                         "org.freedesktop.systemd1",
1960                         "/org/freedesktop/systemd1",
1961                         "org.freedesktop.systemd1.Manager",
1962                         "GetUnit",
1963                         NULL,
1964                         &reply,
1965                         "s", unit);
1966         if (r < 0)
1967                 return r;
1968
1969         r = sd_bus_message_read(reply, "o", &path);
1970         if (r < 0)
1971                 return r;
1972
1973         r = sd_bus_get_property_trivial(
1974                         bus,
1975                         "org.freedesktop.systemd1",
1976                         path,
1977                         "org.freedesktop.systemd1.Unit",
1978                         "NeedDaemonReload",
1979                         NULL,
1980                         'b', &b);
1981         if (r < 0)
1982                 return r;
1983
1984         return b;
1985 }
1986
1987 typedef struct WaitData {
1988         Set *set;
1989
1990         char *name;
1991         char *result;
1992 } WaitData;
1993
1994 static int wait_filter(sd_bus *bus, sd_bus_message *m, void *data, sd_bus_error *error) {
1995         WaitData *d = data;
1996
1997         assert(bus);
1998         assert(m);
1999         assert(d);
2000
2001         log_debug("Got D-Bus request: %s.%s() on %s",
2002                   sd_bus_message_get_interface(m),
2003                   sd_bus_message_get_member(m),
2004                   sd_bus_message_get_path(m));
2005
2006         if (sd_bus_message_is_signal(m, "org.freedesktop.DBus.Local", "Disconnected")) {
2007                 log_error("Warning! D-Bus connection terminated.");
2008                 sd_bus_close(bus);
2009         } else if (sd_bus_message_is_signal(m, "org.freedesktop.systemd1.Manager", "JobRemoved")) {
2010                 uint32_t id;
2011                 const char *path, *result, *unit;
2012                 char *ret;
2013                 int r;
2014
2015                 r = sd_bus_message_read(m, "uoss", &id, &path, &unit, &result);
2016                 if (r >= 0) {
2017                         ret = set_remove(d->set, (char*) path);
2018                         if (!ret)
2019                                 return 0;
2020
2021                         free(ret);
2022
2023                         if (!isempty(result))
2024                                 d->result = strdup(result);
2025
2026                         if (!isempty(unit))
2027                                 d->name = strdup(unit);
2028
2029                         return 0;
2030                 }
2031 #ifndef NOLEGACY
2032                 r = sd_bus_message_read(m, "uos", &id, &path, &result);
2033                 if (r >= 0) {
2034                         ret = set_remove(d->set, (char*) path);
2035                         if (!ret)
2036                                 return 0;
2037
2038                         free(ret);
2039
2040                         if (*result)
2041                                 d->result = strdup(result);
2042
2043                         return 0;
2044                 }
2045 #endif
2046
2047                 bus_log_parse_error(r);
2048         }
2049
2050         return 0;
2051 }
2052
2053 static int enable_wait_for_jobs(sd_bus *bus) {
2054         int r;
2055
2056         assert(bus);
2057
2058         r = sd_bus_add_match(
2059                         bus,
2060                         "type='signal',"
2061                         "sender='org.freedesktop.systemd1',"
2062                         "interface='org.freedesktop.systemd1.Manager',"
2063                         "member='JobRemoved',"
2064                         "path='/org/freedesktop/systemd1'",
2065                         NULL, NULL);
2066         if (r < 0) {
2067                 log_error("Failed to add match");
2068                 return -EIO;
2069         }
2070
2071         /* This is slightly dirty, since we don't undo the match registrations. */
2072         return 0;
2073 }
2074
2075 static int bus_process_wait(sd_bus *bus) {
2076         int r;
2077
2078         for (;;) {
2079                 r = sd_bus_process(bus, NULL);
2080                 if (r < 0)
2081                         return r;
2082                 if (r > 0)
2083                         return 0;
2084                 r = sd_bus_wait(bus, (uint64_t) -1);
2085                 if (r < 0)
2086                         return r;
2087         }
2088 }
2089
2090 static int check_wait_response(WaitData *d) {
2091         int r = 0;
2092
2093         assert(d->result);
2094
2095         if (!arg_quiet) {
2096                 if (streq(d->result, "timeout"))
2097                         log_error("Job for %s timed out.", strna(d->name));
2098                 else if (streq(d->result, "canceled"))
2099                         log_error("Job for %s canceled.", strna(d->name));
2100                 else if (streq(d->result, "dependency"))
2101                         log_error("A dependency job for %s failed. See 'journalctl -xn' for details.", strna(d->name));
2102                 else if (!streq(d->result, "done") && !streq(d->result, "skipped"))
2103                         log_error("Job for %s failed. See 'systemctl status %s' and 'journalctl -xn' for details.", strna(d->name), strna(d->name));
2104         }
2105
2106         if (streq(d->result, "timeout"))
2107                 r = -ETIME;
2108         else if (streq(d->result, "canceled"))
2109                 r = -ECANCELED;
2110         else if (streq(d->result, "dependency"))
2111                 r = -EIO;
2112         else if (!streq(d->result, "done") && !streq(d->result, "skipped"))
2113                 r = -EIO;
2114
2115         return r;
2116 }
2117
2118 static int wait_for_jobs(sd_bus *bus, Set *s) {
2119         WaitData d = { .set = s };
2120         int r = 0, q;
2121
2122         assert(bus);
2123         assert(s);
2124
2125         q = sd_bus_add_filter(bus, wait_filter, &d);
2126         if (q < 0)
2127                 return log_oom();
2128
2129         while (!set_isempty(s)) {
2130                 q = bus_process_wait(bus);
2131                 if (q < 0) {
2132                         log_error("Failed to wait for response: %s", strerror(-r));
2133                         return q;
2134                 }
2135
2136                 if (d.result) {
2137                         q = check_wait_response(&d);
2138                         /* Return the first error as it is most likely to be
2139                          * meaningful. */
2140                         if (q < 0 && r == 0)
2141                                 r = q;
2142                         log_debug("Got result %s/%s for job %s",
2143                                   strna(d.result), strerror(-q), strna(d.name));
2144                 }
2145
2146                 free(d.name);
2147                 d.name = NULL;
2148
2149                 free(d.result);
2150                 d.result = NULL;
2151         }
2152
2153         q = sd_bus_remove_filter(bus, wait_filter, &d);
2154         if (q < 0 && r == 0)
2155                 r = q;
2156
2157         return r;
2158 }
2159
2160 static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet) {
2161         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2162         _cleanup_free_ char *n = NULL, *state = NULL;
2163         const char *path;
2164         int r;
2165
2166         assert(name);
2167
2168         n = unit_name_mangle(name, MANGLE_NOGLOB);
2169         if (!n)
2170                 return log_oom();
2171
2172         /* We don't use unit_dbus_path_from_name() directly since we
2173          * don't want to load the unit if it isn't loaded. */
2174
2175         r = sd_bus_call_method(
2176                         bus,
2177                         "org.freedesktop.systemd1",
2178                         "/org/freedesktop/systemd1",
2179                         "org.freedesktop.systemd1.Manager",
2180                         "GetUnit",
2181                         NULL,
2182                         &reply,
2183                         "s", n);
2184         if (r < 0) {
2185                 if (!quiet)
2186                         puts("unknown");
2187                 return 0;
2188         }
2189
2190         r = sd_bus_message_read(reply, "o", &path);
2191         if (r < 0)
2192                 return bus_log_parse_error(r);
2193
2194         r = sd_bus_get_property_string(
2195                         bus,
2196                         "org.freedesktop.systemd1",
2197                         path,
2198                         "org.freedesktop.systemd1.Unit",
2199                         "ActiveState",
2200                         NULL,
2201                         &state);
2202         if (r < 0) {
2203                 if (!quiet)
2204                         puts("unknown");
2205                 return 0;
2206         }
2207
2208         if (!quiet)
2209                 puts(state);
2210
2211         return nulstr_contains(good_states, state);
2212 }
2213
2214 static int check_triggering_units(
2215                 sd_bus *bus,
2216                 const char *name) {
2217
2218         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2219         _cleanup_free_ char *path = NULL, *n = NULL, *state = NULL;
2220         _cleanup_strv_free_ char **triggered_by = NULL;
2221         bool print_warning_label = true;
2222         char **i;
2223         int r;
2224
2225         n = unit_name_mangle(name, MANGLE_NOGLOB);
2226         if (!n)
2227                 return log_oom();
2228
2229         path = unit_dbus_path_from_name(n);
2230         if (!path)
2231                 return log_oom();
2232
2233         r = sd_bus_get_property_string(
2234                         bus,
2235                         "org.freedesktop.systemd1",
2236                         path,
2237                         "org.freedesktop.systemd1.Unit",
2238                         "LoadState",
2239                         &error,
2240                         &state);
2241         if (r < 0) {
2242                 log_error("Failed to get load state of %s: %s", n, bus_error_message(&error, r));
2243                 return r;
2244         }
2245
2246         if (streq(state, "masked"))
2247                 return 0;
2248
2249         r = sd_bus_get_property_strv(
2250                         bus,
2251                         "org.freedesktop.systemd1",
2252                         path,
2253                         "org.freedesktop.systemd1.Unit",
2254                         "TriggeredBy",
2255                         &error,
2256                         &triggered_by);
2257         if (r < 0) {
2258                 log_error("Failed to get triggered by array of %s: %s", n, bus_error_message(&error, r));
2259                 return r;
2260         }
2261
2262         STRV_FOREACH(i, triggered_by) {
2263                 r = check_one_unit(bus, *i, "active\0reloading\0", true);
2264                 if (r < 0) {
2265                         log_error("Failed to check unit: %s", strerror(-r));
2266                         return r;
2267                 }
2268
2269                 if (r == 0)
2270                         continue;
2271
2272                 if (print_warning_label) {
2273                         log_warning("Warning: Stopping %s, but it can still be activated by:", n);
2274                         print_warning_label = false;
2275                 }
2276
2277                 log_warning("  %s", *i);
2278         }
2279
2280         return 0;
2281 }
2282
2283 static const char *verb_to_method(const char *verb) {
2284        uint i;
2285
2286        for (i = 0; i < ELEMENTSOF(unit_actions); i++)
2287                 if (streq_ptr(unit_actions[i].verb, verb))
2288                         return unit_actions[i].method;
2289
2290        return "StartUnit";
2291 }
2292
2293 static const char *method_to_verb(const char *method) {
2294        uint i;
2295
2296        for (i = 0; i < ELEMENTSOF(unit_actions); i++)
2297                 if (streq_ptr(unit_actions[i].method, method))
2298                         return unit_actions[i].verb;
2299
2300        return "n/a";
2301 }
2302
2303 static int start_unit_one(
2304                 sd_bus *bus,
2305                 const char *method,
2306                 const char *name,
2307                 const char *mode,
2308                 sd_bus_error *error,
2309                 Set *s) {
2310
2311         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2312         const char *path;
2313         int r;
2314
2315         assert(method);
2316         assert(name);
2317         assert(mode);
2318         assert(error);
2319
2320         log_debug("Calling manager for %s on %s, %s", method, name, mode);
2321         r = sd_bus_call_method(
2322                         bus,
2323                         "org.freedesktop.systemd1",
2324                         "/org/freedesktop/systemd1",
2325                         "org.freedesktop.systemd1.Manager",
2326                         method,
2327                         error,
2328                         &reply,
2329                         "ss", name, mode);
2330         if (r < 0) {
2331                 const char *verb;
2332
2333                 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
2334                         /* There's always a fallback possible for
2335                          * legacy actions. */
2336                         return -EADDRNOTAVAIL;
2337
2338                 verb = method_to_verb(method);
2339
2340                 log_error("Failed to %s %s: %s", verb, name, bus_error_message(error, r));
2341                 return r;
2342         }
2343
2344         r = sd_bus_message_read(reply, "o", &path);
2345         if (r < 0)
2346                 return bus_log_parse_error(r);
2347
2348         if (need_daemon_reload(bus, name) > 0)
2349                 log_warning("Warning: Unit file of %s changed on disk, 'systemctl%s daemon-reload' recommended.",
2350                             name, arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
2351
2352         if (s) {
2353                 char *p;
2354
2355                 p = strdup(path);
2356                 if (!p)
2357                         return log_oom();
2358
2359                 log_debug("Adding %s to the set", p);
2360                 r = set_consume(s, p);
2361                 if (r < 0)
2362                         return log_oom();
2363         }
2364
2365         return 0;
2366 }
2367
2368 static int expand_names(sd_bus *bus, char **names, const char* suffix, char ***ret) {
2369
2370         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2371         _cleanup_strv_free_ char **mangled = NULL, **globs = NULL;
2372         char **name;
2373         int r = 0, i;
2374
2375         STRV_FOREACH(name, names) {
2376                 char *t;
2377
2378                 if (suffix)
2379                         t = unit_name_mangle_with_suffix(*name, MANGLE_GLOB, suffix);
2380                 else
2381                         t = unit_name_mangle(*name, MANGLE_GLOB);
2382                 if (!t)
2383                         return log_oom();
2384
2385                 if (string_is_glob(t))
2386                         r = strv_consume(&globs, t);
2387                 else
2388                         r = strv_consume(&mangled, t);
2389                 if (r < 0)
2390                         return log_oom();
2391         }
2392
2393         /* Query the manager only if any of the names are a glob, since
2394          * this is fairly expensive */
2395         if (!strv_isempty(globs)) {
2396                 _cleanup_free_ UnitInfo *unit_infos = NULL;
2397
2398                 r = get_unit_list(bus, &reply, &unit_infos, globs);
2399                 if (r < 0)
2400                         return r;
2401
2402                 for (i = 0; i < r; i++)
2403                         if (strv_extend(&mangled, unit_infos[i].id) < 0)
2404                                 return log_oom();
2405         }
2406
2407         *ret = mangled;
2408         mangled = NULL; /* do not free */
2409         return 0;
2410 }
2411
2412 static const struct {
2413         const char *target;
2414         const char *verb;
2415         const char *mode;
2416 } action_table[_ACTION_MAX] = {
2417         [ACTION_HALT]         = { SPECIAL_HALT_TARGET,         "halt",         "replace-irreversibly" },
2418         [ACTION_POWEROFF]     = { SPECIAL_POWEROFF_TARGET,     "poweroff",     "replace-irreversibly" },
2419         [ACTION_REBOOT]       = { SPECIAL_REBOOT_TARGET,       "reboot",       "replace-irreversibly" },
2420         [ACTION_KEXEC]        = { SPECIAL_KEXEC_TARGET,        "kexec",        "replace-irreversibly" },
2421         [ACTION_RUNLEVEL2]    = { SPECIAL_RUNLEVEL2_TARGET,    NULL,           "isolate" },
2422         [ACTION_RUNLEVEL3]    = { SPECIAL_RUNLEVEL3_TARGET,    NULL,           "isolate" },
2423         [ACTION_RUNLEVEL4]    = { SPECIAL_RUNLEVEL4_TARGET,    NULL,           "isolate" },
2424         [ACTION_RUNLEVEL5]    = { SPECIAL_RUNLEVEL5_TARGET,    NULL,           "isolate" },
2425         [ACTION_RESCUE]       = { SPECIAL_RESCUE_TARGET,       "rescue",       "isolate" },
2426         [ACTION_EMERGENCY]    = { SPECIAL_EMERGENCY_TARGET,    "emergency",    "isolate" },
2427         [ACTION_DEFAULT]      = { SPECIAL_DEFAULT_TARGET,      "default",      "isolate" },
2428         [ACTION_EXIT]         = { SPECIAL_EXIT_TARGET,         "exit",         "replace-irreversibly" },
2429         [ACTION_SUSPEND]      = { SPECIAL_SUSPEND_TARGET,      "suspend",      "replace-irreversibly" },
2430         [ACTION_HIBERNATE]    = { SPECIAL_HIBERNATE_TARGET,    "hibernate",    "replace-irreversibly" },
2431         [ACTION_HYBRID_SLEEP] = { SPECIAL_HYBRID_SLEEP_TARGET, "hybrid-sleep", "replace-irreversibly" },
2432 };
2433
2434 static enum action verb_to_action(const char *verb) {
2435         enum action i;
2436
2437         for (i = _ACTION_INVALID; i < _ACTION_MAX; i++)
2438                 if (streq_ptr(action_table[i].verb, verb))
2439                         return i;
2440
2441         return _ACTION_INVALID;
2442 }
2443
2444 static int start_unit(sd_bus *bus, char **args) {
2445         _cleanup_set_free_free_ Set *s = NULL;
2446         _cleanup_strv_free_ char **names = NULL;
2447         const char *method, *mode, *one_name;
2448         char **name;
2449         int r = 0;
2450
2451         assert(bus);
2452
2453         ask_password_agent_open_if_enabled();
2454
2455         if (arg_action == ACTION_SYSTEMCTL) {
2456                 enum action action;
2457                 method = verb_to_method(args[0]);
2458                 action = verb_to_action(args[0]);
2459
2460                 mode = streq(args[0], "isolate") ? "isolate" :
2461                        action_table[action].mode ?: arg_job_mode;
2462
2463                 one_name = action_table[action].target;
2464         } else {
2465                 assert(arg_action < ELEMENTSOF(action_table));
2466                 assert(action_table[arg_action].target);
2467
2468                 method = "StartUnit";
2469
2470                 mode = action_table[arg_action].mode;
2471                 one_name = action_table[arg_action].target;
2472         }
2473
2474         if (one_name)
2475                 names = strv_new(one_name, NULL);
2476         else {
2477                 r = expand_names(bus, args + 1, NULL, &names);
2478                 if (r < 0)
2479                         log_error("Failed to expand names: %s", strerror(-r));
2480         }
2481
2482         if (!arg_no_block) {
2483                 r = enable_wait_for_jobs(bus);
2484                 if (r < 0) {
2485                         log_error("Could not watch jobs: %s", strerror(-r));
2486                         return r;
2487                 }
2488
2489                 s = set_new(string_hash_func, string_compare_func);
2490                 if (!s)
2491                         return log_oom();
2492         }
2493
2494         STRV_FOREACH(name, names) {
2495                 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2496                 int q;
2497
2498                 q = start_unit_one(bus, method, *name, mode, &error, s);
2499                 if (r >= 0 && q < 0)
2500                         r = translate_bus_error_to_exit_status(q, &error);
2501         }
2502
2503         if (!arg_no_block) {
2504                 int q;
2505
2506                 q = wait_for_jobs(bus, s);
2507                 if (q < 0)
2508                         return q;
2509
2510                 /* When stopping units, warn if they can still be triggered by
2511                  * another active unit (socket, path, timer) */
2512                 if (!arg_quiet && streq(method, "StopUnit"))
2513                         STRV_FOREACH(name, names)
2514                                 check_triggering_units(bus, *name);
2515         }
2516
2517         return r;
2518 }
2519
2520 /* Ask systemd-logind, which might grant access to unprivileged users
2521  * through PolicyKit */
2522 static int reboot_with_logind(sd_bus *bus, enum action a) {
2523 #ifdef HAVE_LOGIND
2524         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2525         const char *method;
2526         int r;
2527
2528         if (!bus)
2529                 return -EIO;
2530
2531         polkit_agent_open_if_enabled();
2532
2533         switch (a) {
2534
2535         case ACTION_REBOOT:
2536                 method = "Reboot";
2537                 break;
2538
2539         case ACTION_POWEROFF:
2540                 method = "PowerOff";
2541                 break;
2542
2543         case ACTION_SUSPEND:
2544                 method = "Suspend";
2545                 break;
2546
2547         case ACTION_HIBERNATE:
2548                 method = "Hibernate";
2549                 break;
2550
2551         case ACTION_HYBRID_SLEEP:
2552                 method = "HybridSleep";
2553                 break;
2554
2555         default:
2556                 return -EINVAL;
2557         }
2558
2559         r = sd_bus_call_method(
2560                         bus,
2561                         "org.freedesktop.login1",
2562                         "/org/freedesktop/login1",
2563                         "org.freedesktop.login1.Manager",
2564                         method,
2565                         &error,
2566                         NULL,
2567                         "b", true);
2568         if (r < 0)
2569                 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
2570
2571         return r;
2572 #else
2573         return -ENOSYS;
2574 #endif
2575 }
2576
2577 static int check_inhibitors(sd_bus *bus, enum action a) {
2578 #ifdef HAVE_LOGIND
2579         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2580         _cleanup_strv_free_ char **sessions = NULL;
2581         const char *what, *who, *why, *mode;
2582         uint32_t uid, pid;
2583         unsigned c = 0;
2584         char **s;
2585         int r;
2586
2587         if (!bus)
2588                 return 0;
2589
2590         if (arg_ignore_inhibitors || arg_force > 0)
2591                 return 0;
2592
2593         if (arg_when > 0)
2594                 return 0;
2595
2596         if (geteuid() == 0)
2597                 return 0;
2598
2599         if (!on_tty())
2600                 return 0;
2601
2602         r = sd_bus_call_method(
2603                         bus,
2604                         "org.freedesktop.login1",
2605                         "/org/freedesktop/login1",
2606                         "org.freedesktop.login1.Manager",
2607                         "ListInhibitors",
2608                         NULL,
2609                         &reply,
2610                         NULL);
2611         if (r < 0)
2612                 /* If logind is not around, then there are no inhibitors... */
2613                 return 0;
2614
2615         r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssuu)");
2616         if (r < 0)
2617                 return bus_log_parse_error(r);
2618
2619         while ((r = sd_bus_message_read(reply, "(ssssuu)", &what, &who, &why, &mode, &uid, &pid)) > 0) {
2620                 _cleanup_free_ char *comm = NULL, *user = NULL;
2621                 _cleanup_strv_free_ char **sv = NULL;
2622
2623                 if (!streq(mode, "block"))
2624                         continue;
2625
2626                 sv = strv_split(what, ":");
2627                 if (!sv)
2628                         return log_oom();
2629
2630                 if (!strv_contains(sv,
2631                                   a == ACTION_HALT ||
2632                                   a == ACTION_POWEROFF ||
2633                                   a == ACTION_REBOOT ||
2634                                   a == ACTION_KEXEC ? "shutdown" : "sleep"))
2635                         continue;
2636
2637                 get_process_comm(pid, &comm);
2638                 user = uid_to_name(uid);
2639
2640                 log_warning("Operation inhibited by \"%s\" (PID %lu \"%s\", user %s), reason is \"%s\".",
2641                             who, (unsigned long) pid, strna(comm), strna(user), why);
2642
2643                 c++;
2644         }
2645         if (r < 0)
2646                 return bus_log_parse_error(r);
2647
2648         r = sd_bus_message_exit_container(reply);
2649         if (r < 0)
2650                 return bus_log_parse_error(r);
2651
2652         /* Check for current sessions */
2653         sd_get_sessions(&sessions);
2654         STRV_FOREACH(s, sessions) {
2655                 _cleanup_free_ char *type = NULL, *tty = NULL, *seat = NULL, *user = NULL, *service = NULL, *class = NULL;
2656
2657                 if (sd_session_get_uid(*s, &uid) < 0 || uid == getuid())
2658                         continue;
2659
2660                 if (sd_session_get_class(*s, &class) < 0 || !streq(class, "user"))
2661                         continue;
2662
2663                 if (sd_session_get_type(*s, &type) < 0 || (!streq(type, "x11") && !streq(type, "tty")))
2664                         continue;
2665
2666                 sd_session_get_tty(*s, &tty);
2667                 sd_session_get_seat(*s, &seat);
2668                 sd_session_get_service(*s, &service);
2669                 user = uid_to_name(uid);
2670
2671                 log_warning("User %s is logged in on %s.", strna(user), isempty(tty) ? (isempty(seat) ? strna(service) : seat) : tty);
2672                 c++;
2673         }
2674
2675         if (c <= 0)
2676                 return 0;
2677
2678         log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
2679                   action_table[a].verb);
2680
2681         return -EPERM;
2682 #else
2683         return 0;
2684 #endif
2685 }
2686
2687 static int start_special(sd_bus *bus, char **args) {
2688         enum action a;
2689         int r;
2690
2691         assert(args);
2692
2693         a = verb_to_action(args[0]);
2694
2695         r = check_inhibitors(bus, a);
2696         if (r < 0)
2697                 return r;
2698
2699         if (arg_force >= 2 && geteuid() != 0) {
2700                 log_error("Must be root.");
2701                 return -EPERM;
2702         }
2703
2704         if (arg_force >= 2 &&
2705             (a == ACTION_HALT ||
2706              a == ACTION_POWEROFF ||
2707              a == ACTION_REBOOT))
2708                 return halt_now(a);
2709
2710         if (arg_force >= 1 &&
2711             (a == ACTION_HALT ||
2712              a == ACTION_POWEROFF ||
2713              a == ACTION_REBOOT ||
2714              a == ACTION_KEXEC ||
2715              a == ACTION_EXIT))
2716                 return daemon_reload(bus, args);
2717
2718         /* first try logind, to allow authentication with polkit */
2719         if (geteuid() != 0 &&
2720             (a == ACTION_POWEROFF ||
2721              a == ACTION_REBOOT ||
2722              a == ACTION_SUSPEND ||
2723              a == ACTION_HIBERNATE ||
2724              a == ACTION_HYBRID_SLEEP)) {
2725                 r = reboot_with_logind(bus, a);
2726                 if (r >= 0)
2727                         return r;
2728         }
2729
2730         r = start_unit(bus, args);
2731         if (r == EXIT_SUCCESS)
2732                 warn_wall(a);
2733
2734         return r;
2735 }
2736
2737 static int check_unit_generic(sd_bus *bus, int code, const char *good_states, char **args) {
2738         _cleanup_strv_free_ char **names = NULL;
2739         char **name;
2740         int r;
2741
2742         assert(bus);
2743         assert(args);
2744
2745         r = expand_names(bus, args, NULL, &names);
2746         if (r < 0) {
2747                 log_error("Failed to expand names: %s", strerror(-r));
2748                 return r;
2749         }
2750
2751         STRV_FOREACH(name, names) {
2752                 int state;
2753
2754                 state = check_one_unit(bus, *name, good_states, arg_quiet);
2755                 if (state < 0)
2756                         return state;
2757                 if (state == 0)
2758                         r = code;
2759         }
2760
2761         return r;
2762 }
2763
2764 static int check_unit_active(sd_bus *bus, char **args) {
2765         /* According to LSB: 3, "program is not running" */
2766         return check_unit_generic(bus, 3, "active\0reloading\0", args + 1);
2767 }
2768
2769 static int check_unit_failed(sd_bus *bus, char **args) {
2770         return check_unit_generic(bus, 1, "failed\0", args + 1);
2771 }
2772
2773 static int kill_unit(sd_bus *bus, char **args) {
2774         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2775         _cleanup_strv_free_ char **names = NULL;
2776         char **name;
2777         int r, q;
2778
2779         assert(bus);
2780         assert(args);
2781
2782         if (!arg_kill_who)
2783                 arg_kill_who = "all";
2784
2785         r = expand_names(bus, args + 1, NULL, &names);
2786         if (r < 0)
2787                 log_error("Failed to expand names: %s", strerror(-r));
2788
2789         STRV_FOREACH(name, names) {
2790                 q = sd_bus_call_method(
2791                                 bus,
2792                                 "org.freedesktop.systemd1",
2793                                 "/org/freedesktop/systemd1",
2794                                 "org.freedesktop.systemd1.Manager",
2795                                 "KillUnit",
2796                                 &error,
2797                                 NULL,
2798                                 "ssi", *names, arg_kill_who, arg_signal);
2799                 if (q < 0) {
2800                         log_error("Failed to kill unit %s: %s",
2801                                   *names, bus_error_message(&error, r));
2802                         if (r == 0)
2803                                 r = q;
2804                 }
2805         }
2806
2807         return r;
2808 }
2809
2810 typedef struct ExecStatusInfo {
2811         char *name;
2812
2813         char *path;
2814         char **argv;
2815
2816         bool ignore;
2817
2818         usec_t start_timestamp;
2819         usec_t exit_timestamp;
2820         pid_t pid;
2821         int code;
2822         int status;
2823
2824         LIST_FIELDS(struct ExecStatusInfo, exec);
2825 } ExecStatusInfo;
2826
2827 static void exec_status_info_free(ExecStatusInfo *i) {
2828         assert(i);
2829
2830         free(i->name);
2831         free(i->path);
2832         strv_free(i->argv);
2833         free(i);
2834 }
2835
2836 static int exec_status_info_deserialize(sd_bus_message *m, ExecStatusInfo *i) {
2837         uint64_t start_timestamp, exit_timestamp, start_timestamp_monotonic, exit_timestamp_monotonic;
2838         const char *path;
2839         uint32_t pid;
2840         int32_t code, status;
2841         int ignore, r;
2842
2843         assert(m);
2844         assert(i);
2845
2846         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_STRUCT, "sasbttttuii");
2847         if (r < 0)
2848                 return bus_log_parse_error(r);
2849         else if (r == 0)
2850                 return 0;
2851
2852         r = sd_bus_message_read(m, "s", &path);
2853         if (r < 0)
2854                 return bus_log_parse_error(r);
2855
2856         i->path = strdup(path);
2857         if (!i->path)
2858                 return log_oom();
2859
2860         r = sd_bus_message_read_strv(m, &i->argv);
2861         if (r < 0)
2862                 return bus_log_parse_error(r);
2863
2864         r = sd_bus_message_read(m,
2865                                 "bttttuii",
2866                                 &ignore,
2867                                 &start_timestamp, &start_timestamp_monotonic,
2868                                 &exit_timestamp, &exit_timestamp_monotonic,
2869                                 &pid,
2870                                 &code, &status);
2871         if (r < 0)
2872                 return bus_log_parse_error(r);
2873
2874         i->ignore = ignore;
2875         i->start_timestamp = (usec_t) start_timestamp;
2876         i->exit_timestamp = (usec_t) exit_timestamp;
2877         i->pid = (pid_t) pid;
2878         i->code = code;
2879         i->status = status;
2880
2881         r = sd_bus_message_exit_container(m);
2882         if (r < 0)
2883                 return bus_log_parse_error(r);
2884
2885         return 1;
2886 }
2887
2888 typedef struct UnitStatusInfo {
2889         const char *id;
2890         const char *load_state;
2891         const char *active_state;
2892         const char *sub_state;
2893         const char *unit_file_state;
2894
2895         const char *description;
2896         const char *following;
2897
2898         char **documentation;
2899
2900         const char *fragment_path;
2901         const char *source_path;
2902         const char *control_group;
2903
2904         char **dropin_paths;
2905
2906         const char *load_error;
2907         const char *result;
2908
2909         usec_t inactive_exit_timestamp;
2910         usec_t inactive_exit_timestamp_monotonic;
2911         usec_t active_enter_timestamp;
2912         usec_t active_exit_timestamp;
2913         usec_t inactive_enter_timestamp;
2914
2915         bool need_daemon_reload;
2916
2917         /* Service */
2918         pid_t main_pid;
2919         pid_t control_pid;
2920         const char *status_text;
2921         const char *pid_file;
2922         bool running:1;
2923
2924         usec_t start_timestamp;
2925         usec_t exit_timestamp;
2926
2927         int exit_code, exit_status;
2928
2929         usec_t condition_timestamp;
2930         bool condition_result;
2931         bool failed_condition_trigger;
2932         bool failed_condition_negate;
2933         const char *failed_condition;
2934         const char *failed_condition_param;
2935
2936         /* Socket */
2937         unsigned n_accepted;
2938         unsigned n_connections;
2939         bool accept;
2940
2941         /* Pairs of type, path */
2942         char **listen;
2943
2944         /* Device */
2945         const char *sysfs_path;
2946
2947         /* Mount, Automount */
2948         const char *where;
2949
2950         /* Swap */
2951         const char *what;
2952
2953         LIST_HEAD(ExecStatusInfo, exec);
2954 } UnitStatusInfo;
2955
2956 static void print_status_info(
2957                 UnitStatusInfo *i,
2958                 bool *ellipsized) {
2959
2960         ExecStatusInfo *p;
2961         const char *on, *off, *ss;
2962         usec_t timestamp;
2963         char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
2964         char since2[FORMAT_TIMESTAMP_MAX], *s2;
2965         const char *path;
2966         int flags =
2967                 arg_all * OUTPUT_SHOW_ALL |
2968                 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
2969                 on_tty() * OUTPUT_COLOR |
2970                 !arg_quiet * OUTPUT_WARN_CUTOFF |
2971                 arg_full * OUTPUT_FULL_WIDTH;
2972         char **t, **t2;
2973
2974         assert(i);
2975
2976         /* This shows pretty information about a unit. See
2977          * print_property() for a low-level property printer */
2978
2979         printf("%s", strna(i->id));
2980
2981         if (i->description && !streq_ptr(i->id, i->description))
2982                 printf(" - %s", i->description);
2983
2984         printf("\n");
2985
2986         if (i->following)
2987                 printf("   Follow: unit currently follows state of %s\n", i->following);
2988
2989         if (streq_ptr(i->load_state, "error")) {
2990                 on = ansi_highlight_red();
2991                 off = ansi_highlight_off();
2992         } else
2993                 on = off = "";
2994
2995         path = i->source_path ? i->source_path : i->fragment_path;
2996
2997         if (i->load_error)
2998                 printf("   Loaded: %s%s%s (Reason: %s)\n",
2999                        on, strna(i->load_state), off, i->load_error);
3000         else if (path && i->unit_file_state)
3001                 printf("   Loaded: %s%s%s (%s; %s)\n",
3002                        on, strna(i->load_state), off, path, i->unit_file_state);
3003         else if (path)
3004                 printf("   Loaded: %s%s%s (%s)\n",
3005                        on, strna(i->load_state), off, path);
3006         else
3007                 printf("   Loaded: %s%s%s\n",
3008                        on, strna(i->load_state), off);
3009
3010         if (!strv_isempty(i->dropin_paths)) {
3011                 _cleanup_free_ char *dir = NULL;
3012                 bool last = false;
3013                 char ** dropin;
3014
3015                 STRV_FOREACH(dropin, i->dropin_paths) {
3016                         if (! dir || last) {
3017                                 printf(dir ? "        " : "  Drop-In: ");
3018
3019                                 free(dir);
3020                                 dir = NULL;
3021
3022                                 if (path_get_parent(*dropin, &dir) < 0) {
3023                                         log_oom();
3024                                         return;
3025                                 }
3026
3027                                 printf("%s\n           %s", dir,
3028                                        draw_special_char(DRAW_TREE_RIGHT));
3029                         }
3030
3031                         last = ! (*(dropin + 1) && startswith(*(dropin + 1), dir));
3032
3033                         printf("%s%s", basename(*dropin), last ? "\n" : ", ");
3034                 }
3035         }
3036
3037         ss = streq_ptr(i->active_state, i->sub_state) ? NULL : i->sub_state;
3038
3039         if (streq_ptr(i->active_state, "failed")) {
3040                 on = ansi_highlight_red();
3041                 off = ansi_highlight_off();
3042         } else if (streq_ptr(i->active_state, "active") || streq_ptr(i->active_state, "reloading")) {
3043                 on = ansi_highlight_green();
3044                 off = ansi_highlight_off();
3045         } else
3046                 on = off = "";
3047
3048         if (ss)
3049                 printf("   Active: %s%s (%s)%s",
3050                        on, strna(i->active_state), ss, off);
3051         else
3052                 printf("   Active: %s%s%s",
3053                        on, strna(i->active_state), off);
3054
3055         if (!isempty(i->result) && !streq(i->result, "success"))
3056                 printf(" (Result: %s)", i->result);
3057
3058         timestamp = (streq_ptr(i->active_state, "active")      ||
3059                      streq_ptr(i->active_state, "reloading"))   ? i->active_enter_timestamp :
3060                     (streq_ptr(i->active_state, "inactive")    ||
3061                      streq_ptr(i->active_state, "failed"))      ? i->inactive_enter_timestamp :
3062                     streq_ptr(i->active_state, "activating")    ? i->inactive_exit_timestamp :
3063                                                                   i->active_exit_timestamp;
3064
3065         s1 = format_timestamp_relative(since1, sizeof(since1), timestamp);
3066         s2 = format_timestamp(since2, sizeof(since2), timestamp);
3067
3068         if (s1)
3069                 printf(" since %s; %s\n", s2, s1);
3070         else if (s2)
3071                 printf(" since %s\n", s2);
3072         else
3073                 printf("\n");
3074
3075         if (!i->condition_result && i->condition_timestamp > 0) {
3076                 s1 = format_timestamp_relative(since1, sizeof(since1), i->condition_timestamp);
3077                 s2 = format_timestamp(since2, sizeof(since2), i->condition_timestamp);
3078
3079                 printf("           start condition failed at %s%s%s\n",
3080                        s2, s1 ? "; " : "", s1 ? s1 : "");
3081                 if (i->failed_condition_trigger)
3082                         printf("           none of the trigger conditions were met\n");
3083                 else if (i->failed_condition)
3084                         printf("           %s=%s%s was not met\n",
3085                                i->failed_condition,
3086                                i->failed_condition_negate ? "!" : "",
3087                                i->failed_condition_param);
3088         }
3089
3090         if (i->sysfs_path)
3091                 printf("   Device: %s\n", i->sysfs_path);
3092         if (i->where)
3093                 printf("    Where: %s\n", i->where);
3094         if (i->what)
3095                 printf("     What: %s\n", i->what);
3096
3097         STRV_FOREACH(t, i->documentation)
3098                 printf(" %*s %s\n", 9, t == i->documentation ? "Docs:" : "", *t);
3099
3100         STRV_FOREACH_PAIR(t, t2, i->listen)
3101                 printf(" %*s %s (%s)\n", 9, t == i->listen ? "Listen:" : "", *t2, *t);
3102
3103         if (i->accept)
3104                 printf(" Accepted: %u; Connected: %u\n", i->n_accepted, i->n_connections);
3105
3106         LIST_FOREACH(exec, p, i->exec) {
3107                 _cleanup_free_ char *argv = NULL;
3108                 bool good;
3109
3110                 /* Only show exited processes here */
3111                 if (p->code == 0)
3112                         continue;
3113
3114                 argv = strv_join(p->argv, " ");
3115                 printf("  Process: %u %s=%s ", p->pid, p->name, strna(argv));
3116
3117                 good = is_clean_exit_lsb(p->code, p->status, NULL);
3118                 if (!good) {
3119                         on = ansi_highlight_red();
3120                         off = ansi_highlight_off();
3121                 } else
3122                         on = off = "";
3123
3124                 printf("%s(code=%s, ", on, sigchld_code_to_string(p->code));
3125
3126                 if (p->code == CLD_EXITED) {
3127                         const char *c;
3128
3129                         printf("status=%i", p->status);
3130
3131                         c = exit_status_to_string(p->status, EXIT_STATUS_SYSTEMD);
3132                         if (c)
3133                                 printf("/%s", c);
3134
3135                 } else
3136                         printf("signal=%s", signal_to_string(p->status));
3137
3138                 printf(")%s\n", off);
3139
3140                 if (i->main_pid == p->pid &&
3141                     i->start_timestamp == p->start_timestamp &&
3142                     i->exit_timestamp == p->start_timestamp)
3143                         /* Let's not show this twice */
3144                         i->main_pid = 0;
3145
3146                 if (p->pid == i->control_pid)
3147                         i->control_pid = 0;
3148         }
3149
3150         if (i->main_pid > 0 || i->control_pid > 0) {
3151                 if (i->main_pid > 0) {
3152                         printf(" Main PID: %u", (unsigned) i->main_pid);
3153
3154                         if (i->running) {
3155                                 _cleanup_free_ char *comm = NULL;
3156                                 get_process_comm(i->main_pid, &comm);
3157                                 if (comm)
3158                                         printf(" (%s)", comm);
3159                         } else if (i->exit_code > 0) {
3160                                 printf(" (code=%s, ", sigchld_code_to_string(i->exit_code));
3161
3162                                 if (i->exit_code == CLD_EXITED) {
3163                                         const char *c;
3164
3165                                         printf("status=%i", i->exit_status);
3166
3167                                         c = exit_status_to_string(i->exit_status, EXIT_STATUS_SYSTEMD);
3168                                         if (c)
3169                                                 printf("/%s", c);
3170
3171                                 } else
3172                                         printf("signal=%s", signal_to_string(i->exit_status));
3173                                 printf(")");
3174                         }
3175
3176                         if (i->control_pid > 0)
3177                                 printf(";");
3178                 }
3179
3180                 if (i->control_pid > 0) {
3181                         _cleanup_free_ char *c = NULL;
3182
3183                         printf(" %8s: %u", i->main_pid ? "" : " Control", (unsigned) i->control_pid);
3184
3185                         get_process_comm(i->control_pid, &c);
3186                         if (c)
3187                                 printf(" (%s)", c);
3188                 }
3189
3190                 printf("\n");
3191         }
3192
3193         if (i->status_text)
3194                 printf("   Status: \"%s\"\n", i->status_text);
3195
3196         if (i->control_group &&
3197             (i->main_pid > 0 || i->control_pid > 0 || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, i->control_group, false) == 0)) {
3198                 unsigned c;
3199
3200                 printf("   CGroup: %s\n", i->control_group);
3201
3202                 if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_CONTAINER) {
3203                         unsigned k = 0;
3204                         pid_t extra[2];
3205                         char prefix[] = "           ";
3206
3207                         c = columns();
3208                         if (c > sizeof(prefix) - 1)
3209                                 c -= sizeof(prefix) - 1;
3210                         else
3211                                 c = 0;
3212
3213                         if (i->main_pid > 0)
3214                                 extra[k++] = i->main_pid;
3215
3216                         if (i->control_pid > 0)
3217                                 extra[k++] = i->control_pid;
3218
3219                         show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, i->control_group, prefix,
3220                                                       c, false, extra, k, flags);
3221                 }
3222         }
3223
3224         if (i->id && arg_transport == BUS_TRANSPORT_LOCAL) {
3225                 printf("\n");
3226                 show_journal_by_unit(stdout,
3227                                      i->id,
3228                                      arg_output,
3229                                      0,
3230                                      i->inactive_exit_timestamp_monotonic,
3231                                      arg_lines,
3232                                      getuid(),
3233                                      flags,
3234                                      arg_scope == UNIT_FILE_SYSTEM,
3235                                      ellipsized);
3236         }
3237
3238         if (i->need_daemon_reload)
3239                 printf("\n%sWarning:%s Unit file changed on disk, 'systemctl %sdaemon-reload' recommended.\n",
3240                        ansi_highlight_red(),
3241                        ansi_highlight_off(),
3242                        arg_scope == UNIT_FILE_SYSTEM ? "" : "--user ");
3243 }
3244
3245 static void show_unit_help(UnitStatusInfo *i) {
3246         char **p;
3247
3248         assert(i);
3249
3250         if (!i->documentation) {
3251                 log_info("Documentation for %s not known.", i->id);
3252                 return;
3253         }
3254
3255         STRV_FOREACH(p, i->documentation) {
3256
3257                 if (startswith(*p, "man:")) {
3258                         const char *args[4] = { "man", NULL, NULL, NULL };
3259                         _cleanup_free_ char *page = NULL, *section = NULL;
3260                         char *e = NULL;
3261                         pid_t pid;
3262                         size_t k;
3263
3264                         k = strlen(*p);
3265
3266                         if ((*p)[k-1] == ')')
3267                                 e = strrchr(*p, '(');
3268
3269                         if (e) {
3270                                 page = strndup((*p) + 4, e - *p - 4);
3271                                 section = strndup(e + 1, *p + k - e - 2);
3272                                 if (!page || !section) {
3273                                         log_oom();
3274                                         return;
3275                                 }
3276
3277                                 args[1] = section;
3278                                 args[2] = page;
3279                         } else
3280                                 args[1] = *p + 4;
3281
3282                         pid = fork();
3283                         if (pid < 0) {
3284                                 log_error("Failed to fork: %m");
3285                                 continue;
3286                         }
3287
3288                         if (pid == 0) {
3289                                 /* Child */
3290                                 execvp(args[0], (char**) args);
3291                                 log_error("Failed to execute man: %m");
3292                                 _exit(EXIT_FAILURE);
3293                         }
3294
3295                         wait_for_terminate(pid, NULL);
3296                 } else
3297                         log_info("Can't show: %s", *p);
3298         }
3299 }
3300
3301 static int status_property(const char *name, sd_bus_message *m, UnitStatusInfo *i, const char *contents) {
3302         int r;
3303
3304         assert(name);
3305         assert(m);
3306         assert(i);
3307
3308         switch (contents[0]) {
3309
3310         case SD_BUS_TYPE_STRING: {
3311                 const char *s;
3312
3313                 r = sd_bus_message_read(m, "s", &s);
3314                 if (r < 0)
3315                         return bus_log_parse_error(r);
3316
3317                 if (!isempty(s)) {
3318                         if (streq(name, "Id"))
3319                                 i->id = s;
3320                         else if (streq(name, "LoadState"))
3321                                 i->load_state = s;
3322                         else if (streq(name, "ActiveState"))
3323                                 i->active_state = s;
3324                         else if (streq(name, "SubState"))
3325                                 i->sub_state = s;
3326                         else if (streq(name, "Description"))
3327                                 i->description = s;
3328                         else if (streq(name, "FragmentPath"))
3329                                 i->fragment_path = s;
3330                         else if (streq(name, "SourcePath"))
3331                                 i->source_path = s;
3332 #ifndef NOLEGACY
3333                         else if (streq(name, "DefaultControlGroup")) {
3334                                 const char *e;
3335                                 e = startswith(s, SYSTEMD_CGROUP_CONTROLLER ":");
3336                                 if (e)
3337                                         i->control_group = e;
3338                         }
3339 #endif
3340                         else if (streq(name, "ControlGroup"))
3341                                 i->control_group = s;
3342                         else if (streq(name, "StatusText"))
3343                                 i->status_text = s;
3344                         else if (streq(name, "PIDFile"))
3345                                 i->pid_file = s;
3346                         else if (streq(name, "SysFSPath"))
3347                                 i->sysfs_path = s;
3348                         else if (streq(name, "Where"))
3349                                 i->where = s;
3350                         else if (streq(name, "What"))
3351                                 i->what = s;
3352                         else if (streq(name, "Following"))
3353                                 i->following = s;
3354                         else if (streq(name, "UnitFileState"))
3355                                 i->unit_file_state = s;
3356                         else if (streq(name, "Result"))
3357                                 i->result = s;
3358                 }
3359
3360                 break;
3361         }
3362
3363         case SD_BUS_TYPE_BOOLEAN: {
3364                 int b;
3365
3366                 r = sd_bus_message_read(m, "b", &b);
3367                 if (r < 0)
3368                         return bus_log_parse_error(r);
3369
3370                 if (streq(name, "Accept"))
3371                         i->accept = b;
3372                 else if (streq(name, "NeedDaemonReload"))
3373                         i->need_daemon_reload = b;
3374                 else if (streq(name, "ConditionResult"))
3375                         i->condition_result = b;
3376
3377                 break;
3378         }
3379
3380         case SD_BUS_TYPE_UINT32: {
3381                 uint32_t u;
3382
3383                 r = sd_bus_message_read(m, "u", &u);
3384                 if (r < 0)
3385                         return bus_log_parse_error(r);
3386
3387                 if (streq(name, "MainPID")) {
3388                         if (u > 0) {
3389                                 i->main_pid = (pid_t) u;
3390                                 i->running = true;
3391                         }
3392                 } else if (streq(name, "ControlPID"))
3393                         i->control_pid = (pid_t) u;
3394                 else if (streq(name, "ExecMainPID")) {
3395                         if (u > 0)
3396                                 i->main_pid = (pid_t) u;
3397                 } else if (streq(name, "NAccepted"))
3398                         i->n_accepted = u;
3399                 else if (streq(name, "NConnections"))
3400                         i->n_connections = u;
3401
3402                 break;
3403         }
3404
3405         case SD_BUS_TYPE_INT32: {
3406                 int32_t j;
3407
3408                 r = sd_bus_message_read(m, "i", &j);
3409                 if (r < 0)
3410                         return bus_log_parse_error(r);
3411
3412                 if (streq(name, "ExecMainCode"))
3413                         i->exit_code = (int) j;
3414                 else if (streq(name, "ExecMainStatus"))
3415                         i->exit_status = (int) j;
3416
3417                 break;
3418         }
3419
3420         case SD_BUS_TYPE_UINT64: {
3421                 uint64_t u;
3422
3423                 r = sd_bus_message_read(m, "t", &u);
3424                 if (r < 0)
3425                         return bus_log_parse_error(r);
3426
3427                 if (streq(name, "ExecMainStartTimestamp"))
3428                         i->start_timestamp = (usec_t) u;
3429                 else if (streq(name, "ExecMainExitTimestamp"))
3430                         i->exit_timestamp = (usec_t) u;
3431                 else if (streq(name, "ActiveEnterTimestamp"))
3432                         i->active_enter_timestamp = (usec_t) u;
3433                 else if (streq(name, "InactiveEnterTimestamp"))
3434                         i->inactive_enter_timestamp = (usec_t) u;
3435                 else if (streq(name, "InactiveExitTimestamp"))
3436                         i->inactive_exit_timestamp = (usec_t) u;
3437                 else if (streq(name, "InactiveExitTimestampMonotonic"))
3438                         i->inactive_exit_timestamp_monotonic = (usec_t) u;
3439                 else if (streq(name, "ActiveExitTimestamp"))
3440                         i->active_exit_timestamp = (usec_t) u;
3441                 else if (streq(name, "ConditionTimestamp"))
3442                         i->condition_timestamp = (usec_t) u;
3443
3444                 break;
3445         }
3446
3447         case SD_BUS_TYPE_ARRAY:
3448
3449                 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3450                         _cleanup_free_ ExecStatusInfo *info = NULL;
3451
3452                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3453                         if (r < 0)
3454                                 return bus_log_parse_error(r);
3455
3456                         info = new0(ExecStatusInfo, 1);
3457                         if (!info)
3458                                 return log_oom();
3459
3460                         while ((r = exec_status_info_deserialize(m, info)) > 0) {
3461
3462                                 info->name = strdup(name);
3463                                 if (!info->name)
3464                                         log_oom();
3465
3466                                 LIST_PREPEND(exec, i->exec, info);
3467
3468                                 info = new0(ExecStatusInfo, 1);
3469                                 if (!info)
3470                                         log_oom();
3471                         }
3472
3473                         if (r < 0)
3474                                 return bus_log_parse_error(r);
3475
3476                         r = sd_bus_message_exit_container(m);
3477                         if (r < 0)
3478                                 return bus_log_parse_error(r);
3479
3480                         return 0;
3481
3482                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3483                         const char *type, *path;
3484
3485                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3486                         if (r < 0)
3487                                 return bus_log_parse_error(r);
3488
3489                         while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0) {
3490
3491                                 r = strv_extend(&i->listen, type);
3492                                 if (r < 0)
3493                                         return r;
3494
3495                                 r = strv_extend(&i->listen, path);
3496                                 if (r < 0)
3497                                         return r;
3498                         }
3499                         if (r < 0)
3500                                 return bus_log_parse_error(r);
3501
3502                         r = sd_bus_message_exit_container(m);
3503                         if (r < 0)
3504                                 return bus_log_parse_error(r);
3505
3506                         return 0;
3507
3508                 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "DropInPaths")) {
3509
3510                         r = sd_bus_message_read_strv(m, &i->dropin_paths);
3511                         if (r < 0)
3512                                 return bus_log_parse_error(r);
3513
3514                 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Documentation")) {
3515
3516                         r = sd_bus_message_read_strv(m, &i->documentation);
3517                         if (r < 0)
3518                                 return bus_log_parse_error(r);
3519
3520                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Conditions")) {
3521                         const char *cond, *param;
3522                         int trigger, negate;
3523                         int32_t state;
3524
3525                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
3526                         if (r < 0)
3527                                 return bus_log_parse_error(r);
3528
3529                         while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, &param, &state)) > 0) {
3530                                 log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
3531                                 if (state < 0 && (!trigger || !i->failed_condition)) {
3532                                         i->failed_condition = cond;
3533                                         i->failed_condition_trigger = trigger;
3534                                         i->failed_condition_negate = negate;
3535                                         i->failed_condition_param = param;
3536                                 }
3537                         }
3538                         if (r < 0)
3539                                 return bus_log_parse_error(r);
3540
3541                         r = sd_bus_message_exit_container(m);
3542                         if (r < 0)
3543                                 return bus_log_parse_error(r);
3544
3545                 } else
3546                         goto skip;
3547
3548                 break;
3549
3550         case SD_BUS_TYPE_STRUCT_BEGIN:
3551
3552                 if (streq(name, "LoadError")) {
3553                         const char *n, *message;
3554
3555                         r = sd_bus_message_read(m, "(ss)", &n, &message);
3556                         if (r < 0)
3557                                 return bus_log_parse_error(r);
3558
3559                         if (!isempty(message))
3560                                 i->load_error = message;
3561                 } else
3562                         goto skip;
3563
3564                 break;
3565
3566         default:
3567                 goto skip;
3568         }
3569
3570         return 0;
3571
3572 skip:
3573         r = sd_bus_message_skip(m, contents);
3574         if (r < 0)
3575                 return bus_log_parse_error(r);
3576
3577         return 0;
3578 }
3579
3580 static int print_property(const char *name, sd_bus_message *m, const char *contents) {
3581         int r;
3582
3583         assert(name);
3584         assert(m);
3585
3586         /* This is a low-level property printer, see
3587          * print_status_info() for the nicer output */
3588
3589         if (arg_properties && !strv_find(arg_properties, name)) {
3590                 /* skip what we didn't read */
3591                 r = sd_bus_message_skip(m, contents);
3592                 return r;
3593         }
3594
3595         switch (contents[0]) {
3596
3597         case SD_BUS_TYPE_STRUCT_BEGIN:
3598
3599                 if (contents[1] == SD_BUS_TYPE_UINT32 && streq(name, "Job")) {
3600                         uint32_t u;
3601
3602                         r = sd_bus_message_read(m, "(uo)", &u, NULL);
3603 &nbs