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