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