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