chiark / gitweb /
systemctl: fix invalid free when enabling sysv services fails
[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-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);
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);
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         int r;
5734         char *t;
5735
5736         assert(new_path);
5737         assert(original_path);
5738         assert(ret_tmp_fn);
5739
5740         t = tempfn_random(new_path);
5741         if (!t)
5742                 return log_oom();
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 find_paths_to_edit(sd_bus *bus, char **names, char ***paths) {
6030         _cleanup_free_ char *user_home = NULL;
6031         _cleanup_free_ char *user_runtime = NULL;
6032         char **name;
6033         int r;
6034
6035         assert(names);
6036         assert(paths);
6037
6038         if (arg_scope == UNIT_FILE_USER) {
6039                 r = user_config_home(&user_home);
6040                 if (r < 0)
6041                         return log_oom();
6042                 else if (r == 0) {
6043                         log_error("Cannot edit units for the user instance: home directory unknown");
6044                         return -1;
6045                 }
6046
6047                 r = user_runtime_dir(&user_runtime);
6048                 if (r < 0)
6049                         return log_oom();
6050                 else if (r == 0) {
6051                         log_error("Cannot edit units for the user instance: runtime directory unknown");
6052                         return -1;
6053                 }
6054         }
6055
6056         if (!bus || avoid_bus()) {
6057                 _cleanup_lookup_paths_free_ LookupPaths lp = {};
6058
6059                 /* If there is no bus, we try to find the units by testing each available directory
6060                  * according to the scope.
6061                  */
6062                 r = lookup_paths_init(&lp,
6063                                 arg_scope == UNIT_FILE_SYSTEM ? SYSTEMD_SYSTEM : SYSTEMD_USER,
6064                                 arg_scope == UNIT_FILE_USER,
6065                                 arg_root,
6066                                 NULL, NULL, NULL);
6067                 if (r < 0) {
6068                         log_error_errno(r, "Failed get lookup paths: %m");
6069                         return r;
6070                 }
6071
6072                 STRV_FOREACH(name, names) {
6073                         _cleanup_free_ char *path = NULL;
6074                         char *new_path, *tmp_path;
6075
6076                         r = unit_file_find_path(&lp, *name, &path);
6077                         if (r < 0)
6078                                 return r;
6079                         if (r == 0) {
6080                                 log_warning("%s ignored: not found", *name);
6081                                 continue;
6082                         }
6083
6084                         if (arg_full)
6085                                 r = unit_file_create_copy(*name, path, user_home, user_runtime, &new_path, &tmp_path);
6086                         else
6087                                 r = unit_file_create_drop_in(*name, user_home, user_runtime, &new_path, &tmp_path);
6088
6089                         if (r < 0)
6090                                 continue;
6091
6092                         r = strv_push(paths, new_path);
6093                         if (r < 0)
6094                                 return log_oom();
6095
6096                         r = strv_push(paths, tmp_path);
6097                         if (r < 0)
6098                                 return log_oom();
6099                 }
6100         } else {
6101                 STRV_FOREACH(name, names) {
6102                         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
6103                         _cleanup_free_ char *fragment_path = NULL;
6104                         _cleanup_free_ char *unit = NULL;
6105                         char *new_path, *tmp_path;
6106
6107                         unit = unit_dbus_path_from_name(*name);
6108                         if (!unit)
6109                                 return log_oom();
6110
6111                         if (need_daemon_reload(bus, *name) > 0) {
6112                                 log_warning("%s ignored: unit file changed on disk. Run 'systemctl%s daemon-reload'.",
6113                                         *name, arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
6114                                 continue;
6115                         }
6116
6117                         r = sd_bus_get_property_string(
6118                                         bus,
6119                                         "org.freedesktop.systemd1",
6120                                         unit,
6121                                         "org.freedesktop.systemd1.Unit",
6122                                         "FragmentPath",
6123                                         &error,
6124                                         &fragment_path);
6125                         if (r < 0) {
6126                                 log_warning("Failed to get FragmentPath: %s", bus_error_message(&error, r));
6127                                 continue;
6128                         }
6129
6130                         if (isempty(fragment_path)) {
6131                                 log_warning("%s ignored: not found", *name);
6132                                 continue;
6133                         }
6134
6135                         if (arg_full)
6136                                 r = unit_file_create_copy(*name, fragment_path, user_home, user_runtime, &new_path, &tmp_path);
6137                         else
6138                                 r = unit_file_create_drop_in(*name, user_home, user_runtime, &new_path, &tmp_path);
6139                         if (r < 0)
6140                                 continue;
6141
6142                         r = strv_push(paths, new_path);
6143                         if (r < 0)
6144                                 return log_oom();
6145
6146                         r = strv_push(paths, tmp_path);
6147                         if (r < 0)
6148                                 return log_oom();
6149                 }
6150         }
6151
6152         return 0;
6153 }
6154
6155 static int edit(sd_bus *bus, char **args) {
6156         _cleanup_strv_free_ char **names = NULL;
6157         _cleanup_strv_free_ char **paths = NULL;
6158         char **original, **tmp;
6159         int r;
6160
6161         assert(args);
6162
6163         if (!on_tty()) {
6164                 log_error("Cannot edit units if we are not on a tty");
6165                 return -EINVAL;
6166         }
6167
6168         if (arg_transport != BUS_TRANSPORT_LOCAL) {
6169                 log_error("Cannot remotely edit units");
6170                 return -EINVAL;
6171         }
6172
6173         r = expand_names(bus, args + 1, NULL, &names);
6174         if (r < 0)
6175                 return log_error_errno(r, "Failed to expand names: %m");
6176
6177         if (!names) {
6178                 log_error("No unit name found by expanding names");
6179                 return -ENOENT;
6180         }
6181
6182         r = find_paths_to_edit(bus, names, &paths);
6183         if (r < 0)
6184                 return r;
6185
6186         if (strv_isempty(paths)) {
6187                 log_error("Cannot find any units to edit");
6188                 return -ENOENT;
6189         }
6190
6191         r = run_editor(paths);
6192         if (r < 0)
6193                 goto end;
6194
6195         STRV_FOREACH_PAIR(original, tmp, paths) {
6196                 /* If the temporary file is empty we ignore it.
6197                  * It's useful if the user wants to cancel its modification
6198                  */
6199                 if (null_or_empty_path(*tmp)) {
6200                         log_warning("Edition of %s canceled: temporary file empty", *original);
6201                         continue;
6202                 }
6203                 r = rename(*tmp, *original);
6204                 if (r < 0) {
6205                         r = log_error_errno(errno, "Failed to rename %s to %s: %m", *tmp, *original);
6206                         goto end;
6207                 }
6208         }
6209
6210         if (!arg_no_reload && bus && !avoid_bus())
6211                 r = daemon_reload(bus, args);
6212
6213 end:
6214         STRV_FOREACH_PAIR(original, tmp, paths)
6215                 unlink_noerrno(*tmp);
6216
6217         return r;
6218 }
6219
6220 static void systemctl_help(void) {
6221
6222         pager_open_if_enabled();
6223
6224         printf("%s [OPTIONS...] {COMMAND} ...\n\n"
6225                "Query or send control commands to the systemd manager.\n\n"
6226                "  -h --help           Show this help\n"
6227                "     --version        Show package version\n"
6228                "     --system         Connect to system manager\n"
6229                "     --user           Connect to user service manager\n"
6230                "  -H --host=[USER@]HOST\n"
6231                "                      Operate on remote host\n"
6232                "  -M --machine=CONTAINER\n"
6233                "                      Operate on local container\n"
6234                "  -t --type=TYPE      List only units of a particular type\n"
6235                "     --state=STATE    List only units with particular LOAD or SUB or ACTIVE state\n"
6236                "  -p --property=NAME  Show only properties by this name\n"
6237                "  -a --all            Show all loaded units/properties, including dead/empty\n"
6238                "                      ones. To list all units installed on the system, use\n"
6239                "                      the 'list-unit-files' command instead.\n"
6240                "  -l --full           Don't ellipsize unit names on output\n"
6241                "  -r --recursive      Show unit list of host and local containers\n"
6242                "     --reverse        Show reverse dependencies with 'list-dependencies'\n"
6243                "     --job-mode=MODE  Specify how to deal with already queued jobs, when\n"
6244                "                      queueing a new job\n"
6245                "     --show-types     When showing sockets, explicitly show their type\n"
6246                "  -i --ignore-inhibitors\n"
6247                "                      When shutting down or sleeping, ignore inhibitors\n"
6248                "     --kill-who=WHO   Who to send signal to\n"
6249                "  -s --signal=SIGNAL  Which signal to send\n"
6250                "  -q --quiet          Suppress output\n"
6251                "     --no-block       Do not wait until operation finished\n"
6252                "     --no-wall        Don't send wall message before halt/power-off/reboot\n"
6253                "     --no-reload      When enabling/disabling unit files, don't reload daemon\n"
6254                "                      configuration\n"
6255                "     --no-legend      Do not print a legend (column headers and hints)\n"
6256                "     --no-pager       Do not pipe output into a pager\n"
6257                "     --no-ask-password\n"
6258                "                      Do not ask for system passwords\n"
6259                "     --global         Enable/disable unit files globally\n"
6260                "     --runtime        Enable unit files only temporarily until next reboot\n"
6261                "  -f --force          When enabling unit files, override existing symlinks\n"
6262                "                      When shutting down, execute action immediately\n"
6263                "     --preset-mode=   Specifies whether fully apply presets, or only enable,\n"
6264                "                      or only disable\n"
6265                "     --root=PATH      Enable unit files in the specified root directory\n"
6266                "  -n --lines=INTEGER  Number of journal entries to show\n"
6267                "  -o --output=STRING  Change journal output mode (short, short-monotonic,\n"
6268                "                      verbose, export, json, json-pretty, json-sse, cat)\n"
6269                "     --plain          Print unit dependencies as a list instead of a tree\n\n"
6270                "Unit Commands:\n"
6271                "  list-units [PATTERN...]         List loaded units\n"
6272                "  list-sockets [PATTERN...]       List loaded sockets ordered by address\n"
6273                "  list-timers [PATTERN...]        List loaded timers ordered by next elapse\n"
6274                "  start NAME...                   Start (activate) one or more units\n"
6275                "  stop NAME...                    Stop (deactivate) one or more units\n"
6276                "  reload NAME...                  Reload one or more units\n"
6277                "  restart NAME...                 Start or restart one or more units\n"
6278                "  try-restart NAME...             Restart one or more units if active\n"
6279                "  reload-or-restart NAME...       Reload one or more units if possible,\n"
6280                "                                  otherwise start or restart\n"
6281                "  reload-or-try-restart NAME...   Reload one or more units if possible,\n"
6282                "                                  otherwise restart if active\n"
6283                "  isolate NAME                    Start one unit and stop all others\n"
6284                "  kill NAME...                    Send signal to processes of a unit\n"
6285                "  is-active PATTERN...            Check whether units are active\n"
6286                "  is-failed PATTERN...            Check whether units are failed\n"
6287                "  status [PATTERN...|PID...]      Show runtime status of one or more units\n"
6288                "  show [PATTERN...|JOB...]        Show properties of one or more\n"
6289                "                                  units/jobs or the manager\n"
6290                "  cat PATTERN...                  Show files and drop-ins of one or more units\n"
6291                "  set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
6292                "  help PATTERN...|PID...          Show manual for one or more units\n"
6293                "  reset-failed [PATTERN...]       Reset failed state for all, one, or more\n"
6294                "                                  units\n"
6295                "  list-dependencies [NAME]        Recursively show units which are required\n"
6296                "                                  or wanted by this unit or by which this\n"
6297                "                                  unit is required or wanted\n\n"
6298                "Unit File Commands:\n"
6299                "  list-unit-files [PATTERN...]    List installed unit files\n"
6300                "  enable NAME...                  Enable one or more unit files\n"
6301                "  disable NAME...                 Disable one or more unit files\n"
6302                "  reenable NAME...                Reenable one or more unit files\n"
6303                "  preset NAME...                  Enable/disable one or more unit files\n"
6304                "                                  based on preset configuration\n"
6305                "  preset-all                      Enable/disable all unit files based on\n"
6306                "                                  preset configuration\n"
6307                "  is-enabled NAME...              Check whether unit files are enabled\n\n"
6308                "  mask NAME...                    Mask one or more units\n"
6309                "  unmask NAME...                  Unmask one or more units\n"
6310                "  link PATH...                    Link one or more units files into\n"
6311                "                                  the search path\n"
6312                "  add-wants TARGET NAME...        Add 'Wants' dependency for the target\n"
6313                "                                  on specified one or more units\n"
6314                "  add-requires TARGET NAME...     Add 'Requires' dependency for the target\n"
6315                "                                  on specified one or more units\n"
6316                "  get-default                     Get the name of the default target\n"
6317                "  set-default NAME                Set the default target\n"
6318                "  edit NAME...                    Edit one or more unit files\n"
6319                "\n"
6320                "Machine Commands:\n"
6321                "  list-machines [PATTERN...]      List local containers and host\n\n"
6322                "Job Commands:\n"
6323                "  list-jobs [PATTERN...]          List jobs\n"
6324                "  cancel [JOB...]                 Cancel all, one, or more jobs\n\n"
6325                "Snapshot Commands:\n"
6326                "  snapshot [NAME]                 Create a snapshot\n"
6327                "  delete NAME...                  Remove one or more snapshots\n\n"
6328                "Environment Commands:\n"
6329                "  show-environment                Dump environment\n"
6330                "  set-environment NAME=VALUE...   Set one or more environment variables\n"
6331                "  unset-environment NAME...       Unset one or more environment variables\n"
6332                "  import-environment NAME...      Import all, one or more environment variables\n\n"
6333                "Manager Lifecycle Commands:\n"
6334                "  daemon-reload                   Reload systemd manager configuration\n"
6335                "  daemon-reexec                   Reexecute systemd manager\n\n"
6336                "System Commands:\n"
6337                "  is-system-running               Check whether system is fully running\n"
6338                "  default                         Enter system default mode\n"
6339                "  rescue                          Enter system rescue mode\n"
6340                "  emergency                       Enter system emergency mode\n"
6341                "  halt                            Shut down and halt the system\n"
6342                "  poweroff                        Shut down and power-off the system\n"
6343                "  reboot [ARG]                    Shut down and reboot the system\n"
6344                "  kexec                           Shut down and reboot the system with kexec\n"
6345                "  exit                            Request user instance exit\n"
6346                "  switch-root ROOT [INIT]         Change to a different root file system\n"
6347                "  suspend                         Suspend the system\n"
6348                "  hibernate                       Hibernate the system\n"
6349                "  hybrid-sleep                    Hibernate and suspend the system\n",
6350                program_invocation_short_name);
6351 }
6352
6353 static void halt_help(void) {
6354         printf("%s [OPTIONS...]%s\n\n"
6355                "%s the system.\n\n"
6356                "     --help      Show this help\n"
6357                "     --halt      Halt the machine\n"
6358                "  -p --poweroff  Switch off the machine\n"
6359                "     --reboot    Reboot the machine\n"
6360                "  -f --force     Force immediate halt/power-off/reboot\n"
6361                "  -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
6362                "  -d --no-wtmp   Don't write wtmp record\n"
6363                "     --no-wall   Don't send wall message before halt/power-off/reboot\n",
6364                program_invocation_short_name,
6365                arg_action == ACTION_REBOOT   ? " [ARG]" : "",
6366                arg_action == ACTION_REBOOT   ? "Reboot" :
6367                arg_action == ACTION_POWEROFF ? "Power off" :
6368                                                "Halt");
6369 }
6370
6371 static void shutdown_help(void) {
6372         printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
6373                "Shut down the system.\n\n"
6374                "     --help      Show this help\n"
6375                "  -H --halt      Halt the machine\n"
6376                "  -P --poweroff  Power-off the machine\n"
6377                "  -r --reboot    Reboot the machine\n"
6378                "  -h             Equivalent to --poweroff, overridden by --halt\n"
6379                "  -k             Don't halt/power-off/reboot, just send warnings\n"
6380                "     --no-wall   Don't send wall message before halt/power-off/reboot\n"
6381                "  -c             Cancel a pending shutdown\n",
6382                program_invocation_short_name);
6383 }
6384
6385 static void telinit_help(void) {
6386         printf("%s [OPTIONS...] {COMMAND}\n\n"
6387                "Send control commands to the init daemon.\n\n"
6388                "     --help      Show this help\n"
6389                "     --no-wall   Don't send wall message before halt/power-off/reboot\n\n"
6390                "Commands:\n"
6391                "  0              Power-off the machine\n"
6392                "  6              Reboot the machine\n"
6393                "  2, 3, 4, 5     Start runlevelX.target unit\n"
6394                "  1, s, S        Enter rescue mode\n"
6395                "  q, Q           Reload init daemon configuration\n"
6396                "  u, U           Reexecute init daemon\n",
6397                program_invocation_short_name);
6398 }
6399
6400 static void runlevel_help(void) {
6401         printf("%s [OPTIONS...]\n\n"
6402                "Prints the previous and current runlevel of the init system.\n\n"
6403                "     --help      Show this help\n",
6404                program_invocation_short_name);
6405 }
6406
6407 static void help_types(void) {
6408         int i;
6409         const char *t;
6410
6411         if (!arg_no_legend)
6412                 puts("Available unit types:");
6413         for (i = 0; i < _UNIT_TYPE_MAX; i++) {
6414                 t = unit_type_to_string(i);
6415                 if (t)
6416                         puts(t);
6417         }
6418 }
6419
6420 static int systemctl_parse_argv(int argc, char *argv[]) {
6421
6422         enum {
6423                 ARG_FAIL = 0x100,
6424                 ARG_REVERSE,
6425                 ARG_AFTER,
6426                 ARG_BEFORE,
6427                 ARG_SHOW_TYPES,
6428                 ARG_IRREVERSIBLE,
6429                 ARG_IGNORE_DEPENDENCIES,
6430                 ARG_VERSION,
6431                 ARG_USER,
6432                 ARG_SYSTEM,
6433                 ARG_GLOBAL,
6434                 ARG_NO_BLOCK,
6435                 ARG_NO_LEGEND,
6436                 ARG_NO_PAGER,
6437                 ARG_NO_WALL,
6438                 ARG_ROOT,
6439                 ARG_NO_RELOAD,
6440                 ARG_KILL_WHO,
6441                 ARG_NO_ASK_PASSWORD,
6442                 ARG_FAILED,
6443                 ARG_RUNTIME,
6444                 ARG_FORCE,
6445                 ARG_PLAIN,
6446                 ARG_STATE,
6447                 ARG_JOB_MODE,
6448                 ARG_PRESET_MODE,
6449         };
6450
6451         static const struct option options[] = {
6452                 { "help",                no_argument,       NULL, 'h'                     },
6453                 { "version",             no_argument,       NULL, ARG_VERSION             },
6454                 { "type",                required_argument, NULL, 't'                     },
6455                 { "property",            required_argument, NULL, 'p'                     },
6456                 { "all",                 no_argument,       NULL, 'a'                     },
6457                 { "reverse",             no_argument,       NULL, ARG_REVERSE             },
6458                 { "after",               no_argument,       NULL, ARG_AFTER               },
6459                 { "before",              no_argument,       NULL, ARG_BEFORE              },
6460                 { "show-types",          no_argument,       NULL, ARG_SHOW_TYPES          },
6461                 { "failed",              no_argument,       NULL, ARG_FAILED              }, /* compatibility only */
6462                 { "full",                no_argument,       NULL, 'l'                     },
6463                 { "job-mode",            required_argument, NULL, ARG_JOB_MODE            },
6464                 { "fail",                no_argument,       NULL, ARG_FAIL                }, /* compatibility only */
6465                 { "irreversible",        no_argument,       NULL, ARG_IRREVERSIBLE        }, /* compatibility only */
6466                 { "ignore-dependencies", no_argument,       NULL, ARG_IGNORE_DEPENDENCIES }, /* compatibility only */
6467                 { "ignore-inhibitors",   no_argument,       NULL, 'i'                     },
6468                 { "user",                no_argument,       NULL, ARG_USER                },
6469                 { "system",              no_argument,       NULL, ARG_SYSTEM              },
6470                 { "global",              no_argument,       NULL, ARG_GLOBAL              },
6471                 { "no-block",            no_argument,       NULL, ARG_NO_BLOCK            },
6472                 { "no-legend",           no_argument,       NULL, ARG_NO_LEGEND           },
6473                 { "no-pager",            no_argument,       NULL, ARG_NO_PAGER            },
6474                 { "no-wall",             no_argument,       NULL, ARG_NO_WALL             },
6475                 { "quiet",               no_argument,       NULL, 'q'                     },
6476                 { "root",                required_argument, NULL, ARG_ROOT                },
6477                 { "force",               no_argument,       NULL, ARG_FORCE               },
6478                 { "no-reload",           no_argument,       NULL, ARG_NO_RELOAD           },
6479                 { "kill-who",            required_argument, NULL, ARG_KILL_WHO            },
6480                 { "signal",              required_argument, NULL, 's'                     },
6481                 { "no-ask-password",     no_argument,       NULL, ARG_NO_ASK_PASSWORD     },
6482                 { "host",                required_argument, NULL, 'H'                     },
6483                 { "machine",             required_argument, NULL, 'M'                     },
6484                 { "runtime",             no_argument,       NULL, ARG_RUNTIME             },
6485                 { "lines",               required_argument, NULL, 'n'                     },
6486                 { "output",              required_argument, NULL, 'o'                     },
6487                 { "plain",               no_argument,       NULL, ARG_PLAIN               },
6488                 { "state",               required_argument, NULL, ARG_STATE               },
6489                 { "recursive",           no_argument,       NULL, 'r'                     },
6490                 { "preset-mode",         required_argument, NULL, ARG_PRESET_MODE         },
6491                 {}
6492         };
6493
6494         int c;
6495
6496         assert(argc >= 0);
6497         assert(argv);
6498
6499         while ((c = getopt_long(argc, argv, "ht:p:alqfs:H:M:n:o:ir", options, NULL)) >= 0)
6500
6501                 switch (c) {
6502
6503                 case 'h':
6504                         systemctl_help();
6505                         return 0;
6506
6507                 case ARG_VERSION:
6508                         puts(PACKAGE_STRING);
6509                         puts(SYSTEMD_FEATURES);
6510                         return 0;
6511
6512                 case 't': {
6513                         const char *word, *state;
6514                         size_t size;
6515
6516                         FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
6517                                 _cleanup_free_ char *type;
6518
6519                                 type = strndup(word, size);
6520                                 if (!type)
6521                                         return -ENOMEM;
6522
6523                                 if (streq(type, "help")) {
6524                                         help_types();
6525                                         return 0;
6526                                 }
6527
6528                                 if (unit_type_from_string(type) >= 0) {
6529                                         if (strv_push(&arg_types, type))
6530                                                 return log_oom();
6531                                         type = NULL;
6532                                         continue;
6533                                 }
6534
6535                                 /* It's much nicer to use --state= for
6536                                  * load states, but let's support this
6537                                  * in --types= too for compatibility
6538                                  * with old versions */
6539                                 if (unit_load_state_from_string(optarg) >= 0) {
6540                                         if (strv_push(&arg_states, type) < 0)
6541                                                 return log_oom();
6542                                         type = NULL;
6543                                         continue;
6544                                 }
6545
6546                                 log_error("Unknown unit type or load state '%s'.", type);
6547                                 log_info("Use -t help to see a list of allowed values.");
6548                                 return -EINVAL;
6549                         }
6550
6551                         break;
6552                 }
6553
6554                 case 'p': {
6555                         /* Make sure that if the empty property list
6556                            was specified, we won't show any properties. */
6557                         if (isempty(optarg) && !arg_properties) {
6558                                 arg_properties = new0(char*, 1);
6559                                 if (!arg_properties)
6560                                         return log_oom();
6561                         } else {
6562                                 const char *word, *state;
6563                                 size_t size;
6564
6565                                 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
6566                                         char *prop;
6567
6568                                         prop = strndup(word, size);
6569                                         if (!prop)
6570                                                 return log_oom();
6571
6572                                         if (strv_consume(&arg_properties, prop) < 0)
6573                                                 return log_oom();
6574                                 }
6575                         }
6576
6577                         /* If the user asked for a particular
6578                          * property, show it to him, even if it is
6579                          * empty. */
6580                         arg_all = true;
6581
6582                         break;
6583                 }
6584
6585                 case 'a':
6586                         arg_all = true;
6587                         break;
6588
6589                 case ARG_REVERSE:
6590                         arg_dependency = DEPENDENCY_REVERSE;
6591                         break;
6592
6593                 case ARG_AFTER:
6594                         arg_dependency = DEPENDENCY_AFTER;
6595                         break;
6596
6597                 case ARG_BEFORE:
6598                         arg_dependency = DEPENDENCY_BEFORE;
6599                         break;
6600
6601                 case ARG_SHOW_TYPES:
6602                         arg_show_types = true;
6603                         break;
6604
6605                 case ARG_JOB_MODE:
6606                         arg_job_mode = optarg;
6607                         break;
6608
6609                 case ARG_FAIL:
6610                         arg_job_mode = "fail";
6611                         break;
6612
6613                 case ARG_IRREVERSIBLE:
6614                         arg_job_mode = "replace-irreversibly";
6615                         break;
6616
6617                 case ARG_IGNORE_DEPENDENCIES:
6618                         arg_job_mode = "ignore-dependencies";
6619                         break;
6620
6621                 case ARG_USER:
6622                         arg_scope = UNIT_FILE_USER;
6623                         break;
6624
6625                 case ARG_SYSTEM:
6626                         arg_scope = UNIT_FILE_SYSTEM;
6627                         break;
6628
6629                 case ARG_GLOBAL:
6630                         arg_scope = UNIT_FILE_GLOBAL;
6631                         break;
6632
6633                 case ARG_NO_BLOCK:
6634                         arg_no_block = true;
6635                         break;
6636
6637                 case ARG_NO_LEGEND:
6638                         arg_no_legend = true;
6639                         break;
6640
6641                 case ARG_NO_PAGER:
6642                         arg_no_pager = true;
6643                         break;
6644
6645                 case ARG_NO_WALL:
6646                         arg_no_wall = true;
6647                         break;
6648
6649                 case ARG_ROOT:
6650                         arg_root = optarg;
6651                         break;
6652
6653                 case 'l':
6654                         arg_full = true;
6655                         break;
6656
6657                 case ARG_FAILED:
6658                         if (strv_extend(&arg_states, "failed") < 0)
6659                                 return log_oom();
6660
6661                         break;
6662
6663                 case 'q':
6664                         arg_quiet = true;
6665                         break;
6666
6667                 case ARG_FORCE:
6668                         arg_force ++;
6669                         break;
6670
6671                 case 'f':
6672                         arg_force ++;
6673                         break;
6674
6675                 case ARG_NO_RELOAD:
6676                         arg_no_reload = true;
6677                         break;
6678
6679                 case ARG_KILL_WHO:
6680                         arg_kill_who = optarg;
6681                         break;
6682
6683                 case 's':
6684                         if ((arg_signal = signal_from_string_try_harder(optarg)) < 0) {
6685                                 log_error("Failed to parse signal string %s.", optarg);
6686                                 return -EINVAL;
6687                         }
6688                         break;
6689
6690                 case ARG_NO_ASK_PASSWORD:
6691                         arg_ask_password = false;
6692                         break;
6693
6694                 case 'H':
6695                         arg_transport = BUS_TRANSPORT_REMOTE;
6696                         arg_host = optarg;
6697                         break;
6698
6699                 case 'M':
6700                         arg_transport = BUS_TRANSPORT_CONTAINER;
6701                         arg_host = optarg;
6702                         break;
6703
6704                 case ARG_RUNTIME:
6705                         arg_runtime = true;
6706                         break;
6707
6708                 case 'n':
6709                         if (safe_atou(optarg, &arg_lines) < 0) {
6710                                 log_error("Failed to parse lines '%s'", optarg);
6711                                 return -EINVAL;
6712                         }
6713                         break;
6714
6715                 case 'o':
6716                         arg_output = output_mode_from_string(optarg);
6717                         if (arg_output < 0) {
6718                                 log_error("Unknown output '%s'.", optarg);
6719                                 return -EINVAL;
6720                         }
6721                         break;
6722
6723                 case 'i':
6724                         arg_ignore_inhibitors = true;
6725                         break;
6726
6727                 case ARG_PLAIN:
6728                         arg_plain = true;
6729                         break;
6730
6731                 case ARG_STATE: {
6732                         const char *word, *state;
6733                         size_t size;
6734
6735                         FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
6736                                 char *s;
6737
6738                                 s = strndup(word, size);
6739                                 if (!s)
6740                                         return log_oom();
6741
6742                                 if (strv_consume(&arg_states, s) < 0)
6743                                         return log_oom();
6744                         }
6745                         break;
6746                 }
6747
6748                 case 'r':
6749                         if (geteuid() != 0) {
6750                                 log_error("--recursive requires root privileges.");
6751                                 return -EPERM;
6752                         }
6753
6754                         arg_recursive = true;
6755                         break;
6756
6757                 case ARG_PRESET_MODE:
6758
6759                         arg_preset_mode = unit_file_preset_mode_from_string(optarg);
6760                         if (arg_preset_mode < 0) {
6761                                 log_error("Failed to parse preset mode: %s.", optarg);
6762                                 return -EINVAL;
6763                         }
6764
6765                         break;
6766
6767                 case '?':
6768                         return -EINVAL;
6769
6770                 default:
6771                         assert_not_reached("Unhandled option");
6772                 }
6773
6774         if (arg_transport != BUS_TRANSPORT_LOCAL && arg_scope != UNIT_FILE_SYSTEM) {
6775                 log_error("Cannot access user instance remotely.");
6776                 return -EINVAL;
6777         }
6778
6779         return 1;
6780 }
6781
6782 static int halt_parse_argv(int argc, char *argv[]) {
6783
6784         enum {
6785                 ARG_HELP = 0x100,
6786                 ARG_HALT,
6787                 ARG_REBOOT,
6788                 ARG_NO_WALL
6789         };
6790
6791         static const struct option options[] = {
6792                 { "help",      no_argument,       NULL, ARG_HELP    },
6793                 { "halt",      no_argument,       NULL, ARG_HALT    },
6794                 { "poweroff",  no_argument,       NULL, 'p'         },
6795                 { "reboot",    no_argument,       NULL, ARG_REBOOT  },
6796                 { "force",     no_argument,       NULL, 'f'         },
6797                 { "wtmp-only", no_argument,       NULL, 'w'         },
6798                 { "no-wtmp",   no_argument,       NULL, 'd'         },
6799                 { "no-wall",   no_argument,       NULL, ARG_NO_WALL },
6800                 {}
6801         };
6802
6803         int c, r, runlevel;
6804
6805         assert(argc >= 0);
6806         assert(argv);
6807
6808         if (utmp_get_runlevel(&runlevel, NULL) >= 0)
6809                 if (runlevel == '0' || runlevel == '6')
6810                         arg_force = 2;
6811
6812         while ((c = getopt_long(argc, argv, "pfwdnih", options, NULL)) >= 0)
6813                 switch (c) {
6814
6815                 case ARG_HELP:
6816                         halt_help();
6817                         return 0;
6818
6819                 case ARG_HALT:
6820                         arg_action = ACTION_HALT;
6821                         break;
6822
6823                 case 'p':
6824                         if (arg_action != ACTION_REBOOT)
6825                                 arg_action = ACTION_POWEROFF;
6826                         break;
6827
6828                 case ARG_REBOOT:
6829                         arg_action = ACTION_REBOOT;
6830                         break;
6831
6832                 case 'f':
6833                         arg_force = 2;
6834                         break;
6835
6836                 case 'w':
6837                         arg_dry = true;
6838                         break;
6839
6840                 case 'd':
6841                         arg_no_wtmp = true;
6842                         break;
6843
6844                 case ARG_NO_WALL:
6845                         arg_no_wall = true;
6846                         break;
6847
6848                 case 'i':
6849                 case 'h':
6850                 case 'n':
6851                         /* Compatibility nops */
6852                         break;
6853
6854                 case '?':
6855                         return -EINVAL;
6856
6857                 default:
6858                         assert_not_reached("Unhandled option");
6859                 }
6860
6861         if (arg_action == ACTION_REBOOT && (argc == optind || argc == optind + 1)) {
6862                 r = update_reboot_param_file(argc == optind + 1 ? argv[optind] : NULL);
6863                 if (r < 0)
6864                         return r;
6865         } else if (optind < argc) {
6866                 log_error("Too many arguments.");
6867                 return -EINVAL;
6868         }
6869
6870         return 1;
6871 }
6872
6873 static int parse_time_spec(const char *t, usec_t *_u) {
6874         assert(t);
6875         assert(_u);
6876
6877         if (streq(t, "now"))
6878                 *_u = 0;
6879         else if (!strchr(t, ':')) {
6880                 uint64_t u;
6881
6882                 if (safe_atou64(t, &u) < 0)
6883                         return -EINVAL;
6884
6885                 *_u = now(CLOCK_REALTIME) + USEC_PER_MINUTE * u;
6886         } else {
6887                 char *e = NULL;
6888                 long hour, minute;
6889                 struct tm tm = {};
6890                 time_t s;
6891                 usec_t n;
6892
6893                 errno = 0;
6894                 hour = strtol(t, &e, 10);
6895                 if (errno > 0 || *e != ':' || hour < 0 || hour > 23)
6896                         return -EINVAL;
6897
6898                 minute = strtol(e+1, &e, 10);
6899                 if (errno > 0 || *e != 0 || minute < 0 || minute > 59)
6900                         return -EINVAL;
6901
6902                 n = now(CLOCK_REALTIME);
6903                 s = (time_t) (n / USEC_PER_SEC);
6904
6905                 assert_se(localtime_r(&s, &tm));
6906
6907                 tm.tm_hour = (int) hour;
6908                 tm.tm_min = (int) minute;
6909                 tm.tm_sec = 0;
6910
6911                 assert_se(s = mktime(&tm));
6912
6913                 *_u = (usec_t) s * USEC_PER_SEC;
6914
6915                 while (*_u <= n)
6916                         *_u += USEC_PER_DAY;
6917         }
6918
6919         return 0;
6920 }
6921
6922 static int shutdown_parse_argv(int argc, char *argv[]) {
6923
6924         enum {
6925                 ARG_HELP = 0x100,
6926                 ARG_NO_WALL
6927         };
6928
6929         static const struct option options[] = {
6930                 { "help",      no_argument,       NULL, ARG_HELP    },
6931                 { "halt",      no_argument,       NULL, 'H'         },
6932                 { "poweroff",  no_argument,       NULL, 'P'         },
6933                 { "reboot",    no_argument,       NULL, 'r'         },
6934                 { "kexec",     no_argument,       NULL, 'K'         }, /* not documented extension */
6935                 { "no-wall",   no_argument,       NULL, ARG_NO_WALL },
6936                 {}
6937         };
6938
6939         int c, r;
6940
6941         assert(argc >= 0);
6942         assert(argv);
6943
6944         while ((c = getopt_long(argc, argv, "HPrhkt:afFc", options, NULL)) >= 0)
6945                 switch (c) {
6946
6947                 case ARG_HELP:
6948                         shutdown_help();
6949                         return 0;
6950
6951                 case 'H':
6952                         arg_action = ACTION_HALT;
6953                         break;
6954
6955                 case 'P':
6956                         arg_action = ACTION_POWEROFF;
6957                         break;
6958
6959                 case 'r':
6960                         if (kexec_loaded())
6961                                 arg_action = ACTION_KEXEC;
6962                         else
6963                                 arg_action = ACTION_REBOOT;
6964                         break;
6965
6966                 case 'K':
6967                         arg_action = ACTION_KEXEC;
6968                         break;
6969
6970                 case 'h':
6971                         if (arg_action != ACTION_HALT)
6972                                 arg_action = ACTION_POWEROFF;
6973                         break;
6974
6975                 case 'k':
6976                         arg_dry = true;
6977                         break;
6978
6979                 case ARG_NO_WALL:
6980                         arg_no_wall = true;
6981                         break;
6982
6983                 case 't':
6984                 case 'a':
6985                         /* Compatibility nops */
6986                         break;
6987
6988                 case 'c':
6989                         arg_action = ACTION_CANCEL_SHUTDOWN;
6990                         break;
6991
6992                 case '?':
6993                         return -EINVAL;
6994
6995                 default:
6996                         assert_not_reached("Unhandled option");
6997                 }
6998
6999         if (argc > optind && arg_action != ACTION_CANCEL_SHUTDOWN) {
7000                 r = parse_time_spec(argv[optind], &arg_when);
7001                 if (r < 0) {
7002                         log_error("Failed to parse time specification: %s", argv[optind]);
7003                         return r;
7004                 }
7005         } else
7006                 arg_when = now(CLOCK_REALTIME) + USEC_PER_MINUTE;
7007
7008         if (argc > optind && arg_action == ACTION_CANCEL_SHUTDOWN)
7009                 /* No time argument for shutdown cancel */
7010                 arg_wall = argv + optind;
7011         else if (argc > optind + 1)
7012                 /* We skip the time argument */
7013                 arg_wall = argv + optind + 1;
7014
7015         optind = argc;
7016
7017         return 1;
7018 }
7019
7020 static int telinit_parse_argv(int argc, char *argv[]) {
7021
7022         enum {
7023                 ARG_HELP = 0x100,
7024                 ARG_NO_WALL
7025         };
7026
7027         static const struct option options[] = {
7028                 { "help",      no_argument,       NULL, ARG_HELP    },
7029                 { "no-wall",   no_argument,       NULL, ARG_NO_WALL },
7030                 {}
7031         };
7032
7033         static const struct {
7034                 char from;
7035                 enum action to;
7036         } table[] = {
7037                 { '0', ACTION_POWEROFF },
7038                 { '6', ACTION_REBOOT },
7039                 { '1', ACTION_RESCUE },
7040                 { '2', ACTION_RUNLEVEL2 },
7041                 { '3', ACTION_RUNLEVEL3 },
7042                 { '4', ACTION_RUNLEVEL4 },
7043                 { '5', ACTION_RUNLEVEL5 },
7044                 { 's', ACTION_RESCUE },
7045                 { 'S', ACTION_RESCUE },
7046                 { 'q', ACTION_RELOAD },
7047                 { 'Q', ACTION_RELOAD },
7048                 { 'u', ACTION_REEXEC },
7049                 { 'U', ACTION_REEXEC }
7050         };
7051
7052         unsigned i;
7053         int c;
7054
7055         assert(argc >= 0);
7056         assert(argv);
7057
7058         while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0)
7059                 switch (c) {
7060
7061                 case ARG_HELP:
7062                         telinit_help();
7063                         return 0;
7064
7065                 case ARG_NO_WALL:
7066                         arg_no_wall = true;
7067                         break;
7068
7069                 case '?':
7070                         return -EINVAL;
7071
7072                 default:
7073                         assert_not_reached("Unhandled option");
7074                 }
7075
7076         if (optind >= argc) {
7077                 log_error("%s: required argument missing.",
7078                           program_invocation_short_name);
7079                 return -EINVAL;
7080         }
7081
7082         if (optind + 1 < argc) {
7083                 log_error("Too many arguments.");
7084                 return -EINVAL;
7085         }
7086
7087         if (strlen(argv[optind]) != 1) {
7088                 log_error("Expected single character argument.");
7089                 return -EINVAL;
7090         }
7091
7092         for (i = 0; i < ELEMENTSOF(table); i++)
7093                 if (table[i].from == argv[optind][0])
7094                         break;
7095
7096         if (i >= ELEMENTSOF(table)) {
7097                 log_error("Unknown command '%s'.", argv[optind]);
7098                 return -EINVAL;
7099         }
7100
7101         arg_action = table[i].to;
7102
7103         optind ++;
7104
7105         return 1;
7106 }
7107
7108 static int runlevel_parse_argv(int argc, char *argv[]) {
7109
7110         enum {
7111                 ARG_HELP = 0x100,
7112         };
7113
7114         static const struct option options[] = {
7115                 { "help",      no_argument,       NULL, ARG_HELP    },
7116                 {}
7117         };
7118
7119         int c;
7120
7121         assert(argc >= 0);
7122         assert(argv);
7123
7124         while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0)
7125                 switch (c) {
7126
7127                 case ARG_HELP:
7128                         runlevel_help();
7129                         return 0;
7130
7131                 case '?':
7132                         return -EINVAL;
7133
7134                 default:
7135                         assert_not_reached("Unhandled option");
7136                 }
7137
7138         if (optind < argc) {
7139                 log_error("Too many arguments.");
7140                 return -EINVAL;
7141         }
7142
7143         return 1;
7144 }
7145
7146 static int parse_argv(int argc, char *argv[]) {
7147         assert(argc >= 0);
7148         assert(argv);
7149
7150         if (program_invocation_short_name) {
7151
7152                 if (strstr(program_invocation_short_name, "halt")) {
7153                         arg_action = ACTION_HALT;
7154                         return halt_parse_argv(argc, argv);
7155                 } else if (strstr(program_invocation_short_name, "poweroff")) {
7156                         arg_action = ACTION_POWEROFF;
7157                         return halt_parse_argv(argc, argv);
7158                 } else if (strstr(program_invocation_short_name, "reboot")) {
7159                         if (kexec_loaded())
7160                                 arg_action = ACTION_KEXEC;
7161                         else
7162                                 arg_action = ACTION_REBOOT;
7163                         return halt_parse_argv(argc, argv);
7164                 } else if (strstr(program_invocation_short_name, "shutdown")) {
7165                         arg_action = ACTION_POWEROFF;
7166                         return shutdown_parse_argv(argc, argv);
7167                 } else if (strstr(program_invocation_short_name, "init")) {
7168
7169                         if (sd_booted() > 0) {
7170                                 arg_action = _ACTION_INVALID;
7171                                 return telinit_parse_argv(argc, argv);
7172                         } else {
7173                                 /* Hmm, so some other init system is
7174                                  * running, we need to forward this
7175                                  * request to it. For now we simply
7176                                  * guess that it is Upstart. */
7177
7178                                 execv(TELINIT, argv);
7179
7180                                 log_error("Couldn't find an alternative telinit implementation to spawn.");
7181                                 return -EIO;
7182                         }
7183
7184                 } else if (strstr(program_invocation_short_name, "runlevel")) {
7185                         arg_action = ACTION_RUNLEVEL;
7186                         return runlevel_parse_argv(argc, argv);
7187                 }
7188         }
7189
7190         arg_action = ACTION_SYSTEMCTL;
7191         return systemctl_parse_argv(argc, argv);
7192 }
7193
7194 _pure_ static int action_to_runlevel(void) {
7195
7196         static const char table[_ACTION_MAX] = {
7197                 [ACTION_HALT] =      '0',
7198                 [ACTION_POWEROFF] =  '0',
7199                 [ACTION_REBOOT] =    '6',
7200                 [ACTION_RUNLEVEL2] = '2',
7201                 [ACTION_RUNLEVEL3] = '3',
7202                 [ACTION_RUNLEVEL4] = '4',
7203                 [ACTION_RUNLEVEL5] = '5',
7204                 [ACTION_RESCUE] =    '1'
7205         };
7206
7207         assert(arg_action < _ACTION_MAX);
7208
7209         return table[arg_action];
7210 }
7211
7212 static int talk_initctl(void) {
7213
7214         struct init_request request = {
7215                 .magic = INIT_MAGIC,
7216                 .sleeptime  = 0,
7217                 .cmd = INIT_CMD_RUNLVL
7218         };
7219
7220         _cleanup_close_ int fd = -1;
7221         char rl;
7222         int r;
7223
7224         rl = action_to_runlevel();
7225         if (!rl)
7226                 return 0;
7227
7228         request.runlevel = rl;
7229
7230         fd = open(INIT_FIFO, O_WRONLY|O_NDELAY|O_CLOEXEC|O_NOCTTY);
7231         if (fd < 0) {
7232                 if (errno == ENOENT)
7233                         return 0;
7234
7235                 log_error_errno(errno, "Failed to open "INIT_FIFO": %m");
7236                 return -errno;
7237         }
7238
7239         r = loop_write(fd, &request, sizeof(request), false);
7240         if (r < 0)
7241                 return log_error_errno(r, "Failed to write to "INIT_FIFO": %m");
7242
7243         return 1;
7244 }
7245
7246 static int systemctl_main(sd_bus *bus, int argc, char *argv[], int bus_error) {
7247
7248         static const struct {
7249                 const char* verb;
7250                 const enum {
7251                         MORE,
7252                         LESS,
7253                         EQUAL
7254                 } argc_cmp;
7255                 const int argc;
7256                 int (* const dispatch)(sd_bus *bus, char **args);
7257                 const enum {
7258                         NOBUS = 1,
7259                         FORCE,
7260                 } bus;
7261         } verbs[] = {
7262                 { "list-units",            MORE,  0, list_units        },
7263                 { "list-unit-files",       MORE,  1, list_unit_files,  NOBUS },
7264                 { "list-sockets",          MORE,  1, list_sockets      },
7265                 { "list-timers",           MORE,  1, list_timers       },
7266                 { "list-jobs",             MORE,  1, list_jobs         },
7267                 { "list-machines",         MORE,  1, list_machines     },
7268                 { "clear-jobs",            EQUAL, 1, daemon_reload     },
7269                 { "cancel",                MORE,  2, cancel_job        },
7270                 { "start",                 MORE,  2, start_unit        },
7271                 { "stop",                  MORE,  2, start_unit        },
7272                 { "condstop",              MORE,  2, start_unit        }, /* For compatibility with ALTLinux */
7273                 { "reload",                MORE,  2, start_unit        },
7274                 { "restart",               MORE,  2, start_unit        },
7275                 { "try-restart",           MORE,  2, start_unit        },
7276                 { "reload-or-restart",     MORE,  2, start_unit        },
7277                 { "reload-or-try-restart", MORE,  2, start_unit        },
7278                 { "force-reload",          MORE,  2, start_unit        }, /* For compatibility with SysV */
7279                 { "condreload",            MORE,  2, start_unit        }, /* For compatibility with ALTLinux */
7280                 { "condrestart",           MORE,  2, start_unit        }, /* For compatibility with RH */
7281                 { "isolate",               EQUAL, 2, start_unit        },
7282                 { "kill",                  MORE,  2, kill_unit         },
7283                 { "is-active",             MORE,  2, check_unit_active },
7284                 { "check",                 MORE,  2, check_unit_active },
7285                 { "is-failed",             MORE,  2, check_unit_failed },
7286                 { "show",                  MORE,  1, show              },
7287                 { "cat",                   MORE,  2, cat               },
7288                 { "status",                MORE,  1, show              },
7289                 { "help",                  MORE,  2, show              },
7290                 { "snapshot",              LESS,  2, snapshot          },
7291                 { "delete",                MORE,  2, delete_snapshot   },
7292                 { "daemon-reload",         EQUAL, 1, daemon_reload     },
7293                 { "daemon-reexec",         EQUAL, 1, daemon_reload     },
7294                 { "show-environment",      EQUAL, 1, show_environment  },
7295                 { "set-environment",       MORE,  2, set_environment   },
7296                 { "unset-environment",     MORE,  2, set_environment   },
7297                 { "import-environment",    MORE,  1, import_environment},
7298                 { "halt",                  EQUAL, 1, start_special,    FORCE },
7299                 { "poweroff",              EQUAL, 1, start_special,    FORCE },
7300                 { "reboot",                EQUAL, 1, start_special,    FORCE },
7301                 { "kexec",                 EQUAL, 1, start_special     },
7302                 { "suspend",               EQUAL, 1, start_special     },
7303                 { "hibernate",             EQUAL, 1, start_special     },
7304                 { "hybrid-sleep",          EQUAL, 1, start_special     },
7305                 { "default",               EQUAL, 1, start_special     },
7306                 { "rescue",                EQUAL, 1, start_special     },
7307                 { "emergency",             EQUAL, 1, start_special     },
7308                 { "exit",                  EQUAL, 1, start_special     },
7309                 { "reset-failed",          MORE,  1, reset_failed      },
7310                 { "enable",                MORE,  2, enable_unit,      NOBUS },
7311                 { "disable",               MORE,  2, enable_unit,      NOBUS },
7312                 { "is-enabled",            MORE,  2, unit_is_enabled,  NOBUS },
7313                 { "reenable",              MORE,  2, enable_unit,      NOBUS },
7314                 { "preset",                MORE,  2, enable_unit,      NOBUS },
7315                 { "preset-all",            EQUAL, 1, preset_all,       NOBUS },
7316                 { "mask",                  MORE,  2, enable_unit,      NOBUS },
7317                 { "unmask",                MORE,  2, enable_unit,      NOBUS },
7318                 { "link",                  MORE,  2, enable_unit,      NOBUS },
7319                 { "switch-root",           MORE,  2, switch_root       },
7320                 { "list-dependencies",     LESS,  2, list_dependencies },
7321                 { "set-default",           EQUAL, 2, set_default,      NOBUS },
7322                 { "get-default",           EQUAL, 1, get_default,      NOBUS },
7323                 { "set-property",          MORE,  3, set_property      },
7324                 { "is-system-running",     EQUAL, 1, is_system_running },
7325                 { "add-wants",             MORE,  3, add_dependency,   NOBUS },
7326                 { "add-requires",          MORE,  3, add_dependency,   NOBUS },
7327                 { "edit",                  MORE,  2, edit,             NOBUS },
7328                 {}
7329         }, *verb = verbs;
7330
7331         int left;
7332
7333         assert(argc >= 0);
7334         assert(argv);
7335
7336         left = argc - optind;
7337
7338         /* Special rule: no arguments (left == 0) means "list-units" */
7339         if (left > 0) {
7340                 if (streq(argv[optind], "help") && !argv[optind+1]) {
7341                         log_error("This command expects one or more "
7342                                   "unit names. Did you mean --help?");
7343                         return -EINVAL;
7344                 }
7345
7346                 for (; verb->verb; verb++)
7347                         if (streq(argv[optind], verb->verb))
7348                                 goto found;
7349
7350                 log_error("Unknown operation '%s'.", argv[optind]);
7351                 return -EINVAL;
7352         }
7353 found:
7354
7355         switch (verb->argc_cmp) {
7356
7357         case EQUAL:
7358                 if (left != verb->argc) {
7359                         log_error("Invalid number of arguments.");
7360                         return -EINVAL;
7361                 }
7362
7363                 break;
7364
7365         case MORE:
7366                 if (left < verb->argc) {
7367                         log_error("Too few arguments.");
7368                         return -EINVAL;
7369                 }
7370
7371                 break;
7372
7373         case LESS:
7374                 if (left > verb->argc) {
7375                         log_error("Too many arguments.");
7376                         return -EINVAL;
7377                 }
7378
7379                 break;
7380
7381         default:
7382                 assert_not_reached("Unknown comparison operator.");
7383         }
7384
7385         /* Require a bus connection for all operations but
7386          * enable/disable */
7387         if (verb->bus == NOBUS) {
7388                 if (!bus && !avoid_bus()) {
7389                         log_error_errno(bus_error, "Failed to get D-Bus connection: %m");
7390                         return -EIO;
7391                 }
7392
7393         } else {
7394                 if (running_in_chroot() > 0) {
7395                         log_info("Running in chroot, ignoring request.");
7396                         return 0;
7397                 }
7398
7399                 if ((verb->bus != FORCE || arg_force <= 0) && !bus) {
7400                         log_error_errno(bus_error, "Failed to get D-Bus connection: %m");
7401                         return -EIO;
7402                 }
7403         }
7404
7405         return verb->dispatch(bus, argv + optind);
7406 }
7407
7408 static int send_shutdownd(usec_t t, char mode, bool dry_run, bool warn, const char *message) {
7409
7410         struct sd_shutdown_command c = {
7411                 .usec = t,
7412                 .mode = mode,
7413                 .dry_run = dry_run,
7414                 .warn_wall = warn,
7415         };
7416
7417         union sockaddr_union sockaddr = {
7418                 .un.sun_family = AF_UNIX,
7419                 .un.sun_path = "/run/systemd/shutdownd",
7420         };
7421
7422         struct iovec iovec[2] = {{
7423                  .iov_base = (char*) &c,
7424                  .iov_len = offsetof(struct sd_shutdown_command, wall_message),
7425         }};
7426
7427         struct msghdr msghdr = {
7428                 .msg_name = &sockaddr,
7429                 .msg_namelen = offsetof(struct sockaddr_un, sun_path)
7430                                + strlen("/run/systemd/shutdownd"),
7431                 .msg_iov = iovec,
7432                 .msg_iovlen = 1,
7433         };
7434
7435         _cleanup_close_ int fd;
7436
7437         fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
7438         if (fd < 0)
7439                 return -errno;
7440
7441         if (!isempty(message)) {
7442                 iovec[1].iov_base = (char*) message;
7443                 iovec[1].iov_len = strlen(message);
7444                 msghdr.msg_iovlen++;
7445         }
7446
7447         if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) < 0)
7448                 return -errno;
7449
7450         return 0;
7451 }
7452
7453 static int reload_with_fallback(sd_bus *bus) {
7454
7455         if (bus) {
7456                 /* First, try systemd via D-Bus. */
7457                 if (daemon_reload(bus, NULL) >= 0)
7458                         return 0;
7459         }
7460
7461         /* Nothing else worked, so let's try signals */
7462         assert(arg_action == ACTION_RELOAD || arg_action == ACTION_REEXEC);
7463
7464         if (kill(1, arg_action == ACTION_RELOAD ? SIGHUP : SIGTERM) < 0)
7465                 return log_error_errno(errno, "kill() failed: %m");
7466
7467         return 0;
7468 }
7469
7470 static int start_with_fallback(sd_bus *bus) {
7471
7472         if (bus) {
7473                 /* First, try systemd via D-Bus. */
7474                 if (start_unit(bus, NULL) >= 0)
7475                         goto done;
7476         }
7477
7478         /* Nothing else worked, so let's try
7479          * /dev/initctl */
7480         if (talk_initctl() > 0)
7481                 goto done;
7482
7483         log_error("Failed to talk to init daemon.");
7484         return -EIO;
7485
7486 done:
7487         warn_wall(arg_action);
7488         return 0;
7489 }
7490
7491 static int halt_now(enum action a) {
7492
7493         /* The kernel will automaticall flush ATA disks and suchlike
7494          * on reboot(), but the file systems need to be synce'd
7495          * explicitly in advance. */
7496         sync();
7497
7498         /* Make sure C-A-D is handled by the kernel from this point
7499          * on... */
7500         reboot(RB_ENABLE_CAD);
7501
7502         switch (a) {
7503
7504         case ACTION_HALT:
7505                 log_info("Halting.");
7506                 reboot(RB_HALT_SYSTEM);
7507                 return -errno;
7508
7509         case ACTION_POWEROFF:
7510                 log_info("Powering off.");
7511                 reboot(RB_POWER_OFF);
7512                 return -errno;
7513
7514         case ACTION_REBOOT: {
7515                 _cleanup_free_ char *param = NULL;
7516
7517                 if (read_one_line_file(REBOOT_PARAM_FILE, &param) >= 0) {
7518                         log_info("Rebooting with argument '%s'.", param);
7519                         syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
7520                                 LINUX_REBOOT_CMD_RESTART2, param);
7521                 }
7522
7523                 log_info("Rebooting.");
7524                 reboot(RB_AUTOBOOT);
7525                 return -errno;
7526         }
7527
7528         default:
7529                 assert_not_reached("Unknown action.");
7530         }
7531 }
7532
7533 static int halt_main(sd_bus *bus) {
7534         int r;
7535
7536         r = check_inhibitors(bus, arg_action);
7537         if (r < 0)
7538                 return r;
7539
7540         if (geteuid() != 0) {
7541                 /* Try logind if we are a normal user and no special
7542                  * mode applies. Maybe PolicyKit allows us to shutdown
7543                  * the machine. */
7544
7545                 if (arg_when <= 0 &&
7546                     !arg_dry &&
7547                     arg_force <= 0 &&
7548                     (arg_action == ACTION_POWEROFF ||
7549                      arg_action == ACTION_REBOOT)) {
7550                         r = reboot_with_logind(bus, arg_action);
7551                         if (r >= 0)
7552                                 return r;
7553                 }
7554
7555                 log_error("Must be root.");
7556                 return -EPERM;
7557         }
7558
7559         if (arg_when > 0) {
7560                 _cleanup_free_ char *m;
7561
7562                 m = strv_join(arg_wall, " ");
7563                 if (!m)
7564                         return log_oom();
7565
7566                 r = send_shutdownd(arg_when,
7567                                    arg_action == ACTION_HALT     ? 'H' :
7568                                    arg_action == ACTION_POWEROFF ? 'P' :
7569                                    arg_action == ACTION_KEXEC    ? 'K' :
7570                                                                    'r',
7571                                    arg_dry,
7572                                    !arg_no_wall,
7573                                    m);
7574
7575                 if (r < 0)
7576                         log_warning_errno(r, "Failed to talk to shutdownd, proceeding with immediate shutdown: %m");
7577                 else {
7578                         char date[FORMAT_TIMESTAMP_MAX];
7579
7580                         log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.",
7581                                  format_timestamp(date, sizeof(date), arg_when));
7582                         return 0;
7583                 }
7584         }
7585
7586         if (!arg_dry && !arg_force)
7587                 return start_with_fallback(bus);
7588
7589         if (!arg_no_wtmp) {
7590                 if (sd_booted() > 0)
7591                         log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
7592                 else {
7593                         r = utmp_put_shutdown();
7594                         if (r < 0)
7595                                 log_warning_errno(r, "Failed to write utmp record: %m");
7596                 }
7597         }
7598
7599         if (arg_dry)
7600                 return 0;
7601
7602         r = halt_now(arg_action);
7603         log_error_errno(r, "Failed to reboot: %m");
7604
7605         return r;
7606 }
7607
7608 static int runlevel_main(void) {
7609         int r, runlevel, previous;
7610
7611         r = utmp_get_runlevel(&runlevel, &previous);
7612         if (r < 0) {
7613                 puts("unknown");
7614                 return r;
7615         }
7616
7617         printf("%c %c\n",
7618                previous <= 0 ? 'N' : previous,
7619                runlevel <= 0 ? 'N' : runlevel);
7620
7621         return 0;
7622 }
7623
7624 int main(int argc, char*argv[]) {
7625         _cleanup_bus_close_unref_ sd_bus *bus = NULL;
7626         int r;
7627
7628         setlocale(LC_ALL, "");
7629         log_parse_environment();
7630         log_open();
7631
7632         /* Explicitly not on_tty() to avoid setting cached value.
7633          * This becomes relevant for piping output which might be
7634          * ellipsized. */
7635         original_stdout_is_tty = isatty(STDOUT_FILENO);
7636
7637         r = parse_argv(argc, argv);
7638         if (r <= 0)
7639                 goto finish;
7640
7641         /* /sbin/runlevel doesn't need to communicate via D-Bus, so
7642          * let's shortcut this */
7643         if (arg_action == ACTION_RUNLEVEL) {
7644                 r = runlevel_main();
7645                 goto finish;
7646         }
7647
7648         if (running_in_chroot() > 0 && arg_action != ACTION_SYSTEMCTL) {
7649                 log_info("Running in chroot, ignoring request.");
7650                 r = 0;
7651                 goto finish;
7652         }
7653
7654         if (!avoid_bus())
7655                 r = bus_open_transport_systemd(arg_transport, arg_host, arg_scope != UNIT_FILE_SYSTEM, &bus);
7656
7657         /* systemctl_main() will print an error message for the bus
7658          * connection, but only if it needs to */
7659
7660         switch (arg_action) {
7661
7662         case ACTION_SYSTEMCTL:
7663                 r = systemctl_main(bus, argc, argv, r);
7664                 break;
7665
7666         case ACTION_HALT:
7667         case ACTION_POWEROFF:
7668         case ACTION_REBOOT:
7669         case ACTION_KEXEC:
7670                 r = halt_main(bus);
7671                 break;
7672
7673         case ACTION_RUNLEVEL2:
7674         case ACTION_RUNLEVEL3:
7675         case ACTION_RUNLEVEL4:
7676         case ACTION_RUNLEVEL5:
7677         case ACTION_RESCUE:
7678         case ACTION_EMERGENCY:
7679         case ACTION_DEFAULT:
7680                 r = start_with_fallback(bus);
7681                 break;
7682
7683         case ACTION_RELOAD:
7684         case ACTION_REEXEC:
7685                 r = reload_with_fallback(bus);
7686                 break;
7687
7688         case ACTION_CANCEL_SHUTDOWN: {
7689                 _cleanup_free_ char *m = NULL;
7690
7691                 if (arg_wall) {
7692                         m = strv_join(arg_wall, " ");
7693                         if (!m) {
7694                                 r = log_oom();
7695                                 goto finish;
7696                         }
7697                 }
7698
7699                 r = send_shutdownd(arg_when, SD_SHUTDOWN_NONE, false, !arg_no_wall, m);
7700                 if (r < 0)
7701                         log_warning_errno(r, "Failed to talk to shutdownd, shutdown hasn't been cancelled: %m");
7702                 break;
7703         }
7704
7705         case ACTION_RUNLEVEL:
7706         case _ACTION_INVALID:
7707         default:
7708                 assert_not_reached("Unknown action");
7709         }
7710
7711 finish:
7712         pager_close();
7713         ask_password_agent_close();
7714         polkit_agent_close();
7715
7716         strv_free(arg_types);
7717         strv_free(arg_states);
7718         strv_free(arg_properties);
7719
7720         return r < 0 ? EXIT_FAILURE : r;
7721 }