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