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