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