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