chiark / gitweb /
systemctl: handle correctly template units for edit verb
[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 typedef struct WaitData {
2274         Set *set;
2275
2276         char *name;
2277         char *result;
2278 } WaitData;
2279
2280 static int wait_filter(sd_bus *bus, sd_bus_message *m, void *data, sd_bus_error *error) {
2281         WaitData *d = data;
2282
2283         assert(bus);
2284         assert(m);
2285         assert(d);
2286
2287         log_debug("Got D-Bus request: %s.%s() on %s",
2288                   sd_bus_message_get_interface(m),
2289                   sd_bus_message_get_member(m),
2290                   sd_bus_message_get_path(m));
2291
2292         if (sd_bus_message_is_signal(m, "org.freedesktop.DBus.Local", "Disconnected")) {
2293                 log_error("Warning! D-Bus connection terminated.");
2294                 sd_bus_close(bus);
2295         } else if (sd_bus_message_is_signal(m, "org.freedesktop.systemd1.Manager", "JobRemoved")) {
2296                 uint32_t id;
2297                 const char *path, *result, *unit;
2298                 char *ret;
2299                 int r;
2300
2301                 r = sd_bus_message_read(m, "uoss", &id, &path, &unit, &result);
2302                 if (r >= 0) {
2303                         ret = set_remove(d->set, (char*) path);
2304                         if (!ret)
2305                                 return 0;
2306
2307                         free(ret);
2308
2309                         if (!isempty(result))
2310                                 d->result = strdup(result);
2311
2312                         if (!isempty(unit))
2313                                 d->name = strdup(unit);
2314
2315                         return 0;
2316                 }
2317 #ifndef NOLEGACY
2318                 r = sd_bus_message_read(m, "uos", &id, &path, &result);
2319                 if (r >= 0) {
2320                         ret = set_remove(d->set, (char*) path);
2321                         if (!ret)
2322                                 return 0;
2323
2324                         free(ret);
2325
2326                         if (*result)
2327                                 d->result = strdup(result);
2328
2329                         return 0;
2330                 }
2331 #endif
2332
2333                 bus_log_parse_error(r);
2334         }
2335
2336         return 0;
2337 }
2338
2339 static int enable_wait_for_jobs(sd_bus *bus) {
2340         int r;
2341
2342         assert(bus);
2343
2344         r = sd_bus_add_match(
2345                         bus,
2346                         NULL,
2347                         "type='signal',"
2348                         "sender='org.freedesktop.systemd1',"
2349                         "interface='org.freedesktop.systemd1.Manager',"
2350                         "member='JobRemoved',"
2351                         "path='/org/freedesktop/systemd1'",
2352                         NULL, NULL);
2353         if (r < 0) {
2354                 log_error("Failed to add match");
2355                 return -EIO;
2356         }
2357
2358         /* This is slightly dirty, since we don't undo the match registrations. */
2359         return 0;
2360 }
2361
2362 static int bus_process_wait(sd_bus *bus) {
2363         int r;
2364
2365         for (;;) {
2366                 r = sd_bus_process(bus, NULL);
2367                 if (r < 0)
2368                         return r;
2369                 if (r > 0)
2370                         return 0;
2371                 r = sd_bus_wait(bus, (uint64_t) -1);
2372                 if (r < 0)
2373                         return r;
2374         }
2375 }
2376
2377 static int check_wait_response(WaitData *d) {
2378         int r = 0;
2379
2380         assert(d->result);
2381
2382         if (!arg_quiet) {
2383                 if (streq(d->result, "timeout"))
2384                         log_error("Job for %s timed out.", strna(d->name));
2385                 else if (streq(d->result, "canceled"))
2386                         log_error("Job for %s canceled.", strna(d->name));
2387                 else if (streq(d->result, "dependency"))
2388                         log_error("A dependency job for %s failed. See 'journalctl -xe' for details.", strna(d->name));
2389                 else if (!streq(d->result, "done") && !streq(d->result, "skipped")) {
2390                         if (d->name) {
2391                                 bool quotes;
2392
2393                                 quotes = chars_intersect(d->name, SHELL_NEED_QUOTES);
2394
2395                                 log_error("Job for %s failed. See \"systemctl status %s%s%s\" and \"journalctl -xe\" for details.",
2396                                           d->name,
2397                                           quotes ? "'" : "", d->name, quotes ? "'" : "");
2398                         } else
2399                                 log_error("Job failed. See \"journalctl -xe\" for details.");
2400                 }
2401         }
2402
2403         if (streq(d->result, "timeout"))
2404                 r = -ETIME;
2405         else if (streq(d->result, "canceled"))
2406                 r = -ECANCELED;
2407         else if (streq(d->result, "dependency"))
2408                 r = -EIO;
2409         else if (!streq(d->result, "done") && !streq(d->result, "skipped"))
2410                 r = -EIO;
2411
2412         return r;
2413 }
2414
2415 static int wait_for_jobs(sd_bus *bus, Set *s) {
2416         _cleanup_bus_slot_unref_ sd_bus_slot *slot = NULL;
2417         WaitData d = { .set = s };
2418         int r = 0, q;
2419
2420         assert(bus);
2421         assert(s);
2422
2423         q = sd_bus_add_filter(bus, &slot, wait_filter, &d);
2424         if (q < 0)
2425                 return log_oom();
2426
2427         while (!set_isempty(s)) {
2428                 q = bus_process_wait(bus);
2429                 if (q < 0)
2430                         return log_error_errno(q, "Failed to wait for response: %m");
2431
2432                 if (d.result) {
2433                         q = check_wait_response(&d);
2434                         /* Return the first error as it is most likely to be
2435                          * meaningful. */
2436                         if (q < 0 && r == 0)
2437                                 r = q;
2438                         log_debug("Got result %s/%s for job %s",
2439                                   strna(d.result), strerror(-q), strna(d.name));
2440                 }
2441
2442                 free(d.name);
2443                 d.name = NULL;
2444
2445                 free(d.result);
2446                 d.result = NULL;
2447         }
2448
2449         return r;
2450 }
2451
2452 static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet) {
2453         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2454         _cleanup_free_ char *n = NULL, *state = NULL;
2455         const char *path;
2456         int r;
2457
2458         assert(name);
2459
2460         n = unit_name_mangle(name, MANGLE_NOGLOB);
2461         if (!n)
2462                 return log_oom();
2463
2464         /* We don't use unit_dbus_path_from_name() directly since we
2465          * don't want to load the unit if it isn't loaded. */
2466
2467         r = sd_bus_call_method(
2468                         bus,
2469                         "org.freedesktop.systemd1",
2470                         "/org/freedesktop/systemd1",
2471                         "org.freedesktop.systemd1.Manager",
2472                         "GetUnit",
2473                         NULL,
2474                         &reply,
2475                         "s", n);
2476         if (r < 0) {
2477                 if (!quiet)
2478                         puts("unknown");
2479                 return 0;
2480         }
2481
2482         r = sd_bus_message_read(reply, "o", &path);
2483         if (r < 0)
2484                 return bus_log_parse_error(r);
2485
2486         r = sd_bus_get_property_string(
2487                         bus,
2488                         "org.freedesktop.systemd1",
2489                         path,
2490                         "org.freedesktop.systemd1.Unit",
2491                         "ActiveState",
2492                         NULL,
2493                         &state);
2494         if (r < 0) {
2495                 if (!quiet)
2496                         puts("unknown");
2497                 return 0;
2498         }
2499
2500         if (!quiet)
2501                 puts(state);
2502
2503         return nulstr_contains(good_states, state);
2504 }
2505
2506 static int check_triggering_units(
2507                 sd_bus *bus,
2508                 const char *name) {
2509
2510         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2511         _cleanup_free_ char *path = NULL, *n = NULL, *state = NULL;
2512         _cleanup_strv_free_ char **triggered_by = NULL;
2513         bool print_warning_label = true;
2514         char **i;
2515         int r;
2516
2517         n = unit_name_mangle(name, MANGLE_NOGLOB);
2518         if (!n)
2519                 return log_oom();
2520
2521         path = unit_dbus_path_from_name(n);
2522         if (!path)
2523                 return log_oom();
2524
2525         r = sd_bus_get_property_string(
2526                         bus,
2527                         "org.freedesktop.systemd1",
2528                         path,
2529                         "org.freedesktop.systemd1.Unit",
2530                         "LoadState",
2531                         &error,
2532                         &state);
2533         if (r < 0) {
2534                 log_error("Failed to get load state of %s: %s", n, bus_error_message(&error, r));
2535                 return r;
2536         }
2537
2538         if (streq(state, "masked"))
2539                 return 0;
2540
2541         r = sd_bus_get_property_strv(
2542                         bus,
2543                         "org.freedesktop.systemd1",
2544                         path,
2545                         "org.freedesktop.systemd1.Unit",
2546                         "TriggeredBy",
2547                         &error,
2548                         &triggered_by);
2549         if (r < 0) {
2550                 log_error("Failed to get triggered by array of %s: %s", n, bus_error_message(&error, r));
2551                 return r;
2552         }
2553
2554         STRV_FOREACH(i, triggered_by) {
2555                 r = check_one_unit(bus, *i, "active\0reloading\0", true);
2556                 if (r < 0)
2557                         return log_error_errno(r, "Failed to check unit: %m");
2558
2559                 if (r == 0)
2560                         continue;
2561
2562                 if (print_warning_label) {
2563                         log_warning("Warning: Stopping %s, but it can still be activated by:", n);
2564                         print_warning_label = false;
2565                 }
2566
2567                 log_warning("  %s", *i);
2568         }
2569
2570         return 0;
2571 }
2572
2573 static const struct {
2574         const char *verb;
2575         const char *method;
2576 } unit_actions[] = {
2577         { "start",                 "StartUnit" },
2578         { "stop",                  "StopUnit" },
2579         { "condstop",              "StopUnit" },
2580         { "reload",                "ReloadUnit" },
2581         { "restart",               "RestartUnit" },
2582         { "try-restart",           "TryRestartUnit" },
2583         { "condrestart",           "TryRestartUnit" },
2584         { "reload-or-restart",     "ReloadOrRestartUnit" },
2585         { "reload-or-try-restart", "ReloadOrTryRestartUnit" },
2586         { "condreload",            "ReloadOrTryRestartUnit" },
2587         { "force-reload",          "ReloadOrTryRestartUnit" }
2588 };
2589
2590 static const char *verb_to_method(const char *verb) {
2591        uint i;
2592
2593        for (i = 0; i < ELEMENTSOF(unit_actions); i++)
2594                 if (streq_ptr(unit_actions[i].verb, verb))
2595                         return unit_actions[i].method;
2596
2597        return "StartUnit";
2598 }
2599
2600 static const char *method_to_verb(const char *method) {
2601        uint i;
2602
2603        for (i = 0; i < ELEMENTSOF(unit_actions); i++)
2604                 if (streq_ptr(unit_actions[i].method, method))
2605                         return unit_actions[i].verb;
2606
2607        return "n/a";
2608 }
2609
2610 static int start_unit_one(
2611                 sd_bus *bus,
2612                 const char *method,
2613                 const char *name,
2614                 const char *mode,
2615                 sd_bus_error *error,
2616                 Set *s) {
2617
2618         _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
2619         const char *path;
2620         int r;
2621
2622         assert(method);
2623         assert(name);
2624         assert(mode);
2625         assert(error);
2626
2627         log_debug("Calling manager for %s on %s, %s", method, name, mode);
2628
2629         r = sd_bus_message_new_method_call(
2630                         bus,
2631                         &m,
2632                         "org.freedesktop.systemd1",
2633                         "/org/freedesktop/systemd1",
2634                         "org.freedesktop.systemd1.Manager",
2635                         method);
2636         if (r < 0)
2637                 return bus_log_create_error(r);
2638
2639         r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
2640         if (r < 0)
2641                 return bus_log_create_error(r);
2642
2643         r = sd_bus_message_append(m, "ss", name, mode);
2644         if (r < 0)
2645                 return bus_log_create_error(r);
2646
2647         r = sd_bus_call(bus, m, 0, error, &reply);
2648         if (r < 0) {
2649                 const char *verb;
2650
2651                 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
2652                         /* There's always a fallback possible for
2653                          * legacy actions. */
2654                         return -EADDRNOTAVAIL;
2655
2656                 verb = method_to_verb(method);
2657
2658                 log_error("Failed to %s %s: %s", verb, name, bus_error_message(error, r));
2659                 return r;
2660         }
2661
2662         r = sd_bus_message_read(reply, "o", &path);
2663         if (r < 0)
2664                 return bus_log_parse_error(r);
2665
2666         if (need_daemon_reload(bus, name) > 0)
2667                 log_warning("Warning: Unit file of %s changed on disk, 'systemctl%s daemon-reload' recommended.",
2668                             name, arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
2669
2670         if (s) {
2671                 char *p;
2672
2673                 p = strdup(path);
2674                 if (!p)
2675                         return log_oom();
2676
2677                 log_debug("Adding %s to the set", p);
2678                 r = set_consume(s, p);
2679                 if (r < 0)
2680                         return log_oom();
2681         }
2682
2683         return 0;
2684 }
2685
2686 static int expand_names(sd_bus *bus, char **names, const char* suffix, char ***ret) {
2687
2688         _cleanup_strv_free_ char **mangled = NULL, **globs = NULL;
2689         char **name;
2690         int r = 0, i;
2691
2692         STRV_FOREACH(name, names) {
2693                 char *t;
2694
2695                 if (suffix)
2696                         t = unit_name_mangle_with_suffix(*name, MANGLE_GLOB, suffix);
2697                 else
2698                         t = unit_name_mangle(*name, MANGLE_GLOB);
2699                 if (!t)
2700                         return log_oom();
2701
2702                 if (string_is_glob(t))
2703                         r = strv_consume(&globs, t);
2704                 else
2705                         r = strv_consume(&mangled, t);
2706                 if (r < 0)
2707                         return log_oom();
2708         }
2709
2710         /* Query the manager only if any of the names are a glob, since
2711          * this is fairly expensive */
2712         if (!strv_isempty(globs)) {
2713                 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2714                 _cleanup_free_ UnitInfo *unit_infos = NULL;
2715
2716                 r = get_unit_list(bus, NULL, globs, &unit_infos, 0, &reply);
2717                 if (r < 0)
2718                         return r;
2719
2720                 for (i = 0; i < r; i++)
2721                         if (strv_extend(&mangled, unit_infos[i].id) < 0)
2722                                 return log_oom();
2723         }
2724
2725         *ret = mangled;
2726         mangled = NULL; /* do not free */
2727
2728         return 0;
2729 }
2730
2731 static const struct {
2732         const char *target;
2733         const char *verb;
2734         const char *mode;
2735 } action_table[_ACTION_MAX] = {
2736         [ACTION_HALT]         = { SPECIAL_HALT_TARGET,         "halt",         "replace-irreversibly" },
2737         [ACTION_POWEROFF]     = { SPECIAL_POWEROFF_TARGET,     "poweroff",     "replace-irreversibly" },
2738         [ACTION_REBOOT]       = { SPECIAL_REBOOT_TARGET,       "reboot",       "replace-irreversibly" },
2739         [ACTION_KEXEC]        = { SPECIAL_KEXEC_TARGET,        "kexec",        "replace-irreversibly" },
2740         [ACTION_RUNLEVEL2]    = { SPECIAL_RUNLEVEL2_TARGET,    NULL,           "isolate" },
2741         [ACTION_RUNLEVEL3]    = { SPECIAL_RUNLEVEL3_TARGET,    NULL,           "isolate" },
2742         [ACTION_RUNLEVEL4]    = { SPECIAL_RUNLEVEL4_TARGET,    NULL,           "isolate" },
2743         [ACTION_RUNLEVEL5]    = { SPECIAL_RUNLEVEL5_TARGET,    NULL,           "isolate" },
2744         [ACTION_RESCUE]       = { SPECIAL_RESCUE_TARGET,       "rescue",       "isolate" },
2745         [ACTION_EMERGENCY]    = { SPECIAL_EMERGENCY_TARGET,    "emergency",    "isolate" },
2746         [ACTION_DEFAULT]      = { SPECIAL_DEFAULT_TARGET,      "default",      "isolate" },
2747         [ACTION_EXIT]         = { SPECIAL_EXIT_TARGET,         "exit",         "replace-irreversibly" },
2748         [ACTION_SUSPEND]      = { SPECIAL_SUSPEND_TARGET,      "suspend",      "replace-irreversibly" },
2749         [ACTION_HIBERNATE]    = { SPECIAL_HIBERNATE_TARGET,    "hibernate",    "replace-irreversibly" },
2750         [ACTION_HYBRID_SLEEP] = { SPECIAL_HYBRID_SLEEP_TARGET, "hybrid-sleep", "replace-irreversibly" },
2751 };
2752
2753 static enum action verb_to_action(const char *verb) {
2754         enum action i;
2755
2756         for (i = _ACTION_INVALID; i < _ACTION_MAX; i++)
2757                 if (streq_ptr(action_table[i].verb, verb))
2758                         return i;
2759
2760         return _ACTION_INVALID;
2761 }
2762
2763 static int start_unit(sd_bus *bus, char **args) {
2764         _cleanup_set_free_free_ Set *s = NULL;
2765         _cleanup_strv_free_ char **names = NULL;
2766         const char *method, *mode, *one_name, *suffix = NULL;
2767         char **name;
2768         int r = 0;
2769
2770         assert(bus);
2771
2772         ask_password_agent_open_if_enabled();
2773
2774         if (arg_action == ACTION_SYSTEMCTL) {
2775                 enum action action;
2776                 method = verb_to_method(args[0]);
2777                 action = verb_to_action(args[0]);
2778
2779                 if (streq(args[0], "isolate")) {
2780                         mode = "isolate";
2781                         suffix = ".target";
2782                 } else
2783                         mode = action_table[action].mode ?: arg_job_mode;
2784
2785                 one_name = action_table[action].target;
2786         } else {
2787                 assert(arg_action < ELEMENTSOF(action_table));
2788                 assert(action_table[arg_action].target);
2789
2790                 method = "StartUnit";
2791
2792                 mode = action_table[arg_action].mode;
2793                 one_name = action_table[arg_action].target;
2794         }
2795
2796         if (one_name)
2797                 names = strv_new(one_name, NULL);
2798         else {
2799                 r = expand_names(bus, args + 1, suffix, &names);
2800                 if (r < 0)
2801                         log_error_errno(r, "Failed to expand names: %m");
2802         }
2803
2804         if (!arg_no_block) {
2805                 r = enable_wait_for_jobs(bus);
2806                 if (r < 0)
2807                         return log_error_errno(r, "Could not watch jobs: %m");
2808
2809                 s = set_new(&string_hash_ops);
2810                 if (!s)
2811                         return log_oom();
2812         }
2813
2814         STRV_FOREACH(name, names) {
2815                 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2816                 int q;
2817
2818                 q = start_unit_one(bus, method, *name, mode, &error, s);
2819                 if (r >= 0 && q < 0)
2820                         r = translate_bus_error_to_exit_status(q, &error);
2821         }
2822
2823         if (!arg_no_block) {
2824                 int q;
2825
2826                 q = wait_for_jobs(bus, s);
2827                 if (q < 0)
2828                         return q;
2829
2830                 /* When stopping units, warn if they can still be triggered by
2831                  * another active unit (socket, path, timer) */
2832                 if (!arg_quiet && streq(method, "StopUnit"))
2833                         STRV_FOREACH(name, names)
2834                                 check_triggering_units(bus, *name);
2835         }
2836
2837         return r;
2838 }
2839
2840 /* Ask systemd-logind, which might grant access to unprivileged users
2841  * through PolicyKit */
2842 static int reboot_with_logind(sd_bus *bus, enum action a) {
2843 #ifdef HAVE_LOGIND
2844         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2845         const char *method;
2846         int r;
2847
2848         if (!bus)
2849                 return -EIO;
2850
2851         polkit_agent_open_if_enabled();
2852
2853         switch (a) {
2854
2855         case ACTION_REBOOT:
2856                 method = "Reboot";
2857                 break;
2858
2859         case ACTION_POWEROFF:
2860                 method = "PowerOff";
2861                 break;
2862
2863         case ACTION_SUSPEND:
2864                 method = "Suspend";
2865                 break;
2866
2867         case ACTION_HIBERNATE:
2868                 method = "Hibernate";
2869                 break;
2870
2871         case ACTION_HYBRID_SLEEP:
2872                 method = "HybridSleep";
2873                 break;
2874
2875         default:
2876                 return -EINVAL;
2877         }
2878
2879         r = sd_bus_call_method(
2880                         bus,
2881                         "org.freedesktop.login1",
2882                         "/org/freedesktop/login1",
2883                         "org.freedesktop.login1.Manager",
2884                         method,
2885                         &error,
2886                         NULL,
2887                         "b", arg_ask_password);
2888         if (r < 0)
2889                 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
2890
2891         return r;
2892 #else
2893         return -ENOSYS;
2894 #endif
2895 }
2896
2897 static int check_inhibitors(sd_bus *bus, enum action a) {
2898 #ifdef HAVE_LOGIND
2899         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2900         _cleanup_strv_free_ char **sessions = NULL;
2901         const char *what, *who, *why, *mode;
2902         uint32_t uid, pid;
2903         unsigned c = 0;
2904         char **s;
2905         int r;
2906
2907         if (!bus)
2908                 return 0;
2909
2910         if (arg_ignore_inhibitors || arg_force > 0)
2911                 return 0;
2912
2913         if (arg_when > 0)
2914                 return 0;
2915
2916         if (geteuid() == 0)
2917                 return 0;
2918
2919         if (!on_tty())
2920                 return 0;
2921
2922         r = sd_bus_call_method(
2923                         bus,
2924                         "org.freedesktop.login1",
2925                         "/org/freedesktop/login1",
2926                         "org.freedesktop.login1.Manager",
2927                         "ListInhibitors",
2928                         NULL,
2929                         &reply,
2930                         NULL);
2931         if (r < 0)
2932                 /* If logind is not around, then there are no inhibitors... */
2933                 return 0;
2934
2935         r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssuu)");
2936         if (r < 0)
2937                 return bus_log_parse_error(r);
2938
2939         while ((r = sd_bus_message_read(reply, "(ssssuu)", &what, &who, &why, &mode, &uid, &pid)) > 0) {
2940                 _cleanup_free_ char *comm = NULL, *user = NULL;
2941                 _cleanup_strv_free_ char **sv = NULL;
2942
2943                 if (!streq(mode, "block"))
2944                         continue;
2945
2946                 sv = strv_split(what, ":");
2947                 if (!sv)
2948                         return log_oom();
2949
2950                 if (!strv_contains(sv,
2951                                   a == ACTION_HALT ||
2952                                   a == ACTION_POWEROFF ||
2953                                   a == ACTION_REBOOT ||
2954                                   a == ACTION_KEXEC ? "shutdown" : "sleep"))
2955                         continue;
2956
2957                 get_process_comm(pid, &comm);
2958                 user = uid_to_name(uid);
2959
2960                 log_warning("Operation inhibited by \"%s\" (PID "PID_FMT" \"%s\", user %s), reason is \"%s\".",
2961                             who, pid, strna(comm), strna(user), why);
2962
2963                 c++;
2964         }
2965         if (r < 0)
2966                 return bus_log_parse_error(r);
2967
2968         r = sd_bus_message_exit_container(reply);
2969         if (r < 0)
2970                 return bus_log_parse_error(r);
2971
2972         /* Check for current sessions */
2973         sd_get_sessions(&sessions);
2974         STRV_FOREACH(s, sessions) {
2975                 _cleanup_free_ char *type = NULL, *tty = NULL, *seat = NULL, *user = NULL, *service = NULL, *class = NULL;
2976
2977                 if (sd_session_get_uid(*s, &uid) < 0 || uid == getuid())
2978                         continue;
2979
2980                 if (sd_session_get_class(*s, &class) < 0 || !streq(class, "user"))
2981                         continue;
2982
2983                 if (sd_session_get_type(*s, &type) < 0 || (!streq(type, "x11") && !streq(type, "tty")))
2984                         continue;
2985
2986                 sd_session_get_tty(*s, &tty);
2987                 sd_session_get_seat(*s, &seat);
2988                 sd_session_get_service(*s, &service);
2989                 user = uid_to_name(uid);
2990
2991                 log_warning("User %s is logged in on %s.", strna(user), isempty(tty) ? (isempty(seat) ? strna(service) : seat) : tty);
2992                 c++;
2993         }
2994
2995         if (c <= 0)
2996                 return 0;
2997
2998         log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
2999                   action_table[a].verb);
3000
3001         return -EPERM;
3002 #else
3003         return 0;
3004 #endif
3005 }
3006
3007 static int start_special(sd_bus *bus, char **args) {
3008         enum action a;
3009         int r;
3010
3011         assert(args);
3012
3013         a = verb_to_action(args[0]);
3014
3015         r = check_inhibitors(bus, a);
3016         if (r < 0)
3017                 return r;
3018
3019         if (arg_force >= 2 && geteuid() != 0) {
3020                 log_error("Must be root.");
3021                 return -EPERM;
3022         }
3023
3024         if (arg_force >= 2 &&
3025             (a == ACTION_HALT ||
3026              a == ACTION_POWEROFF ||
3027              a == ACTION_REBOOT))
3028                 return halt_now(a);
3029
3030         if (arg_force >= 1 &&
3031             (a == ACTION_HALT ||
3032              a == ACTION_POWEROFF ||
3033              a == ACTION_REBOOT ||
3034              a == ACTION_KEXEC ||
3035              a == ACTION_EXIT))
3036                 return daemon_reload(bus, args);
3037
3038         /* first try logind, to allow authentication with polkit */
3039         if (geteuid() != 0 &&
3040             (a == ACTION_POWEROFF ||
3041              a == ACTION_REBOOT ||
3042              a == ACTION_SUSPEND ||
3043              a == ACTION_HIBERNATE ||
3044              a == ACTION_HYBRID_SLEEP)) {
3045                 r = reboot_with_logind(bus, a);
3046                 if (r >= 0)
3047                         return r;
3048         }
3049
3050         r = start_unit(bus, args);
3051         if (r == EXIT_SUCCESS)
3052                 warn_wall(a);
3053
3054         return r;
3055 }
3056
3057 static int check_unit_generic(sd_bus *bus, int code, const char *good_states, char **args) {
3058         _cleanup_strv_free_ char **names = NULL;
3059         char **name;
3060         int r;
3061
3062         assert(bus);
3063         assert(args);
3064
3065         r = expand_names(bus, args, NULL, &names);
3066         if (r < 0)
3067                 return log_error_errno(r, "Failed to expand names: %m");
3068
3069         STRV_FOREACH(name, names) {
3070                 int state;
3071
3072                 state = check_one_unit(bus, *name, good_states, arg_quiet);
3073                 if (state < 0)
3074                         return state;
3075                 if (state == 0)
3076                         r = code;
3077         }
3078
3079         return r;
3080 }
3081
3082 static int check_unit_active(sd_bus *bus, char **args) {
3083         /* According to LSB: 3, "program is not running" */
3084         return check_unit_generic(bus, 3, "active\0reloading\0", args + 1);
3085 }
3086
3087 static int check_unit_failed(sd_bus *bus, char **args) {
3088         return check_unit_generic(bus, 1, "failed\0", args + 1);
3089 }
3090
3091 static int kill_unit(sd_bus *bus, char **args) {
3092         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3093         _cleanup_strv_free_ char **names = NULL;
3094         char **name;
3095         int r, q;
3096
3097         assert(bus);
3098         assert(args);
3099
3100         if (!arg_kill_who)
3101                 arg_kill_who = "all";
3102
3103         r = expand_names(bus, args + 1, NULL, &names);
3104         if (r < 0)
3105                 log_error_errno(r, "Failed to expand names: %m");
3106
3107         STRV_FOREACH(name, names) {
3108                 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
3109
3110                 q = sd_bus_message_new_method_call(
3111                                 bus,
3112                                 &m,
3113                                 "org.freedesktop.systemd1",
3114                                 "/org/freedesktop/systemd1",
3115                                 "org.freedesktop.systemd1.Manager",
3116                                 "KillUnit");
3117                 if (q < 0)
3118                         return bus_log_create_error(q);
3119
3120                 q = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
3121                 if (q < 0)
3122                         return bus_log_create_error(q);
3123
3124                 q = sd_bus_message_append(m, "ssi", *names, arg_kill_who, arg_signal);
3125                 if (q < 0)
3126                         return bus_log_create_error(q);
3127
3128                 q = sd_bus_call(bus, m, 0, &error, NULL);
3129                 if (q < 0) {
3130                         log_error("Failed to kill unit %s: %s", *names, bus_error_message(&error, q));
3131                         if (r == 0)
3132                                 r = q;
3133                 }
3134         }
3135
3136         return r;
3137 }
3138
3139 typedef struct ExecStatusInfo {
3140         char *name;
3141
3142         char *path;
3143         char **argv;
3144
3145         bool ignore;
3146
3147         usec_t start_timestamp;
3148         usec_t exit_timestamp;
3149         pid_t pid;
3150         int code;
3151         int status;
3152
3153         LIST_FIELDS(struct ExecStatusInfo, exec);
3154 } ExecStatusInfo;
3155
3156 static void exec_status_info_free(ExecStatusInfo *i) {
3157         assert(i);
3158
3159         free(i->name);
3160         free(i->path);
3161         strv_free(i->argv);
3162         free(i);
3163 }
3164
3165 static int exec_status_info_deserialize(sd_bus_message *m, ExecStatusInfo *i) {
3166         uint64_t start_timestamp, exit_timestamp, start_timestamp_monotonic, exit_timestamp_monotonic;
3167         const char *path;
3168         uint32_t pid;
3169         int32_t code, status;
3170         int ignore, r;
3171
3172         assert(m);
3173         assert(i);
3174
3175         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_STRUCT, "sasbttttuii");
3176         if (r < 0)
3177                 return bus_log_parse_error(r);
3178         else if (r == 0)
3179                 return 0;
3180
3181         r = sd_bus_message_read(m, "s", &path);
3182         if (r < 0)
3183                 return bus_log_parse_error(r);
3184
3185         i->path = strdup(path);
3186         if (!i->path)
3187                 return log_oom();
3188
3189         r = sd_bus_message_read_strv(m, &i->argv);
3190         if (r < 0)
3191                 return bus_log_parse_error(r);
3192
3193         r = sd_bus_message_read(m,
3194                                 "bttttuii",
3195                                 &ignore,
3196                                 &start_timestamp, &start_timestamp_monotonic,
3197                                 &exit_timestamp, &exit_timestamp_monotonic,
3198                                 &pid,
3199                                 &code, &status);
3200         if (r < 0)
3201                 return bus_log_parse_error(r);
3202
3203         i->ignore = ignore;
3204         i->start_timestamp = (usec_t) start_timestamp;
3205         i->exit_timestamp = (usec_t) exit_timestamp;
3206         i->pid = (pid_t) pid;
3207         i->code = code;
3208         i->status = status;
3209
3210         r = sd_bus_message_exit_container(m);
3211         if (r < 0)
3212                 return bus_log_parse_error(r);
3213
3214         return 1;
3215 }
3216
3217 typedef struct UnitStatusInfo {
3218         const char *id;
3219         const char *load_state;
3220         const char *active_state;
3221         const char *sub_state;
3222         const char *unit_file_state;
3223         const char *unit_file_preset;
3224
3225         const char *description;
3226         const char *following;
3227
3228         char **documentation;
3229
3230         const char *fragment_path;
3231         const char *source_path;
3232         const char *control_group;
3233
3234         char **dropin_paths;
3235
3236         const char *load_error;
3237         const char *result;
3238
3239         usec_t inactive_exit_timestamp;
3240         usec_t inactive_exit_timestamp_monotonic;
3241         usec_t active_enter_timestamp;
3242         usec_t active_exit_timestamp;
3243         usec_t inactive_enter_timestamp;
3244
3245         bool need_daemon_reload;
3246
3247         /* Service */
3248         pid_t main_pid;
3249         pid_t control_pid;
3250         const char *status_text;
3251         const char *pid_file;
3252         bool running:1;
3253         int status_errno;
3254
3255         usec_t start_timestamp;
3256         usec_t exit_timestamp;
3257
3258         int exit_code, exit_status;
3259
3260         usec_t condition_timestamp;
3261         bool condition_result;
3262         bool failed_condition_trigger;
3263         bool failed_condition_negate;
3264         const char *failed_condition;
3265         const char *failed_condition_parameter;
3266
3267         usec_t assert_timestamp;
3268         bool assert_result;
3269         bool failed_assert_trigger;
3270         bool failed_assert_negate;
3271         const char *failed_assert;
3272         const char *failed_assert_parameter;
3273
3274         /* Socket */
3275         unsigned n_accepted;
3276         unsigned n_connections;
3277         bool accept;
3278
3279         /* Pairs of type, path */
3280         char **listen;
3281
3282         /* Device */
3283         const char *sysfs_path;
3284
3285         /* Mount, Automount */
3286         const char *where;
3287
3288         /* Swap */
3289         const char *what;
3290
3291         LIST_HEAD(ExecStatusInfo, exec);
3292 } UnitStatusInfo;
3293
3294 static void print_status_info(
3295                 UnitStatusInfo *i,
3296                 bool *ellipsized) {
3297
3298         ExecStatusInfo *p;
3299         const char *active_on, *active_off, *on, *off, *ss;
3300         usec_t timestamp;
3301         char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
3302         char since2[FORMAT_TIMESTAMP_MAX], *s2;
3303         const char *path;
3304         int flags =
3305                 arg_all * OUTPUT_SHOW_ALL |
3306                 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
3307                 on_tty() * OUTPUT_COLOR |
3308                 !arg_quiet * OUTPUT_WARN_CUTOFF |
3309                 arg_full * OUTPUT_FULL_WIDTH;
3310         char **t, **t2;
3311
3312         assert(i);
3313
3314         /* This shows pretty information about a unit. See
3315          * print_property() for a low-level property printer */
3316
3317         if (streq_ptr(i->active_state, "failed")) {
3318                 active_on = ansi_highlight_red();
3319                 active_off = ansi_highlight_off();
3320         } else if (streq_ptr(i->active_state, "active") || streq_ptr(i->active_state, "reloading")) {
3321                 active_on = ansi_highlight_green();
3322                 active_off = ansi_highlight_off();
3323         } else
3324                 active_on = active_off = "";
3325
3326         printf("%s%s%s %s", active_on, draw_special_char(DRAW_BLACK_CIRCLE), active_off, strna(i->id));
3327
3328         if (i->description && !streq_ptr(i->id, i->description))
3329                 printf(" - %s", i->description);
3330
3331         printf("\n");
3332
3333         if (i->following)
3334                 printf("   Follow: unit currently follows state of %s\n", i->following);
3335
3336         if (streq_ptr(i->load_state, "error")) {
3337                 on = ansi_highlight_red();
3338                 off = ansi_highlight_off();
3339         } else
3340                 on = off = "";
3341
3342         path = i->source_path ? i->source_path : i->fragment_path;
3343
3344         if (i->load_error)
3345                 printf("   Loaded: %s%s%s (Reason: %s)\n",
3346                        on, strna(i->load_state), off, i->load_error);
3347         else if (path && !isempty(i->unit_file_state) && !isempty(i->unit_file_preset))
3348                 printf("   Loaded: %s%s%s (%s; %s; vendor preset: %s)\n",
3349                        on, strna(i->load_state), off, path, i->unit_file_state, i->unit_file_preset);
3350         else if (path && !isempty(i->unit_file_state))
3351                 printf("   Loaded: %s%s%s (%s; %s)\n",
3352                        on, strna(i->load_state), off, path, i->unit_file_state);
3353         else if (path)
3354                 printf("   Loaded: %s%s%s (%s)\n",
3355                        on, strna(i->load_state), off, path);
3356         else
3357                 printf("   Loaded: %s%s%s\n",
3358                        on, strna(i->load_state), off);
3359
3360         if (!strv_isempty(i->dropin_paths)) {
3361                 _cleanup_free_ char *dir = NULL;
3362                 bool last = false;
3363                 char ** dropin;
3364
3365                 STRV_FOREACH(dropin, i->dropin_paths) {
3366                         if (! dir || last) {
3367                                 printf(dir ? "        " : "  Drop-In: ");
3368
3369                                 free(dir);
3370                                 dir = NULL;
3371
3372                                 if (path_get_parent(*dropin, &dir) < 0) {
3373                                         log_oom();
3374                                         return;
3375                                 }
3376
3377                                 printf("%s\n           %s", dir,
3378                                        draw_special_char(DRAW_TREE_RIGHT));
3379                         }
3380
3381                         last = ! (*(dropin + 1) && startswith(*(dropin + 1), dir));
3382
3383                         printf("%s%s", basename(*dropin), last ? "\n" : ", ");
3384                 }
3385         }
3386
3387         ss = streq_ptr(i->active_state, i->sub_state) ? NULL : i->sub_state;
3388         if (ss)
3389                 printf("   Active: %s%s (%s)%s",
3390                        active_on, strna(i->active_state), ss, active_off);
3391         else
3392                 printf("   Active: %s%s%s",
3393                        active_on, strna(i->active_state), active_off);
3394
3395         if (!isempty(i->result) && !streq(i->result, "success"))
3396                 printf(" (Result: %s)", i->result);
3397
3398         timestamp = (streq_ptr(i->active_state, "active")      ||
3399                      streq_ptr(i->active_state, "reloading"))   ? i->active_enter_timestamp :
3400                     (streq_ptr(i->active_state, "inactive")    ||
3401                      streq_ptr(i->active_state, "failed"))      ? i->inactive_enter_timestamp :
3402                     streq_ptr(i->active_state, "activating")    ? i->inactive_exit_timestamp :
3403                                                                   i->active_exit_timestamp;
3404
3405         s1 = format_timestamp_relative(since1, sizeof(since1), timestamp);
3406         s2 = format_timestamp(since2, sizeof(since2), timestamp);
3407
3408         if (s1)
3409                 printf(" since %s; %s\n", s2, s1);
3410         else if (s2)
3411                 printf(" since %s\n", s2);
3412         else
3413                 printf("\n");
3414
3415         if (!i->condition_result && i->condition_timestamp > 0) {
3416                 s1 = format_timestamp_relative(since1, sizeof(since1), i->condition_timestamp);
3417                 s2 = format_timestamp(since2, sizeof(since2), i->condition_timestamp);
3418
3419                 printf("Condition: start %scondition failed%s at %s%s%s\n",
3420                        ansi_highlight_yellow(), ansi_highlight_off(),
3421                        s2, s1 ? "; " : "", s1 ? s1 : "");
3422                 if (i->failed_condition_trigger)
3423                         printf("           none of the trigger conditions were met\n");
3424                 else if (i->failed_condition)
3425                         printf("           %s=%s%s was not met\n",
3426                                i->failed_condition,
3427                                i->failed_condition_negate ? "!" : "",
3428                                i->failed_condition_parameter);
3429         }
3430
3431         if (!i->assert_result && i->assert_timestamp > 0) {
3432                 s1 = format_timestamp_relative(since1, sizeof(since1), i->assert_timestamp);
3433                 s2 = format_timestamp(since2, sizeof(since2), i->assert_timestamp);
3434
3435                 printf("   Assert: start %sassertion failed%s at %s%s%s\n",
3436                        ansi_highlight_red(), ansi_highlight_off(),
3437                        s2, s1 ? "; " : "", s1 ? s1 : "");
3438                 if (i->failed_assert_trigger)
3439                         printf("           none of the trigger assertions were met\n");
3440                 else if (i->failed_assert)
3441                         printf("           %s=%s%s was not met\n",
3442                                i->failed_assert,
3443                                i->failed_assert_negate ? "!" : "",
3444                                i->failed_assert_parameter);
3445         }
3446
3447         if (i->sysfs_path)
3448                 printf("   Device: %s\n", i->sysfs_path);
3449         if (i->where)
3450                 printf("    Where: %s\n", i->where);
3451         if (i->what)
3452                 printf("     What: %s\n", i->what);
3453
3454         STRV_FOREACH(t, i->documentation)
3455                 printf(" %*s %s\n", 9, t == i->documentation ? "Docs:" : "", *t);
3456
3457         STRV_FOREACH_PAIR(t, t2, i->listen)
3458                 printf(" %*s %s (%s)\n", 9, t == i->listen ? "Listen:" : "", *t2, *t);
3459
3460         if (i->accept)
3461                 printf(" Accepted: %u; Connected: %u\n", i->n_accepted, i->n_connections);
3462
3463         LIST_FOREACH(exec, p, i->exec) {
3464                 _cleanup_free_ char *argv = NULL;
3465                 bool good;
3466
3467                 /* Only show exited processes here */
3468                 if (p->code == 0)
3469                         continue;
3470
3471                 argv = strv_join(p->argv, " ");
3472                 printf("  Process: %u %s=%s ", p->pid, p->name, strna(argv));
3473
3474                 good = is_clean_exit_lsb(p->code, p->status, NULL);
3475                 if (!good) {
3476                         on = ansi_highlight_red();
3477                         off = ansi_highlight_off();
3478                 } else
3479                         on = off = "";
3480
3481                 printf("%s(code=%s, ", on, sigchld_code_to_string(p->code));
3482
3483                 if (p->code == CLD_EXITED) {
3484                         const char *c;
3485
3486                         printf("status=%i", p->status);
3487
3488                         c = exit_status_to_string(p->status, EXIT_STATUS_SYSTEMD);
3489                         if (c)
3490                                 printf("/%s", c);
3491
3492                 } else
3493                         printf("signal=%s", signal_to_string(p->status));
3494
3495                 printf(")%s\n", off);
3496
3497                 if (i->main_pid == p->pid &&
3498                     i->start_timestamp == p->start_timestamp &&
3499                     i->exit_timestamp == p->start_timestamp)
3500                         /* Let's not show this twice */
3501                         i->main_pid = 0;
3502
3503                 if (p->pid == i->control_pid)
3504                         i->control_pid = 0;
3505         }
3506
3507         if (i->main_pid > 0 || i->control_pid > 0) {
3508                 if (i->main_pid > 0) {
3509                         printf(" Main PID: "PID_FMT, i->main_pid);
3510
3511                         if (i->running) {
3512                                 _cleanup_free_ char *comm = NULL;
3513                                 get_process_comm(i->main_pid, &comm);
3514                                 if (comm)
3515                                         printf(" (%s)", comm);
3516                         } else if (i->exit_code > 0) {
3517                                 printf(" (code=%s, ", sigchld_code_to_string(i->exit_code));
3518
3519                                 if (i->exit_code == CLD_EXITED) {
3520                                         const char *c;
3521
3522                                         printf("status=%i", i->exit_status);
3523
3524                                         c = exit_status_to_string(i->exit_status, EXIT_STATUS_SYSTEMD);
3525                                         if (c)
3526                                                 printf("/%s", c);
3527
3528                                 } else
3529                                         printf("signal=%s", signal_to_string(i->exit_status));
3530                                 printf(")");
3531                         }
3532
3533                         if (i->control_pid > 0)
3534                                 printf(";");
3535                 }
3536
3537                 if (i->control_pid > 0) {
3538                         _cleanup_free_ char *c = NULL;
3539
3540                         printf(" %8s: "PID_FMT, i->main_pid ? "" : " Control", i->control_pid);
3541
3542                         get_process_comm(i->control_pid, &c);
3543                         if (c)
3544                                 printf(" (%s)", c);
3545                 }
3546
3547                 printf("\n");
3548         }
3549
3550         if (i->status_text)
3551                 printf("   Status: \"%s\"\n", i->status_text);
3552         if (i->status_errno > 0)
3553                 printf("    Error: %i (%s)\n", i->status_errno, strerror(i->status_errno));
3554
3555         if (i->control_group &&
3556             (i->main_pid > 0 || i->control_pid > 0 ||
3557              ((arg_transport != BUS_TRANSPORT_LOCAL && arg_transport != BUS_TRANSPORT_CONTAINER) || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, i->control_group, false) == 0))) {
3558                 unsigned c;
3559
3560                 printf("   CGroup: %s\n", i->control_group);
3561
3562                 if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_CONTAINER) {
3563                         unsigned k = 0;
3564                         pid_t extra[2];
3565                         static const char prefix[] = "           ";
3566
3567                         c = columns();
3568                         if (c > sizeof(prefix) - 1)
3569                                 c -= sizeof(prefix) - 1;
3570                         else
3571                                 c = 0;
3572
3573                         if (i->main_pid > 0)
3574                                 extra[k++] = i->main_pid;
3575
3576                         if (i->control_pid > 0)
3577                                 extra[k++] = i->control_pid;
3578
3579                         show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, i->control_group, prefix, c, false, extra, k, flags);
3580                 }
3581         }
3582
3583         if (i->id && arg_transport == BUS_TRANSPORT_LOCAL) {
3584                 show_journal_by_unit(stdout,
3585                                      i->id,
3586                                      arg_output,
3587                                      0,
3588                                      i->inactive_exit_timestamp_monotonic,
3589                                      arg_lines,
3590                                      getuid(),
3591                                      flags | OUTPUT_BEGIN_NEWLINE,
3592                                      arg_scope == UNIT_FILE_SYSTEM,
3593                                      ellipsized);
3594         }
3595
3596         if (i->need_daemon_reload)
3597                 printf("\n%sWarning:%s Unit file changed on disk, 'systemctl %sdaemon-reload' recommended.\n",
3598                        ansi_highlight_red(),
3599                        ansi_highlight_off(),
3600                        arg_scope == UNIT_FILE_SYSTEM ? "" : "--user ");
3601 }
3602
3603 static void show_unit_help(UnitStatusInfo *i) {
3604         char **p;
3605
3606         assert(i);
3607
3608         if (!i->documentation) {
3609                 log_info("Documentation for %s not known.", i->id);
3610                 return;
3611         }
3612
3613         STRV_FOREACH(p, i->documentation)
3614                 if (startswith(*p, "man:"))
3615                         show_man_page(*p + 4, false);
3616                 else
3617                         log_info("Can't show: %s", *p);
3618 }
3619
3620 static int status_property(const char *name, sd_bus_message *m, UnitStatusInfo *i, const char *contents) {
3621         int r;
3622
3623         assert(name);
3624         assert(m);
3625         assert(i);
3626
3627         switch (contents[0]) {
3628
3629         case SD_BUS_TYPE_STRING: {
3630                 const char *s;
3631
3632                 r = sd_bus_message_read(m, "s", &s);
3633                 if (r < 0)
3634                         return bus_log_parse_error(r);
3635
3636                 if (!isempty(s)) {
3637                         if (streq(name, "Id"))
3638                                 i->id = s;
3639                         else if (streq(name, "LoadState"))
3640                                 i->load_state = s;
3641                         else if (streq(name, "ActiveState"))
3642                                 i->active_state = s;
3643                         else if (streq(name, "SubState"))
3644                                 i->sub_state = s;
3645                         else if (streq(name, "Description"))
3646                                 i->description = s;
3647                         else if (streq(name, "FragmentPath"))
3648                                 i->fragment_path = s;
3649                         else if (streq(name, "SourcePath"))
3650                                 i->source_path = s;
3651 #ifndef NOLEGACY
3652                         else if (streq(name, "DefaultControlGroup")) {
3653                                 const char *e;
3654                                 e = startswith(s, SYSTEMD_CGROUP_CONTROLLER ":");
3655                                 if (e)
3656                                         i->control_group = e;
3657                         }
3658 #endif
3659                         else if (streq(name, "ControlGroup"))
3660                                 i->control_group = s;
3661                         else if (streq(name, "StatusText"))
3662                                 i->status_text = s;
3663                         else if (streq(name, "PIDFile"))
3664                                 i->pid_file = s;
3665                         else if (streq(name, "SysFSPath"))
3666                                 i->sysfs_path = s;
3667                         else if (streq(name, "Where"))
3668                                 i->where = s;
3669                         else if (streq(name, "What"))
3670                                 i->what = s;
3671                         else if (streq(name, "Following"))
3672                                 i->following = s;
3673                         else if (streq(name, "UnitFileState"))
3674                                 i->unit_file_state = s;
3675                         else if (streq(name, "UnitFilePreset"))
3676                                 i->unit_file_preset = s;
3677                         else if (streq(name, "Result"))
3678                                 i->result = s;
3679                 }
3680
3681                 break;
3682         }
3683
3684         case SD_BUS_TYPE_BOOLEAN: {
3685                 int b;
3686
3687                 r = sd_bus_message_read(m, "b", &b);
3688                 if (r < 0)
3689                         return bus_log_parse_error(r);
3690
3691                 if (streq(name, "Accept"))
3692                         i->accept = b;
3693                 else if (streq(name, "NeedDaemonReload"))
3694                         i->need_daemon_reload = b;
3695                 else if (streq(name, "ConditionResult"))
3696                         i->condition_result = b;
3697                 else if (streq(name, "AssertResult"))
3698                         i->assert_result = b;
3699
3700                 break;
3701         }
3702
3703         case SD_BUS_TYPE_UINT32: {
3704                 uint32_t u;
3705
3706                 r = sd_bus_message_read(m, "u", &u);
3707                 if (r < 0)
3708                         return bus_log_parse_error(r);
3709
3710                 if (streq(name, "MainPID")) {
3711                         if (u > 0) {
3712                                 i->main_pid = (pid_t) u;
3713                                 i->running = true;
3714                         }
3715                 } else if (streq(name, "ControlPID"))
3716                         i->control_pid = (pid_t) u;
3717                 else if (streq(name, "ExecMainPID")) {
3718                         if (u > 0)
3719                                 i->main_pid = (pid_t) u;
3720                 } else if (streq(name, "NAccepted"))
3721                         i->n_accepted = u;
3722                 else if (streq(name, "NConnections"))
3723                         i->n_connections = u;
3724
3725                 break;
3726         }
3727
3728         case SD_BUS_TYPE_INT32: {
3729                 int32_t j;
3730
3731                 r = sd_bus_message_read(m, "i", &j);
3732                 if (r < 0)
3733                         return bus_log_parse_error(r);
3734
3735                 if (streq(name, "ExecMainCode"))
3736                         i->exit_code = (int) j;
3737                 else if (streq(name, "ExecMainStatus"))
3738                         i->exit_status = (int) j;
3739                 else if (streq(name, "StatusErrno"))
3740                         i->status_errno = (int) j;
3741
3742                 break;
3743         }
3744
3745         case SD_BUS_TYPE_UINT64: {
3746                 uint64_t u;
3747
3748                 r = sd_bus_message_read(m, "t", &u);
3749                 if (r < 0)
3750                         return bus_log_parse_error(r);
3751
3752                 if (streq(name, "ExecMainStartTimestamp"))
3753                         i->start_timestamp = (usec_t) u;
3754                 else if (streq(name, "ExecMainExitTimestamp"))
3755                         i->exit_timestamp = (usec_t) u;
3756                 else if (streq(name, "ActiveEnterTimestamp"))
3757                         i->active_enter_timestamp = (usec_t) u;
3758                 else if (streq(name, "InactiveEnterTimestamp"))
3759                         i->inactive_enter_timestamp = (usec_t) u;
3760                 else if (streq(name, "InactiveExitTimestamp"))
3761                         i->inactive_exit_timestamp = (usec_t) u;
3762                 else if (streq(name, "InactiveExitTimestampMonotonic"))
3763                         i->inactive_exit_timestamp_monotonic = (usec_t) u;
3764                 else if (streq(name, "ActiveExitTimestamp"))
3765                         i->active_exit_timestamp = (usec_t) u;
3766                 else if (streq(name, "ConditionTimestamp"))
3767                         i->condition_timestamp = (usec_t) u;
3768                 else if (streq(name, "AssertTimestamp"))
3769                         i->assert_timestamp = (usec_t) u;
3770
3771                 break;
3772         }
3773
3774         case SD_BUS_TYPE_ARRAY:
3775
3776                 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3777                         _cleanup_free_ ExecStatusInfo *info = NULL;
3778
3779                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3780                         if (r < 0)
3781                                 return bus_log_parse_error(r);
3782
3783                         info = new0(ExecStatusInfo, 1);
3784                         if (!info)
3785                                 return log_oom();
3786
3787                         while ((r = exec_status_info_deserialize(m, info)) > 0) {
3788
3789                                 info->name = strdup(name);
3790                                 if (!info->name)
3791                                         log_oom();
3792
3793                                 LIST_PREPEND(exec, i->exec, info);
3794
3795                                 info = new0(ExecStatusInfo, 1);
3796                                 if (!info)
3797                                         log_oom();
3798                         }
3799
3800                         if (r < 0)
3801                                 return bus_log_parse_error(r);
3802
3803                         r = sd_bus_message_exit_container(m);
3804                         if (r < 0)
3805                                 return bus_log_parse_error(r);
3806
3807                         return 0;
3808
3809                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3810                         const char *type, *path;
3811
3812                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3813                         if (r < 0)
3814                                 return bus_log_parse_error(r);
3815
3816                         while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0) {
3817
3818                                 r = strv_extend(&i->listen, type);
3819                                 if (r < 0)
3820                                         return r;
3821
3822                                 r = strv_extend(&i->listen, path);
3823                                 if (r < 0)
3824                                         return r;
3825                         }
3826                         if (r < 0)
3827                                 return bus_log_parse_error(r);
3828
3829                         r = sd_bus_message_exit_container(m);
3830                         if (r < 0)
3831                                 return bus_log_parse_error(r);
3832
3833                         return 0;
3834
3835                 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "DropInPaths")) {
3836
3837                         r = sd_bus_message_read_strv(m, &i->dropin_paths);
3838                         if (r < 0)
3839                                 return bus_log_parse_error(r);
3840
3841                 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Documentation")) {
3842
3843                         r = sd_bus_message_read_strv(m, &i->documentation);
3844                         if (r < 0)
3845                                 return bus_log_parse_error(r);
3846
3847                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Conditions")) {
3848                         const char *cond, *param;
3849                         int trigger, negate;
3850                         int32_t state;
3851
3852                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
3853                         if (r < 0)
3854                                 return bus_log_parse_error(r);
3855
3856                         while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, &param, &state)) > 0) {
3857                                 log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
3858                                 if (state < 0 && (!trigger || !i->failed_condition)) {
3859                                         i->failed_condition = cond;
3860                                         i->failed_condition_trigger = trigger;
3861                                         i->failed_condition_negate = negate;
3862                                         i->failed_condition_parameter = param;
3863                                 }
3864                         }
3865                         if (r < 0)
3866                                 return bus_log_parse_error(r);
3867
3868                         r = sd_bus_message_exit_container(m);
3869                         if (r < 0)
3870                                 return bus_log_parse_error(r);
3871
3872                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Asserts")) {
3873                         const char *cond, *param;
3874                         int trigger, negate;
3875                         int32_t state;
3876
3877                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
3878                         if (r < 0)
3879                                 return bus_log_parse_error(r);
3880
3881                         while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, &param, &state)) > 0) {
3882                                 log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
3883                                 if (state < 0 && (!trigger || !i->failed_assert)) {
3884                                         i->failed_assert = cond;
3885                                         i->failed_assert_trigger = trigger;
3886                                         i->failed_assert_negate = negate;
3887                                         i->failed_assert_parameter = param;
3888                                 }
3889                         }
3890                         if (r < 0)
3891                                 return bus_log_parse_error(r);
3892
3893                         r = sd_bus_message_exit_container(m);
3894                         if (r < 0)
3895                                 return bus_log_parse_error(r);
3896
3897                 } else
3898                         goto skip;
3899
3900                 break;
3901
3902         case SD_BUS_TYPE_STRUCT_BEGIN:
3903
3904                 if (streq(name, "LoadError")) {
3905                         const char *n, *message;
3906
3907                         r = sd_bus_message_read(m, "(ss)", &n, &message);
3908                         if (r < 0)
3909                                 return bus_log_parse_error(r);
3910
3911                         if (!isempty(message))
3912                                 i->load_error = message;
3913                 } else
3914                         goto skip;
3915
3916                 break;
3917
3918         default:
3919                 goto skip;
3920         }
3921
3922         return 0;
3923
3924 skip:
3925         r = sd_bus_message_skip(m, contents);
3926         if (r < 0)
3927                 return bus_log_parse_error(r);
3928
3929         return 0;
3930 }
3931
3932 static int print_property(const char *name, sd_bus_message *m, const char *contents) {
3933         int r;
3934
3935         assert(name);
3936         assert(m);
3937
3938         /* This is a low-level property printer, see
3939          * print_status_info() for the nicer output */
3940
3941         if (arg_properties && !strv_find(arg_properties, name)) {
3942                 /* skip what we didn't read */
3943                 r = sd_bus_message_skip(m, contents);
3944                 return r;
3945         }
3946
3947         switch (contents[0]) {
3948
3949         case SD_BUS_TYPE_STRUCT_BEGIN:
3950
3951                 if (contents[1] == SD_BUS_TYPE_UINT32 && streq(name, "Job")) {
3952                         uint32_t u;
3953
3954                         r = sd_bus_message_read(m, "(uo)", &u, NULL);
3955                         if (r < 0)
3956                                 return bus_log_parse_error(r);
3957
3958                         if (u > 0)
3959                                 printf("%s=%"PRIu32"\n", name, u);
3960                         else if (arg_all)
3961                                 printf("%s=\n", name);
3962
3963                         return 0;
3964
3965                 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Unit")) {
3966                         const char *s;
3967
3968                         r = sd_bus_message_read(m, "(so)", &s, NULL);
3969                         if (r < 0)
3970                                 return bus_log_parse_error(r);
3971
3972                         if (arg_all || !isempty(s))
3973                                 printf("%s=%s\n", name, s);
3974
3975                         return 0;
3976
3977                 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "LoadError")) {
3978                         const char *a = NULL, *b = NULL;
3979
3980                         r = sd_bus_message_read(m, "(ss)", &a, &b);
3981                         if (r < 0)
3982                                 return bus_log_parse_error(r);
3983
3984                         if (arg_all || !isempty(a) || !isempty(b))
3985                                 printf("%s=%s \"%s\"\n", name, strempty(a), strempty(b));
3986
3987                         return 0;
3988                 } else if (streq_ptr(name, "SystemCallFilter")) {
3989                         _cleanup_strv_free_ char **l = NULL;
3990                         int whitelist;
3991
3992                         r = sd_bus_message_enter_container(m, 'r', "bas");
3993                         if (r < 0)
3994                                 return bus_log_parse_error(r);
3995
3996                         r = sd_bus_message_read(m, "b", &whitelist);
3997                         if (r < 0)
3998                                 return bus_log_parse_error(r);
3999
4000                         r = sd_bus_message_read_strv(m, &l);
4001                         if (r < 0)
4002                                 return bus_log_parse_error(r);
4003
4004                         r = sd_bus_message_exit_container(m);
4005                         if (r < 0)
4006                                 return bus_log_parse_error(r);
4007
4008                         if (arg_all || whitelist || !strv_isempty(l)) {
4009                                 bool first = true;
4010                                 char **i;
4011
4012                                 fputs(name, stdout);
4013                                 fputc('=', stdout);
4014
4015                                 if (!whitelist)
4016                                         fputc('~', stdout);
4017
4018                                 STRV_FOREACH(i, l) {
4019                                         if (first)
4020                                                 first = false;
4021                                         else
4022                                                 fputc(' ', stdout);
4023
4024                                         fputs(*i, stdout);
4025                                 }
4026                                 fputc('\n', stdout);
4027                         }
4028
4029                         return 0;
4030                 }
4031
4032                 break;
4033
4034         case SD_BUS_TYPE_ARRAY:
4035
4036                 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "EnvironmentFiles")) {
4037                         const char *path;
4038                         int ignore;
4039
4040                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sb)");
4041                         if (r < 0)
4042                                 return bus_log_parse_error(r);
4043
4044                         while ((r = sd_bus_message_read(m, "(sb)", &path, &ignore)) > 0)
4045                                 printf("EnvironmentFile=%s (ignore_errors=%s)\n", path, yes_no(ignore));
4046
4047                         if (r < 0)
4048                                 return bus_log_parse_error(r);
4049
4050                         r = sd_bus_message_exit_container(m);
4051                         if (r < 0)
4052                                 return bus_log_parse_error(r);
4053
4054                         return 0;
4055
4056                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Paths")) {
4057                         const char *type, *path;
4058
4059                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
4060                         if (r < 0)
4061                                 return bus_log_parse_error(r);
4062
4063                         while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
4064                                 printf("%s=%s\n", type, path);
4065                         if (r < 0)
4066                                 return bus_log_parse_error(r);
4067
4068                         r = sd_bus_message_exit_container(m);
4069                         if (r < 0)
4070                                 return bus_log_parse_error(r);
4071
4072                         return 0;
4073
4074                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
4075                         const char *type, *path;
4076
4077                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
4078                         if (r < 0)
4079                                 return bus_log_parse_error(r);
4080
4081                         while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
4082                                 printf("Listen%s=%s\n", type, path);
4083                         if (r < 0)
4084                                 return bus_log_parse_error(r);
4085
4086                         r = sd_bus_message_exit_container(m);
4087                         if (r < 0)
4088                                 return bus_log_parse_error(r);
4089
4090                         return 0;
4091
4092                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Timers")) {
4093                         const char *base;
4094                         uint64_t value, next_elapse;
4095
4096                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(stt)");
4097                         if (r < 0)
4098                                 return bus_log_parse_error(r);
4099
4100                         while ((r = sd_bus_message_read(m, "(stt)", &base, &value, &next_elapse)) > 0) {
4101                                 char timespan1[FORMAT_TIMESPAN_MAX], timespan2[FORMAT_TIMESPAN_MAX];
4102
4103                                 printf("%s={ value=%s ; next_elapse=%s }\n",
4104                                        base,
4105                                        format_timespan(timespan1, sizeof(timespan1), value, 0),
4106                                        format_timespan(timespan2, sizeof(timespan2), next_elapse, 0));
4107                         }
4108                         if (r < 0)
4109                                 return bus_log_parse_error(r);
4110
4111                         r = sd_bus_message_exit_container(m);
4112                         if (r < 0)
4113                                 return bus_log_parse_error(r);
4114
4115                         return 0;
4116
4117                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
4118                         ExecStatusInfo info = {};
4119
4120                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
4121                         if (r < 0)
4122                                 return bus_log_parse_error(r);
4123
4124                         while ((r = exec_status_info_deserialize(m, &info)) > 0) {
4125                                 char timestamp1[FORMAT_TIMESTAMP_MAX], timestamp2[FORMAT_TIMESTAMP_MAX];
4126                                 _cleanup_free_ char *tt;
4127
4128                                 tt = strv_join(info.argv, " ");
4129
4130                                 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",
4131                                        name,
4132                                        strna(info.path),
4133                                        strna(tt),
4134                                        yes_no(info.ignore),
4135                                        strna(format_timestamp(timestamp1, sizeof(timestamp1), info.start_timestamp)),
4136                                        strna(format_timestamp(timestamp2, sizeof(timestamp2), info.exit_timestamp)),
4137                                        info.pid,
4138                                        sigchld_code_to_string(info.code),
4139                                        info.status,
4140                                        info.code == CLD_EXITED ? "" : "/",
4141                                        strempty(info.code == CLD_EXITED ? NULL : signal_to_string(info.status)));
4142
4143                                 free(info.path);
4144                                 strv_free(info.argv);
4145                                 zero(info);
4146                         }
4147
4148                         r = sd_bus_message_exit_container(m);
4149                         if (r < 0)
4150                                 return bus_log_parse_error(r);
4151
4152                         return 0;
4153
4154                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "DeviceAllow")) {
4155                         const char *path, *rwm;
4156
4157                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
4158                         if (r < 0)
4159                                 return bus_log_parse_error(r);
4160
4161                         while ((r = sd_bus_message_read(m, "(ss)", &path, &rwm)) > 0)
4162                                 printf("%s=%s %s\n", name, strna(path), strna(rwm));
4163                         if (r < 0)
4164                                 return bus_log_parse_error(r);
4165
4166                         r = sd_bus_message_exit_container(m);
4167                         if (r < 0)
4168                                 return bus_log_parse_error(r);
4169
4170                         return 0;
4171
4172                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "BlockIODeviceWeight")) {
4173                         const char *path;
4174                         uint64_t weight;
4175
4176                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
4177                         if (r < 0)
4178                                 return bus_log_parse_error(r);
4179
4180                         while ((r = sd_bus_message_read(m, "(st)", &path, &weight)) > 0)
4181                                 printf("%s=%s %" PRIu64 "\n", name, strna(path), weight);
4182                         if (r < 0)
4183                                 return bus_log_parse_error(r);
4184
4185                         r = sd_bus_message_exit_container(m);
4186                         if (r < 0)
4187                                 return bus_log_parse_error(r);
4188
4189                         return 0;
4190
4191                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && (streq(name, "BlockIOReadBandwidth") || streq(name, "BlockIOWriteBandwidth"))) {
4192                         const char *path;
4193                         uint64_t bandwidth;
4194
4195                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
4196                         if (r < 0)
4197                                 return bus_log_parse_error(r);
4198
4199                         while ((r = sd_bus_message_read(m, "(st)", &path, &bandwidth)) > 0)
4200                                 printf("%s=%s %" PRIu64 "\n", name, strna(path), bandwidth);
4201                         if (r < 0)
4202                                 return bus_log_parse_error(r);
4203
4204                         r = sd_bus_message_exit_container(m);
4205                         if (r < 0)
4206                                 return bus_log_parse_error(r);
4207
4208                         return 0;
4209                 }
4210
4211                 break;
4212         }
4213
4214         r = bus_print_property(name, m, arg_all);
4215         if (r < 0)
4216                 return bus_log_parse_error(r);
4217
4218         if (r == 0) {
4219                 r = sd_bus_message_skip(m, contents);
4220                 if (r < 0)
4221                         return bus_log_parse_error(r);
4222
4223                 if (arg_all)
4224                         printf("%s=[unprintable]\n", name);
4225         }
4226
4227         return 0;
4228 }
4229
4230 static int show_one(
4231                 const char *verb,
4232                 sd_bus *bus,
4233                 const char *path,
4234                 bool show_properties,
4235                 bool *new_line,
4236                 bool *ellipsized) {
4237
4238         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4239         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4240         UnitStatusInfo info = {};
4241         ExecStatusInfo *p;
4242         int r;
4243
4244         assert(path);
4245         assert(new_line);
4246
4247         log_debug("Showing one %s", path);
4248
4249         r = sd_bus_call_method(
4250                         bus,
4251                         "org.freedesktop.systemd1",
4252                         path,
4253                         "org.freedesktop.DBus.Properties",
4254                         "GetAll",
4255                         &error,
4256                         &reply,
4257                         "s", "");
4258         if (r < 0) {
4259                 log_error("Failed to get properties: %s", bus_error_message(&error, r));
4260                 return r;
4261         }
4262
4263         r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
4264         if (r < 0)
4265                 return bus_log_parse_error(r);
4266
4267         if (*new_line)
4268                 printf("\n");
4269
4270         *new_line = true;
4271
4272         while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
4273                 const char *name, *contents;
4274
4275                 r = sd_bus_message_read(reply, "s", &name);
4276                 if (r < 0)
4277                         return bus_log_parse_error(r);
4278
4279                 r = sd_bus_message_peek_type(reply, NULL, &contents);
4280                 if (r < 0)
4281                         return bus_log_parse_error(r);
4282
4283                 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, contents);
4284                 if (r < 0)
4285                         return bus_log_parse_error(r);
4286
4287                 if (show_properties)
4288                         r = print_property(name, reply, contents);
4289                 else
4290                         r = status_property(name, reply, &info, contents);
4291                 if (r < 0)
4292                         return r;
4293
4294                 r = sd_bus_message_exit_container(reply);
4295                 if (r < 0)
4296                         return bus_log_parse_error(r);
4297
4298                 r = sd_bus_message_exit_container(reply);
4299                 if (r < 0)
4300                         return bus_log_parse_error(r);
4301         }
4302         if (r < 0)
4303                 return bus_log_parse_error(r);
4304
4305         r = sd_bus_message_exit_container(reply);
4306         if (r < 0)
4307                 return bus_log_parse_error(r);
4308
4309         r = 0;
4310
4311         if (!show_properties) {
4312                 if (streq(verb, "help"))
4313                         show_unit_help(&info);
4314                 else
4315                         print_status_info(&info, ellipsized);
4316         }
4317
4318         strv_free(info.documentation);
4319         strv_free(info.dropin_paths);
4320         strv_free(info.listen);
4321
4322         if (!streq_ptr(info.active_state, "active") &&
4323             !streq_ptr(info.active_state, "reloading") &&
4324             streq(verb, "status")) {
4325                 /* According to LSB: "program not running" */
4326                 /* 0: program is running or service is OK
4327                  * 1: program is dead and /run PID file exists
4328                  * 2: program is dead and /run/lock lock file exists
4329                  * 3: program is not running
4330                  * 4: program or service status is unknown
4331                  */
4332                 if (info.pid_file && access(info.pid_file, F_OK) == 0)
4333                         r = 1;
4334                 else
4335                         r = 3;
4336         }
4337
4338         while ((p = info.exec)) {
4339                 LIST_REMOVE(exec, info.exec, p);
4340                 exec_status_info_free(p);
4341         }
4342
4343         return r;
4344 }
4345
4346 static int get_unit_dbus_path_by_pid(
4347                 sd_bus *bus,
4348                 uint32_t pid,
4349                 char **unit) {
4350
4351         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4352         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4353         char *u;
4354         int r;
4355
4356         r = sd_bus_call_method(
4357                         bus,
4358                         "org.freedesktop.systemd1",
4359                         "/org/freedesktop/systemd1",
4360                         "org.freedesktop.systemd1.Manager",
4361                         "GetUnitByPID",
4362                         &error,
4363                         &reply,
4364                         "u", pid);
4365         if (r < 0) {
4366                 log_error("Failed to get unit for PID "PID_FMT": %s", pid, bus_error_message(&error, r));
4367                 return r;
4368         }
4369
4370         r = sd_bus_message_read(reply, "o", &u);
4371         if (r < 0)
4372                 return bus_log_parse_error(r);
4373
4374         u = strdup(u);
4375         if (!u)
4376                 return log_oom();
4377
4378         *unit = u;
4379         return 0;
4380 }
4381
4382 static int show_all(
4383                 const char* verb,
4384                 sd_bus *bus,
4385                 bool show_properties,
4386                 bool *new_line,
4387                 bool *ellipsized) {
4388
4389         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4390         _cleanup_free_ UnitInfo *unit_infos = NULL;
4391         const UnitInfo *u;
4392         unsigned c;
4393         int r, ret = 0;
4394
4395         r = get_unit_list(bus, NULL, NULL, &unit_infos, 0, &reply);
4396         if (r < 0)
4397                 return r;
4398
4399         pager_open_if_enabled();
4400
4401         c = (unsigned) r;
4402
4403         qsort_safe(unit_infos, c, sizeof(UnitInfo), compare_unit_info);
4404
4405         for (u = unit_infos; u < unit_infos + c; u++) {
4406                 _cleanup_free_ char *p = NULL;
4407
4408                 p = unit_dbus_path_from_name(u->id);
4409                 if (!p)
4410                         return log_oom();
4411
4412                 r = show_one(verb, bus, p, show_properties, new_line, ellipsized);
4413                 if (r < 0)
4414                         return r;
4415                 else if (r > 0 && ret == 0)
4416                         ret = r;
4417         }
4418
4419         return ret;
4420 }
4421
4422 static int show_system_status(sd_bus *bus) {
4423         char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], since2[FORMAT_TIMESTAMP_MAX];
4424         _cleanup_free_ char *hn = NULL;
4425         struct machine_info mi = {};
4426         const char *on, *off;
4427         int r;
4428
4429         hn = gethostname_malloc();
4430         if (!hn)
4431                 return log_oom();
4432
4433         r = bus_map_all_properties(bus, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map, &mi);
4434         if (r < 0)
4435                 return log_error_errno(r, "Failed to read server status: %m");
4436
4437         if (streq_ptr(mi.state, "degraded")) {
4438                 on = ansi_highlight_red();
4439                 off = ansi_highlight_off();
4440         } else if (!streq_ptr(mi.state, "running")) {
4441                 on = ansi_highlight_yellow();
4442                 off = ansi_highlight_off();
4443         } else
4444                 on = off = "";
4445
4446         printf("%s%s%s %s\n", on, draw_special_char(DRAW_BLACK_CIRCLE), off, arg_host ? arg_host : hn);
4447
4448         printf("    State: %s%s%s\n",
4449                on, strna(mi.state), off);
4450
4451         printf("     Jobs: %u queued\n", mi.n_jobs);
4452         printf("   Failed: %u units\n", mi.n_failed_units);
4453
4454         printf("    Since: %s; %s\n",
4455                format_timestamp(since2, sizeof(since2), mi.timestamp),
4456                format_timestamp_relative(since1, sizeof(since1), mi.timestamp));
4457
4458         printf("   CGroup: %s\n", mi.control_group ?: "/");
4459         if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_CONTAINER) {
4460                 int flags =
4461                         arg_all * OUTPUT_SHOW_ALL |
4462                         (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
4463                         on_tty() * OUTPUT_COLOR |
4464                         !arg_quiet * OUTPUT_WARN_CUTOFF |
4465                         arg_full * OUTPUT_FULL_WIDTH;
4466
4467                 static const char prefix[] = "           ";
4468                 unsigned c;
4469
4470                 c = columns();
4471                 if (c > sizeof(prefix) - 1)
4472                         c -= sizeof(prefix) - 1;
4473                 else
4474                         c = 0;
4475
4476                 show_cgroup(SYSTEMD_CGROUP_CONTROLLER, strempty(mi.control_group), prefix, c, false, flags);
4477         }
4478
4479         free(mi.state);
4480         free(mi.control_group);
4481
4482         return 0;
4483 }
4484
4485 static int show(sd_bus *bus, char **args) {
4486         bool show_properties, show_status, new_line = false;
4487         bool ellipsized = false;
4488         int r, ret = 0;
4489
4490         assert(bus);
4491         assert(args);
4492
4493         show_properties = streq(args[0], "show");
4494         show_status = streq(args[0], "status");
4495
4496         if (show_properties)
4497                 pager_open_if_enabled();
4498
4499         /* If no argument is specified inspect the manager itself */
4500
4501         if (show_properties && strv_length(args) <= 1)
4502                 return show_one(args[0], bus, "/org/freedesktop/systemd1", show_properties, &new_line, &ellipsized);
4503
4504         if (show_status && strv_length(args) <= 1) {
4505
4506                 pager_open_if_enabled();
4507                 show_system_status(bus);
4508                 new_line = true;
4509
4510                 if (arg_all)
4511                         ret = show_all(args[0], bus, false, &new_line, &ellipsized);
4512         } else {
4513                 _cleanup_free_ char **patterns = NULL;
4514                 char **name;
4515
4516                 STRV_FOREACH(name, args + 1) {
4517                         _cleanup_free_ char *unit = NULL;
4518                         uint32_t id;
4519
4520                         if (safe_atou32(*name, &id) < 0) {
4521                                 if (strv_push(&patterns, *name) < 0)
4522                                         return log_oom();
4523
4524                                 continue;
4525                         } else if (show_properties) {
4526                                 /* Interpret as job id */
4527                                 if (asprintf(&unit, "/org/freedesktop/systemd1/job/%u", id) < 0)
4528                                         return log_oom();
4529
4530                         } else {
4531                                 /* Interpret as PID */
4532                                 r = get_unit_dbus_path_by_pid(bus, id, &unit);
4533                                 if (r < 0) {
4534                                         ret = r;
4535                                         continue;
4536                                 }
4537                         }
4538
4539                         r = show_one(args[0], bus, unit, show_properties,
4540                                      &new_line, &ellipsized);
4541                         if (r < 0)
4542                                 return r;
4543                         else if (r > 0 && ret == 0)
4544                                 ret = r;
4545                 }
4546
4547                 if (!strv_isempty(patterns)) {
4548                         _cleanup_strv_free_ char **names = NULL;
4549
4550                         r = expand_names(bus, patterns, NULL, &names);
4551                         if (r < 0)
4552                                 log_error_errno(r, "Failed to expand names: %m");
4553
4554                         STRV_FOREACH(name, names) {
4555                                 _cleanup_free_ char *unit;
4556
4557                                 unit = unit_dbus_path_from_name(*name);
4558                                 if (!unit)
4559                                         return log_oom();
4560
4561                                 r = show_one(args[0], bus, unit, show_properties,
4562                                              &new_line, &ellipsized);
4563                                 if (r < 0)
4564                                         return r;
4565                                 else if (r > 0 && ret == 0)
4566                                         ret = r;
4567                         }
4568                 }
4569         }
4570
4571         if (ellipsized && !arg_quiet)
4572                 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
4573
4574         return ret;
4575 }
4576
4577 static int cat(sd_bus *bus, char **args) {
4578         _cleanup_strv_free_ char **names = NULL;
4579         char **name;
4580         bool first = true;
4581         int r = 0;
4582
4583         assert(bus);
4584         assert(args);
4585
4586         r = expand_names(bus, args + 1, NULL, &names);
4587         if (r < 0)
4588                 log_error_errno(r, "Failed to expand names: %m");
4589
4590         pager_open_if_enabled();
4591
4592         STRV_FOREACH(name, names) {
4593                 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4594                 _cleanup_strv_free_ char **dropin_paths = NULL;
4595                 _cleanup_free_ char *fragment_path = NULL, *unit = NULL;
4596                 char **path;
4597
4598                 unit = unit_dbus_path_from_name(*name);
4599                 if (!unit)
4600                         return log_oom();
4601
4602                 if (need_daemon_reload(bus, *name) > 0)
4603                         log_warning("Unit file of %s changed on disk. Run 'systemctl%s daemon-reload'.",
4604                                     *name, arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
4605
4606                 r = sd_bus_get_property_string(
4607                                 bus,
4608                                 "org.freedesktop.systemd1",
4609                                 unit,
4610                                 "org.freedesktop.systemd1.Unit",
4611                                 "FragmentPath",
4612                                 &error,
4613                                 &fragment_path);
4614                 if (r < 0) {
4615                         log_warning("Failed to get FragmentPath: %s", bus_error_message(&error, r));
4616                         continue;
4617                 }
4618
4619                 r = sd_bus_get_property_strv(
4620                                 bus,
4621                                 "org.freedesktop.systemd1",
4622                                 unit,
4623                                 "org.freedesktop.systemd1.Unit",
4624                                 "DropInPaths",
4625                                 &error,
4626                                 &dropin_paths);
4627                 if (r < 0) {
4628                         log_warning("Failed to get DropInPaths: %s", bus_error_message(&error, r));
4629                         continue;
4630                 }
4631
4632                 if (first)
4633                         first = false;
4634                 else
4635                         puts("");
4636
4637                 if (!isempty(fragment_path)) {
4638                         printf("%s# %s%s\n",
4639                                ansi_highlight_blue(),
4640                                fragment_path,
4641                                ansi_highlight_off());
4642                         fflush(stdout);
4643
4644                         r = copy_file_fd(fragment_path, STDOUT_FILENO, false);
4645                         if (r < 0) {
4646                                 log_warning_errno(r, "Failed to cat %s: %m", fragment_path);
4647                                 continue;
4648                         }
4649                 }
4650
4651                 STRV_FOREACH(path, dropin_paths) {
4652                         printf("%s%s# %s%s\n",
4653                                isempty(fragment_path) && path == dropin_paths ? "" : "\n",
4654                                ansi_highlight_blue(),
4655                                *path,
4656                                ansi_highlight_off());
4657                         fflush(stdout);
4658
4659                         r = copy_file_fd(*path, STDOUT_FILENO, false);
4660                         if (r < 0) {
4661                                 log_warning_errno(r, "Failed to cat %s: %m", *path);
4662                                 continue;
4663                         }
4664                 }
4665         }
4666
4667         return r < 0 ? r : 0;
4668 }
4669
4670 static int set_property(sd_bus *bus, char **args) {
4671         _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4672         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4673         _cleanup_free_ char *n = NULL;
4674         char **i;
4675         int r;
4676
4677         r = sd_bus_message_new_method_call(
4678                         bus,
4679                         &m,
4680                         "org.freedesktop.systemd1",
4681                         "/org/freedesktop/systemd1",
4682                         "org.freedesktop.systemd1.Manager",
4683                         "SetUnitProperties");
4684         if (r < 0)
4685                 return bus_log_create_error(r);
4686
4687         r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4688         if (r < 0)
4689                 return bus_log_create_error(r);
4690
4691         n = unit_name_mangle(args[1], MANGLE_NOGLOB);
4692         if (!n)
4693                 return log_oom();
4694
4695         r = sd_bus_message_append(m, "sb", n, arg_runtime);
4696         if (r < 0)
4697                 return bus_log_create_error(r);
4698
4699         r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, "(sv)");
4700         if (r < 0)
4701                 return bus_log_create_error(r);
4702
4703         STRV_FOREACH(i, args + 2) {
4704                 r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv");
4705                 if (r < 0)
4706                         return bus_log_create_error(r);
4707
4708                 r = bus_append_unit_property_assignment(m, *i);
4709                 if (r < 0)
4710                         return r;
4711
4712                 r = sd_bus_message_close_container(m);
4713                 if (r < 0)
4714                         return bus_log_create_error(r);
4715         }
4716
4717         r = sd_bus_message_close_container(m);
4718         if (r < 0)
4719                 return bus_log_create_error(r);
4720
4721         r = sd_bus_call(bus, m, 0, &error, NULL);
4722         if (r < 0) {
4723                 log_error("Failed to set unit properties on %s: %s", n, bus_error_message(&error, r));
4724                 return r;
4725         }
4726
4727         return 0;
4728 }
4729
4730 static int snapshot(sd_bus *bus, char **args) {
4731         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4732         _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
4733         _cleanup_free_ char *n = NULL, *id = NULL;
4734         const char *path;
4735         int r;
4736
4737         if (strv_length(args) > 1)
4738                 n = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".snapshot");
4739         else
4740                 n = strdup("");
4741         if (!n)
4742                 return log_oom();
4743
4744         r = sd_bus_message_new_method_call(
4745                         bus,
4746                         &m,
4747                         "org.freedesktop.systemd1",
4748                         "/org/freedesktop/systemd1",
4749                         "org.freedesktop.systemd1.Manager",
4750                         "CreateSnapshot");
4751         if (r < 0)
4752                 return bus_log_create_error(r);
4753
4754         r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4755         if (r < 0)
4756                 return bus_log_create_error(r);
4757
4758         r = sd_bus_message_append(m, "sb", n, false);
4759         if (r < 0)
4760                 return bus_log_create_error(r);
4761
4762         r = sd_bus_call(bus, m, 0, &error, &reply);
4763         if (r < 0) {
4764                 log_error("Failed to create snapshot: %s", bus_error_message(&error, r));
4765                 return r;
4766         }
4767
4768         r = sd_bus_message_read(reply, "o", &path);
4769         if (r < 0)
4770                 return bus_log_parse_error(r);
4771
4772         r = sd_bus_get_property_string(
4773                         bus,
4774                         "org.freedesktop.systemd1",
4775                         path,
4776                         "org.freedesktop.systemd1.Unit",
4777                         "Id",
4778                         &error,
4779                         &id);
4780         if (r < 0) {
4781                 log_error("Failed to get ID of snapshot: %s", bus_error_message(&error, r));
4782                 return r;
4783         }
4784
4785         if (!arg_quiet)
4786                 puts(id);
4787
4788         return 0;
4789 }
4790
4791 static int delete_snapshot(sd_bus *bus, char **args) {
4792         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4793         _cleanup_strv_free_ char **names = NULL;
4794         char **name;
4795         int r;
4796
4797         assert(args);
4798
4799         r = expand_names(bus, args + 1, ".snapshot", &names);
4800         if (r < 0)
4801                 log_error_errno(r, "Failed to expand names: %m");
4802
4803         STRV_FOREACH(name, names) {
4804                 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4805                 int q;
4806
4807                 q = sd_bus_message_new_method_call(
4808                                 bus,
4809                                 &m,
4810                                 "org.freedesktop.systemd1",
4811                                 "/org/freedesktop/systemd1",
4812                                 "org.freedesktop.systemd1.Manager",
4813                                 "RemoveSnapshot");
4814                 if (q < 0)
4815                         return bus_log_create_error(q);
4816
4817                 q = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4818                 if (q < 0)
4819                         return bus_log_create_error(q);
4820
4821                 q = sd_bus_message_append(m, "s", *name);
4822                 if (q < 0)
4823                         return bus_log_create_error(q);
4824
4825                 q = sd_bus_call(bus, m, 0, &error, NULL);
4826                 if (q < 0) {
4827                         log_error("Failed to remove snapshot %s: %s", *name, bus_error_message(&error, q));
4828                         if (r == 0)
4829                                 r = q;
4830                 }
4831         }
4832
4833         return r;
4834 }
4835
4836 static int daemon_reload(sd_bus *bus, char **args) {
4837         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4838         _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4839         const char *method;
4840         int r;
4841
4842         if (arg_action == ACTION_RELOAD)
4843                 method = "Reload";
4844         else if (arg_action == ACTION_REEXEC)
4845                 method = "Reexecute";
4846         else {
4847                 assert(arg_action == ACTION_SYSTEMCTL);
4848
4849                 method =
4850                         streq(args[0], "clear-jobs")    ||
4851                         streq(args[0], "cancel")        ? "ClearJobs" :
4852                         streq(args[0], "daemon-reexec") ? "Reexecute" :
4853                         streq(args[0], "reset-failed")  ? "ResetFailed" :
4854                         streq(args[0], "halt")          ? "Halt" :
4855                         streq(args[0], "poweroff")      ? "PowerOff" :
4856                         streq(args[0], "reboot")        ? "Reboot" :
4857                         streq(args[0], "kexec")         ? "KExec" :
4858                         streq(args[0], "exit")          ? "Exit" :
4859                                     /* "daemon-reload" */ "Reload";
4860         }
4861
4862         r = sd_bus_message_new_method_call(
4863                         bus,
4864                         &m,
4865                         "org.freedesktop.systemd1",
4866                         "/org/freedesktop/systemd1",
4867                         "org.freedesktop.systemd1.Manager",
4868                         method);
4869         if (r < 0)
4870                 return bus_log_create_error(r);
4871
4872         r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4873         if (r < 0)
4874                 return bus_log_create_error(r);
4875
4876         r = sd_bus_call(bus, m, 0, &error, NULL);
4877         if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
4878                 /* There's always a fallback possible for
4879                  * legacy actions. */
4880                 r = -EADDRNOTAVAIL;
4881         else if ((r == -ETIMEDOUT || r == -ECONNRESET) && streq(method, "Reexecute"))
4882                 /* On reexecution, we expect a disconnect, not a
4883                  * reply */
4884                 r = 0;
4885         else if (r < 0)
4886                 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
4887
4888         return r < 0 ? r : 0;
4889 }
4890
4891 static int reset_failed(sd_bus *bus, char **args) {
4892         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4893         _cleanup_strv_free_ char **names = NULL;
4894         char **name;
4895         int r, q;
4896
4897         if (strv_length(args) <= 1)
4898                 return daemon_reload(bus, args);
4899
4900         r = expand_names(bus, args + 1, NULL, &names);
4901         if (r < 0)
4902                 log_error_errno(r, "Failed to expand names: %m");
4903
4904         STRV_FOREACH(name, names) {
4905                 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4906
4907                 q = sd_bus_message_new_method_call(
4908                                 bus,
4909                                 &m,
4910                                 "org.freedesktop.systemd1",
4911                                 "/org/freedesktop/systemd1",
4912                                 "org.freedesktop.systemd1.Manager",
4913                                 "ResetFailedUnit");
4914                 if (q < 0)
4915                         return bus_log_create_error(q);
4916
4917                 q = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4918                 if (q < 0)
4919                         return bus_log_create_error(q);
4920
4921                 q = sd_bus_message_append(m, "s", *name);
4922                 if (q < 0)
4923                         return bus_log_create_error(q);
4924
4925                 q = sd_bus_call(bus, m, 0, &error, NULL);
4926                 if (q < 0) {
4927                         log_error("Failed to reset failed state of unit %s: %s", *name, bus_error_message(&error, q));
4928                         if (r == 0)
4929                                 r = q;
4930                 }
4931         }
4932
4933         return r;
4934 }
4935
4936 static int show_environment(sd_bus *bus, char **args) {
4937         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4938         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4939         const char *text;
4940         int r;
4941
4942         pager_open_if_enabled();
4943
4944         r = sd_bus_get_property(
4945                         bus,
4946                         "org.freedesktop.systemd1",
4947                         "/org/freedesktop/systemd1",
4948                         "org.freedesktop.systemd1.Manager",
4949                         "Environment",
4950                         &error,
4951                         &reply,
4952                         "as");
4953         if (r < 0) {
4954                 log_error("Failed to get environment: %s", bus_error_message(&error, r));
4955                 return r;
4956         }
4957
4958         r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "s");
4959         if (r < 0)
4960                 return bus_log_parse_error(r);
4961
4962         while ((r = sd_bus_message_read_basic(reply, SD_BUS_TYPE_STRING, &text)) > 0)
4963                 puts(text);
4964         if (r < 0)
4965                 return bus_log_parse_error(r);
4966
4967         r = sd_bus_message_exit_container(reply);
4968         if (r < 0)
4969                 return bus_log_parse_error(r);
4970
4971         return 0;
4972 }
4973
4974 static int switch_root(sd_bus *bus, char **args) {
4975         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4976         _cleanup_free_ char *cmdline_init = NULL;
4977         const char *root, *init;
4978         unsigned l;
4979         int r;
4980
4981         l = strv_length(args);
4982         if (l < 2 || l > 3) {
4983                 log_error("Wrong number of arguments.");
4984                 return -EINVAL;
4985         }
4986
4987         root = args[1];
4988
4989         if (l >= 3)
4990                 init = args[2];
4991         else {
4992                 r = parse_env_file("/proc/cmdline", WHITESPACE,
4993                                    "init", &cmdline_init,
4994                                    NULL);
4995                 if (r < 0)
4996                         log_debug_errno(r, "Failed to parse /proc/cmdline: %m");
4997
4998                 init = cmdline_init;
4999         }
5000
5001         if (isempty(init))
5002                 init = NULL;
5003
5004         if (init) {
5005                 const char *root_systemd_path = NULL, *root_init_path = NULL;
5006
5007                 root_systemd_path = strappenda(root, "/" SYSTEMD_BINARY_PATH);
5008                 root_init_path = strappenda(root, "/", init);
5009
5010                 /* If the passed init is actually the same as the
5011                  * systemd binary, then let's suppress it. */
5012                 if (files_same(root_init_path, root_systemd_path) > 0)
5013                         init = NULL;
5014         }
5015
5016         log_debug("Switching root - root: %s; init: %s", root, strna(init));
5017
5018         r = sd_bus_call_method(
5019                         bus,
5020                         "org.freedesktop.systemd1",
5021                         "/org/freedesktop/systemd1",
5022                         "org.freedesktop.systemd1.Manager",
5023                         "SwitchRoot",
5024                         &error,
5025                         NULL,
5026                         "ss", root, init);
5027         if (r < 0) {
5028                 log_error("Failed to switch root: %s", bus_error_message(&error, r));
5029                 return r;
5030         }
5031
5032         return 0;
5033 }
5034
5035 static int set_environment(sd_bus *bus, char **args) {
5036         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5037         _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
5038         const char *method;
5039         int r;
5040
5041         assert(bus);
5042         assert(args);
5043
5044         method = streq(args[0], "set-environment")
5045                 ? "SetEnvironment"
5046                 : "UnsetEnvironment";
5047
5048         r = sd_bus_message_new_method_call(
5049                         bus,
5050                         &m,
5051                         "org.freedesktop.systemd1",
5052                         "/org/freedesktop/systemd1",
5053                         "org.freedesktop.systemd1.Manager",
5054                         method);
5055         if (r < 0)
5056                 return bus_log_create_error(r);
5057
5058         r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5059         if (r < 0)
5060                 return bus_log_create_error(r);
5061
5062         r = sd_bus_message_append_strv(m, args + 1);
5063         if (r < 0)
5064                 return bus_log_create_error(r);
5065
5066         r = sd_bus_call(bus, m, 0, &error, NULL);
5067         if (r < 0) {
5068                 log_error("Failed to set environment: %s", bus_error_message(&error, r));
5069                 return r;
5070         }
5071
5072         return 0;
5073 }
5074
5075 static int import_environment(sd_bus *bus, char **args) {
5076         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5077         _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
5078         int r;
5079
5080         assert(bus);
5081         assert(args);
5082
5083         r = sd_bus_message_new_method_call(
5084                         bus,
5085                         &m,
5086                         "org.freedesktop.systemd1",
5087                         "/org/freedesktop/systemd1",
5088                         "org.freedesktop.systemd1.Manager",
5089                         "SetEnvironment");
5090         if (r < 0)
5091                 return bus_log_create_error(r);
5092
5093         r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5094         if (r < 0)
5095                 return bus_log_create_error(r);
5096
5097         if (strv_isempty(args + 1))
5098                 r = sd_bus_message_append_strv(m, environ);
5099         else {
5100                 char **a, **b;
5101
5102                 r = sd_bus_message_open_container(m, 'a', "s");
5103                 if (r < 0)
5104                         return bus_log_create_error(r);
5105
5106                 STRV_FOREACH(a, args + 1) {
5107
5108                         if (!env_name_is_valid(*a)) {
5109                                 log_error("Not a valid environment variable name: %s", *a);
5110                                 return -EINVAL;
5111                         }
5112
5113                         STRV_FOREACH(b, environ) {
5114                                 const char *eq;
5115
5116                                 eq = startswith(*b, *a);
5117                                 if (eq && *eq == '=') {
5118
5119                                         r = sd_bus_message_append(m, "s", *b);
5120                                         if (r < 0)
5121                                                 return bus_log_create_error(r);
5122
5123                                         break;
5124                                 }
5125                         }
5126                 }
5127
5128                 r = sd_bus_message_close_container(m);
5129         }
5130         if (r < 0)
5131                 return bus_log_create_error(r);
5132
5133         r = sd_bus_call(bus, m, 0, &error, NULL);
5134         if (r < 0) {
5135                 log_error("Failed to import environment: %s", bus_error_message(&error, r));
5136                 return r;
5137         }
5138
5139         return 0;
5140 }
5141
5142 static int enable_sysv_units(const char *verb, char **args) {
5143         int r = 0;
5144
5145 #if defined(HAVE_SYSV_COMPAT) && defined(HAVE_CHKCONFIG)
5146         unsigned f = 0;
5147         _cleanup_lookup_paths_free_ LookupPaths paths = {};
5148
5149         if (arg_scope != UNIT_FILE_SYSTEM)
5150                 return 0;
5151
5152         if (!streq(verb, "enable") &&
5153             !streq(verb, "disable") &&
5154             !streq(verb, "is-enabled"))
5155                 return 0;
5156
5157         /* Processes all SysV units, and reshuffles the array so that
5158          * afterwards only the native units remain */
5159
5160         r = lookup_paths_init(&paths, SYSTEMD_SYSTEM, false, arg_root, NULL, NULL, NULL);
5161         if (r < 0)
5162                 return r;
5163
5164         r = 0;
5165         while (args[f]) {
5166                 const char *name;
5167                 _cleanup_free_ char *p = NULL, *q = NULL, *l = NULL;
5168                 bool found_native = false, found_sysv;
5169                 unsigned c = 1;
5170                 const char *argv[6] = { "/sbin/chkconfig", NULL, NULL, NULL, NULL };
5171                 char **k;
5172                 int j;
5173                 pid_t pid;
5174                 siginfo_t status;
5175
5176                 name = args[f++];
5177
5178                 if (!endswith(name, ".service"))
5179                         continue;
5180
5181                 if (path_is_absolute(name))
5182                         continue;
5183
5184                 STRV_FOREACH(k, paths.unit_path) {
5185                         _cleanup_free_ char *path = NULL;
5186
5187                         path = path_join(arg_root, *k, name);
5188                         if (!path)
5189                                 return log_oom();
5190
5191                         found_native = access(path, F_OK) >= 0;
5192                         if (found_native)
5193                                 break;
5194                 }
5195
5196                 if (found_native)
5197                         continue;
5198
5199                 p = path_join(arg_root, SYSTEM_SYSVINIT_PATH, name);
5200                 if (!p)
5201                         return log_oom();
5202
5203                 p[strlen(p) - strlen(".service")] = 0;
5204                 found_sysv = access(p, F_OK) >= 0;
5205                 if (!found_sysv)
5206                         continue;
5207
5208                 log_info("%s is not a native service, redirecting to /sbin/chkconfig.", name);
5209
5210                 if (!isempty(arg_root))
5211                         argv[c++] = q = strappend("--root=", arg_root);
5212
5213                 argv[c++] = basename(p);
5214                 argv[c++] =
5215                         streq(verb, "enable") ? "on" :
5216                         streq(verb, "disable") ? "off" : "--level=5";
5217                 argv[c] = NULL;
5218
5219                 l = strv_join((char**)argv, " ");
5220                 if (!l)
5221                         return log_oom();
5222
5223                 log_info("Executing %s", l);
5224
5225                 pid = fork();
5226                 if (pid < 0)
5227                         return log_error_errno(errno, "Failed to fork: %m");
5228                 else if (pid == 0) {
5229                         /* Child */
5230
5231                         execv(argv[0], (char**) argv);
5232                         _exit(EXIT_FAILURE);
5233                 }
5234
5235                 j = wait_for_terminate(pid, &status);
5236                 if (j < 0) {
5237                         log_error_errno(r, "Failed to wait for child: %m");
5238                         return j;
5239                 }
5240
5241                 if (status.si_code == CLD_EXITED) {
5242                         if (streq(verb, "is-enabled")) {
5243                                 if (status.si_status == 0) {
5244                                         if (!arg_quiet)
5245                                                 puts("enabled");
5246                                         r = 1;
5247                                 } else {
5248                                         if (!arg_quiet)
5249                                                 puts("disabled");
5250                                 }
5251
5252                         } else if (status.si_status != 0)
5253                                 return -EINVAL;
5254                 } else
5255                         return -EPROTO;
5256
5257                 /* Remove this entry, so that we don't try enabling it as native unit */
5258                 assert(f > 0 && streq(args[f-1], name));
5259                 assert_se(strv_remove(args + f - 1, name));
5260         }
5261
5262 #endif
5263         return r;
5264 }
5265
5266 static int mangle_names(char **original_names, char ***mangled_names) {
5267         char **i, **l, **name;
5268
5269         l = new(char*, strv_length(original_names) + 1);
5270         if (!l)
5271                 return log_oom();
5272
5273         i = l;
5274         STRV_FOREACH(name, original_names) {
5275
5276                 /* When enabling units qualified path names are OK,
5277                  * too, hence allow them explicitly. */
5278
5279                 if (is_path(*name))
5280                         *i = strdup(*name);
5281                 else
5282                         *i = unit_name_mangle(*name, MANGLE_NOGLOB);
5283
5284                 if (!*i) {
5285                         strv_free(l);
5286                         return log_oom();
5287                 }
5288
5289                 i++;
5290         }
5291
5292         *i = NULL;
5293         *mangled_names = l;
5294
5295         return 0;
5296 }
5297
5298 static int enable_unit(sd_bus *bus, char **args) {
5299         _cleanup_strv_free_ char **names = NULL;
5300         const char *verb = args[0];
5301         UnitFileChange *changes = NULL;
5302         unsigned n_changes = 0;
5303         int carries_install_info = -1;
5304         int r;
5305
5306         if (!args[1])
5307                 return 0;
5308
5309         r = mangle_names(args+1, &names);
5310         if (r < 0)
5311                 return r;
5312
5313         r = enable_sysv_units(verb, names);
5314         if (r < 0)
5315                 return r;
5316
5317         /* If the operation was fully executed by the SysV compat,
5318          * let's finish early */
5319         if (strv_isempty(names))
5320                 return 0;
5321
5322         if (!bus || avoid_bus()) {
5323                 if (streq(verb, "enable")) {
5324                         r = unit_file_enable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5325                         carries_install_info = r;
5326                 } else if (streq(verb, "disable"))
5327                         r = unit_file_disable(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
5328                 else if (streq(verb, "reenable")) {
5329                         r = unit_file_reenable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5330                         carries_install_info = r;
5331                 } else if (streq(verb, "link"))
5332                         r = unit_file_link(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5333                 else if (streq(verb, "preset")) {
5334                         r = unit_file_preset(arg_scope, arg_runtime, arg_root, names, arg_preset_mode, arg_force, &changes, &n_changes);
5335                         carries_install_info = r;
5336                 } else if (streq(verb, "mask"))
5337                         r = unit_file_mask(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5338                 else if (streq(verb, "unmask"))
5339                         r = unit_file_unmask(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
5340                 else
5341                         assert_not_reached("Unknown verb");
5342
5343                 if (r < 0) {
5344                         log_error_errno(r, "Operation failed: %m");
5345                         goto finish;
5346                 }
5347
5348                 if (!arg_quiet)
5349                         dump_unit_file_changes(changes, n_changes);
5350
5351                 r = 0;
5352         } else {
5353                 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
5354                 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5355                 int expect_carries_install_info = false;
5356                 bool send_force = true, send_preset_mode = false;
5357                 const char *method;
5358
5359                 if (streq(verb, "enable")) {
5360                         method = "EnableUnitFiles";
5361                         expect_carries_install_info = true;
5362                 } else if (streq(verb, "disable")) {
5363                         method = "DisableUnitFiles";
5364                         send_force = false;
5365                 } else if (streq(verb, "reenable")) {
5366                         method = "ReenableUnitFiles";
5367                         expect_carries_install_info = true;
5368                 } else if (streq(verb, "link"))
5369                         method = "LinkUnitFiles";
5370                 else if (streq(verb, "preset")) {
5371
5372                         if (arg_preset_mode != UNIT_FILE_PRESET_FULL) {
5373                                 method = "PresetUnitFilesWithMode";
5374                                 send_preset_mode = true;
5375                         } else
5376                                 method = "PresetUnitFiles";
5377
5378                         expect_carries_install_info = true;
5379                 } else if (streq(verb, "mask"))
5380                         method = "MaskUnitFiles";
5381                 else if (streq(verb, "unmask")) {
5382                         method = "UnmaskUnitFiles";
5383                         send_force = false;
5384                 } else
5385                         assert_not_reached("Unknown verb");
5386
5387                 r = sd_bus_message_new_method_call(
5388                                 bus,
5389                                 &m,
5390                                 "org.freedesktop.systemd1",
5391                                 "/org/freedesktop/systemd1",
5392                                 "org.freedesktop.systemd1.Manager",
5393                                 method);
5394                 if (r < 0)
5395                         return bus_log_create_error(r);
5396
5397                 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5398                 if (r < 0)
5399                         return bus_log_create_error(r);
5400
5401                 r = sd_bus_message_append_strv(m, names);
5402                 if (r < 0)
5403                         return bus_log_create_error(r);
5404
5405                 if (send_preset_mode) {
5406                         r = sd_bus_message_append(m, "s", unit_file_preset_mode_to_string(arg_preset_mode));
5407                         if (r < 0)
5408                                 return bus_log_create_error(r);
5409                 }
5410
5411                 r = sd_bus_message_append(m, "b", arg_runtime);
5412                 if (r < 0)
5413                         return bus_log_create_error(r);
5414
5415                 if (send_force) {
5416                         r = sd_bus_message_append(m, "b", arg_force);
5417                         if (r < 0)
5418                                 return bus_log_create_error(r);
5419                 }
5420
5421                 r = sd_bus_call(bus, m, 0, &error, &reply);
5422                 if (r < 0) {
5423                         log_error("Failed to execute operation: %s", bus_error_message(&error, r));
5424                         return r;
5425                 }
5426
5427                 if (expect_carries_install_info) {
5428                         r = sd_bus_message_read(reply, "b", &carries_install_info);
5429                         if (r < 0)
5430                                 return bus_log_parse_error(r);
5431                 }
5432
5433                 r = deserialize_and_dump_unit_file_changes(reply);
5434                 if (r < 0)
5435                         return r;
5436
5437                 /* Try to reload if enabled */
5438                 if (!arg_no_reload)
5439                         r = daemon_reload(bus, args);
5440                 else
5441                         r = 0;
5442         }
5443
5444         if (carries_install_info == 0)
5445                 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
5446                             "using systemctl.\n"
5447                             "Possible reasons for having this kind of units are:\n"
5448                             "1) A unit may be statically enabled by being symlinked from another unit's\n"
5449                             "   .wants/ or .requires/ directory.\n"
5450                             "2) A unit's purpose may be to act as a helper for some other unit which has\n"
5451                             "   a requirement dependency on it.\n"
5452                             "3) A unit may be started when needed via activation (socket, path, timer,\n"
5453                             "   D-Bus, udev, scripted systemctl call, ...).\n");
5454
5455 finish:
5456         unit_file_changes_free(changes, n_changes);
5457
5458         return r;
5459 }
5460
5461 static int add_dependency(sd_bus *bus, char **args) {
5462         _cleanup_strv_free_ char **names = NULL;
5463         _cleanup_free_ char *target = NULL;
5464         const char *verb = args[0];
5465         UnitDependency dep;
5466         int r = 0;
5467
5468         if (!args[1])
5469                 return 0;
5470
5471         target = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".target");
5472         if (!target)
5473                 return log_oom();
5474
5475         r = mangle_names(args+2, &names);
5476         if (r < 0)
5477                 return r;
5478
5479         if (streq(verb, "add-wants"))
5480                 dep = UNIT_WANTS;
5481         else if (streq(verb, "add-requires"))
5482                 dep = UNIT_REQUIRES;
5483         else
5484                 assert_not_reached("Unknown verb");
5485
5486         if (!bus || avoid_bus()) {
5487                 UnitFileChange *changes = NULL;
5488                 unsigned n_changes = 0;
5489
5490                 r = unit_file_add_dependency(arg_scope, arg_runtime, arg_root, names, target, dep, arg_force, &changes, &n_changes);
5491
5492                 if (r < 0)
5493                         return log_error_errno(r, "Can't add dependency: %m");
5494
5495                 if (!arg_quiet)
5496                         dump_unit_file_changes(changes, n_changes);
5497
5498                 unit_file_changes_free(changes, n_changes);
5499
5500         } else {
5501                 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
5502                 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5503
5504                 r = sd_bus_message_new_method_call(
5505                                 bus,
5506                                 &m,
5507                                 "org.freedesktop.systemd1",
5508                                 "/org/freedesktop/systemd1",
5509                                 "org.freedesktop.systemd1.Manager",
5510                                 "AddDependencyUnitFiles");
5511                 if (r < 0)
5512                         return bus_log_create_error(r);
5513
5514                 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5515                 if (r < 0)
5516                         return bus_log_create_error(r);
5517
5518                 r = sd_bus_message_append_strv(m, names);
5519                 if (r < 0)
5520                         return bus_log_create_error(r);
5521
5522                 r = sd_bus_message_append(m, "ssbb", target, unit_dependency_to_string(dep), arg_runtime, arg_force);
5523                 if (r < 0)
5524                         return bus_log_create_error(r);
5525
5526                 r = sd_bus_call(bus, m, 0, &error, &reply);
5527                 if (r < 0) {
5528                         log_error("Failed to execute operation: %s", bus_error_message(&error, r));
5529                         return r;
5530                 }
5531
5532                 r = deserialize_and_dump_unit_file_changes(reply);
5533                 if (r < 0)
5534                         return r;
5535
5536                 if (!arg_no_reload)
5537                         r = daemon_reload(bus, args);
5538                 else
5539                         r = 0;
5540         }
5541
5542         return r;
5543 }
5544
5545 static int preset_all(sd_bus *bus, char **args) {
5546         UnitFileChange *changes = NULL;
5547         unsigned n_changes = 0;
5548         int r;
5549
5550         if (!bus || avoid_bus()) {
5551
5552                 r = unit_file_preset_all(arg_scope, arg_runtime, arg_root, arg_preset_mode, arg_force, &changes, &n_changes);
5553                 if (r < 0) {
5554                         log_error_errno(r, "Operation failed: %m");
5555                         goto finish;
5556                 }
5557
5558                 if (!arg_quiet)
5559                         dump_unit_file_changes(changes, n_changes);
5560
5561                 r = 0;
5562
5563         } else {
5564                 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
5565                 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5566
5567                 r = sd_bus_message_new_method_call(
5568                                 bus,
5569                                 &m,
5570                                 "org.freedesktop.systemd1",
5571                                 "/org/freedesktop/systemd1",
5572                                 "org.freedesktop.systemd1.Manager",
5573                                 "PresetAllUnitFiles");
5574                 if (r < 0)
5575                         return bus_log_create_error(r);
5576
5577                 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5578                 if (r < 0)
5579                         return bus_log_create_error(r);
5580
5581                 r = sd_bus_message_append(
5582                                 m,
5583                                 "sbb",
5584                                 unit_file_preset_mode_to_string(arg_preset_mode),
5585                                 arg_runtime,
5586                                 arg_force);
5587                 if (r < 0)
5588                         return bus_log_create_error(r);
5589
5590                 r = sd_bus_call(bus, m, 0, &error, &reply);
5591                 if (r < 0) {
5592                         log_error("Failed to execute operation: %s", bus_error_message(&error, r));
5593                         return r;
5594                 }
5595
5596                 r = deserialize_and_dump_unit_file_changes(reply);
5597                 if (r < 0)
5598                         return r;
5599
5600                 if (!arg_no_reload)
5601                         r = daemon_reload(bus, args);
5602                 else
5603                         r = 0;
5604         }
5605
5606 finish:
5607         unit_file_changes_free(changes, n_changes);
5608
5609         return r;
5610 }
5611
5612 static int unit_is_enabled(sd_bus *bus, char **args) {
5613
5614         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5615         _cleanup_strv_free_ char **names = NULL;
5616         bool enabled;
5617         char **name;
5618         int r;
5619
5620         r = mangle_names(args+1, &names);
5621         if (r < 0)
5622                 return r;
5623
5624         r = enable_sysv_units(args[0], names);
5625         if (r < 0)
5626                 return r;
5627
5628         enabled = r > 0;
5629
5630         if (!bus || avoid_bus()) {
5631
5632                 STRV_FOREACH(name, names) {
5633                         UnitFileState state;
5634
5635                         state = unit_file_get_state(arg_scope, arg_root, *name);
5636                         if (state < 0)
5637                                 return log_error_errno(state, "Failed to get unit file state for %s: %m", *name);
5638
5639                         if (state == UNIT_FILE_ENABLED ||
5640                             state == UNIT_FILE_ENABLED_RUNTIME ||
5641                             state == UNIT_FILE_STATIC ||
5642                             state == UNIT_FILE_INDIRECT)
5643                                 enabled = true;
5644
5645                         if (!arg_quiet)
5646                                 puts(unit_file_state_to_string(state));
5647                 }
5648
5649         } else {
5650                 STRV_FOREACH(name, names) {
5651                         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
5652                         const char *s;
5653
5654                         r = sd_bus_call_method(
5655                                         bus,
5656                                         "org.freedesktop.systemd1",
5657                                         "/org/freedesktop/systemd1",
5658                                         "org.freedesktop.systemd1.Manager",
5659                                         "GetUnitFileState",
5660                                         &error,
5661                                         &reply,
5662                                         "s", *name);
5663                         if (r < 0) {
5664                                 log_error("Failed to get unit file state for %s: %s", *name, bus_error_message(&error, r));
5665                                 return r;
5666                         }
5667
5668                         r = sd_bus_message_read(reply, "s", &s);
5669                         if (r < 0)
5670                                 return bus_log_parse_error(r);
5671
5672                         if (STR_IN_SET(s, "enabled", "enabled-runtime", "static", "indirect"))
5673                                 enabled = true;
5674
5675                         if (!arg_quiet)
5676                                 puts(s);
5677                 }
5678         }
5679
5680         return !enabled;
5681 }
5682
5683 static int is_system_running(sd_bus *bus, char **args) {
5684         _cleanup_free_ char *state = NULL;
5685         int r;
5686
5687         r = sd_bus_get_property_string(
5688                         bus,
5689                         "org.freedesktop.systemd1",
5690                         "/org/freedesktop/systemd1",
5691                         "org.freedesktop.systemd1.Manager",
5692                         "SystemState",
5693                         NULL,
5694                         &state);
5695         if (r < 0) {
5696                 if (!arg_quiet)
5697                         puts("unknown");
5698                 return 0;
5699         }
5700
5701         if (!arg_quiet)
5702                 puts(state);
5703
5704         return streq(state, "running") ? EXIT_SUCCESS : EXIT_FAILURE;
5705 }
5706
5707 static int unit_file_find_path(LookupPaths *lp, const char *unit_name, char **unit_path) {
5708         char **p;
5709
5710         assert(lp);
5711         assert(unit_name);
5712         assert(unit_path);
5713
5714         STRV_FOREACH(p, lp->unit_path) {
5715                 char *path;
5716
5717                 path = path_join(arg_root, *p, unit_name);
5718                 if (!path)
5719                         return log_oom();
5720
5721                 if (access(path, F_OK) == 0) {
5722                         *unit_path = path;
5723                         return 1;
5724                 }
5725
5726                 free(path);
5727         }
5728
5729         return 0;
5730 }
5731
5732 static int create_edit_temp_file(const char *new_path, const char *original_path, char **ret_tmp_fn) {
5733         char *t;
5734         int r;
5735
5736         assert(new_path);
5737         assert(original_path);
5738         assert(ret_tmp_fn);
5739
5740         r = tempfn_random(new_path, &t);
5741         if (r < 0)
5742                 return log_error_errno(r, "Failed to determine temporary filename for %s: %m", new_path);
5743
5744         r = mkdir_parents(new_path, 0755);
5745         if (r < 0) {
5746                 log_error_errno(r, "Failed to create directories for %s: %m", new_path);
5747                 free(t);
5748                 return r;
5749         }
5750
5751         r = copy_file(original_path, t, 0, 0644);
5752         if (r == -ENOENT) {
5753                 r = touch(t);
5754                 if (r < 0) {
5755                         log_error_errno(r, "Failed to create temporary file %s: %m", t);
5756                         free(t);
5757                         return r;
5758                 }
5759         } else if (r < 0) {
5760                 log_error_errno(r, "Failed to copy %s to %s: %m", original_path, t);
5761                 free(t);
5762                 return r;
5763         }
5764
5765         *ret_tmp_fn = t;
5766
5767         return 0;
5768 }
5769
5770 static int get_drop_in_to_edit(const char *unit_name, const char *user_home, const char *user_runtime, char **ret_path) {
5771         char *tmp_new_path;
5772         char *tmp;
5773
5774         assert(unit_name);
5775         assert(ret_path);
5776
5777         switch (arg_scope) {
5778                 case UNIT_FILE_SYSTEM:
5779                         tmp = strappenda(arg_runtime ? "/run/systemd/system/" : SYSTEM_CONFIG_UNIT_PATH "/", unit_name, ".d/override.conf");
5780                         break;
5781                 case UNIT_FILE_GLOBAL:
5782                         tmp = strappenda(arg_runtime ? "/run/systemd/user/" : USER_CONFIG_UNIT_PATH "/", unit_name, ".d/override.conf");
5783                         break;
5784                 case UNIT_FILE_USER:
5785                         assert(user_home);
5786                         assert(user_runtime);
5787
5788                         tmp = strappenda(arg_runtime ? user_runtime : user_home, "/", unit_name, ".d/override.conf");
5789                         break;
5790                 default:
5791                         assert_not_reached("Invalid scope");
5792         }
5793
5794         tmp_new_path = path_join(arg_root, tmp, NULL);
5795         if (!tmp_new_path)
5796                 return log_oom();
5797
5798         *ret_path = tmp_new_path;
5799
5800         return 0;
5801 }
5802
5803 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) {
5804         char *tmp_new_path;
5805         char *tmp_tmp_path;
5806         int r;
5807
5808         assert(unit_name);
5809         assert(ret_new_path);
5810         assert(ret_tmp_path);
5811
5812         r = get_drop_in_to_edit(unit_name, user_home, user_runtime, &tmp_new_path);
5813         if (r < 0)
5814                 return r;
5815
5816         r = create_edit_temp_file(tmp_new_path, tmp_new_path, &tmp_tmp_path);
5817         if (r < 0) {
5818                 free(tmp_new_path);
5819                 return r;
5820         }
5821
5822         *ret_new_path = tmp_new_path;
5823         *ret_tmp_path = tmp_tmp_path;
5824
5825         return 0;
5826 }
5827
5828 static bool unit_is_editable(const char *unit_name, const char *fragment_path, const char *user_home) {
5829         bool editable = true;
5830         const char *invalid_path;
5831
5832         assert(unit_name);
5833
5834         if (!arg_runtime)
5835                 return true;
5836
5837         switch (arg_scope) {
5838                 case UNIT_FILE_SYSTEM:
5839                         if (path_startswith(fragment_path, "/etc/systemd/system")) {
5840                                 editable = false;
5841                                 invalid_path = "/etc/systemd/system";
5842                         } else if (path_startswith(fragment_path, SYSTEM_CONFIG_UNIT_PATH)) {
5843                                 editable = false;
5844                                 invalid_path = SYSTEM_CONFIG_UNIT_PATH;
5845                         }
5846                         break;
5847                 case UNIT_FILE_GLOBAL:
5848                         if (path_startswith(fragment_path, "/etc/systemd/user")) {
5849                                 editable = false;
5850                                 invalid_path = "/etc/systemd/user";
5851                         } else if (path_startswith(fragment_path, USER_CONFIG_UNIT_PATH)) {
5852                                 editable = false;
5853                                 invalid_path = USER_CONFIG_UNIT_PATH;
5854                         }
5855                         break;
5856                 case UNIT_FILE_USER:
5857                         assert(user_home);
5858
5859                         if (path_startswith(fragment_path, "/etc/systemd/user")) {
5860                                 editable = false;
5861                                 invalid_path = "/etc/systemd/user";
5862                         } else if (path_startswith(fragment_path, USER_CONFIG_UNIT_PATH)) {
5863                                 editable = false;
5864                                 invalid_path = USER_CONFIG_UNIT_PATH;
5865                         } else if (path_startswith(fragment_path, user_home)) {
5866                                 editable = false;
5867                                 invalid_path = user_home;
5868                         }
5869                         break;
5870                 default:
5871                         assert_not_reached("Invalid scope");
5872         }
5873
5874         if (!editable)
5875                 log_error("%s ignored: cannot temporarily edit units from %s", unit_name, invalid_path);
5876
5877         return editable;
5878 }
5879
5880 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) {
5881         char *tmp_new_path;
5882
5883         assert(unit_name);
5884         assert(ret_path);
5885
5886         if (!unit_is_editable(unit_name, fragment_path, user_home))
5887                 return -EINVAL;
5888
5889         switch (arg_scope) {
5890                 case UNIT_FILE_SYSTEM:
5891                         tmp_new_path = path_join(arg_root, arg_runtime ? "/run/systemd/system/" : SYSTEM_CONFIG_UNIT_PATH, unit_name);
5892                         break;
5893                 case UNIT_FILE_GLOBAL:
5894                         tmp_new_path = path_join(arg_root, arg_runtime ? "/run/systemd/user/" : USER_CONFIG_UNIT_PATH, unit_name);
5895                         break;
5896                 case UNIT_FILE_USER:
5897                         assert(user_home);
5898                         assert(user_runtime);
5899
5900                         tmp_new_path = path_join(arg_root, arg_runtime ? user_runtime : user_home, unit_name);
5901                         break;
5902                 default:
5903                         assert_not_reached("Invalid scope");
5904         }
5905         if (!tmp_new_path)
5906                 return log_oom();
5907
5908         *ret_path = tmp_new_path;
5909
5910         return 0;
5911 }
5912
5913 static int unit_file_create_copy(const char *unit_name,
5914                                  const char *fragment_path,
5915                                  const char *user_home,
5916                                  const char *user_runtime,
5917                                  char **ret_new_path,
5918                                  char **ret_tmp_path) {
5919         char *tmp_new_path;
5920         char *tmp_tmp_path;
5921         int r;
5922
5923         assert(fragment_path);
5924         assert(unit_name);
5925         assert(ret_new_path);
5926         assert(ret_tmp_path);
5927
5928         r = get_copy_to_edit(unit_name, fragment_path, user_home, user_runtime, &tmp_new_path);
5929         if (r < 0)
5930                 return r;
5931
5932         if (!path_equal(fragment_path, tmp_new_path) && access(tmp_new_path, F_OK) == 0) {
5933                 char response;
5934
5935                 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);
5936                 if (r < 0) {
5937                         free(tmp_new_path);
5938                         return r;
5939                 }
5940                 if (response != 'y') {
5941                         log_warning("%s ignored", unit_name);
5942                         free(tmp_new_path);
5943                         return -1;
5944                 }
5945         }
5946
5947         r = create_edit_temp_file(tmp_new_path, fragment_path, &tmp_tmp_path);
5948         if (r < 0) {
5949                 log_error_errno(r, "Failed to create temporary file for %s: %m", tmp_new_path);
5950                 free(tmp_new_path);
5951                 return r;
5952         }
5953
5954         *ret_new_path = tmp_new_path;
5955         *ret_tmp_path = tmp_tmp_path;
5956
5957         return 0;
5958 }
5959
5960 static int run_editor(char **paths) {
5961         pid_t pid;
5962         int r;
5963
5964         assert(paths);
5965
5966         pid = fork();
5967         if (pid < 0) {
5968                 log_error_errno(errno, "Failed to fork: %m");
5969                 return -errno;
5970         }
5971
5972         if (pid == 0) {
5973                 const char **args;
5974                 char **backup_editors = STRV_MAKE("nano", "vim", "vi");
5975                 char *editor;
5976                 char **tmp_path, **original_path, **p;
5977                 unsigned i = 1;
5978                 size_t argc;
5979
5980                 argc = strv_length(paths)/2 + 1;
5981                 args = newa(const char*, argc + 1);
5982
5983                 args[0] = NULL;
5984                 STRV_FOREACH_PAIR(original_path, tmp_path, paths) {
5985                         args[i] = *tmp_path;
5986                         i++;
5987                 }
5988                 args[argc] = NULL;
5989
5990                 /* SYSTEMD_EDITOR takes precedence over EDITOR which takes precedence over VISUAL
5991                  * If neither SYSTEMD_EDITOR nor EDITOR nor VISUAL are present,
5992                  * we try to execute well known editors
5993                  */
5994                 editor = getenv("SYSTEMD_EDITOR");
5995                 if (!editor)
5996                         editor = getenv("EDITOR");
5997                 if (!editor)
5998                         editor = getenv("VISUAL");
5999
6000                 if (!isempty(editor)) {
6001                         args[0] = editor;
6002                         execvp(editor, (char* const*) args);
6003                 }
6004
6005                 STRV_FOREACH(p, backup_editors) {
6006                         args[0] = *p;
6007                         execvp(*p, (char* const*) args);
6008                         /* We do not fail if the editor doesn't exist
6009                          * because we want to try each one of them before
6010                          * failing.
6011                          */
6012                         if (errno != ENOENT) {
6013                                 log_error("Failed to execute %s: %m", editor);
6014                                 _exit(EXIT_FAILURE);
6015                         }
6016                 }
6017
6018                 log_error("Cannot edit unit(s): No editor available. Please set either SYSTEMD_EDITOR or EDITOR or VISUAL environment variable");
6019                 _exit(EXIT_FAILURE);
6020         }
6021
6022         r = wait_for_terminate_and_warn("editor", pid, true);
6023         if (r < 0)
6024                 return log_error_errno(r, "Failed to wait for child: %m");
6025
6026         return r;
6027 }
6028
6029 static int unit_find_path(sd_bus *bus, const char *unit_name, const char *template, bool avoid_bus_cache, LookupPaths *lp, char **path) {
6030         int r;
6031
6032         assert(unit_name);
6033         assert(path);
6034         assert(lp);
6035
6036         if (!avoid_bus_cache && !unit_name_is_template(unit_name)) {
6037                 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
6038                 _cleanup_free_ char *unit = NULL;
6039                 _cleanup_free_ char *tmp_path = NULL;
6040
6041                 unit = unit_dbus_path_from_name(unit_name);
6042                 if (!unit)
6043                         return log_oom();
6044
6045                 if (need_daemon_reload(bus, unit_name) > 0) {
6046                         log_warning("%s ignored: unit file changed on disk. Run 'systemctl%s daemon-reload'.",
6047                                     unit_name, arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
6048                         return 0;
6049                 }
6050
6051                 r = sd_bus_get_property_string(
6052                                 bus,
6053                                 "org.freedesktop.systemd1",
6054                                 unit,
6055                                 "org.freedesktop.systemd1.Unit",
6056                                 "FragmentPath",
6057                                 &error,
6058                                 &tmp_path);
6059                 if (r < 0) {
6060                         log_warning("Failed to get FragmentPath: %s", bus_error_message(&error, r));
6061                         return 0;
6062                 }
6063
6064                 if (isempty(tmp_path)) {
6065                         log_warning("%s ignored: not found", template);
6066                         return 0;
6067                 }
6068
6069                 *path = tmp_path;
6070                 tmp_path = NULL;
6071
6072                 return 1;
6073         } else {
6074                 r = unit_file_find_path(lp, template, path);
6075                 if (r == 0)
6076                         log_warning("%s ignored: not found", template);
6077                 return r;
6078         }
6079
6080         return 0;
6081 }
6082
6083 static int find_paths_to_edit(sd_bus *bus, char **names, char ***paths) {
6084         _cleanup_free_ char *user_home = NULL;
6085         _cleanup_free_ char *user_runtime = NULL;
6086         _cleanup_lookup_paths_free_ LookupPaths lp = {};
6087         bool avoid_bus_cache;
6088         char **name;
6089         int r;
6090
6091         assert(names);
6092         assert(paths);
6093
6094         if (arg_scope == UNIT_FILE_USER) {
6095                 r = user_config_home(&user_home);
6096                 if (r < 0)
6097                         return log_oom();
6098                 else if (r == 0) {
6099                         log_error("Cannot edit units for the user instance: home directory unknown");
6100                         return -1;
6101                 }
6102
6103                 r = user_runtime_dir(&user_runtime);
6104                 if (r < 0)
6105                         return log_oom();
6106                 else if (r == 0) {
6107                         log_error("Cannot edit units for the user instance: runtime directory unknown");
6108                         return -1;
6109                 }
6110         }
6111
6112         r = lookup_paths_init(&lp,
6113                               arg_scope == UNIT_FILE_SYSTEM ? SYSTEMD_SYSTEM : SYSTEMD_USER,
6114                               arg_scope == UNIT_FILE_USER,
6115                               arg_root,
6116                               NULL, NULL, NULL);
6117         if (r < 0) {
6118                 log_error_errno(r, "Failed get lookup paths: %m");
6119                 return r;
6120         }
6121
6122         avoid_bus_cache = !bus || avoid_bus();
6123
6124         STRV_FOREACH(name, names) {
6125                 _cleanup_free_ char *path = NULL;
6126                 _cleanup_free_ char *template = NULL;
6127                 char *new_path, *tmp_path;
6128
6129                 template = unit_name_template(*name);
6130                 if (!template)
6131                         return log_oom();
6132
6133                 r = unit_find_path(bus, *name, template, avoid_bus_cache, &lp, &path);
6134                 if (r < 0)
6135                         return r;
6136                 else if (r == 0) {
6137                         continue;
6138                 }
6139
6140                 if (arg_full)
6141                         r = unit_file_create_copy(template, path, user_home, user_runtime, &new_path, &tmp_path);
6142                 else
6143                         r = unit_file_create_drop_in(template, user_home, user_runtime, &new_path, &tmp_path);
6144
6145                 if (r < 0)
6146                         continue;
6147
6148                 r = strv_push_pair(paths, new_path, tmp_path);
6149                 if (r < 0)
6150                         return log_oom();
6151         }
6152
6153         return 0;
6154 }
6155
6156 static int edit(sd_bus *bus, char **args) {
6157         _cleanup_strv_free_ char **names = NULL;
6158         _cleanup_strv_free_ char **paths = NULL;
6159         char **original, **tmp;
6160         int r;
6161
6162         assert(args);
6163
6164         if (!on_tty()) {
6165                 log_error("Cannot edit units if we are not on a tty");
6166                 return -EINVAL;
6167         }
6168
6169         if (arg_transport != BUS_TRANSPORT_LOCAL) {
6170                 log_error("Cannot remotely edit units");
6171                 return -EINVAL;
6172         }
6173
6174         r = expand_names(bus, args + 1, NULL, &names);
6175         if (r < 0)
6176                 return log_error_errno(r, "Failed to expand names: %m");
6177
6178         if (!names) {
6179                 log_error("No unit name found by expanding names");
6180                 return -ENOENT;
6181         }
6182
6183         r = find_paths_to_edit(bus, names, &paths);
6184         if (r < 0)
6185                 return r;
6186
6187         if (strv_isempty(paths)) {
6188                 log_error("Cannot find any units to edit");
6189                 return -ENOENT;
6190         }
6191
6192         r = run_editor(paths);
6193         if (r < 0)
6194                 goto end;
6195
6196         STRV_FOREACH_PAIR(original, tmp, paths) {
6197                 /* If the temporary file is empty we ignore it.
6198                  * It's useful if the user wants to cancel its modification
6199                  */
6200                 if (null_or_empty_path(*tmp)) {
6201                         log_warning("Edition of %s canceled: temporary file empty", *original);
6202                         continue;
6203                 }
6204                 r = rename(*tmp, *original);
6205                 if (r < 0) {
6206                         r = log_error_errno(errno, "Failed to rename %s to %s: %m", *tmp, *original);
6207                         goto end;
6208                 }
6209         }
6210
6211         if (!arg_no_reload && bus && !avoid_bus())
6212                 r = daemon_reload(bus, args);
6213
6214 end:
6215         STRV_FOREACH_PAIR(original, tmp, paths)
6216                 unlink_noerrno(*tmp);
6217
6218         return r;
6219 }
6220
6221 static void systemctl_help(void) {
6222
6223         pager_open_if_enabled();
6224
6225         printf("%s [OPTIONS...] {COMMAND} ...\n\n"
6226                "Query or send control commands to the systemd manager.\n\n"
6227                "  -h --help           Show this help\n"
6228                "     --version        Show package version\n"
6229                "     --system         Connect to system manager\n"
6230                "     --user           Connect to user service manager\n"
6231                "  -H --host=[USER@]HOST\n"
6232                "                      Operate on remote host\n"
6233                "  -M --machine=CONTAINER\n"
6234                "                      Operate on local container\n"
6235                "  -t --type=TYPE      List only units of a particular type\n"
6236                "     --state=STATE    List only units with particular LOAD or SUB or ACTIVE state\n"
6237                "  -p --property=NAME  Show only properties by this name\n"
6238                "  -a --all            Show all loaded units/properties, including dead/empty\n"
6239                "                      ones. To list all units installed on the system, use\n"
6240                "                      the 'list-unit-files' command instead.\n"
6241                "  -l --full           Don't ellipsize unit names on output\n"
6242                "  -r --recursive      Show unit list of host and local containers\n"
6243                "     --reverse        Show reverse dependencies with 'list-dependencies'\n"
6244                "     --job-mode=MODE  Specify how to deal with already queued jobs, when\n"
6245                "                      queueing a new job\n"
6246                "     --show-types     When showing sockets, explicitly show their type\n"
6247                "  -i --ignore-inhibitors\n"
6248                "                      When shutting down or sleeping, ignore inhibitors\n"
6249                "     --kill-who=WHO   Who to send signal to\n"
6250                "  -s --signal=SIGNAL  Which signal to send\n"
6251                "  -q --quiet          Suppress output\n"
6252                "     --no-block       Do not wait until operation finished\n"
6253                "     --no-wall        Don't send wall message before halt/power-off/reboot\n"
6254                "     --no-reload      When enabling/disabling unit files, don't reload daemon\n"
6255                "                      configuration\n"
6256                "     --no-legend      Do not print a legend (column headers and hints)\n"
6257                "     --no-pager       Do not pipe output into a pager\n"
6258                "     --no-ask-password\n"
6259                "                      Do not ask for system passwords\n"
6260                "     --global         Enable/disable unit files globally\n"
6261                "     --runtime        Enable unit files only temporarily until next reboot\n"
6262                "  -f --force          When enabling unit files, override existing symlinks\n"
6263                "                      When shutting down, execute action immediately\n"
6264                "     --preset-mode=   Specifies whether fully apply presets, or only enable,\n"
6265                "                      or only disable\n"
6266                "     --root=PATH      Enable unit files in the specified root directory\n"
6267                "  -n --lines=INTEGER  Number of journal entries to show\n"
6268                "  -o --output=STRING  Change journal output mode (short, short-monotonic,\n"
6269                "                      verbose, export, json, json-pretty, json-sse, cat)\n"
6270                "     --plain          Print unit dependencies as a list instead of a tree\n\n"
6271                "Unit Commands:\n"
6272                "  list-units [PATTERN...]         List loaded units\n"
6273                "  list-sockets [PATTERN...]       List loaded sockets ordered by address\n"
6274                "  list-timers [PATTERN...]        List loaded timers ordered by next elapse\n"
6275                "  start NAME...                   Start (activate) one or more units\n"
6276                "  stop NAME...                    Stop (deactivate) one or more units\n"
6277                "  reload NAME...                  Reload one or more units\n"
6278                "  restart NAME...                 Start or restart one or more units\n"
6279                "  try-restart NAME...             Restart one or more units if active\n"
6280                "  reload-or-restart NAME...       Reload one or more units if possible,\n"
6281                "                                  otherwise start or restart\n"
6282                "  reload-or-try-restart NAME...   Reload one or more units if possible,\n"
6283                "                                  otherwise restart if active\n"
6284                "  isolate NAME                    Start one unit and stop all others\n"
6285                "  kill NAME...                    Send signal to processes of a unit\n"
6286                "  is-active PATTERN...            Check whether units are active\n"
6287                "  is-failed PATTERN...            Check whether units are failed\n"
6288                "  status [PATTERN...|PID...]      Show runtime status of one or more units\n"
6289                "  show [PATTERN...|JOB...]        Show properties of one or more\n"
6290                "                                  units/jobs or the manager\n"
6291                "  cat PATTERN...                  Show files and drop-ins of one or more units\n"
6292                "  set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
6293                "  help PATTERN...|PID...          Show manual for one or more units\n"
6294                "  reset-failed [PATTERN...]       Reset failed state for all, one, or more\n"
6295                "                                  units\n"
6296                "  list-dependencies [NAME]        Recursively show units which are required\n"
6297                "                                  or wanted by this unit or by which this\n"
6298                "                                  unit is required or wanted\n\n"
6299                "Unit File Commands:\n"
6300                "  list-unit-files [PATTERN...]    List installed unit files\n"
6301                "  enable NAME...                  Enable one or more unit files\n"
6302                "  disable NAME...                 Disable one or more unit files\n"
6303                "  reenable NAME...                Reenable one or more unit files\n"
6304                "  preset NAME...                  Enable/disable one or more unit files\n"
6305                "                                  based on preset configuration\n"
6306                "  preset-all                      Enable/disable all unit files based on\n"
6307                "                                  preset configuration\n"
6308                "  is-enabled NAME...              Check whether unit files are enabled\n\n"
6309                "  mask NAME...                    Mask one or more units\n"
6310                "  unmask NAME...                  Unmask one or more units\n"
6311                "  link PATH...                    Link one or more units files into\n"
6312                "                                  the search path\n"
6313                "  add-wants TARGET NAME...        Add 'Wants' dependency for the target\n"
6314                "                                  on specified one or more units\n"
6315                "  add-requires TARGET NAME...     Add 'Requires' dependency for the target\n"
6316                "                                  on specified one or more units\n"
6317                "  get-default                     Get the name of the default target\n"
6318                "  set-default NAME                Set the default target\n"
6319                "  edit NAME...                    Edit one or more unit files\n"
6320                "\n"
6321                "Machine Commands:\n"
6322                "  list-machines [PATTERN...]      List local containers and host\n\n"
6323                "Job Commands:\n"
6324                "  list-jobs [PATTERN...]          List jobs\n"
6325                "  cancel [JOB...]                 Cancel all, one, or more jobs\n\n"
6326                "Snapshot Commands:\n"
6327                "  snapshot [NAME]                 Create a snapshot\n"
6328                "  delete NAME...                  Remove one or more snapshots\n\n"
6329                "Environment Commands:\n"
6330                "  show-environment                Dump environment\n"
6331                "  set-environment NAME=VALUE...   Set one or more environment variables\n"
6332                "  unset-environment NAME...       Unset one or more environment variables\n"
6333                "  import-environment NAME...      Import all, one or more environment variables\n\n"
6334                "Manager Lifecycle Commands:\n"
6335                "  daemon-reload                   Reload systemd manager configuration\n"
6336                "  daemon-reexec                   Reexecute systemd manager\n\n"
6337                "System Commands:\n"
6338                "  is-system-running               Check whether system is fully running\n"
6339                "  default                         Enter system default mode\n"
6340                "  rescue                          Enter system rescue mode\n"
6341                "  emergency                       Enter system emergency mode\n"
6342                "  halt                            Shut down and halt the system\n"
6343                "  poweroff                        Shut down and power-off the system\n"
6344                "  reboot [ARG]                    Shut down and reboot the system\n"
6345                "  kexec                           Shut down and reboot the system with kexec\n"
6346                "  exit                            Request user instance exit\n"
6347                "  switch-root ROOT [INIT]         Change to a different root file system\n"
6348                "  suspend                         Suspend the system\n"
6349                "  hibernate                       Hibernate the system\n"
6350                "  hybrid-sleep                    Hibernate and suspend the system\n",
6351                program_invocation_short_name);
6352 }
6353
6354 static void halt_help(void) {
6355         printf("%s [OPTIONS...]%s\n\n"
6356                "%s the system.\n\n"
6357                "     --help      Show this help\n"
6358                "     --halt      Halt the machine\n"
6359                "  -p --poweroff  Switch off the machine\n"
6360                "     --reboot    Reboot the machine\n"
6361                "  -f --force     Force immediate halt/power-off/reboot\n"
6362                "  -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
6363                "  -d --no-wtmp   Don't write wtmp record\n"
6364                "     --no-wall   Don't send wall message before halt/power-off/reboot\n",
6365                program_invocation_short_name,
6366                arg_action == ACTION_REBOOT   ? " [ARG]" : "",
6367                arg_action == ACTION_REBOOT   ? "Reboot" :
6368                arg_action == ACTION_POWEROFF ? "Power off" :
6369                                                "Halt");
6370 }
6371
6372 static void shutdown_help(void) {
6373         printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
6374                "Shut down the system.\n\n"
6375                "     --help      Show this help\n"
6376                "  -H --halt      Halt the machine\n"
6377                "  -P --poweroff  Power-off the machine\n"
6378                "  -r --reboot    Reboot the machine\n"
6379                "  -h             Equivalent to --poweroff, overridden by --halt\n"
6380                "  -k             Don't halt/power-off/reboot, just send warnings\n"
6381                "     --no-wall   Don't send wall message before halt/power-off/reboot\n"
6382                "  -c             Cancel a pending shutdown\n",
6383                program_invocation_short_name);
6384 }
6385
6386 static void telinit_help(void) {
6387         printf("%s [OPTIONS...] {COMMAND}\n\n"
6388                "Send control commands to the init daemon.\n\n"
6389                "     --help      Show this help\n"
6390                "     --no-wall   Don't send wall message before halt/power-off/reboot\n\n"
6391                "Commands:\n"
6392                "  0              Power-off the machine\n"
6393                "  6              Reboot the machine\n"
6394                "  2, 3, 4, 5     Start runlevelX.target unit\n"
6395                "  1, s, S        Enter rescue mode\n"
6396                "  q, Q           Reload init daemon configuration\n"
6397                "  u, U           Reexecute init daemon\n",
6398                program_invocation_short_name);
6399 }
6400
6401 static void runlevel_help(void) {
6402         printf("%s [OPTIONS...]\n\n"
6403                "Prints the previous and current runlevel of the init system.\n\n"
6404                "     --help      Show this help\n",
6405                program_invocation_short_name);
6406 }
6407
6408 static void help_types(void) {
6409         int i;
6410         const char *t;
6411
6412         if (!arg_no_legend)
6413                 puts("Available unit types:");
6414         for (i = 0; i < _UNIT_TYPE_MAX; i++) {
6415                 t = unit_type_to_string(i);
6416                 if (t)
6417                         puts(t);
6418         }
6419 }
6420
6421 static int systemctl_parse_argv(int argc, char *argv[]) {
6422
6423         enum {
6424                 ARG_FAIL = 0x100,
6425                 ARG_REVERSE,
6426                 ARG_AFTER,
6427                 ARG_BEFORE,
6428                 ARG_SHOW_TYPES,
6429                 ARG_IRREVERSIBLE,
6430                 ARG_IGNORE_DEPENDENCIES,
6431                 ARG_VERSION,
6432                 ARG_USER,
6433                 ARG_SYSTEM,
6434                 ARG_GLOBAL,
6435                 ARG_NO_BLOCK,
6436                 ARG_NO_LEGEND,
6437                 ARG_NO_PAGER,
6438                 ARG_NO_WALL,
6439                 ARG_ROOT,
6440                 ARG_NO_RELOAD,
6441                 ARG_KILL_WHO,
6442                 ARG_NO_ASK_PASSWORD,
6443                 ARG_FAILED,
6444                 ARG_RUNTIME,
6445                 ARG_FORCE,
6446                 ARG_PLAIN,
6447                 ARG_STATE,
6448                 ARG_JOB_MODE,
6449                 ARG_PRESET_MODE,
6450         };
6451
6452         static const struct option options[] = {
6453                 { "help",                no_argument,       NULL, 'h'                     },
6454                 { "version",             no_argument,       NULL, ARG_VERSION             },
6455                 { "type",                required_argument, NULL, 't'                     },
6456                 { "property",            required_argument, NULL, 'p'                     },
6457                 { "all",                 no_argument,       NULL, 'a'                     },
6458                 { "reverse",             no_argument,       NULL, ARG_REVERSE             },
6459                 { "after",               no_argument,       NULL, ARG_AFTER               },
6460                 { "before",              no_argument,       NULL, ARG_BEFORE              },
6461                 { "show-types",          no_argument,       NULL, ARG_SHOW_TYPES          },
6462                 { "failed",              no_argument,       NULL, ARG_FAILED              }, /* compatibility only */
6463                 { "full",                no_argument,       NULL, 'l'                     },
6464                 { "job-mode",            required_argument, NULL, ARG_JOB_MODE            },
6465                 { "fail",                no_argument,       NULL, ARG_FAIL                }, /* compatibility only */
6466                 { "irreversible",        no_argument,       NULL, ARG_IRREVERSIBLE        }, /* compatibility only */
6467                 { "ignore-dependencies", no_argument,       NULL, ARG_IGNORE_DEPENDENCIES }, /* compatibility only */
6468                 { "ignore-inhibitors",   no_argument,       NULL, 'i'                     },
6469                 { "user",                no_argument,       NULL, ARG_USER                },
6470                 { "system",              no_argument,       NULL, ARG_SYSTEM              },
6471                 { "global",              no_argument,       NULL, ARG_GLOBAL              },
6472                 { "no-block",            no_argument,       NULL, ARG_NO_BLOCK            },
6473                 { "no-legend",           no_argument,       NULL, ARG_NO_LEGEND           },
6474                 { "no-pager",            no_argument,       NULL, ARG_NO_PAGER            },
6475                 { "no-wall",             no_argument,       NULL, ARG_NO_WALL             },
6476                 { "quiet",               no_argument,       NULL, 'q'                     },
6477                 { "root",                required_argument, NULL, ARG_ROOT                },
6478                 { "force",               no_argument,       NULL, ARG_FORCE               },
6479                 { "no-reload",           no_argument,       NULL, ARG_NO_RELOAD           },
6480                 { "kill-who",            required_argument, NULL, ARG_KILL_WHO            },
6481                 { "signal",              required_argument, NULL, 's'                     },
6482                 { "no-ask-password",     no_argument,       NULL, ARG_NO_ASK_PASSWORD     },
6483                 { "host",                required_argument, NULL, 'H'                     },
6484                 { "machine",             required_argument, NULL, 'M'                     },
6485                 { "runtime",             no_argument,       NULL, ARG_RUNTIME             },
6486                 { "lines",               required_argument, NULL, 'n'                     },
6487                 { "output",              required_argument, NULL, 'o'                     },
6488                 { "plain",               no_argument,       NULL, ARG_PLAIN               },
6489                 { "state",               required_argument, NULL, ARG_STATE               },
6490                 { "recursive",           no_argument,       NULL, 'r'                     },
6491                 { "preset-mode",         required_argument, NULL, ARG_PRESET_MODE         },
6492                 {}
6493         };
6494
6495         int c;
6496
6497         assert(argc >= 0);
6498         assert(argv);
6499
6500         while ((c = getopt_long(argc, argv, "ht:p:alqfs:H:M:n:o:ir", options, NULL)) >= 0)
6501
6502                 switch (c) {
6503
6504                 case 'h':
6505                         systemctl_help();
6506                         return 0;
6507
6508                 case ARG_VERSION:
6509                         puts(PACKAGE_STRING);
6510                         puts(SYSTEMD_FEATURES);
6511                         return 0;
6512
6513                 case 't': {
6514                         const char *word, *state;
6515                         size_t size;
6516
6517                         FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
6518                                 _cleanup_free_ char *type;
6519
6520                                 type = strndup(word, size);
6521                                 if (!type)
6522                                         return -ENOMEM;
6523
6524                                 if (streq(type, "help")) {
6525                                         help_types();
6526                                         return 0;
6527                                 }
6528
6529                                 if (unit_type_from_string(type) >= 0) {
6530                                         if (strv_push(&arg_types, type))
6531                                                 return log_oom();
6532                                         type = NULL;
6533                                         continue;
6534                                 }
6535
6536                                 /* It's much nicer to use --state= for
6537                                  * load states, but let's support this
6538                                  * in --types= too for compatibility
6539                                  * with old versions */
6540                                 if (unit_load_state_from_string(optarg) >= 0) {
6541                                         if (strv_push(&arg_states, type) < 0)
6542                                                 return log_oom();
6543                                         type = NULL;
6544                                         continue;
6545                                 }
6546
6547                                 log_error("Unknown unit type or load state '%s'.", type);
6548                                 log_info("Use -t help to see a list of allowed values.");
6549                                 return -EINVAL;
6550                         }
6551
6552                         break;
6553                 }
6554
6555                 case 'p': {
6556                         /* Make sure that if the empty property list
6557                            was specified, we won't show any properties. */
6558                         if (isempty(optarg) && !arg_properties) {
6559                                 arg_properties = new0(char*, 1);
6560                                 if (!arg_properties)
6561                                         return log_oom();
6562                         } else {
6563                                 const char *word, *state;
6564                                 size_t size;
6565
6566                                 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
6567                                         char *prop;
6568
6569                                         prop = strndup(word, size);
6570                                         if (!prop)
6571                                                 return log_oom();
6572
6573                                         if (strv_consume(&arg_properties, prop) < 0)
6574                                                 return log_oom();
6575                                 }
6576                         }
6577
6578                         /* If the user asked for a particular
6579                          * property, show it to him, even if it is
6580                          * empty. */
6581                         arg_all = true;
6582
6583                         break;
6584                 }
6585
6586                 case 'a':
6587                         arg_all = true;
6588                         break;
6589
6590                 case ARG_REVERSE:
6591                         arg_dependency = DEPENDENCY_REVERSE;
6592                         break;
6593
6594                 case ARG_AFTER:
6595                         arg_dependency = DEPENDENCY_AFTER;
6596                         break;
6597
6598                 case ARG_BEFORE:
6599                         arg_dependency = DEPENDENCY_BEFORE;
6600                         break;
6601
6602                 case ARG_SHOW_TYPES:
6603                         arg_show_types = true;
6604                         break;
6605
6606                 case ARG_JOB_MODE:
6607                         arg_job_mode = optarg;
6608                         break;
6609
6610                 case ARG_FAIL:
6611                         arg_job_mode = "fail";
6612                         break;
6613
6614                 case ARG_IRREVERSIBLE:
6615                         arg_job_mode = "replace-irreversibly";
6616                         break;
6617
6618                 case ARG_IGNORE_DEPENDENCIES:
6619                         arg_job_mode = "ignore-dependencies";
6620                         break;
6621
6622                 case ARG_USER:
6623                         arg_scope = UNIT_FILE_USER;
6624                         break;
6625
6626                 case ARG_SYSTEM:
6627                         arg_scope = UNIT_FILE_SYSTEM;
6628                         break;
6629
6630                 case ARG_GLOBAL:
6631                         arg_scope = UNIT_FILE_GLOBAL;
6632                         break;
6633
6634                 case ARG_NO_BLOCK:
6635                         arg_no_block = true;
6636                         break;
6637
6638                 case ARG_NO_LEGEND:
6639                         arg_no_legend = true;
6640                         break;
6641
6642                 case ARG_NO_PAGER:
6643                         arg_no_pager = true;
6644                         break;
6645
6646                 case ARG_NO_WALL:
6647                         arg_no_wall = true;
6648                         break;
6649
6650                 case ARG_ROOT:
6651                         arg_root = optarg;
6652                         break;
6653
6654                 case 'l':
6655                         arg_full = true;
6656                         break;
6657
6658                 case ARG_FAILED:
6659                         if (strv_extend(&arg_states, "failed") < 0)
6660                                 return log_oom();
6661
6662                         break;
6663
6664                 case 'q':
6665                         arg_quiet = true;
6666                         break;
6667
6668                 case ARG_FORCE:
6669                         arg_force ++;
6670                         break;
6671
6672                 case 'f':
6673                         arg_force ++;
6674                         break;
6675
6676                 case ARG_NO_RELOAD:
6677                         arg_no_reload = true;
6678                         break;
6679
6680                 case ARG_KILL_WHO:
6681                         arg_kill_who = optarg;
6682                         break;
6683
6684                 case 's':
6685                         if ((arg_signal = signal_from_string_try_harder(optarg)) < 0) {
6686                                 log_error("Failed to parse signal string %s.", optarg);
6687                                 return -EINVAL;
6688                         }
6689                         break;
6690
6691                 case ARG_NO_ASK_PASSWORD:
6692                         arg_ask_password = false;
6693                         break;
6694
6695                 case 'H':
6696                         arg_transport = BUS_TRANSPORT_REMOTE;
6697                         arg_host = optarg;
6698                         break;
6699
6700                 case 'M':
6701                         arg_transport = BUS_TRANSPORT_CONTAINER;
6702                         arg_host = optarg;
6703                         break;
6704
6705                 case ARG_RUNTIME:
6706                         arg_runtime = true;
6707                         break;
6708
6709                 case 'n':
6710                         if (safe_atou(optarg, &arg_lines) < 0) {
6711                                 log_error("Failed to parse lines '%s'", optarg);
6712                                 return -EINVAL;
6713                         }
6714                         break;
6715
6716                 case 'o':
6717                         arg_output = output_mode_from_string(optarg);
6718                         if (arg_output < 0) {
6719                                 log_error("Unknown output '%s'.", optarg);
6720                                 return -EINVAL;
6721                         }
6722                         break;
6723
6724                 case 'i':
6725                         arg_ignore_inhibitors = true;
6726                         break;
6727
6728                 case ARG_PLAIN:
6729                         arg_plain = true;
6730                         break;
6731
6732                 case ARG_STATE: {
6733                         const char *word, *state;
6734                         size_t size;
6735
6736                         FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
6737                                 char *s;
6738
6739                                 s = strndup(word, size);
6740                                 if (!s)
6741                                         return log_oom();
6742
6743                                 if (strv_consume(&arg_states, s) < 0)
6744                                         return log_oom();
6745                         }
6746                         break;
6747                 }
6748
6749                 case 'r':
6750                         if (geteuid() != 0) {
6751                                 log_error("--recursive requires root privileges.");
6752                                 return -EPERM;
6753                         }
6754
6755                         arg_recursive = true;
6756                         break;
6757
6758                 case ARG_PRESET_MODE:
6759
6760                         arg_preset_mode = unit_file_preset_mode_from_string(optarg);
6761                         if (arg_preset_mode < 0) {
6762                                 log_error("Failed to parse preset mode: %s.", optarg);
6763                                 return -EINVAL;
6764                         }
6765
6766                         break;
6767
6768                 case '?':
6769                         return -EINVAL;
6770
6771                 default:
6772                         assert_not_reached("Unhandled option");
6773                 }
6774
6775         if (arg_transport != BUS_TRANSPORT_LOCAL && arg_scope != UNIT_FILE_SYSTEM) {
6776                 log_error("Cannot access user instance remotely.");
6777                 return -EINVAL;
6778         }
6779
6780         return 1;
6781 }
6782
6783 static int halt_parse_argv(int argc, char *argv[]) {
6784
6785         enum {
6786                 ARG_HELP = 0x100,
6787                 ARG_HALT,
6788                 ARG_REBOOT,
6789                 ARG_NO_WALL
6790         };
6791
6792         static const struct option options[] = {
6793                 { "help",      no_argument,       NULL, ARG_HELP    },
6794                 { "halt",      no_argument,       NULL, ARG_HALT    },
6795                 { "poweroff",  no_argument,       NULL, 'p'         },
6796                 { "reboot",    no_argument,       NULL, ARG_REBOOT  },
6797                 { "force",     no_argument,       NULL, 'f'         },
6798                 { "wtmp-only", no_argument,       NULL, 'w'         },
6799                 { "no-wtmp",   no_argument,       NULL, 'd'         },
6800                 { "no-wall",   no_argument,       NULL, ARG_NO_WALL },
6801                 {}
6802         };
6803
6804         int c, r, runlevel;
6805
6806         assert(argc >= 0);
6807         assert(argv);
6808
6809         if (utmp_get_runlevel(&runlevel, NULL) >= 0)
6810                 if (runlevel == '0' || runlevel == '6')
6811                         arg_force = 2;
6812
6813         while ((c = getopt_long(argc, argv, "pfwdnih", options, NULL)) >= 0)
6814                 switch (c) {
6815
6816                 case ARG_HELP:
6817                         halt_help();
6818                         return 0;
6819
6820                 case ARG_HALT:
6821                         arg_action = ACTION_HALT;
6822                         break;
6823
6824                 case 'p':
6825                         if (arg_action != ACTION_REBOOT)
6826                                 arg_action = ACTION_POWEROFF;
6827                         break;
6828
6829                 case ARG_REBOOT:
6830                         arg_action = ACTION_REBOOT;
6831                         break;
6832
6833                 case 'f':
6834                         arg_force = 2;
6835                         break;
6836
6837                 case 'w':
6838                         arg_dry = true;
6839                         break;
6840
6841                 case 'd':
6842                         arg_no_wtmp = true;
6843                         break;
6844
6845                 case ARG_NO_WALL:
6846                         arg_no_wall = true;
6847                         break;
6848
6849                 case 'i':
6850                 case 'h':
6851                 case 'n':
6852                         /* Compatibility nops */
6853                         break;
6854
6855                 case '?':
6856                         return -EINVAL;
6857
6858                 default:
6859                         assert_not_reached("Unhandled option");
6860                 }
6861
6862         if (arg_action == ACTION_REBOOT && (argc == optind || argc == optind + 1)) {
6863                 r = update_reboot_param_file(argc == optind + 1 ? argv[optind] : NULL);
6864                 if (r < 0)
6865                         return r;
6866         } else if (optind < argc) {
6867                 log_error("Too many arguments.");
6868                 return -EINVAL;
6869         }
6870
6871         return 1;
6872 }
6873
6874 static int parse_time_spec(const char *t, usec_t *_u) {
6875         assert(t);
6876         assert(_u);
6877
6878         if (streq(t, "now"))
6879                 *_u = 0;
6880         else if (!strchr(t, ':')) {
6881                 uint64_t u;
6882
6883                 if (safe_atou64(t, &u) < 0)
6884                         return -EINVAL;
6885
6886                 *_u = now(CLOCK_REALTIME) + USEC_PER_MINUTE * u;
6887         } else {
6888                 char *e = NULL;
6889                 long hour, minute;
6890                 struct tm tm = {};
6891                 time_t s;
6892                 usec_t n;
6893
6894                 errno = 0;
6895                 hour = strtol(t, &e, 10);
6896                 if (errno > 0 || *e != ':' || hour < 0 || hour > 23)
6897                         return -EINVAL;
6898
6899                 minute = strtol(e+1, &e, 10);
6900                 if (errno > 0 || *e != 0 || minute < 0 || minute > 59)
6901                         return -EINVAL;
6902
6903                 n = now(CLOCK_REALTIME);
6904                 s = (time_t) (n / USEC_PER_SEC);
6905
6906                 assert_se(localtime_r(&s, &tm));
6907
6908                 tm.tm_hour = (int) hour;
6909                 tm.tm_min = (int) minute;
6910                 tm.tm_sec = 0;
6911
6912                 assert_se(s = mktime(&tm));
6913
6914                 *_u = (usec_t) s * USEC_PER_SEC;
6915
6916                 while (*_u <= n)
6917                         *_u += USEC_PER_DAY;
6918         }
6919
6920         return 0;
6921 }
6922
6923 static int shutdown_parse_argv(int argc, char *argv[]) {
6924
6925         enum {
6926                 ARG_HELP = 0x100,
6927                 ARG_NO_WALL
6928         };
6929
6930         static const struct option options[] = {
6931                 { "help",      no_argument,       NULL, ARG_HELP    },
6932                 { "halt",      no_argument,       NULL, 'H'         },
6933                 { "poweroff",  no_argument,       NULL, 'P'         },
6934                 { "reboot",    no_argument,       NULL, 'r'         },
6935                 { "kexec",     no_argument,       NULL, 'K'         }, /* not documented extension */
6936                 { "no-wall",   no_argument,       NULL, ARG_NO_WALL },
6937                 {}
6938         };
6939
6940         int c, r;
6941
6942         assert(argc >= 0);
6943         assert(argv);
6944
6945         while ((c = getopt_long(argc, argv, "HPrhkt:afFc", options, NULL)) >= 0)
6946                 switch (c) {
6947
6948                 case ARG_HELP:
6949                         shutdown_help();
6950                         return 0;
6951
6952                 case 'H':
6953                         arg_action = ACTION_HALT;
6954                         break;
6955
6956                 case 'P':
6957                         arg_action = ACTION_POWEROFF;
6958                         break;
6959
6960                 case 'r':
6961                         if (kexec_loaded())
6962                                 arg_action = ACTION_KEXEC;
6963                         else
6964                                 arg_action = ACTION_REBOOT;
6965                         break;
6966
6967                 case 'K':
6968                         arg_action = ACTION_KEXEC;
6969                         break;
6970
6971                 case 'h':
6972                         if (arg_action != ACTION_HALT)
6973                                 arg_action = ACTION_POWEROFF;
6974                         break;
6975
6976                 case 'k':
6977                         arg_dry = true;
6978                         break;
6979
6980                 case ARG_NO_WALL:
6981                         arg_no_wall = true;
6982                         break;
6983
6984                 case 't':
6985                 case 'a':
6986                         /* Compatibility nops */
6987                         break;
6988
6989                 case 'c':
6990                         arg_action = ACTION_CANCEL_SHUTDOWN;
6991                         break;
6992
6993                 case '?':
6994                         return -EINVAL;
6995
6996                 default:
6997                         assert_not_reached("Unhandled option");
6998                 }
6999
7000         if (argc > optind && arg_action != ACTION_CANCEL_SHUTDOWN) {
7001                 r = parse_time_spec(argv[optind], &arg_when);
7002                 if (r < 0) {
7003                         log_error("Failed to parse time specification: %s", argv[optind]);
7004                         return r;
7005                 }
7006         } else
7007                 arg_when = now(CLOCK_REALTIME) + USEC_PER_MINUTE;
7008
7009         if (argc > optind && arg_action == ACTION_CANCEL_SHUTDOWN)
7010                 /* No time argument for shutdown cancel */
7011                 arg_wall = argv + optind;
7012         else if (argc > optind + 1)
7013                 /* We skip the time argument */
7014                 arg_wall = argv + optind + 1;
7015
7016         optind = argc;
7017
7018         return 1;
7019 }
7020
7021 static int telinit_parse_argv(int argc, char *argv[]) {
7022
7023         enum {
7024                 ARG_HELP = 0x100,
7025                 ARG_NO_WALL
7026         };
7027
7028         static const struct option options[] = {
7029                 { "help",      no_argument,       NULL, ARG_HELP    },
7030                 { "no-wall",   no_argument,       NULL, ARG_NO_WALL },
7031                 {}
7032         };
7033
7034         static const struct {
7035                 char from;
7036                 enum action to;
7037         } table[] = {
7038                 { '0', ACTION_POWEROFF },
7039                 { '6', ACTION_REBOOT },
7040                 { '1', ACTION_RESCUE },
7041                 { '2', ACTION_RUNLEVEL2 },
7042                 { '3', ACTION_RUNLEVEL3 },
7043                 { '4', ACTION_RUNLEVEL4 },
7044                 { '5', ACTION_RUNLEVEL5 },
7045                 { 's', ACTION_RESCUE },
7046                 { 'S', ACTION_RESCUE },
7047                 { 'q', ACTION_RELOAD },
7048                 { 'Q', ACTION_RELOAD },
7049                 { 'u', ACTION_REEXEC },
7050                 { 'U', ACTION_REEXEC }
7051         };
7052
7053         unsigned i;
7054         int c;
7055
7056         assert(argc >= 0);
7057         assert(argv);
7058
7059         while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0)
7060                 switch (c) {
7061
7062                 case ARG_HELP:
7063                         telinit_help();
7064                         return 0;
7065
7066                 case ARG_NO_WALL:
7067                         arg_no_wall = true;
7068                         break;
7069
7070                 case '?':
7071                         return -EINVAL;
7072
7073                 default:
7074                         assert_not_reached("Unhandled option");
7075                 }
7076
7077         if (optind >= argc) {
7078                 log_error("%s: required argument missing.",
7079                           program_invocation_short_name);
7080                 return -EINVAL;
7081         }
7082
7083         if (optind + 1 < argc) {
7084                 log_error("Too many arguments.");
7085                 return -EINVAL;
7086         }
7087
7088         if (strlen(argv[optind]) != 1) {
7089                 log_error("Expected single character argument.");
7090                 return -EINVAL;
7091         }
7092
7093         for (i = 0; i < ELEMENTSOF(table); i++)
7094                 if (table[i].from == argv[optind][0])
7095                         break;
7096
7097         if (i >= ELEMENTSOF(table)) {
7098                 log_error("Unknown command '%s'.", argv[optind]);
7099                 return -EINVAL;
7100         }
7101
7102         arg_action = table[i].to;
7103
7104         optind ++;
7105
7106         return 1;
7107 }
7108
7109 static int runlevel_parse_argv(int argc, char *argv[]) {
7110
7111         enum {
7112                 ARG_HELP = 0x100,
7113         };
7114
7115         static const struct option options[] = {
7116                 { "help",      no_argument,       NULL, ARG_HELP    },
7117                 {}
7118         };
7119
7120         int c;
7121
7122         assert(argc >= 0);
7123         assert(argv);
7124
7125         while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0)
7126                 switch (c) {
7127
7128                 case ARG_HELP:
7129                         runlevel_help();
7130                         return 0;
7131
7132                 case '?':
7133                         return -EINVAL;
7134
7135                 default:
7136                         assert_not_reached("Unhandled option");
7137                 }
7138
7139         if (optind < argc) {
7140                 log_error("Too many arguments.");
7141                 return -EINVAL;
7142         }
7143
7144         return 1;
7145 }
7146
7147 static int parse_argv(int argc, char *argv[]) {
7148         assert(argc >= 0);
7149         assert(argv);
7150
7151         if (program_invocation_short_name) {
7152
7153                 if (strstr(program_invocation_short_name, "halt")) {
7154                         arg_action = ACTION_HALT;
7155                         return halt_parse_argv(argc, argv);
7156                 } else if (strstr(program_invocation_short_name, "poweroff")) {
7157                         arg_action = ACTION_POWEROFF;
7158                         return halt_parse_argv(argc, argv);
7159                 } else if (strstr(program_invocation_short_name, "reboot")) {
7160                         if (kexec_loaded())
7161                                 arg_action = ACTION_KEXEC;
7162                         else
7163                                 arg_action = ACTION_REBOOT;
7164                         return halt_parse_argv(argc, argv);
7165                 } else if (strstr(program_invocation_short_name, "shutdown")) {
7166                         arg_action = ACTION_POWEROFF;
7167                         return shutdown_parse_argv(argc, argv);
7168                 } else if (strstr(program_invocation_short_name, "init")) {
7169
7170                         if (sd_booted() > 0) {
7171                                 arg_action = _ACTION_INVALID;
7172                                 return telinit_parse_argv(argc, argv);
7173                         } else {
7174                                 /* Hmm, so some other init system is
7175                                  * running, we need to forward this
7176                                  * request to it. For now we simply
7177                                  * guess that it is Upstart. */
7178
7179                                 execv(TELINIT, argv);
7180
7181                                 log_error("Couldn't find an alternative telinit implementation to spawn.");
7182                                 return -EIO;
7183                         }
7184
7185                 } else if (strstr(program_invocation_short_name, "runlevel")) {
7186                         arg_action = ACTION_RUNLEVEL;
7187                         return runlevel_parse_argv(argc, argv);
7188                 }
7189         }
7190
7191         arg_action = ACTION_SYSTEMCTL;
7192         return systemctl_parse_argv(argc, argv);
7193 }
7194
7195 _pure_ static int action_to_runlevel(void) {
7196
7197         static const char table[_ACTION_MAX] = {
7198                 [ACTION_HALT] =      '0',
7199                 [ACTION_POWEROFF] =  '0',
7200                 [ACTION_REBOOT] =    '6',
7201                 [ACTION_RUNLEVEL2] = '2',
7202                 [ACTION_RUNLEVEL3] = '3',
7203                 [ACTION_RUNLEVEL4] = '4',
7204                 [ACTION_RUNLEVEL5] = '5',
7205                 [ACTION_RESCUE] =    '1'
7206         };
7207
7208         assert(arg_action < _ACTION_MAX);
7209
7210         return table[arg_action];
7211 }
7212
7213 static int talk_initctl(void) {
7214
7215         struct init_request request = {
7216                 .magic = INIT_MAGIC,
7217                 .sleeptime  = 0,
7218                 .cmd = INIT_CMD_RUNLVL
7219         };
7220
7221         _cleanup_close_ int fd = -1;
7222         char rl;
7223         int r;
7224
7225         rl = action_to_runlevel();
7226         if (!rl)
7227                 return 0;
7228
7229         request.runlevel = rl;
7230
7231         fd = open(INIT_FIFO, O_WRONLY|O_NDELAY|O_CLOEXEC|O_NOCTTY);
7232         if (fd < 0) {
7233                 if (errno == ENOENT)
7234                         return 0;
7235
7236                 log_error_errno(errno, "Failed to open "INIT_FIFO": %m");
7237                 return -errno;
7238         }
7239
7240         r = loop_write(fd, &request, sizeof(request), false);
7241         if (r < 0)
7242                 return log_error_errno(r, "Failed to write to "INIT_FIFO": %m");
7243
7244         return 1;
7245 }
7246
7247 static int systemctl_main(sd_bus *bus, int argc, char *argv[], int bus_error) {
7248
7249         static const struct {
7250                 const char* verb;
7251                 const enum {
7252                         MORE,
7253                         LESS,
7254                         EQUAL
7255                 } argc_cmp;
7256                 const int argc;
7257                 int (* const dispatch)(sd_bus *bus, char **args);
7258                 const enum {
7259                         NOBUS = 1,
7260                         FORCE,
7261                 } bus;
7262         } verbs[] = {
7263                 { "list-units",            MORE,  0, list_units        },
7264                 { "list-unit-files",       MORE,  1, list_unit_files,  NOBUS },
7265                 { "list-sockets",          MORE,  1, list_sockets      },
7266                 { "list-timers",           MORE,  1, list_timers       },
7267                 { "list-jobs",             MORE,  1, list_jobs         },
7268                 { "list-machines",         MORE,  1, list_machines     },
7269                 { "clear-jobs",            EQUAL, 1, daemon_reload     },
7270                 { "cancel",                MORE,  2, cancel_job        },
7271                 { "start",                 MORE,  2, start_unit        },
7272                 { "stop",                  MORE,  2, start_unit        },
7273                 { "condstop",              MORE,  2, start_unit        }, /* For compatibility with ALTLinux */
7274                 { "reload",                MORE,  2, start_unit        },
7275                 { "restart",               MORE,  2, start_unit        },
7276                 { "try-restart",           MORE,  2, start_unit        },
7277                 { "reload-or-restart",     MORE,  2, start_unit        },
7278                 { "reload-or-try-restart", MORE,  2, start_unit        },
7279                 { "force-reload",          MORE,  2, start_unit        }, /* For compatibility with SysV */
7280                 { "condreload",            MORE,  2, start_unit        }, /* For compatibility with ALTLinux */
7281                 { "condrestart",           MORE,  2, start_unit        }, /* For compatibility with RH */
7282                 { "isolate",               EQUAL, 2, start_unit        },
7283                 { "kill",                  MORE,  2, kill_unit         },
7284                 { "is-active",             MORE,  2, check_unit_active },
7285                 { "check",                 MORE,  2, check_unit_active },
7286                 { "is-failed",             MORE,  2, check_unit_failed },
7287                 { "show",                  MORE,  1, show              },
7288                 { "cat",                   MORE,  2, cat               },
7289                 { "status",                MORE,  1, show              },
7290                 { "help",                  MORE,  2, show              },
7291                 { "snapshot",              LESS,  2, snapshot          },
7292                 { "delete",                MORE,  2, delete_snapshot   },
7293                 { "daemon-reload",         EQUAL, 1, daemon_reload     },
7294                 { "daemon-reexec",         EQUAL, 1, daemon_reload     },
7295                 { "show-environment",      EQUAL, 1, show_environment  },
7296                 { "set-environment",       MORE,  2, set_environment   },
7297                 { "unset-environment",     MORE,  2, set_environment   },
7298                 { "import-environment",    MORE,  1, import_environment},
7299                 { "halt",                  EQUAL, 1, start_special,    FORCE },
7300                 { "poweroff",              EQUAL, 1, start_special,    FORCE },
7301                 { "reboot",                EQUAL, 1, start_special,    FORCE },
7302                 { "kexec",                 EQUAL, 1, start_special     },
7303                 { "suspend",               EQUAL, 1, start_special     },
7304                 { "hibernate",             EQUAL, 1, start_special     },
7305                 { "hybrid-sleep",          EQUAL, 1, start_special     },
7306                 { "default",               EQUAL, 1, start_special     },
7307                 { "rescue",                EQUAL, 1, start_special     },
7308                 { "emergency",             EQUAL, 1, start_special     },
7309                 { "exit",                  EQUAL, 1, start_special     },
7310                 { "reset-failed",          MORE,  1, reset_failed      },
7311                 { "enable",                MORE,  2, enable_unit,      NOBUS },
7312                 { "disable",               MORE,  2, enable_unit,      NOBUS },
7313                 { "is-enabled",            MORE,  2, unit_is_enabled,  NOBUS },
7314                 { "reenable",              MORE,  2, enable_unit,      NOBUS },
7315                 { "preset",                MORE,  2, enable_unit,      NOBUS },
7316                 { "preset-all",            EQUAL, 1, preset_all,       NOBUS },
7317                 { "mask",                  MORE,  2, enable_unit,      NOBUS },
7318                 { "unmask",                MORE,  2, enable_unit,      NOBUS },
7319                 { "link",                  MORE,  2, enable_unit,      NOBUS },
7320                 { "switch-root",           MORE,  2, switch_root       },
7321                 { "list-dependencies",     LESS,  2, list_dependencies },
7322                 { "set-default",           EQUAL, 2, set_default,      NOBUS },
7323                 { "get-default",           EQUAL, 1, get_default,      NOBUS },
7324                 { "set-property",          MORE,  3, set_property      },
7325                 { "is-system-running",     EQUAL, 1, is_system_running },
7326                 { "add-wants",             MORE,  3, add_dependency,   NOBUS },
7327                 { "add-requires",          MORE,  3, add_dependency,   NOBUS },
7328                 { "edit",                  MORE,  2, edit,             NOBUS },
7329                 {}
7330         }, *verb = verbs;
7331
7332         int left;
7333
7334         assert(argc >= 0);
7335         assert(argv);
7336
7337         left = argc - optind;
7338
7339         /* Special rule: no arguments (left == 0) means "list-units" */
7340         if (left > 0) {
7341                 if (streq(argv[optind], "help") && !argv[optind+1]) {
7342                         log_error("This command expects one or more "
7343                                   "unit names. Did you mean --help?");
7344                         return -EINVAL;
7345                 }
7346
7347                 for (; verb->verb; verb++)
7348                         if (streq(argv[optind], verb->verb))
7349                                 goto found;
7350
7351                 log_error("Unknown operation '%s'.", argv[optind]);
7352                 return -EINVAL;
7353         }
7354 found:
7355
7356         switch (verb->argc_cmp) {
7357
7358         case EQUAL:
7359                 if (left != verb->argc) {
7360                         log_error("Invalid number of arguments.");
7361                         return -EINVAL;
7362                 }
7363
7364                 break;
7365
7366         case MORE:
7367                 if (left < verb->argc) {
7368                         log_error("Too few arguments.");
7369                         return -EINVAL;
7370                 }
7371
7372                 break;
7373
7374         case LESS:
7375                 if (left > verb->argc) {
7376                         log_error("Too many arguments.");
7377                         return -EINVAL;
7378                 }
7379
7380                 break;
7381
7382         default:
7383                 assert_not_reached("Unknown comparison operator.");
7384         }
7385
7386         /* Require a bus connection for all operations but
7387          * enable/disable */
7388         if (verb->bus == NOBUS) {
7389                 if (!bus && !avoid_bus()) {
7390                         log_error_errno(bus_error, "Failed to get D-Bus connection: %m");
7391                         return -EIO;
7392                 }
7393
7394         } else {
7395                 if (running_in_chroot() > 0) {
7396                         log_info("Running in chroot, ignoring request.");
7397                         return 0;
7398                 }
7399
7400                 if ((verb->bus != FORCE || arg_force <= 0) && !bus) {
7401                         log_error_errno(bus_error, "Failed to get D-Bus connection: %m");
7402                         return -EIO;
7403                 }
7404         }
7405
7406         return verb->dispatch(bus, argv + optind);
7407 }
7408
7409 static int send_shutdownd(usec_t t, char mode, bool dry_run, bool warn, const char *message) {
7410
7411         struct sd_shutdown_command c = {
7412                 .usec = t,
7413                 .mode = mode,
7414                 .dry_run = dry_run,
7415                 .warn_wall = warn,
7416         };
7417
7418         union sockaddr_union sockaddr = {
7419                 .un.sun_family = AF_UNIX,
7420                 .un.sun_path = "/run/systemd/shutdownd",
7421         };
7422
7423         struct iovec iovec[2] = {{
7424                  .iov_base = (char*) &c,
7425                  .iov_len = offsetof(struct sd_shutdown_command, wall_message),
7426         }};
7427
7428         struct msghdr msghdr = {
7429                 .msg_name = &sockaddr,
7430                 .msg_namelen = offsetof(struct sockaddr_un, sun_path)
7431                                + strlen("/run/systemd/shutdownd"),
7432                 .msg_iov = iovec,
7433                 .msg_iovlen = 1,
7434         };
7435
7436         _cleanup_close_ int fd;
7437
7438         fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
7439         if (fd < 0)
7440                 return -errno;
7441
7442         if (!isempty(message)) {
7443                 iovec[1].iov_base = (char*) message;
7444                 iovec[1].iov_len = strlen(message);
7445                 msghdr.msg_iovlen++;
7446         }
7447
7448         if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) < 0)
7449                 return -errno;
7450
7451         return 0;
7452 }
7453
7454 static int reload_with_fallback(sd_bus *bus) {
7455
7456         if (bus) {
7457                 /* First, try systemd via D-Bus. */
7458                 if (daemon_reload(bus, NULL) >= 0)
7459                         return 0;
7460         }
7461
7462         /* Nothing else worked, so let's try signals */
7463         assert(arg_action == ACTION_RELOAD || arg_action == ACTION_REEXEC);
7464
7465         if (kill(1, arg_action == ACTION_RELOAD ? SIGHUP : SIGTERM) < 0)
7466                 return log_error_errno(errno, "kill() failed: %m");
7467
7468         return 0;
7469 }
7470
7471 static int start_with_fallback(sd_bus *bus) {
7472
7473         if (bus) {
7474                 /* First, try systemd via D-Bus. */
7475                 if (start_unit(bus, NULL) >= 0)
7476                         goto done;
7477         }
7478
7479         /* Nothing else worked, so let's try
7480          * /dev/initctl */
7481         if (talk_initctl() > 0)
7482                 goto done;
7483
7484         log_error("Failed to talk to init daemon.");
7485         return -EIO;
7486
7487 done:
7488         warn_wall(arg_action);
7489         return 0;
7490 }
7491
7492 static int halt_now(enum action a) {
7493
7494         /* The kernel will automaticall flush ATA disks and suchlike
7495          * on reboot(), but the file systems need to be synce'd
7496          * explicitly in advance. */
7497         sync();
7498
7499         /* Make sure C-A-D is handled by the kernel from this point
7500          * on... */
7501         reboot(RB_ENABLE_CAD);
7502
7503         switch (a) {
7504
7505         case ACTION_HALT:
7506                 log_info("Halting.");
7507                 reboot(RB_HALT_SYSTEM);
7508                 return -errno;
7509
7510         case ACTION_POWEROFF:
7511                 log_info("Powering off.");
7512                 reboot(RB_POWER_OFF);
7513                 return -errno;
7514
7515         case ACTION_REBOOT: {
7516                 _cleanup_free_ char *param = NULL;
7517
7518                 if (read_one_line_file(REBOOT_PARAM_FILE, &param) >= 0) {
7519                         log_info("Rebooting with argument '%s'.", param);
7520                         syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
7521                                 LINUX_REBOOT_CMD_RESTART2, param);
7522                 }
7523
7524                 log_info("Rebooting.");
7525                 reboot(RB_AUTOBOOT);
7526                 return -errno;
7527         }
7528
7529         default:
7530                 assert_not_reached("Unknown action.");
7531         }
7532 }
7533
7534 static int halt_main(sd_bus *bus) {
7535         int r;
7536
7537         r = check_inhibitors(bus, arg_action);
7538         if (r < 0)
7539                 return r;
7540
7541         if (geteuid() != 0) {
7542                 /* Try logind if we are a normal user and no special
7543                  * mode applies. Maybe PolicyKit allows us to shutdown
7544                  * the machine. */
7545
7546                 if (arg_when <= 0 &&
7547                     !arg_dry &&
7548                     arg_force <= 0 &&
7549                     (arg_action == ACTION_POWEROFF ||
7550                      arg_action == ACTION_REBOOT)) {
7551                         r = reboot_with_logind(bus, arg_action);
7552                         if (r >= 0)
7553                                 return r;
7554                 }
7555
7556                 log_error("Must be root.");
7557                 return -EPERM;
7558         }
7559
7560         if (arg_when > 0) {
7561                 _cleanup_free_ char *m;
7562
7563                 m = strv_join(arg_wall, " ");
7564                 if (!m)
7565                         return log_oom();
7566
7567                 r = send_shutdownd(arg_when,
7568                                    arg_action == ACTION_HALT     ? 'H' :
7569                                    arg_action == ACTION_POWEROFF ? 'P' :
7570                                    arg_action == ACTION_KEXEC    ? 'K' :
7571                                                                    'r',
7572                                    arg_dry,
7573                                    !arg_no_wall,
7574                                    m);
7575
7576                 if (r < 0)
7577                         log_warning_errno(r, "Failed to talk to shutdownd, proceeding with immediate shutdown: %m");
7578                 else {
7579                         char date[FORMAT_TIMESTAMP_MAX];
7580
7581                         log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.",
7582                                  format_timestamp(date, sizeof(date), arg_when));
7583                         return 0;
7584                 }
7585         }
7586
7587         if (!arg_dry && !arg_force)
7588                 return start_with_fallback(bus);
7589
7590         if (!arg_no_wtmp) {
7591                 if (sd_booted() > 0)
7592                         log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
7593                 else {
7594                         r = utmp_put_shutdown();
7595                         if (r < 0)
7596                                 log_warning_errno(r, "Failed to write utmp record: %m");
7597                 }
7598         }
7599
7600         if (arg_dry)
7601                 return 0;
7602
7603         r = halt_now(arg_action);
7604         log_error_errno(r, "Failed to reboot: %m");
7605
7606         return r;
7607 }
7608
7609 static int runlevel_main(void) {
7610         int r, runlevel, previous;
7611
7612         r = utmp_get_runlevel(&runlevel, &previous);
7613         if (r < 0) {
7614                 puts("unknown");
7615                 return r;
7616         }
7617
7618         printf("%c %c\n",
7619                previous <= 0 ? 'N' : previous,
7620                runlevel <= 0 ? 'N' : runlevel);
7621
7622         return 0;
7623 }
7624
7625 int main(int argc, char*argv[]) {
7626         _cleanup_bus_close_unref_ sd_bus *bus = NULL;
7627         int r;
7628
7629         setlocale(LC_ALL, "");
7630         log_parse_environment();
7631         log_open();
7632
7633         /* Explicitly not on_tty() to avoid setting cached value.
7634          * This becomes relevant for piping output which might be
7635          * ellipsized. */
7636         original_stdout_is_tty = isatty(STDOUT_FILENO);
7637
7638         r = parse_argv(argc, argv);
7639         if (r <= 0)
7640                 goto finish;
7641
7642         /* /sbin/runlevel doesn't need to communicate via D-Bus, so
7643          * let's shortcut this */
7644         if (arg_action == ACTION_RUNLEVEL) {
7645                 r = runlevel_main();
7646                 goto finish;
7647         }
7648
7649         if (running_in_chroot() > 0 && arg_action != ACTION_SYSTEMCTL) {
7650                 log_info("Running in chroot, ignoring request.");
7651                 r = 0;
7652                 goto finish;
7653         }
7654
7655         if (!avoid_bus())
7656                 r = bus_open_transport_systemd(arg_transport, arg_host, arg_scope != UNIT_FILE_SYSTEM, &bus);
7657
7658         /* systemctl_main() will print an error message for the bus
7659          * connection, but only if it needs to */
7660
7661         switch (arg_action) {
7662
7663         case ACTION_SYSTEMCTL:
7664                 r = systemctl_main(bus, argc, argv, r);
7665                 break;
7666
7667         case ACTION_HALT:
7668         case ACTION_POWEROFF:
7669         case ACTION_REBOOT:
7670         case ACTION_KEXEC:
7671                 r = halt_main(bus);
7672                 break;
7673
7674         case ACTION_RUNLEVEL2:
7675         case ACTION_RUNLEVEL3:
7676         case ACTION_RUNLEVEL4:
7677         case ACTION_RUNLEVEL5:
7678         case ACTION_RESCUE:
7679         case ACTION_EMERGENCY:
7680         case ACTION_DEFAULT:
7681                 r = start_with_fallback(bus);
7682                 break;
7683
7684         case ACTION_RELOAD:
7685         case ACTION_REEXEC:
7686                 r = reload_with_fallback(bus);
7687                 break;
7688
7689         case ACTION_CANCEL_SHUTDOWN: {
7690                 _cleanup_free_ char *m = NULL;
7691
7692                 if (arg_wall) {
7693                         m = strv_join(arg_wall, " ");
7694                         if (!m) {
7695                                 r = log_oom();
7696                                 goto finish;
7697                         }
7698                 }
7699
7700                 r = send_shutdownd(arg_when, SD_SHUTDOWN_NONE, false, !arg_no_wall, m);
7701                 if (r < 0)
7702                         log_warning_errno(r, "Failed to talk to shutdownd, shutdown hasn't been cancelled: %m");
7703                 break;
7704         }
7705
7706         case ACTION_RUNLEVEL:
7707         case _ACTION_INVALID:
7708         default:
7709                 assert_not_reached("Unknown action");
7710         }
7711
7712 finish:
7713         pager_close();
7714         ask_password_agent_close();
7715         polkit_agent_close();
7716
7717         strv_free(arg_types);
7718         strv_free(arg_states);
7719         strv_free(arg_properties);
7720
7721         return r < 0 ? EXIT_FAILURE : r;
7722 }