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