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