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