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