chiark / gitweb /
b9d9b3aa961e8ace832a607d5a842a655f0c6aac
[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 (!bus || avoid_bus()) {
4744                 if (streq(verb, "enable")) {
4745                         r = unit_file_enable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
4746                         carries_install_info = r;
4747                 } else if (streq(verb, "disable"))
4748                         r = unit_file_disable(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
4749                 else if (streq(verb, "reenable")) {
4750                         r = unit_file_reenable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
4751                         carries_install_info = r;
4752                 } else if (streq(verb, "link"))
4753                         r = unit_file_link(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
4754                 else if (streq(verb, "preset")) {
4755                         r = unit_file_preset(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
4756                         carries_install_info = r;
4757                 } else if (streq(verb, "mask"))
4758                         r = unit_file_mask(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
4759                 else if (streq(verb, "unmask"))
4760                         r = unit_file_unmask(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
4761                 else
4762                         assert_not_reached("Unknown verb");
4763
4764                 if (r < 0) {
4765                         log_error("Operation failed: %s", strerror(-r));
4766                         goto finish;
4767                 }
4768
4769                 if (!arg_quiet)
4770                         dump_unit_file_changes(changes, n_changes);
4771
4772                 r = 0;
4773         } else {
4774                 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
4775                 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4776                 int expect_carries_install_info = false;
4777                 bool send_force = true;
4778                 const char *method;
4779
4780                 if (streq(verb, "enable")) {
4781                         method = "EnableUnitFiles";
4782                         expect_carries_install_info = true;
4783                 } else if (streq(verb, "disable")) {
4784                         method = "DisableUnitFiles";
4785                         send_force = false;
4786                 } else if (streq(verb, "reenable")) {
4787                         method = "ReenableUnitFiles";
4788                         expect_carries_install_info = true;
4789                 } else if (streq(verb, "link"))
4790                         method = "LinkUnitFiles";
4791                 else if (streq(verb, "preset")) {
4792                         method = "PresetUnitFiles";
4793                         expect_carries_install_info = true;
4794                 } else if (streq(verb, "mask"))
4795                         method = "MaskUnitFiles";
4796                 else if (streq(verb, "unmask")) {
4797                         method = "UnmaskUnitFiles";
4798                         send_force = false;
4799                 } else
4800                         assert_not_reached("Unknown verb");
4801
4802                 r = sd_bus_message_new_method_call(
4803                                 bus,
4804                                 "org.freedesktop.systemd1",
4805                                 "/org/freedesktop/systemd1",
4806                                 "org.freedesktop.systemd1.Manager",
4807                                 method,
4808                                 &m);
4809                 if (r < 0)
4810                         return bus_log_create_error(r);
4811
4812                 r = sd_bus_message_append_strv(m, names);
4813                 if (r < 0)
4814                         return bus_log_create_error(r);
4815
4816                 r = sd_bus_message_append(m, "b", arg_runtime);
4817                 if (r < 0)
4818                         return bus_log_create_error(r);
4819
4820                 if (send_force) {
4821                         r = sd_bus_message_append(m, "b", arg_force);
4822                         if (r < 0)
4823                                 return bus_log_create_error(r);
4824                 }
4825
4826                 r = sd_bus_call(bus, m, 0, &error, &reply);
4827                 if (r < 0) {
4828                         log_error("Failed to execute operation: %s", bus_error_message(&error, r));
4829                         return r;
4830                 }
4831
4832                 if (expect_carries_install_info) {
4833                         r = sd_bus_message_read(reply, "b", &carries_install_info);
4834                         if (r < 0)
4835                                 return bus_log_parse_error(r);
4836                 }
4837
4838                 r = deserialize_and_dump_unit_file_changes(reply);
4839                 if (r < 0)
4840                         return r;
4841
4842                 /* Try to reload if enabeld */
4843                 if (!arg_no_reload)
4844                         r = daemon_reload(bus, args);
4845                 else
4846                         r = 0;
4847         }
4848
4849         if (carries_install_info == 0)
4850                 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
4851                             "using systemctl.\n"
4852                             "Possible reasons for having this kind of units are:\n"
4853                             "1) A unit may be statically enabled by being symlinked from another unit's\n"
4854                             "   .wants/ or .requires/ directory.\n"
4855                             "2) A unit's purpose may be to act as a helper for some other unit which has\n"
4856                             "   a requirement dependency on it.\n"
4857                             "3) A unit may be started when needed via activation (socket, path, timer,\n"
4858                             "   D-Bus, udev, scripted systemctl call, ...).\n");
4859
4860 finish:
4861         unit_file_changes_free(changes, n_changes);
4862
4863         return r;
4864 }
4865
4866 static int unit_is_enabled(sd_bus *bus, char **args) {
4867
4868         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4869         _cleanup_strv_free_ char **names = NULL;
4870         bool enabled;
4871         char **name;
4872         int r;
4873
4874         r = mangle_names(args+1, &names);
4875         if (r < 0)
4876                 return r;
4877
4878         r = enable_sysv_units(args[0], names);
4879         if (r < 0)
4880                 return r;
4881
4882         enabled = r > 0;
4883
4884         if (!bus || avoid_bus()) {
4885
4886                 STRV_FOREACH(name, names) {
4887                         UnitFileState state;
4888
4889                         state = unit_file_get_state(arg_scope, arg_root, *name);
4890                         if (state < 0) {
4891                                 log_error("Failed to get unit file state for %s: %s", *name, strerror(-state));
4892                                 return state;
4893                         }
4894
4895                         if (state == UNIT_FILE_ENABLED ||
4896                             state == UNIT_FILE_ENABLED_RUNTIME ||
4897                             state == UNIT_FILE_STATIC)
4898                                 enabled = true;
4899
4900                         if (!arg_quiet)
4901                                 puts(unit_file_state_to_string(state));
4902                 }
4903
4904         } else {
4905                 STRV_FOREACH(name, names) {
4906                         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4907                         const char *s;
4908
4909                         r = sd_bus_call_method(
4910                                         bus,
4911                                         "org.freedesktop.systemd1",
4912                                         "/org/freedesktop/systemd1",
4913                                         "org.freedesktop.systemd1.Manager",
4914                                         "GetUnitFileState",
4915                                         &error,
4916                                         &reply,
4917                                         "s", *name);
4918                         if (r < 0) {
4919                                 log_error("Failed to get unit file state for %s: %s", *name, bus_error_message(&error, r));
4920                                 return r;
4921                         }
4922
4923                         r = sd_bus_message_read(reply, "s", &s);
4924                         if (r < 0)
4925                                 return bus_log_parse_error(r);
4926
4927                         if (streq(s, "enabled") ||
4928                             streq(s, "enabled-runtime") ||
4929                             streq(s, "static"))
4930                                 enabled = true;
4931
4932                         if (!arg_quiet)
4933                                 puts(s);
4934                 }
4935         }
4936
4937         return !enabled;
4938 }
4939
4940 static int systemctl_help(void) {
4941
4942         pager_open_if_enabled();
4943
4944         printf("%s [OPTIONS...] {COMMAND} ...\n\n"
4945                "Query or send control commands to the systemd manager.\n\n"
4946                "  -h --help           Show this help\n"
4947                "     --version        Show package version\n"
4948                "     --system         Connect to system manager\n"
4949                "     --user           Connect to user service manager\n"
4950                "  -H --host=[USER@]HOST\n"
4951                "                      Operate on remote host\n"
4952                "  -M --machine=CONTAINER\n"
4953                "                      Operate on local container\n"
4954                "  -t --type=TYPE      List only units of a particular type\n"
4955                "     --state=STATE    List only units with particular LOAD or SUB or ACTIVE state\n"
4956                "  -p --property=NAME  Show only properties by this name\n"
4957                "  -a --all            Show all loaded units/properties, including dead/empty\n"
4958                "                      ones. To list all units installed on the system, use\n"
4959                "                      the 'list-unit-files' command instead.\n"
4960                "  -l --full           Don't ellipsize unit names on output\n"
4961                "     --reverse        Show reverse dependencies with 'list-dependencies'\n"
4962                "     --job-mode=MODE  Specify how to deal with already queued jobs, when\n"
4963                "                      queueing a new job\n"
4964                "     --show-types     When showing sockets, explicitly show their type\n"
4965                "  -i --ignore-inhibitors\n"
4966                "                      When shutting down or sleeping, ignore inhibitors\n"
4967                "     --kill-who=WHO   Who to send signal to\n"
4968                "  -s --signal=SIGNAL  Which signal to send\n"
4969                "  -q --quiet          Suppress output\n"
4970                "     --no-block       Do not wait until operation finished\n"
4971                "     --no-wall        Don't send wall message before halt/power-off/reboot\n"
4972                "     --no-reload      When enabling/disabling unit files, don't reload daemon\n"
4973                "                      configuration\n"
4974                "     --no-legend      Do not print a legend (column headers and hints)\n"
4975                "     --no-pager       Do not pipe output into a pager\n"
4976                "     --no-ask-password\n"
4977                "                      Do not ask for system passwords\n"
4978                "     --global         Enable/disable unit files globally\n"
4979                "     --runtime        Enable unit files only temporarily until next reboot\n"
4980                "  -f --force          When enabling unit files, override existing symlinks\n"
4981                "                      When shutting down, execute action immediately\n"
4982                "     --root=PATH      Enable unit files in the specified root directory\n"
4983                "  -n --lines=INTEGER  Number of journal entries to show\n"
4984                "  -o --output=STRING  Change journal output mode (short, short-monotonic,\n"
4985                "                      verbose, export, json, json-pretty, json-sse, cat)\n"
4986                "     --plain          Print unit dependencies as a list instead of a tree\n\n"
4987                "Unit Commands:\n"
4988                "  list-units [PATTERN...]         List loaded units\n"
4989                "  list-sockets [PATTERN...]       List loaded sockets ordered by address\n"
4990                "  list-timers [PATTERN...]        List loaded timers ordered by next elapse\n"
4991                "  start NAME...                   Start (activate) one or more units\n"
4992                "  stop NAME...                    Stop (deactivate) one or more units\n"
4993                "  reload NAME...                  Reload one or more units\n"
4994                "  restart NAME...                 Start or restart one or more units\n"
4995                "  try-restart NAME...             Restart one or more units if active\n"
4996                "  reload-or-restart NAME...       Reload one or more units if possible,\n"
4997                "                                  otherwise start or restart\n"
4998                "  reload-or-try-restart NAME...   Reload one or more units if possible,\n"
4999                "                                  otherwise restart if active\n"
5000                "  isolate NAME                    Start one unit and stop all others\n"
5001                "  kill NAME...                    Send signal to processes of a unit\n"
5002                "  is-active NAME...               Check whether units are active\n"
5003                "  is-failed NAME...               Check whether units are failed\n"
5004                "  status [NAME...|PID...]         Show runtime status of one or more units\n"
5005                "  show [NAME...|JOB...]           Show properties of one or more\n"
5006                "                                  units/jobs or the manager\n"
5007                "  cat NAME...                     Show files and drop-ins of one or more units\n"
5008                "  set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
5009                "  help NAME...|PID...             Show manual for one or more units\n"
5010                "  reset-failed [NAME...]          Reset failed state for all, one, or more\n"
5011                "                                  units\n"
5012                "  list-dependencies [NAME]        Recursively show units which are required\n"
5013                "                                  or wanted by this unit or by which this\n"
5014                "                                  unit is required or wanted\n\n"
5015                "Unit File Commands:\n"
5016                "  list-unit-files [PATTERN...]    List installed unit files\n"
5017                "  enable NAME...                  Enable one or more unit files\n"
5018                "  disable NAME...                 Disable one or more unit files\n"
5019                "  reenable NAME...                Reenable one or more unit files\n"
5020                "  preset NAME...                  Enable/disable one or more unit files\n"
5021                "                                  based on preset configuration\n"
5022                "  is-enabled NAME...              Check whether unit files are enabled\n\n"
5023                "  mask NAME...                    Mask one or more units\n"
5024                "  unmask NAME...                  Unmask one or more units\n"
5025                "  link PATH...                    Link one or more units files into\n"
5026                "                                  the search path\n"
5027                "  get-default                     Get the name of the default target\n"
5028                "  set-default NAME                Set the default target\n\n"
5029                "Job Commands:\n"
5030                "  list-jobs [PATTERN...]          List jobs\n"
5031                "  cancel [JOB...]                 Cancel all, one, or more jobs\n\n"
5032                "Snapshot Commands:\n"
5033                "  snapshot [NAME]                 Create a snapshot\n"
5034                "  delete NAME...                  Remove one or more snapshots\n\n"
5035                "Environment Commands:\n"
5036                "  show-environment                Dump environment\n"
5037                "  set-environment NAME=VALUE...   Set one or more environment variables\n"
5038                "  unset-environment NAME...       Unset one or more environment variables\n"
5039                "  import-environment NAME...      Import all, one or more environment variables\n\n"
5040                "Manager Lifecycle Commands:\n"
5041                "  daemon-reload                   Reload systemd manager configuration\n"
5042                "  daemon-reexec                   Reexecute systemd manager\n\n"
5043                "System Commands:\n"
5044                "  default                         Enter system default mode\n"
5045                "  rescue                          Enter system rescue mode\n"
5046                "  emergency                       Enter system emergency mode\n"
5047                "  halt                            Shut down and halt the system\n"
5048                "  poweroff                        Shut down and power-off the system\n"
5049                "  reboot [ARG]                    Shut down and reboot the system\n"
5050                "  kexec                           Shut down and reboot the system with kexec\n"
5051                "  exit                            Request user instance exit\n"
5052                "  switch-root ROOT [INIT]         Change to a different root file system\n"
5053                "  suspend                         Suspend the system\n"
5054                "  hibernate                       Hibernate the system\n"
5055                "  hybrid-sleep                    Hibernate and suspend the system\n",
5056                program_invocation_short_name);
5057
5058         return 0;
5059 }
5060
5061 static int halt_help(void) {
5062
5063         printf("%s [OPTIONS...]%s\n\n"
5064                "%s the system.\n\n"
5065                "     --help      Show this help\n"
5066                "     --halt      Halt the machine\n"
5067                "  -p --poweroff  Switch off the machine\n"
5068                "     --reboot    Reboot the machine\n"
5069                "  -f --force     Force immediate halt/power-off/reboot\n"
5070                "  -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
5071                "  -d --no-wtmp   Don't write wtmp record\n"
5072                "     --no-wall   Don't send wall message before halt/power-off/reboot\n",
5073                program_invocation_short_name,
5074                arg_action == ACTION_REBOOT   ? " [ARG]" : "",
5075                arg_action == ACTION_REBOOT   ? "Reboot" :
5076                arg_action == ACTION_POWEROFF ? "Power off" :
5077                                                "Halt");
5078
5079         return 0;
5080 }
5081
5082 static int shutdown_help(void) {
5083
5084         printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
5085                "Shut down the system.\n\n"
5086                "     --help      Show this help\n"
5087                "  -H --halt      Halt the machine\n"
5088                "  -P --poweroff  Power-off the machine\n"
5089                "  -r --reboot    Reboot the machine\n"
5090                "  -h             Equivalent to --poweroff, overridden by --halt\n"
5091                "  -k             Don't halt/power-off/reboot, just send warnings\n"
5092                "     --no-wall   Don't send wall message before halt/power-off/reboot\n"
5093                "  -c             Cancel a pending shutdown\n",
5094                program_invocation_short_name);
5095
5096         return 0;
5097 }
5098
5099 static int telinit_help(void) {
5100
5101         printf("%s [OPTIONS...] {COMMAND}\n\n"
5102                "Send control commands to the init daemon.\n\n"
5103                "     --help      Show this help\n"
5104                "     --no-wall   Don't send wall message before halt/power-off/reboot\n\n"
5105                "Commands:\n"
5106                "  0              Power-off the machine\n"
5107                "  6              Reboot the machine\n"
5108                "  2, 3, 4, 5     Start runlevelX.target unit\n"
5109                "  1, s, S        Enter rescue mode\n"
5110                "  q, Q           Reload init daemon configuration\n"
5111                "  u, U           Reexecute init daemon\n",
5112                program_invocation_short_name);
5113
5114         return 0;
5115 }
5116
5117 static int runlevel_help(void) {
5118
5119         printf("%s [OPTIONS...]\n\n"
5120                "Prints the previous and current runlevel of the init system.\n\n"
5121                "     --help      Show this help\n",
5122                program_invocation_short_name);
5123
5124         return 0;
5125 }
5126
5127 static int help_types(void) {
5128         int i;
5129         const char *t;
5130
5131         puts("Available unit types:");
5132         for (i = 0; i < _UNIT_TYPE_MAX; i++) {
5133                 t = unit_type_to_string(i);
5134                 if (t)
5135                         puts(t);
5136         }
5137
5138         return 0;
5139 }
5140
5141 static int systemctl_parse_argv(int argc, char *argv[]) {
5142
5143         enum {
5144                 ARG_FAIL = 0x100,
5145                 ARG_REVERSE,
5146                 ARG_AFTER,
5147                 ARG_BEFORE,
5148                 ARG_SHOW_TYPES,
5149                 ARG_IRREVERSIBLE,
5150                 ARG_IGNORE_DEPENDENCIES,
5151                 ARG_VERSION,
5152                 ARG_USER,
5153                 ARG_SYSTEM,
5154                 ARG_GLOBAL,
5155                 ARG_NO_BLOCK,
5156                 ARG_NO_LEGEND,
5157                 ARG_NO_PAGER,
5158                 ARG_NO_WALL,
5159                 ARG_ROOT,
5160                 ARG_NO_RELOAD,
5161                 ARG_KILL_WHO,
5162                 ARG_NO_ASK_PASSWORD,
5163                 ARG_FAILED,
5164                 ARG_RUNTIME,
5165                 ARG_FORCE,
5166                 ARG_PLAIN,
5167                 ARG_STATE,
5168                 ARG_JOB_MODE
5169         };
5170
5171         static const struct option options[] = {
5172                 { "help",                no_argument,       NULL, 'h'                     },
5173                 { "version",             no_argument,       NULL, ARG_VERSION             },
5174                 { "type",                required_argument, NULL, 't'                     },
5175                 { "property",            required_argument, NULL, 'p'                     },
5176                 { "all",                 no_argument,       NULL, 'a'                     },
5177                 { "reverse",             no_argument,       NULL, ARG_REVERSE             },
5178                 { "after",               no_argument,       NULL, ARG_AFTER               },
5179                 { "before",              no_argument,       NULL, ARG_BEFORE              },
5180                 { "show-types",          no_argument,       NULL, ARG_SHOW_TYPES          },
5181                 { "failed",              no_argument,       NULL, ARG_FAILED              }, /* compatibility only */
5182                 { "full",                no_argument,       NULL, 'l'                     },
5183                 { "job-mode",            required_argument, NULL, ARG_JOB_MODE            },
5184                 { "fail",                no_argument,       NULL, ARG_FAIL                }, /* compatibility only */
5185                 { "irreversible",        no_argument,       NULL, ARG_IRREVERSIBLE        }, /* compatibility only */
5186                 { "ignore-dependencies", no_argument,       NULL, ARG_IGNORE_DEPENDENCIES }, /* compatibility only */
5187                 { "ignore-inhibitors",   no_argument,       NULL, 'i'                     },
5188                 { "user",                no_argument,       NULL, ARG_USER                },
5189                 { "system",              no_argument,       NULL, ARG_SYSTEM              },
5190                 { "global",              no_argument,       NULL, ARG_GLOBAL              },
5191                 { "no-block",            no_argument,       NULL, ARG_NO_BLOCK            },
5192                 { "no-legend",           no_argument,       NULL, ARG_NO_LEGEND           },
5193                 { "no-pager",            no_argument,       NULL, ARG_NO_PAGER            },
5194                 { "no-wall",             no_argument,       NULL, ARG_NO_WALL             },
5195                 { "quiet",               no_argument,       NULL, 'q'                     },
5196                 { "root",                required_argument, NULL, ARG_ROOT                },
5197                 { "force",               no_argument,       NULL, ARG_FORCE               },
5198                 { "no-reload",           no_argument,       NULL, ARG_NO_RELOAD           },
5199                 { "kill-who",            required_argument, NULL, ARG_KILL_WHO            },
5200                 { "signal",              required_argument, NULL, 's'                     },
5201                 { "no-ask-password",     no_argument,       NULL, ARG_NO_ASK_PASSWORD     },
5202                 { "host",                required_argument, NULL, 'H'                     },
5203                 { "machine",             required_argument, NULL, 'M'                     },
5204                 { "runtime",             no_argument,       NULL, ARG_RUNTIME             },
5205                 { "lines",               required_argument, NULL, 'n'                     },
5206                 { "output",              required_argument, NULL, 'o'                     },
5207                 { "plain",               no_argument,       NULL, ARG_PLAIN               },
5208                 { "state",               required_argument, NULL, ARG_STATE               },
5209                 {}
5210         };
5211
5212         int c;
5213
5214         assert(argc >= 0);
5215         assert(argv);
5216
5217         while ((c = getopt_long(argc, argv, "ht:p:alqfs:H:M:n:o:i", options, NULL)) >= 0) {
5218
5219                 switch (c) {
5220
5221                 case 'h':
5222                         return systemctl_help();
5223
5224                 case ARG_VERSION:
5225                         puts(PACKAGE_STRING);
5226                         puts(SYSTEMD_FEATURES);
5227                         return 0;
5228
5229                 case 't': {
5230                         char *word, *state;
5231                         size_t size;
5232
5233                         FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
5234                                 _cleanup_free_ char *type;
5235
5236                                 type = strndup(word, size);
5237                                 if (!type)
5238                                         return -ENOMEM;
5239
5240                                 if (streq(type, "help")) {
5241                                         help_types();
5242                                         return 0;
5243                                 }
5244
5245                                 if (unit_type_from_string(type) >= 0) {
5246                                         if (strv_push(&arg_types, type))
5247                                                 return log_oom();
5248                                         type = NULL;
5249                                         continue;
5250                                 }
5251
5252                                 /* It's much nicer to use --state= for
5253                                  * load states, but let's support this
5254                                  * in --types= too for compatibility
5255                                  * with old versions */
5256                                 if (unit_load_state_from_string(optarg) >= 0) {
5257                                         if (strv_push(&arg_states, type) < 0)
5258                                                 return log_oom();
5259                                         type = NULL;
5260                                         continue;
5261                                 }
5262
5263                                 log_error("Unknown unit type or load state '%s'.", type);
5264                                 log_info("Use -t help to see a list of allowed values.");
5265                                 return -EINVAL;
5266                         }
5267
5268                         break;
5269                 }
5270
5271                 case 'p': {
5272                         /* Make sure that if the empty property list
5273                            was specified, we won't show any properties. */
5274                         if (isempty(optarg) && !arg_properties) {
5275                                 arg_properties = new0(char*, 1);
5276                                 if (!arg_properties)
5277                                         return log_oom();
5278                         } else {
5279                                 char *word, *state;
5280                                 size_t size;
5281
5282                                 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
5283                                         char *prop;
5284
5285                                         prop = strndup(word, size);
5286                                         if (!prop)
5287                                                 return log_oom();
5288
5289                                         if (strv_push(&arg_properties, prop) < 0) {
5290                                                 free(prop);
5291                                                 return log_oom();
5292                                         }
5293                                 }
5294                         }
5295
5296                         /* If the user asked for a particular
5297                          * property, show it to him, even if it is
5298                          * empty. */
5299                         arg_all = true;
5300
5301                         break;
5302                 }
5303
5304                 case 'a':
5305                         arg_all = true;
5306                         break;
5307
5308                 case ARG_REVERSE:
5309                         arg_dependency = DEPENDENCY_REVERSE;
5310                         break;
5311
5312                 case ARG_AFTER:
5313                         arg_dependency = DEPENDENCY_AFTER;
5314                         break;
5315
5316                 case ARG_BEFORE:
5317                         arg_dependency = DEPENDENCY_BEFORE;
5318                         break;
5319
5320                 case ARG_SHOW_TYPES:
5321                         arg_show_types = true;
5322                         break;
5323
5324                 case ARG_JOB_MODE:
5325                         arg_job_mode = optarg;
5326                         break;
5327
5328                 case ARG_FAIL:
5329                         arg_job_mode = "fail";
5330                         break;
5331
5332                 case ARG_IRREVERSIBLE:
5333                         arg_job_mode = "replace-irreversibly";
5334                         break;
5335
5336                 case ARG_IGNORE_DEPENDENCIES:
5337                         arg_job_mode = "ignore-dependencies";
5338                         break;
5339
5340                 case ARG_USER:
5341                         arg_scope = UNIT_FILE_USER;
5342                         break;
5343
5344                 case ARG_SYSTEM:
5345                         arg_scope = UNIT_FILE_SYSTEM;
5346                         break;
5347
5348                 case ARG_GLOBAL:
5349                         arg_scope = UNIT_FILE_GLOBAL;
5350                         break;
5351
5352                 case ARG_NO_BLOCK:
5353                         arg_no_block = true;
5354                         break;
5355
5356                 case ARG_NO_LEGEND:
5357                         arg_no_legend = true;
5358                         break;
5359
5360                 case ARG_NO_PAGER:
5361                         arg_no_pager = true;
5362                         break;
5363
5364                 case ARG_NO_WALL:
5365                         arg_no_wall = true;
5366                         break;
5367
5368                 case ARG_ROOT:
5369                         arg_root = optarg;
5370                         break;
5371
5372                 case 'l':
5373                         arg_full = true;
5374                         break;
5375
5376                 case ARG_FAILED:
5377                         if (strv_extend(&arg_states, "failed") < 0)
5378                                 return log_oom();
5379
5380                         break;
5381
5382                 case 'q':
5383                         arg_quiet = true;
5384                         break;
5385
5386                 case ARG_FORCE:
5387                         arg_force ++;
5388                         break;
5389
5390                 case 'f':
5391                         arg_force ++;
5392                         break;
5393
5394                 case ARG_NO_RELOAD:
5395                         arg_no_reload = true;
5396                         break;
5397
5398                 case ARG_KILL_WHO:
5399                         arg_kill_who = optarg;
5400                         break;
5401
5402                 case 's':
5403                         if ((arg_signal = signal_from_string_try_harder(optarg)) < 0) {
5404                                 log_error("Failed to parse signal string %s.", optarg);
5405                                 return -EINVAL;
5406                         }
5407                         break;
5408
5409                 case ARG_NO_ASK_PASSWORD:
5410                         arg_ask_password = false;
5411                         break;
5412
5413                 case 'H':
5414                         arg_transport = BUS_TRANSPORT_REMOTE;
5415                         arg_host = optarg;
5416                         break;
5417
5418                 case 'M':
5419                         arg_transport = BUS_TRANSPORT_CONTAINER;
5420                         arg_host = optarg;
5421                         break;
5422
5423                 case ARG_RUNTIME:
5424                         arg_runtime = true;
5425                         break;
5426
5427                 case 'n':
5428                         if (safe_atou(optarg, &arg_lines) < 0) {
5429                                 log_error("Failed to parse lines '%s'", optarg);
5430                                 return -EINVAL;
5431                         }
5432                         break;
5433
5434                 case 'o':
5435                         arg_output = output_mode_from_string(optarg);
5436                         if (arg_output < 0) {
5437                                 log_error("Unknown output '%s'.", optarg);
5438                                 return -EINVAL;
5439                         }
5440                         break;
5441
5442                 case 'i':
5443                         arg_ignore_inhibitors = true;
5444                         break;
5445
5446                 case ARG_PLAIN:
5447                         arg_plain = true;
5448                         break;
5449
5450                 case ARG_STATE: {
5451                         char *word, *state;
5452                         size_t size;
5453
5454                         FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
5455                                 char *s;
5456
5457                                 s = strndup(word, size);
5458                                 if (!s)
5459                                         return log_oom();
5460
5461                                 if (strv_push(&arg_states, s) < 0) {
5462                                         free(s);
5463                                         return log_oom();
5464                                 }
5465                         }
5466                         break;
5467                 }
5468
5469                 case '?':
5470                         return -EINVAL;
5471
5472                 default:
5473                         assert_not_reached("Unhandled option");
5474                 }
5475         }
5476
5477         if (arg_transport != BUS_TRANSPORT_LOCAL && arg_scope != UNIT_FILE_SYSTEM) {
5478                 log_error("Cannot access user instance remotely.");
5479                 return -EINVAL;
5480         }
5481
5482         return 1;
5483 }
5484
5485 static int halt_parse_argv(int argc, char *argv[]) {
5486
5487         enum {
5488                 ARG_HELP = 0x100,
5489                 ARG_HALT,
5490                 ARG_REBOOT,
5491                 ARG_NO_WALL
5492         };
5493
5494         static const struct option options[] = {
5495                 { "help",      no_argument,       NULL, ARG_HELP    },
5496                 { "halt",      no_argument,       NULL, ARG_HALT    },
5497                 { "poweroff",  no_argument,       NULL, 'p'         },
5498                 { "reboot",    no_argument,       NULL, ARG_REBOOT  },
5499                 { "force",     no_argument,       NULL, 'f'         },
5500                 { "wtmp-only", no_argument,       NULL, 'w'         },
5501                 { "no-wtmp",   no_argument,       NULL, 'd'         },
5502                 { "no-wall",   no_argument,       NULL, ARG_NO_WALL },
5503                 {}
5504         };
5505
5506         int c, r, runlevel;
5507
5508         assert(argc >= 0);
5509         assert(argv);
5510
5511         if (utmp_get_runlevel(&runlevel, NULL) >= 0)
5512                 if (runlevel == '0' || runlevel == '6')
5513                         arg_force = 2;
5514
5515         while ((c = getopt_long(argc, argv, "pfwdnih", options, NULL)) >= 0) {
5516                 switch (c) {
5517
5518                 case ARG_HELP:
5519                         return halt_help();
5520
5521                 case ARG_HALT:
5522                         arg_action = ACTION_HALT;
5523                         break;
5524
5525                 case 'p':
5526                         if (arg_action != ACTION_REBOOT)
5527                                 arg_action = ACTION_POWEROFF;
5528                         break;
5529
5530                 case ARG_REBOOT:
5531                         arg_action = ACTION_REBOOT;
5532                         break;
5533
5534                 case 'f':
5535                         arg_force = 2;
5536                         break;
5537
5538                 case 'w':
5539                         arg_dry = true;
5540                         break;
5541
5542                 case 'd':
5543                         arg_no_wtmp = true;
5544                         break;
5545
5546                 case ARG_NO_WALL:
5547                         arg_no_wall = true;
5548                         break;
5549
5550                 case 'i':
5551                 case 'h':
5552                 case 'n':
5553                         /* Compatibility nops */
5554                         break;
5555
5556                 case '?':
5557                         return -EINVAL;
5558
5559                 default:
5560                         assert_not_reached("Unhandled option");
5561                 }
5562         }
5563
5564         if (arg_action == ACTION_REBOOT && argc == optind + 1) {
5565                 r = write_string_file(REBOOT_PARAM_FILE, argv[optind]);
5566                 if (r < 0) {
5567                         log_error("Failed to write reboot param to "
5568                                   REBOOT_PARAM_FILE": %s", strerror(-r));
5569                         return r;
5570                 }
5571         } else if (optind < argc) {
5572                 log_error("Too many arguments.");
5573                 return -EINVAL;
5574         }
5575
5576         return 1;
5577 }
5578
5579 static int parse_time_spec(const char *t, usec_t *_u) {
5580         assert(t);
5581         assert(_u);
5582
5583         if (streq(t, "now"))
5584                 *_u = 0;
5585         else if (!strchr(t, ':')) {
5586                 uint64_t u;
5587
5588                 if (safe_atou64(t, &u) < 0)
5589                         return -EINVAL;
5590
5591                 *_u = now(CLOCK_REALTIME) + USEC_PER_MINUTE * u;
5592         } else {
5593                 char *e = NULL;
5594                 long hour, minute;
5595                 struct tm tm = {};
5596                 time_t s;
5597                 usec_t n;
5598
5599                 errno = 0;
5600                 hour = strtol(t, &e, 10);
5601                 if (errno > 0 || *e != ':' || hour < 0 || hour > 23)
5602                         return -EINVAL;
5603
5604                 minute = strtol(e+1, &e, 10);
5605                 if (errno > 0 || *e != 0 || minute < 0 || minute > 59)
5606                         return -EINVAL;
5607
5608                 n = now(CLOCK_REALTIME);
5609                 s = (time_t) (n / USEC_PER_SEC);
5610
5611                 assert_se(localtime_r(&s, &tm));
5612
5613                 tm.tm_hour = (int) hour;
5614                 tm.tm_min = (int) minute;
5615                 tm.tm_sec = 0;
5616
5617                 assert_se(s = mktime(&tm));
5618
5619                 *_u = (usec_t) s * USEC_PER_SEC;
5620
5621                 while (*_u <= n)
5622                         *_u += USEC_PER_DAY;
5623         }
5624
5625         return 0;
5626 }
5627
5628 static int shutdown_parse_argv(int argc, char *argv[]) {
5629
5630         enum {
5631                 ARG_HELP = 0x100,
5632                 ARG_NO_WALL
5633         };
5634
5635         static const struct option options[] = {
5636                 { "help",      no_argument,       NULL, ARG_HELP    },
5637                 { "halt",      no_argument,       NULL, 'H'         },
5638                 { "poweroff",  no_argument,       NULL, 'P'         },
5639                 { "reboot",    no_argument,       NULL, 'r'         },
5640                 { "kexec",     no_argument,       NULL, 'K'         }, /* not documented extension */
5641                 { "no-wall",   no_argument,       NULL, ARG_NO_WALL },
5642                 {}
5643         };
5644
5645         int c, r;
5646
5647         assert(argc >= 0);
5648         assert(argv);
5649
5650         while ((c = getopt_long(argc, argv, "HPrhkt:afFc", options, NULL)) >= 0) {
5651                 switch (c) {
5652
5653                 case ARG_HELP:
5654                         return shutdown_help();
5655
5656                 case 'H':
5657                         arg_action = ACTION_HALT;
5658                         break;
5659
5660                 case 'P':
5661                         arg_action = ACTION_POWEROFF;
5662                         break;
5663
5664                 case 'r':
5665                         if (kexec_loaded())
5666                                 arg_action = ACTION_KEXEC;
5667                         else
5668                                 arg_action = ACTION_REBOOT;
5669                         break;
5670
5671                 case 'K':
5672                         arg_action = ACTION_KEXEC;
5673                         break;
5674
5675                 case 'h':
5676                         if (arg_action != ACTION_HALT)
5677                                 arg_action = ACTION_POWEROFF;
5678                         break;
5679
5680                 case 'k':
5681                         arg_dry = true;
5682                         break;
5683
5684                 case ARG_NO_WALL:
5685                         arg_no_wall = true;
5686                         break;
5687
5688                 case 't':
5689                 case 'a':
5690                         /* Compatibility nops */
5691                         break;
5692
5693                 case 'c':
5694                         arg_action = ACTION_CANCEL_SHUTDOWN;
5695                         break;
5696
5697                 case '?':
5698                         return -EINVAL;
5699
5700                 default:
5701                         assert_not_reached("Unhandled option");
5702                 }
5703         }
5704
5705         if (argc > optind && arg_action != ACTION_CANCEL_SHUTDOWN) {
5706                 r = parse_time_spec(argv[optind], &arg_when);
5707                 if (r < 0) {
5708                         log_error("Failed to parse time specification: %s", argv[optind]);
5709                         return r;
5710                 }
5711         } else
5712                 arg_when = now(CLOCK_REALTIME) + USEC_PER_MINUTE;
5713
5714         if (argc > optind && arg_action == ACTION_CANCEL_SHUTDOWN)
5715                 /* No time argument for shutdown cancel */
5716                 arg_wall = argv + optind;
5717         else if (argc > optind + 1)
5718                 /* We skip the time argument */
5719                 arg_wall = argv + optind + 1;
5720
5721         optind = argc;
5722
5723         return 1;
5724 }
5725
5726 static int telinit_parse_argv(int argc, char *argv[]) {
5727
5728         enum {
5729                 ARG_HELP = 0x100,
5730                 ARG_NO_WALL
5731         };
5732
5733         static const struct option options[] = {
5734                 { "help",      no_argument,       NULL, ARG_HELP    },
5735                 { "no-wall",   no_argument,       NULL, ARG_NO_WALL },
5736                 {}
5737         };
5738
5739         static const struct {
5740                 char from;
5741                 enum action to;
5742         } table[] = {
5743                 { '0', ACTION_POWEROFF },
5744                 { '6', ACTION_REBOOT },
5745                 { '1', ACTION_RESCUE },
5746                 { '2', ACTION_RUNLEVEL2 },
5747                 { '3', ACTION_RUNLEVEL3 },
5748                 { '4', ACTION_RUNLEVEL4 },
5749                 { '5', ACTION_RUNLEVEL5 },
5750                 { 's', ACTION_RESCUE },
5751                 { 'S', ACTION_RESCUE },
5752                 { 'q', ACTION_RELOAD },
5753                 { 'Q', ACTION_RELOAD },
5754                 { 'u', ACTION_REEXEC },
5755                 { 'U', ACTION_REEXEC }
5756         };
5757
5758         unsigned i;
5759         int c;
5760
5761         assert(argc >= 0);
5762         assert(argv);
5763
5764         while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0) {
5765                 switch (c) {
5766
5767                 case ARG_HELP:
5768                         return telinit_help();
5769
5770                 case ARG_NO_WALL:
5771                         arg_no_wall = true;
5772                         break;
5773
5774                 case '?':
5775                         return -EINVAL;
5776
5777                 default:
5778                         assert_not_reached("Unhandled option");
5779                 }
5780         }
5781
5782         if (optind >= argc) {
5783                 telinit_help();
5784                 return -EINVAL;
5785         }
5786
5787         if (optind + 1 < argc) {
5788                 log_error("Too many arguments.");
5789                 return -EINVAL;
5790         }
5791
5792         if (strlen(argv[optind]) != 1) {
5793                 log_error("Expected single character argument.");
5794                 return -EINVAL;
5795         }
5796
5797         for (i = 0; i < ELEMENTSOF(table); i++)
5798                 if (table[i].from == argv[optind][0])
5799                         break;
5800
5801         if (i >= ELEMENTSOF(table)) {
5802                 log_error("Unknown command '%s'.", argv[optind]);
5803                 return -EINVAL;
5804         }
5805
5806         arg_action = table[i].to;
5807
5808         optind ++;
5809
5810         return 1;
5811 }
5812
5813 static int runlevel_parse_argv(int argc, char *argv[]) {
5814
5815         enum {
5816                 ARG_HELP = 0x100,
5817         };
5818
5819         static const struct option options[] = {
5820                 { "help",      no_argument,       NULL, ARG_HELP    },
5821                 {}
5822         };
5823
5824         int c;
5825
5826         assert(argc >= 0);
5827         assert(argv);
5828
5829         while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0) {
5830                 switch (c) {
5831
5832                 case ARG_HELP:
5833                         return runlevel_help();
5834                         return 0;
5835
5836                 case '?':
5837                         return -EINVAL;
5838
5839                 default:
5840                         assert_not_reached("Unhandled option");
5841                 }
5842         }
5843
5844         if (optind < argc) {
5845                 log_error("Too many arguments.");
5846                 return -EINVAL;
5847         }
5848
5849         return 1;
5850 }
5851
5852 static int parse_argv(int argc, char *argv[]) {
5853         assert(argc >= 0);
5854         assert(argv);
5855
5856         if (program_invocation_short_name) {
5857
5858                 if (strstr(program_invocation_short_name, "halt")) {
5859                         arg_action = ACTION_HALT;
5860                         return halt_parse_argv(argc, argv);
5861                 } else if (strstr(program_invocation_short_name, "poweroff")) {
5862                         arg_action = ACTION_POWEROFF;
5863                         return halt_parse_argv(argc, argv);
5864                 } else if (strstr(program_invocation_short_name, "reboot")) {
5865                         if (kexec_loaded())
5866                                 arg_action = ACTION_KEXEC;
5867                         else
5868                                 arg_action = ACTION_REBOOT;
5869                         return halt_parse_argv(argc, argv);
5870                 } else if (strstr(program_invocation_short_name, "shutdown")) {
5871                         arg_action = ACTION_POWEROFF;
5872                         return shutdown_parse_argv(argc, argv);
5873                 } else if (strstr(program_invocation_short_name, "init")) {
5874
5875                         if (sd_booted() > 0) {
5876                                 arg_action = _ACTION_INVALID;
5877                                 return telinit_parse_argv(argc, argv);
5878                         } else {
5879                                 /* Hmm, so some other init system is
5880                                  * running, we need to forward this
5881                                  * request to it. For now we simply
5882                                  * guess that it is Upstart. */
5883
5884                                 execv(TELINIT, argv);
5885
5886                                 log_error("Couldn't find an alternative telinit implementation to spawn.");
5887                                 return -EIO;
5888                         }
5889
5890                 } else if (strstr(program_invocation_short_name, "runlevel")) {
5891                         arg_action = ACTION_RUNLEVEL;
5892                         return runlevel_parse_argv(argc, argv);
5893                 }
5894         }
5895
5896         arg_action = ACTION_SYSTEMCTL;
5897         return systemctl_parse_argv(argc, argv);
5898 }
5899
5900 _pure_ static int action_to_runlevel(void) {
5901
5902         static const char table[_ACTION_MAX] = {
5903                 [ACTION_HALT] =      '0',
5904                 [ACTION_POWEROFF] =  '0',
5905                 [ACTION_REBOOT] =    '6',
5906                 [ACTION_RUNLEVEL2] = '2',
5907                 [ACTION_RUNLEVEL3] = '3',
5908                 [ACTION_RUNLEVEL4] = '4',
5909                 [ACTION_RUNLEVEL5] = '5',
5910                 [ACTION_RESCUE] =    '1'
5911         };
5912
5913         assert(arg_action < _ACTION_MAX);
5914
5915         return table[arg_action];
5916 }
5917
5918 static int talk_initctl(void) {
5919
5920         struct init_request request = {
5921                 .magic = INIT_MAGIC,
5922                 .sleeptime  = 0,
5923                 .cmd = INIT_CMD_RUNLVL
5924         };
5925
5926         _cleanup_close_ int fd = -1;
5927         char rl;
5928         int r;
5929
5930         rl = action_to_runlevel();
5931         if (!rl)
5932                 return 0;
5933
5934         request.runlevel = rl;
5935
5936         fd = open(INIT_FIFO, O_WRONLY|O_NDELAY|O_CLOEXEC|O_NOCTTY);
5937         if (fd < 0) {
5938                 if (errno == ENOENT)
5939                         return 0;
5940
5941                 log_error("Failed to open "INIT_FIFO": %m");
5942                 return -errno;
5943         }
5944
5945         errno = 0;
5946         r = loop_write(fd, &request, sizeof(request), false) != sizeof(request);
5947         if (r) {
5948                 log_error("Failed to write to "INIT_FIFO": %m");
5949                 return errno > 0 ? -errno : -EIO;
5950         }
5951
5952         return 1;
5953 }
5954
5955 static int systemctl_main(sd_bus *bus, int argc, char *argv[], int bus_error) {
5956
5957         static const struct {
5958                 const char* verb;
5959                 const enum {
5960                         MORE,
5961                         LESS,
5962                         EQUAL
5963                 } argc_cmp;
5964                 const int argc;
5965                 int (* const dispatch)(sd_bus *bus, char **args);
5966                 const enum {
5967                         NOBUS = 1,
5968                         FORCE,
5969                 } bus;
5970         } verbs[] = {
5971                 { "list-units",            MORE,  0, list_units        },
5972                 { "list-unit-files",       MORE,  1, list_unit_files,  NOBUS },
5973                 { "list-sockets",          MORE,  1, list_sockets      },
5974                 { "list-timers",           MORE,  1, list_timers       },
5975                 { "list-jobs",             MORE,  1, list_jobs         },
5976                 { "clear-jobs",            EQUAL, 1, daemon_reload     },
5977                 { "cancel",                MORE,  2, cancel_job        },
5978                 { "start",                 MORE,  2, start_unit        },
5979                 { "stop",                  MORE,  2, start_unit        },
5980                 { "condstop",              MORE,  2, start_unit        }, /* For compatibility with ALTLinux */
5981                 { "reload",                MORE,  2, start_unit        },
5982                 { "restart",               MORE,  2, start_unit        },
5983                 { "try-restart",           MORE,  2, start_unit        },
5984                 { "reload-or-restart",     MORE,  2, start_unit        },
5985                 { "reload-or-try-restart", MORE,  2, start_unit        },
5986                 { "force-reload",          MORE,  2, start_unit        }, /* For compatibility with SysV */
5987                 { "condreload",            MORE,  2, start_unit        }, /* For compatibility with ALTLinux */
5988                 { "condrestart",           MORE,  2, start_unit        }, /* For compatibility with RH */
5989                 { "isolate",               EQUAL, 2, start_unit        },
5990                 { "kill",                  MORE,  2, kill_unit         },
5991                 { "is-active",             MORE,  2, check_unit_active },
5992                 { "check",                 MORE,  2, check_unit_active },
5993                 { "is-failed",             MORE,  2, check_unit_failed },
5994                 { "show",                  MORE,  1, show              },
5995                 { "cat",                   MORE,  2, cat               },
5996                 { "status",                MORE,  1, show              },
5997                 { "help",                  MORE,  2, show              },
5998                 { "snapshot",              LESS,  2, snapshot          },
5999                 { "delete",                MORE,  2, delete_snapshot   },
6000                 { "daemon-reload",         EQUAL, 1, daemon_reload     },
6001                 { "daemon-reexec",         EQUAL, 1, daemon_reload     },
6002                 { "show-environment",      EQUAL, 1, show_environment  },
6003                 { "set-environment",       MORE,  2, set_environment   },
6004                 { "unset-environment",     MORE,  2, set_environment   },
6005                 { "import-environment",    MORE,  1, import_environment},
6006                 { "halt",                  EQUAL, 1, start_special,    FORCE },
6007                 { "poweroff",              EQUAL, 1, start_special,    FORCE },
6008                 { "reboot",                EQUAL, 1, start_special,    FORCE },
6009                 { "kexec",                 EQUAL, 1, start_special     },
6010                 { "suspend",               EQUAL, 1, start_special     },
6011                 { "hibernate",             EQUAL, 1, start_special     },
6012                 { "hybrid-sleep",          EQUAL, 1, start_special     },
6013                 { "default",               EQUAL, 1, start_special     },
6014                 { "rescue",                EQUAL, 1, start_special     },
6015                 { "emergency",             EQUAL, 1, start_special     },
6016                 { "exit",                  EQUAL, 1, start_special     },
6017                 { "reset-failed",          MORE,  1, reset_failed      },
6018                 { "enable",                MORE,  2, enable_unit,      NOBUS },
6019                 { "disable",               MORE,  2, enable_unit,      NOBUS },
6020                 { "is-enabled",            MORE,  2, unit_is_enabled,  NOBUS },
6021                 { "reenable",              MORE,  2, enable_unit,      NOBUS },
6022                 { "preset",                MORE,  2, enable_unit,      NOBUS },
6023                 { "mask",                  MORE,  2, enable_unit,      NOBUS },
6024                 { "unmask",                MORE,  2, enable_unit,      NOBUS },
6025                 { "link",                  MORE,  2, enable_unit,      NOBUS },
6026                 { "switch-root",           MORE,  2, switch_root       },
6027                 { "list-dependencies",     LESS,  2, list_dependencies },
6028                 { "set-default",           EQUAL, 2, set_default,      NOBUS },
6029                 { "get-default",           EQUAL, 1, get_default,      NOBUS },
6030                 { "set-property",          MORE,  3, set_property      },
6031                 {}
6032         }, *verb = verbs;
6033
6034         int left;
6035
6036         assert(argc >= 0);
6037         assert(argv);
6038
6039         left = argc - optind;
6040
6041         /* Special rule: no arguments (left == 0) means "list-units" */
6042         if (left > 0) {
6043                 if (streq(argv[optind], "help") && !argv[optind+1]) {
6044                         log_error("This command expects one or more "
6045                                   "unit names. Did you mean --help?");
6046                         return -EINVAL;
6047                 }
6048
6049                 for (; verb->verb; verb++)
6050                         if (streq(argv[optind], verb->verb))
6051                                 goto found;
6052
6053                 log_error("Unknown operation '%s'.", argv[optind]);
6054                 return -EINVAL;
6055         }
6056 found:
6057
6058         switch (verb->argc_cmp) {
6059
6060         case EQUAL:
6061                 if (left != verb->argc) {
6062                         log_error("Invalid number of arguments.");
6063                         return -EINVAL;
6064                 }
6065
6066                 break;
6067
6068         case MORE:
6069                 if (left < verb->argc) {
6070                         log_error("Too few arguments.");
6071                         return -EINVAL;
6072                 }
6073
6074                 break;
6075
6076         case LESS:
6077                 if (left > verb->argc) {
6078                         log_error("Too many arguments.");
6079                         return -EINVAL;
6080                 }
6081
6082                 break;
6083
6084         default:
6085                 assert_not_reached("Unknown comparison operator.");
6086         }
6087
6088         /* Require a bus connection for all operations but
6089          * enable/disable */
6090         if (verb->bus == NOBUS) {
6091                 if (!bus && !avoid_bus()) {
6092                         log_error("Failed to get D-Bus connection: %s", strerror(-bus_error));
6093                         return -EIO;
6094                 }
6095
6096         } else {
6097                 if (running_in_chroot() > 0) {
6098                         log_info("Running in chroot, ignoring request.");
6099                         return 0;
6100                 }
6101
6102                 if ((verb->bus != FORCE || arg_force <= 0) && !bus) {
6103                         log_error("Failed to get D-Bus connection: %s", strerror(-bus_error));
6104                         return -EIO;
6105                 }
6106         }
6107
6108         return verb->dispatch(bus, argv + optind);
6109 }
6110
6111 static int send_shutdownd(usec_t t, char mode, bool dry_run, bool warn, const char *message) {
6112
6113         struct sd_shutdown_command c = {
6114                 .usec = t,
6115                 .mode = mode,
6116                 .dry_run = dry_run,
6117                 .warn_wall = warn,
6118         };
6119
6120         union sockaddr_union sockaddr = {
6121                 .un.sun_family = AF_UNIX,
6122                 .un.sun_path = "/run/systemd/shutdownd",
6123         };
6124
6125         struct iovec iovec[2] = {{
6126                  .iov_base = (char*) &c,
6127                  .iov_len = offsetof(struct sd_shutdown_command, wall_message),
6128         }};
6129
6130         struct msghdr msghdr = {
6131                 .msg_name = &sockaddr,
6132                 .msg_namelen = offsetof(struct sockaddr_un, sun_path)
6133                                + sizeof("/run/systemd/shutdownd") - 1,
6134                 .msg_iov = iovec,
6135                 .msg_iovlen = 1,
6136         };
6137
6138         _cleanup_close_ int fd;
6139
6140         fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
6141         if (fd < 0)
6142                 return -errno;
6143
6144         if (!isempty(message)) {
6145                 iovec[1].iov_base = (char*) message;
6146                 iovec[1].iov_len = strlen(message);
6147                 msghdr.msg_iovlen++;
6148         }
6149
6150         if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) < 0)
6151                 return -errno;
6152
6153         return 0;
6154 }
6155
6156 static int reload_with_fallback(sd_bus *bus) {
6157
6158         if (bus) {
6159                 /* First, try systemd via D-Bus. */
6160                 if (daemon_reload(bus, NULL) >= 0)
6161                         return 0;
6162         }
6163
6164         /* Nothing else worked, so let's try signals */
6165         assert(arg_action == ACTION_RELOAD || arg_action == ACTION_REEXEC);
6166
6167         if (kill(1, arg_action == ACTION_RELOAD ? SIGHUP : SIGTERM) < 0) {
6168                 log_error("kill() failed: %m");
6169                 return -errno;
6170         }
6171
6172         return 0;
6173 }
6174
6175 static int start_with_fallback(sd_bus *bus) {
6176
6177         if (bus) {
6178                 /* First, try systemd via D-Bus. */
6179                 if (start_unit(bus, NULL) >= 0)
6180                         goto done;
6181         }
6182
6183         /* Nothing else worked, so let's try
6184          * /dev/initctl */
6185         if (talk_initctl() > 0)
6186                 goto done;
6187
6188         log_error("Failed to talk to init daemon.");
6189         return -EIO;
6190
6191 done:
6192         warn_wall(arg_action);
6193         return 0;
6194 }
6195
6196 static int halt_now(enum action a) {
6197
6198 /* Make sure C-A-D is handled by the kernel from this
6199          * point on... */
6200         reboot(RB_ENABLE_CAD);
6201
6202         switch (a) {
6203
6204         case ACTION_HALT:
6205                 log_info("Halting.");
6206                 reboot(RB_HALT_SYSTEM);
6207                 return -errno;
6208
6209         case ACTION_POWEROFF:
6210                 log_info("Powering off.");
6211                 reboot(RB_POWER_OFF);
6212                 return -errno;
6213
6214         case ACTION_REBOOT: {
6215                 _cleanup_free_ char *param = NULL;
6216
6217                 if (read_one_line_file(REBOOT_PARAM_FILE, &param) >= 0) {
6218                         log_info("Rebooting with argument '%s'.", param);
6219                         syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
6220                                 LINUX_REBOOT_CMD_RESTART2, param);
6221                 }
6222
6223                 log_info("Rebooting.");
6224                 reboot(RB_AUTOBOOT);
6225                 return -errno;
6226         }
6227
6228         default:
6229                 assert_not_reached("Unknown action.");
6230         }
6231 }
6232
6233 static int halt_main(sd_bus *bus) {
6234         int r;
6235
6236         r = check_inhibitors(bus, arg_action);
6237         if (r < 0)
6238                 return r;
6239
6240         if (geteuid() != 0) {
6241                 /* Try logind if we are a normal user and no special
6242                  * mode applies. Maybe PolicyKit allows us to shutdown
6243                  * the machine. */
6244
6245                 if (arg_when <= 0 &&
6246                     !arg_dry &&
6247                     arg_force <= 0 &&
6248                     (arg_action == ACTION_POWEROFF ||
6249                      arg_action == ACTION_REBOOT)) {
6250                         r = reboot_with_logind(bus, arg_action);
6251                         if (r >= 0)
6252                                 return r;
6253                 }
6254
6255                 log_error("Must be root.");
6256                 return -EPERM;
6257         }
6258
6259         if (arg_when > 0) {
6260                 _cleanup_free_ char *m;
6261
6262                 m = strv_join(arg_wall, " ");
6263                 if (!m)
6264                         return log_oom();
6265
6266                 r = send_shutdownd(arg_when,
6267                                    arg_action == ACTION_HALT     ? 'H' :
6268                                    arg_action == ACTION_POWEROFF ? 'P' :
6269                                    arg_action == ACTION_KEXEC    ? 'K' :
6270                                                                    'r',
6271                                    arg_dry,
6272                                    !arg_no_wall,
6273                                    m);
6274
6275                 if (r < 0)
6276                         log_warning("Failed to talk to shutdownd, proceeding with immediate shutdown: %s", strerror(-r));
6277                 else {
6278                         char date[FORMAT_TIMESTAMP_MAX];
6279
6280                         log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.",
6281                                  format_timestamp(date, sizeof(date), arg_when));
6282                         return 0;
6283                 }
6284         }
6285
6286         if (!arg_dry && !arg_force)
6287                 return start_with_fallback(bus);
6288
6289         if (!arg_no_wtmp) {
6290                 if (sd_booted() > 0)
6291                         log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
6292                 else {
6293                         r = utmp_put_shutdown();
6294                         if (r < 0)
6295                                 log_warning("Failed to write utmp record: %s", strerror(-r));
6296                 }
6297         }
6298
6299         if (arg_dry)
6300                 return 0;
6301
6302         r = halt_now(arg_action);
6303         log_error("Failed to reboot: %s", strerror(-r));
6304
6305         return r;
6306 }
6307
6308 static int runlevel_main(void) {
6309         int r, runlevel, previous;
6310
6311         r = utmp_get_runlevel(&runlevel, &previous);
6312         if (r < 0) {
6313                 puts("unknown");
6314                 return r;
6315         }
6316
6317         printf("%c %c\n",
6318                previous <= 0 ? 'N' : previous,
6319                runlevel <= 0 ? 'N' : runlevel);
6320
6321         return 0;
6322 }
6323
6324 int main(int argc, char*argv[]) {
6325         _cleanup_bus_unref_ sd_bus *bus = NULL;
6326         int r;
6327
6328         setlocale(LC_ALL, "");
6329         log_parse_environment();
6330         log_open();
6331
6332         /* Explicitly not on_tty() to avoid setting cached value.
6333          * This becomes relevant for piping output which might be
6334          * ellipsized. */
6335         original_stdout_is_tty = isatty(STDOUT_FILENO);
6336
6337         r = parse_argv(argc, argv);
6338         if (r <= 0)
6339                 goto finish;
6340
6341         /* /sbin/runlevel doesn't need to communicate via D-Bus, so
6342          * let's shortcut this */
6343         if (arg_action == ACTION_RUNLEVEL) {
6344                 r = runlevel_main();
6345                 goto finish;
6346         }
6347
6348         if (running_in_chroot() > 0 && arg_action != ACTION_SYSTEMCTL) {
6349                 log_info("Running in chroot, ignoring request.");
6350                 r = 0;
6351                 goto finish;
6352         }
6353
6354         if (!avoid_bus())
6355                 r = bus_open_transport_systemd(arg_transport, arg_host, arg_scope != UNIT_FILE_SYSTEM, &bus);
6356
6357         /* systemctl_main() will print an error message for the bus
6358          * connection, but only if it needs to */
6359
6360         switch (arg_action) {
6361
6362         case ACTION_SYSTEMCTL:
6363                 r = systemctl_main(bus, argc, argv, r);
6364                 break;
6365
6366         case ACTION_HALT:
6367         case ACTION_POWEROFF:
6368         case ACTION_REBOOT:
6369         case ACTION_KEXEC:
6370                 r = halt_main(bus);
6371                 break;
6372
6373         case ACTION_RUNLEVEL2:
6374         case ACTION_RUNLEVEL3:
6375         case ACTION_RUNLEVEL4:
6376         case ACTION_RUNLEVEL5:
6377         case ACTION_RESCUE:
6378         case ACTION_EMERGENCY:
6379         case ACTION_DEFAULT:
6380                 r = start_with_fallback(bus);
6381                 break;
6382
6383         case ACTION_RELOAD:
6384         case ACTION_REEXEC:
6385                 r = reload_with_fallback(bus);
6386                 break;
6387
6388         case ACTION_CANCEL_SHUTDOWN: {
6389                 _cleanup_free_ char *m = NULL;
6390
6391                 if (arg_wall) {
6392                         m = strv_join(arg_wall, " ");
6393                         if (!m) {
6394                                 r = log_oom();
6395                                 goto finish;
6396                         }
6397                 }
6398
6399                 r = send_shutdownd(arg_when, SD_SHUTDOWN_NONE, false, !arg_no_wall, m);
6400                 if (r < 0)
6401                         log_warning("Failed to talk to shutdownd, shutdown hasn't been cancelled: %s", strerror(-r));
6402                 break;
6403         }
6404
6405         case ACTION_RUNLEVEL:
6406         case _ACTION_INVALID:
6407         default:
6408                 assert_not_reached("Unknown action");
6409         }
6410
6411 finish:
6412         pager_close();
6413         ask_password_agent_close();
6414         polkit_agent_close();
6415
6416         strv_free(arg_types);
6417         strv_free(arg_states);
6418         strv_free(arg_properties);
6419
6420         return r < 0 ? EXIT_FAILURE : r;
6421 }