chiark / gitweb /
9e4811505e2fe5fe6d4a1c25920bf183f1b6831b
[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         char *state;
1419         char *control_group;
1420         uint32_t n_failed_units;
1421         uint32_t n_jobs;
1422         usec_t timestamp;
1423 };
1424
1425 static const struct bus_properties_map machine_info_property_map[] = {
1426         { "SystemState",        "s", NULL, offsetof(struct machine_info, state)          },
1427         { "NJobs",              "u", NULL, offsetof(struct machine_info, n_jobs)         },
1428         { "NFailedUnits",       "u", NULL, offsetof(struct machine_info, n_failed_units) },
1429         { "ControlGroup",       "s", NULL, offsetof(struct machine_info, control_group)  },
1430         { "UserspaceTimestamp", "t", NULL, offsetof(struct machine_info, timestamp)      },
1431         {}
1432 };
1433
1434 static void free_machines_list(struct machine_info *machine_infos, int n) {
1435         int i;
1436
1437         if (!machine_infos)
1438                 return;
1439
1440         for (i = 0; i < n; i++) {
1441                 free(machine_infos[i].name);
1442                 free(machine_infos[i].state);
1443                 free(machine_infos[i].control_group);
1444         }
1445
1446         free(machine_infos);
1447 }
1448
1449 static int compare_machine_info(const void *a, const void *b) {
1450         const struct machine_info *u = a, *v = b;
1451
1452         if (u->is_host != v->is_host)
1453                 return u->is_host > v->is_host ? 1 : -1;
1454
1455         return strcasecmp(u->name, v->name);
1456 }
1457
1458 static int get_machine_properties(sd_bus *bus, struct machine_info *mi) {
1459         _cleanup_bus_unref_ sd_bus *container = NULL;
1460         int r;
1461
1462         assert(mi);
1463
1464         if (!bus) {
1465                 r = sd_bus_open_system_container(&container, mi->name);
1466                 if (r < 0)
1467                         return r;
1468
1469                 bus = container;
1470         }
1471
1472         r = bus_map_all_properties(bus, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map, mi);
1473         if (r < 0)
1474                 return r;
1475
1476         return 0;
1477 }
1478
1479 static bool output_show_machine(const char *name, char **patterns) {
1480         char **i;
1481
1482         assert(name);
1483
1484         if (strv_isempty(patterns))
1485                 return true;
1486
1487         STRV_FOREACH(i, patterns)
1488                 if (fnmatch(*i, name, FNM_NOESCAPE) == 0)
1489                         return true;
1490
1491         return false;
1492 }
1493
1494 static int get_machine_list(
1495                 sd_bus *bus,
1496                 struct machine_info **_machine_infos,
1497                 char **patterns) {
1498
1499         struct machine_info *machine_infos = NULL;
1500         _cleanup_strv_free_ char **m = NULL;
1501         _cleanup_free_ char *hn = NULL;
1502         size_t sz = 0;
1503         char **i;
1504         int c = 0;
1505
1506         hn = gethostname_malloc();
1507         if (!hn)
1508                 return log_oom();
1509
1510         if (output_show_machine(hn, patterns)) {
1511                 if (!GREEDY_REALLOC0(machine_infos, sz, c+1))
1512                         return log_oom();
1513
1514                 machine_infos[c].is_host = true;
1515                 machine_infos[c].name = hn;
1516                 hn = NULL;
1517
1518                 get_machine_properties(bus, &machine_infos[c]);
1519                 c++;
1520         }
1521
1522         sd_get_machine_names(&m);
1523         STRV_FOREACH(i, m) {
1524                 _cleanup_free_ char *class = NULL;
1525
1526                 if (!output_show_machine(*i, patterns))
1527                         continue;
1528
1529                 sd_machine_get_class(*i, &class);
1530                 if (!streq_ptr(class, "container"))
1531                         continue;
1532
1533                 if (!GREEDY_REALLOC0(machine_infos, sz, c+1)) {
1534                         free_machines_list(machine_infos, c);
1535                         return log_oom();
1536                 }
1537
1538                 machine_infos[c].is_host = false;
1539                 machine_infos[c].name = strdup(*i);
1540                 if (!machine_infos[c].name) {
1541                         free_machines_list(machine_infos, c);
1542                         return log_oom();
1543                 }
1544
1545                 get_machine_properties(NULL, &machine_infos[c]);
1546                 c++;
1547         }
1548
1549         *_machine_infos = machine_infos;
1550         return c;
1551 }
1552
1553 static void output_machines_list(struct machine_info *machine_infos, unsigned n) {
1554         struct machine_info *m;
1555         unsigned
1556                 namelen = sizeof("NAME") - 1,
1557                 statelen = sizeof("STATE") - 1,
1558                 failedlen = sizeof("FAILED") - 1,
1559                 jobslen = sizeof("JOBS") - 1;
1560
1561         assert(machine_infos || n == 0);
1562
1563         for (m = machine_infos; m < machine_infos + n; m++) {
1564                 namelen = MAX(namelen, strlen(m->name) + (m->is_host ? sizeof(" (host)") - 1 : 0));
1565                 statelen = MAX(statelen, m->state ? strlen(m->state) : 0);
1566                 failedlen = MAX(failedlen, DECIMAL_STR_WIDTH(m->n_failed_units));
1567                 jobslen = MAX(jobslen, DECIMAL_STR_WIDTH(m->n_jobs));
1568         }
1569
1570         if (!arg_no_legend)
1571                 printf("%-*s %-*s %-*s %-*s\n",
1572                          namelen, "NAME",
1573                         statelen, "STATE",
1574                        failedlen, "FAILED",
1575                          jobslen, "JOBS");
1576
1577         for (m = machine_infos; m < machine_infos + n; m++) {
1578                 const char *on_state, *off_state, *on_failed, *off_failed;
1579
1580                 if (streq_ptr(m->state, "degraded")) {
1581                         on_state = ansi_highlight_red();
1582                         off_state = ansi_highlight_off();
1583                 } else if (!streq_ptr(m->state, "running")) {
1584                         on_state = ansi_highlight_yellow();
1585                         off_state = ansi_highlight_off();
1586                 } else
1587                         on_state = off_state = "";
1588
1589                 if (m->n_failed_units > 0) {
1590                         on_failed = ansi_highlight_red();
1591                         off_failed = ansi_highlight_off();
1592                 } else
1593                         on_failed = off_failed = "";
1594
1595                 if (m->is_host)
1596                         printf("%-*s (host) %s%-*s%s %s%*u%s %*u\n",
1597                                (int) (namelen - (sizeof(" (host)")-1)), strna(m->name),
1598                                on_state, statelen, strna(m->state), off_state,
1599                                on_failed, failedlen, m->n_failed_units, off_failed,
1600                                jobslen, m->n_jobs);
1601                 else
1602                         printf("%-*s %s%-*s%s %s%*u%s %*u\n",
1603                                namelen, strna(m->name),
1604                                on_state, statelen, strna(m->state), off_state,
1605                                on_failed, failedlen, m->n_failed_units, off_failed,
1606                                jobslen, m->n_jobs);
1607         }
1608
1609         if (!arg_no_legend)
1610                 printf("\n%u machines listed.\n", n);
1611 }
1612
1613 static int list_machines(sd_bus *bus, char **args) {
1614         struct machine_info *machine_infos = NULL;
1615         int r;
1616
1617         assert(bus);
1618
1619         if (geteuid() != 0) {
1620                 log_error("Must be root.");
1621                 return -EPERM;
1622         }
1623
1624         pager_open_if_enabled();
1625
1626         r = get_machine_list(bus, &machine_infos, strv_skip_first(args));
1627         if (r < 0)
1628                 return r;
1629
1630         qsort_safe(machine_infos, r, sizeof(struct machine_info), compare_machine_info);
1631         output_machines_list(machine_infos, r);
1632         free_machines_list(machine_infos, r);
1633
1634         return 0;
1635 }
1636
1637 static int get_default(sd_bus *bus, char **args) {
1638         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1639         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1640         _cleanup_free_ char *_path = NULL;
1641         const char *path;
1642         int r;
1643
1644         if (!bus || avoid_bus()) {
1645                 r = unit_file_get_default(arg_scope, arg_root, &_path);
1646                 if (r < 0) {
1647                         log_error("Failed to get default target: %s", strerror(-r));
1648                         return r;
1649                 }
1650                 path = _path;
1651
1652         } else {
1653                 r = sd_bus_call_method(
1654                                 bus,
1655                                 "org.freedesktop.systemd1",
1656                                 "/org/freedesktop/systemd1",
1657                                 "org.freedesktop.systemd1.Manager",
1658                                 "GetDefaultTarget",
1659                                 &error,
1660                                 &reply,
1661                                 NULL);
1662                 if (r < 0) {
1663                         log_error("Failed to get default target: %s", bus_error_message(&error, -r));
1664                         return r;
1665                 }
1666
1667                 r = sd_bus_message_read(reply, "s", &path);
1668                 if (r < 0)
1669                         return bus_log_parse_error(r);
1670         }
1671
1672         if (path)
1673                 printf("%s\n", path);
1674
1675         return 0;
1676 }
1677
1678 static void dump_unit_file_changes(const UnitFileChange *changes, unsigned n_changes) {
1679         unsigned i;
1680
1681         assert(changes || n_changes == 0);
1682
1683         for (i = 0; i < n_changes; i++) {
1684                 if (changes[i].type == UNIT_FILE_SYMLINK)
1685                         log_info("ln -s '%s' '%s'", changes[i].source, changes[i].path);
1686                 else
1687                         log_info("rm '%s'", changes[i].path);
1688         }
1689 }
1690
1691 static int deserialize_and_dump_unit_file_changes(sd_bus_message *m) {
1692         const char *type, *path, *source;
1693         int r;
1694
1695         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sss)");
1696         if (r < 0)
1697                 return bus_log_parse_error(r);
1698
1699         while ((r = sd_bus_message_read(m, "(sss)", &type, &path, &source)) > 0) {
1700                 if (!arg_quiet) {
1701                         if (streq(type, "symlink"))
1702                                 log_info("ln -s '%s' '%s'", source, path);
1703                         else
1704                                 log_info("rm '%s'", path);
1705                 }
1706         }
1707         if (r < 0)
1708                 return bus_log_parse_error(r);
1709
1710         r = sd_bus_message_exit_container(m);
1711         if (r < 0)
1712                 return bus_log_parse_error(r);
1713
1714         return 0;
1715 }
1716
1717 static int set_default(sd_bus *bus, char **args) {
1718         _cleanup_free_ char *unit = NULL;
1719         UnitFileChange *changes = NULL;
1720         unsigned n_changes = 0;
1721         int r;
1722
1723         unit = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".target");
1724         if (!unit)
1725                 return log_oom();
1726
1727         if (!bus || avoid_bus()) {
1728                 r = unit_file_set_default(arg_scope, arg_root, unit, arg_force, &changes, &n_changes);
1729                 if (r < 0) {
1730                         log_error("Failed to set default target: %s", strerror(-r));
1731                         return r;
1732                 }
1733
1734                 if (!arg_quiet)
1735                         dump_unit_file_changes(changes, n_changes);
1736
1737                 r = 0;
1738         } else {
1739                 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1740                 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1741
1742                 r = sd_bus_call_method(
1743                                 bus,
1744                                 "org.freedesktop.systemd1",
1745                                 "/org/freedesktop/systemd1",
1746                                 "org.freedesktop.systemd1.Manager",
1747                                 "SetDefaultTarget",
1748                                 &error,
1749                                 &reply,
1750                                 "sb", unit, arg_force);
1751                 if (r < 0) {
1752                         log_error("Failed to set default target: %s", bus_error_message(&error, -r));
1753                         return r;
1754                 }
1755
1756                 r = deserialize_and_dump_unit_file_changes(reply);
1757                 if (r < 0)
1758                         return r;
1759
1760                 /* Try to reload if enabeld */
1761                 if (!arg_no_reload)
1762                         r = daemon_reload(bus, args);
1763                 else
1764                         r = 0;
1765         }
1766
1767         unit_file_changes_free(changes, n_changes);
1768
1769         return r;
1770 }
1771
1772 struct job_info {
1773         uint32_t id;
1774         const char *name, *type, *state;
1775 };
1776
1777 static void output_jobs_list(const struct job_info* jobs, unsigned n, bool skipped) {
1778         unsigned id_len, unit_len, type_len, state_len;
1779         const struct job_info *j;
1780         const char *on, *off;
1781         bool shorten = false;
1782
1783         assert(n == 0 || jobs);
1784
1785         if (n == 0) {
1786                 on = ansi_highlight_green();
1787                 off = ansi_highlight_off();
1788
1789                 printf("%sNo jobs %s.%s\n", on, skipped ? "listed" : "running", off);
1790                 return;
1791         }
1792
1793         pager_open_if_enabled();
1794
1795         id_len = sizeof("JOB")-1;
1796         unit_len = sizeof("UNIT")-1;
1797         type_len = sizeof("TYPE")-1;
1798         state_len = sizeof("STATE")-1;
1799
1800         for (j = jobs; j < jobs + n; j++) {
1801                 uint32_t id = j->id;
1802                 assert(j->name && j->type && j->state);
1803
1804                 id_len = MAX(id_len, DECIMAL_STR_WIDTH(id));
1805                 unit_len = MAX(unit_len, strlen(j->name));
1806                 type_len = MAX(type_len, strlen(j->type));
1807                 state_len = MAX(state_len, strlen(j->state));
1808         }
1809
1810         if (!arg_full && id_len + 1 + unit_len + type_len + 1 + state_len > columns()) {
1811                 unit_len = MAX(33u, columns() - id_len - type_len - state_len - 3);
1812                 shorten = true;
1813         }
1814
1815         if (!arg_no_legend)
1816                 printf("%*s %-*s %-*s %-*s\n",
1817                        id_len, "JOB",
1818                        unit_len, "UNIT",
1819                        type_len, "TYPE",
1820                        state_len, "STATE");
1821
1822         for (j = jobs; j < jobs + n; j++) {
1823                 _cleanup_free_ char *e = NULL;
1824
1825                 if (streq(j->state, "running")) {
1826                         on = ansi_highlight();
1827                         off = ansi_highlight_off();
1828                 } else
1829                         on = off = "";
1830
1831                 e = shorten ? ellipsize(j->name, unit_len, 33) : NULL;
1832                 printf("%*u %s%-*s%s %-*s %s%-*s%s\n",
1833                        id_len, j->id,
1834                        on, unit_len, e ? e : j->name, off,
1835                        type_len, j->type,
1836                        on, state_len, j->state, off);
1837         }
1838
1839         if (!arg_no_legend) {
1840                 on = ansi_highlight();
1841                 off = ansi_highlight_off();
1842
1843                 printf("\n%s%u jobs listed%s.\n", on, n, off);
1844         }
1845 }
1846
1847 static bool output_show_job(struct job_info *job, char **patterns) {
1848         char **pattern;
1849
1850         assert(job);
1851
1852         if (strv_isempty(patterns))
1853                 return true;
1854
1855         STRV_FOREACH(pattern, patterns)
1856                 if (fnmatch(*pattern, job->name, FNM_NOESCAPE) == 0)
1857                         return true;
1858         return false;
1859 }
1860
1861 static int list_jobs(sd_bus *bus, char **args) {
1862         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1863         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1864         const char *name, *type, *state, *job_path, *unit_path;
1865         _cleanup_free_ struct job_info *jobs = NULL;
1866         size_t size = 0;
1867         unsigned c = 0;
1868         uint32_t id;
1869         int r;
1870         bool skipped = false;
1871
1872         r = sd_bus_call_method(
1873                         bus,
1874                         "org.freedesktop.systemd1",
1875                         "/org/freedesktop/systemd1",
1876                         "org.freedesktop.systemd1.Manager",
1877                         "ListJobs",
1878                         &error,
1879                         &reply,
1880                         NULL);
1881         if (r < 0) {
1882                 log_error("Failed to list jobs: %s", bus_error_message(&error, r));
1883                 return r;
1884         }
1885
1886         r = sd_bus_message_enter_container(reply, 'a', "(usssoo)");
1887         if (r < 0)
1888                 return bus_log_parse_error(r);
1889
1890         while ((r = sd_bus_message_read(reply, "(usssoo)", &id, &name, &type, &state, &job_path, &unit_path)) > 0) {
1891                 struct job_info job = { id, name, type, state };
1892
1893                 if (!output_show_job(&job, strv_skip_first(args))) {
1894                         skipped = true;
1895                         continue;
1896                 }
1897
1898                 if (!GREEDY_REALLOC(jobs, size, c + 1))
1899                         return log_oom();
1900
1901                 jobs[c++] = job;
1902         }
1903         if (r < 0)
1904                 return bus_log_parse_error(r);
1905
1906         r = sd_bus_message_exit_container(reply);
1907         if (r < 0)
1908                 return bus_log_parse_error(r);
1909
1910         output_jobs_list(jobs, c, skipped);
1911         return r;
1912 }
1913
1914 static int cancel_job(sd_bus *bus, char **args) {
1915         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1916         char **name;
1917
1918         assert(args);
1919
1920         if (strv_length(args) <= 1)
1921                 return daemon_reload(bus, args);
1922
1923         STRV_FOREACH(name, args+1) {
1924                 uint32_t id;
1925                 int r;
1926
1927                 r = safe_atou32(*name, &id);
1928                 if (r < 0) {
1929                         log_error("Failed to parse job id \"%s\": %s", *name, strerror(-r));
1930                         return r;
1931                 }
1932
1933                 r = sd_bus_call_method(
1934                                 bus,
1935                                 "org.freedesktop.systemd1",
1936                                 "/org/freedesktop/systemd1",
1937                                 "org.freedesktop.systemd1.Manager",
1938                                 "CancelJob",
1939                                 &error,
1940                                 NULL,
1941                                 "u", id);
1942                 if (r < 0) {
1943                         log_error("Failed to cancel job %u: %s", (unsigned) id, bus_error_message(&error, r));
1944                         return r;
1945                 }
1946         }
1947
1948         return 0;
1949 }
1950
1951 static int need_daemon_reload(sd_bus *bus, const char *unit) {
1952         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1953         const char *path;
1954         int b, r;
1955
1956         /* We ignore all errors here, since this is used to show a
1957          * warning only */
1958
1959         /* We don't use unit_dbus_path_from_name() directly since we
1960          * don't want to load the unit if it isn't loaded. */
1961
1962         r = sd_bus_call_method(
1963                         bus,
1964                         "org.freedesktop.systemd1",
1965                         "/org/freedesktop/systemd1",
1966                         "org.freedesktop.systemd1.Manager",
1967                         "GetUnit",
1968                         NULL,
1969                         &reply,
1970                         "s", unit);
1971         if (r < 0)
1972                 return r;
1973
1974         r = sd_bus_message_read(reply, "o", &path);
1975         if (r < 0)
1976                 return r;
1977
1978         r = sd_bus_get_property_trivial(
1979                         bus,
1980                         "org.freedesktop.systemd1",
1981                         path,
1982                         "org.freedesktop.systemd1.Unit",
1983                         "NeedDaemonReload",
1984                         NULL,
1985                         'b', &b);
1986         if (r < 0)
1987                 return r;
1988
1989         return b;
1990 }
1991
1992 typedef struct WaitData {
1993         Set *set;
1994
1995         char *name;
1996         char *result;
1997 } WaitData;
1998
1999 static int wait_filter(sd_bus *bus, sd_bus_message *m, void *data, sd_bus_error *error) {
2000         WaitData *d = data;
2001
2002         assert(bus);
2003         assert(m);
2004         assert(d);
2005
2006         log_debug("Got D-Bus request: %s.%s() on %s",
2007                   sd_bus_message_get_interface(m),
2008                   sd_bus_message_get_member(m),
2009                   sd_bus_message_get_path(m));
2010
2011         if (sd_bus_message_is_signal(m, "org.freedesktop.DBus.Local", "Disconnected")) {
2012                 log_error("Warning! D-Bus connection terminated.");
2013                 sd_bus_close(bus);
2014         } else if (sd_bus_message_is_signal(m, "org.freedesktop.systemd1.Manager", "JobRemoved")) {
2015                 uint32_t id;
2016                 const char *path, *result, *unit;
2017                 char *ret;
2018                 int r;
2019
2020                 r = sd_bus_message_read(m, "uoss", &id, &path, &unit, &result);
2021                 if (r >= 0) {
2022                         ret = set_remove(d->set, (char*) path);
2023                         if (!ret)
2024                                 return 0;
2025
2026                         free(ret);
2027
2028                         if (!isempty(result))
2029                                 d->result = strdup(result);
2030
2031                         if (!isempty(unit))
2032                                 d->name = strdup(unit);
2033
2034                         return 0;
2035                 }
2036 #ifndef NOLEGACY
2037                 r = sd_bus_message_read(m, "uos", &id, &path, &result);
2038                 if (r >= 0) {
2039                         ret = set_remove(d->set, (char*) path);
2040                         if (!ret)
2041                                 return 0;
2042
2043                         free(ret);
2044
2045                         if (*result)
2046                                 d->result = strdup(result);
2047
2048                         return 0;
2049                 }
2050 #endif
2051
2052                 bus_log_parse_error(r);
2053         }
2054
2055         return 0;
2056 }
2057
2058 static int enable_wait_for_jobs(sd_bus *bus) {
2059         int r;
2060
2061         assert(bus);
2062
2063         r = sd_bus_add_match(
2064                         bus,
2065                         "type='signal',"
2066                         "sender='org.freedesktop.systemd1',"
2067                         "interface='org.freedesktop.systemd1.Manager',"
2068                         "member='JobRemoved',"
2069                         "path='/org/freedesktop/systemd1'",
2070                         NULL, NULL);
2071         if (r < 0) {
2072                 log_error("Failed to add match");
2073                 return -EIO;
2074         }
2075
2076         /* This is slightly dirty, since we don't undo the match registrations. */
2077         return 0;
2078 }
2079
2080 static int bus_process_wait(sd_bus *bus) {
2081         int r;
2082
2083         for (;;) {
2084                 r = sd_bus_process(bus, NULL);
2085                 if (r < 0)
2086                         return r;
2087                 if (r > 0)
2088                         return 0;
2089                 r = sd_bus_wait(bus, (uint64_t) -1);
2090                 if (r < 0)
2091                         return r;
2092         }
2093 }
2094
2095 static int check_wait_response(WaitData *d) {
2096         int r = 0;
2097
2098         assert(d->result);
2099
2100         if (!arg_quiet) {
2101                 if (streq(d->result, "timeout"))
2102                         log_error("Job for %s timed out.", strna(d->name));
2103                 else if (streq(d->result, "canceled"))
2104                         log_error("Job for %s canceled.", strna(d->name));
2105                 else if (streq(d->result, "dependency"))
2106                         log_error("A dependency job for %s failed. See 'journalctl -xn' for details.", strna(d->name));
2107                 else if (!streq(d->result, "done") && !streq(d->result, "skipped"))
2108                         log_error("Job for %s failed. See 'systemctl status %s' and 'journalctl -xn' for details.", strna(d->name), strna(d->name));
2109         }
2110
2111         if (streq(d->result, "timeout"))
2112                 r = -ETIME;
2113         else if (streq(d->result, "canceled"))
2114                 r = -ECANCELED;
2115         else if (streq(d->result, "dependency"))
2116                 r = -EIO;
2117         else if (!streq(d->result, "done") && !streq(d->result, "skipped"))
2118                 r = -EIO;
2119
2120         return r;
2121 }
2122
2123 static int wait_for_jobs(sd_bus *bus, Set *s) {
2124         WaitData d = { .set = s };
2125         int r = 0, q;
2126
2127         assert(bus);
2128         assert(s);
2129
2130         q = sd_bus_add_filter(bus, wait_filter, &d);
2131         if (q < 0)
2132                 return log_oom();
2133
2134         while (!set_isempty(s)) {
2135                 q = bus_process_wait(bus);
2136                 if (q < 0) {
2137                         log_error("Failed to wait for response: %s", strerror(-r));
2138                         return q;
2139                 }
2140
2141                 if (d.result) {
2142                         q = check_wait_response(&d);
2143                         /* Return the first error as it is most likely to be
2144                          * meaningful. */
2145                         if (q < 0 && r == 0)
2146                                 r = q;
2147                         log_debug("Got result %s/%s for job %s",
2148                                   strna(d.result), strerror(-q), strna(d.name));
2149                 }
2150
2151                 free(d.name);
2152                 d.name = NULL;
2153
2154                 free(d.result);
2155                 d.result = NULL;
2156         }
2157
2158         q = sd_bus_remove_filter(bus, wait_filter, &d);
2159         if (q < 0 && r == 0)
2160                 r = q;
2161
2162         return r;
2163 }
2164
2165 static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet) {
2166         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2167         _cleanup_free_ char *n = NULL, *state = NULL;
2168         const char *path;
2169         int r;
2170
2171         assert(name);
2172
2173         n = unit_name_mangle(name, MANGLE_NOGLOB);
2174         if (!n)
2175                 return log_oom();
2176
2177         /* We don't use unit_dbus_path_from_name() directly since we
2178          * don't want to load the unit if it isn't loaded. */
2179
2180         r = sd_bus_call_method(
2181                         bus,
2182                         "org.freedesktop.systemd1",
2183                         "/org/freedesktop/systemd1",
2184                         "org.freedesktop.systemd1.Manager",
2185                         "GetUnit",
2186                         NULL,
2187                         &reply,
2188                         "s", n);
2189         if (r < 0) {
2190                 if (!quiet)
2191                         puts("unknown");
2192                 return 0;
2193         }
2194
2195         r = sd_bus_message_read(reply, "o", &path);
2196         if (r < 0)
2197                 return bus_log_parse_error(r);
2198
2199         r = sd_bus_get_property_string(
2200                         bus,
2201                         "org.freedesktop.systemd1",
2202                         path,
2203                         "org.freedesktop.systemd1.Unit",
2204                         "ActiveState",
2205                         NULL,
2206                         &state);
2207         if (r < 0) {
2208                 if (!quiet)
2209                         puts("unknown");
2210                 return 0;
2211         }
2212
2213         if (!quiet)
2214                 puts(state);
2215
2216         return nulstr_contains(good_states, state);
2217 }
2218
2219 static int check_triggering_units(
2220                 sd_bus *bus,
2221                 const char *name) {
2222
2223         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2224         _cleanup_free_ char *path = NULL, *n = NULL, *state = NULL;
2225         _cleanup_strv_free_ char **triggered_by = NULL;
2226         bool print_warning_label = true;
2227         char **i;
2228         int r;
2229
2230         n = unit_name_mangle(name, MANGLE_NOGLOB);
2231         if (!n)
2232                 return log_oom();
2233
2234         path = unit_dbus_path_from_name(n);
2235         if (!path)
2236                 return log_oom();
2237
2238         r = sd_bus_get_property_string(
2239                         bus,
2240                         "org.freedesktop.systemd1",
2241                         path,
2242                         "org.freedesktop.systemd1.Unit",
2243                         "LoadState",
2244                         &error,
2245                         &state);
2246         if (r < 0) {
2247                 log_error("Failed to get load state of %s: %s", n, bus_error_message(&error, r));
2248                 return r;
2249         }
2250
2251         if (streq(state, "masked"))
2252                 return 0;
2253
2254         r = sd_bus_get_property_strv(
2255                         bus,
2256                         "org.freedesktop.systemd1",
2257                         path,
2258                         "org.freedesktop.systemd1.Unit",
2259                         "TriggeredBy",
2260                         &error,
2261                         &triggered_by);
2262         if (r < 0) {
2263                 log_error("Failed to get triggered by array of %s: %s", n, bus_error_message(&error, r));
2264                 return r;
2265         }
2266
2267         STRV_FOREACH(i, triggered_by) {
2268                 r = check_one_unit(bus, *i, "active\0reloading\0", true);
2269                 if (r < 0) {
2270                         log_error("Failed to check unit: %s", strerror(-r));
2271                         return r;
2272                 }
2273
2274                 if (r == 0)
2275                         continue;
2276
2277                 if (print_warning_label) {
2278                         log_warning("Warning: Stopping %s, but it can still be activated by:", n);
2279                         print_warning_label = false;
2280                 }
2281
2282                 log_warning("  %s", *i);
2283         }
2284
2285         return 0;
2286 }
2287
2288 static const char *verb_to_method(const char *verb) {
2289        uint i;
2290
2291        for (i = 0; i < ELEMENTSOF(unit_actions); i++)
2292                 if (streq_ptr(unit_actions[i].verb, verb))
2293                         return unit_actions[i].method;
2294
2295        return "StartUnit";
2296 }
2297
2298 static const char *method_to_verb(const char *method) {
2299        uint i;
2300
2301        for (i = 0; i < ELEMENTSOF(unit_actions); i++)
2302                 if (streq_ptr(unit_actions[i].method, method))
2303                         return unit_actions[i].verb;
2304
2305        return "n/a";
2306 }
2307
2308 static int start_unit_one(
2309                 sd_bus *bus,
2310                 const char *method,
2311                 const char *name,
2312                 const char *mode,
2313                 sd_bus_error *error,
2314                 Set *s) {
2315
2316         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2317         const char *path;
2318         int r;
2319
2320         assert(method);
2321         assert(name);
2322         assert(mode);
2323         assert(error);
2324
2325         log_debug("Calling manager for %s on %s, %s", method, name, mode);
2326         r = sd_bus_call_method(
2327                         bus,
2328                         "org.freedesktop.systemd1",
2329                         "/org/freedesktop/systemd1",
2330                         "org.freedesktop.systemd1.Manager",
2331                         method,
2332                         error,
2333                         &reply,
2334                         "ss", name, mode);
2335         if (r < 0) {
2336                 const char *verb;
2337
2338                 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
2339                         /* There's always a fallback possible for
2340                          * legacy actions. */
2341                         return -EADDRNOTAVAIL;
2342
2343                 verb = method_to_verb(method);
2344
2345                 log_error("Failed to %s %s: %s", verb, name, bus_error_message(error, r));
2346                 return r;
2347         }
2348
2349         r = sd_bus_message_read(reply, "o", &path);
2350         if (r < 0)
2351                 return bus_log_parse_error(r);
2352
2353         if (need_daemon_reload(bus, name) > 0)
2354                 log_warning("Warning: Unit file of %s changed on disk, 'systemctl%s daemon-reload' recommended.",
2355                             name, arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
2356
2357         if (s) {
2358                 char *p;
2359
2360                 p = strdup(path);
2361                 if (!p)
2362                         return log_oom();
2363
2364                 log_debug("Adding %s to the set", p);
2365                 r = set_consume(s, p);
2366                 if (r < 0)
2367                         return log_oom();
2368         }
2369
2370         return 0;
2371 }
2372
2373 static int expand_names(sd_bus *bus, char **names, const char* suffix, char ***ret) {
2374
2375         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2376         _cleanup_strv_free_ char **mangled = NULL, **globs = NULL;
2377         char **name;
2378         int r = 0, i;
2379
2380         STRV_FOREACH(name, names) {
2381                 char *t;
2382
2383                 if (suffix)
2384                         t = unit_name_mangle_with_suffix(*name, MANGLE_GLOB, suffix);
2385                 else
2386                         t = unit_name_mangle(*name, MANGLE_GLOB);
2387                 if (!t)
2388                         return log_oom();
2389
2390                 if (string_is_glob(t))
2391                         r = strv_consume(&globs, t);
2392                 else
2393                         r = strv_consume(&mangled, t);
2394                 if (r < 0)
2395                         return log_oom();
2396         }
2397
2398         /* Query the manager only if any of the names are a glob, since
2399          * this is fairly expensive */
2400         if (!strv_isempty(globs)) {
2401                 _cleanup_free_ UnitInfo *unit_infos = NULL;
2402
2403                 r = get_unit_list(bus, &reply, &unit_infos, globs);
2404                 if (r < 0)
2405                         return r;
2406
2407                 for (i = 0; i < r; i++)
2408                         if (strv_extend(&mangled, unit_infos[i].id) < 0)
2409                                 return log_oom();
2410         }
2411
2412         *ret = mangled;
2413         mangled = NULL; /* do not free */
2414         return 0;
2415 }
2416
2417 static const struct {
2418         const char *target;
2419         const char *verb;
2420         const char *mode;
2421 } action_table[_ACTION_MAX] = {
2422         [ACTION_HALT]         = { SPECIAL_HALT_TARGET,         "halt",         "replace-irreversibly" },
2423         [ACTION_POWEROFF]     = { SPECIAL_POWEROFF_TARGET,     "poweroff",     "replace-irreversibly" },
2424         [ACTION_REBOOT]       = { SPECIAL_REBOOT_TARGET,       "reboot",       "replace-irreversibly" },
2425         [ACTION_KEXEC]        = { SPECIAL_KEXEC_TARGET,        "kexec",        "replace-irreversibly" },
2426         [ACTION_RUNLEVEL2]    = { SPECIAL_RUNLEVEL2_TARGET,    NULL,           "isolate" },
2427         [ACTION_RUNLEVEL3]    = { SPECIAL_RUNLEVEL3_TARGET,    NULL,           "isolate" },
2428         [ACTION_RUNLEVEL4]    = { SPECIAL_RUNLEVEL4_TARGET,    NULL,           "isolate" },
2429         [ACTION_RUNLEVEL5]    = { SPECIAL_RUNLEVEL5_TARGET,    NULL,           "isolate" },
2430         [ACTION_RESCUE]       = { SPECIAL_RESCUE_TARGET,       "rescue",       "isolate" },
2431         [ACTION_EMERGENCY]    = { SPECIAL_EMERGENCY_TARGET,    "emergency",    "isolate" },
2432         [ACTION_DEFAULT]      = { SPECIAL_DEFAULT_TARGET,      "default",      "isolate" },
2433         [ACTION_EXIT]         = { SPECIAL_EXIT_TARGET,         "exit",         "replace-irreversibly" },
2434         [ACTION_SUSPEND]      = { SPECIAL_SUSPEND_TARGET,      "suspend",      "replace-irreversibly" },
2435         [ACTION_HIBERNATE]    = { SPECIAL_HIBERNATE_TARGET,    "hibernate",    "replace-irreversibly" },
2436         [ACTION_HYBRID_SLEEP] = { SPECIAL_HYBRID_SLEEP_TARGET, "hybrid-sleep", "replace-irreversibly" },
2437 };
2438
2439 static enum action verb_to_action(const char *verb) {
2440         enum action i;
2441
2442         for (i = _ACTION_INVALID; i < _ACTION_MAX; i++)
2443                 if (streq_ptr(action_table[i].verb, verb))
2444                         return i;
2445
2446         return _ACTION_INVALID;
2447 }
2448
2449 static int start_unit(sd_bus *bus, char **args) {
2450         _cleanup_set_free_free_ Set *s = NULL;
2451         _cleanup_strv_free_ char **names = NULL;
2452         const char *method, *mode, *one_name;
2453         char **name;
2454         int r = 0;
2455
2456         assert(bus);
2457
2458         ask_password_agent_open_if_enabled();
2459
2460         if (arg_action == ACTION_SYSTEMCTL) {
2461                 enum action action;
2462                 method = verb_to_method(args[0]);
2463                 action = verb_to_action(args[0]);
2464
2465                 mode = streq(args[0], "isolate") ? "isolate" :
2466                        action_table[action].mode ?: arg_job_mode;
2467
2468                 one_name = action_table[action].target;
2469         } else {
2470                 assert(arg_action < ELEMENTSOF(action_table));
2471                 assert(action_table[arg_action].target);
2472
2473                 method = "StartUnit";
2474
2475                 mode = action_table[arg_action].mode;
2476                 one_name = action_table[arg_action].target;
2477         }
2478
2479         if (one_name)
2480                 names = strv_new(one_name, NULL);
2481         else {
2482                 r = expand_names(bus, args + 1, NULL, &names);
2483                 if (r < 0)
2484                         log_error("Failed to expand names: %s", strerror(-r));
2485         }
2486
2487         if (!arg_no_block) {
2488                 r = enable_wait_for_jobs(bus);
2489                 if (r < 0) {
2490                         log_error("Could not watch jobs: %s", strerror(-r));
2491                         return r;
2492                 }
2493
2494                 s = set_new(string_hash_func, string_compare_func);
2495                 if (!s)
2496                         return log_oom();
2497         }
2498
2499         STRV_FOREACH(name, names) {
2500                 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2501                 int q;
2502
2503                 q = start_unit_one(bus, method, *name, mode, &error, s);
2504                 if (r >= 0 && q < 0)
2505                         r = translate_bus_error_to_exit_status(q, &error);
2506         }
2507
2508         if (!arg_no_block) {
2509                 int q;
2510
2511                 q = wait_for_jobs(bus, s);
2512                 if (q < 0)
2513                         return q;
2514
2515                 /* When stopping units, warn if they can still be triggered by
2516                  * another active unit (socket, path, timer) */
2517                 if (!arg_quiet && streq(method, "StopUnit"))
2518                         STRV_FOREACH(name, names)
2519                                 check_triggering_units(bus, *name);
2520         }
2521
2522         return r;
2523 }
2524
2525 /* Ask systemd-logind, which might grant access to unprivileged users
2526  * through PolicyKit */
2527 static int reboot_with_logind(sd_bus *bus, enum action a) {
2528 #ifdef HAVE_LOGIND
2529         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2530         const char *method;
2531         int r;
2532
2533         if (!bus)
2534                 return -EIO;
2535
2536         polkit_agent_open_if_enabled();
2537
2538         switch (a) {
2539
2540         case ACTION_REBOOT:
2541                 method = "Reboot";
2542                 break;
2543
2544         case ACTION_POWEROFF:
2545                 method = "PowerOff";
2546                 break;
2547
2548         case ACTION_SUSPEND:
2549                 method = "Suspend";
2550                 break;
2551
2552         case ACTION_HIBERNATE:
2553                 method = "Hibernate";
2554                 break;
2555
2556         case ACTION_HYBRID_SLEEP:
2557                 method = "HybridSleep";
2558                 break;
2559
2560         default:
2561                 return -EINVAL;
2562         }
2563
2564         r = sd_bus_call_method(
2565                         bus,
2566                         "org.freedesktop.login1",
2567                         "/org/freedesktop/login1",
2568                         "org.freedesktop.login1.Manager",
2569                         method,
2570                         &error,
2571                         NULL,
2572                         "b", true);
2573         if (r < 0)
2574                 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
2575
2576         return r;
2577 #else
2578         return -ENOSYS;
2579 #endif
2580 }
2581
2582 static int check_inhibitors(sd_bus *bus, enum action a) {
2583 #ifdef HAVE_LOGIND
2584         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2585         _cleanup_strv_free_ char **sessions = NULL;
2586         const char *what, *who, *why, *mode;
2587         uint32_t uid, pid;
2588         unsigned c = 0;
2589         char **s;
2590         int r;
2591
2592         if (!bus)
2593                 return 0;
2594
2595         if (arg_ignore_inhibitors || arg_force > 0)
2596                 return 0;
2597
2598         if (arg_when > 0)
2599                 return 0;
2600
2601         if (geteuid() == 0)
2602                 return 0;
2603
2604         if (!on_tty())
2605                 return 0;
2606
2607         r = sd_bus_call_method(
2608                         bus,
2609                         "org.freedesktop.login1",
2610                         "/org/freedesktop/login1",
2611                         "org.freedesktop.login1.Manager",
2612                         "ListInhibitors",
2613                         NULL,
2614                         &reply,
2615                         NULL);
2616         if (r < 0)
2617                 /* If logind is not around, then there are no inhibitors... */
2618                 return 0;
2619
2620         r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssuu)");
2621         if (r < 0)
2622                 return bus_log_parse_error(r);
2623
2624         while ((r = sd_bus_message_read(reply, "(ssssuu)", &what, &who, &why, &mode, &uid, &pid)) > 0) {
2625                 _cleanup_free_ char *comm = NULL, *user = NULL;
2626                 _cleanup_strv_free_ char **sv = NULL;
2627
2628                 if (!streq(mode, "block"))
2629                         continue;
2630
2631                 sv = strv_split(what, ":");
2632                 if (!sv)
2633                         return log_oom();
2634
2635                 if (!strv_contains(sv,
2636                                   a == ACTION_HALT ||
2637                                   a == ACTION_POWEROFF ||
2638                                   a == ACTION_REBOOT ||
2639                                   a == ACTION_KEXEC ? "shutdown" : "sleep"))
2640                         continue;
2641
2642                 get_process_comm(pid, &comm);
2643                 user = uid_to_name(uid);
2644
2645                 log_warning("Operation inhibited by \"%s\" (PID %lu \"%s\", user %s), reason is \"%s\".",
2646                             who, (unsigned long) pid, strna(comm), strna(user), why);
2647
2648                 c++;
2649         }
2650         if (r < 0)
2651                 return bus_log_parse_error(r);
2652
2653         r = sd_bus_message_exit_container(reply);
2654         if (r < 0)
2655                 return bus_log_parse_error(r);
2656
2657         /* Check for current sessions */
2658         sd_get_sessions(&sessions);
2659         STRV_FOREACH(s, sessions) {
2660                 _cleanup_free_ char *type = NULL, *tty = NULL, *seat = NULL, *user = NULL, *service = NULL, *class = NULL;
2661
2662                 if (sd_session_get_uid(*s, &uid) < 0 || uid == getuid())
2663                         continue;
2664
2665                 if (sd_session_get_class(*s, &class) < 0 || !streq(class, "user"))
2666                         continue;
2667
2668                 if (sd_session_get_type(*s, &type) < 0 || (!streq(type, "x11") && !streq(type, "tty")))
2669                         continue;
2670
2671                 sd_session_get_tty(*s, &tty);
2672                 sd_session_get_seat(*s, &seat);
2673                 sd_session_get_service(*s, &service);
2674                 user = uid_to_name(uid);
2675
2676                 log_warning("User %s is logged in on %s.", strna(user), isempty(tty) ? (isempty(seat) ? strna(service) : seat) : tty);
2677                 c++;
2678         }
2679
2680         if (c <= 0)
2681                 return 0;
2682
2683         log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
2684                   action_table[a].verb);
2685
2686         return -EPERM;
2687 #else
2688         return 0;
2689 #endif
2690 }
2691
2692 static int start_special(sd_bus *bus, char **args) {
2693         enum action a;
2694         int r;
2695
2696         assert(args);
2697
2698         a = verb_to_action(args[0]);
2699
2700         r = check_inhibitors(bus, a);
2701         if (r < 0)
2702                 return r;
2703
2704         if (arg_force >= 2 && geteuid() != 0) {
2705                 log_error("Must be root.");
2706                 return -EPERM;
2707         }
2708
2709         if (arg_force >= 2 &&
2710             (a == ACTION_HALT ||
2711              a == ACTION_POWEROFF ||
2712              a == ACTION_REBOOT))
2713                 return halt_now(a);
2714
2715         if (arg_force >= 1 &&
2716             (a == ACTION_HALT ||
2717              a == ACTION_POWEROFF ||
2718              a == ACTION_REBOOT ||
2719              a == ACTION_KEXEC ||
2720              a == ACTION_EXIT))
2721                 return daemon_reload(bus, args);
2722
2723         /* first try logind, to allow authentication with polkit */
2724         if (geteuid() != 0 &&
2725             (a == ACTION_POWEROFF ||
2726              a == ACTION_REBOOT ||
2727              a == ACTION_SUSPEND ||
2728              a == ACTION_HIBERNATE ||
2729              a == ACTION_HYBRID_SLEEP)) {
2730                 r = reboot_with_logind(bus, a);
2731                 if (r >= 0)
2732                         return r;
2733         }
2734
2735         r = start_unit(bus, args);
2736         if (r == EXIT_SUCCESS)
2737                 warn_wall(a);
2738
2739         return r;
2740 }
2741
2742 static int check_unit_generic(sd_bus *bus, int code, const char *good_states, char **args) {
2743         _cleanup_strv_free_ char **names = NULL;
2744         char **name;
2745         int r;
2746
2747         assert(bus);
2748         assert(args);
2749
2750         r = expand_names(bus, args, NULL, &names);
2751         if (r < 0) {
2752                 log_error("Failed to expand names: %s", strerror(-r));
2753                 return r;
2754         }
2755
2756         STRV_FOREACH(name, names) {
2757                 int state;
2758
2759                 state = check_one_unit(bus, *name, good_states, arg_quiet);
2760                 if (state < 0)
2761                         return state;
2762                 if (state == 0)
2763                         r = code;
2764         }
2765
2766         return r;
2767 }
2768
2769 static int check_unit_active(sd_bus *bus, char **args) {
2770         /* According to LSB: 3, "program is not running" */
2771         return check_unit_generic(bus, 3, "active\0reloading\0", args + 1);
2772 }
2773
2774 static int check_unit_failed(sd_bus *bus, char **args) {
2775         return check_unit_generic(bus, 1, "failed\0", args + 1);
2776 }
2777
2778 static int kill_unit(sd_bus *bus, char **args) {
2779         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2780         _cleanup_strv_free_ char **names = NULL;
2781         char **name;
2782         int r, q;
2783
2784         assert(bus);
2785         assert(args);
2786
2787         if (!arg_kill_who)
2788                 arg_kill_who = "all";
2789
2790         r = expand_names(bus, args + 1, NULL, &names);
2791         if (r < 0)
2792                 log_error("Failed to expand names: %s", strerror(-r));
2793
2794         STRV_FOREACH(name, names) {
2795                 q = sd_bus_call_method(
2796                                 bus,
2797                                 "org.freedesktop.systemd1",
2798                                 "/org/freedesktop/systemd1",
2799                                 "org.freedesktop.systemd1.Manager",
2800                                 "KillUnit",
2801                                 &error,
2802                                 NULL,
2803                                 "ssi", *names, arg_kill_who, arg_signal);
2804                 if (q < 0) {
2805                         log_error("Failed to kill unit %s: %s",
2806                                   *names, bus_error_message(&error, r));
2807                         if (r == 0)
2808                                 r = q;
2809                 }
2810         }
2811
2812         return r;
2813 }
2814
2815 typedef struct ExecStatusInfo {
2816         char *name;
2817
2818         char *path;
2819         char **argv;
2820
2821         bool ignore;
2822
2823         usec_t start_timestamp;
2824         usec_t exit_timestamp;
2825         pid_t pid;
2826         int code;
2827         int status;
2828
2829         LIST_FIELDS(struct ExecStatusInfo, exec);
2830 } ExecStatusInfo;
2831
2832 static void exec_status_info_free(ExecStatusInfo *i) {
2833         assert(i);
2834
2835         free(i->name);
2836         free(i->path);
2837         strv_free(i->argv);
2838         free(i);
2839 }
2840
2841 static int exec_status_info_deserialize(sd_bus_message *m, ExecStatusInfo *i) {
2842         uint64_t start_timestamp, exit_timestamp, start_timestamp_monotonic, exit_timestamp_monotonic;
2843         const char *path;
2844         uint32_t pid;
2845         int32_t code, status;
2846         int ignore, r;
2847
2848         assert(m);
2849         assert(i);
2850
2851         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_STRUCT, "sasbttttuii");
2852         if (r < 0)
2853                 return bus_log_parse_error(r);
2854         else if (r == 0)
2855                 return 0;
2856
2857         r = sd_bus_message_read(m, "s", &path);
2858         if (r < 0)
2859                 return bus_log_parse_error(r);
2860
2861         i->path = strdup(path);
2862         if (!i->path)
2863                 return log_oom();
2864
2865         r = sd_bus_message_read_strv(m, &i->argv);
2866         if (r < 0)
2867                 return bus_log_parse_error(r);
2868
2869         r = sd_bus_message_read(m,
2870                                 "bttttuii",
2871                                 &ignore,
2872                                 &start_timestamp, &start_timestamp_monotonic,
2873                                 &exit_timestamp, &exit_timestamp_monotonic,
2874                                 &pid,
2875                                 &code, &status);
2876         if (r < 0)
2877                 return bus_log_parse_error(r);
2878
2879         i->ignore = ignore;
2880         i->start_timestamp = (usec_t) start_timestamp;
2881         i->exit_timestamp = (usec_t) exit_timestamp;
2882         i->pid = (pid_t) pid;
2883         i->code = code;
2884         i->status = status;
2885
2886         r = sd_bus_message_exit_container(m);
2887         if (r < 0)
2888                 return bus_log_parse_error(r);
2889
2890         return 1;
2891 }
2892
2893 typedef struct UnitStatusInfo {
2894         const char *id;
2895         const char *load_state;
2896         const char *active_state;
2897         const char *sub_state;
2898         const char *unit_file_state;
2899
2900         const char *description;
2901         const char *following;
2902
2903         char **documentation;
2904
2905         const char *fragment_path;
2906         const char *source_path;
2907         const char *control_group;
2908
2909         char **dropin_paths;
2910
2911         const char *load_error;
2912         const char *result;
2913
2914         usec_t inactive_exit_timestamp;
2915         usec_t inactive_exit_timestamp_monotonic;
2916         usec_t active_enter_timestamp;
2917         usec_t active_exit_timestamp;
2918         usec_t inactive_enter_timestamp;
2919
2920         bool need_daemon_reload;
2921
2922         /* Service */
2923         pid_t main_pid;
2924         pid_t control_pid;
2925         const char *status_text;
2926         const char *pid_file;
2927         bool running:1;
2928
2929         usec_t start_timestamp;
2930         usec_t exit_timestamp;
2931
2932         int exit_code, exit_status;
2933
2934         usec_t condition_timestamp;
2935         bool condition_result;
2936         bool failed_condition_trigger;
2937         bool failed_condition_negate;
2938         const char *failed_condition;
2939         const char *failed_condition_param;
2940
2941         /* Socket */
2942         unsigned n_accepted;
2943         unsigned n_connections;
2944         bool accept;
2945
2946         /* Pairs of type, path */
2947         char **listen;
2948
2949         /* Device */
2950         const char *sysfs_path;
2951
2952         /* Mount, Automount */
2953         const char *where;
2954
2955         /* Swap */
2956         const char *what;
2957
2958         LIST_HEAD(ExecStatusInfo, exec);
2959 } UnitStatusInfo;
2960
2961 static void print_status_info(
2962                 UnitStatusInfo *i,
2963                 bool *ellipsized) {
2964
2965         ExecStatusInfo *p;
2966         const char *active_on, *active_off, *on, *off, *ss;
2967         usec_t timestamp;
2968         char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
2969         char since2[FORMAT_TIMESTAMP_MAX], *s2;
2970         const char *path;
2971         int flags =
2972                 arg_all * OUTPUT_SHOW_ALL |
2973                 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
2974                 on_tty() * OUTPUT_COLOR |
2975                 !arg_quiet * OUTPUT_WARN_CUTOFF |
2976                 arg_full * OUTPUT_FULL_WIDTH;
2977         char **t, **t2;
2978
2979         assert(i);
2980
2981         /* This shows pretty information about a unit. See
2982          * print_property() for a low-level property printer */
2983
2984         if (streq_ptr(i->active_state, "failed")) {
2985                 active_on = ansi_highlight_red();
2986                 active_off = ansi_highlight_off();
2987         } else if (streq_ptr(i->active_state, "active") || streq_ptr(i->active_state, "reloading")) {
2988                 active_on = ansi_highlight_green();
2989                 active_off = ansi_highlight_off();
2990         } else
2991                 active_on = active_off = "";
2992
2993         printf("%s%s%s%s", active_on, draw_special_char(DRAW_BLACK_CIRCLE), active_off, strna(i->id));
2994
2995         if (i->description && !streq_ptr(i->id, i->description))
2996                 printf(" - %s", i->description);
2997
2998         printf("\n");
2999
3000         if (i->following)
3001                 printf("   Follow: unit currently follows state of %s\n", i->following);
3002
3003         if (streq_ptr(i->load_state, "error")) {
3004                 on = ansi_highlight_red();
3005                 off = ansi_highlight_off();
3006         } else
3007                 on = off = "";
3008
3009         path = i->source_path ? i->source_path : i->fragment_path;
3010
3011         if (i->load_error)
3012                 printf("   Loaded: %s%s%s (Reason: %s)\n",
3013                        on, strna(i->load_state), off, i->load_error);
3014         else if (path && i->unit_file_state)
3015                 printf("   Loaded: %s%s%s (%s; %s)\n",
3016                        on, strna(i->load_state), off, path, i->unit_file_state);
3017         else if (path)
3018                 printf("   Loaded: %s%s%s (%s)\n",
3019                        on, strna(i->load_state), off, path);
3020         else
3021                 printf("   Loaded: %s%s%s\n",
3022                        on, strna(i->load_state), off);
3023
3024         if (!strv_isempty(i->dropin_paths)) {
3025                 _cleanup_free_ char *dir = NULL;
3026                 bool last = false;
3027                 char ** dropin;
3028
3029                 STRV_FOREACH(dropin, i->dropin_paths) {
3030                         if (! dir || last) {
3031                                 printf(dir ? "        " : "  Drop-In: ");
3032
3033                                 free(dir);
3034                                 dir = NULL;
3035
3036                                 if (path_get_parent(*dropin, &dir) < 0) {
3037                                         log_oom();
3038                                         return;
3039                                 }
3040
3041                                 printf("%s\n           %s", dir,
3042                                        draw_special_char(DRAW_TREE_RIGHT));
3043                         }
3044
3045                         last = ! (*(dropin + 1) && startswith(*(dropin + 1), dir));
3046
3047                         printf("%s%s", basename(*dropin), last ? "\n" : ", ");
3048                 }
3049         }
3050
3051         ss = streq_ptr(i->active_state, i->sub_state) ? NULL : i->sub_state;
3052         if (ss)
3053                 printf("   Active: %s%s (%s)%s",
3054                        active_on, strna(i->active_state), ss, active_off);
3055         else
3056                 printf("   Active: %s%s%s",
3057                        active_on, strna(i->active_state), active_off);
3058
3059         if (!isempty(i->result) && !streq(i->result, "success"))
3060                 printf(" (Result: %s)", i->result);
3061
3062         timestamp = (streq_ptr(i->active_state, "active")      ||
3063                      streq_ptr(i->active_state, "reloading"))   ? i->active_enter_timestamp :
3064                     (streq_ptr(i->active_state, "inactive")    ||
3065                      streq_ptr(i->active_state, "failed"))      ? i->inactive_enter_timestamp :
3066                     streq_ptr(i->active_state, "activating")    ? i->inactive_exit_timestamp :
3067                                                                   i->active_exit_timestamp;
3068
3069         s1 = format_timestamp_relative(since1, sizeof(since1), timestamp);
3070         s2 = format_timestamp(since2, sizeof(since2), timestamp);
3071
3072         if (s1)
3073                 printf(" since %s; %s\n", s2, s1);
3074         else if (s2)
3075                 printf(" since %s\n", s2);
3076         else
3077                 printf("\n");
3078
3079         if (!i->condition_result && i->condition_timestamp > 0) {
3080                 s1 = format_timestamp_relative(since1, sizeof(since1), i->condition_timestamp);
3081                 s2 = format_timestamp(since2, sizeof(since2), i->condition_timestamp);
3082
3083                 printf("           start condition failed at %s%s%s\n",
3084                        s2, s1 ? "; " : "", s1 ? s1 : "");
3085                 if (i->failed_condition_trigger)
3086                         printf("           none of the trigger conditions were met\n");
3087                 else if (i->failed_condition)
3088                         printf("           %s=%s%s was not met\n",
3089                                i->failed_condition,
3090                                i->failed_condition_negate ? "!" : "",
3091                                i->failed_condition_param);
3092         }
3093
3094         if (i->sysfs_path)
3095                 printf("   Device: %s\n", i->sysfs_path);
3096         if (i->where)
3097                 printf("    Where: %s\n", i->where);
3098         if (i->what)
3099                 printf("     What: %s\n", i->what);
3100
3101         STRV_FOREACH(t, i->documentation)
3102                 printf(" %*s %s\n", 9, t == i->documentation ? "Docs:" : "", *t);
3103
3104         STRV_FOREACH_PAIR(t, t2, i->listen)
3105                 printf(" %*s %s (%s)\n", 9, t == i->listen ? "Listen:" : "", *t2, *t);
3106
3107         if (i->accept)
3108                 printf(" Accepted: %u; Connected: %u\n", i->n_accepted, i->n_connections);
3109
3110         LIST_FOREACH(exec, p, i->exec) {
3111                 _cleanup_free_ char *argv = NULL;
3112                 bool good;
3113
3114                 /* Only show exited processes here */
3115                 if (p->code == 0)
3116                         continue;
3117
3118                 argv = strv_join(p->argv, " ");
3119                 printf("  Process: %u %s=%s ", p->pid, p->name, strna(argv));
3120
3121                 good = is_clean_exit_lsb(p->code, p->status, NULL);
3122                 if (!good) {
3123                         on = ansi_highlight_red();
3124                         off = ansi_highlight_off();
3125                 } else
3126                         on = off = "";
3127
3128                 printf("%s(code=%s, ", on, sigchld_code_to_string(p->code));
3129
3130                 if (p->code == CLD_EXITED) {
3131                         const char *c;
3132
3133                         printf("status=%i", p->status);
3134
3135                         c = exit_status_to_string(p->status, EXIT_STATUS_SYSTEMD);
3136                         if (c)
3137                                 printf("/%s", c);
3138
3139                 } else
3140                         printf("signal=%s", signal_to_string(p->status));
3141
3142                 printf(")%s\n", off);
3143
3144                 if (i->main_pid == p->pid &&
3145                     i->start_timestamp == p->start_timestamp &&
3146                     i->exit_timestamp == p->start_timestamp)
3147                         /* Let's not show this twice */
3148                         i->main_pid = 0;
3149
3150                 if (p->pid == i->control_pid)
3151                         i->control_pid = 0;
3152         }
3153
3154         if (i->main_pid > 0 || i->control_pid > 0) {
3155                 if (i->main_pid > 0) {
3156                         printf(" Main PID: %u", (unsigned) i->main_pid);
3157
3158                         if (i->running) {
3159                                 _cleanup_free_ char *comm = NULL;
3160                                 get_process_comm(i->main_pid, &comm);
3161                                 if (comm)
3162                                         printf(" (%s)", comm);
3163                         } else if (i->exit_code > 0) {
3164                                 printf(" (code=%s, ", sigchld_code_to_string(i->exit_code));
3165
3166                                 if (i->exit_code == CLD_EXITED) {
3167                                         const char *c;
3168
3169                                         printf("status=%i", i->exit_status);
3170
3171                                         c = exit_status_to_string(i->exit_status, EXIT_STATUS_SYSTEMD);
3172                                         if (c)
3173                                                 printf("/%s", c);
3174
3175                                 } else
3176                                         printf("signal=%s", signal_to_string(i->exit_status));
3177                                 printf(")");
3178                         }
3179
3180                         if (i->control_pid > 0)
3181                                 printf(";");
3182                 }
3183
3184                 if (i->control_pid > 0) {
3185                         _cleanup_free_ char *c = NULL;
3186
3187                         printf(" %8s: %u", i->main_pid ? "" : " Control", (unsigned) i->control_pid);
3188
3189                         get_process_comm(i->control_pid, &c);
3190                         if (c)
3191                                 printf(" (%s)", c);
3192                 }
3193
3194                 printf("\n");
3195         }
3196
3197         if (i->status_text)
3198                 printf("   Status: \"%s\"\n", i->status_text);
3199
3200         if (i->control_group &&
3201             (i->main_pid > 0 || i->control_pid > 0 ||
3202              ((arg_transport != BUS_TRANSPORT_LOCAL && arg_transport != BUS_TRANSPORT_CONTAINER) || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, i->control_group, false) == 0))) {
3203                 unsigned c;
3204
3205                 printf("   CGroup: %s\n", i->control_group);
3206
3207                 if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_CONTAINER) {
3208                         unsigned k = 0;
3209                         pid_t extra[2];
3210                         static const char prefix[] = "           ";
3211
3212                         c = columns();
3213                         if (c > sizeof(prefix) - 1)
3214                                 c -= sizeof(prefix) - 1;
3215                         else
3216                                 c = 0;
3217
3218                         if (i->main_pid > 0)
3219                                 extra[k++] = i->main_pid;
3220
3221                         if (i->control_pid > 0)
3222                                 extra[k++] = i->control_pid;
3223
3224                         show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, i->control_group, prefix, c, false, extra, k, flags);
3225                 }
3226         }
3227
3228         if (i->id && arg_transport == BUS_TRANSPORT_LOCAL) {
3229                 printf("\n");
3230                 show_journal_by_unit(stdout,
3231                                      i->id,
3232                                      arg_output,
3233                                      0,
3234                                      i->inactive_exit_timestamp_monotonic,
3235                                      arg_lines,
3236                                      getuid(),
3237                                      flags,
3238                                      arg_scope == UNIT_FILE_SYSTEM,
3239                                      ellipsized);
3240         }
3241
3242         if (i->need_daemon_reload)
3243                 printf("\n%sWarning:%s Unit file changed on disk, 'systemctl %sdaemon-reload' recommended.\n",
3244                        ansi_highlight_red(),
3245                        ansi_highlight_off(),
3246                        arg_scope == UNIT_FILE_SYSTEM ? "" : "--user ");
3247 }
3248
3249 static void show_unit_help(UnitStatusInfo *i) {
3250         char **p;
3251
3252         assert(i);
3253
3254         if (!i->documentation) {
3255                 log_info("Documentation for %s not known.", i->id);
3256                 return;
3257         }
3258
3259         STRV_FOREACH(p, i->documentation) {
3260
3261                 if (startswith(*p, "man:")) {
3262                         const char *args[4] = { "man", NULL, NULL, NULL };
3263                         _cleanup_free_ char *page = NULL, *section = NULL;
3264                         char *e = NULL;
3265                         pid_t pid;
3266                         size_t k;
3267
3268                         k = strlen(*p);
3269
3270                         if ((*p)[k-1] == ')')
3271                                 e = strrchr(*p, '(');
3272
3273                         if (e) {
3274                                 page = strndup((*p) + 4, e - *p - 4);
3275                                 section = strndup(e + 1, *p + k - e - 2);
3276                                 if (!page || !section) {
3277                                         log_oom();
3278                                         return;
3279                                 }
3280
3281                                 args[1] = section;
3282                                 args[2] = page;
3283                         } else
3284                                 args[1] = *p + 4;
3285
3286                         pid = fork();
3287                         if (pid < 0) {
3288                                 log_error("Failed to fork: %m");
3289                                 continue;
3290                         }
3291
3292                         if (pid == 0) {
3293                                 /* Child */
3294                                 execvp(args[0], (char**) args);
3295                                 log_error("Failed to execute man: %m");
3296                                 _exit(EXIT_FAILURE);
3297                         }
3298
3299                         wait_for_terminate(pid, NULL);
3300                 } else
3301                         log_info("Can't show: %s", *p);
3302         }
3303 }
3304
3305 static int status_property(const char *name, sd_bus_message *m, UnitStatusInfo *i, const char *contents) {
3306         int r;
3307
3308         assert(name);
3309         assert(m);
3310         assert(i);
3311
3312         switch (contents[0]) {
3313
3314         case SD_BUS_TYPE_STRING: {
3315                 const char *s;
3316
3317                 r = sd_bus_message_read(m, "s", &s);
3318                 if (r < 0)
3319                         return bus_log_parse_error(r);
3320
3321                 if (!isempty(s)) {
3322                         if (streq(name, "Id"))
3323                                 i->id = s;
3324                         else if (streq(name, "LoadState"))
3325                                 i->load_state = s;
3326                         else if (streq(name, "ActiveState"))
3327                                 i->active_state = s;
3328                         else if (streq(name, "SubState"))
3329                                 i->sub_state = s;
3330                         else if (streq(name, "Description"))
3331                                 i->description = s;
3332                         else if (streq(name, "FragmentPath"))
3333                                 i->fragment_path = s;
3334                         else if (streq(name, "SourcePath"))
3335                                 i->source_path = s;
3336 #ifndef NOLEGACY
3337                         else if (streq(name, "DefaultControlGroup")) {
3338                                 const char *e;
3339                                 e = startswith(s, SYSTEMD_CGROUP_CONTROLLER ":");
3340                                 if (e)
3341                                         i->control_group = e;
3342                         }
3343 #endif
3344                         else if (streq(name, "ControlGroup"))
3345                                 i->control_group = s;
3346                         else if (streq(name, "StatusText"))
3347                                 i->status_text = s;
3348                         else if (streq(name, "PIDFile"))
3349                                 i->pid_file = s;
3350                         else if (streq(name, "SysFSPath"))
3351                                 i->sysfs_path = s;
3352                         else if (streq(name, "Where"))
3353                                 i->where = s;
3354                         else if (streq(name, "What"))
3355                                 i->what = s;
3356                         else if (streq(name, "Following"))
3357                                 i->following = s;
3358                         else if (streq(name, "UnitFileState"))
3359                                 i->unit_file_state = s;
3360                         else if (streq(name, "Result"))
3361                                 i->result = s;
3362                 }
3363
3364                 break;
3365         }
3366
3367         case SD_BUS_TYPE_BOOLEAN: {
3368                 int b;
3369
3370                 r = sd_bus_message_read(m, "b", &b);
3371                 if (r < 0)
3372                         return bus_log_parse_error(r);
3373
3374                 if (streq(name, "Accept"))
3375                         i->accept = b;
3376                 else if (streq(name, "NeedDaemonReload"))
3377                         i->need_daemon_reload = b;
3378                 else if (streq(name, "ConditionResult"))
3379                         i->condition_result = b;
3380
3381                 break;
3382         }
3383
3384         case SD_BUS_TYPE_UINT32: {
3385                 uint32_t u;
3386
3387                 r = sd_bus_message_read(m, "u", &u);
3388                 if (r < 0)
3389                         return bus_log_parse_error(r);
3390
3391                 if (streq(name, "MainPID")) {
3392                         if (u > 0) {
3393                                 i->main_pid = (pid_t) u;
3394                                 i->running = true;
3395                         }
3396                 } else if (streq(name, "ControlPID"))
3397                         i->control_pid = (pid_t) u;
3398                 else if (streq(name, "ExecMainPID")) {
3399                         if (u > 0)
3400                                 i->main_pid = (pid_t) u;
3401                 } else if (streq(name, "NAccepted"))
3402                         i->n_accepted = u;
3403                 else if (streq(name, "NConnections"))
3404                         i->n_connections = u;
3405
3406                 break;
3407         }
3408
3409         case SD_BUS_TYPE_INT32: {
3410                 int32_t j;
3411
3412                 r = sd_bus_message_read(m, "i", &j);
3413                 if (r < 0)
3414                         return bus_log_parse_error(r);
3415
3416                 if (streq(name, "ExecMainCode"))
3417                         i->exit_code = (int) j;
3418                 else if (streq(name, "ExecMainStatus"))
3419                         i->exit_status = (int) j;
3420
3421                 break;
3422         }
3423
3424         case SD_BUS_TYPE_UINT64: {
3425                 uint64_t u;
3426
3427                 r = sd_bus_message_read(m, "t", &u);
3428                 if (r < 0)
3429                         return bus_log_parse_error(r);
3430
3431                 if (streq(name, "ExecMainStartTimestamp"))
3432                         i->start_timestamp = (usec_t) u;
3433                 else if (streq(name, "ExecMainExitTimestamp"))
3434                         i->exit_timestamp = (usec_t) u;
3435                 else if (streq(name, "ActiveEnterTimestamp"))
3436                         i->active_enter_timestamp = (usec_t) u;
3437                 else if (streq(name, "InactiveEnterTimestamp"))
3438                         i->inactive_enter_timestamp = (usec_t) u;
3439                 else if (streq(name, "InactiveExitTimestamp"))
3440                         i->inactive_exit_timestamp = (usec_t) u;
3441                 else if (streq(name, "InactiveExitTimestampMonotonic"))
3442                         i->inactive_exit_timestamp_monotonic = (usec_t) u;
3443                 else if (streq(name, "ActiveExitTimestamp"))
3444                         i->active_exit_timestamp = (usec_t) u;
3445                 else if (streq(name, "ConditionTimestamp"))
3446                         i->condition_timestamp = (usec_t) u;
3447
3448                 break;
3449         }
3450
3451         case SD_BUS_TYPE_ARRAY:
3452
3453                 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3454                         _cleanup_free_ ExecStatusInfo *info = NULL;
3455
3456                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3457                         if (r < 0)
3458                                 return bus_log_parse_error(r);
3459
3460                         info = new0(ExecStatusInfo, 1);
3461                         if (!info)
3462                                 return log_oom();
3463
3464                         while ((r = exec_status_info_deserialize(m, info)) > 0) {
3465
3466                                 info->name = strdup(name);
3467                                 if (!info->name)
3468                                         log_oom();
3469
3470                                 LIST_PREPEND(exec, i->exec, info);
3471
3472                                 info = new0(ExecStatusInfo, 1);
3473                                 if (!info)
3474                                         log_oom();
3475                         }
3476
3477                         if (r < 0)
3478                                 return bus_log_parse_error(r);
3479
3480                         r = sd_bus_message_exit_container(m);
3481                         if (r < 0)
3482                                 return bus_log_parse_error(r);
3483
3484                         return 0;
3485
3486                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3487                         const char *type, *path;
3488
3489                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3490                         if (r < 0)
3491                                 return bus_log_parse_error(r);
3492
3493                         while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0) {
3494
3495                                 r = strv_extend(&i->listen, type);
3496                                 if (r < 0)
3497                                         return r;
3498
3499                                 r = strv_extend(&i->listen, path);
3500                                 if (r < 0)
3501                                         return r;
3502                         }
3503                         if (r < 0)
3504                                 return bus_log_parse_error(r);
3505
3506                         r = sd_bus_message_exit_container(m);
3507                         if (r < 0)
3508                                 return bus_log_parse_error(r);
3509
3510                         return 0;
3511
3512                 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "DropInPaths")) {
3513
3514                         r = sd_bus_message_read_strv(m, &i->dropin_paths);
3515                         if (r < 0)
3516                                 return bus_log_parse_error(r);
3517
3518                 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Documentation")) {
3519
3520                         r = sd_bus_message_read_strv(m, &i->documentation);
3521                         if (r < 0)
3522                                 return bus_log_parse_error(r);
3523
3524                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Conditions")) {
3525                         const char *cond, *param;
3526                         int trigger, negate;
3527                         int32_t state;
3528
3529                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
3530                         if (r < 0)
3531                                 return bus_log_parse_error(r);
3532
3533                         while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, &param, &state)) > 0) {
3534                                 log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
3535                                 if (state < 0 && (!trigger || !i->failed_condition)) {
3536                                         i->failed_condition = cond;
3537                                         i->failed_condition_trigger = trigger;
3538                                         i->failed_condition_negate = negate;
3539                                         i->failed_condition_param = param;
3540                                 }
3541                         }
3542                         if (r < 0)
3543                                 return bus_log_parse_error(r);
3544
3545                         r = sd_bus_message_exit_container(m);
3546                         if (r < 0)
3547                                 return bus_log_parse_error(r);
3548
3549                 } else
3550                         goto skip;
3551
3552                 break;
3553
3554         case SD_BUS_TYPE_STRUCT_BEGIN:
3555
3556                 if (streq(name, "LoadError")) {
3557                         const char *n, *message;
3558
3559                         r = sd_bus_message_read(m, "(ss)", &n, &message);
3560                         if (r < 0)
3561                                 return bus_log_parse_error(r);
3562
3563                         if (!isempty(message))
3564                                 i->load_error = message;
3565                 } else
3566                         goto skip;
3567
3568                 break;
3569
3570         default:
3571                 goto skip;
3572         }
3573
3574         return 0;
3575
3576 skip:
3577         r = sd_bus_message_skip(m, contents);
3578         if (r < 0)
3579                 return bus_log_parse_error(r);
3580
3581         return 0;
3582 }
3583
3584 static int print_property(const char *name, sd_bus_message *m, const char *contents) {
3585         int r;
3586
3587         assert(name);
3588         assert(m);
3589
3590         /* This is a low-level property printer, see
3591          * print_status_info() for the nicer output */
3592
3593         if (arg_properties && !strv_find(arg_properties, name)) {
3594                 /* skip what we didn't read */
3595                 r = sd_bus_message_skip(m, contents);
3596                 return r;
3597         }
3598
3599         switch (contents[0]) {
3600
3601         case SD_BUS_TYPE_STRUCT_BEGIN:
3602
3603                 if (contents[1] == SD_BUS_TYPE_UINT32 && streq(name, "Job")) {
3604                         uint32_t u;
3605
3606                         r = sd_bus_message_read(m, "(uo)", &u, NULL);
3607                         if (r < 0)
3608                                 return bus_log_parse_error(r);
3609
3610                         if (u > 0)
3611                                 printf("%s=%u\n", name, (unsigned) u);
3612                         else if (arg_all)
3613                                 printf("%s=\n", name);
3614
3615                         return 0;
3616
3617                 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Unit")) {
3618                         const char *s;
3619
3620                         r = sd_bus_message_read(m, "(so)", &s, NULL);
3621                         if (r < 0)
3622                                 return bus_log_parse_error(r);
3623
3624                         if (arg_all || !isempty(s))
3625                                 printf("%s=%s\n", name, s);
3626
3627                         return 0;
3628
3629                 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "LoadError")) {
3630                         const char *a = NULL, *b = NULL;
3631
3632                         r = sd_bus_message_read(m, "(ss)", &a, &b);
3633                         if (r < 0)
3634                                 return bus_log_parse_error(r);
3635
3636                         if (arg_all || !isempty(a) || !isempty(b))
3637                                 printf("%s=%s \"%s\"\n", name, strempty(a), strempty(b));
3638
3639                         return 0;
3640                 } else if (streq_ptr(name, "SystemCallFilter")) {
3641                         _cleanup_strv_free_ char **l = NULL;
3642                         int whitelist;
3643
3644                         r = sd_bus_message_enter_container(m, 'r', "bas");
3645                         if (r < 0)
3646                                 return bus_log_parse_error(r);
3647
3648                         r = sd_bus_message_read(m, "b", &whitelist);
3649                         if (r < 0)
3650                                 return bus_log_parse_error(r);
3651
3652                         r = sd_bus_message_read_strv(m, &l);
3653                         if (r < 0)
3654                                 return bus_log_parse_error(r);
3655
3656                         r = sd_bus_message_exit_container(m);
3657                         if (r < 0)
3658                                 return bus_log_parse_error(r);
3659
3660                         if (arg_all || whitelist || !strv_isempty(l)) {
3661                                 bool first = true;
3662                                 char **i;
3663
3664                                 fputs(name, stdout);
3665                                 fputc('=', stdout);
3666
3667                                 if (!whitelist)
3668                                         fputc('~', stdout);
3669
3670                                 STRV_FOREACH(i, l) {
3671                                         if (first)
3672                                                 first = false;
3673                                         else
3674                                                 fputc(' ', stdout);
3675
3676                                         fputs(*i, stdout);
3677                                 }
3678                                 fputc('\n', stdout);
3679                         }
3680
3681                         return 0;
3682                 }
3683
3684                 break;
3685
3686         case SD_BUS_TYPE_ARRAY:
3687
3688                 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "EnvironmentFiles")) {
3689                         const char *path;
3690                         int ignore;
3691
3692                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sb)");
3693                         if (r < 0)
3694                                 return bus_log_parse_error(r);
3695
3696                         while ((r = sd_bus_message_read(m, "(sb)", &path, &ignore)) > 0)
3697                                 printf("EnvironmentFile=%s (ignore_errors=%s)\n", path, yes_no(ignore));
3698
3699                         if (r < 0)
3700                                 return bus_log_parse_error(r);
3701
3702                         r = sd_bus_message_exit_container(m);
3703                         if (r < 0)
3704                                 return bus_log_parse_error(r);
3705
3706                         return 0;
3707
3708                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Paths")) {
3709                         const char *type, *path;
3710
3711                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3712                         if (r < 0)
3713                                 return bus_log_parse_error(r);
3714
3715                         while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
3716                                 printf("%s=%s\n", type, path);
3717                         if (r < 0)
3718                                 return bus_log_parse_error(r);
3719
3720                         r = sd_bus_message_exit_container(m);
3721                         if (r < 0)
3722                                 return bus_log_parse_error(r);
3723
3724                         return 0;
3725
3726                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3727                         const char *type, *path;
3728
3729                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3730                         if (r < 0)
3731                                 return bus_log_parse_error(r);
3732
3733                         while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
3734                                 printf("Listen%s=%s\n", type, path);
3735                         if (r < 0)
3736                                 return bus_log_parse_error(r);
3737
3738                         r = sd_bus_message_exit_container(m);
3739                         if (r < 0)
3740                                 return bus_log_parse_error(r);
3741
3742                         return 0;
3743
3744                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Timers")) {
3745                         const char *base;
3746                         uint64_t value, next_elapse;
3747
3748                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(stt)");
3749                         if (r < 0)
3750                                 return bus_log_parse_error(r);
3751
3752                         while ((r = sd_bus_message_read(m, "(stt)", &base, &value, &next_elapse)) > 0) {
3753                                 char timespan1[FORMAT_TIMESPAN_MAX], timespan2[FORMAT_TIMESPAN_MAX];
3754
3755                                 printf("%s={ value=%s ; next_elapse=%s }\n",
3756                                        base,
3757                                        format_timespan(timespan1, sizeof(timespan1), value, 0),
3758                                        format_timespan(timespan2, sizeof(timespan2), next_elapse, 0));
3759                         }
3760                         if (r < 0)
3761                                 return bus_log_parse_error(r);
3762
3763                         r = sd_bus_message_exit_container(m);
3764                         if (r < 0)
3765                                 return bus_log_parse_error(r);
3766
3767                         return 0;
3768
3769                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3770                         ExecStatusInfo info = {};
3771
3772                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3773                         if (r < 0)
3774                                 return bus_log_parse_error(r);
3775
3776                         while ((r = exec_status_info_deserialize(m, &info)) > 0) {
3777                                 char timestamp1[FORMAT_TIMESTAMP_MAX], timestamp2[FORMAT_TIMESTAMP_MAX];
3778                                 _cleanup_free_ char *tt;
3779
3780                                 tt = strv_join(info.argv, " ");
3781
3782                                 printf("%s={ path=%s ; argv[]=%s ; ignore_errors=%s ; start_time=[%s] ; stop_time=[%s] ; pid=%u ; code=%s ; status=%i%s%s }\n",
3783                                        name,
3784                                        strna(info.path),
3785                                        strna(tt),
3786                                        yes_no(info.ignore),
3787                                        strna(format_timestamp(timestamp1, sizeof(timestamp1), info.start_timestamp)),
3788                                        strna(format_timestamp(timestamp2, sizeof(timestamp2), info.exit_timestamp)),
3789                                        (unsigned) info. pid,
3790                                        sigchld_code_to_string(info.code),
3791                                        info.status,
3792                                        info.code == CLD_EXITED ? "" : "/",
3793                                        strempty(info.code == CLD_EXITED ? NULL : signal_to_string(info.status)));
3794
3795                                 free(info.path);
3796                                 strv_free(info.argv);
3797                                 zero(info);
3798                         }
3799
3800                         r = sd_bus_message_exit_container(m);
3801                         if (r < 0)
3802                                 return bus_log_parse_error(r);
3803
3804                         return 0;
3805
3806                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "DeviceAllow")) {
3807                         const char *path, *rwm;
3808
3809                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3810                         if (r < 0)
3811                                 return bus_log_parse_error(r);
3812
3813                         while ((r = sd_bus_message_read(m, "(ss)", &path, &rwm)) > 0)
3814                                 printf("%s=%s %s\n", name, strna(path), strna(rwm));
3815                         if (r < 0)
3816                                 return bus_log_parse_error(r);
3817
3818                         r = sd_bus_message_exit_container(m);
3819                         if (r < 0)
3820                                 return bus_log_parse_error(r);
3821
3822                         return 0;
3823
3824                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "BlockIODeviceWeight")) {
3825                         const char *path;
3826                         uint64_t weight;
3827
3828                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
3829                         if (r < 0)
3830                                 return bus_log_parse_error(r);
3831
3832                         while ((r = sd_bus_message_read(m, "(st)", &path, &weight)) > 0)
3833                                 printf("%s=%s %" PRIu64 "\n", name, strna(path), weight);
3834                         if (r < 0)
3835                                 return bus_log_parse_error(r);
3836
3837                         r = sd_bus_message_exit_container(m);
3838                         if (r < 0)
3839                                 return bus_log_parse_error(r);
3840
3841                         return 0;
3842
3843                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && (streq(name, "BlockIOReadBandwidth") || streq(name, "BlockIOWriteBandwidth"))) {
3844                         const char *path;
3845                         uint64_t bandwidth;
3846
3847                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
3848                         if (r < 0)
3849                                 return bus_log_parse_error(r);
3850
3851                         while ((r = sd_bus_message_read(m, "(st)", &path, &bandwidth)) > 0)
3852                                 printf("%s=%s %" PRIu64 "\n", name, strna(path), bandwidth);
3853                         if (r < 0)
3854                                 return bus_log_parse_error(r);
3855
3856                         r = sd_bus_message_exit_container(m);
3857                         if (r < 0)
3858                                 return bus_log_parse_error(r);
3859
3860                         return 0;
3861                 }
3862
3863                 break;
3864         }
3865
3866         r = bus_print_property(name, m, arg_all);
3867         if (r < 0)
3868                 return bus_log_parse_error(r);
3869
3870         if (r == 0) {
3871                 r = sd_bus_message_skip(m, contents);
3872                 if (r < 0)
3873                         return bus_log_parse_error(r);
3874
3875                 if (arg_all)
3876                         printf("%s=[unprintable]\n", name);
3877         }
3878
3879         return 0;
3880 }
3881
3882 static int show_one(
3883                 const char *verb,
3884                 sd_bus *bus,
3885                 const char *path,
3886                 bool show_properties,
3887                 bool *new_line,
3888                 bool *ellipsized) {
3889
3890         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3891         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3892         UnitStatusInfo info = {};
3893         ExecStatusInfo *p;
3894         int r;
3895
3896         assert(path);
3897         assert(new_line);
3898
3899         log_debug("Showing one %s", path);
3900
3901         r = sd_bus_call_method(
3902                         bus,
3903                         "org.freedesktop.systemd1",
3904                         path,
3905                         "org.freedesktop.DBus.Properties",
3906                         "GetAll",
3907                         &error,
3908                         &reply,
3909                         "s", "");
3910         if (r < 0) {
3911                 log_error("Failed to get properties: %s", bus_error_message(&error, r));
3912                 return r;
3913         }
3914
3915         r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
3916         if (r < 0)
3917                 return bus_log_parse_error(r);
3918
3919         if (*new_line)
3920                 printf("\n");
3921
3922         *new_line = true;
3923
3924         while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
3925                 const char *name, *contents;
3926
3927                 r = sd_bus_message_read(reply, "s", &name);
3928                 if (r < 0)
3929                         return bus_log_parse_error(r);
3930
3931                 r = sd_bus_message_peek_type(reply, NULL, &contents);
3932                 if (r < 0)
3933                         return bus_log_parse_error(r);
3934
3935                 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, contents);
3936                 if (r < 0)
3937                         return bus_log_parse_error(r);
3938
3939                 if (show_properties)
3940                         r = print_property(name, reply, contents);
3941                 else
3942                         r = status_property(name, reply, &info, contents);
3943                 if (r < 0)
3944                         return r;
3945
3946                 r = sd_bus_message_exit_container(reply);
3947                 if (r < 0)
3948                         return bus_log_parse_error(r);
3949
3950                 r = sd_bus_message_exit_container(reply);
3951                 if (r < 0)
3952                         return bus_log_parse_error(r);
3953         }
3954         if (r < 0)
3955                 return bus_log_parse_error(r);
3956
3957         r = sd_bus_message_exit_container(reply);
3958         if (r < 0)
3959                 return bus_log_parse_error(r);
3960
3961         r = 0;
3962
3963         if (!show_properties) {
3964                 if (streq(verb, "help"))
3965                         show_unit_help(&info);
3966                 else
3967                         print_status_info(&info, ellipsized);
3968         }
3969
3970         strv_free(info.documentation);
3971         strv_free(info.dropin_paths);
3972         strv_free(info.listen);
3973
3974         if (!streq_ptr(info.active_state, "active") &&
3975             !streq_ptr(info.active_state, "reloading") &&
3976             streq(verb, "status")) {
3977                 /* According to LSB: "program not running" */
3978                 /* 0: program is running or service is OK
3979                  * 1: program is dead and /run PID file exists
3980                  * 2: program is dead and /run/lock lock file exists
3981                  * 3: program is not running
3982                  * 4: program or service status is unknown
3983                  */
3984                 if (info.pid_file && access(info.pid_file, F_OK) == 0)
3985                         r = 1;
3986                 else
3987                         r = 3;
3988         }
3989
3990         while ((p = info.exec)) {
3991                 LIST_REMOVE(exec, info.exec, p);
3992                 exec_status_info_free(p);
3993         }
3994
3995         return r;
3996 }
3997
3998 static int get_unit_dbus_path_by_pid(
3999                 sd_bus *bus,
4000                 uint32_t pid,
4001                 char **unit) {
4002
4003         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4004         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4005         char *u;
4006         int r;
4007
4008         r = sd_bus_call_method(
4009                         bus,
4010                         "org.freedesktop.systemd1",
4011                         "/org/freedesktop/systemd1",
4012                         "org.freedesktop.systemd1.Manager",
4013                         "GetUnitByPID",
4014                         &error,
4015                         &reply,
4016                         "u", pid);
4017         if (r < 0) {
4018                 log_error("Failed to get unit for PID %lu: %s", (unsigned long) pid, bus_error_message(&error, r));
4019                 return r;
4020         }
4021
4022         r = sd_bus_message_read(reply, "o", &u);
4023         if (r < 0)
4024                 return bus_log_parse_error(r);
4025
4026         u = strdup(u);
4027         if (!u)
4028                 return log_oom();
4029
4030         *unit = u;
4031         return 0;
4032 }
4033
4034 static int show_all(
4035                 const char* verb,
4036                 sd_bus *bus,
4037                 bool show_properties,
4038                 bool *new_line,
4039                 bool *ellipsized) {
4040
4041         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4042         _cleanup_free_ UnitInfo *unit_infos = NULL;
4043         const UnitInfo *u;
4044         unsigned c;
4045         int r;
4046
4047         r = get_unit_list(bus, &reply, &unit_infos, NULL);
4048         if (r < 0)
4049                 return r;
4050
4051         pager_open_if_enabled();
4052
4053         c = (unsigned) r;
4054
4055         qsort_safe(unit_infos, c, sizeof(UnitInfo), compare_unit_info);
4056
4057         for (u = unit_infos; u < unit_infos + c; u++) {
4058                 _cleanup_free_ char *p = NULL;
4059
4060                 p = unit_dbus_path_from_name(u->id);
4061                 if (!p)
4062                         return log_oom();
4063
4064                 r = show_one(verb, bus, p, show_properties, new_line, ellipsized);
4065                 if (r < 0)
4066                         return r;
4067         }
4068
4069         return 0;
4070 }
4071
4072 static int cat(sd_bus *bus, char **args) {
4073         _cleanup_free_ char *unit = NULL;
4074         _cleanup_strv_free_ char **names = NULL;
4075         char **name;
4076         bool first = true;
4077         int r = 0;
4078
4079         assert(bus);
4080         assert(args);
4081
4082         r = expand_names(bus, args + 1, NULL, &names);
4083         if (r < 0)
4084                 log_error("Failed to expand names: %s", strerror(-r));
4085
4086         pager_open_if_enabled();
4087
4088         STRV_FOREACH(name, names) {
4089                 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4090                 _cleanup_strv_free_ char **dropin_paths = NULL;
4091                 _cleanup_free_ char *fragment_path = NULL;
4092                 char **path;
4093
4094                 unit = unit_dbus_path_from_name(*name);
4095                 if (!unit)
4096                         return log_oom();
4097
4098                 if (need_daemon_reload(bus, *name) > 0)
4099                         log_warning("Unit file of %s changed on disk. Run 'systemctl%s daemon-reload'.",
4100                                     *name, arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
4101
4102                 r = sd_bus_get_property_string(
4103                                 bus,
4104                                 "org.freedesktop.systemd1",
4105                                 unit,
4106                                 "org.freedesktop.systemd1.Unit",
4107                                 "FragmentPath",
4108                                 &error,
4109                                 &fragment_path);
4110                 if (r < 0) {
4111                         log_warning("Failed to get FragmentPath: %s", bus_error_message(&error, r));
4112                         continue;
4113                 }
4114
4115                 r = sd_bus_get_property_strv(
4116                                 bus,
4117                                 "org.freedesktop.systemd1",
4118                                 unit,
4119                                 "org.freedesktop.systemd1.Unit",
4120                                 "DropInPaths",
4121                                 &error,
4122                                 &dropin_paths);
4123                 if (r < 0) {
4124                         log_warning("Failed to get DropInPaths: %s", bus_error_message(&error, r));
4125                         continue;
4126                 }
4127
4128                 if (first)
4129                         first = false;
4130                 else
4131                         puts("");
4132
4133                 if (!isempty(fragment_path)) {
4134                         printf("%s# %s%s\n",
4135                                ansi_highlight_blue(),
4136                                fragment_path,
4137                                ansi_highlight_off());
4138                         fflush(stdout);
4139
4140                         r = sendfile_full(STDOUT_FILENO, fragment_path);
4141                         if (r < 0) {
4142                                 log_warning("Failed to cat %s: %s", fragment_path, strerror(-r));
4143                                 continue;
4144                         }
4145                 }
4146
4147                 STRV_FOREACH(path, dropin_paths) {
4148                         printf("%s%s# %s%s\n",
4149                                isempty(fragment_path) && path == dropin_paths ? "" : "\n",
4150                                ansi_highlight_blue(),
4151                                *path,
4152                                ansi_highlight_off());
4153                         fflush(stdout);
4154
4155                         r = sendfile_full(STDOUT_FILENO, *path);
4156                         if (r < 0) {
4157                                 log_warning("Failed to cat %s: %s", *path, strerror(-r));
4158                                 continue;
4159                         }
4160                 }
4161         }
4162
4163         return r < 0 ? r : 0;
4164 }
4165
4166 static int show_system_status(sd_bus *bus) {
4167         char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], since2[FORMAT_TIMESTAMP_MAX];
4168         _cleanup_free_ char *hn = NULL;
4169         struct machine_info mi = {};
4170         const char *on, *off;
4171         int r;
4172
4173         hn = gethostname_malloc();
4174         if (!hn)
4175                 return log_oom();
4176
4177         r = bus_map_all_properties(bus, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map, &mi);
4178         if (r < 0) {
4179                 log_error("Failed to read server status: %s", strerror(-r));
4180                 return r;
4181         }
4182
4183         if (streq_ptr(mi.state, "degraded")) {
4184                 on = ansi_highlight_red();
4185                 off = ansi_highlight_off();
4186         } else if (!streq_ptr(mi.state, "running")) {
4187                 on = ansi_highlight_yellow();
4188                 off = ansi_highlight_off();
4189         } else
4190                 on = off = "";
4191
4192         printf("%s%s%s%s\n", on, draw_special_char(DRAW_BLACK_CIRCLE), off, arg_host ? arg_host : hn);
4193
4194         printf("    State: %s%s%s\n",
4195                on, strna(mi.state), off);
4196
4197         printf("     Jobs: %u queued\n", mi.n_jobs);
4198         printf("   Failed: %u units\n", mi.n_failed_units);
4199
4200         printf("    Since: %s; %s\n",
4201                format_timestamp(since2, sizeof(since2), mi.timestamp),
4202                format_timestamp_relative(since1, sizeof(since1), mi.timestamp));
4203
4204         printf("   CGroup: %s\n", mi.control_group ?: "/");
4205         if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_CONTAINER) {
4206                 int flags =
4207                         arg_all * OUTPUT_SHOW_ALL |
4208                         (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
4209                         on_tty() * OUTPUT_COLOR |
4210                         !arg_quiet * OUTPUT_WARN_CUTOFF |
4211                         arg_full * OUTPUT_FULL_WIDTH;
4212
4213                 static const char prefix[] = "           ";
4214                 unsigned c;
4215
4216                 c = columns();
4217                 if (c > sizeof(prefix) - 1)
4218                         c -= sizeof(prefix) - 1;
4219                 else
4220                         c = 0;
4221
4222                 show_cgroup(SYSTEMD_CGROUP_CONTROLLER, strempty(mi.control_group), prefix, c, false, flags);
4223         }
4224
4225         free(mi.state);
4226         free(mi.control_group);
4227
4228         return 0;
4229 }
4230
4231 static int show(sd_bus *bus, char **args) {
4232         bool show_properties, show_status, new_line = false;
4233         bool ellipsized = false;
4234         int r, ret = 0;
4235
4236         assert(bus);
4237         assert(args);
4238
4239         show_properties = streq(args[0], "show");
4240         show_status = streq(args[0], "status");
4241
4242         if (show_properties)
4243                 pager_open_if_enabled();
4244
4245         /* If no argument is specified inspect the manager itself */
4246
4247         if (show_properties && strv_length(args) <= 1)
4248                 return show_one(args[0], bus, "/org/freedesktop/systemd1", show_properties, &new_line, &ellipsized);
4249
4250         if (show_status && strv_length(args) <= 1) {
4251
4252                 if (arg_all)
4253                         pager_open_if_enabled();
4254
4255                 show_system_status(bus);
4256                 new_line = true;
4257
4258                 if (arg_all)
4259                         ret = show_all(args[0], bus, false, &new_line, &ellipsized);
4260         } else {
4261                 _cleanup_free_ char **patterns = NULL;
4262                 char **name;
4263
4264                 STRV_FOREACH(name, args + 1) {
4265                         _cleanup_free_ char *unit = NULL;
4266                         uint32_t id;
4267
4268                         if (safe_atou32(*name, &id) < 0) {
4269                                 if (strv_push(&patterns, *name) < 0)
4270                                         return log_oom();
4271
4272                                 continue;
4273                         } else if (show_properties) {
4274                                 /* Interpret as job id */
4275                                 if (asprintf(&unit, "/org/freedesktop/systemd1/job/%u", id) < 0)
4276                                         return log_oom();
4277
4278                         } else {
4279                                 /* Interpret as PID */
4280                                 r = get_unit_dbus_path_by_pid(bus, id, &unit);
4281                                 if (r < 0) {
4282                                         ret = r;
4283                                         continue;
4284                                 }
4285                         }
4286
4287                         show_one(args[0], bus, unit, show_properties, &new_line, &ellipsized);
4288                 }
4289
4290                 if (!strv_isempty(patterns)) {
4291                         _cleanup_strv_free_ char **names = NULL;
4292
4293                         r = expand_names(bus, patterns, NULL, &names);
4294                         if (r < 0)
4295                                 log_error("Failed to expand names: %s", strerror(-r));
4296
4297                         STRV_FOREACH(name, names) {
4298                                 _cleanup_free_ char *unit;
4299
4300                                 unit = unit_dbus_path_from_name(*name);
4301                                 if (!unit)
4302                                         return log_oom();
4303
4304                                 show_one(args[0], bus, unit, show_properties, &new_line, &ellipsized);
4305                         }
4306                 }
4307         }
4308
4309         if (ellipsized && !arg_quiet)
4310                 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
4311
4312         return ret;
4313 }
4314
4315 static int set_property(sd_bus *bus, char **args) {
4316         _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4317         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4318         _cleanup_free_ char *n = NULL;
4319         char **i;
4320         int r;
4321
4322         r = sd_bus_message_new_method_call(
4323                         bus,
4324                         &m,
4325                         "org.freedesktop.systemd1",
4326                         "/org/freedesktop/systemd1",
4327                         "org.freedesktop.systemd1.Manager",
4328                         "SetUnitProperties");
4329         if (r < 0)
4330                 return bus_log_create_error(r);
4331
4332         n = unit_name_mangle(args[1], MANGLE_NOGLOB);
4333         if (!n)
4334                 return log_oom();
4335
4336         r = sd_bus_message_append(m, "sb", n, arg_runtime);
4337         if (r < 0)
4338                 return bus_log_create_error(r);
4339
4340         r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, "(sv)");
4341         if (r < 0)
4342                 return bus_log_create_error(r);
4343
4344         STRV_FOREACH(i, args + 2) {
4345                 r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv");
4346                 if (r < 0)
4347                         return bus_log_create_error(r);
4348
4349                 r = bus_append_unit_property_assignment(m, *i);
4350                 if (r < 0)
4351                         return r;
4352
4353                 r = sd_bus_message_close_container(m);
4354                 if (r < 0)
4355                         return bus_log_create_error(r);
4356         }
4357
4358         r = sd_bus_message_close_container(m);
4359         if (r < 0)
4360                 return bus_log_create_error(r);
4361
4362         r = sd_bus_call(bus, m, 0, &error, NULL);
4363         if (r < 0) {
4364                 log_error("Failed to set unit properties on %s: %s", n, bus_error_message(&error, r));
4365                 return r;
4366         }
4367
4368         return 0;
4369 }
4370
4371 static int snapshot(sd_bus *bus, char **args) {
4372         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4373         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4374         _cleanup_free_ char *n = NULL, *id = NULL;
4375         const char *path;
4376         int r;
4377
4378         if (strv_length(args) > 1)
4379                 n = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".snapshot");
4380         else
4381                 n = strdup("");
4382         if (!n)
4383                 return log_oom();
4384
4385         r = sd_bus_call_method(
4386                         bus,
4387                         "org.freedesktop.systemd1",
4388                         "/org/freedesktop/systemd1",
4389                         "org.freedesktop.systemd1.Manager",
4390                         "CreateSnapshot",
4391                         &error,
4392                         &reply,
4393                         "sb", n, false);
4394         if (r < 0) {
4395                 log_error("Failed to create snapshot: %s", bus_error_message(&error, r));
4396                 return r;
4397         }
4398
4399         r = sd_bus_message_read(reply, "o", &path);
4400         if (r < 0)
4401                 return bus_log_parse_error(r);
4402
4403         r = sd_bus_get_property_string(
4404                         bus,
4405                         "org.freedesktop.systemd1",
4406                         path,
4407                         "org.freedesktop.systemd1.Unit",
4408                         "Id",
4409                         &error,
4410                         &id);
4411         if (r < 0) {
4412                 log_error("Failed to get ID of snapshot: %s", bus_error_message(&error, r));
4413                 return r;
4414         }
4415
4416         if (!arg_quiet)
4417                 puts(id);
4418
4419         return 0;
4420 }
4421
4422 static int delete_snapshot(sd_bus *bus, char **args) {
4423         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4424         _cleanup_strv_free_ char **names = NULL;
4425         char **name;
4426         int r, q;
4427
4428         assert(args);
4429
4430         r = expand_names(bus, args + 1, ".snapshot", &names);
4431         if (r < 0)
4432                 log_error("Failed to expand names: %s", strerror(-r));
4433
4434         STRV_FOREACH(name, names) {
4435                 q = sd_bus_call_method(
4436                                 bus,
4437                                 "org.freedesktop.systemd1",
4438                                 "/org/freedesktop/systemd1",
4439                                 "org.freedesktop.systemd1.Manager",
4440                                 "RemoveSnapshot",
4441                                 &error,
4442                                 NULL,
4443                                 "s", *name);
4444                 if (q < 0) {
4445                         log_error("Failed to remove snapshot %s: %s",
4446                                   *name, bus_error_message(&error, r));
4447                         if (r == 0)
4448                                 r = q;
4449                 }
4450         }
4451
4452         return r;
4453 }
4454
4455 static int daemon_reload(sd_bus *bus, char **args) {
4456         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4457         const char *method;
4458         int r;
4459
4460         if (arg_action == ACTION_RELOAD)
4461                 method = "Reload";
4462         else if (arg_action == ACTION_REEXEC)
4463                 method = "Reexecute";
4464         else {
4465                 assert(arg_action == ACTION_SYSTEMCTL);
4466
4467                 method =
4468                         streq(args[0], "clear-jobs")    ||
4469                         streq(args[0], "cancel")        ? "ClearJobs" :
4470                         streq(args[0], "daemon-reexec") ? "Reexecute" :
4471                         streq(args[0], "reset-failed")  ? "ResetFailed" :
4472                         streq(args[0], "halt")          ? "Halt" :
4473                         streq(args[0], "poweroff")      ? "PowerOff" :
4474                         streq(args[0], "reboot")        ? "Reboot" :
4475                         streq(args[0], "kexec")         ? "KExec" :
4476                         streq(args[0], "exit")          ? "Exit" :
4477                                     /* "daemon-reload" */ "Reload";
4478         }
4479
4480         r = sd_bus_call_method(
4481                         bus,
4482                         "org.freedesktop.systemd1",
4483                         "/org/freedesktop/systemd1",
4484                         "org.freedesktop.systemd1.Manager",
4485                         method,
4486                         &error,
4487                         NULL,
4488                         NULL);
4489
4490         if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
4491                 /* There's always a fallback possible for
4492                  * legacy actions. */
4493                 r = -EADDRNOTAVAIL;
4494         else if ((r == -ETIMEDOUT || r == -ECONNRESET) && streq(method, "Reexecute"))
4495                 /* On reexecution, we expect a disconnect, not a
4496                  * reply */
4497                 r = 0;
4498         else if (r < 0)
4499                 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
4500
4501         return r < 0 ? r : 0;
4502 }
4503
4504 static int reset_failed(sd_bus *bus, char **args) {
4505         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4506         _cleanup_strv_free_ char **names = NULL;
4507         char **name;
4508         int r, q;
4509
4510         if (strv_length(args) <= 1)
4511                 return daemon_reload(bus, args);
4512
4513         r = expand_names(bus, args + 1, NULL, &names);
4514         if (r < 0)
4515                 log_error("Failed to expand names: %s", strerror(-r));
4516
4517         STRV_FOREACH(name, names) {
4518                 q = sd_bus_call_method(
4519                                 bus,
4520                                 "org.freedesktop.systemd1",
4521                                 "/org/freedesktop/systemd1",
4522                                 "org.freedesktop.systemd1.Manager",
4523                                 "ResetFailedUnit",
4524                                 &error,
4525                                 NULL,
4526                                 "s", *name);
4527                 if (q < 0) {
4528                         log_error("Failed to reset failed state of unit %s: %s",
4529                                   *name, bus_error_message(&error, r));
4530                         if (r == 0)
4531                                 r = q;
4532                 }
4533         }
4534
4535         return r;
4536 }
4537
4538 static int show_environment(sd_bus *bus, char **args) {
4539         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4540         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4541         const char *text;
4542         int r;
4543
4544         pager_open_if_enabled();
4545
4546         r = sd_bus_get_property(
4547                         bus,
4548                         "org.freedesktop.systemd1",
4549                         "/org/freedesktop/systemd1",
4550                         "org.freedesktop.systemd1.Manager",
4551                         "Environment",
4552                         &error,
4553                         &reply,
4554                         "as");
4555         if (r < 0) {
4556                 log_error("Failed to get environment: %s", bus_error_message(&error, r));
4557                 return r;
4558         }
4559
4560         r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "s");
4561         if (r < 0)
4562                 return bus_log_parse_error(r);
4563
4564         while ((r = sd_bus_message_read_basic(reply, SD_BUS_TYPE_STRING, &text)) > 0)
4565                 puts(text);
4566         if (r < 0)
4567                 return bus_log_parse_error(r);
4568
4569         r = sd_bus_message_exit_container(reply);
4570         if (r < 0)
4571                 return bus_log_parse_error(r);
4572
4573         return 0;
4574 }
4575
4576 static int switch_root(sd_bus *bus, char **args) {
4577         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4578         _cleanup_free_ char *cmdline_init = NULL;
4579         const char *root, *init;
4580         unsigned l;
4581         int r;
4582
4583         l = strv_length(args);
4584         if (l < 2 || l > 3) {
4585                 log_error("Wrong number of arguments.");
4586                 return -EINVAL;
4587         }
4588
4589         root = args[1];
4590
4591         if (l >= 3)
4592                 init = args[2];
4593         else {
4594                 r = parse_env_file("/proc/cmdline", WHITESPACE,
4595                                    "init", &cmdline_init,
4596                                    NULL);
4597                 if (r < 0)
4598                         log_debug("Failed to parse /proc/cmdline: %s", strerror(-r));
4599
4600                 init = cmdline_init;
4601         }
4602
4603         if (isempty(init))
4604                 init = NULL;
4605
4606         if (init) {
4607                 const char *root_systemd_path = NULL, *root_init_path = NULL;
4608
4609                 root_systemd_path = strappenda(root, "/" SYSTEMD_BINARY_PATH);
4610                 root_init_path = strappenda3(root, "/", init);
4611
4612                 /* If the passed init is actually the same as the
4613                  * systemd binary, then let's suppress it. */
4614                 if (files_same(root_init_path, root_systemd_path) > 0)
4615                         init = NULL;
4616         }
4617
4618         log_debug("Switching root - root: %s; init: %s", root, strna(init));
4619
4620         r = sd_bus_call_method(
4621                         bus,
4622                         "org.freedesktop.systemd1",
4623                         "/org/freedesktop/systemd1",
4624                         "org.freedesktop.systemd1.Manager",
4625                         "SwitchRoot",
4626                         &error,
4627                         NULL,
4628                         "ss", root, init);
4629         if (r < 0) {
4630                 log_error("Failed to switch root: %s", bus_error_message(&error, r));
4631                 return r;
4632         }
4633
4634         return 0;
4635 }
4636
4637 static int set_environment(sd_bus *bus, char **args) {
4638         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4639         _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4640         const char *method;
4641         int r;
4642
4643         assert(bus);
4644         assert(args);
4645
4646         method = streq(args[0], "set-environment")
4647                 ? "SetEnvironment"
4648                 : "UnsetEnvironment";
4649
4650         r = sd_bus_message_new_method_call(
4651                         bus,
4652                         &m,
4653                         "org.freedesktop.systemd1",
4654                         "/org/freedesktop/systemd1",
4655                         "org.freedesktop.systemd1.Manager",
4656                         method);
4657         if (r < 0)
4658                 return bus_log_create_error(r);
4659
4660         r = sd_bus_message_append_strv(m, args + 1);
4661         if (r < 0)
4662                 return bus_log_create_error(r);
4663
4664         r = sd_bus_call(bus, m, 0, &error, NULL);
4665         if (r < 0) {
4666                 log_error("Failed to set environment: %s", bus_error_message(&error, r));
4667                 return r;
4668         }
4669
4670         return 0;
4671 }
4672
4673 static int import_environment(sd_bus *bus, char **args) {
4674         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4675         _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4676         int r;
4677
4678         assert(bus);
4679         assert(args);
4680
4681         r = sd_bus_message_new_method_call(
4682                         bus,
4683                         &m,
4684                         "org.freedesktop.systemd1",
4685                         "/org/freedesktop/systemd1",
4686                         "org.freedesktop.systemd1.Manager",
4687                         "SetEnvironment");
4688         if (r < 0)
4689                 return bus_log_create_error(r);
4690
4691         if (strv_isempty(args + 1))
4692                 r = sd_bus_message_append_strv(m, environ);
4693         else {
4694                 char **a, **b;
4695
4696                 r = sd_bus_message_open_container(m, 'a', "s");
4697                 if (r < 0)
4698                         return bus_log_create_error(r);
4699
4700                 STRV_FOREACH(a, args + 1) {
4701
4702                         if (!env_name_is_valid(*a)) {
4703                                 log_error("Not a valid environment variable name: %s", *a);
4704                                 return -EINVAL;
4705                         }
4706
4707                         STRV_FOREACH(b, environ) {
4708                                 const char *eq;
4709
4710                                 eq = startswith(*b, *a);
4711                                 if (eq && *eq == '=') {
4712
4713                                         r = sd_bus_message_append(m, "s", *b);
4714                                         if (r < 0)
4715                                                 return bus_log_create_error(r);
4716
4717                                         break;
4718                                 }
4719                         }
4720                 }
4721
4722                 r = sd_bus_message_close_container(m);
4723         }
4724         if (r < 0)
4725                 return bus_log_create_error(r);
4726
4727         r = sd_bus_call(bus, m, 0, &error, NULL);
4728         if (r < 0) {
4729                 log_error("Failed to import environment: %s", bus_error_message(&error, r));
4730                 return r;
4731         }
4732
4733         return 0;
4734 }
4735
4736 static int enable_sysv_units(const char *verb, char **args) {
4737         int r = 0;
4738
4739 #if defined(HAVE_SYSV_COMPAT) && defined(HAVE_CHKCONFIG)
4740         unsigned f = 1, t = 1;
4741         _cleanup_lookup_paths_free_ LookupPaths paths = {};
4742
4743         if (arg_scope != UNIT_FILE_SYSTEM)
4744                 return 0;
4745
4746         if (!streq(verb, "enable") &&
4747             !streq(verb, "disable") &&
4748             !streq(verb, "is-enabled"))
4749                 return 0;
4750
4751         /* Processes all SysV units, and reshuffles the array so that
4752          * afterwards only the native units remain */
4753
4754         r = lookup_paths_init(&paths, SYSTEMD_SYSTEM, false, NULL, NULL, NULL);
4755         if (r < 0)
4756                 return r;
4757
4758         r = 0;
4759         for (f = 0; args[f]; f++) {
4760                 const char *name;
4761                 _cleanup_free_ char *p = NULL, *q = NULL;
4762                 bool found_native = false, found_sysv;
4763                 unsigned c = 1;
4764                 const char *argv[6] = { "/sbin/chkconfig", NULL, NULL, NULL, NULL };
4765                 char **k, *l;
4766                 int j;
4767                 pid_t pid;
4768                 siginfo_t status;
4769
4770                 name = args[f];
4771
4772                 if (!endswith(name, ".service"))
4773                         continue;
4774
4775                 if (path_is_absolute(name))
4776                         continue;
4777
4778                 STRV_FOREACH(k, paths.unit_path) {
4779                         if (!isempty(arg_root))
4780                                 asprintf(&p, "%s/%s/%s", arg_root, *k, name);
4781                         else
4782                                 asprintf(&p, "%s/%s", *k, name);
4783
4784                         if (!p) {
4785                                 r = log_oom();
4786                                 goto finish;
4787                         }
4788
4789                         found_native = access(p, F_OK) >= 0;
4790                         free(p);
4791                         p = NULL;
4792
4793                         if (found_native)
4794                                 break;
4795                 }
4796
4797                 if (found_native)
4798                         continue;
4799
4800                 if (!isempty(arg_root))
4801                         asprintf(&p, "%s/" SYSTEM_SYSVINIT_PATH "/%s", arg_root, name);
4802                 else
4803                         asprintf(&p, SYSTEM_SYSVINIT_PATH "/%s", name);
4804                 if (!p) {
4805                         r = log_oom();
4806                         goto finish;
4807                 }
4808
4809                 p[strlen(p) - sizeof(".service") + 1] = 0;
4810                 found_sysv = access(p, F_OK) >= 0;
4811
4812                 if (!found_sysv)
4813                         continue;
4814
4815                 /* Mark this entry, so that we don't try enabling it as native unit */
4816                 args[f] = (char*) "";
4817
4818                 log_info("%s is not a native service, redirecting to /sbin/chkconfig.", name);
4819
4820                 if (!isempty(arg_root))
4821                         argv[c++] = q = strappend("--root=", arg_root);
4822
4823                 argv[c++] = basename(p);
4824                 argv[c++] =
4825                         streq(verb, "enable") ? "on" :
4826                         streq(verb, "disable") ? "off" : "--level=5";
4827                 argv[c] = NULL;
4828
4829                 l = strv_join((char**)argv, " ");
4830                 if (!l) {
4831                         r = log_oom();
4832                         goto finish;
4833                 }
4834
4835                 log_info("Executing %s", l);
4836                 free(l);
4837
4838                 pid = fork();
4839                 if (pid < 0) {
4840                         log_error("Failed to fork: %m");
4841                         r = -errno;
4842                         goto finish;
4843                 } else if (pid == 0) {
4844                         /* Child */
4845
4846                         execv(argv[0], (char**) argv);
4847                         _exit(EXIT_FAILURE);
4848                 }
4849
4850                 j = wait_for_terminate(pid, &status);
4851                 if (j < 0) {
4852                         log_error("Failed to wait for child: %s", strerror(-r));
4853                         r = j;
4854                         goto finish;
4855                 }
4856
4857                 if (status.si_code == CLD_EXITED) {
4858                         if (streq(verb, "is-enabled")) {
4859                                 if (status.si_status == 0) {
4860                                         if (!arg_quiet)
4861                                                 puts("enabled");
4862                                         r = 1;
4863                                 } else {
4864                                         if (!arg_quiet)
4865                                                 puts("disabled");
4866                                 }
4867
4868                         } else if (status.si_status != 0) {
4869                                 r = -EINVAL;
4870                                 goto finish;
4871                         }
4872                 } else {
4873                         r = -EPROTO;
4874                         goto finish;
4875                 }
4876         }
4877
4878 finish:
4879         /* Drop all SysV units */
4880         for (f = 0, t = 0; args[f]; f++) {
4881
4882                 if (isempty(args[f]))
4883                         continue;
4884
4885                 args[t++] = args[f];
4886         }
4887
4888         args[t] = NULL;
4889
4890 #endif
4891         return r;
4892 }
4893
4894 static int mangle_names(char **original_names, char ***mangled_names) {
4895         char **i, **l, **name;
4896
4897         l = new(char*, strv_length(original_names) + 1);
4898         if (!l)
4899                 return log_oom();
4900
4901         i = l;
4902         STRV_FOREACH(name, original_names) {
4903
4904                 /* When enabling units qualified path names are OK,
4905                  * too, hence allow them explicitly. */
4906
4907                 if (is_path(*name))
4908                         *i = strdup(*name);
4909                 else
4910                         *i = unit_name_mangle(*name, MANGLE_NOGLOB);
4911
4912                 if (!*i) {
4913                         strv_free(l);
4914                         return log_oom();
4915                 }
4916
4917                 i++;
4918         }
4919
4920         *i = NULL;
4921         *mangled_names = l;
4922
4923         return 0;
4924 }
4925
4926 static int enable_unit(sd_bus *bus, char **args) {
4927         _cleanup_strv_free_ char **names = NULL;
4928         const char *verb = args[0];
4929         UnitFileChange *changes = NULL;
4930         unsigned n_changes = 0;
4931         int carries_install_info = -1;
4932         int r;
4933
4934         if (!args[1])
4935                 return 0;
4936
4937         r = mangle_names(args+1, &names);
4938         if (r < 0)
4939                 return r;
4940
4941         r = enable_sysv_units(verb, names);
4942         if (r < 0)
4943                 return r;
4944
4945         /* If the operation was fully executed by the SysV compat,
4946          * let's finish early */
4947         if (strv_isempty(names))
4948                 return 0;
4949
4950         if (!bus || avoid_bus()) {
4951                 if (streq(verb, "enable")) {
4952                         r = unit_file_enable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
4953                         carries_install_info = r;
4954                 } else if (streq(verb, "disable"))
4955                         r = unit_file_disable(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
4956                 else if (streq(verb, "reenable")) {
4957                         r = unit_file_reenable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
4958                         carries_install_info = r;
4959                 } else if (streq(verb, "link"))
4960                         r = unit_file_link(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
4961                 else if (streq(verb, "preset")) {
4962                         r = unit_file_preset(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
4963                         carries_install_info = r;
4964                 } else if (streq(verb, "mask"))
4965                         r = unit_file_mask(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
4966                 else if (streq(verb, "unmask"))
4967                         r = unit_file_unmask(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
4968                 else
4969                         assert_not_reached("Unknown verb");
4970
4971                 if (r < 0) {
4972                         log_error("Operation failed: %s", strerror(-r));
4973                         goto finish;
4974                 }
4975
4976                 if (!arg_quiet)
4977                         dump_unit_file_changes(changes, n_changes);
4978
4979                 r = 0;
4980         } else {
4981                 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
4982                 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4983                 int expect_carries_install_info = false;
4984                 bool send_force = true;
4985                 const char *method;
4986
4987                 if (streq(verb, "enable")) {
4988                         method = "EnableUnitFiles";
4989                         expect_carries_install_info = true;
4990                 } else if (streq(verb, "disable")) {
4991                         method = "DisableUnitFiles";
4992                         send_force = false;
4993                 } else if (streq(verb, "reenable")) {
4994                         method = "ReenableUnitFiles";
4995                         expect_carries_install_info = true;
4996                 } else if (streq(verb, "link"))
4997                         method = "LinkUnitFiles";
4998                 else if (streq(verb, "preset")) {
4999                         method = "PresetUnitFiles";
5000                         expect_carries_install_info = true;
5001                 } else if (streq(verb, "mask"))
5002                         method = "MaskUnitFiles";
5003                 else if (streq(verb, "unmask")) {
5004                         method = "UnmaskUnitFiles";
5005                         send_force = false;
5006                 } else
5007                         assert_not_reached("Unknown verb");
5008
5009                 r = sd_bus_message_new_method_call(
5010                                 bus,
5011                                 &m,
5012                                 "org.freedesktop.systemd1",
5013                                 "/org/freedesktop/systemd1",
5014                                 "org.freedesktop.systemd1.Manager",
5015                                 method);
5016                 if (r < 0)
5017                         return bus_log_create_error(r);
5018
5019                 r = sd_bus_message_append_strv(m, names);
5020                 if (r < 0)
5021                         return bus_log_create_error(r);
5022
5023                 r = sd_bus_message_append(m, "b", arg_runtime);
5024                 if (r < 0)
5025                         return bus_log_create_error(r);
5026
5027                 if (send_force) {
5028                         r = sd_bus_message_append(m, "b", arg_force);
5029                         if (r < 0)
5030                                 return bus_log_create_error(r);
5031                 }
5032
5033                 r = sd_bus_call(bus, m, 0, &error, &reply);
5034                 if (r < 0) {
5035                         log_error("Failed to execute operation: %s", bus_error_message(&error, r));
5036                         return r;
5037                 }
5038
5039                 if (expect_carries_install_info) {
5040                         r = sd_bus_message_read(reply, "b", &carries_install_info);
5041                         if (r < 0)
5042                                 return bus_log_parse_error(r);
5043                 }
5044
5045                 r = deserialize_and_dump_unit_file_changes(reply);
5046                 if (r < 0)
5047                         return r;
5048
5049                 /* Try to reload if enabeld */
5050                 if (!arg_no_reload)
5051                         r = daemon_reload(bus, args);
5052                 else
5053                         r = 0;
5054         }
5055
5056         if (carries_install_info == 0)
5057                 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
5058                             "using systemctl.\n"
5059                             "Possible reasons for having this kind of units are:\n"
5060                             "1) A unit may be statically enabled by being symlinked from another unit's\n"
5061                             "   .wants/ or .requires/ directory.\n"
5062                             "2) A unit's purpose may be to act as a helper for some other unit which has\n"
5063                             "   a requirement dependency on it.\n"
5064                             "3) A unit may be started when needed via activation (socket, path, timer,\n"
5065                             "   D-Bus, udev, scripted systemctl call, ...).\n");
5066
5067 finish:
5068         unit_file_changes_free(changes, n_changes);
5069
5070         return r;
5071 }
5072
5073 static int unit_is_enabled(sd_bus *bus, char **args) {
5074
5075         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5076         _cleanup_strv_free_ char **names = NULL;
5077         bool enabled;
5078         char **name;
5079         int r;
5080
5081         r = mangle_names(args+1, &names);
5082         if (r < 0)
5083                 return r;
5084
5085         r = enable_sysv_units(args[0], names);
5086         if (r < 0)
5087                 return r;
5088
5089         enabled = r > 0;
5090
5091         if (!bus || avoid_bus()) {
5092
5093                 STRV_FOREACH(name, names) {
5094                         UnitFileState state;
5095
5096                         state = unit_file_get_state(arg_scope, arg_root, *name);
5097                         if (state < 0) {
5098                                 log_error("Failed to get unit file state for %s: %s", *name, strerror(-state));
5099                                 return state;
5100                         }
5101
5102                         if (state == UNIT_FILE_ENABLED ||
5103                             state == UNIT_FILE_ENABLED_RUNTIME ||
5104                             state == UNIT_FILE_STATIC)
5105                                 enabled = true;
5106
5107                         if (!arg_quiet)
5108                                 puts(unit_file_state_to_string(state));
5109                 }
5110
5111         } else {
5112                 STRV_FOREACH(name, names) {
5113                         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
5114                         const char *s;
5115
5116                         r = sd_bus_call_method(
5117                                         bus,
5118                                         "org.freedesktop.systemd1",
5119                                         "/org/freedesktop/systemd1",
5120                                         "org.freedesktop.systemd1.Manager",
5121                                         "GetUnitFileState",
5122                                         &error,
5123                                         &reply,
5124                                         "s", *name);
5125                         if (r < 0) {
5126                                 log_error("Failed to get unit file state for %s: %s", *name, bus_error_message(&error, r));
5127                                 return r;
5128                         }
5129
5130                         r = sd_bus_message_read(reply, "s", &s);
5131                         if (r < 0)
5132                                 return bus_log_parse_error(r);
5133
5134                         if (streq(s, "enabled") ||
5135                             streq(s, "enabled-runtime") ||
5136                             streq(s, "static"))
5137                                 enabled = true;
5138
5139                         if (!arg_quiet)
5140                                 puts(s);
5141                 }
5142         }
5143
5144         return !enabled;
5145 }
5146
5147 static int systemctl_help(void) {
5148
5149         pager_open_if_enabled();
5150
5151         printf("%s [OPTIONS...] {COMMAND} ...\n\n"
5152                "Query or send control commands to the systemd manager.\n\n"
5153                "  -h --help           Show this help\n"
5154                "     --version        Show package version\n"
5155                "     --system         Connect to system manager\n"
5156                "     --user           Connect to user service manager\n"
5157                "  -H --host=[USER@]HOST\n"
5158                "                      Operate on remote host\n"
5159                "  -M --machine=CONTAINER\n"
5160                "                      Operate on local container\n"
5161                "  -t --type=TYPE      List only units of a particular type\n"
5162                "     --state=STATE    List only units with particular LOAD or SUB or ACTIVE state\n"
5163                "  -p --property=NAME  Show only properties by this name\n"
5164                "  -a --all            Show all loaded units/properties, including dead/empty\n"
5165                "                      ones. To list all units installed on the system, use\n"
5166                "                      the 'list-unit-files' command instead.\n"
5167                "  -l --full           Don't ellipsize unit names on output\n"
5168                "     --reverse        Show reverse dependencies with 'list-dependencies'\n"
5169                "     --job-mode=MODE  Specify how to deal with already queued jobs, when\n"
5170                "                      queueing a new job\n"
5171                "     --show-types     When showing sockets, explicitly show their type\n"
5172                "  -i --ignore-inhibitors\n"
5173                "                      When shutting down or sleeping, ignore inhibitors\n"
5174                "     --kill-who=WHO   Who to send signal to\n"
5175                "  -s --signal=SIGNAL  Which signal to send\n"
5176                "  -q --quiet          Suppress output\n"
5177                "     --no-block       Do not wait until operation finished\n"
5178                "     --no-wall        Don't send wall message before halt/power-off/reboot\n"
5179                "     --no-reload      When enabling/disabling unit files, don't reload daemon\n"
5180                "                      configuration\n"
5181                "     --no-legend      Do not print a legend (column headers and hints)\n"
5182                "     --no-pager       Do not pipe output into a pager\n"
5183                "     --no-ask-password\n"
5184                "                      Do not ask for system passwords\n"
5185                "     --global         Enable/disable unit files globally\n"
5186                "     --runtime        Enable unit files only temporarily until next reboot\n"
5187                "  -f --force          When enabling unit files, override existing symlinks\n"
5188                "                      When shutting down, execute action immediately\n"
5189                "     --root=PATH      Enable unit files in the specified root directory\n"
5190                "  -n --lines=INTEGER  Number of journal entries to show\n"
5191                "  -o --output=STRING  Change journal output mode (short, short-monotonic,\n"
5192                "                      verbose, export, json, json-pretty, json-sse, cat)\n"
5193                "     --plain          Print unit dependencies as a list instead of a tree\n\n"
5194                "Unit Commands:\n"
5195                "  list-units [PATTERN...]         List loaded units\n"
5196                "  list-sockets [PATTERN...]       List loaded sockets ordered by address\n"
5197                "  list-timers [PATTERN...]        List loaded timers ordered by next elapse\n"
5198                "  start NAME...                   Start (activate) one or more units\n"
5199                "  stop NAME...                    Stop (deactivate) one or more units\n"
5200                "  reload NAME...                  Reload one or more units\n"
5201                "  restart NAME...                 Start or restart one or more units\n"
5202                "  try-restart NAME...             Restart one or more units if active\n"
5203                "  reload-or-restart NAME...       Reload one or more units if possible,\n"
5204                "                                  otherwise start or restart\n"
5205                "  reload-or-try-restart NAME...   Reload one or more units if possible,\n"
5206                "                                  otherwise restart if active\n"
5207                "  isolate NAME                    Start one unit and stop all others\n"
5208                "  kill NAME...                    Send signal to processes of a unit\n"
5209                "  is-active NAME...               Check whether units are active\n"
5210                "  is-failed NAME...               Check whether units are failed\n"
5211                "  status [NAME...|PID...]         Show runtime status of one or more units\n"
5212                "  show [NAME...|JOB...]           Show properties of one or more\n"
5213                "                                  units/jobs or the manager\n"
5214                "  cat NAME...                     Show files and drop-ins of one or more units\n"
5215                "  set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
5216                "  help NAME...|PID...             Show manual for one or more units\n"
5217                "  reset-failed [NAME...]          Reset failed state for all, one, or more\n"
5218                "                                  units\n"
5219                "  list-dependencies [NAME]        Recursively show units which are required\n"
5220                "                                  or wanted by this unit or by which this\n"
5221                "                                  unit is required or wanted\n\n"
5222                "Unit File Commands:\n"
5223                "  list-unit-files [PATTERN...]    List installed unit files\n"
5224                "  enable NAME...                  Enable one or more unit files\n"
5225                "  disable NAME...                 Disable one or more unit files\n"
5226                "  reenable NAME...                Reenable one or more unit files\n"
5227                "  preset NAME...                  Enable/disable one or more unit files\n"
5228                "                                  based on preset configuration\n"
5229                "  is-enabled NAME...              Check whether unit files are enabled\n\n"
5230                "  mask NAME...                    Mask one or more units\n"
5231                "  unmask NAME...                  Unmask one or more units\n"
5232                "  link PATH...                    Link one or more units files into\n"
5233                "                                  the search path\n"
5234                "  get-default                     Get the name of the default target\n"
5235                "  set-default NAME                Set the default target\n\n"
5236                "Machine Commands:\n"
5237                "  list-machines [PATTERN...]      List local containers and host\n\n"
5238                "Job Commands:\n"
5239                "  list-jobs [PATTERN...]          List jobs\n"
5240                "  cancel [JOB...]                 Cancel all, one, or more jobs\n\n"
5241                "Snapshot Commands:\n"
5242                "  snapshot [NAME]                 Create a snapshot\n"
5243                "  delete NAME...                  Remove one or more snapshots\n\n"
5244                "Environment Commands:\n"
5245                "  show-environment                Dump environment\n"
5246                "  set-environment NAME=VALUE...   Set one or more environment variables\n"
5247                "  unset-environment NAME...       Unset one or more environment variables\n"
5248                "  import-environment NAME...      Import all, one or more environment variables\n\n"
5249                "Manager Lifecycle Commands:\n"
5250                "  daemon-reload                   Reload systemd manager configuration\n"
5251                "  daemon-reexec                   Reexecute systemd manager\n\n"
5252                "System Commands:\n"
5253                "  default                         Enter system default mode\n"
5254                "  rescue                          Enter system rescue mode\n"
5255                "  emergency                       Enter system emergency mode\n"
5256                "  halt                            Shut down and halt the system\n"
5257                "  poweroff                        Shut down and power-off the system\n"
5258                "  reboot [ARG]                    Shut down and reboot the system\n"
5259                "  kexec                           Shut down and reboot the system with kexec\n"
5260                "  exit                            Request user instance exit\n"
5261                "  switch-root ROOT [INIT]         Change to a different root file system\n"
5262                "  suspend                         Suspend the system\n"
5263                "  hibernate                       Hibernate the system\n"
5264                "  hybrid-sleep                    Hibernate and suspend the system\n",
5265                program_invocation_short_name);
5266
5267         return 0;
5268 }
5269
5270 static int halt_help(void) {
5271
5272         printf("%s [OPTIONS...]%s\n\n"
5273                "%s the system.\n\n"
5274                "     --help      Show this help\n"
5275                "     --halt      Halt the machine\n"
5276                "  -p --poweroff  Switch off the machine\n"
5277                "     --reboot    Reboot the machine\n"
5278                "  -f --force     Force immediate halt/power-off/reboot\n"
5279                "  -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
5280                "  -d --no-wtmp   Don't write wtmp record\n"
5281                "     --no-wall   Don't send wall message before halt/power-off/reboot\n",
5282                program_invocation_short_name,
5283                arg_action == ACTION_REBOOT   ? " [ARG]" : "",
5284                arg_action == ACTION_REBOOT   ? "Reboot" :
5285                arg_action == ACTION_POWEROFF ? "Power off" :
5286                                                "Halt");
5287
5288         return 0;
5289 }
5290
5291 static int shutdown_help(void) {
5292
5293         printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
5294                "Shut down the system.\n\n"
5295                "     --help      Show this help\n"
5296                "  -H --halt      Halt the machine\n"
5297                "  -P --poweroff  Power-off the machine\n"
5298                "  -r --reboot    Reboot the machine\n"
5299                "  -h             Equivalent to --poweroff, overridden by --halt\n"
5300                "  -k             Don't halt/power-off/reboot, just send warnings\n"
5301                "     --no-wall   Don't send wall message before halt/power-off/reboot\n"
5302                "  -c             Cancel a pending shutdown\n",
5303                program_invocation_short_name);
5304
5305         return 0;
5306 }
5307
5308 static int telinit_help(void) {
5309
5310         printf("%s [OPTIONS...] {COMMAND}\n\n"
5311                "Send control commands to the init daemon.\n\n"
5312                "     --help      Show this help\n"
5313                "     --no-wall   Don't send wall message before halt/power-off/reboot\n\n"
5314                "Commands:\n"
5315                "  0              Power-off the machine\n"
5316                "  6              Reboot the machine\n"
5317                "  2, 3, 4, 5     Start runlevelX.target unit\n"
5318                "  1, s, S        Enter rescue mode\n"
5319                "  q, Q           Reload init daemon configuration\n"
5320                "  u, U           Reexecute init daemon\n",
5321                program_invocation_short_name);
5322
5323         return 0;
5324 }
5325
5326 static int runlevel_help(void) {
5327
5328         printf("%s [OPTIONS...]\n\n"
5329                "Prints the previous and current runlevel of the init system.\n\n"
5330                "     --help      Show this help\n",
5331                program_invocation_short_name);
5332
5333         return 0;
5334 }
5335
5336 static int help_types(void) {
5337         int i;
5338         const char *t;
5339
5340         puts("Available unit types:");
5341         for (i = 0; i < _UNIT_TYPE_MAX; i++) {
5342                 t = unit_type_to_string(i);
5343                 if (t)
5344                         puts(t);
5345         }
5346
5347         return 0;
5348 }
5349
5350 static int systemctl_parse_argv(int argc, char *argv[]) {
5351
5352         enum {
5353                 ARG_FAIL = 0x100,
5354                 ARG_REVERSE,
5355                 ARG_AFTER,
5356                 ARG_BEFORE,
5357                 ARG_SHOW_TYPES,
5358                 ARG_IRREVERSIBLE,
5359                 ARG_IGNORE_DEPENDENCIES,
5360                 ARG_VERSION,
5361                 ARG_USER,
5362                 ARG_SYSTEM,
5363                 ARG_GLOBAL,
5364                 ARG_NO_BLOCK,
5365                 ARG_NO_LEGEND,
5366                 ARG_NO_PAGER,
5367                 ARG_NO_WALL,
5368                 ARG_ROOT,
5369                 ARG_NO_RELOAD,
5370                 ARG_KILL_WHO,
5371                 ARG_NO_ASK_PASSWORD,
5372                 ARG_FAILED,
5373                 ARG_RUNTIME,
5374                 ARG_FORCE,
5375                 ARG_PLAIN,
5376                 ARG_STATE,
5377                 ARG_JOB_MODE
5378         };
5379
5380         static const struct option options[] = {
5381                 { "help",                no_argument,       NULL, 'h'                     },
5382                 { "version",             no_argument,       NULL, ARG_VERSION             },
5383                 { "type",                required_argument, NULL, 't'                     },
5384                 { "property",            required_argument, NULL, 'p'                     },
5385                 { "all",                 no_argument,       NULL, 'a'                     },
5386                 { "reverse",             no_argument,       NULL, ARG_REVERSE             },
5387                 { "after",               no_argument,       NULL, ARG_AFTER               },
5388                 { "before",              no_argument,       NULL, ARG_BEFORE              },
5389                 { "show-types",          no_argument,       NULL, ARG_SHOW_TYPES          },
5390                 { "failed",              no_argument,       NULL, ARG_FAILED              }, /* compatibility only */
5391                 { "full",                no_argument,       NULL, 'l'                     },
5392                 { "job-mode",            required_argument, NULL, ARG_JOB_MODE            },
5393                 { "fail",                no_argument,       NULL, ARG_FAIL                }, /* compatibility only */
5394                 { "irreversible",        no_argument,       NULL, ARG_IRREVERSIBLE        }, /* compatibility only */
5395                 { "ignore-dependencies", no_argument,       NULL, ARG_IGNORE_DEPENDENCIES }, /* compatibility only */
5396                 { "ignore-inhibitors",   no_argument,       NULL, 'i'                     },
5397                 { "user",                no_argument,       NULL, ARG_USER                },
5398                 { "system",              no_argument,       NULL, ARG_SYSTEM              },
5399                 { "global",              no_argument,       NULL, ARG_GLOBAL              },
5400                 { "no-block",            no_argument,       NULL, ARG_NO_BLOCK            },
5401                 { "no-legend",           no_argument,       NULL, ARG_NO_LEGEND           },
5402                 { "no-pager",            no_argument,       NULL, ARG_NO_PAGER            },
5403                 { "no-wall",             no_argument,       NULL, ARG_NO_WALL             },
5404                 { "quiet",               no_argument,       NULL, 'q'                     },
5405                 { "root",                required_argument, NULL, ARG_ROOT                },
5406                 { "force",               no_argument,       NULL, ARG_FORCE               },
5407                 { "no-reload",           no_argument,       NULL, ARG_NO_RELOAD           },
5408                 { "kill-who",            required_argument, NULL, ARG_KILL_WHO            },
5409                 { "signal",              required_argument, NULL, 's'                     },
5410                 { "no-ask-password",     no_argument,       NULL, ARG_NO_ASK_PASSWORD     },
5411                 { "host",                required_argument, NULL, 'H'                     },
5412                 { "machine",             required_argument, NULL, 'M'                     },
5413                 { "runtime",             no_argument,       NULL, ARG_RUNTIME             },
5414                 { "lines",               required_argument, NULL, 'n'                     },
5415                 { "output",              required_argument, NULL, 'o'                     },
5416                 { "plain",               no_argument,       NULL, ARG_PLAIN               },
5417                 { "state",               required_argument, NULL, ARG_STATE               },
5418                 {}
5419         };
5420
5421         int c;
5422
5423         assert(argc >= 0);
5424         assert(argv);
5425
5426         while ((c = getopt_long(argc, argv, "ht:p:alqfs:H:M:n:o:i", options, NULL)) >= 0) {
5427
5428                 switch (c) {
5429
5430                 case 'h':
5431                         return systemctl_help();
5432
5433                 case ARG_VERSION:
5434                         puts(PACKAGE_STRING);
5435                         puts(SYSTEMD_FEATURES);
5436                         return 0;
5437
5438                 case 't': {
5439                         char *word, *state;
5440                         size_t size;
5441
5442                         FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
5443                                 _cleanup_free_ char *type;
5444
5445                                 type = strndup(word, size);
5446                                 if (!type)
5447                                         return -ENOMEM;
5448
5449                                 if (streq(type, "help")) {
5450                                         help_types();
5451                                         return 0;
5452                                 }
5453
5454                                 if (unit_type_from_string(type) >= 0) {
5455                                         if (strv_push(&arg_types, type))
5456                                                 return log_oom();
5457                                         type = NULL;
5458                                         continue;
5459                                 }
5460
5461                                 /* It's much nicer to use --state= for
5462                                  * load states, but let's support this
5463                                  * in --types= too for compatibility
5464                                  * with old versions */
5465                                 if (unit_load_state_from_string(optarg) >= 0) {
5466                                         if (strv_push(&arg_states, type) < 0)
5467                                                 return log_oom();
5468                                         type = NULL;
5469                                         continue;
5470                                 }
5471
5472                                 log_error("Unknown unit type or load state '%s'.", type);
5473                                 log_info("Use -t help to see a list of allowed values.");
5474                                 return -EINVAL;
5475                         }
5476
5477                         break;
5478                 }
5479
5480                 case 'p': {
5481                         /* Make sure that if the empty property list
5482                            was specified, we won't show any properties. */
5483                         if (isempty(optarg) && !arg_properties) {
5484                                 arg_properties = new0(char*, 1);
5485                                 if (!arg_properties)
5486                                         return log_oom();
5487                         } else {
5488                                 char *word, *state;
5489                                 size_t size;
5490
5491                                 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
5492                                         char *prop;
5493
5494                                         prop = strndup(word, size);
5495                                         if (!prop)
5496                                                 return log_oom();
5497
5498                                         if (strv_consume(&arg_properties, prop) < 0)
5499                                                 return log_oom();
5500                                 }
5501                         }
5502
5503                         /* If the user asked for a particular
5504                          * property, show it to him, even if it is
5505                          * empty. */
5506                         arg_all = true;
5507
5508                         break;
5509                 }
5510
5511                 case 'a':
5512                         arg_all = true;
5513                         break;
5514
5515                 case ARG_REVERSE:
5516                         arg_dependency = DEPENDENCY_REVERSE;
5517                         break;
5518
5519                 case ARG_AFTER:
5520                         arg_dependency = DEPENDENCY_AFTER;
5521                         break;
5522
5523                 case ARG_BEFORE:
5524                         arg_dependency = DEPENDENCY_BEFORE;
5525                         break;
5526
5527                 case ARG_SHOW_TYPES:
5528                         arg_show_types = true;
5529                         break;
5530
5531                 case ARG_JOB_MODE:
5532                         arg_job_mode = optarg;
5533                         break;
5534
5535                 case ARG_FAIL:
5536                         arg_job_mode = "fail";
5537                         break;
5538
5539                 case ARG_IRREVERSIBLE:
5540                         arg_job_mode = "replace-irreversibly";
5541                         break;
5542
5543                 case ARG_IGNORE_DEPENDENCIES:
5544                         arg_job_mode = "ignore-dependencies";
5545                         break;
5546
5547                 case ARG_USER:
5548                         arg_scope = UNIT_FILE_USER;
5549                         break;
5550
5551                 case ARG_SYSTEM:
5552                         arg_scope = UNIT_FILE_SYSTEM;
5553                         break;
5554
5555                 case ARG_GLOBAL:
5556                         arg_scope = UNIT_FILE_GLOBAL;
5557                         break;
5558
5559                 case ARG_NO_BLOCK:
5560                         arg_no_block = true;
5561                         break;
5562
5563                 case ARG_NO_LEGEND:
5564                         arg_no_legend = true;
5565                         break;
5566
5567                 case ARG_NO_PAGER:
5568                         arg_no_pager = true;
5569                         break;
5570
5571                 case ARG_NO_WALL:
5572                         arg_no_wall = true;
5573                         break;
5574
5575                 case ARG_ROOT:
5576                         arg_root = optarg;
5577                         break;
5578
5579                 case 'l':
5580                         arg_full = true;
5581                         break;
5582
5583                 case ARG_FAILED:
5584                         if (strv_extend(&arg_states, "failed") < 0)
5585                                 return log_oom();
5586
5587                         break;
5588
5589                 case 'q':
5590                         arg_quiet = true;
5591                         break;
5592
5593                 case ARG_FORCE:
5594                         arg_force ++;
5595                         break;
5596
5597                 case 'f':
5598                         arg_force ++;
5599                         break;
5600
5601                 case ARG_NO_RELOAD:
5602                         arg_no_reload = true;
5603                         break;
5604
5605                 case ARG_KILL_WHO:
5606                         arg_kill_who = optarg;
5607                         break;
5608
5609                 case 's':
5610                         if ((arg_signal = signal_from_string_try_harder(optarg)) < 0) {
5611                                 log_error("Failed to parse signal string %s.", optarg);
5612                                 return -EINVAL;
5613                         }
5614                         break;
5615
5616                 case ARG_NO_ASK_PASSWORD:
5617                         arg_ask_password = false;
5618                         break;
5619
5620                 case 'H':
5621                         arg_transport = BUS_TRANSPORT_REMOTE;
5622                         arg_host = optarg;
5623                         break;
5624
5625                 case 'M':
5626                         arg_transport = BUS_TRANSPORT_CONTAINER;
5627                         arg_host = optarg;
5628                         break;
5629
5630                 case ARG_RUNTIME:
5631                         arg_runtime = true;
5632                         break;
5633
5634                 case 'n':
5635                         if (safe_atou(optarg, &arg_lines) < 0) {
5636                                 log_error("Failed to parse lines '%s'", optarg);
5637                                 return -EINVAL;
5638                         }
5639                         break;
5640
5641                 case 'o':
5642                         arg_output = output_mode_from_string(optarg);
5643                         if (arg_output < 0) {
5644                                 log_error("Unknown output '%s'.", optarg);
5645                                 return -EINVAL;
5646                         }
5647                         break;
5648
5649                 case 'i':
5650                         arg_ignore_inhibitors = true;
5651                         break;
5652
5653                 case ARG_PLAIN:
5654                         arg_plain = true;
5655                         break;
5656
5657                 case ARG_STATE: {
5658                         char *word, *state;
5659                         size_t size;
5660
5661                         FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
5662                                 char *s;
5663
5664                                 s = strndup(word, size);
5665                                 if (!s)
5666                                         return log_oom();
5667
5668                                 if (strv_consume(&arg_states, s) < 0)
5669                                         return log_oom();
5670                         }
5671                         break;
5672                 }
5673
5674                 case '?':
5675                         return -EINVAL;
5676
5677                 default:
5678                         assert_not_reached("Unhandled option");
5679                 }
5680         }
5681
5682         if (arg_transport != BUS_TRANSPORT_LOCAL && arg_scope != UNIT_FILE_SYSTEM) {
5683                 log_error("Cannot access user instance remotely.");
5684                 return -EINVAL;
5685         }
5686
5687         return 1;
5688 }
5689
5690 static int halt_parse_argv(int argc, char *argv[]) {
5691
5692         enum {
5693                 ARG_HELP = 0x100,
5694                 ARG_HALT,
5695                 ARG_REBOOT,
5696                 ARG_NO_WALL
5697         };
5698
5699         static const struct option options[] = {
5700                 { "help",      no_argument,       NULL, ARG_HELP    },
5701                 { "halt",      no_argument,       NULL, ARG_HALT    },
5702                 { "poweroff",  no_argument,       NULL, 'p'         },
5703                 { "reboot",    no_argument,       NULL, ARG_REBOOT  },
5704                 { "force",     no_argument,       NULL, 'f'         },
5705                 { "wtmp-only", no_argument,       NULL, 'w'         },
5706                 { "no-wtmp",   no_argument,       NULL, 'd'         },
5707                 { "no-wall",   no_argument,       NULL, ARG_NO_WALL },
5708                 {}
5709         };
5710
5711         int c, r, runlevel;
5712
5713         assert(argc >= 0);
5714         assert(argv);
5715
5716         if (utmp_get_runlevel(&runlevel, NULL) >= 0)
5717                 if (runlevel == '0' || runlevel == '6')
5718                         arg_force = 2;
5719
5720         while ((c = getopt_long(argc, argv, "pfwdnih", options, NULL)) >= 0) {
5721                 switch (c) {
5722
5723                 case ARG_HELP:
5724                         return halt_help();
5725
5726                 case ARG_HALT:
5727                         arg_action = ACTION_HALT;
5728                         break;
5729
5730                 case 'p':
5731                         if (arg_action != ACTION_REBOOT)
5732                                 arg_action = ACTION_POWEROFF;
5733                         break;
5734
5735                 case ARG_REBOOT:
5736                         arg_action = ACTION_REBOOT;
5737                         break;
5738
5739                 case 'f':
5740                         arg_force = 2;
5741                         break;
5742
5743                 case 'w':
5744                         arg_dry = true;
5745                         break;
5746
5747                 case 'd':
5748                         arg_no_wtmp = true;
5749                         break;
5750
5751                 case ARG_NO_WALL:
5752                         arg_no_wall = true;
5753                         break;
5754
5755                 case 'i':
5756                 case 'h':
5757                 case 'n':
5758                         /* Compatibility nops */
5759                         break;
5760
5761                 case '?':
5762                         return -EINVAL;
5763
5764                 default:
5765                         assert_not_reached("Unhandled option");
5766                 }
5767         }
5768
5769         if (arg_action == ACTION_REBOOT && argc == optind + 1) {
5770                 r = write_string_file(REBOOT_PARAM_FILE, argv[optind]);
5771                 if (r < 0) {
5772                         log_error("Failed to write reboot param to "
5773                                   REBOOT_PARAM_FILE": %s", strerror(-r));
5774                         return r;
5775                 }
5776         } else if (optind < argc) {
5777                 log_error("Too many arguments.");
5778                 return -EINVAL;
5779         }
5780
5781         return 1;
5782 }
5783
5784 static int parse_time_spec(const char *t, usec_t *_u) {
5785         assert(t);
5786         assert(_u);
5787
5788         if (streq(t, "now"))
5789                 *_u = 0;
5790         else if (!strchr(t, ':')) {
5791                 uint64_t u;
5792
5793                 if (safe_atou64(t, &u) < 0)
5794                         return -EINVAL;
5795
5796                 *_u = now(CLOCK_REALTIME) + USEC_PER_MINUTE * u;
5797         } else {
5798                 char *e = NULL;
5799                 long hour, minute;
5800                 struct tm tm = {};
5801                 time_t s;
5802                 usec_t n;
5803
5804                 errno = 0;
5805                 hour = strtol(t, &e, 10);
5806                 if (errno > 0 || *e != ':' || hour < 0 || hour > 23)
5807                         return -EINVAL;
5808
5809                 minute = strtol(e+1, &e, 10);
5810                 if (errno > 0 || *e != 0 || minute < 0 || minute > 59)
5811                         return -EINVAL;
5812
5813                 n = now(CLOCK_REALTIME);
5814                 s = (time_t) (n / USEC_PER_SEC);
5815
5816                 assert_se(localtime_r(&s, &tm));
5817
5818                 tm.tm_hour = (int) hour;
5819                 tm.tm_min = (int) minute;
5820                 tm.tm_sec = 0;
5821
5822                 assert_se(s = mktime(&tm));
5823
5824                 *_u = (usec_t) s * USEC_PER_SEC;
5825
5826                 while (*_u <= n)
5827                         *_u += USEC_PER_DAY;
5828         }
5829
5830         return 0;
5831 }
5832
5833 static int shutdown_parse_argv(int argc, char *argv[]) {
5834
5835         enum {
5836                 ARG_HELP = 0x100,
5837                 ARG_NO_WALL
5838         };
5839
5840         static const struct option options[] = {
5841                 { "help",      no_argument,       NULL, ARG_HELP    },
5842                 { "halt",      no_argument,       NULL, 'H'         },
5843                 { "poweroff",  no_argument,       NULL, 'P'         },
5844                 { "reboot",    no_argument,       NULL, 'r'         },
5845                 { "kexec",     no_argument,       NULL, 'K'         }, /* not documented extension */
5846                 { "no-wall",   no_argument,       NULL, ARG_NO_WALL },
5847                 {}
5848         };
5849
5850         int c, r;
5851
5852         assert(argc >= 0);
5853         assert(argv);
5854
5855         while ((c = getopt_long(argc, argv, "HPrhkt:afFc", options, NULL)) >= 0) {
5856                 switch (c) {
5857
5858                 case ARG_HELP:
5859                         return shutdown_help();
5860
5861                 case 'H':
5862                         arg_action = ACTION_HALT;
5863                         break;
5864
5865                 case 'P':
5866                         arg_action = ACTION_POWEROFF;
5867                         break;
5868
5869                 case 'r':
5870                         if (kexec_loaded())
5871                                 arg_action = ACTION_KEXEC;
5872                         else
5873                                 arg_action = ACTION_REBOOT;
5874                         break;
5875
5876                 case 'K':
5877                         arg_action = ACTION_KEXEC;
5878                         break;
5879
5880                 case 'h':
5881                         if (arg_action != ACTION_HALT)
5882                                 arg_action = ACTION_POWEROFF;
5883                         break;
5884
5885                 case 'k':
5886                         arg_dry = true;
5887                         break;
5888
5889                 case ARG_NO_WALL:
5890                         arg_no_wall = true;
5891                         break;
5892
5893                 case 't':
5894                 case 'a':
5895                         /* Compatibility nops */
5896                         break;
5897
5898                 case 'c':
5899                         arg_action = ACTION_CANCEL_SHUTDOWN;
5900                         break;
5901
5902                 case '?':
5903                         return -EINVAL;
5904
5905                 default:
5906                         assert_not_reached("Unhandled option");
5907                 }
5908         }
5909
5910         if (argc > optind && arg_action != ACTION_CANCEL_SHUTDOWN) {
5911                 r = parse_time_spec(argv[optind], &arg_when);
5912                 if (r < 0) {
5913                         log_error("Failed to parse time specification: %s", argv[optind]);
5914                         return r;
5915                 }
5916         } else
5917                 arg_when = now(CLOCK_REALTIME) + USEC_PER_MINUTE;
5918
5919         if (argc > optind && arg_action == ACTION_CANCEL_SHUTDOWN)
5920                 /* No time argument for shutdown cancel */
5921                 arg_wall = argv + optind;
5922         else if (argc > optind + 1)
5923                 /* We skip the time argument */
5924                 arg_wall = argv + optind + 1;
5925
5926         optind = argc;
5927
5928         return 1;
5929 }
5930
5931 static int telinit_parse_argv(int argc, char *argv[]) {
5932
5933         enum {
5934                 ARG_HELP = 0x100,
5935                 ARG_NO_WALL
5936         };
5937
5938         static const struct option options[] = {
5939                 { "help",      no_argument,       NULL, ARG_HELP    },
5940                 { "no-wall",   no_argument,       NULL, ARG_NO_WALL },
5941                 {}
5942         };
5943
5944         static const struct {
5945                 char from;
5946                 enum action to;
5947         } table[] = {
5948                 { '0', ACTION_POWEROFF },
5949                 { '6', ACTION_REBOOT },
5950                 { '1', ACTION_RESCUE },
5951                 { '2', ACTION_RUNLEVEL2 },
5952                 { '3', ACTION_RUNLEVEL3 },
5953                 { '4', ACTION_RUNLEVEL4 },
5954                 { '5', ACTION_RUNLEVEL5 },
5955                 { 's', ACTION_RESCUE },
5956                 { 'S', ACTION_RESCUE },
5957                 { 'q', ACTION_RELOAD },
5958                 { 'Q', ACTION_RELOAD },
5959                 { 'u', ACTION_REEXEC },
5960                 { 'U', ACTION_REEXEC }
5961         };
5962
5963         unsigned i;
5964         int c;
5965
5966         assert(argc >= 0);
5967         assert(argv);
5968
5969         while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0) {
5970                 switch (c) {
5971
5972                 case ARG_HELP:
5973                         return telinit_help();
5974
5975                 case ARG_NO_WALL:
5976                         arg_no_wall = true;
5977                         break;
5978
5979                 case '?':
5980                         return -EINVAL;
5981
5982                 default:
5983                         assert_not_reached("Unhandled option");
5984                 }
5985         }
5986
5987         if (optind >= argc) {
5988                 telinit_help();
5989                 return -EINVAL;
5990         }
5991
5992         if (optind + 1 < argc) {
5993                 log_error("Too many arguments.");
5994                 return -EINVAL;
5995         }
5996
5997         if (strlen(argv[optind]) != 1) {
5998                 log_error("Expected single character argument.");
5999                 return -EINVAL;
6000         }
6001
6002         for (i = 0; i < ELEMENTSOF(table); i++)
6003                 if (table[i].from == argv[optind][0])
6004                         break;
6005
6006         if (i >= ELEMENTSOF(table)) {
6007                 log_error("Unknown command '%s'.", argv[optind]);
6008                 return -EINVAL;
6009         }
6010
6011         arg_action = table[i].to;
6012
6013         optind ++;
6014
6015         return 1;
6016 }
6017
6018 static int runlevel_parse_argv(int argc, char *argv[]) {
6019
6020         enum {
6021                 ARG_HELP = 0x100,
6022         };
6023
6024         static const struct option options[] = {
6025                 { "help",      no_argument,       NULL, ARG_HELP    },
6026                 {}
6027         };
6028
6029         int c;
6030
6031         assert(argc >= 0);
6032         assert(argv);
6033
6034         while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0) {
6035                 switch (c) {
6036
6037                 case ARG_HELP:
6038                         return runlevel_help();
6039
6040                 case '?':
6041                         return -EINVAL;
6042
6043                 default:
6044                         assert_not_reached("Unhandled option");
6045                 }
6046         }
6047
6048         if (optind < argc) {
6049                 log_error("Too many arguments.");
6050                 return -EINVAL;
6051         }
6052
6053         return 1;
6054 }
6055
6056 static int parse_argv(int argc, char *argv[]) {
6057         assert(argc >= 0);
6058         assert(argv);
6059
6060         if (program_invocation_short_name) {
6061
6062                 if (strstr(program_invocation_short_name, "halt")) {
6063                         arg_action = ACTION_HALT;
6064                         return halt_parse_argv(argc, argv);
6065                 } else if (strstr(program_invocation_short_name, "poweroff")) {
6066                         arg_action = ACTION_POWEROFF;
6067                         return halt_parse_argv(argc, argv);
6068                 } else if (strstr(program_invocation_short_name, "reboot")) {
6069                         if (kexec_loaded())
6070                                 arg_action = ACTION_KEXEC;
6071                         else
6072                                 arg_action = ACTION_REBOOT;
6073                         return halt_parse_argv(argc, argv);
6074                 } else if (strstr(program_invocation_short_name, "shutdown")) {
6075                         arg_action = ACTION_POWEROFF;
6076                         return shutdown_parse_argv(argc, argv);
6077                 } else if (strstr(program_invocation_short_name, "init")) {
6078
6079                         if (sd_booted() > 0) {
6080                                 arg_action = _ACTION_INVALID;
6081                                 return telinit_parse_argv(argc, argv);
6082                         } else {
6083                                 /* Hmm, so some other init system is
6084                                  * running, we need to forward this
6085                                  * request to it. For now we simply
6086                                  * guess that it is Upstart. */
6087
6088                                 execv(TELINIT, argv);
6089
6090                                 log_error("Couldn't find an alternative telinit implementation to spawn.");
6091                                 return -EIO;
6092                         }
6093
6094                 } else if (strstr(program_invocation_short_name, "runlevel")) {
6095                         arg_action = ACTION_RUNLEVEL;
6096                         return runlevel_parse_argv(argc, argv);
6097                 }
6098         }
6099
6100         arg_action = ACTION_SYSTEMCTL;
6101         return systemctl_parse_argv(argc, argv);
6102 }
6103
6104 _pure_ static int action_to_runlevel(void) {
6105
6106         static const char table[_ACTION_MAX] = {
6107                 [ACTION_HALT] =      '0',
6108                 [ACTION_POWEROFF] =  '0',
6109                 [ACTION_REBOOT] =    '6',
6110                 [ACTION_RUNLEVEL2] = '2',
6111                 [ACTION_RUNLEVEL3] = '3',
6112                 [ACTION_RUNLEVEL4] = '4',
6113                 [ACTION_RUNLEVEL5] = '5',
6114                 [ACTION_RESCUE] =    '1'
6115         };
6116
6117         assert(arg_action < _ACTION_MAX);
6118
6119         return table[arg_action];
6120 }
6121
6122 static int talk_initctl(void) {
6123
6124         struct init_request request = {
6125                 .magic = INIT_MAGIC,
6126                 .sleeptime  = 0,
6127                 .cmd = INIT_CMD_RUNLVL
6128         };
6129
6130         _cleanup_close_ int fd = -1;
6131         char rl;
6132         int r;
6133
6134         rl = action_to_runlevel();
6135         if (!rl)
6136                 return 0;
6137
6138         request.runlevel = rl;
6139
6140         fd = open(INIT_FIFO, O_WRONLY|O_NDELAY|O_CLOEXEC|O_NOCTTY);
6141         if (fd < 0) {
6142                 if (errno == ENOENT)
6143                         return 0;
6144
6145                 log_error("Failed to open "INIT_FIFO": %m");
6146                 return -errno;
6147         }
6148
6149         errno = 0;
6150         r = loop_write(fd, &request, sizeof(request), false) != sizeof(request);
6151         if (r) {
6152                 log_error("Failed to write to "INIT_FIFO": %m");
6153                 return errno > 0 ? -errno : -EIO;
6154         }
6155
6156         return 1;
6157 }
6158
6159 static int systemctl_main(sd_bus *bus, int argc, char *argv[], int bus_error) {
6160
6161         static const struct {
6162                 const char* verb;
6163                 const enum {
6164                         MORE,
6165                         LESS,
6166                         EQUAL
6167                 } argc_cmp;
6168                 const int argc;
6169                 int (* const dispatch)(sd_bus *bus, char **args);
6170                 const enum {
6171                         NOBUS = 1,
6172                         FORCE,
6173                 } bus;
6174         } verbs[] = {
6175                 { "list-units",            MORE,  0, list_units        },
6176                 { "list-unit-files",       MORE,  1, list_unit_files,  NOBUS },
6177                 { "list-sockets",          MORE,  1, list_sockets      },
6178                 { "list-timers",           MORE,  1, list_timers       },
6179                 { "list-jobs",             MORE,  1, list_jobs         },
6180                 { "list-machines",         MORE,  1, list_machines     },
6181                 { "clear-jobs",            EQUAL, 1, daemon_reload     },
6182                 { "cancel",                MORE,  2, cancel_job        },
6183                 { "start",                 MORE,  2, start_unit        },
6184                 { "stop",                  MORE,  2, start_unit        },
6185                 { "condstop",              MORE,  2, start_unit        }, /* For compatibility with ALTLinux */
6186                 { "reload",                MORE,  2, start_unit        },
6187                 { "restart",               MORE,  2, start_unit        },
6188                 { "try-restart",           MORE,  2, start_unit        },
6189                 { "reload-or-restart",     MORE,  2, start_unit        },
6190                 { "reload-or-try-restart", MORE,  2, start_unit        },
6191                 { "force-reload",          MORE,  2, start_unit        }, /* For compatibility with SysV */
6192                 { "condreload",            MORE,  2, start_unit        }, /* For compatibility with ALTLinux */
6193                 { "condrestart",           MORE,  2, start_unit        }, /* For compatibility with RH */
6194                 { "isolate",               EQUAL, 2, start_unit        },
6195                 { "kill",                  MORE,  2, kill_unit         },
6196                 { "is-active",             MORE,  2, check_unit_active },
6197                 { "check",                 MORE,  2, check_unit_active },
6198                 { "is-failed",             MORE,  2, check_unit_failed },
6199                 { "show",                  MORE,  1, show              },
6200                 { "cat",                   MORE,  2, cat               },
6201                 { "status",                MORE,  1, show              },
6202                 { "help",                  MORE,  2, show              },
6203                 { "snapshot",              LESS,  2, snapshot          },
6204                 { "delete",                MORE,  2, delete_snapshot   },
6205                 { "daemon-reload",         EQUAL, 1, daemon_reload     },
6206                 { "daemon-reexec",         EQUAL, 1, daemon_reload     },
6207                 { "show-environment",      EQUAL, 1, show_environment  },
6208                 { "set-environment",       MORE,  2, set_environment   },
6209                 { "unset-environment",     MORE,  2, set_environment   },
6210                 { "import-environment",    MORE,  1, import_environment},
6211                 { "halt",                  EQUAL, 1, start_special,    FORCE },
6212                 { "poweroff",              EQUAL, 1, start_special,    FORCE },
6213                 { "reboot",                EQUAL, 1, start_special,    FORCE },
6214                 { "kexec",                 EQUAL, 1, start_special     },
6215                 { "suspend",               EQUAL, 1, start_special     },
6216                 { "hibernate",             EQUAL, 1, start_special     },
6217                 { "hybrid-sleep",          EQUAL, 1, start_special     },
6218                 { "default",               EQUAL, 1, start_special     },
6219                 { "rescue",                EQUAL, 1, start_special     },
6220                 { "emergency",             EQUAL, 1, start_special     },
6221                 { "exit",                  EQUAL, 1, start_special     },
6222                 { "reset-failed",          MORE,  1, reset_failed      },
6223                 { "enable",                MORE,  2, enable_unit,      NOBUS },
6224                 { "disable",               MORE,  2, enable_unit,      NOBUS },
6225                 { "is-enabled",            MORE,  2, unit_is_enabled,  NOBUS },
6226                 { "reenable",              MORE,  2, enable_unit,      NOBUS },
6227                 { "preset",                MORE,  2, enable_unit,      NOBUS },
6228                 { "mask",                  MORE,  2, enable_unit,      NOBUS },
6229                 { "unmask",                MORE,  2, enable_unit,      NOBUS },
6230                 { "link",                  MORE,  2, enable_unit,      NOBUS },
6231                 { "switch-root",           MORE,  2, switch_root       },
6232                 { "list-dependencies",     LESS,  2, list_dependencies },
6233                 { "set-default",           EQUAL, 2, set_default,      NOBUS },
6234                 { "get-default",           EQUAL, 1, get_default,      NOBUS },
6235                 { "set-property",          MORE,  3, set_property      },
6236                 {}
6237         }, *verb = verbs;
6238
6239         int left;
6240
6241         assert(argc >= 0);
6242         assert(argv);
6243
6244         left = argc - optind;
6245
6246         /* Special rule: no arguments (left == 0) means "list-units" */
6247         if (left > 0) {
6248                 if (streq(argv[optind], "help") && !argv[optind+1]) {
6249                         log_error("This command expects one or more "
6250                                   "unit names. Did you mean --help?");
6251                         return -EINVAL;
6252                 }
6253
6254                 for (; verb->verb; verb++)
6255                         if (streq(argv[optind], verb->verb))
6256                                 goto found;
6257
6258                 log_error("Unknown operation '%s'.", argv[optind]);
6259                 return -EINVAL;
6260         }
6261 found:
6262
6263         switch (verb->argc_cmp) {
6264
6265         case EQUAL:
6266                 if (left != verb->argc) {
6267                         log_error("Invalid number of arguments.");
6268                         return -EINVAL;
6269                 }
6270
6271                 break;
6272
6273         case MORE:
6274                 if (left < verb->argc) {
6275                         log_error("Too few arguments.");
6276                         return -EINVAL;
6277                 }
6278
6279                 break;
6280
6281         case LESS:
6282                 if (left > verb->argc) {
6283                         log_error("Too many arguments.");
6284                         return -EINVAL;
6285                 }
6286
6287                 break;
6288
6289         default:
6290                 assert_not_reached("Unknown comparison operator.");
6291         }
6292
6293         /* Require a bus connection for all operations but
6294          * enable/disable */
6295         if (verb->bus == NOBUS) {
6296                 if (!bus && !avoid_bus()) {
6297                         log_error("Failed to get D-Bus connection: %s", strerror(-bus_error));
6298                         return -EIO;
6299                 }
6300
6301         } else {
6302                 if (running_in_chroot() > 0) {
6303                         log_info("Running in chroot, ignoring request.");
6304                         return 0;
6305                 }
6306
6307                 if ((verb->bus != FORCE || arg_force <= 0) && !bus) {
6308                         log_error("Failed to get D-Bus connection: %s", strerror(-bus_error));
6309                         return -EIO;
6310                 }
6311         }
6312
6313         return verb->dispatch(bus, argv + optind);
6314 }
6315
6316 static int send_shutdownd(usec_t t, char mode, bool dry_run, bool warn, const char *message) {
6317
6318         struct sd_shutdown_command c = {
6319                 .usec = t,
6320                 .mode = mode,
6321                 .dry_run = dry_run,
6322                 .warn_wall = warn,
6323         };
6324
6325         union sockaddr_union sockaddr = {
6326                 .un.sun_family = AF_UNIX,
6327                 .un.sun_path = "/run/systemd/shutdownd",
6328         };
6329
6330         struct iovec iovec[2] = {{
6331                  .iov_base = (char*) &c,
6332                  .iov_len = offsetof(struct sd_shutdown_command, wall_message),
6333         }};
6334
6335         struct msghdr msghdr = {
6336                 .msg_name = &sockaddr,
6337                 .msg_namelen = offsetof(struct sockaddr_un, sun_path)
6338                                + sizeof("/run/systemd/shutdownd") - 1,
6339                 .msg_iov = iovec,
6340                 .msg_iovlen = 1,
6341         };
6342
6343         _cleanup_close_ int fd;
6344
6345         fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
6346         if (fd < 0)
6347                 return -errno;
6348
6349         if (!isempty(message)) {
6350                 iovec[1].iov_base = (char*) message;
6351                 iovec[1].iov_len = strlen(message);
6352                 msghdr.msg_iovlen++;
6353         }
6354
6355         if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) < 0)
6356                 return -errno;
6357
6358         return 0;
6359 }
6360
6361 static int reload_with_fallback(sd_bus *bus) {
6362
6363         if (bus) {
6364                 /* First, try systemd via D-Bus. */
6365                 if (daemon_reload(bus, NULL) >= 0)
6366                         return 0;
6367         }
6368
6369         /* Nothing else worked, so let's try signals */
6370         assert(arg_action == ACTION_RELOAD || arg_action == ACTION_REEXEC);
6371
6372         if (kill(1, arg_action == ACTION_RELOAD ? SIGHUP : SIGTERM) < 0) {
6373                 log_error("kill() failed: %m");
6374                 return -errno;
6375         }
6376
6377         return 0;
6378 }
6379
6380 static int start_with_fallback(sd_bus *bus) {
6381
6382         if (bus) {
6383                 /* First, try systemd via D-Bus. */
6384                 if (start_unit(bus, NULL) >= 0)
6385                         goto done;
6386         }
6387
6388         /* Nothing else worked, so let's try
6389          * /dev/initctl */
6390         if (talk_initctl() > 0)
6391                 goto done;
6392
6393         log_error("Failed to talk to init daemon.");
6394         return -EIO;
6395
6396 done:
6397         warn_wall(arg_action);
6398         return 0;
6399 }
6400
6401 static int halt_now(enum action a) {
6402
6403 /* Make sure C-A-D is handled by the kernel from this
6404          * point on... */
6405         reboot(RB_ENABLE_CAD);
6406
6407         switch (a) {
6408
6409         case ACTION_HALT:
6410                 log_info("Halting.");
6411                 reboot(RB_HALT_SYSTEM);
6412                 return -errno;
6413
6414         case ACTION_POWEROFF:
6415                 log_info("Powering off.");
6416                 reboot(RB_POWER_OFF);
6417                 return -errno;
6418
6419         case ACTION_REBOOT: {
6420                 _cleanup_free_ char *param = NULL;
6421
6422                 if (read_one_line_file(REBOOT_PARAM_FILE, &param) >= 0) {
6423                         log_info("Rebooting with argument '%s'.", param);
6424                         syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
6425                                 LINUX_REBOOT_CMD_RESTART2, param);
6426                 }
6427
6428                 log_info("Rebooting.");
6429                 reboot(RB_AUTOBOOT);
6430                 return -errno;
6431         }
6432
6433         default:
6434                 assert_not_reached("Unknown action.");
6435         }
6436 }
6437
6438 static int halt_main(sd_bus *bus) {
6439         int r;
6440
6441         r = check_inhibitors(bus, arg_action);
6442         if (r < 0)
6443                 return r;
6444
6445         if (geteuid() != 0) {
6446                 /* Try logind if we are a normal user and no special
6447                  * mode applies. Maybe PolicyKit allows us to shutdown
6448                  * the machine. */
6449
6450                 if (arg_when <= 0 &&
6451                     !arg_dry &&
6452                     arg_force <= 0 &&
6453                     (arg_action == ACTION_POWEROFF ||
6454                      arg_action == ACTION_REBOOT)) {
6455                         r = reboot_with_logind(bus, arg_action);
6456                         if (r >= 0)
6457                                 return r;
6458                 }
6459
6460                 log_error("Must be root.");
6461                 return -EPERM;
6462         }
6463
6464         if (arg_when > 0) {
6465                 _cleanup_free_ char *m;
6466
6467                 m = strv_join(arg_wall, " ");
6468                 if (!m)
6469                         return log_oom();
6470
6471                 r = send_shutdownd(arg_when,
6472                                    arg_action == ACTION_HALT     ? 'H' :
6473                                    arg_action == ACTION_POWEROFF ? 'P' :
6474                                    arg_action == ACTION_KEXEC    ? 'K' :
6475                                                                    'r',
6476                                    arg_dry,
6477                                    !arg_no_wall,
6478                                    m);
6479
6480                 if (r < 0)
6481                         log_warning("Failed to talk to shutdownd, proceeding with immediate shutdown: %s", strerror(-r));
6482                 else {
6483                         char date[FORMAT_TIMESTAMP_MAX];
6484
6485                         log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.",
6486                                  format_timestamp(date, sizeof(date), arg_when));
6487                         return 0;
6488                 }
6489         }
6490
6491         if (!arg_dry && !arg_force)
6492                 return start_with_fallback(bus);
6493
6494         if (!arg_no_wtmp) {
6495                 if (sd_booted() > 0)
6496                         log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
6497                 else {
6498                         r = utmp_put_shutdown();
6499                         if (r < 0)
6500                                 log_warning("Failed to write utmp record: %s", strerror(-r));
6501                 }
6502         }
6503
6504         if (arg_dry)
6505                 return 0;
6506
6507         r = halt_now(arg_action);
6508         log_error("Failed to reboot: %s", strerror(-r));
6509
6510         return r;
6511 }
6512
6513 static int runlevel_main(void) {
6514         int r, runlevel, previous;
6515
6516         r = utmp_get_runlevel(&runlevel, &previous);
6517         if (r < 0) {
6518                 puts("unknown");
6519                 return r;
6520         }
6521
6522         printf("%c %c\n",
6523                previous <= 0 ? 'N' : previous,
6524                runlevel <= 0 ? 'N' : runlevel);
6525
6526         return 0;
6527 }
6528
6529 int main(int argc, char*argv[]) {
6530         _cleanup_bus_unref_ sd_bus *bus = NULL;
6531         int r;
6532
6533         setlocale(LC_ALL, "");
6534         log_parse_environment();
6535         log_open();
6536
6537         /* Explicitly not on_tty() to avoid setting cached value.
6538          * This becomes relevant for piping output which might be
6539          * ellipsized. */
6540         original_stdout_is_tty = isatty(STDOUT_FILENO);
6541
6542         r = parse_argv(argc, argv);
6543         if (r <= 0)
6544                 goto finish;
6545
6546         /* /sbin/runlevel doesn't need to communicate via D-Bus, so
6547          * let's shortcut this */
6548         if (arg_action == ACTION_RUNLEVEL) {
6549                 r = runlevel_main();
6550                 goto finish;
6551         }
6552
6553         if (running_in_chroot() > 0 && arg_action != ACTION_SYSTEMCTL) {
6554                 log_info("Running in chroot, ignoring request.");
6555                 r = 0;
6556                 goto finish;
6557         }
6558
6559         if (!avoid_bus())
6560                 r = bus_open_transport_systemd(arg_transport, arg_host, arg_scope != UNIT_FILE_SYSTEM, &bus);
6561
6562         /* systemctl_main() will print an error message for the bus
6563          * connection, but only if it needs to */
6564
6565         switch (arg_action) {
6566
6567         case ACTION_SYSTEMCTL:
6568                 r = systemctl_main(bus, argc, argv, r);
6569                 break;
6570
6571         case ACTION_HALT:
6572         case ACTION_POWEROFF:
6573         case ACTION_REBOOT:
6574         case ACTION_KEXEC:
6575                 r = halt_main(bus);
6576                 break;
6577
6578         case ACTION_RUNLEVEL2:
6579         case ACTION_RUNLEVEL3:
6580         case ACTION_RUNLEVEL4:
6581         case ACTION_RUNLEVEL5:
6582         case ACTION_RESCUE:
6583         case ACTION_EMERGENCY:
6584         case ACTION_DEFAULT:
6585                 r = start_with_fallback(bus);
6586                 break;
6587
6588         case ACTION_RELOAD:
6589         case ACTION_REEXEC:
6590                 r = reload_with_fallback(bus);
6591                 break;
6592
6593         case ACTION_CANCEL_SHUTDOWN: {
6594                 _cleanup_free_ char *m = NULL;
6595
6596                 if (arg_wall) {
6597                         m = strv_join(arg_wall, " ");
6598                         if (!m) {
6599                                 r = log_oom();
6600                                 goto finish;
6601                         }
6602                 }
6603
6604                 r = send_shutdownd(arg_when, SD_SHUTDOWN_NONE, false, !arg_no_wall, m);
6605                 if (r < 0)
6606                         log_warning("Failed to talk to shutdownd, shutdown hasn't been cancelled: %s", strerror(-r));
6607                 break;
6608         }
6609
6610         case ACTION_RUNLEVEL:
6611         case _ACTION_INVALID:
6612         default:
6613                 assert_not_reached("Unknown action");
6614         }
6615
6616 finish:
6617         pager_close();
6618         ask_password_agent_close();
6619         polkit_agent_close();
6620
6621         strv_free(arg_types);
6622         strv_free(arg_states);
6623         strv_free(arg_properties);
6624
6625         return r < 0 ? EXIT_FAILURE : r;
6626 }