chiark / gitweb /
ima-setup: simplify
[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 = 1, t = 1;
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         for (f = 0; args[f]; 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                 /* Mark this entry, so that we don't try enabling it as native unit */
5209                 args[f] = (char*) "";
5210
5211                 log_info("%s is not a native service, redirecting to /sbin/chkconfig.", name);
5212
5213                 if (!isempty(arg_root))
5214                         argv[c++] = q = strappend("--root=", arg_root);
5215
5216                 argv[c++] = basename(p);
5217                 argv[c++] =
5218                         streq(verb, "enable") ? "on" :
5219                         streq(verb, "disable") ? "off" : "--level=5";
5220                 argv[c] = NULL;
5221
5222                 l = strv_join((char**)argv, " ");
5223                 if (!l)
5224                         return log_oom();
5225
5226                 log_info("Executing %s", l);
5227
5228                 pid = fork();
5229                 if (pid < 0)
5230                         return log_error_errno(errno, "Failed to fork: %m");
5231                 else if (pid == 0) {
5232                         /* Child */
5233
5234                         execv(argv[0], (char**) argv);
5235                         _exit(EXIT_FAILURE);
5236                 }
5237
5238                 j = wait_for_terminate(pid, &status);
5239                 if (j < 0) {
5240                         log_error_errno(r, "Failed to wait for child: %m");
5241                         return j;
5242                 }
5243
5244                 if (status.si_code == CLD_EXITED) {
5245                         if (streq(verb, "is-enabled")) {
5246                                 if (status.si_status == 0) {
5247                                         if (!arg_quiet)
5248                                                 puts("enabled");
5249                                         r = 1;
5250                                 } else {
5251                                         if (!arg_quiet)
5252                                                 puts("disabled");
5253                                 }
5254
5255                         } else if (status.si_status != 0)
5256                                 return -EINVAL;
5257                 } else
5258                         return -EPROTO;
5259         }
5260
5261         /* Drop all SysV units */
5262         for (f = 0, t = 0; args[f]; f++) {
5263
5264                 if (isempty(args[f]))
5265                         continue;
5266
5267                 args[t++] = args[f];
5268         }
5269
5270         args[t] = NULL;
5271
5272 #endif
5273         return r;
5274 }
5275
5276 static int mangle_names(char **original_names, char ***mangled_names) {
5277         char **i, **l, **name;
5278
5279         l = new(char*, strv_length(original_names) + 1);
5280         if (!l)
5281                 return log_oom();
5282
5283         i = l;
5284         STRV_FOREACH(name, original_names) {
5285
5286                 /* When enabling units qualified path names are OK,
5287                  * too, hence allow them explicitly. */
5288
5289                 if (is_path(*name))
5290                         *i = strdup(*name);
5291                 else
5292                         *i = unit_name_mangle(*name, MANGLE_NOGLOB);
5293
5294                 if (!*i) {
5295                         strv_free(l);
5296                         return log_oom();
5297                 }
5298
5299                 i++;
5300         }
5301
5302         *i = NULL;
5303         *mangled_names = l;
5304
5305         return 0;
5306 }
5307
5308 static int enable_unit(sd_bus *bus, char **args) {
5309         _cleanup_strv_free_ char **names = NULL;
5310         const char *verb = args[0];
5311         UnitFileChange *changes = NULL;
5312         unsigned n_changes = 0;
5313         int carries_install_info = -1;
5314         int r;
5315
5316         if (!args[1])
5317                 return 0;
5318
5319         r = mangle_names(args+1, &names);
5320         if (r < 0)
5321                 return r;
5322
5323         r = enable_sysv_units(verb, names);
5324         if (r < 0)
5325                 return r;
5326
5327         /* If the operation was fully executed by the SysV compat,
5328          * let's finish early */
5329         if (strv_isempty(names))
5330                 return 0;
5331
5332         if (!bus || avoid_bus()) {
5333                 if (streq(verb, "enable")) {
5334                         r = unit_file_enable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5335                         carries_install_info = r;
5336                 } else if (streq(verb, "disable"))
5337                         r = unit_file_disable(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
5338                 else if (streq(verb, "reenable")) {
5339                         r = unit_file_reenable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5340                         carries_install_info = r;
5341                 } else if (streq(verb, "link"))
5342                         r = unit_file_link(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5343                 else if (streq(verb, "preset")) {
5344                         r = unit_file_preset(arg_scope, arg_runtime, arg_root, names, arg_preset_mode, arg_force, &changes, &n_changes);
5345                         carries_install_info = r;
5346                 } else if (streq(verb, "mask"))
5347                         r = unit_file_mask(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5348                 else if (streq(verb, "unmask"))
5349                         r = unit_file_unmask(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
5350                 else
5351                         assert_not_reached("Unknown verb");
5352
5353                 if (r < 0) {
5354                         log_error_errno(r, "Operation failed: %m");
5355                         goto finish;
5356                 }
5357
5358                 if (!arg_quiet)
5359                         dump_unit_file_changes(changes, n_changes);
5360
5361                 r = 0;
5362         } else {
5363                 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
5364                 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5365                 int expect_carries_install_info = false;
5366                 bool send_force = true, send_preset_mode = false;
5367                 const char *method;
5368
5369                 if (streq(verb, "enable")) {
5370                         method = "EnableUnitFiles";
5371                         expect_carries_install_info = true;
5372                 } else if (streq(verb, "disable")) {
5373                         method = "DisableUnitFiles";
5374                         send_force = false;
5375                 } else if (streq(verb, "reenable")) {
5376                         method = "ReenableUnitFiles";
5377                         expect_carries_install_info = true;
5378                 } else if (streq(verb, "link"))
5379                         method = "LinkUnitFiles";
5380                 else if (streq(verb, "preset")) {
5381
5382                         if (arg_preset_mode != UNIT_FILE_PRESET_FULL) {
5383                                 method = "PresetUnitFilesWithMode";
5384                                 send_preset_mode = true;
5385                         } else
5386                                 method = "PresetUnitFiles";
5387
5388                         expect_carries_install_info = true;
5389                 } else if (streq(verb, "mask"))
5390                         method = "MaskUnitFiles";
5391                 else if (streq(verb, "unmask")) {
5392                         method = "UnmaskUnitFiles";
5393                         send_force = false;
5394                 } else
5395                         assert_not_reached("Unknown verb");
5396
5397                 r = sd_bus_message_new_method_call(
5398                                 bus,
5399                                 &m,
5400                                 "org.freedesktop.systemd1",
5401                                 "/org/freedesktop/systemd1",
5402                                 "org.freedesktop.systemd1.Manager",
5403                                 method);
5404                 if (r < 0)
5405                         return bus_log_create_error(r);
5406
5407                 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5408                 if (r < 0)
5409                         return bus_log_create_error(r);
5410
5411                 r = sd_bus_message_append_strv(m, names);
5412                 if (r < 0)
5413                         return bus_log_create_error(r);
5414
5415                 if (send_preset_mode) {
5416                         r = sd_bus_message_append(m, "s", unit_file_preset_mode_to_string(arg_preset_mode));
5417                         if (r < 0)
5418                                 return bus_log_create_error(r);
5419                 }
5420
5421                 r = sd_bus_message_append(m, "b", arg_runtime);
5422                 if (r < 0)
5423                         return bus_log_create_error(r);
5424
5425                 if (send_force) {
5426                         r = sd_bus_message_append(m, "b", arg_force);
5427                         if (r < 0)
5428                                 return bus_log_create_error(r);
5429                 }
5430
5431                 r = sd_bus_call(bus, m, 0, &error, &reply);
5432                 if (r < 0) {
5433                         log_error("Failed to execute operation: %s", bus_error_message(&error, r));
5434                         return r;
5435                 }
5436
5437                 if (expect_carries_install_info) {
5438                         r = sd_bus_message_read(reply, "b", &carries_install_info);
5439                         if (r < 0)
5440                                 return bus_log_parse_error(r);
5441                 }
5442
5443                 r = deserialize_and_dump_unit_file_changes(reply);
5444                 if (r < 0)
5445                         return r;
5446
5447                 /* Try to reload if enabled */
5448                 if (!arg_no_reload)
5449                         r = daemon_reload(bus, args);
5450                 else
5451                         r = 0;
5452         }
5453
5454         if (carries_install_info == 0)
5455                 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
5456                             "using systemctl.\n"
5457                             "Possible reasons for having this kind of units are:\n"
5458                             "1) A unit may be statically enabled by being symlinked from another unit's\n"
5459                             "   .wants/ or .requires/ directory.\n"
5460                             "2) A unit's purpose may be to act as a helper for some other unit which has\n"
5461                             "   a requirement dependency on it.\n"
5462                             "3) A unit may be started when needed via activation (socket, path, timer,\n"
5463                             "   D-Bus, udev, scripted systemctl call, ...).\n");
5464
5465 finish:
5466         unit_file_changes_free(changes, n_changes);
5467
5468         return r;
5469 }
5470
5471 static int add_dependency(sd_bus *bus, char **args) {
5472         _cleanup_strv_free_ char **names = NULL;
5473         _cleanup_free_ char *target = NULL;
5474         const char *verb = args[0];
5475         UnitDependency dep;
5476         int r = 0;
5477
5478         if (!args[1])
5479                 return 0;
5480
5481         target = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".target");
5482         if (!target)
5483                 return log_oom();
5484
5485         r = mangle_names(args+2, &names);
5486         if (r < 0)
5487                 return r;
5488
5489         if (streq(verb, "add-wants"))
5490                 dep = UNIT_WANTS;
5491         else if (streq(verb, "add-requires"))
5492                 dep = UNIT_REQUIRES;
5493         else
5494                 assert_not_reached("Unknown verb");
5495
5496         if (!bus || avoid_bus()) {
5497                 UnitFileChange *changes = NULL;
5498                 unsigned n_changes = 0;
5499
5500                 r = unit_file_add_dependency(arg_scope, arg_runtime, arg_root, names, target, dep, arg_force, &changes, &n_changes);
5501
5502                 if (r < 0)
5503                         return log_error_errno(r, "Can't add dependency: %m");
5504
5505                 if (!arg_quiet)
5506                         dump_unit_file_changes(changes, n_changes);
5507
5508                 unit_file_changes_free(changes, n_changes);
5509
5510         } else {
5511                 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
5512                 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5513
5514                 r = sd_bus_message_new_method_call(
5515                                 bus,
5516                                 &m,
5517                                 "org.freedesktop.systemd1",
5518                                 "/org/freedesktop/systemd1",
5519                                 "org.freedesktop.systemd1.Manager",
5520                                 "AddDependencyUnitFiles");
5521                 if (r < 0)
5522                         return bus_log_create_error(r);
5523
5524                 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5525                 if (r < 0)
5526                         return bus_log_create_error(r);
5527
5528                 r = sd_bus_message_append_strv(m, names);
5529                 if (r < 0)
5530                         return bus_log_create_error(r);
5531
5532                 r = sd_bus_message_append(m, "ssbb", target, unit_dependency_to_string(dep), arg_runtime, arg_force);
5533                 if (r < 0)
5534                         return bus_log_create_error(r);
5535
5536                 r = sd_bus_call(bus, m, 0, &error, &reply);
5537                 if (r < 0) {
5538                         log_error("Failed to execute operation: %s", bus_error_message(&error, r));
5539                         return r;
5540                 }
5541
5542                 r = deserialize_and_dump_unit_file_changes(reply);
5543                 if (r < 0)
5544                         return r;
5545
5546                 if (!arg_no_reload)
5547                         r = daemon_reload(bus, args);
5548                 else
5549                         r = 0;
5550         }
5551
5552         return r;
5553 }
5554
5555 static int preset_all(sd_bus *bus, char **args) {
5556         UnitFileChange *changes = NULL;
5557         unsigned n_changes = 0;
5558         int r;
5559
5560         if (!bus || avoid_bus()) {
5561
5562                 r = unit_file_preset_all(arg_scope, arg_runtime, arg_root, arg_preset_mode, arg_force, &changes, &n_changes);
5563                 if (r < 0) {
5564                         log_error_errno(r, "Operation failed: %m");
5565                         goto finish;
5566                 }
5567
5568                 if (!arg_quiet)
5569                         dump_unit_file_changes(changes, n_changes);
5570
5571                 r = 0;
5572
5573         } else {
5574                 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
5575                 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5576
5577                 r = sd_bus_message_new_method_call(
5578                                 bus,
5579                                 &m,
5580                                 "org.freedesktop.systemd1",
5581                                 "/org/freedesktop/systemd1",
5582                                 "org.freedesktop.systemd1.Manager",
5583                                 "PresetAllUnitFiles");
5584                 if (r < 0)
5585                         return bus_log_create_error(r);
5586
5587                 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5588                 if (r < 0)
5589                         return bus_log_create_error(r);
5590
5591                 r = sd_bus_message_append(
5592                                 m,
5593                                 "sbb",
5594                                 unit_file_preset_mode_to_string(arg_preset_mode),
5595                                 arg_runtime,
5596                                 arg_force);
5597                 if (r < 0)
5598                         return bus_log_create_error(r);
5599
5600                 r = sd_bus_call(bus, m, 0, &error, &reply);
5601                 if (r < 0) {
5602                         log_error("Failed to execute operation: %s", bus_error_message(&error, r));
5603                         return r;
5604                 }
5605
5606                 r = deserialize_and_dump_unit_file_changes(reply);
5607                 if (r < 0)
5608                         return r;
5609
5610                 if (!arg_no_reload)
5611                         r = daemon_reload(bus, args);
5612                 else
5613                         r = 0;
5614         }
5615
5616 finish:
5617         unit_file_changes_free(changes, n_changes);
5618
5619         return r;
5620 }
5621
5622 static int unit_is_enabled(sd_bus *bus, char **args) {
5623
5624         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5625         _cleanup_strv_free_ char **names = NULL;
5626         bool enabled;
5627         char **name;
5628         int r;
5629
5630         r = mangle_names(args+1, &names);
5631         if (r < 0)
5632                 return r;
5633
5634         r = enable_sysv_units(args[0], names);
5635         if (r < 0)
5636                 return r;
5637
5638         enabled = r > 0;
5639
5640         if (!bus || avoid_bus()) {
5641
5642                 STRV_FOREACH(name, names) {
5643                         UnitFileState state;
5644
5645                         state = unit_file_get_state(arg_scope, arg_root, *name);
5646                         if (state < 0)
5647                                 return log_error_errno(state, "Failed to get unit file state for %s: %m", *name);
5648
5649                         if (state == UNIT_FILE_ENABLED ||
5650                             state == UNIT_FILE_ENABLED_RUNTIME ||
5651                             state == UNIT_FILE_STATIC ||
5652                             state == UNIT_FILE_INDIRECT)
5653                                 enabled = true;
5654
5655                         if (!arg_quiet)
5656                                 puts(unit_file_state_to_string(state));
5657                 }
5658
5659         } else {
5660                 STRV_FOREACH(name, names) {
5661                         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
5662                         const char *s;
5663
5664                         r = sd_bus_call_method(
5665                                         bus,
5666                                         "org.freedesktop.systemd1",
5667                                         "/org/freedesktop/systemd1",
5668                                         "org.freedesktop.systemd1.Manager",
5669                                         "GetUnitFileState",
5670                                         &error,
5671                                         &reply,
5672                                         "s", *name);
5673                         if (r < 0) {
5674                                 log_error("Failed to get unit file state for %s: %s", *name, bus_error_message(&error, r));
5675                                 return r;
5676                         }
5677
5678                         r = sd_bus_message_read(reply, "s", &s);
5679                         if (r < 0)
5680                                 return bus_log_parse_error(r);
5681
5682                         if (STR_IN_SET(s, "enabled", "enabled-runtime", "static", "indirect"))
5683                                 enabled = true;
5684
5685                         if (!arg_quiet)
5686                                 puts(s);
5687                 }
5688         }
5689
5690         return !enabled;
5691 }
5692
5693 static int is_system_running(sd_bus *bus, char **args) {
5694         _cleanup_free_ char *state = NULL;
5695         int r;
5696
5697         r = sd_bus_get_property_string(
5698                         bus,
5699                         "org.freedesktop.systemd1",
5700                         "/org/freedesktop/systemd1",
5701                         "org.freedesktop.systemd1.Manager",
5702                         "SystemState",
5703                         NULL,
5704                         &state);
5705         if (r < 0) {
5706                 if (!arg_quiet)
5707                         puts("unknown");
5708                 return 0;
5709         }
5710
5711         if (!arg_quiet)
5712                 puts(state);
5713
5714         return streq(state, "running") ? EXIT_SUCCESS : EXIT_FAILURE;
5715 }
5716
5717 static int unit_file_find_path(LookupPaths *lp, const char *unit_name, char **unit_path) {
5718         char **p;
5719
5720         assert(lp);
5721         assert(unit_name);
5722         assert(unit_path);
5723
5724         STRV_FOREACH(p, lp->unit_path) {
5725                 char *path;
5726
5727                 path = path_join(arg_root, *p, unit_name);
5728                 if (!path)
5729                         return log_oom();
5730
5731                 if (access(path, F_OK) == 0) {
5732                         *unit_path = path;
5733                         return 1;
5734                 }
5735
5736                 free(path);
5737         }
5738
5739         return 0;
5740 }
5741
5742 static int create_edit_temp_file(const char *new_path, const char *original_path, char **ret_tmp_fn) {
5743         int r;
5744         char *t;
5745
5746         assert(new_path);
5747         assert(original_path);
5748         assert(ret_tmp_fn);
5749
5750         t = tempfn_random(new_path);
5751         if (!t)
5752                 return log_oom();
5753
5754         r = mkdir_parents(new_path, 0755);
5755         if (r < 0) {
5756                 log_error_errno(r, "Failed to create directories for %s: %m", new_path);
5757                 free(t);
5758                 return r;
5759         }
5760
5761         r = copy_file(original_path, t, 0, 0644);
5762         if (r == -ENOENT) {
5763                 r = touch(t);
5764                 if (r < 0) {
5765                         log_error_errno(r, "Failed to create temporary file %s: %m", t);
5766                         free(t);
5767                         return r;
5768                 }
5769         } else if (r < 0) {
5770                 log_error_errno(r, "Failed to copy %s to %s: %m", original_path, t);
5771                 free(t);
5772                 return r;
5773         }
5774
5775         *ret_tmp_fn = t;
5776
5777         return 0;
5778 }
5779
5780 static int get_drop_in_to_edit(const char *unit_name, const char *user_home, const char *user_runtime, char **ret_path) {
5781         char *tmp_new_path;
5782         char *tmp;
5783
5784         assert(unit_name);
5785         assert(ret_path);
5786
5787         switch (arg_scope) {
5788                 case UNIT_FILE_SYSTEM:
5789                         tmp = strappenda(arg_runtime ? "/run/systemd/system/" : SYSTEM_CONFIG_UNIT_PATH "/", unit_name, ".d/override.conf");
5790                         break;
5791                 case UNIT_FILE_GLOBAL:
5792                         tmp = strappenda(arg_runtime ? "/run/systemd/user/" : USER_CONFIG_UNIT_PATH "/", unit_name, ".d/override.conf");
5793                         break;
5794                 case UNIT_FILE_USER:
5795                         assert(user_home);
5796                         assert(user_runtime);
5797
5798                         tmp = strappenda(arg_runtime ? user_runtime : user_home, "/", unit_name, ".d/override.conf");
5799                         break;
5800                 default:
5801                         assert_not_reached("Invalid scope");
5802         }
5803
5804         tmp_new_path = path_join(arg_root, tmp, NULL);
5805         if (!tmp_new_path)
5806                 return log_oom();
5807
5808         *ret_path = tmp_new_path;
5809
5810         return 0;
5811 }
5812
5813 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) {
5814         char *tmp_new_path;
5815         char *tmp_tmp_path;
5816         int r;
5817
5818         assert(unit_name);
5819         assert(ret_new_path);
5820         assert(ret_tmp_path);
5821
5822         r = get_drop_in_to_edit(unit_name, user_home, user_runtime, &tmp_new_path);
5823         if (r < 0)
5824                 return r;
5825
5826         r = create_edit_temp_file(tmp_new_path, tmp_new_path, &tmp_tmp_path);
5827         if (r < 0) {
5828                 free(tmp_new_path);
5829                 return r;
5830         }
5831
5832         *ret_new_path = tmp_new_path;
5833         *ret_tmp_path = tmp_tmp_path;
5834
5835         return 0;
5836 }
5837
5838 static bool unit_is_editable(const char *unit_name, const char *fragment_path, const char *user_home) {
5839         bool editable = true;
5840         const char *invalid_path;
5841
5842         assert(unit_name);
5843
5844         if (!arg_runtime)
5845                 return true;
5846
5847         switch (arg_scope) {
5848                 case UNIT_FILE_SYSTEM:
5849                         if (path_startswith(fragment_path, "/etc/systemd/system")) {
5850                                 editable = false;
5851                                 invalid_path = "/etc/systemd/system";
5852                         } else if (path_startswith(fragment_path, SYSTEM_CONFIG_UNIT_PATH)) {
5853                                 editable = false;
5854                                 invalid_path = SYSTEM_CONFIG_UNIT_PATH;
5855                         }
5856                         break;
5857                 case UNIT_FILE_GLOBAL:
5858                         if (path_startswith(fragment_path, "/etc/systemd/user")) {
5859                                 editable = false;
5860                                 invalid_path = "/etc/systemd/user";
5861                         } else if (path_startswith(fragment_path, USER_CONFIG_UNIT_PATH)) {
5862                                 editable = false;
5863                                 invalid_path = USER_CONFIG_UNIT_PATH;
5864                         }
5865                         break;
5866                 case UNIT_FILE_USER:
5867                         assert(user_home);
5868
5869                         if (path_startswith(fragment_path, "/etc/systemd/user")) {
5870                                 editable = false;
5871                                 invalid_path = "/etc/systemd/user";
5872                         } else if (path_startswith(fragment_path, USER_CONFIG_UNIT_PATH)) {
5873                                 editable = false;
5874                                 invalid_path = USER_CONFIG_UNIT_PATH;
5875                         } else if (path_startswith(fragment_path, user_home)) {
5876                                 editable = false;
5877                                 invalid_path = user_home;
5878                         }
5879                         break;
5880                 default:
5881                         assert_not_reached("Invalid scope");
5882         }
5883
5884         if (!editable)
5885                 log_error("%s ignored: cannot temporarily edit units from %s", unit_name, invalid_path);
5886
5887         return editable;
5888 }
5889
5890 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) {
5891         char *tmp_new_path;
5892
5893         assert(unit_name);
5894         assert(ret_path);
5895
5896         if (!unit_is_editable(unit_name, fragment_path, user_home))
5897                 return -EINVAL;
5898
5899         switch (arg_scope) {
5900                 case UNIT_FILE_SYSTEM:
5901                         tmp_new_path = path_join(arg_root, arg_runtime ? "/run/systemd/system/" : SYSTEM_CONFIG_UNIT_PATH, unit_name);
5902                         break;
5903                 case UNIT_FILE_GLOBAL:
5904                         tmp_new_path = path_join(arg_root, arg_runtime ? "/run/systemd/user/" : USER_CONFIG_UNIT_PATH, unit_name);
5905                         break;
5906                 case UNIT_FILE_USER:
5907                         assert(user_home);
5908                         assert(user_runtime);
5909
5910                         tmp_new_path = path_join(arg_root, arg_runtime ? user_runtime : user_home, unit_name);
5911                         break;
5912                 default:
5913                         assert_not_reached("Invalid scope");
5914         }
5915         if (!tmp_new_path)
5916                 return log_oom();
5917
5918         *ret_path = tmp_new_path;
5919
5920         return 0;
5921 }
5922
5923 static int unit_file_create_copy(const char *unit_name,
5924                                  const char *fragment_path,
5925                                  const char *user_home,
5926                                  const char *user_runtime,
5927                                  char **ret_new_path,
5928                                  char **ret_tmp_path) {
5929         char *tmp_new_path;
5930         char *tmp_tmp_path;
5931         int r;
5932
5933         assert(fragment_path);
5934         assert(unit_name);
5935         assert(ret_new_path);
5936         assert(ret_tmp_path);
5937
5938         r = get_copy_to_edit(unit_name, fragment_path, user_home, user_runtime, &tmp_new_path);
5939         if (r < 0)
5940                 return r;
5941
5942         if (!path_equal(fragment_path, tmp_new_path) && access(tmp_new_path, F_OK) == 0) {
5943                 char response;
5944
5945                 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);
5946                 if (r < 0) {
5947                         free(tmp_new_path);
5948                         return r;
5949                 }
5950                 if (response != 'y') {
5951                         log_warning("%s ignored", unit_name);
5952                         free(tmp_new_path);
5953                         return -1;
5954                 }
5955         }
5956
5957         r = create_edit_temp_file(tmp_new_path, fragment_path, &tmp_tmp_path);
5958         if (r < 0) {
5959                 log_error_errno(r, "Failed to create temporary file for %s: %m", tmp_new_path);
5960                 free(tmp_new_path);
5961                 return r;
5962         }
5963
5964         *ret_new_path = tmp_new_path;
5965         *ret_tmp_path = tmp_tmp_path;
5966
5967         return 0;
5968 }
5969
5970 static int run_editor(char **paths) {
5971         pid_t pid;
5972         int r;
5973
5974         assert(paths);
5975
5976         pid = fork();
5977         if (pid < 0) {
5978                 log_error_errno(errno, "Failed to fork: %m");
5979                 return -errno;
5980         }
5981
5982         if (pid == 0) {
5983                 const char **args;
5984                 char **backup_editors = STRV_MAKE("nano", "vim", "vi");
5985                 char *editor;
5986                 char **tmp_path, **original_path, **p;
5987                 unsigned i = 1;
5988                 size_t argc;
5989
5990                 argc = strv_length(paths)/2 + 1;
5991                 args = newa(const char*, argc + 1);
5992
5993                 args[0] = NULL;
5994                 STRV_FOREACH_PAIR(original_path, tmp_path, paths) {
5995                         args[i] = *tmp_path;
5996                         i++;
5997                 }
5998                 args[argc] = NULL;
5999
6000                 /* SYSTEMD_EDITOR takes precedence over EDITOR which takes precedence over VISUAL
6001                  * If neither SYSTEMD_EDITOR nor EDITOR nor VISUAL are present,
6002                  * we try to execute well known editors
6003                  */
6004                 editor = getenv("SYSTEMD_EDITOR");
6005                 if (!editor)
6006                         editor = getenv("EDITOR");
6007                 if (!editor)
6008                         editor = getenv("VISUAL");
6009
6010                 if (!isempty(editor)) {
6011                         args[0] = editor;
6012                         execvp(editor, (char* const*) args);
6013                 }
6014
6015                 STRV_FOREACH(p, backup_editors) {
6016                         args[0] = *p;
6017                         execvp(*p, (char* const*) args);
6018                         /* We do not fail if the editor doesn't exist
6019                          * because we want to try each one of them before
6020                          * failing.
6021                          */
6022                         if (errno != ENOENT) {
6023                                 log_error("Failed to execute %s: %m", editor);
6024                                 _exit(EXIT_FAILURE);
6025                         }
6026                 }
6027
6028                 log_error("Cannot edit unit(s): No editor available. Please set either SYSTEMD_EDITOR or EDITOR or VISUAL environment variable");
6029                 _exit(EXIT_FAILURE);
6030         }
6031
6032         r = wait_for_terminate_and_warn("editor", pid, true);
6033         if (r < 0)
6034                 return log_error_errno(r, "Failed to wait for child: %m");
6035
6036         return r;
6037 }
6038
6039 static int find_paths_to_edit(sd_bus *bus, char **names, char ***paths) {
6040         _cleanup_free_ char *user_home = NULL;
6041         _cleanup_free_ char *user_runtime = NULL;
6042         char **name;
6043         int r;
6044
6045         assert(names);
6046         assert(paths);
6047
6048         if (arg_scope == UNIT_FILE_USER) {
6049                 r = user_config_home(&user_home);
6050                 if (r < 0)
6051                         return log_oom();
6052                 else if (r == 0) {
6053                         log_error("Cannot edit units for the user instance: home directory unknown");
6054                         return -1;
6055                 }
6056
6057                 r = user_runtime_dir(&user_runtime);
6058                 if (r < 0)
6059                         return log_oom();
6060                 else if (r == 0) {
6061                         log_error("Cannot edit units for the user instance: runtime directory unknown");
6062                         return -1;
6063                 }
6064         }
6065
6066         if (!bus || avoid_bus()) {
6067                 _cleanup_lookup_paths_free_ LookupPaths lp = {};
6068
6069                 /* If there is no bus, we try to find the units by testing each available directory
6070                  * according to the scope.
6071                  */
6072                 r = lookup_paths_init(&lp,
6073                                 arg_scope == UNIT_FILE_SYSTEM ? SYSTEMD_SYSTEM : SYSTEMD_USER,
6074                                 arg_scope == UNIT_FILE_USER,
6075                                 arg_root,
6076                                 NULL, NULL, NULL);
6077                 if (r < 0) {
6078                         log_error_errno(r, "Failed get lookup paths: %m");
6079                         return r;
6080                 }
6081
6082                 STRV_FOREACH(name, names) {
6083                         _cleanup_free_ char *path = NULL;
6084                         char *new_path, *tmp_path;
6085
6086                         r = unit_file_find_path(&lp, *name, &path);
6087                         if (r < 0)
6088                                 return r;
6089                         if (r == 0) {
6090                                 log_warning("%s ignored: not found", *name);
6091                                 continue;
6092                         }
6093
6094                         if (arg_full)
6095                                 r = unit_file_create_copy(*name, path, user_home, user_runtime, &new_path, &tmp_path);
6096                         else
6097                                 r = unit_file_create_drop_in(*name, user_home, user_runtime, &new_path, &tmp_path);
6098
6099                         if (r < 0)
6100                                 continue;
6101
6102                         r = strv_push(paths, new_path);
6103                         if (r < 0)
6104                                 return log_oom();
6105
6106                         r = strv_push(paths, tmp_path);
6107                         if (r < 0)
6108                                 return log_oom();
6109                 }
6110         } else {
6111                 STRV_FOREACH(name, names) {
6112                         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
6113                         _cleanup_free_ char *fragment_path = NULL;
6114                         _cleanup_free_ char *unit = NULL;
6115                         char *new_path, *tmp_path;
6116
6117                         unit = unit_dbus_path_from_name(*name);
6118                         if (!unit)
6119                                 return log_oom();
6120
6121                         if (need_daemon_reload(bus, *name) > 0) {
6122                                 log_warning("%s ignored: unit file changed on disk. Run 'systemctl%s daemon-reload'.",
6123                                         *name, arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
6124                                 continue;
6125                         }
6126
6127                         r = sd_bus_get_property_string(
6128                                         bus,
6129                                         "org.freedesktop.systemd1",
6130                                         unit,
6131                                         "org.freedesktop.systemd1.Unit",
6132                                         "FragmentPath",
6133                                         &error,
6134                                         &fragment_path);
6135                         if (r < 0) {
6136                                 log_warning("Failed to get FragmentPath: %s", bus_error_message(&error, r));
6137                                 continue;
6138                         }
6139
6140                         if (isempty(fragment_path)) {
6141                                 log_warning("%s ignored: not found", *name);
6142                                 continue;
6143                         }
6144
6145                         if (arg_full)
6146                                 r = unit_file_create_copy(*name, fragment_path, user_home, user_runtime, &new_path, &tmp_path);
6147                         else
6148                                 r = unit_file_create_drop_in(*name, user_home, user_runtime, &new_path, &tmp_path);
6149                         if (r < 0)
6150                                 continue;
6151
6152                         r = strv_push(paths, new_path);
6153                         if (r < 0)
6154                                 return log_oom();
6155
6156                         r = strv_push(paths, tmp_path);
6157                         if (r < 0)
6158                                 return log_oom();
6159                 }
6160         }
6161
6162         return 0;
6163 }
6164
6165 static int edit(sd_bus *bus, char **args) {
6166         _cleanup_strv_free_ char **names = NULL;
6167         _cleanup_strv_free_ char **paths = NULL;
6168         char **original, **tmp;
6169         int r;
6170
6171         assert(args);
6172
6173         if (!on_tty()) {
6174                 log_error("Cannot edit units if we are not on a tty");
6175                 return -EINVAL;
6176         }
6177
6178         if (arg_transport != BUS_TRANSPORT_LOCAL) {
6179                 log_error("Cannot remotely edit units");
6180                 return -EINVAL;
6181         }
6182
6183         r = expand_names(bus, args + 1, NULL, &names);
6184         if (r < 0)
6185                 return log_error_errno(r, "Failed to expand names: %m");
6186
6187         if (!names) {
6188                 log_error("No unit name found by expanding names");
6189                 return -ENOENT;
6190         }
6191
6192         r = find_paths_to_edit(bus, names, &paths);
6193         if (r < 0)
6194                 return r;
6195
6196         if (strv_isempty(paths)) {
6197                 log_error("Cannot find any units to edit");
6198                 return -ENOENT;
6199         }
6200
6201         r = run_editor(paths);
6202         if (r < 0)
6203                 goto end;
6204
6205         STRV_FOREACH_PAIR(original, tmp, paths) {
6206                 /* If the temporary file is empty we ignore it.
6207                  * It's useful if the user wants to cancel its modification
6208                  */
6209                 if (null_or_empty_path(*tmp)) {
6210                         log_warning("Edition of %s canceled: temporary file empty", *original);
6211                         continue;
6212                 }
6213                 r = rename(*tmp, *original);
6214                 if (r < 0) {
6215                         r = log_error_errno(errno, "Failed to rename %s to %s: %m", *tmp, *original);
6216                         goto end;
6217                 }
6218         }
6219
6220         if (!arg_no_reload && bus && !avoid_bus())
6221                 r = daemon_reload(bus, args);
6222
6223 end:
6224         STRV_FOREACH_PAIR(original, tmp, paths)
6225                 unlink_noerrno(*tmp);
6226
6227         return r;
6228 }
6229
6230 static void systemctl_help(void) {
6231
6232         pager_open_if_enabled();
6233
6234         printf("%s [OPTIONS...] {COMMAND} ...\n\n"
6235                "Query or send control commands to the systemd manager.\n\n"
6236                "  -h --help           Show this help\n"
6237                "     --version        Show package version\n"
6238                "     --system         Connect to system manager\n"
6239                "     --user           Connect to user service manager\n"
6240                "  -H --host=[USER@]HOST\n"
6241                "                      Operate on remote host\n"
6242                "  -M --machine=CONTAINER\n"
6243                "                      Operate on local container\n"
6244                "  -t --type=TYPE      List only units of a particular type\n"
6245                "     --state=STATE    List only units with particular LOAD or SUB or ACTIVE state\n"
6246                "  -p --property=NAME  Show only properties by this name\n"
6247                "  -a --all            Show all loaded units/properties, including dead/empty\n"
6248                "                      ones. To list all units installed on the system, use\n"
6249                "                      the 'list-unit-files' command instead.\n"
6250                "  -l --full           Don't ellipsize unit names on output\n"
6251                "  -r --recursive      Show unit list of host and local containers\n"
6252                "     --reverse        Show reverse dependencies with 'list-dependencies'\n"
6253                "     --job-mode=MODE  Specify how to deal with already queued jobs, when\n"
6254                "                      queueing a new job\n"
6255                "     --show-types     When showing sockets, explicitly show their type\n"
6256                "  -i --ignore-inhibitors\n"
6257                "                      When shutting down or sleeping, ignore inhibitors\n"
6258                "     --kill-who=WHO   Who to send signal to\n"
6259                "  -s --signal=SIGNAL  Which signal to send\n"
6260                "  -q --quiet          Suppress output\n"
6261                "     --no-block       Do not wait until operation finished\n"
6262                "     --no-wall        Don't send wall message before halt/power-off/reboot\n"
6263                "     --no-reload      When enabling/disabling unit files, don't reload daemon\n"
6264                "                      configuration\n"
6265                "     --no-legend      Do not print a legend (column headers and hints)\n"
6266                "     --no-pager       Do not pipe output into a pager\n"
6267                "     --no-ask-password\n"
6268                "                      Do not ask for system passwords\n"
6269                "     --global         Enable/disable unit files globally\n"
6270                "     --runtime        Enable unit files only temporarily until next reboot\n"
6271                "  -f --force          When enabling unit files, override existing symlinks\n"
6272                "                      When shutting down, execute action immediately\n"
6273                "     --preset-mode=   Specifies whether fully apply presets, or only enable,\n"
6274                "                      or only disable\n"
6275                "     --root=PATH      Enable unit files in the specified root directory\n"
6276                "  -n --lines=INTEGER  Number of journal entries to show\n"
6277                "  -o --output=STRING  Change journal output mode (short, short-monotonic,\n"
6278                "                      verbose, export, json, json-pretty, json-sse, cat)\n"
6279                "     --plain          Print unit dependencies as a list instead of a tree\n\n"
6280                "Unit Commands:\n"
6281                "  list-units [PATTERN...]         List loaded units\n"
6282                "  list-sockets [PATTERN...]       List loaded sockets ordered by address\n"
6283                "  list-timers [PATTERN...]        List loaded timers ordered by next elapse\n"
6284                "  start NAME...                   Start (activate) one or more units\n"
6285                "  stop NAME...                    Stop (deactivate) one or more units\n"
6286                "  reload NAME...                  Reload one or more units\n"
6287                "  restart NAME...                 Start or restart one or more units\n"
6288                "  try-restart NAME...             Restart one or more units if active\n"
6289                "  reload-or-restart NAME...       Reload one or more units if possible,\n"
6290                "                                  otherwise start or restart\n"
6291                "  reload-or-try-restart NAME...   Reload one or more units if possible,\n"
6292                "                                  otherwise restart if active\n"
6293                "  isolate NAME                    Start one unit and stop all others\n"
6294                "  kill NAME...                    Send signal to processes of a unit\n"
6295                "  is-active PATTERN...            Check whether units are active\n"
6296                "  is-failed PATTERN...            Check whether units are failed\n"
6297                "  status [PATTERN...|PID...]      Show runtime status of one or more units\n"
6298                "  show [PATTERN...|JOB...]        Show properties of one or more\n"
6299                "                                  units/jobs or the manager\n"
6300                "  cat PATTERN...                  Show files and drop-ins of one or more units\n"
6301                "  set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
6302                "  help PATTERN...|PID...          Show manual for one or more units\n"
6303                "  reset-failed [PATTERN...]       Reset failed state for all, one, or more\n"
6304                "                                  units\n"
6305                "  list-dependencies [NAME]        Recursively show units which are required\n"
6306                "                                  or wanted by this unit or by which this\n"
6307                "                                  unit is required or wanted\n\n"
6308                "Unit File Commands:\n"
6309                "  list-unit-files [PATTERN...]    List installed unit files\n"
6310                "  enable NAME...                  Enable one or more unit files\n"
6311                "  disable NAME...                 Disable one or more unit files\n"
6312                "  reenable NAME...                Reenable one or more unit files\n"
6313                "  preset NAME...                  Enable/disable one or more unit files\n"
6314                "                                  based on preset configuration\n"
6315                "  preset-all                      Enable/disable all unit files based on\n"
6316                "                                  preset configuration\n"
6317                "  is-enabled NAME...              Check whether unit files are enabled\n\n"
6318                "  mask NAME...                    Mask one or more units\n"
6319                "  unmask NAME...                  Unmask one or more units\n"
6320                "  link PATH...                    Link one or more units files into\n"
6321                "                                  the search path\n"
6322                "  add-wants TARGET NAME...        Add 'Wants' dependency for the target\n"
6323                "                                  on specified one or more units\n"
6324                "  add-requires TARGET NAME...     Add 'Requires' dependency for the target\n"
6325                "                                  on specified one or more units\n"
6326                "  get-default                     Get the name of the default target\n"
6327                "  set-default NAME                Set the default target\n"
6328                "  edit NAME...                    Edit one or more unit files\n"
6329                "\n"
6330                "Machine Commands:\n"
6331                "  list-machines [PATTERN...]      List local containers and host\n\n"
6332                "Job Commands:\n"
6333                "  list-jobs [PATTERN...]          List jobs\n"
6334                "  cancel [JOB...]                 Cancel all, one, or more jobs\n\n"
6335                "Snapshot Commands:\n"
6336                "  snapshot [NAME]                 Create a snapshot\n"
6337                "  delete NAME...                  Remove one or more snapshots\n\n"
6338                "Environment Commands:\n"
6339                "  show-environment                Dump environment\n"
6340                "  set-environment NAME=VALUE...   Set one or more environment variables\n"
6341                "  unset-environment NAME...       Unset one or more environment variables\n"
6342                "  import-environment NAME...      Import all, one or more environment variables\n\n"
6343                "Manager Lifecycle Commands:\n"
6344                "  daemon-reload                   Reload systemd manager configuration\n"
6345                "  daemon-reexec                   Reexecute systemd manager\n\n"
6346                "System Commands:\n"
6347                "  is-system-running               Check whether system is fully running\n"
6348                "  default                         Enter system default mode\n"
6349                "  rescue                          Enter system rescue mode\n"
6350                "  emergency                       Enter system emergency mode\n"
6351                "  halt                            Shut down and halt the system\n"
6352                "  poweroff                        Shut down and power-off the system\n"
6353                "  reboot [ARG]                    Shut down and reboot the system\n"
6354                "  kexec                           Shut down and reboot the system with kexec\n"
6355                "  exit                            Request user instance exit\n"
6356                "  switch-root ROOT [INIT]         Change to a different root file system\n"
6357                "  suspend                         Suspend the system\n"
6358                "  hibernate                       Hibernate the system\n"
6359                "  hybrid-sleep                    Hibernate and suspend the system\n",
6360                program_invocation_short_name);
6361 }
6362
6363 static void halt_help(void) {
6364         printf("%s [OPTIONS...]%s\n\n"
6365                "%s the system.\n\n"
6366                "     --help      Show this help\n"
6367                "     --halt      Halt the machine\n"
6368                "  -p --poweroff  Switch off the machine\n"
6369                "     --reboot    Reboot the machine\n"
6370                "  -f --force     Force immediate halt/power-off/reboot\n"
6371                "  -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
6372                "  -d --no-wtmp   Don't write wtmp record\n"
6373                "     --no-wall   Don't send wall message before halt/power-off/reboot\n",
6374                program_invocation_short_name,
6375                arg_action == ACTION_REBOOT   ? " [ARG]" : "",
6376                arg_action == ACTION_REBOOT   ? "Reboot" :
6377                arg_action == ACTION_POWEROFF ? "Power off" :
6378                                                "Halt");
6379 }
6380
6381 static void shutdown_help(void) {
6382         printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
6383                "Shut down the system.\n\n"
6384                "     --help      Show this help\n"
6385                "  -H --halt      Halt the machine\n"
6386                "  -P --poweroff  Power-off the machine\n"
6387                "  -r --reboot    Reboot the machine\n"
6388                "  -h             Equivalent to --poweroff, overridden by --halt\n"
6389                "  -k             Don't halt/power-off/reboot, just send warnings\n"
6390                "     --no-wall   Don't send wall message before halt/power-off/reboot\n"
6391                "  -c             Cancel a pending shutdown\n",
6392                program_invocation_short_name);
6393 }
6394
6395 static void telinit_help(void) {
6396         printf("%s [OPTIONS...] {COMMAND}\n\n"
6397                "Send control commands to the init daemon.\n\n"
6398                "     --help      Show this help\n"
6399                "     --no-wall   Don't send wall message before halt/power-off/reboot\n\n"
6400                "Commands:\n"
6401                "  0              Power-off the machine\n"
6402                "  6              Reboot the machine\n"
6403                "  2, 3, 4, 5     Start runlevelX.target unit\n"
6404                "  1, s, S        Enter rescue mode\n"
6405                "  q, Q           Reload init daemon configuration\n"
6406                "  u, U           Reexecute init daemon\n",
6407                program_invocation_short_name);
6408 }
6409
6410 static void runlevel_help(void) {
6411         printf("%s [OPTIONS...]\n\n"
6412                "Prints the previous and current runlevel of the init system.\n\n"
6413                "     --help      Show this help\n",
6414                program_invocation_short_name);
6415 }
6416
6417 static void help_types(void) {
6418         int i;
6419         const char *t;
6420
6421         if (!arg_no_legend)
6422                 puts("Available unit types:");
6423         for (i = 0; i < _UNIT_TYPE_MAX; i++) {
6424                 t = unit_type_to_string(i);
6425                 if (t)
6426                         puts(t);
6427         }
6428 }
6429
6430 static int systemctl_parse_argv(int argc, char *argv[]) {
6431
6432         enum {
6433                 ARG_FAIL = 0x100,
6434                 ARG_REVERSE,
6435                 ARG_AFTER,
6436                 ARG_BEFORE,
6437                 ARG_SHOW_TYPES,
6438                 ARG_IRREVERSIBLE,
6439                 ARG_IGNORE_DEPENDENCIES,
6440                 ARG_VERSION,
6441                 ARG_USER,
6442                 ARG_SYSTEM,
6443                 ARG_GLOBAL,
6444                 ARG_NO_BLOCK,
6445                 ARG_NO_LEGEND,
6446                 ARG_NO_PAGER,
6447                 ARG_NO_WALL,
6448                 ARG_ROOT,
6449                 ARG_NO_RELOAD,
6450                 ARG_KILL_WHO,
6451                 ARG_NO_ASK_PASSWORD,
6452                 ARG_FAILED,
6453                 ARG_RUNTIME,
6454                 ARG_FORCE,
6455                 ARG_PLAIN,
6456                 ARG_STATE,
6457                 ARG_JOB_MODE,
6458                 ARG_PRESET_MODE,
6459         };
6460
6461         static const struct option options[] = {
6462                 { "help",                no_argument,       NULL, 'h'                     },
6463                 { "version",             no_argument,       NULL, ARG_VERSION             },
6464                 { "type",                required_argument, NULL, 't'                     },
6465                 { "property",            required_argument, NULL, 'p'                     },
6466                 { "all",                 no_argument,       NULL, 'a'                     },
6467                 { "reverse",             no_argument,       NULL, ARG_REVERSE             },
6468                 { "after",               no_argument,       NULL, ARG_AFTER               },
6469                 { "before",              no_argument,       NULL, ARG_BEFORE              },
6470                 { "show-types",          no_argument,       NULL, ARG_SHOW_TYPES          },
6471                 { "failed",              no_argument,       NULL, ARG_FAILED              }, /* compatibility only */
6472                 { "full",                no_argument,       NULL, 'l'                     },
6473                 { "job-mode",            required_argument, NULL, ARG_JOB_MODE            },
6474                 { "fail",                no_argument,       NULL, ARG_FAIL                }, /* compatibility only */
6475                 { "irreversible",        no_argument,       NULL, ARG_IRREVERSIBLE        }, /* compatibility only */
6476                 { "ignore-dependencies", no_argument,       NULL, ARG_IGNORE_DEPENDENCIES }, /* compatibility only */
6477                 { "ignore-inhibitors",   no_argument,       NULL, 'i'                     },
6478                 { "user",                no_argument,       NULL, ARG_USER                },
6479                 { "system",              no_argument,       NULL, ARG_SYSTEM              },
6480                 { "global",              no_argument,       NULL, ARG_GLOBAL              },
6481                 { "no-block",            no_argument,       NULL, ARG_NO_BLOCK            },
6482                 { "no-legend",           no_argument,       NULL, ARG_NO_LEGEND           },
6483                 { "no-pager",            no_argument,       NULL, ARG_NO_PAGER            },
6484                 { "no-wall",             no_argument,       NULL, ARG_NO_WALL             },
6485                 { "quiet",               no_argument,       NULL, 'q'                     },
6486                 { "root",                required_argument, NULL, ARG_ROOT                },
6487                 { "force",               no_argument,       NULL, ARG_FORCE               },
6488                 { "no-reload",           no_argument,       NULL, ARG_NO_RELOAD           },
6489                 { "kill-who",            required_argument, NULL, ARG_KILL_WHO            },
6490                 { "signal",              required_argument, NULL, 's'                     },
6491                 { "no-ask-password",     no_argument,       NULL, ARG_NO_ASK_PASSWORD     },
6492                 { "host",                required_argument, NULL, 'H'                     },
6493                 { "machine",             required_argument, NULL, 'M'                     },
6494                 { "runtime",             no_argument,       NULL, ARG_RUNTIME             },
6495                 { "lines",               required_argument, NULL, 'n'                     },
6496                 { "output",              required_argument, NULL, 'o'                     },
6497                 { "plain",               no_argument,       NULL, ARG_PLAIN               },
6498                 { "state",               required_argument, NULL, ARG_STATE               },
6499                 { "recursive",           no_argument,       NULL, 'r'                     },
6500                 { "preset-mode",         required_argument, NULL, ARG_PRESET_MODE         },
6501                 {}
6502         };
6503
6504         int c;
6505
6506         assert(argc >= 0);
6507         assert(argv);
6508
6509         while ((c = getopt_long(argc, argv, "ht:p:alqfs:H:M:n:o:ir", options, NULL)) >= 0)
6510
6511                 switch (c) {
6512
6513                 case 'h':
6514                         systemctl_help();
6515                         return 0;
6516
6517                 case ARG_VERSION:
6518                         puts(PACKAGE_STRING);
6519                         puts(SYSTEMD_FEATURES);
6520                         return 0;
6521
6522                 case 't': {
6523                         const char *word, *state;
6524                         size_t size;
6525
6526                         FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
6527                                 _cleanup_free_ char *type;
6528
6529                                 type = strndup(word, size);
6530                                 if (!type)
6531                                         return -ENOMEM;
6532
6533                                 if (streq(type, "help")) {
6534                                         help_types();
6535                                         return 0;
6536                                 }
6537
6538                                 if (unit_type_from_string(type) >= 0) {
6539                                         if (strv_push(&arg_types, type))
6540                                                 return log_oom();
6541                                         type = NULL;
6542                                         continue;
6543                                 }
6544
6545                                 /* It's much nicer to use --state= for
6546                                  * load states, but let's support this
6547                                  * in --types= too for compatibility
6548                                  * with old versions */
6549                                 if (unit_load_state_from_string(optarg) >= 0) {
6550                                         if (strv_push(&arg_states, type) < 0)
6551                                                 return log_oom();
6552                                         type = NULL;
6553                                         continue;
6554                                 }
6555
6556                                 log_error("Unknown unit type or load state '%s'.", type);
6557                                 log_info("Use -t help to see a list of allowed values.");
6558                                 return -EINVAL;
6559                         }
6560
6561                         break;
6562                 }
6563
6564                 case 'p': {
6565                         /* Make sure that if the empty property list
6566                            was specified, we won't show any properties. */
6567                         if (isempty(optarg) && !arg_properties) {
6568                                 arg_properties = new0(char*, 1);
6569                                 if (!arg_properties)
6570                                         return log_oom();
6571                         } else {
6572                                 const char *word, *state;
6573                                 size_t size;
6574
6575                                 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
6576                                         char *prop;
6577
6578                                         prop = strndup(word, size);
6579                                         if (!prop)
6580                                                 return log_oom();
6581
6582                                         if (strv_consume(&arg_properties, prop) < 0)
6583                                                 return log_oom();
6584                                 }
6585                         }
6586
6587                         /* If the user asked for a particular
6588                          * property, show it to him, even if it is
6589                          * empty. */
6590                         arg_all = true;
6591
6592                         break;
6593                 }
6594
6595                 case 'a':
6596                         arg_all = true;
6597                         break;
6598
6599                 case ARG_REVERSE:
6600                         arg_dependency = DEPENDENCY_REVERSE;
6601                         break;
6602
6603                 case ARG_AFTER:
6604                         arg_dependency = DEPENDENCY_AFTER;
6605                         break;
6606
6607                 case ARG_BEFORE:
6608                         arg_dependency = DEPENDENCY_BEFORE;
6609                         break;
6610
6611                 case ARG_SHOW_TYPES:
6612                         arg_show_types = true;
6613                         break;
6614
6615                 case ARG_JOB_MODE:
6616                         arg_job_mode = optarg;
6617                         break;
6618
6619                 case ARG_FAIL:
6620                         arg_job_mode = "fail";
6621                         break;
6622
6623                 case ARG_IRREVERSIBLE:
6624                         arg_job_mode = "replace-irreversibly";
6625                         break;
6626
6627                 case ARG_IGNORE_DEPENDENCIES:
6628                         arg_job_mode = "ignore-dependencies";
6629                         break;
6630
6631                 case ARG_USER:
6632                         arg_scope = UNIT_FILE_USER;
6633                         break;
6634
6635                 case ARG_SYSTEM:
6636                         arg_scope = UNIT_FILE_SYSTEM;
6637                         break;
6638
6639                 case ARG_GLOBAL:
6640                         arg_scope = UNIT_FILE_GLOBAL;
6641                         break;
6642
6643                 case ARG_NO_BLOCK:
6644                         arg_no_block = true;
6645                         break;
6646
6647                 case ARG_NO_LEGEND:
6648                         arg_no_legend = true;
6649                         break;
6650
6651                 case ARG_NO_PAGER:
6652                         arg_no_pager = true;
6653                         break;
6654
6655                 case ARG_NO_WALL:
6656                         arg_no_wall = true;
6657                         break;
6658
6659                 case ARG_ROOT:
6660                         arg_root = optarg;
6661                         break;
6662
6663                 case 'l':
6664                         arg_full = true;
6665                         break;
6666
6667                 case ARG_FAILED:
6668                         if (strv_extend(&arg_states, "failed") < 0)
6669                                 return log_oom();
6670
6671                         break;
6672
6673                 case 'q':
6674                         arg_quiet = true;
6675                         break;
6676
6677                 case ARG_FORCE:
6678                         arg_force ++;
6679                         break;
6680
6681                 case 'f':
6682                         arg_force ++;
6683                         break;
6684
6685                 case ARG_NO_RELOAD:
6686                         arg_no_reload = true;
6687                         break;
6688
6689                 case ARG_KILL_WHO:
6690                         arg_kill_who = optarg;
6691                         break;
6692
6693                 case 's':
6694                         if ((arg_signal = signal_from_string_try_harder(optarg)) < 0) {
6695                                 log_error("Failed to parse signal string %s.", optarg);
6696                                 return -EINVAL;
6697                         }
6698                         break;
6699
6700                 case ARG_NO_ASK_PASSWORD:
6701                         arg_ask_password = false;
6702                         break;
6703
6704                 case 'H':
6705                         arg_transport = BUS_TRANSPORT_REMOTE;
6706                         arg_host = optarg;
6707                         break;
6708
6709                 case 'M':
6710                         arg_transport = BUS_TRANSPORT_CONTAINER;
6711                         arg_host = optarg;
6712                         break;
6713
6714                 case ARG_RUNTIME:
6715                         arg_runtime = true;
6716                         break;
6717
6718                 case 'n':
6719                         if (safe_atou(optarg, &arg_lines) < 0) {
6720                                 log_error("Failed to parse lines '%s'", optarg);
6721                                 return -EINVAL;
6722                         }
6723                         break;
6724
6725                 case 'o':
6726                         arg_output = output_mode_from_string(optarg);
6727                         if (arg_output < 0) {
6728                                 log_error("Unknown output '%s'.", optarg);
6729                                 return -EINVAL;
6730                         }
6731                         break;
6732
6733                 case 'i':
6734                         arg_ignore_inhibitors = true;
6735                         break;
6736
6737                 case ARG_PLAIN:
6738                         arg_plain = true;
6739                         break;
6740
6741                 case ARG_STATE: {
6742                         const char *word, *state;
6743                         size_t size;
6744
6745                         FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
6746                                 char *s;
6747
6748                                 s = strndup(word, size);
6749                                 if (!s)
6750                                         return log_oom();
6751
6752                                 if (strv_consume(&arg_states, s) < 0)
6753                                         return log_oom();
6754                         }
6755                         break;
6756                 }
6757
6758                 case 'r':
6759                         if (geteuid() != 0) {
6760                                 log_error("--recursive requires root privileges.");
6761                                 return -EPERM;
6762                         }
6763
6764                         arg_recursive = true;
6765                         break;
6766
6767                 case ARG_PRESET_MODE:
6768
6769                         arg_preset_mode = unit_file_preset_mode_from_string(optarg);
6770                         if (arg_preset_mode < 0) {
6771                                 log_error("Failed to parse preset mode: %s.", optarg);
6772                                 return -EINVAL;
6773                         }
6774
6775                         break;
6776
6777                 case '?':
6778                         return -EINVAL;
6779
6780                 default:
6781                         assert_not_reached("Unhandled option");
6782                 }
6783
6784         if (arg_transport != BUS_TRANSPORT_LOCAL && arg_scope != UNIT_FILE_SYSTEM) {
6785                 log_error("Cannot access user instance remotely.");
6786                 return -EINVAL;
6787         }
6788
6789         return 1;
6790 }
6791
6792 static int halt_parse_argv(int argc, char *argv[]) {
6793
6794         enum {
6795                 ARG_HELP = 0x100,
6796                 ARG_HALT,
6797                 ARG_REBOOT,
6798                 ARG_NO_WALL
6799         };
6800
6801         static const struct option options[] = {
6802                 { "help",      no_argument,       NULL, ARG_HELP    },
6803                 { "halt",      no_argument,       NULL, ARG_HALT    },
6804                 { "poweroff",  no_argument,       NULL, 'p'         },
6805                 { "reboot",    no_argument,       NULL, ARG_REBOOT  },
6806                 { "force",     no_argument,       NULL, 'f'         },
6807                 { "wtmp-only", no_argument,       NULL, 'w'         },
6808                 { "no-wtmp",   no_argument,       NULL, 'd'         },
6809                 { "no-wall",   no_argument,       NULL, ARG_NO_WALL },
6810                 {}
6811         };
6812
6813         int c, r, runlevel;
6814
6815         assert(argc >= 0);
6816         assert(argv);
6817
6818         if (utmp_get_runlevel(&runlevel, NULL) >= 0)
6819                 if (runlevel == '0' || runlevel == '6')
6820                         arg_force = 2;
6821
6822         while ((c = getopt_long(argc, argv, "pfwdnih", options, NULL)) >= 0)
6823                 switch (c) {
6824
6825                 case ARG_HELP:
6826                         halt_help();
6827                         return 0;
6828
6829                 case ARG_HALT:
6830                         arg_action = ACTION_HALT;
6831                         break;
6832
6833                 case 'p':
6834                         if (arg_action != ACTION_REBOOT)
6835                                 arg_action = ACTION_POWEROFF;
6836                         break;
6837
6838                 case ARG_REBOOT:
6839                         arg_action = ACTION_REBOOT;
6840                         break;
6841
6842                 case 'f':
6843                         arg_force = 2;
6844                         break;
6845
6846                 case 'w':
6847                         arg_dry = true;
6848                         break;
6849
6850                 case 'd':
6851                         arg_no_wtmp = true;
6852                         break;
6853
6854                 case ARG_NO_WALL:
6855                         arg_no_wall = true;
6856                         break;
6857
6858                 case 'i':
6859                 case 'h':
6860                 case 'n':
6861                         /* Compatibility nops */
6862                         break;
6863
6864                 case '?':
6865                         return -EINVAL;
6866
6867                 default:
6868                         assert_not_reached("Unhandled option");
6869                 }
6870
6871         if (arg_action == ACTION_REBOOT && (argc == optind || argc == optind + 1)) {
6872                 r = update_reboot_param_file(argc == optind + 1 ? argv[optind] : NULL);
6873                 if (r < 0)
6874                         return r;
6875         } else if (optind < argc) {
6876                 log_error("Too many arguments.");
6877                 return -EINVAL;
6878         }
6879
6880         return 1;
6881 }
6882
6883 static int parse_time_spec(const char *t, usec_t *_u) {
6884         assert(t);
6885         assert(_u);
6886
6887         if (streq(t, "now"))
6888                 *_u = 0;
6889         else if (!strchr(t, ':')) {
6890                 uint64_t u;
6891
6892                 if (safe_atou64(t, &u) < 0)
6893                         return -EINVAL;
6894
6895                 *_u = now(CLOCK_REALTIME) + USEC_PER_MINUTE * u;
6896         } else {
6897                 char *e = NULL;
6898                 long hour, minute;
6899                 struct tm tm = {};
6900                 time_t s;
6901                 usec_t n;
6902
6903                 errno = 0;
6904                 hour = strtol(t, &e, 10);
6905                 if (errno > 0 || *e != ':' || hour < 0 || hour > 23)
6906                         return -EINVAL;
6907
6908                 minute = strtol(e+1, &e, 10);
6909                 if (errno > 0 || *e != 0 || minute < 0 || minute > 59)
6910                         return -EINVAL;
6911
6912                 n = now(CLOCK_REALTIME);
6913                 s = (time_t) (n / USEC_PER_SEC);
6914
6915                 assert_se(localtime_r(&s, &tm));
6916
6917                 tm.tm_hour = (int) hour;
6918                 tm.tm_min = (int) minute;
6919                 tm.tm_sec = 0;
6920
6921                 assert_se(s = mktime(&tm));
6922
6923                 *_u = (usec_t) s * USEC_PER_SEC;
6924
6925                 while (*_u <= n)
6926                         *_u += USEC_PER_DAY;
6927         }
6928
6929         return 0;
6930 }
6931
6932 static int shutdown_parse_argv(int argc, char *argv[]) {
6933
6934         enum {
6935                 ARG_HELP = 0x100,
6936                 ARG_NO_WALL
6937         };
6938
6939         static const struct option options[] = {
6940                 { "help",      no_argument,       NULL, ARG_HELP    },
6941                 { "halt",      no_argument,       NULL, 'H'         },
6942                 { "poweroff",  no_argument,       NULL, 'P'         },
6943                 { "reboot",    no_argument,       NULL, 'r'         },
6944                 { "kexec",     no_argument,       NULL, 'K'         }, /* not documented extension */
6945                 { "no-wall",   no_argument,       NULL, ARG_NO_WALL },
6946                 {}
6947         };
6948
6949         int c, r;
6950
6951         assert(argc >= 0);
6952         assert(argv);
6953
6954         while ((c = getopt_long(argc, argv, "HPrhkt:afFc", options, NULL)) >= 0)
6955                 switch (c) {
6956
6957                 case ARG_HELP:
6958                         shutdown_help();
6959                         return 0;
6960
6961                 case 'H':
6962                         arg_action = ACTION_HALT;
6963                         break;
6964
6965                 case 'P':
6966                         arg_action = ACTION_POWEROFF;
6967                         break;
6968
6969                 case 'r':
6970                         if (kexec_loaded())
6971                                 arg_action = ACTION_KEXEC;
6972                         else
6973                                 arg_action = ACTION_REBOOT;
6974                         break;
6975
6976                 case 'K':
6977                         arg_action = ACTION_KEXEC;
6978                         break;
6979
6980                 case 'h':
6981                         if (arg_action != ACTION_HALT)
6982                                 arg_action = ACTION_POWEROFF;
6983                         break;
6984
6985                 case 'k':
6986                         arg_dry = true;
6987                         break;
6988
6989                 case ARG_NO_WALL:
6990                         arg_no_wall = true;
6991                         break;
6992
6993                 case 't':
6994                 case 'a':
6995                         /* Compatibility nops */
6996                         break;
6997
6998                 case 'c':
6999                         arg_action = ACTION_CANCEL_SHUTDOWN;
7000                         break;
7001
7002                 case '?':
7003                         return -EINVAL;
7004
7005                 default:
7006                         assert_not_reached("Unhandled option");
7007                 }
7008
7009         if (argc > optind && arg_action != ACTION_CANCEL_SHUTDOWN) {
7010                 r = parse_time_spec(argv[optind], &arg_when);
7011                 if (r < 0) {
7012                         log_error("Failed to parse time specification: %s", argv[optind]);
7013                         return r;
7014                 }
7015         } else
7016                 arg_when = now(CLOCK_REALTIME) + USEC_PER_MINUTE;
7017
7018         if (argc > optind && arg_action == ACTION_CANCEL_SHUTDOWN)
7019                 /* No time argument for shutdown cancel */
7020                 arg_wall = argv + optind;
7021         else if (argc > optind + 1)
7022                 /* We skip the time argument */
7023                 arg_wall = argv + optind + 1;
7024
7025         optind = argc;
7026
7027         return 1;
7028 }
7029
7030 static int telinit_parse_argv(int argc, char *argv[]) {
7031
7032         enum {
7033                 ARG_HELP = 0x100,
7034                 ARG_NO_WALL
7035         };
7036
7037         static const struct option options[] = {
7038                 { "help",      no_argument,       NULL, ARG_HELP    },
7039                 { "no-wall",   no_argument,       NULL, ARG_NO_WALL },
7040                 {}
7041         };
7042
7043         static const struct {
7044                 char from;
7045                 enum action to;
7046         } table[] = {
7047                 { '0', ACTION_POWEROFF },
7048                 { '6', ACTION_REBOOT },
7049                 { '1', ACTION_RESCUE },
7050                 { '2', ACTION_RUNLEVEL2 },
7051                 { '3', ACTION_RUNLEVEL3 },
7052                 { '4', ACTION_RUNLEVEL4 },
7053                 { '5', ACTION_RUNLEVEL5 },
7054                 { 's', ACTION_RESCUE },
7055                 { 'S', ACTION_RESCUE },
7056                 { 'q', ACTION_RELOAD },
7057                 { 'Q', ACTION_RELOAD },
7058                 { 'u', ACTION_REEXEC },
7059                 { 'U', ACTION_REEXEC }
7060         };
7061
7062         unsigned i;
7063         int c;
7064
7065         assert(argc >= 0);
7066         assert(argv);
7067
7068         while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0)
7069                 switch (c) {
7070
7071                 case ARG_HELP:
7072                         telinit_help();
7073                         return 0;
7074
7075                 case ARG_NO_WALL:
7076                         arg_no_wall = true;
7077                         break;
7078
7079                 case '?':
7080                         return -EINVAL;
7081
7082                 default:
7083                         assert_not_reached("Unhandled option");
7084                 }
7085
7086         if (optind >= argc) {
7087                 log_error("%s: required argument missing.",
7088                           program_invocation_short_name);
7089                 return -EINVAL;
7090         }
7091
7092         if (optind + 1 < argc) {
7093                 log_error("Too many arguments.");
7094                 return -EINVAL;
7095         }
7096
7097         if (strlen(argv[optind]) != 1) {
7098                 log_error("Expected single character argument.");
7099                 return -EINVAL;
7100         }
7101
7102         for (i = 0; i < ELEMENTSOF(table); i++)
7103                 if (table[i].from == argv[optind][0])
7104                         break;
7105
7106         if (i >= ELEMENTSOF(table)) {
7107                 log_error("Unknown command '%s'.", argv[optind]);
7108                 return -EINVAL;
7109         }
7110
7111         arg_action = table[i].to;
7112
7113         optind ++;
7114
7115         return 1;
7116 }
7117
7118 static int runlevel_parse_argv(int argc, char *argv[]) {
7119
7120         enum {
7121                 ARG_HELP = 0x100,
7122         };
7123
7124         static const struct option options[] = {
7125                 { "help",      no_argument,       NULL, ARG_HELP    },
7126                 {}
7127         };
7128
7129         int c;
7130
7131         assert(argc >= 0);
7132         assert(argv);
7133
7134         while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0)
7135                 switch (c) {
7136
7137                 case ARG_HELP:
7138                         runlevel_help();
7139                         return 0;
7140
7141                 case '?':
7142                         return -EINVAL;
7143
7144                 default:
7145                         assert_not_reached("Unhandled option");
7146                 }
7147
7148         if (optind < argc) {
7149                 log_error("Too many arguments.");
7150                 return -EINVAL;
7151         }
7152
7153         return 1;
7154 }
7155
7156 static int parse_argv(int argc, char *argv[]) {
7157         assert(argc >= 0);
7158         assert(argv);
7159
7160         if (program_invocation_short_name) {
7161
7162                 if (strstr(program_invocation_short_name, "halt")) {
7163                         arg_action = ACTION_HALT;
7164                         return halt_parse_argv(argc, argv);
7165                 } else if (strstr(program_invocation_short_name, "poweroff")) {
7166                         arg_action = ACTION_POWEROFF;
7167                         return halt_parse_argv(argc, argv);
7168                 } else if (strstr(program_invocation_short_name, "reboot")) {
7169                         if (kexec_loaded())
7170                                 arg_action = ACTION_KEXEC;
7171                         else
7172                                 arg_action = ACTION_REBOOT;
7173                         return halt_parse_argv(argc, argv);
7174                 } else if (strstr(program_invocation_short_name, "shutdown")) {
7175                         arg_action = ACTION_POWEROFF;
7176                         return shutdown_parse_argv(argc, argv);
7177                 } else if (strstr(program_invocation_short_name, "init")) {
7178
7179                         if (sd_booted() > 0) {
7180                                 arg_action = _ACTION_INVALID;
7181                                 return telinit_parse_argv(argc, argv);
7182                         } else {
7183                                 /* Hmm, so some other init system is
7184                                  * running, we need to forward this
7185                                  * request to it. For now we simply
7186                                  * guess that it is Upstart. */
7187
7188                                 execv(TELINIT, argv);
7189
7190                                 log_error("Couldn't find an alternative telinit implementation to spawn.");
7191                                 return -EIO;
7192                         }
7193
7194                 } else if (strstr(program_invocation_short_name, "runlevel")) {
7195                         arg_action = ACTION_RUNLEVEL;
7196                         return runlevel_parse_argv(argc, argv);
7197                 }
7198         }
7199
7200         arg_action = ACTION_SYSTEMCTL;
7201         return systemctl_parse_argv(argc, argv);
7202 }
7203
7204 _pure_ static int action_to_runlevel(void) {
7205
7206         static const char table[_ACTION_MAX] = {
7207                 [ACTION_HALT] =      '0',
7208                 [ACTION_POWEROFF] =  '0',
7209                 [ACTION_REBOOT] =    '6',
7210                 [ACTION_RUNLEVEL2] = '2',
7211                 [ACTION_RUNLEVEL3] = '3',
7212                 [ACTION_RUNLEVEL4] = '4',
7213                 [ACTION_RUNLEVEL5] = '5',
7214                 [ACTION_RESCUE] =    '1'
7215         };
7216
7217         assert(arg_action < _ACTION_MAX);
7218
7219         return table[arg_action];
7220 }
7221
7222 static int talk_initctl(void) {
7223
7224         struct init_request request = {
7225                 .magic = INIT_MAGIC,
7226                 .sleeptime  = 0,
7227                 .cmd = INIT_CMD_RUNLVL
7228         };
7229
7230         _cleanup_close_ int fd = -1;
7231         char rl;
7232         int r;
7233
7234         rl = action_to_runlevel();
7235         if (!rl)
7236                 return 0;
7237
7238         request.runlevel = rl;
7239
7240         fd = open(INIT_FIFO, O_WRONLY|O_NDELAY|O_CLOEXEC|O_NOCTTY);
7241         if (fd < 0) {
7242                 if (errno == ENOENT)
7243                         return 0;
7244
7245                 log_error_errno(errno, "Failed to open "INIT_FIFO": %m");
7246                 return -errno;
7247         }
7248
7249         r = loop_write(fd, &request, sizeof(request), false);
7250         if (r < 0)
7251                 return log_error_errno(r, "Failed to write to "INIT_FIFO": %m");
7252
7253         return 1;
7254 }
7255
7256 static int systemctl_main(sd_bus *bus, int argc, char *argv[], int bus_error) {
7257
7258         static const struct {
7259                 const char* verb;
7260                 const enum {
7261                         MORE,
7262                         LESS,
7263                         EQUAL
7264                 } argc_cmp;
7265                 const int argc;
7266                 int (* const dispatch)(sd_bus *bus, char **args);
7267                 const enum {
7268                         NOBUS = 1,
7269                         FORCE,
7270                 } bus;
7271         } verbs[] = {
7272                 { "list-units",            MORE,  0, list_units        },
7273                 { "list-unit-files",       MORE,  1, list_unit_files,  NOBUS },
7274                 { "list-sockets",          MORE,  1, list_sockets      },
7275                 { "list-timers",           MORE,  1, list_timers       },
7276                 { "list-jobs",             MORE,  1, list_jobs         },
7277                 { "list-machines",         MORE,  1, list_machines     },
7278                 { "clear-jobs",            EQUAL, 1, daemon_reload     },
7279                 { "cancel",                MORE,  2, cancel_job        },
7280                 { "start",                 MORE,  2, start_unit        },
7281                 { "stop",                  MORE,  2, start_unit        },
7282                 { "condstop",              MORE,  2, start_unit        }, /* For compatibility with ALTLinux */
7283                 { "reload",                MORE,  2, start_unit        },
7284                 { "restart",               MORE,  2, start_unit        },
7285                 { "try-restart",           MORE,  2, start_unit        },
7286                 { "reload-or-restart",     MORE,  2, start_unit        },
7287                 { "reload-or-try-restart", MORE,  2, start_unit        },
7288                 { "force-reload",          MORE,  2, start_unit        }, /* For compatibility with SysV */
7289                 { "condreload",            MORE,  2, start_unit        }, /* For compatibility with ALTLinux */
7290                 { "condrestart",           MORE,  2, start_unit        }, /* For compatibility with RH */
7291                 { "isolate",               EQUAL, 2, start_unit        },
7292                 { "kill",                  MORE,  2, kill_unit         },
7293                 { "is-active",             MORE,  2, check_unit_active },
7294                 { "check",                 MORE,  2, check_unit_active },
7295                 { "is-failed",             MORE,  2, check_unit_failed },
7296                 { "show",                  MORE,  1, show              },
7297                 { "cat",                   MORE,  2, cat               },
7298                 { "status",                MORE,  1, show              },
7299                 { "help",                  MORE,  2, show              },
7300                 { "snapshot",              LESS,  2, snapshot          },
7301                 { "delete",                MORE,  2, delete_snapshot   },
7302                 { "daemon-reload",         EQUAL, 1, daemon_reload     },
7303                 { "daemon-reexec",         EQUAL, 1, daemon_reload     },
7304                 { "show-environment",      EQUAL, 1, show_environment  },
7305                 { "set-environment",       MORE,  2, set_environment   },
7306                 { "unset-environment",     MORE,  2, set_environment   },
7307                 { "import-environment",    MORE,  1, import_environment},
7308                 { "halt",                  EQUAL, 1, start_special,    FORCE },
7309                 { "poweroff",              EQUAL, 1, start_special,    FORCE },
7310                 { "reboot",                EQUAL, 1, start_special,    FORCE },
7311                 { "kexec",                 EQUAL, 1, start_special     },
7312                 { "suspend",               EQUAL, 1, start_special     },
7313                 { "hibernate",             EQUAL, 1, start_special     },
7314                 { "hybrid-sleep",          EQUAL, 1, start_special     },
7315                 { "default",               EQUAL, 1, start_special     },
7316                 { "rescue",                EQUAL, 1, start_special     },
7317                 { "emergency",             EQUAL, 1, start_special     },
7318                 { "exit",                  EQUAL, 1, start_special     },
7319                 { "reset-failed",          MORE,  1, reset_failed      },
7320                 { "enable",                MORE,  2, enable_unit,      NOBUS },
7321                 { "disable",               MORE,  2, enable_unit,      NOBUS },
7322                 { "is-enabled",            MORE,  2, unit_is_enabled,  NOBUS },
7323                 { "reenable",              MORE,  2, enable_unit,      NOBUS },
7324                 { "preset",                MORE,  2, enable_unit,      NOBUS },
7325                 { "preset-all",            EQUAL, 1, preset_all,       NOBUS },
7326                 { "mask",                  MORE,  2, enable_unit,      NOBUS },
7327                 { "unmask",                MORE,  2, enable_unit,      NOBUS },
7328                 { "link",                  MORE,  2, enable_unit,      NOBUS },
7329                 { "switch-root",           MORE,  2, switch_root       },
7330                 { "list-dependencies",     LESS,  2, list_dependencies },
7331                 { "set-default",           EQUAL, 2, set_default,      NOBUS },
7332                 { "get-default",           EQUAL, 1, get_default,      NOBUS },
7333                 { "set-property",          MORE,  3, set_property      },
7334                 { "is-system-running",     EQUAL, 1, is_system_running },
7335                 { "add-wants",             MORE,  3, add_dependency,   NOBUS },
7336                 { "add-requires",          MORE,  3, add_dependency,   NOBUS },
7337                 { "edit",                  MORE,  2, edit,             NOBUS },
7338                 {}
7339         }, *verb = verbs;
7340
7341         int left;
7342
7343         assert(argc >= 0);
7344         assert(argv);
7345
7346         left = argc - optind;
7347
7348         /* Special rule: no arguments (left == 0) means "list-units" */
7349         if (left > 0) {
7350                 if (streq(argv[optind], "help") && !argv[optind+1]) {
7351                         log_error("This command expects one or more "
7352                                   "unit names. Did you mean --help?");
7353                         return -EINVAL;
7354                 }
7355
7356                 for (; verb->verb; verb++)
7357                         if (streq(argv[optind], verb->verb))
7358                                 goto found;
7359
7360                 log_error("Unknown operation '%s'.", argv[optind]);
7361                 return -EINVAL;
7362         }
7363 found:
7364
7365         switch (verb->argc_cmp) {
7366
7367         case EQUAL:
7368                 if (left != verb->argc) {
7369                         log_error("Invalid number of arguments.");
7370                         return -EINVAL;
7371                 }
7372
7373                 break;
7374
7375         case MORE:
7376                 if (left < verb->argc) {
7377                         log_error("Too few arguments.");
7378                         return -EINVAL;
7379                 }
7380
7381                 break;
7382
7383         case LESS:
7384                 if (left > verb->argc) {
7385                         log_error("Too many arguments.");
7386                         return -EINVAL;
7387                 }
7388
7389                 break;
7390
7391         default:
7392                 assert_not_reached("Unknown comparison operator.");
7393         }
7394
7395         /* Require a bus connection for all operations but
7396          * enable/disable */
7397         if (verb->bus == NOBUS) {
7398                 if (!bus && !avoid_bus()) {
7399                         log_error_errno(bus_error, "Failed to get D-Bus connection: %m");
7400                         return -EIO;
7401                 }
7402
7403         } else {
7404                 if (running_in_chroot() > 0) {
7405                         log_info("Running in chroot, ignoring request.");
7406                         return 0;
7407                 }
7408
7409                 if ((verb->bus != FORCE || arg_force <= 0) && !bus) {
7410                         log_error_errno(bus_error, "Failed to get D-Bus connection: %m");
7411                         return -EIO;
7412                 }
7413         }
7414
7415         return verb->dispatch(bus, argv + optind);
7416 }
7417
7418 static int send_shutdownd(usec_t t, char mode, bool dry_run, bool warn, const char *message) {
7419
7420         struct sd_shutdown_command c = {
7421                 .usec = t,
7422                 .mode = mode,
7423                 .dry_run = dry_run,
7424                 .warn_wall = warn,
7425         };
7426
7427         union sockaddr_union sockaddr = {
7428                 .un.sun_family = AF_UNIX,
7429                 .un.sun_path = "/run/systemd/shutdownd",
7430         };
7431
7432         struct iovec iovec[2] = {{
7433                  .iov_base = (char*) &c,
7434                  .iov_len = offsetof(struct sd_shutdown_command, wall_message),
7435         }};
7436
7437         struct msghdr msghdr = {
7438                 .msg_name = &sockaddr,
7439                 .msg_namelen = offsetof(struct sockaddr_un, sun_path)
7440                                + strlen("/run/systemd/shutdownd"),
7441                 .msg_iov = iovec,
7442                 .msg_iovlen = 1,
7443         };
7444
7445         _cleanup_close_ int fd;
7446
7447         fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
7448         if (fd < 0)
7449                 return -errno;
7450
7451         if (!isempty(message)) {
7452                 iovec[1].iov_base = (char*) message;
7453                 iovec[1].iov_len = strlen(message);
7454                 msghdr.msg_iovlen++;
7455         }
7456
7457         if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) < 0)
7458                 return -errno;
7459
7460         return 0;
7461 }
7462
7463 static int reload_with_fallback(sd_bus *bus) {
7464
7465         if (bus) {
7466                 /* First, try systemd via D-Bus. */
7467                 if (daemon_reload(bus, NULL) >= 0)
7468                         return 0;
7469         }
7470
7471         /* Nothing else worked, so let's try signals */
7472         assert(arg_action == ACTION_RELOAD || arg_action == ACTION_REEXEC);
7473
7474         if (kill(1, arg_action == ACTION_RELOAD ? SIGHUP : SIGTERM) < 0)
7475                 return log_error_errno(errno, "kill() failed: %m");
7476
7477         return 0;
7478 }
7479
7480 static int start_with_fallback(sd_bus *bus) {
7481
7482         if (bus) {
7483                 /* First, try systemd via D-Bus. */
7484                 if (start_unit(bus, NULL) >= 0)
7485                         goto done;
7486         }
7487
7488         /* Nothing else worked, so let's try
7489          * /dev/initctl */
7490         if (talk_initctl() > 0)
7491                 goto done;
7492
7493         log_error("Failed to talk to init daemon.");
7494         return -EIO;
7495
7496 done:
7497         warn_wall(arg_action);
7498         return 0;
7499 }
7500
7501 static int halt_now(enum action a) {
7502
7503         /* The kernel will automaticall flush ATA disks and suchlike
7504          * on reboot(), but the file systems need to be synce'd
7505          * explicitly in advance. */
7506         sync();
7507
7508         /* Make sure C-A-D is handled by the kernel from this point
7509          * on... */
7510         reboot(RB_ENABLE_CAD);
7511
7512         switch (a) {
7513
7514         case ACTION_HALT:
7515                 log_info("Halting.");
7516                 reboot(RB_HALT_SYSTEM);
7517                 return -errno;
7518
7519         case ACTION_POWEROFF:
7520                 log_info("Powering off.");
7521                 reboot(RB_POWER_OFF);
7522                 return -errno;
7523
7524         case ACTION_REBOOT: {
7525                 _cleanup_free_ char *param = NULL;
7526
7527                 if (read_one_line_file(REBOOT_PARAM_FILE, &param) >= 0) {
7528                         log_info("Rebooting with argument '%s'.", param);
7529                         syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
7530                                 LINUX_REBOOT_CMD_RESTART2, param);
7531                 }
7532
7533                 log_info("Rebooting.");
7534                 reboot(RB_AUTOBOOT);
7535                 return -errno;
7536         }
7537
7538         default:
7539                 assert_not_reached("Unknown action.");
7540         }
7541 }
7542
7543 static int halt_main(sd_bus *bus) {
7544         int r;
7545
7546         r = check_inhibitors(bus, arg_action);
7547         if (r < 0)
7548                 return r;
7549
7550         if (geteuid() != 0) {
7551                 /* Try logind if we are a normal user and no special
7552                  * mode applies. Maybe PolicyKit allows us to shutdown
7553                  * the machine. */
7554
7555                 if (arg_when <= 0 &&
7556                     !arg_dry &&
7557                     arg_force <= 0 &&
7558                     (arg_action == ACTION_POWEROFF ||
7559                      arg_action == ACTION_REBOOT)) {
7560                         r = reboot_with_logind(bus, arg_action);
7561                         if (r >= 0)
7562                                 return r;
7563                 }
7564
7565                 log_error("Must be root.");
7566                 return -EPERM;
7567         }
7568
7569         if (arg_when > 0) {
7570                 _cleanup_free_ char *m;
7571
7572                 m = strv_join(arg_wall, " ");
7573                 if (!m)
7574                         return log_oom();
7575
7576                 r = send_shutdownd(arg_when,
7577                                    arg_action == ACTION_HALT     ? 'H' :
7578                                    arg_action == ACTION_POWEROFF ? 'P' :
7579                                    arg_action == ACTION_KEXEC    ? 'K' :
7580                                                                    'r',
7581                                    arg_dry,
7582                                    !arg_no_wall,
7583                                    m);
7584
7585                 if (r < 0)
7586                         log_warning_errno(r, "Failed to talk to shutdownd, proceeding with immediate shutdown: %m");
7587                 else {
7588                         char date[FORMAT_TIMESTAMP_MAX];
7589
7590                         log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.",
7591                                  format_timestamp(date, sizeof(date), arg_when));
7592                         return 0;
7593                 }
7594         }
7595
7596         if (!arg_dry && !arg_force)
7597                 return start_with_fallback(bus);
7598
7599         if (!arg_no_wtmp) {
7600                 if (sd_booted() > 0)
7601                         log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
7602                 else {
7603                         r = utmp_put_shutdown();
7604                         if (r < 0)
7605                                 log_warning_errno(r, "Failed to write utmp record: %m");
7606                 }
7607         }
7608
7609         if (arg_dry)
7610                 return 0;
7611
7612         r = halt_now(arg_action);
7613         log_error_errno(r, "Failed to reboot: %m");
7614
7615         return r;
7616 }
7617
7618 static int runlevel_main(void) {
7619         int r, runlevel, previous;
7620
7621         r = utmp_get_runlevel(&runlevel, &previous);
7622         if (r < 0) {
7623                 puts("unknown");
7624                 return r;
7625         }
7626
7627         printf("%c %c\n",
7628                previous <= 0 ? 'N' : previous,
7629                runlevel <= 0 ? 'N' : runlevel);
7630
7631         return 0;
7632 }
7633
7634 int main(int argc, char*argv[]) {
7635         _cleanup_bus_close_unref_ sd_bus *bus = NULL;
7636         int r;
7637
7638         setlocale(LC_ALL, "");
7639         log_parse_environment();
7640         log_open();
7641
7642         /* Explicitly not on_tty() to avoid setting cached value.
7643          * This becomes relevant for piping output which might be
7644          * ellipsized. */
7645         original_stdout_is_tty = isatty(STDOUT_FILENO);
7646
7647         r = parse_argv(argc, argv);
7648         if (r <= 0)
7649                 goto finish;
7650
7651         /* /sbin/runlevel doesn't need to communicate via D-Bus, so
7652          * let's shortcut this */
7653         if (arg_action == ACTION_RUNLEVEL) {
7654                 r = runlevel_main();
7655                 goto finish;
7656         }
7657
7658         if (running_in_chroot() > 0 && arg_action != ACTION_SYSTEMCTL) {
7659                 log_info("Running in chroot, ignoring request.");
7660                 r = 0;
7661                 goto finish;
7662         }
7663
7664         if (!avoid_bus())
7665                 r = bus_open_transport_systemd(arg_transport, arg_host, arg_scope != UNIT_FILE_SYSTEM, &bus);
7666
7667         /* systemctl_main() will print an error message for the bus
7668          * connection, but only if it needs to */
7669
7670         switch (arg_action) {
7671
7672         case ACTION_SYSTEMCTL:
7673                 r = systemctl_main(bus, argc, argv, r);
7674                 break;
7675
7676         case ACTION_HALT:
7677         case ACTION_POWEROFF:
7678         case ACTION_REBOOT:
7679         case ACTION_KEXEC:
7680                 r = halt_main(bus);
7681                 break;
7682
7683         case ACTION_RUNLEVEL2:
7684         case ACTION_RUNLEVEL3:
7685         case ACTION_RUNLEVEL4:
7686         case ACTION_RUNLEVEL5:
7687         case ACTION_RESCUE:
7688         case ACTION_EMERGENCY:
7689         case ACTION_DEFAULT:
7690                 r = start_with_fallback(bus);
7691                 break;
7692
7693         case ACTION_RELOAD:
7694         case ACTION_REEXEC:
7695                 r = reload_with_fallback(bus);
7696                 break;
7697
7698         case ACTION_CANCEL_SHUTDOWN: {
7699                 _cleanup_free_ char *m = NULL;
7700
7701                 if (arg_wall) {
7702                         m = strv_join(arg_wall, " ");
7703                         if (!m) {
7704                                 r = log_oom();
7705                                 goto finish;
7706                         }
7707                 }
7708
7709                 r = send_shutdownd(arg_when, SD_SHUTDOWN_NONE, false, !arg_no_wall, m);
7710                 if (r < 0)
7711                         log_warning_errno(r, "Failed to talk to shutdownd, shutdown hasn't been cancelled: %m");
7712                 break;
7713         }
7714
7715         case ACTION_RUNLEVEL:
7716         case _ACTION_INVALID:
7717         default:
7718                 assert_not_reached("Unknown action");
7719         }
7720
7721 finish:
7722         pager_close();
7723         ask_password_agent_close();
7724         polkit_agent_close();
7725
7726         strv_free(arg_types);
7727         strv_free(arg_states);
7728         strv_free(arg_properties);
7729
7730         return r < 0 ? EXIT_FAILURE : r;
7731 }