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