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