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