chiark / gitweb /
systemctl: fix visual alignment for lines prefixed with color dots
[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].path, changes[i].source);
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.", path, source);
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         int status_errno;
3174
3175         usec_t start_timestamp;
3176         usec_t exit_timestamp;
3177
3178         int exit_code, exit_status;
3179
3180         usec_t condition_timestamp;
3181         bool condition_result;
3182         bool failed_condition_trigger;
3183         bool failed_condition_negate;
3184         const char *failed_condition;
3185         const char *failed_condition_param;
3186
3187         /* Socket */
3188         unsigned n_accepted;
3189         unsigned n_connections;
3190         bool accept;
3191
3192         /* Pairs of type, path */
3193         char **listen;
3194
3195         /* Device */
3196         const char *sysfs_path;
3197
3198         /* Mount, Automount */
3199         const char *where;
3200
3201         /* Swap */
3202         const char *what;
3203
3204         LIST_HEAD(ExecStatusInfo, exec);
3205 } UnitStatusInfo;
3206
3207 static void print_status_info(
3208                 UnitStatusInfo *i,
3209                 bool *ellipsized) {
3210
3211         ExecStatusInfo *p;
3212         const char *active_on, *active_off, *on, *off, *ss;
3213         usec_t timestamp;
3214         char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
3215         char since2[FORMAT_TIMESTAMP_MAX], *s2;
3216         const char *path;
3217         int flags =
3218                 arg_all * OUTPUT_SHOW_ALL |
3219                 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
3220                 on_tty() * OUTPUT_COLOR |
3221                 !arg_quiet * OUTPUT_WARN_CUTOFF |
3222                 arg_full * OUTPUT_FULL_WIDTH;
3223         char **t, **t2;
3224
3225         assert(i);
3226
3227         /* This shows pretty information about a unit. See
3228          * print_property() for a low-level property printer */
3229
3230         if (streq_ptr(i->active_state, "failed")) {
3231                 active_on = ansi_highlight_red();
3232                 active_off = ansi_highlight_off();
3233         } else if (streq_ptr(i->active_state, "active") || streq_ptr(i->active_state, "reloading")) {
3234                 active_on = ansi_highlight_green();
3235                 active_off = ansi_highlight_off();
3236         } else
3237                 active_on = active_off = "";
3238
3239         printf("%s%s%s %s", active_on, draw_special_char(DRAW_BLACK_CIRCLE), active_off, strna(i->id));
3240
3241         if (i->description && !streq_ptr(i->id, i->description))
3242                 printf(" - %s", i->description);
3243
3244         printf("\n");
3245
3246         if (i->following)
3247                 printf("   Follow: unit currently follows state of %s\n", i->following);
3248
3249         if (streq_ptr(i->load_state, "error")) {
3250                 on = ansi_highlight_red();
3251                 off = ansi_highlight_off();
3252         } else
3253                 on = off = "";
3254
3255         path = i->source_path ? i->source_path : i->fragment_path;
3256
3257         if (i->load_error)
3258                 printf("   Loaded: %s%s%s (Reason: %s)\n",
3259                        on, strna(i->load_state), off, i->load_error);
3260         else if (path && i->unit_file_state)
3261                 printf("   Loaded: %s%s%s (%s; %s)\n",
3262                        on, strna(i->load_state), off, path, i->unit_file_state);
3263         else if (path)
3264                 printf("   Loaded: %s%s%s (%s)\n",
3265                        on, strna(i->load_state), off, path);
3266         else
3267                 printf("   Loaded: %s%s%s\n",
3268                        on, strna(i->load_state), off);
3269
3270         if (!strv_isempty(i->dropin_paths)) {
3271                 _cleanup_free_ char *dir = NULL;
3272                 bool last = false;
3273                 char ** dropin;
3274
3275                 STRV_FOREACH(dropin, i->dropin_paths) {
3276                         if (! dir || last) {
3277                                 printf(dir ? "        " : "  Drop-In: ");
3278
3279                                 free(dir);
3280                                 dir = NULL;
3281
3282                                 if (path_get_parent(*dropin, &dir) < 0) {
3283                                         log_oom();
3284                                         return;
3285                                 }
3286
3287                                 printf("%s\n           %s", dir,
3288                                        draw_special_char(DRAW_TREE_RIGHT));
3289                         }
3290
3291                         last = ! (*(dropin + 1) && startswith(*(dropin + 1), dir));
3292
3293                         printf("%s%s", basename(*dropin), last ? "\n" : ", ");
3294                 }
3295         }
3296
3297         ss = streq_ptr(i->active_state, i->sub_state) ? NULL : i->sub_state;
3298         if (ss)
3299                 printf("   Active: %s%s (%s)%s",
3300                        active_on, strna(i->active_state), ss, active_off);
3301         else
3302                 printf("   Active: %s%s%s",
3303                        active_on, strna(i->active_state), active_off);
3304
3305         if (!isempty(i->result) && !streq(i->result, "success"))
3306                 printf(" (Result: %s)", i->result);
3307
3308         timestamp = (streq_ptr(i->active_state, "active")      ||
3309                      streq_ptr(i->active_state, "reloading"))   ? i->active_enter_timestamp :
3310                     (streq_ptr(i->active_state, "inactive")    ||
3311                      streq_ptr(i->active_state, "failed"))      ? i->inactive_enter_timestamp :
3312                     streq_ptr(i->active_state, "activating")    ? i->inactive_exit_timestamp :
3313                                                                   i->active_exit_timestamp;
3314
3315         s1 = format_timestamp_relative(since1, sizeof(since1), timestamp);
3316         s2 = format_timestamp(since2, sizeof(since2), timestamp);
3317
3318         if (s1)
3319                 printf(" since %s; %s\n", s2, s1);
3320         else if (s2)
3321                 printf(" since %s\n", s2);
3322         else
3323                 printf("\n");
3324
3325         if (!i->condition_result && i->condition_timestamp > 0) {
3326                 s1 = format_timestamp_relative(since1, sizeof(since1), i->condition_timestamp);
3327                 s2 = format_timestamp(since2, sizeof(since2), i->condition_timestamp);
3328
3329                 printf("           start condition failed at %s%s%s\n",
3330                        s2, s1 ? "; " : "", s1 ? s1 : "");
3331                 if (i->failed_condition_trigger)
3332                         printf("           none of the trigger conditions were met\n");
3333                 else if (i->failed_condition)
3334                         printf("           %s=%s%s was not met\n",
3335                                i->failed_condition,
3336                                i->failed_condition_negate ? "!" : "",
3337                                i->failed_condition_param);
3338         }
3339
3340         if (i->sysfs_path)
3341                 printf("   Device: %s\n", i->sysfs_path);
3342         if (i->where)
3343                 printf("    Where: %s\n", i->where);
3344         if (i->what)
3345                 printf("     What: %s\n", i->what);
3346
3347         STRV_FOREACH(t, i->documentation)
3348                 printf(" %*s %s\n", 9, t == i->documentation ? "Docs:" : "", *t);
3349
3350         STRV_FOREACH_PAIR(t, t2, i->listen)
3351                 printf(" %*s %s (%s)\n", 9, t == i->listen ? "Listen:" : "", *t2, *t);
3352
3353         if (i->accept)
3354                 printf(" Accepted: %u; Connected: %u\n", i->n_accepted, i->n_connections);
3355
3356         LIST_FOREACH(exec, p, i->exec) {
3357                 _cleanup_free_ char *argv = NULL;
3358                 bool good;
3359
3360                 /* Only show exited processes here */
3361                 if (p->code == 0)
3362                         continue;
3363
3364                 argv = strv_join(p->argv, " ");
3365                 printf("  Process: %u %s=%s ", p->pid, p->name, strna(argv));
3366
3367                 good = is_clean_exit_lsb(p->code, p->status, NULL);
3368                 if (!good) {
3369                         on = ansi_highlight_red();
3370                         off = ansi_highlight_off();
3371                 } else
3372                         on = off = "";
3373
3374                 printf("%s(code=%s, ", on, sigchld_code_to_string(p->code));
3375
3376                 if (p->code == CLD_EXITED) {
3377                         const char *c;
3378
3379                         printf("status=%i", p->status);
3380
3381                         c = exit_status_to_string(p->status, EXIT_STATUS_SYSTEMD);
3382                         if (c)
3383                                 printf("/%s", c);
3384
3385                 } else
3386                         printf("signal=%s", signal_to_string(p->status));
3387
3388                 printf(")%s\n", off);
3389
3390                 if (i->main_pid == p->pid &&
3391                     i->start_timestamp == p->start_timestamp &&
3392                     i->exit_timestamp == p->start_timestamp)
3393                         /* Let's not show this twice */
3394                         i->main_pid = 0;
3395
3396                 if (p->pid == i->control_pid)
3397                         i->control_pid = 0;
3398         }
3399
3400         if (i->main_pid > 0 || i->control_pid > 0) {
3401                 if (i->main_pid > 0) {
3402                         printf(" Main PID: %u", (unsigned) i->main_pid);
3403
3404                         if (i->running) {
3405                                 _cleanup_free_ char *comm = NULL;
3406                                 get_process_comm(i->main_pid, &comm);
3407                                 if (comm)
3408                                         printf(" (%s)", comm);
3409                         } else if (i->exit_code > 0) {
3410                                 printf(" (code=%s, ", sigchld_code_to_string(i->exit_code));
3411
3412                                 if (i->exit_code == CLD_EXITED) {
3413                                         const char *c;
3414
3415                                         printf("status=%i", i->exit_status);
3416
3417                                         c = exit_status_to_string(i->exit_status, EXIT_STATUS_SYSTEMD);
3418                                         if (c)
3419                                                 printf("/%s", c);
3420
3421                                 } else
3422                                         printf("signal=%s", signal_to_string(i->exit_status));
3423                                 printf(")");
3424                         }
3425
3426                         if (i->control_pid > 0)
3427                                 printf(";");
3428                 }
3429
3430                 if (i->control_pid > 0) {
3431                         _cleanup_free_ char *c = NULL;
3432
3433                         printf(" %8s: %u", i->main_pid ? "" : " Control", (unsigned) i->control_pid);
3434
3435                         get_process_comm(i->control_pid, &c);
3436                         if (c)
3437                                 printf(" (%s)", c);
3438                 }
3439
3440                 printf("\n");
3441         }
3442
3443         if (i->status_text)
3444                 printf("   Status: \"%s\"\n", i->status_text);
3445         if (i->status_errno > 0)
3446                 printf("    Error: %i (%s)\n", i->status_errno, strerror(i->status_errno));
3447
3448         if (i->control_group &&
3449             (i->main_pid > 0 || i->control_pid > 0 ||
3450              ((arg_transport != BUS_TRANSPORT_LOCAL && arg_transport != BUS_TRANSPORT_CONTAINER) || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, i->control_group, false) == 0))) {
3451                 unsigned c;
3452
3453                 printf("   CGroup: %s\n", i->control_group);
3454
3455                 if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_CONTAINER) {
3456                         unsigned k = 0;
3457                         pid_t extra[2];
3458                         static const char prefix[] = "           ";
3459
3460                         c = columns();
3461                         if (c > sizeof(prefix) - 1)
3462                                 c -= sizeof(prefix) - 1;
3463                         else
3464                                 c = 0;
3465
3466                         if (i->main_pid > 0)
3467                                 extra[k++] = i->main_pid;
3468
3469                         if (i->control_pid > 0)
3470                                 extra[k++] = i->control_pid;
3471
3472                         show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, i->control_group, prefix, c, false, extra, k, flags);
3473                 }
3474         }
3475
3476         if (i->id && arg_transport == BUS_TRANSPORT_LOCAL) {
3477                 show_journal_by_unit(stdout,
3478                                      i->id,
3479                                      arg_output,
3480                                      0,
3481                                      i->inactive_exit_timestamp_monotonic,
3482                                      arg_lines,
3483                                      getuid(),
3484                                      flags | OUTPUT_BEGIN_NEWLINE,
3485                                      arg_scope == UNIT_FILE_SYSTEM,
3486                                      ellipsized);
3487         }
3488
3489         if (i->need_daemon_reload)
3490                 printf("\n%sWarning:%s Unit file changed on disk, 'systemctl %sdaemon-reload' recommended.\n",
3491                        ansi_highlight_red(),
3492                        ansi_highlight_off(),
3493                        arg_scope == UNIT_FILE_SYSTEM ? "" : "--user ");
3494 }
3495
3496 static void show_unit_help(UnitStatusInfo *i) {
3497         char **p;
3498
3499         assert(i);
3500
3501         if (!i->documentation) {
3502                 log_info("Documentation for %s not known.", i->id);
3503                 return;
3504         }
3505
3506         STRV_FOREACH(p, i->documentation) {
3507
3508                 if (startswith(*p, "man:")) {
3509                         const char *args[4] = { "man", NULL, NULL, NULL };
3510                         _cleanup_free_ char *page = NULL, *section = NULL;
3511                         char *e = NULL;
3512                         pid_t pid;
3513                         size_t k;
3514
3515                         k = strlen(*p);
3516
3517                         if ((*p)[k-1] == ')')
3518                                 e = strrchr(*p, '(');
3519
3520                         if (e) {
3521                                 page = strndup((*p) + 4, e - *p - 4);
3522                                 section = strndup(e + 1, *p + k - e - 2);
3523                                 if (!page || !section) {
3524                                         log_oom();
3525                                         return;
3526                                 }
3527
3528                                 args[1] = section;
3529                                 args[2] = page;
3530                         } else
3531                                 args[1] = *p + 4;
3532
3533                         pid = fork();
3534                         if (pid < 0) {
3535                                 log_error("Failed to fork: %m");
3536                                 continue;
3537                         }
3538
3539                         if (pid == 0) {
3540                                 /* Child */
3541                                 execvp(args[0], (char**) args);
3542                                 log_error("Failed to execute man: %m");
3543                                 _exit(EXIT_FAILURE);
3544                         }
3545
3546                         wait_for_terminate(pid, NULL);
3547                 } else
3548                         log_info("Can't show: %s", *p);
3549         }
3550 }
3551
3552 static int status_property(const char *name, sd_bus_message *m, UnitStatusInfo *i, const char *contents) {
3553         int r;
3554
3555         assert(name);
3556         assert(m);
3557         assert(i);
3558
3559         switch (contents[0]) {
3560
3561         case SD_BUS_TYPE_STRING: {
3562                 const char *s;
3563
3564                 r = sd_bus_message_read(m, "s", &s);
3565                 if (r < 0)
3566                         return bus_log_parse_error(r);
3567
3568                 if (!isempty(s)) {
3569                         if (streq(name, "Id"))
3570                                 i->id = s;
3571                         else if (streq(name, "LoadState"))
3572                                 i->load_state = s;
3573                         else if (streq(name, "ActiveState"))
3574                                 i->active_state = s;
3575                         else if (streq(name, "SubState"))
3576                                 i->sub_state = s;
3577                         else if (streq(name, "Description"))
3578                                 i->description = s;
3579                         else if (streq(name, "FragmentPath"))
3580                                 i->fragment_path = s;
3581                         else if (streq(name, "SourcePath"))
3582                                 i->source_path = s;
3583 #ifndef NOLEGACY
3584                         else if (streq(name, "DefaultControlGroup")) {
3585                                 const char *e;
3586                                 e = startswith(s, SYSTEMD_CGROUP_CONTROLLER ":");
3587                                 if (e)
3588                                         i->control_group = e;
3589                         }
3590 #endif
3591                         else if (streq(name, "ControlGroup"))
3592                                 i->control_group = s;
3593                         else if (streq(name, "StatusText"))
3594                                 i->status_text = s;
3595                         else if (streq(name, "PIDFile"))
3596                                 i->pid_file = s;
3597                         else if (streq(name, "SysFSPath"))
3598                                 i->sysfs_path = s;
3599                         else if (streq(name, "Where"))
3600                                 i->where = s;
3601                         else if (streq(name, "What"))
3602                                 i->what = s;
3603                         else if (streq(name, "Following"))
3604                                 i->following = s;
3605                         else if (streq(name, "UnitFileState"))
3606                                 i->unit_file_state = s;
3607                         else if (streq(name, "Result"))
3608                                 i->result = s;
3609                 }
3610
3611                 break;
3612         }
3613
3614         case SD_BUS_TYPE_BOOLEAN: {
3615                 int b;
3616
3617                 r = sd_bus_message_read(m, "b", &b);
3618                 if (r < 0)
3619                         return bus_log_parse_error(r);
3620
3621                 if (streq(name, "Accept"))
3622                         i->accept = b;
3623                 else if (streq(name, "NeedDaemonReload"))
3624                         i->need_daemon_reload = b;
3625                 else if (streq(name, "ConditionResult"))
3626                         i->condition_result = b;
3627
3628                 break;
3629         }
3630
3631         case SD_BUS_TYPE_UINT32: {
3632                 uint32_t u;
3633
3634                 r = sd_bus_message_read(m, "u", &u);
3635                 if (r < 0)
3636                         return bus_log_parse_error(r);
3637
3638                 if (streq(name, "MainPID")) {
3639                         if (u > 0) {
3640                                 i->main_pid = (pid_t) u;
3641                                 i->running = true;
3642                         }
3643                 } else if (streq(name, "ControlPID"))
3644                         i->control_pid = (pid_t) u;
3645                 else if (streq(name, "ExecMainPID")) {
3646                         if (u > 0)
3647                                 i->main_pid = (pid_t) u;
3648                 } else if (streq(name, "NAccepted"))
3649                         i->n_accepted = u;
3650                 else if (streq(name, "NConnections"))
3651                         i->n_connections = u;
3652
3653                 break;
3654         }
3655
3656         case SD_BUS_TYPE_INT32: {
3657                 int32_t j;
3658
3659                 r = sd_bus_message_read(m, "i", &j);
3660                 if (r < 0)
3661                         return bus_log_parse_error(r);
3662
3663                 if (streq(name, "ExecMainCode"))
3664                         i->exit_code = (int) j;
3665                 else if (streq(name, "ExecMainStatus"))
3666                         i->exit_status = (int) j;
3667                 else if (streq(name, "StatusErrno"))
3668                         i->status_errno = (int) j;
3669
3670                 break;
3671         }
3672
3673         case SD_BUS_TYPE_UINT64: {
3674                 uint64_t u;
3675
3676                 r = sd_bus_message_read(m, "t", &u);
3677                 if (r < 0)
3678                         return bus_log_parse_error(r);
3679
3680                 if (streq(name, "ExecMainStartTimestamp"))
3681                         i->start_timestamp = (usec_t) u;
3682                 else if (streq(name, "ExecMainExitTimestamp"))
3683                         i->exit_timestamp = (usec_t) u;
3684                 else if (streq(name, "ActiveEnterTimestamp"))
3685                         i->active_enter_timestamp = (usec_t) u;
3686                 else if (streq(name, "InactiveEnterTimestamp"))
3687                         i->inactive_enter_timestamp = (usec_t) u;
3688                 else if (streq(name, "InactiveExitTimestamp"))
3689                         i->inactive_exit_timestamp = (usec_t) u;
3690                 else if (streq(name, "InactiveExitTimestampMonotonic"))
3691                         i->inactive_exit_timestamp_monotonic = (usec_t) u;
3692                 else if (streq(name, "ActiveExitTimestamp"))
3693                         i->active_exit_timestamp = (usec_t) u;
3694                 else if (streq(name, "ConditionTimestamp"))
3695                         i->condition_timestamp = (usec_t) u;
3696
3697                 break;
3698         }
3699
3700         case SD_BUS_TYPE_ARRAY:
3701
3702                 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3703                         _cleanup_free_ ExecStatusInfo *info = NULL;
3704
3705                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3706                         if (r < 0)
3707                                 return bus_log_parse_error(r);
3708
3709                         info = new0(ExecStatusInfo, 1);
3710                         if (!info)
3711                                 return log_oom();
3712
3713                         while ((r = exec_status_info_deserialize(m, info)) > 0) {
3714
3715                                 info->name = strdup(name);
3716                                 if (!info->name)
3717                                         log_oom();
3718
3719                                 LIST_PREPEND(exec, i->exec, info);
3720
3721                                 info = new0(ExecStatusInfo, 1);
3722                                 if (!info)
3723                                         log_oom();
3724                         }
3725
3726                         if (r < 0)
3727                                 return bus_log_parse_error(r);
3728
3729                         r = sd_bus_message_exit_container(m);
3730                         if (r < 0)
3731                                 return bus_log_parse_error(r);
3732
3733                         return 0;
3734
3735                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3736                         const char *type, *path;
3737
3738                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3739                         if (r < 0)
3740                                 return bus_log_parse_error(r);
3741
3742                         while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0) {
3743
3744                                 r = strv_extend(&i->listen, type);
3745                                 if (r < 0)
3746                                         return r;
3747
3748                                 r = strv_extend(&i->listen, path);
3749                                 if (r < 0)
3750                                         return r;
3751                         }
3752                         if (r < 0)
3753                                 return bus_log_parse_error(r);
3754
3755                         r = sd_bus_message_exit_container(m);
3756                         if (r < 0)
3757                                 return bus_log_parse_error(r);
3758
3759                         return 0;
3760
3761                 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "DropInPaths")) {
3762
3763                         r = sd_bus_message_read_strv(m, &i->dropin_paths);
3764                         if (r < 0)
3765                                 return bus_log_parse_error(r);
3766
3767                 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Documentation")) {
3768
3769                         r = sd_bus_message_read_strv(m, &i->documentation);
3770                         if (r < 0)
3771                                 return bus_log_parse_error(r);
3772
3773                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Conditions")) {
3774                         const char *cond, *param;
3775                         int trigger, negate;
3776                         int32_t state;
3777
3778                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
3779                         if (r < 0)
3780                                 return bus_log_parse_error(r);
3781
3782                         while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, &param, &state)) > 0) {
3783                                 log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
3784                                 if (state < 0 && (!trigger || !i->failed_condition)) {
3785                                         i->failed_condition = cond;
3786                                         i->failed_condition_trigger = trigger;
3787                                         i->failed_condition_negate = negate;
3788                                         i->failed_condition_param = param;
3789                                 }
3790                         }
3791                         if (r < 0)
3792                                 return bus_log_parse_error(r);
3793
3794                         r = sd_bus_message_exit_container(m);
3795                         if (r < 0)
3796                                 return bus_log_parse_error(r);
3797
3798                 } else
3799                         goto skip;
3800
3801                 break;
3802
3803         case SD_BUS_TYPE_STRUCT_BEGIN:
3804
3805                 if (streq(name, "LoadError")) {
3806                         const char *n, *message;
3807
3808                         r = sd_bus_message_read(m, "(ss)", &n, &message);
3809                         if (r < 0)
3810                                 return bus_log_parse_error(r);
3811
3812                         if (!isempty(message))
3813                                 i->load_error = message;
3814                 } else
3815                         goto skip;
3816
3817                 break;
3818
3819         default:
3820                 goto skip;
3821         }
3822
3823         return 0;
3824
3825 skip:
3826         r = sd_bus_message_skip(m, contents);
3827         if (r < 0)
3828                 return bus_log_parse_error(r);
3829
3830         return 0;
3831 }
3832
3833 static int print_property(const char *name, sd_bus_message *m, const char *contents) {
3834         int r;
3835
3836         assert(name);
3837         assert(m);
3838
3839         /* This is a low-level property printer, see
3840          * print_status_info() for the nicer output */
3841
3842         if (arg_properties && !strv_find(arg_properties, name)) {
3843                 /* skip what we didn't read */
3844                 r = sd_bus_message_skip(m, contents);
3845                 return r;
3846         }
3847
3848         switch (contents[0]) {
3849
3850         case SD_BUS_TYPE_STRUCT_BEGIN:
3851
3852                 if (contents[1] == SD_BUS_TYPE_UINT32 && streq(name, "Job")) {
3853                         uint32_t u;
3854
3855                         r = sd_bus_message_read(m, "(uo)", &u, NULL);
3856                         if (r < 0)
3857                                 return bus_log_parse_error(r);
3858
3859                         if (u > 0)
3860                                 printf("%s=%u\n", name, (unsigned) u);
3861                         else if (arg_all)
3862                                 printf("%s=\n", name);
3863
3864                         return 0;
3865
3866                 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Unit")) {
3867                         const char *s;
3868
3869                         r = sd_bus_message_read(m, "(so)", &s, NULL);
3870                         if (r < 0)
3871                                 return bus_log_parse_error(r);
3872
3873                         if (arg_all || !isempty(s))
3874                                 printf("%s=%s\n", name, s);
3875
3876                         return 0;
3877
3878                 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "LoadError")) {
3879                         const char *a = NULL, *b = NULL;
3880
3881                         r = sd_bus_message_read(m, "(ss)", &a, &b);
3882                         if (r < 0)
3883                                 return bus_log_parse_error(r);
3884
3885                         if (arg_all || !isempty(a) || !isempty(b))
3886                                 printf("%s=%s \"%s\"\n", name, strempty(a), strempty(b));
3887
3888                         return 0;
3889                 } else if (streq_ptr(name, "SystemCallFilter")) {
3890                         _cleanup_strv_free_ char **l = NULL;
3891                         int whitelist;
3892
3893                         r = sd_bus_message_enter_container(m, 'r', "bas");
3894                         if (r < 0)
3895                                 return bus_log_parse_error(r);
3896
3897                         r = sd_bus_message_read(m, "b", &whitelist);
3898                         if (r < 0)
3899                                 return bus_log_parse_error(r);
3900
3901                         r = sd_bus_message_read_strv(m, &l);
3902                         if (r < 0)
3903                                 return bus_log_parse_error(r);
3904
3905                         r = sd_bus_message_exit_container(m);
3906                         if (r < 0)
3907                                 return bus_log_parse_error(r);
3908
3909                         if (arg_all || whitelist || !strv_isempty(l)) {
3910                                 bool first = true;
3911                                 char **i;
3912
3913                                 fputs(name, stdout);
3914                                 fputc('=', stdout);
3915
3916                                 if (!whitelist)
3917                                         fputc('~', stdout);
3918
3919                                 STRV_FOREACH(i, l) {
3920                                         if (first)
3921                                                 first = false;
3922                                         else
3923                                                 fputc(' ', stdout);
3924
3925                                         fputs(*i, stdout);
3926                                 }
3927                                 fputc('\n', stdout);
3928                         }
3929
3930                         return 0;
3931                 }
3932
3933                 break;
3934
3935         case SD_BUS_TYPE_ARRAY:
3936
3937                 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "EnvironmentFiles")) {
3938                         const char *path;
3939                         int ignore;
3940
3941                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sb)");
3942                         if (r < 0)
3943                                 return bus_log_parse_error(r);
3944
3945                         while ((r = sd_bus_message_read(m, "(sb)", &path, &ignore)) > 0)
3946                                 printf("EnvironmentFile=%s (ignore_errors=%s)\n", path, yes_no(ignore));
3947
3948                         if (r < 0)
3949                                 return bus_log_parse_error(r);
3950
3951                         r = sd_bus_message_exit_container(m);
3952                         if (r < 0)
3953                                 return bus_log_parse_error(r);
3954
3955                         return 0;
3956
3957                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Paths")) {
3958                         const char *type, *path;
3959
3960                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3961                         if (r < 0)
3962                                 return bus_log_parse_error(r);
3963
3964                         while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
3965                                 printf("%s=%s\n", type, path);
3966                         if (r < 0)
3967                                 return bus_log_parse_error(r);
3968
3969                         r = sd_bus_message_exit_container(m);
3970                         if (r < 0)
3971                                 return bus_log_parse_error(r);
3972
3973                         return 0;
3974
3975                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3976                         const char *type, *path;
3977
3978                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3979                         if (r < 0)
3980                                 return bus_log_parse_error(r);
3981
3982                         while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
3983                                 printf("Listen%s=%s\n", type, path);
3984                         if (r < 0)
3985                                 return bus_log_parse_error(r);
3986
3987                         r = sd_bus_message_exit_container(m);
3988                         if (r < 0)
3989                                 return bus_log_parse_error(r);
3990
3991                         return 0;
3992
3993                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Timers")) {
3994                         const char *base;
3995                         uint64_t value, next_elapse;
3996
3997                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(stt)");
3998                         if (r < 0)
3999                                 return bus_log_parse_error(r);
4000
4001                         while ((r = sd_bus_message_read(m, "(stt)", &base, &value, &next_elapse)) > 0) {
4002                                 char timespan1[FORMAT_TIMESPAN_MAX], timespan2[FORMAT_TIMESPAN_MAX];
4003
4004                                 printf("%s={ value=%s ; next_elapse=%s }\n",
4005                                        base,
4006                                        format_timespan(timespan1, sizeof(timespan1), value, 0),
4007                                        format_timespan(timespan2, sizeof(timespan2), next_elapse, 0));
4008                         }
4009                         if (r < 0)
4010                                 return bus_log_parse_error(r);
4011
4012                         r = sd_bus_message_exit_container(m);
4013                         if (r < 0)
4014                                 return bus_log_parse_error(r);
4015
4016                         return 0;
4017
4018                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
4019                         ExecStatusInfo info = {};
4020
4021                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
4022                         if (r < 0)
4023                                 return bus_log_parse_error(r);
4024
4025                         while ((r = exec_status_info_deserialize(m, &info)) > 0) {
4026                                 char timestamp1[FORMAT_TIMESTAMP_MAX], timestamp2[FORMAT_TIMESTAMP_MAX];
4027                                 _cleanup_free_ char *tt;
4028
4029                                 tt = strv_join(info.argv, " ");
4030
4031                                 printf("%s={ path=%s ; argv[]=%s ; ignore_errors=%s ; start_time=[%s] ; stop_time=[%s] ; pid=%u ; code=%s ; status=%i%s%s }\n",
4032                                        name,
4033                                        strna(info.path),
4034                                        strna(tt),
4035                                        yes_no(info.ignore),
4036                                        strna(format_timestamp(timestamp1, sizeof(timestamp1), info.start_timestamp)),
4037                                        strna(format_timestamp(timestamp2, sizeof(timestamp2), info.exit_timestamp)),
4038                                        (unsigned) info. pid,
4039                                        sigchld_code_to_string(info.code),
4040                                        info.status,
4041                                        info.code == CLD_EXITED ? "" : "/",
4042                                        strempty(info.code == CLD_EXITED ? NULL : signal_to_string(info.status)));
4043
4044                                 free(info.path);
4045                                 strv_free(info.argv);
4046                                 zero(info);
4047                         }
4048
4049                         r = sd_bus_message_exit_container(m);
4050                         if (r < 0)
4051                                 return bus_log_parse_error(r);
4052
4053                         return 0;
4054
4055                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "DeviceAllow")) {
4056                         const char *path, *rwm;
4057
4058                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
4059                         if (r < 0)
4060                                 return bus_log_parse_error(r);
4061
4062                         while ((r = sd_bus_message_read(m, "(ss)", &path, &rwm)) > 0)
4063                                 printf("%s=%s %s\n", name, strna(path), strna(rwm));
4064                         if (r < 0)
4065                                 return bus_log_parse_error(r);
4066
4067                         r = sd_bus_message_exit_container(m);
4068                         if (r < 0)
4069                                 return bus_log_parse_error(r);
4070
4071                         return 0;
4072
4073                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "BlockIODeviceWeight")) {
4074                         const char *path;
4075                         uint64_t weight;
4076
4077                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
4078                         if (r < 0)
4079                                 return bus_log_parse_error(r);
4080
4081                         while ((r = sd_bus_message_read(m, "(st)", &path, &weight)) > 0)
4082                                 printf("%s=%s %" PRIu64 "\n", name, strna(path), weight);
4083                         if (r < 0)
4084                                 return bus_log_parse_error(r);
4085
4086                         r = sd_bus_message_exit_container(m);
4087                         if (r < 0)
4088                                 return bus_log_parse_error(r);
4089
4090                         return 0;
4091
4092                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && (streq(name, "BlockIOReadBandwidth") || streq(name, "BlockIOWriteBandwidth"))) {
4093                         const char *path;
4094                         uint64_t bandwidth;
4095
4096                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
4097                         if (r < 0)
4098                                 return bus_log_parse_error(r);
4099
4100                         while ((r = sd_bus_message_read(m, "(st)", &path, &bandwidth)) > 0)
4101                                 printf("%s=%s %" PRIu64 "\n", name, strna(path), bandwidth);
4102                         if (r < 0)
4103                                 return bus_log_parse_error(r);
4104
4105                         r = sd_bus_message_exit_container(m);
4106                         if (r < 0)
4107                                 return bus_log_parse_error(r);
4108
4109                         return 0;
4110                 }
4111
4112                 break;
4113         }
4114
4115         r = bus_print_property(name, m, arg_all);
4116         if (r < 0)
4117                 return bus_log_parse_error(r);
4118
4119         if (r == 0) {
4120                 r = sd_bus_message_skip(m, contents);
4121                 if (r < 0)
4122                         return bus_log_parse_error(r);
4123
4124                 if (arg_all)
4125                         printf("%s=[unprintable]\n", name);
4126         }
4127
4128         return 0;
4129 }
4130
4131 static int show_one(
4132                 const char *verb,
4133                 sd_bus *bus,
4134                 const char *path,
4135                 bool show_properties,
4136                 bool *new_line,
4137                 bool *ellipsized) {
4138
4139         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4140         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4141         UnitStatusInfo info = {};
4142         ExecStatusInfo *p;
4143         int r;
4144
4145         assert(path);
4146         assert(new_line);
4147
4148         log_debug("Showing one %s", path);
4149
4150         r = sd_bus_call_method(
4151                         bus,
4152                         "org.freedesktop.systemd1",
4153                         path,
4154                         "org.freedesktop.DBus.Properties",
4155                         "GetAll",
4156                         &error,
4157                         &reply,
4158                         "s", "");
4159         if (r < 0) {
4160                 log_error("Failed to get properties: %s", bus_error_message(&error, r));
4161                 return r;
4162         }
4163
4164         r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
4165         if (r < 0)
4166                 return bus_log_parse_error(r);
4167
4168         if (*new_line)
4169                 printf("\n");
4170
4171         *new_line = true;
4172
4173         while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
4174                 const char *name, *contents;
4175
4176                 r = sd_bus_message_read(reply, "s", &name);
4177                 if (r < 0)
4178                         return bus_log_parse_error(r);
4179
4180                 r = sd_bus_message_peek_type(reply, NULL, &contents);
4181                 if (r < 0)
4182                         return bus_log_parse_error(r);
4183
4184                 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, contents);
4185                 if (r < 0)
4186                         return bus_log_parse_error(r);
4187
4188                 if (show_properties)
4189                         r = print_property(name, reply, contents);
4190                 else
4191                         r = status_property(name, reply, &info, contents);
4192                 if (r < 0)
4193                         return r;
4194
4195                 r = sd_bus_message_exit_container(reply);
4196                 if (r < 0)
4197                         return bus_log_parse_error(r);
4198
4199                 r = sd_bus_message_exit_container(reply);
4200                 if (r < 0)
4201                         return bus_log_parse_error(r);
4202         }
4203         if (r < 0)
4204                 return bus_log_parse_error(r);
4205
4206         r = sd_bus_message_exit_container(reply);
4207         if (r < 0)
4208                 return bus_log_parse_error(r);
4209
4210         r = 0;
4211
4212         if (!show_properties) {
4213                 if (streq(verb, "help"))
4214                         show_unit_help(&info);
4215                 else
4216                         print_status_info(&info, ellipsized);
4217         }
4218
4219         strv_free(info.documentation);
4220         strv_free(info.dropin_paths);
4221         strv_free(info.listen);
4222
4223         if (!streq_ptr(info.active_state, "active") &&
4224             !streq_ptr(info.active_state, "reloading") &&
4225             streq(verb, "status")) {
4226                 /* According to LSB: "program not running" */
4227                 /* 0: program is running or service is OK
4228                  * 1: program is dead and /run PID file exists
4229                  * 2: program is dead and /run/lock lock file exists
4230                  * 3: program is not running
4231                  * 4: program or service status is unknown
4232                  */
4233                 if (info.pid_file && access(info.pid_file, F_OK) == 0)
4234                         r = 1;
4235                 else
4236                         r = 3;
4237         }
4238
4239         while ((p = info.exec)) {
4240                 LIST_REMOVE(exec, info.exec, p);
4241                 exec_status_info_free(p);
4242         }
4243
4244         return r;
4245 }
4246
4247 static int get_unit_dbus_path_by_pid(
4248                 sd_bus *bus,
4249                 uint32_t pid,
4250                 char **unit) {
4251
4252         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4253         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4254         char *u;
4255         int r;
4256
4257         r = sd_bus_call_method(
4258                         bus,
4259                         "org.freedesktop.systemd1",
4260                         "/org/freedesktop/systemd1",
4261                         "org.freedesktop.systemd1.Manager",
4262                         "GetUnitByPID",
4263                         &error,
4264                         &reply,
4265                         "u", pid);
4266         if (r < 0) {
4267                 log_error("Failed to get unit for PID "PID_FMT": %s", pid, bus_error_message(&error, r));
4268                 return r;
4269         }
4270
4271         r = sd_bus_message_read(reply, "o", &u);
4272         if (r < 0)
4273                 return bus_log_parse_error(r);
4274
4275         u = strdup(u);
4276         if (!u)
4277                 return log_oom();
4278
4279         *unit = u;
4280         return 0;
4281 }
4282
4283 static int show_all(
4284                 const char* verb,
4285                 sd_bus *bus,
4286                 bool show_properties,
4287                 bool *new_line,
4288                 bool *ellipsized) {
4289
4290         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4291         _cleanup_free_ UnitInfo *unit_infos = NULL;
4292         const UnitInfo *u;
4293         unsigned c;
4294         int r, ret = 0;
4295
4296         r = get_unit_list(bus, NULL, NULL, &unit_infos, 0, &reply);
4297         if (r < 0)
4298                 return r;
4299
4300         pager_open_if_enabled();
4301
4302         c = (unsigned) r;
4303
4304         qsort_safe(unit_infos, c, sizeof(UnitInfo), compare_unit_info);
4305
4306         for (u = unit_infos; u < unit_infos + c; u++) {
4307                 _cleanup_free_ char *p = NULL;
4308
4309                 p = unit_dbus_path_from_name(u->id);
4310                 if (!p)
4311                         return log_oom();
4312
4313                 r = show_one(verb, bus, p, show_properties, new_line, ellipsized);
4314                 if (r < 0)
4315                         return r;
4316                 else if (r > 0 && ret == 0)
4317                         ret = r;
4318         }
4319
4320         return ret;
4321 }
4322
4323 static int show_system_status(sd_bus *bus) {
4324         char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], since2[FORMAT_TIMESTAMP_MAX];
4325         _cleanup_free_ char *hn = NULL;
4326         struct machine_info mi = {};
4327         const char *on, *off;
4328         int r;
4329
4330         hn = gethostname_malloc();
4331         if (!hn)
4332                 return log_oom();
4333
4334         r = bus_map_all_properties(bus, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map, &mi);
4335         if (r < 0) {
4336                 log_error("Failed to read server status: %s", strerror(-r));
4337                 return r;
4338         }
4339
4340         if (streq_ptr(mi.state, "degraded")) {
4341                 on = ansi_highlight_red();
4342                 off = ansi_highlight_off();
4343         } else if (!streq_ptr(mi.state, "running")) {
4344                 on = ansi_highlight_yellow();
4345                 off = ansi_highlight_off();
4346         } else
4347                 on = off = "";
4348
4349         printf("%s%s%s %s\n", on, draw_special_char(DRAW_BLACK_CIRCLE), off, arg_host ? arg_host : hn);
4350
4351         printf("    State: %s%s%s\n",
4352                on, strna(mi.state), off);
4353
4354         printf("     Jobs: %u queued\n", mi.n_jobs);
4355         printf("   Failed: %u units\n", mi.n_failed_units);
4356
4357         printf("    Since: %s; %s\n",
4358                format_timestamp(since2, sizeof(since2), mi.timestamp),
4359                format_timestamp_relative(since1, sizeof(since1), mi.timestamp));
4360
4361         printf("   CGroup: %s\n", mi.control_group ?: "/");
4362         if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_CONTAINER) {
4363                 int flags =
4364                         arg_all * OUTPUT_SHOW_ALL |
4365                         (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
4366                         on_tty() * OUTPUT_COLOR |
4367                         !arg_quiet * OUTPUT_WARN_CUTOFF |
4368                         arg_full * OUTPUT_FULL_WIDTH;
4369
4370                 static const char prefix[] = "           ";
4371                 unsigned c;
4372
4373                 c = columns();
4374                 if (c > sizeof(prefix) - 1)
4375                         c -= sizeof(prefix) - 1;
4376                 else
4377                         c = 0;
4378
4379                 show_cgroup(SYSTEMD_CGROUP_CONTROLLER, strempty(mi.control_group), prefix, c, false, flags);
4380         }
4381
4382         free(mi.state);
4383         free(mi.control_group);
4384
4385         return 0;
4386 }
4387
4388 static int show(sd_bus *bus, char **args) {
4389         bool show_properties, show_status, new_line = false;
4390         bool ellipsized = false;
4391         int r, ret = 0;
4392
4393         assert(bus);
4394         assert(args);
4395
4396         show_properties = streq(args[0], "show");
4397         show_status = streq(args[0], "status");
4398
4399         if (show_properties)
4400                 pager_open_if_enabled();
4401
4402         /* If no argument is specified inspect the manager itself */
4403
4404         if (show_properties && strv_length(args) <= 1)
4405                 return show_one(args[0], bus, "/org/freedesktop/systemd1", show_properties, &new_line, &ellipsized);
4406
4407         if (show_status && strv_length(args) <= 1) {
4408
4409                 pager_open_if_enabled();
4410                 show_system_status(bus);
4411                 new_line = true;
4412
4413                 if (arg_all)
4414                         ret = show_all(args[0], bus, false, &new_line, &ellipsized);
4415         } else {
4416                 _cleanup_free_ char **patterns = NULL;
4417                 char **name;
4418
4419                 STRV_FOREACH(name, args + 1) {
4420                         _cleanup_free_ char *unit = NULL;
4421                         uint32_t id;
4422
4423                         if (safe_atou32(*name, &id) < 0) {
4424                                 if (strv_push(&patterns, *name) < 0)
4425                                         return log_oom();
4426
4427                                 continue;
4428                         } else if (show_properties) {
4429                                 /* Interpret as job id */
4430                                 if (asprintf(&unit, "/org/freedesktop/systemd1/job/%u", id) < 0)
4431                                         return log_oom();
4432
4433                         } else {
4434                                 /* Interpret as PID */
4435                                 r = get_unit_dbus_path_by_pid(bus, id, &unit);
4436                                 if (r < 0) {
4437                                         ret = r;
4438                                         continue;
4439                                 }
4440                         }
4441
4442                         r = show_one(args[0], bus, unit, show_properties,
4443                                      &new_line, &ellipsized);
4444                         if (r < 0)
4445                                 return r;
4446                         else if (r > 0 && ret == 0)
4447                                 ret = r;
4448                 }
4449
4450                 if (!strv_isempty(patterns)) {
4451                         _cleanup_strv_free_ char **names = NULL;
4452
4453                         r = expand_names(bus, patterns, NULL, &names);
4454                         if (r < 0)
4455                                 log_error("Failed to expand names: %s", strerror(-r));
4456
4457                         STRV_FOREACH(name, names) {
4458                                 _cleanup_free_ char *unit;
4459
4460                                 unit = unit_dbus_path_from_name(*name);
4461                                 if (!unit)
4462                                         return log_oom();
4463
4464                                 r = show_one(args[0], bus, unit, show_properties,
4465                                              &new_line, &ellipsized);
4466                                 if (r < 0)
4467                                         return r;
4468                                 else if (r > 0 && ret == 0)
4469                                         ret = r;
4470                         }
4471                 }
4472         }
4473
4474         if (ellipsized && !arg_quiet)
4475                 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
4476
4477         return ret;
4478 }
4479
4480 static int cat(sd_bus *bus, char **args) {
4481         _cleanup_free_ char *unit = NULL;
4482         _cleanup_strv_free_ char **names = NULL;
4483         char **name;
4484         bool first = true;
4485         int r = 0;
4486
4487         assert(bus);
4488         assert(args);
4489
4490         r = expand_names(bus, args + 1, NULL, &names);
4491         if (r < 0)
4492                 log_error("Failed to expand names: %s", strerror(-r));
4493
4494         pager_open_if_enabled();
4495
4496         STRV_FOREACH(name, names) {
4497                 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4498                 _cleanup_strv_free_ char **dropin_paths = NULL;
4499                 _cleanup_free_ char *fragment_path = NULL;
4500                 char **path;
4501
4502                 unit = unit_dbus_path_from_name(*name);
4503                 if (!unit)
4504                         return log_oom();
4505
4506                 if (need_daemon_reload(bus, *name) > 0)
4507                         log_warning("Unit file of %s changed on disk. Run 'systemctl%s daemon-reload'.",
4508                                     *name, arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
4509
4510                 r = sd_bus_get_property_string(
4511                                 bus,
4512                                 "org.freedesktop.systemd1",
4513                                 unit,
4514                                 "org.freedesktop.systemd1.Unit",
4515                                 "FragmentPath",
4516                                 &error,
4517                                 &fragment_path);
4518                 if (r < 0) {
4519                         log_warning("Failed to get FragmentPath: %s", bus_error_message(&error, r));
4520                         continue;
4521                 }
4522
4523                 r = sd_bus_get_property_strv(
4524                                 bus,
4525                                 "org.freedesktop.systemd1",
4526                                 unit,
4527                                 "org.freedesktop.systemd1.Unit",
4528                                 "DropInPaths",
4529                                 &error,
4530                                 &dropin_paths);
4531                 if (r < 0) {
4532                         log_warning("Failed to get DropInPaths: %s", bus_error_message(&error, r));
4533                         continue;
4534                 }
4535
4536                 if (first)
4537                         first = false;
4538                 else
4539                         puts("");
4540
4541                 if (!isempty(fragment_path)) {
4542                         printf("%s# %s%s\n",
4543                                ansi_highlight_blue(),
4544                                fragment_path,
4545                                ansi_highlight_off());
4546                         fflush(stdout);
4547
4548                         r = sendfile_full(STDOUT_FILENO, fragment_path);
4549                         if (r < 0) {
4550                                 log_warning("Failed to cat %s: %s", fragment_path, strerror(-r));
4551                                 continue;
4552                         }
4553                 }
4554
4555                 STRV_FOREACH(path, dropin_paths) {
4556                         printf("%s%s# %s%s\n",
4557                                isempty(fragment_path) && path == dropin_paths ? "" : "\n",
4558                                ansi_highlight_blue(),
4559                                *path,
4560                                ansi_highlight_off());
4561                         fflush(stdout);
4562
4563                         r = sendfile_full(STDOUT_FILENO, *path);
4564                         if (r < 0) {
4565                                 log_warning("Failed to cat %s: %s", *path, strerror(-r));
4566                                 continue;
4567                         }
4568                 }
4569         }
4570
4571         return r < 0 ? r : 0;
4572 }
4573
4574 static int set_property(sd_bus *bus, char **args) {
4575         _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4576         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4577         _cleanup_free_ char *n = NULL;
4578         char **i;
4579         int r;
4580
4581         r = sd_bus_message_new_method_call(
4582                         bus,
4583                         &m,
4584                         "org.freedesktop.systemd1",
4585                         "/org/freedesktop/systemd1",
4586                         "org.freedesktop.systemd1.Manager",
4587                         "SetUnitProperties");
4588         if (r < 0)
4589                 return bus_log_create_error(r);
4590
4591         n = unit_name_mangle(args[1], MANGLE_NOGLOB);
4592         if (!n)
4593                 return log_oom();
4594
4595         r = sd_bus_message_append(m, "sb", n, arg_runtime);
4596         if (r < 0)
4597                 return bus_log_create_error(r);
4598
4599         r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, "(sv)");
4600         if (r < 0)
4601                 return bus_log_create_error(r);
4602
4603         STRV_FOREACH(i, args + 2) {
4604                 r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv");
4605                 if (r < 0)
4606                         return bus_log_create_error(r);
4607
4608                 r = bus_append_unit_property_assignment(m, *i);
4609                 if (r < 0)
4610                         return r;
4611
4612                 r = sd_bus_message_close_container(m);
4613                 if (r < 0)
4614                         return bus_log_create_error(r);
4615         }
4616
4617         r = sd_bus_message_close_container(m);
4618         if (r < 0)
4619                 return bus_log_create_error(r);
4620
4621         r = sd_bus_call(bus, m, 0, &error, NULL);
4622         if (r < 0) {
4623                 log_error("Failed to set unit properties on %s: %s", n, bus_error_message(&error, r));
4624                 return r;
4625         }
4626
4627         return 0;
4628 }
4629
4630 static int snapshot(sd_bus *bus, char **args) {
4631         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4632         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4633         _cleanup_free_ char *n = NULL, *id = NULL;
4634         const char *path;
4635         int r;
4636
4637         if (strv_length(args) > 1)
4638                 n = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".snapshot");
4639         else
4640                 n = strdup("");
4641         if (!n)
4642                 return log_oom();
4643
4644         r = sd_bus_call_method(
4645                         bus,
4646                         "org.freedesktop.systemd1",
4647                         "/org/freedesktop/systemd1",
4648                         "org.freedesktop.systemd1.Manager",
4649                         "CreateSnapshot",
4650                         &error,
4651                         &reply,
4652                         "sb", n, false);
4653         if (r < 0) {
4654                 log_error("Failed to create snapshot: %s", bus_error_message(&error, r));
4655                 return r;
4656         }
4657
4658         r = sd_bus_message_read(reply, "o", &path);
4659         if (r < 0)
4660                 return bus_log_parse_error(r);
4661
4662         r = sd_bus_get_property_string(
4663                         bus,
4664                         "org.freedesktop.systemd1",
4665                         path,
4666                         "org.freedesktop.systemd1.Unit",
4667                         "Id",
4668                         &error,
4669                         &id);
4670         if (r < 0) {
4671                 log_error("Failed to get ID of snapshot: %s", bus_error_message(&error, r));
4672                 return r;
4673         }
4674
4675         if (!arg_quiet)
4676                 puts(id);
4677
4678         return 0;
4679 }
4680
4681 static int delete_snapshot(sd_bus *bus, char **args) {
4682         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4683         _cleanup_strv_free_ char **names = NULL;
4684         char **name;
4685         int r, q;
4686
4687         assert(args);
4688
4689         r = expand_names(bus, args + 1, ".snapshot", &names);
4690         if (r < 0)
4691                 log_error("Failed to expand names: %s", strerror(-r));
4692
4693         STRV_FOREACH(name, names) {
4694                 q = sd_bus_call_method(
4695                                 bus,
4696                                 "org.freedesktop.systemd1",
4697                                 "/org/freedesktop/systemd1",
4698                                 "org.freedesktop.systemd1.Manager",
4699                                 "RemoveSnapshot",
4700                                 &error,
4701                                 NULL,
4702                                 "s", *name);
4703                 if (q < 0) {
4704                         log_error("Failed to remove snapshot %s: %s",
4705                                   *name, bus_error_message(&error, r));
4706                         if (r == 0)
4707                                 r = q;
4708                 }
4709         }
4710
4711         return r;
4712 }
4713
4714 static int daemon_reload(sd_bus *bus, char **args) {
4715         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4716         const char *method;
4717         int r;
4718
4719         if (arg_action == ACTION_RELOAD)
4720                 method = "Reload";
4721         else if (arg_action == ACTION_REEXEC)
4722                 method = "Reexecute";
4723         else {
4724                 assert(arg_action == ACTION_SYSTEMCTL);
4725
4726                 method =
4727                         streq(args[0], "clear-jobs")    ||
4728                         streq(args[0], "cancel")        ? "ClearJobs" :
4729                         streq(args[0], "daemon-reexec") ? "Reexecute" :
4730                         streq(args[0], "reset-failed")  ? "ResetFailed" :
4731                         streq(args[0], "halt")          ? "Halt" :
4732                         streq(args[0], "poweroff")      ? "PowerOff" :
4733                         streq(args[0], "reboot")        ? "Reboot" :
4734                         streq(args[0], "kexec")         ? "KExec" :
4735                         streq(args[0], "exit")          ? "Exit" :
4736                                     /* "daemon-reload" */ "Reload";
4737         }
4738
4739         r = sd_bus_call_method(
4740                         bus,
4741                         "org.freedesktop.systemd1",
4742                         "/org/freedesktop/systemd1",
4743                         "org.freedesktop.systemd1.Manager",
4744                         method,
4745                         &error,
4746                         NULL,
4747                         NULL);
4748
4749         if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
4750                 /* There's always a fallback possible for
4751                  * legacy actions. */
4752                 r = -EADDRNOTAVAIL;
4753         else if ((r == -ETIMEDOUT || r == -ECONNRESET) && streq(method, "Reexecute"))
4754                 /* On reexecution, we expect a disconnect, not a
4755                  * reply */
4756                 r = 0;
4757         else if (r < 0)
4758                 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
4759
4760         return r < 0 ? r : 0;
4761 }
4762
4763 static int reset_failed(sd_bus *bus, char **args) {
4764         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4765         _cleanup_strv_free_ char **names = NULL;
4766         char **name;
4767         int r, q;
4768
4769         if (strv_length(args) <= 1)
4770                 return daemon_reload(bus, args);
4771
4772         r = expand_names(bus, args + 1, NULL, &names);
4773         if (r < 0)
4774                 log_error("Failed to expand names: %s", strerror(-r));
4775
4776         STRV_FOREACH(name, names) {
4777                 q = sd_bus_call_method(
4778                                 bus,
4779                                 "org.freedesktop.systemd1",
4780                                 "/org/freedesktop/systemd1",
4781                                 "org.freedesktop.systemd1.Manager",
4782                                 "ResetFailedUnit",
4783                                 &error,
4784                                 NULL,
4785                                 "s", *name);
4786                 if (q < 0) {
4787                         log_error("Failed to reset failed state of unit %s: %s",
4788                                   *name, bus_error_message(&error, r));
4789                         if (r == 0)
4790                                 r = q;
4791                 }
4792         }
4793
4794         return r;
4795 }
4796
4797 static int show_environment(sd_bus *bus, char **args) {
4798         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4799         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4800         const char *text;
4801         int r;
4802
4803         pager_open_if_enabled();
4804
4805         r = sd_bus_get_property(
4806                         bus,
4807                         "org.freedesktop.systemd1",
4808                         "/org/freedesktop/systemd1",
4809                         "org.freedesktop.systemd1.Manager",
4810                         "Environment",
4811                         &error,
4812                         &reply,
4813                         "as");
4814         if (r < 0) {
4815                 log_error("Failed to get environment: %s", bus_error_message(&error, r));
4816                 return r;
4817         }
4818
4819         r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "s");
4820         if (r < 0)
4821                 return bus_log_parse_error(r);
4822
4823         while ((r = sd_bus_message_read_basic(reply, SD_BUS_TYPE_STRING, &text)) > 0)
4824                 puts(text);
4825         if (r < 0)
4826                 return bus_log_parse_error(r);
4827
4828         r = sd_bus_message_exit_container(reply);
4829         if (r < 0)
4830                 return bus_log_parse_error(r);
4831
4832         return 0;
4833 }
4834
4835 static int switch_root(sd_bus *bus, char **args) {
4836         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4837         _cleanup_free_ char *cmdline_init = NULL;
4838         const char *root, *init;
4839         unsigned l;
4840         int r;
4841
4842         l = strv_length(args);
4843         if (l < 2 || l > 3) {
4844                 log_error("Wrong number of arguments.");
4845                 return -EINVAL;
4846         }
4847
4848         root = args[1];
4849
4850         if (l >= 3)
4851                 init = args[2];
4852         else {
4853                 r = parse_env_file("/proc/cmdline", WHITESPACE,
4854                                    "init", &cmdline_init,
4855                                    NULL);
4856                 if (r < 0)
4857                         log_debug("Failed to parse /proc/cmdline: %s", strerror(-r));
4858
4859                 init = cmdline_init;
4860         }
4861
4862         if (isempty(init))
4863                 init = NULL;
4864
4865         if (init) {
4866                 const char *root_systemd_path = NULL, *root_init_path = NULL;
4867
4868                 root_systemd_path = strappenda(root, "/" SYSTEMD_BINARY_PATH);
4869                 root_init_path = strappenda3(root, "/", init);
4870
4871                 /* If the passed init is actually the same as the
4872                  * systemd binary, then let's suppress it. */
4873                 if (files_same(root_init_path, root_systemd_path) > 0)
4874                         init = NULL;
4875         }
4876
4877         log_debug("Switching root - root: %s; init: %s", root, strna(init));
4878
4879         r = sd_bus_call_method(
4880                         bus,
4881                         "org.freedesktop.systemd1",
4882                         "/org/freedesktop/systemd1",
4883                         "org.freedesktop.systemd1.Manager",
4884                         "SwitchRoot",
4885                         &error,
4886                         NULL,
4887                         "ss", root, init);
4888         if (r < 0) {
4889                 log_error("Failed to switch root: %s", bus_error_message(&error, r));
4890                 return r;
4891         }
4892
4893         return 0;
4894 }
4895
4896 static int set_environment(sd_bus *bus, char **args) {
4897         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4898         _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4899         const char *method;
4900         int r;
4901
4902         assert(bus);
4903         assert(args);
4904
4905         method = streq(args[0], "set-environment")
4906                 ? "SetEnvironment"
4907                 : "UnsetEnvironment";
4908
4909         r = sd_bus_message_new_method_call(
4910                         bus,
4911                         &m,
4912                         "org.freedesktop.systemd1",
4913                         "/org/freedesktop/systemd1",
4914                         "org.freedesktop.systemd1.Manager",
4915                         method);
4916         if (r < 0)
4917                 return bus_log_create_error(r);
4918
4919         r = sd_bus_message_append_strv(m, args + 1);
4920         if (r < 0)
4921                 return bus_log_create_error(r);
4922
4923         r = sd_bus_call(bus, m, 0, &error, NULL);
4924         if (r < 0) {
4925                 log_error("Failed to set environment: %s", bus_error_message(&error, r));
4926                 return r;
4927         }
4928
4929         return 0;
4930 }
4931
4932 static int import_environment(sd_bus *bus, char **args) {
4933         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4934         _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4935         int r;
4936
4937         assert(bus);
4938         assert(args);
4939
4940         r = sd_bus_message_new_method_call(
4941                         bus,
4942                         &m,
4943                         "org.freedesktop.systemd1",
4944                         "/org/freedesktop/systemd1",
4945                         "org.freedesktop.systemd1.Manager",
4946                         "SetEnvironment");
4947         if (r < 0)
4948                 return bus_log_create_error(r);
4949
4950         if (strv_isempty(args + 1))
4951                 r = sd_bus_message_append_strv(m, environ);
4952         else {
4953                 char **a, **b;
4954
4955                 r = sd_bus_message_open_container(m, 'a', "s");
4956                 if (r < 0)
4957                         return bus_log_create_error(r);
4958
4959                 STRV_FOREACH(a, args + 1) {
4960
4961                         if (!env_name_is_valid(*a)) {
4962                                 log_error("Not a valid environment variable name: %s", *a);
4963                                 return -EINVAL;
4964                         }
4965
4966                         STRV_FOREACH(b, environ) {
4967                                 const char *eq;
4968
4969                                 eq = startswith(*b, *a);
4970                                 if (eq && *eq == '=') {
4971
4972                                         r = sd_bus_message_append(m, "s", *b);
4973                                         if (r < 0)
4974                                                 return bus_log_create_error(r);
4975
4976                                         break;
4977                                 }
4978                         }
4979                 }
4980
4981                 r = sd_bus_message_close_container(m);
4982         }
4983         if (r < 0)
4984                 return bus_log_create_error(r);
4985
4986         r = sd_bus_call(bus, m, 0, &error, NULL);
4987         if (r < 0) {
4988                 log_error("Failed to import environment: %s", bus_error_message(&error, r));
4989                 return r;
4990         }
4991
4992         return 0;
4993 }
4994
4995 static int enable_sysv_units(const char *verb, char **args) {
4996         int r = 0;
4997
4998 #if defined(HAVE_SYSV_COMPAT) && defined(HAVE_CHKCONFIG)
4999         unsigned f = 1, t = 1;
5000         _cleanup_lookup_paths_free_ LookupPaths paths = {};
5001
5002         if (arg_scope != UNIT_FILE_SYSTEM)
5003                 return 0;
5004
5005         if (!streq(verb, "enable") &&
5006             !streq(verb, "disable") &&
5007             !streq(verb, "is-enabled"))
5008                 return 0;
5009
5010         /* Processes all SysV units, and reshuffles the array so that
5011          * afterwards only the native units remain */
5012
5013         r = lookup_paths_init(&paths, SYSTEMD_SYSTEM, false, arg_root, NULL, NULL, NULL);
5014         if (r < 0)
5015                 return r;
5016
5017         r = 0;
5018         for (f = 0; args[f]; f++) {
5019                 const char *name;
5020                 _cleanup_free_ char *p = NULL, *q = NULL, *l = NULL;
5021                 bool found_native = false, found_sysv;
5022                 unsigned c = 1;
5023                 const char *argv[6] = { "/sbin/chkconfig", NULL, NULL, NULL, NULL };
5024                 char **k;
5025                 int j;
5026                 pid_t pid;
5027                 siginfo_t status;
5028
5029                 name = args[f];
5030
5031                 if (!endswith(name, ".service"))
5032                         continue;
5033
5034                 if (path_is_absolute(name))
5035                         continue;
5036
5037                 STRV_FOREACH(k, paths.unit_path) {
5038                         _cleanup_free_ char *path = NULL;
5039
5040                         if (!isempty(arg_root))
5041                                 asprintf(&path, "%s/%s/%s", arg_root, *k, name);
5042                         else
5043                                 asprintf(&path, "%s/%s", *k, name);
5044
5045                         if (!path) {
5046                                 r = log_oom();
5047                                 goto finish;
5048                         }
5049
5050                         found_native = access(path, F_OK) >= 0;
5051                         if (found_native)
5052                                 break;
5053                 }
5054
5055                 if (found_native)
5056                         continue;
5057
5058                 if (!isempty(arg_root))
5059                         asprintf(&p, "%s/" SYSTEM_SYSVINIT_PATH "/%s", arg_root, name);
5060                 else
5061                         asprintf(&p, SYSTEM_SYSVINIT_PATH "/%s", name);
5062                 if (!p) {
5063                         r = log_oom();
5064                         goto finish;
5065                 }
5066
5067                 p[strlen(p) - strlen(".service")] = 0;
5068                 found_sysv = access(p, F_OK) >= 0;
5069                 if (!found_sysv)
5070                         continue;
5071
5072                 /* Mark this entry, so that we don't try enabling it as native unit */
5073                 args[f] = (char*) "";
5074
5075                 log_info("%s is not a native service, redirecting to /sbin/chkconfig.", name);
5076
5077                 if (!isempty(arg_root))
5078                         argv[c++] = q = strappend("--root=", arg_root);
5079
5080                 argv[c++] = basename(p);
5081                 argv[c++] =
5082                         streq(verb, "enable") ? "on" :
5083                         streq(verb, "disable") ? "off" : "--level=5";
5084                 argv[c] = NULL;
5085
5086                 l = strv_join((char**)argv, " ");
5087                 if (!l) {
5088                         r = log_oom();
5089                         goto finish;
5090                 }
5091
5092                 log_info("Executing %s", l);
5093
5094                 pid = fork();
5095                 if (pid < 0) {
5096                         log_error("Failed to fork: %m");
5097                         r = -errno;
5098                         goto finish;
5099                 } else if (pid == 0) {
5100                         /* Child */
5101
5102                         execv(argv[0], (char**) argv);
5103                         _exit(EXIT_FAILURE);
5104                 }
5105
5106                 j = wait_for_terminate(pid, &status);
5107                 if (j < 0) {
5108                         log_error("Failed to wait for child: %s", strerror(-r));
5109                         r = j;
5110                         goto finish;
5111                 }
5112
5113                 if (status.si_code == CLD_EXITED) {
5114                         if (streq(verb, "is-enabled")) {
5115                                 if (status.si_status == 0) {
5116                                         if (!arg_quiet)
5117                                                 puts("enabled");
5118                                         r = 1;
5119                                 } else {
5120                                         if (!arg_quiet)
5121                                                 puts("disabled");
5122                                 }
5123
5124                         } else if (status.si_status != 0) {
5125                                 r = -EINVAL;
5126                                 goto finish;
5127                         }
5128                 } else {
5129                         r = -EPROTO;
5130                         goto finish;
5131                 }
5132         }
5133
5134 finish:
5135         /* Drop all SysV units */
5136         for (f = 0, t = 0; args[f]; f++) {
5137
5138                 if (isempty(args[f]))
5139                         continue;
5140
5141                 args[t++] = args[f];
5142         }
5143
5144         args[t] = NULL;
5145
5146 #endif
5147         return r;
5148 }
5149
5150 static int mangle_names(char **original_names, char ***mangled_names) {
5151         char **i, **l, **name;
5152
5153         l = new(char*, strv_length(original_names) + 1);
5154         if (!l)
5155                 return log_oom();
5156
5157         i = l;
5158         STRV_FOREACH(name, original_names) {
5159
5160                 /* When enabling units qualified path names are OK,
5161                  * too, hence allow them explicitly. */
5162
5163                 if (is_path(*name))
5164                         *i = strdup(*name);
5165                 else
5166                         *i = unit_name_mangle(*name, MANGLE_NOGLOB);
5167
5168                 if (!*i) {
5169                         strv_free(l);
5170                         return log_oom();
5171                 }
5172
5173                 i++;
5174         }
5175
5176         *i = NULL;
5177         *mangled_names = l;
5178
5179         return 0;
5180 }
5181
5182 static int enable_unit(sd_bus *bus, char **args) {
5183         _cleanup_strv_free_ char **names = NULL;
5184         const char *verb = args[0];
5185         UnitFileChange *changes = NULL;
5186         unsigned n_changes = 0;
5187         int carries_install_info = -1;
5188         int r;
5189
5190         if (!args[1])
5191                 return 0;
5192
5193         r = mangle_names(args+1, &names);
5194         if (r < 0)
5195                 return r;
5196
5197         r = enable_sysv_units(verb, names);
5198         if (r < 0)
5199                 return r;
5200
5201         /* If the operation was fully executed by the SysV compat,
5202          * let's finish early */
5203         if (strv_isempty(names))
5204                 return 0;
5205
5206         if (!bus || avoid_bus()) {
5207                 if (streq(verb, "enable")) {
5208                         r = unit_file_enable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5209                         carries_install_info = r;
5210                 } else if (streq(verb, "disable"))
5211                         r = unit_file_disable(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
5212                 else if (streq(verb, "reenable")) {
5213                         r = unit_file_reenable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5214                         carries_install_info = r;
5215                 } else if (streq(verb, "link"))
5216                         r = unit_file_link(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5217                 else if (streq(verb, "preset")) {
5218                         r = unit_file_preset(arg_scope, arg_runtime, arg_root, names, arg_preset_mode, arg_force, &changes, &n_changes);
5219                         carries_install_info = r;
5220                 } else if (streq(verb, "mask"))
5221                         r = unit_file_mask(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5222                 else if (streq(verb, "unmask"))
5223                         r = unit_file_unmask(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
5224                 else
5225                         assert_not_reached("Unknown verb");
5226
5227                 if (r < 0) {
5228                         log_error("Operation failed: %s", strerror(-r));
5229                         goto finish;
5230                 }
5231
5232                 if (!arg_quiet)
5233                         dump_unit_file_changes(changes, n_changes);
5234
5235                 r = 0;
5236         } else {
5237                 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
5238                 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5239                 int expect_carries_install_info = false;
5240                 bool send_force = true, send_preset_mode = false;
5241                 const char *method;
5242
5243                 if (streq(verb, "enable")) {
5244                         method = "EnableUnitFiles";
5245                         expect_carries_install_info = true;
5246                 } else if (streq(verb, "disable")) {
5247                         method = "DisableUnitFiles";
5248                         send_force = false;
5249                 } else if (streq(verb, "reenable")) {
5250                         method = "ReenableUnitFiles";
5251                         expect_carries_install_info = true;
5252                 } else if (streq(verb, "link"))
5253                         method = "LinkUnitFiles";
5254                 else if (streq(verb, "preset")) {
5255
5256                         if (arg_preset_mode != UNIT_FILE_PRESET_FULL) {
5257                                 method = "PresetUnitFilesWithMode";
5258                                 send_preset_mode = true;
5259                         } else
5260                                 method = "PresetUnitFiles";
5261
5262                         expect_carries_install_info = true;
5263                 } else if (streq(verb, "mask"))
5264                         method = "MaskUnitFiles";
5265                 else if (streq(verb, "unmask")) {
5266                         method = "UnmaskUnitFiles";
5267                         send_force = false;
5268                 } else
5269                         assert_not_reached("Unknown verb");
5270
5271                 r = sd_bus_message_new_method_call(
5272                                 bus,
5273                                 &m,
5274                                 "org.freedesktop.systemd1",
5275                                 "/org/freedesktop/systemd1",
5276                                 "org.freedesktop.systemd1.Manager",
5277                                 method);
5278                 if (r < 0)
5279                         return bus_log_create_error(r);
5280
5281                 r = sd_bus_message_append_strv(m, names);
5282                 if (r < 0)
5283                         return bus_log_create_error(r);
5284
5285                 if (send_preset_mode) {
5286                         r = sd_bus_message_append(m, "s", unit_file_preset_mode_to_string(arg_preset_mode));
5287                         if (r < 0)
5288                                 return bus_log_create_error(r);
5289                 }
5290
5291                 r = sd_bus_message_append(m, "b", arg_runtime);
5292                 if (r < 0)
5293                         return bus_log_create_error(r);
5294
5295                 if (send_force) {
5296                         r = sd_bus_message_append(m, "b", arg_force);
5297                         if (r < 0)
5298                                 return bus_log_create_error(r);
5299                 }
5300
5301                 r = sd_bus_call(bus, m, 0, &error, &reply);
5302                 if (r < 0) {
5303                         log_error("Failed to execute operation: %s", bus_error_message(&error, r));
5304                         return r;
5305                 }
5306
5307                 if (expect_carries_install_info) {
5308                         r = sd_bus_message_read(reply, "b", &carries_install_info);
5309                         if (r < 0)
5310                                 return bus_log_parse_error(r);
5311                 }
5312
5313                 r = deserialize_and_dump_unit_file_changes(reply);
5314                 if (r < 0)
5315                         return r;
5316
5317                 /* Try to reload if enabled */
5318                 if (!arg_no_reload)
5319                         r = daemon_reload(bus, args);
5320                 else
5321                         r = 0;
5322         }
5323
5324         if (carries_install_info == 0)
5325                 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
5326                             "using systemctl.\n"
5327                             "Possible reasons for having this kind of units are:\n"
5328                             "1) A unit may be statically enabled by being symlinked from another unit's\n"
5329                             "   .wants/ or .requires/ directory.\n"
5330                             "2) A unit's purpose may be to act as a helper for some other unit which has\n"
5331                             "   a requirement dependency on it.\n"
5332                             "3) A unit may be started when needed via activation (socket, path, timer,\n"
5333                             "   D-Bus, udev, scripted systemctl call, ...).\n");
5334
5335 finish:
5336         unit_file_changes_free(changes, n_changes);
5337
5338         return r;
5339 }
5340
5341 static int preset_all(sd_bus *bus, char **args) {
5342         UnitFileChange *changes = NULL;
5343         unsigned n_changes = 0;
5344         int r;
5345
5346         if (!bus || avoid_bus()) {
5347
5348                 r = unit_file_preset_all(arg_scope, arg_runtime, arg_root, arg_preset_mode, arg_force, &changes, &n_changes);
5349                 if (r < 0) {
5350                         log_error("Operation failed: %s", strerror(-r));
5351                         goto finish;
5352                 }
5353
5354                 if (!arg_quiet)
5355                         dump_unit_file_changes(changes, n_changes);
5356
5357                 r = 0;
5358
5359         } else {
5360                 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
5361                 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5362
5363                 r = sd_bus_call_method(
5364                                 bus,
5365                                 "org.freedesktop.systemd1",
5366                                 "/org/freedesktop/systemd1",
5367                                 "org.freedesktop.systemd1.Manager",
5368                                 "PresetAllUnitFiles",
5369                                 &error,
5370                                 &reply,
5371                                 "sbb",
5372                                 unit_file_preset_mode_to_string(arg_preset_mode),
5373                                 arg_runtime,
5374                                 arg_force);
5375                 if (r < 0) {
5376                         log_error("Failed to execute operation: %s", bus_error_message(&error, r));
5377                         return r;
5378                 }
5379
5380                 r = deserialize_and_dump_unit_file_changes(reply);
5381                 if (r < 0)
5382                         return r;
5383
5384                 if (!arg_no_reload)
5385                         r = daemon_reload(bus, args);
5386                 else
5387                         r = 0;
5388         }
5389
5390 finish:
5391         unit_file_changes_free(changes, n_changes);
5392
5393         return r;
5394 }
5395
5396 static int unit_is_enabled(sd_bus *bus, char **args) {
5397
5398         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5399         _cleanup_strv_free_ char **names = NULL;
5400         bool enabled;
5401         char **name;
5402         int r;
5403
5404         r = mangle_names(args+1, &names);
5405         if (r < 0)
5406                 return r;
5407
5408         r = enable_sysv_units(args[0], names);
5409         if (r < 0)
5410                 return r;
5411
5412         enabled = r > 0;
5413
5414         if (!bus || avoid_bus()) {
5415
5416                 STRV_FOREACH(name, names) {
5417                         UnitFileState state;
5418
5419                         state = unit_file_get_state(arg_scope, arg_root, *name);
5420                         if (state < 0) {
5421                                 log_error("Failed to get unit file state for %s: %s", *name, strerror(-state));
5422                                 return state;
5423                         }
5424
5425                         if (state == UNIT_FILE_ENABLED ||
5426                             state == UNIT_FILE_ENABLED_RUNTIME ||
5427                             state == UNIT_FILE_STATIC)
5428                                 enabled = true;
5429
5430                         if (!arg_quiet)
5431                                 puts(unit_file_state_to_string(state));
5432                 }
5433
5434         } else {
5435                 STRV_FOREACH(name, names) {
5436                         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
5437                         const char *s;
5438
5439                         r = sd_bus_call_method(
5440                                         bus,
5441                                         "org.freedesktop.systemd1",
5442                                         "/org/freedesktop/systemd1",
5443                                         "org.freedesktop.systemd1.Manager",
5444                                         "GetUnitFileState",
5445                                         &error,
5446                                         &reply,
5447                                         "s", *name);
5448                         if (r < 0) {
5449                                 log_error("Failed to get unit file state for %s: %s", *name, bus_error_message(&error, r));
5450                                 return r;
5451                         }
5452
5453                         r = sd_bus_message_read(reply, "s", &s);
5454                         if (r < 0)
5455                                 return bus_log_parse_error(r);
5456
5457                         if (streq(s, "enabled") ||
5458                             streq(s, "enabled-runtime") ||
5459                             streq(s, "static"))
5460                                 enabled = true;
5461
5462                         if (!arg_quiet)
5463                                 puts(s);
5464                 }
5465         }
5466
5467         return !enabled;
5468 }
5469
5470 static int is_system_running(sd_bus *bus, char **args) {
5471         _cleanup_free_ char *state = NULL;
5472         int r;
5473
5474         r = sd_bus_get_property_string(
5475                         bus,
5476                         "org.freedesktop.systemd1",
5477                         "/org/freedesktop/systemd1",
5478                         "org.freedesktop.systemd1.Manager",
5479                         "SystemState",
5480                         NULL,
5481                         &state);
5482         if (r < 0) {
5483                 if (!arg_quiet)
5484                         puts("unknown");
5485                 return 0;
5486         }
5487
5488         if (!arg_quiet)
5489                 puts(state);
5490
5491         return streq(state, "running") ? EXIT_SUCCESS : EXIT_FAILURE;
5492 }
5493
5494 static int systemctl_help(void) {
5495
5496         pager_open_if_enabled();
5497
5498         printf("%s [OPTIONS...] {COMMAND} ...\n\n"
5499                "Query or send control commands to the systemd manager.\n\n"
5500                "  -h --help           Show this help\n"
5501                "     --version        Show package version\n"
5502                "     --system         Connect to system manager\n"
5503                "     --user           Connect to user service manager\n"
5504                "  -H --host=[USER@]HOST\n"
5505                "                      Operate on remote host\n"
5506                "  -M --machine=CONTAINER\n"
5507                "                      Operate on local container\n"
5508                "  -t --type=TYPE      List only units of a particular type\n"
5509                "     --state=STATE    List only units with particular LOAD or SUB or ACTIVE state\n"
5510                "  -p --property=NAME  Show only properties by this name\n"
5511                "  -a --all            Show all loaded units/properties, including dead/empty\n"
5512                "                      ones. To list all units installed on the system, use\n"
5513                "                      the 'list-unit-files' command instead.\n"
5514                "  -l --full           Don't ellipsize unit names on output\n"
5515                "  -r --recursive      Show unit list of host and local containers\n"
5516                "     --reverse        Show reverse dependencies with 'list-dependencies'\n"
5517                "     --job-mode=MODE  Specify how to deal with already queued jobs, when\n"
5518                "                      queueing a new job\n"
5519                "     --show-types     When showing sockets, explicitly show their type\n"
5520                "  -i --ignore-inhibitors\n"
5521                "                      When shutting down or sleeping, ignore inhibitors\n"
5522                "     --kill-who=WHO   Who to send signal to\n"
5523                "  -s --signal=SIGNAL  Which signal to send\n"
5524                "  -q --quiet          Suppress output\n"
5525                "     --no-block       Do not wait until operation finished\n"
5526                "     --no-wall        Don't send wall message before halt/power-off/reboot\n"
5527                "     --no-reload      When enabling/disabling unit files, don't reload daemon\n"
5528                "                      configuration\n"
5529                "     --no-legend      Do not print a legend (column headers and hints)\n"
5530                "     --no-pager       Do not pipe output into a pager\n"
5531                "     --no-ask-password\n"
5532                "                      Do not ask for system passwords\n"
5533                "     --global         Enable/disable unit files globally\n"
5534                "     --runtime        Enable unit files only temporarily until next reboot\n"
5535                "  -f --force          When enabling unit files, override existing symlinks\n"
5536                "                      When shutting down, execute action immediately\n"
5537                "     --preset-mode=   Specifies whether fully apply presets, or only enable,\n"
5538                "                      or only disable\n"
5539                "     --root=PATH      Enable unit files in the specified root directory\n"
5540                "  -n --lines=INTEGER  Number of journal entries to show\n"
5541                "  -o --output=STRING  Change journal output mode (short, short-monotonic,\n"
5542                "                      verbose, export, json, json-pretty, json-sse, cat)\n"
5543                "     --plain          Print unit dependencies as a list instead of a tree\n\n"
5544                "Unit Commands:\n"
5545                "  list-units [PATTERN...]         List loaded units\n"
5546                "  list-sockets [PATTERN...]       List loaded sockets ordered by address\n"
5547                "  list-timers [PATTERN...]        List loaded timers ordered by next elapse\n"
5548                "  start NAME...                   Start (activate) one or more units\n"
5549                "  stop NAME...                    Stop (deactivate) one or more units\n"
5550                "  reload NAME...                  Reload one or more units\n"
5551                "  restart NAME...                 Start or restart one or more units\n"
5552                "  try-restart NAME...             Restart one or more units if active\n"
5553                "  reload-or-restart NAME...       Reload one or more units if possible,\n"
5554                "                                  otherwise start or restart\n"
5555                "  reload-or-try-restart NAME...   Reload one or more units if possible,\n"
5556                "                                  otherwise restart if active\n"
5557                "  isolate NAME                    Start one unit and stop all others\n"
5558                "  kill NAME...                    Send signal to processes of a unit\n"
5559                "  is-active PATTERN...            Check whether units are active\n"
5560                "  is-failed PATTERN...            Check whether units are failed\n"
5561                "  status [PATTERN...|PID...]      Show runtime status of one or more units\n"
5562                "  show [PATTERN...|JOB...]        Show properties of one or more\n"
5563                "                                  units/jobs or the manager\n"
5564                "  cat PATTERN...                  Show files and drop-ins of one or more units\n"
5565                "  set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
5566                "  help PATTERN...|PID...          Show manual for one or more units\n"
5567                "  reset-failed [PATTERN...]       Reset failed state for all, one, or more\n"
5568                "                                  units\n"
5569                "  list-dependencies [NAME]        Recursively show units which are required\n"
5570                "                                  or wanted by this unit or by which this\n"
5571                "                                  unit is required or wanted\n\n"
5572                "Unit File Commands:\n"
5573                "  list-unit-files [PATTERN...]    List installed unit files\n"
5574                "  enable NAME...                  Enable one or more unit files\n"
5575                "  disable NAME...                 Disable one or more unit files\n"
5576                "  reenable NAME...                Reenable one or more unit files\n"
5577                "  preset NAME...                  Enable/disable one or more unit files\n"
5578                "                                  based on preset configuration\n"
5579                "  preset-all                      Enable/disable all unit files based on\n"
5580                "                                  preset configuration\n"
5581                "  is-enabled NAME...              Check whether unit files are enabled\n\n"
5582                "  mask NAME...                    Mask one or more units\n"
5583                "  unmask NAME...                  Unmask one or more units\n"
5584                "  link PATH...                    Link one or more units files into\n"
5585                "                                  the search path\n"
5586                "  get-default                     Get the name of the default target\n"
5587                "  set-default NAME                Set the default target\n\n"
5588                "Machine Commands:\n"
5589                "  list-machines [PATTERN...]      List local containers and host\n\n"
5590                "Job Commands:\n"
5591                "  list-jobs [PATTERN...]          List jobs\n"
5592                "  cancel [JOB...]                 Cancel all, one, or more jobs\n\n"
5593                "Snapshot Commands:\n"
5594                "  snapshot [NAME]                 Create a snapshot\n"
5595                "  delete NAME...                  Remove one or more snapshots\n\n"
5596                "Environment Commands:\n"
5597                "  show-environment                Dump environment\n"
5598                "  set-environment NAME=VALUE...   Set one or more environment variables\n"
5599                "  unset-environment NAME...       Unset one or more environment variables\n"
5600                "  import-environment NAME...      Import all, one or more environment variables\n\n"
5601                "Manager Lifecycle Commands:\n"
5602                "  daemon-reload                   Reload systemd manager configuration\n"
5603                "  daemon-reexec                   Reexecute systemd manager\n\n"
5604                "System Commands:\n"
5605                "  is-system-running               Check whether system is fully running\n"
5606                "  default                         Enter system default mode\n"
5607                "  rescue                          Enter system rescue mode\n"
5608                "  emergency                       Enter system emergency mode\n"
5609                "  halt                            Shut down and halt the system\n"
5610                "  poweroff                        Shut down and power-off the system\n"
5611                "  reboot [ARG]                    Shut down and reboot the system\n"
5612                "  kexec                           Shut down and reboot the system with kexec\n"
5613                "  exit                            Request user instance exit\n"
5614                "  switch-root ROOT [INIT]         Change to a different root file system\n"
5615                "  suspend                         Suspend the system\n"
5616                "  hibernate                       Hibernate the system\n"
5617                "  hybrid-sleep                    Hibernate and suspend the system\n",
5618                program_invocation_short_name);
5619
5620         return 0;
5621 }
5622
5623 static int halt_help(void) {
5624
5625         printf("%s [OPTIONS...]%s\n\n"
5626                "%s the system.\n\n"
5627                "     --help      Show this help\n"
5628                "     --halt      Halt the machine\n"
5629                "  -p --poweroff  Switch off the machine\n"
5630                "     --reboot    Reboot the machine\n"
5631                "  -f --force     Force immediate halt/power-off/reboot\n"
5632                "  -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
5633                "  -d --no-wtmp   Don't write wtmp record\n"
5634                "     --no-wall   Don't send wall message before halt/power-off/reboot\n",
5635                program_invocation_short_name,
5636                arg_action == ACTION_REBOOT   ? " [ARG]" : "",
5637                arg_action == ACTION_REBOOT   ? "Reboot" :
5638                arg_action == ACTION_POWEROFF ? "Power off" :
5639                                                "Halt");
5640
5641         return 0;
5642 }
5643
5644 static int shutdown_help(void) {
5645
5646         printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
5647                "Shut down the system.\n\n"
5648                "     --help      Show this help\n"
5649                "  -H --halt      Halt the machine\n"
5650                "  -P --poweroff  Power-off the machine\n"
5651                "  -r --reboot    Reboot the machine\n"
5652                "  -h             Equivalent to --poweroff, overridden by --halt\n"
5653                "  -k             Don't halt/power-off/reboot, just send warnings\n"
5654                "     --no-wall   Don't send wall message before halt/power-off/reboot\n"
5655                "  -c             Cancel a pending shutdown\n",
5656                program_invocation_short_name);
5657
5658         return 0;
5659 }
5660
5661 static int telinit_help(void) {
5662
5663         printf("%s [OPTIONS...] {COMMAND}\n\n"
5664                "Send control commands to the init daemon.\n\n"
5665                "     --help      Show this help\n"
5666                "     --no-wall   Don't send wall message before halt/power-off/reboot\n\n"
5667                "Commands:\n"
5668                "  0              Power-off the machine\n"
5669                "  6              Reboot the machine\n"
5670                "  2, 3, 4, 5     Start runlevelX.target unit\n"
5671                "  1, s, S        Enter rescue mode\n"
5672                "  q, Q           Reload init daemon configuration\n"
5673                "  u, U           Reexecute init daemon\n",
5674                program_invocation_short_name);
5675
5676         return 0;
5677 }
5678
5679 static int runlevel_help(void) {
5680
5681         printf("%s [OPTIONS...]\n\n"
5682                "Prints the previous and current runlevel of the init system.\n\n"
5683                "     --help      Show this help\n",
5684                program_invocation_short_name);
5685
5686         return 0;
5687 }
5688
5689 static int help_types(void) {
5690         int i;
5691         const char *t;
5692
5693         puts("Available unit types:");
5694         for (i = 0; i < _UNIT_TYPE_MAX; i++) {
5695                 t = unit_type_to_string(i);
5696                 if (t)
5697                         puts(t);
5698         }
5699
5700         return 0;
5701 }
5702
5703 static int systemctl_parse_argv(int argc, char *argv[]) {
5704
5705         enum {
5706                 ARG_FAIL = 0x100,
5707                 ARG_REVERSE,
5708                 ARG_AFTER,
5709                 ARG_BEFORE,
5710                 ARG_SHOW_TYPES,
5711                 ARG_IRREVERSIBLE,
5712                 ARG_IGNORE_DEPENDENCIES,
5713                 ARG_VERSION,
5714                 ARG_USER,
5715                 ARG_SYSTEM,
5716                 ARG_GLOBAL,
5717                 ARG_NO_BLOCK,
5718                 ARG_NO_LEGEND,
5719                 ARG_NO_PAGER,
5720                 ARG_NO_WALL,
5721                 ARG_ROOT,
5722                 ARG_NO_RELOAD,
5723                 ARG_KILL_WHO,
5724                 ARG_NO_ASK_PASSWORD,
5725                 ARG_FAILED,
5726                 ARG_RUNTIME,
5727                 ARG_FORCE,
5728                 ARG_PLAIN,
5729                 ARG_STATE,
5730                 ARG_JOB_MODE,
5731                 ARG_PRESET_MODE,
5732         };
5733
5734         static const struct option options[] = {
5735                 { "help",                no_argument,       NULL, 'h'                     },
5736                 { "version",             no_argument,       NULL, ARG_VERSION             },
5737                 { "type",                required_argument, NULL, 't'                     },
5738                 { "property",            required_argument, NULL, 'p'                     },
5739                 { "all",                 no_argument,       NULL, 'a'                     },
5740                 { "reverse",             no_argument,       NULL, ARG_REVERSE             },
5741                 { "after",               no_argument,       NULL, ARG_AFTER               },
5742                 { "before",              no_argument,       NULL, ARG_BEFORE              },
5743                 { "show-types",          no_argument,       NULL, ARG_SHOW_TYPES          },
5744                 { "failed",              no_argument,       NULL, ARG_FAILED              }, /* compatibility only */
5745                 { "full",                no_argument,       NULL, 'l'                     },
5746                 { "job-mode",            required_argument, NULL, ARG_JOB_MODE            },
5747                 { "fail",                no_argument,       NULL, ARG_FAIL                }, /* compatibility only */
5748                 { "irreversible",        no_argument,       NULL, ARG_IRREVERSIBLE        }, /* compatibility only */
5749                 { "ignore-dependencies", no_argument,       NULL, ARG_IGNORE_DEPENDENCIES }, /* compatibility only */
5750                 { "ignore-inhibitors",   no_argument,       NULL, 'i'                     },
5751                 { "user",                no_argument,       NULL, ARG_USER                },
5752                 { "system",              no_argument,       NULL, ARG_SYSTEM              },
5753                 { "global",              no_argument,       NULL, ARG_GLOBAL              },
5754                 { "no-block",            no_argument,       NULL, ARG_NO_BLOCK            },
5755                 { "no-legend",           no_argument,       NULL, ARG_NO_LEGEND           },
5756                 { "no-pager",            no_argument,       NULL, ARG_NO_PAGER            },
5757                 { "no-wall",             no_argument,       NULL, ARG_NO_WALL             },
5758                 { "quiet",               no_argument,       NULL, 'q'                     },
5759                 { "root",                required_argument, NULL, ARG_ROOT                },
5760                 { "force",               no_argument,       NULL, ARG_FORCE               },
5761                 { "no-reload",           no_argument,       NULL, ARG_NO_RELOAD           },
5762                 { "kill-who",            required_argument, NULL, ARG_KILL_WHO            },
5763                 { "signal",              required_argument, NULL, 's'                     },
5764                 { "no-ask-password",     no_argument,       NULL, ARG_NO_ASK_PASSWORD     },
5765                 { "host",                required_argument, NULL, 'H'                     },
5766                 { "machine",             required_argument, NULL, 'M'                     },
5767                 { "runtime",             no_argument,       NULL, ARG_RUNTIME             },
5768                 { "lines",               required_argument, NULL, 'n'                     },
5769                 { "output",              required_argument, NULL, 'o'                     },
5770                 { "plain",               no_argument,       NULL, ARG_PLAIN               },
5771                 { "state",               required_argument, NULL, ARG_STATE               },
5772                 { "recursive",           no_argument,       NULL, 'r'                     },
5773                 { "preset-mode",         required_argument, NULL, ARG_PRESET_MODE         },
5774                 {}
5775         };
5776
5777         int c;
5778
5779         assert(argc >= 0);
5780         assert(argv);
5781
5782         while ((c = getopt_long(argc, argv, "ht:p:alqfs:H:M:n:o:ir", options, NULL)) >= 0) {
5783
5784                 switch (c) {
5785
5786                 case 'h':
5787                         return systemctl_help();
5788
5789                 case ARG_VERSION:
5790                         puts(PACKAGE_STRING);
5791                         puts(SYSTEMD_FEATURES);
5792                         return 0;
5793
5794                 case 't': {
5795                         char *word, *state;
5796                         size_t size;
5797
5798                         FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
5799                                 _cleanup_free_ char *type;
5800
5801                                 type = strndup(word, size);
5802                                 if (!type)
5803                                         return -ENOMEM;
5804
5805                                 if (streq(type, "help")) {
5806                                         help_types();
5807                                         return 0;
5808                                 }
5809
5810                                 if (unit_type_from_string(type) >= 0) {
5811                                         if (strv_push(&arg_types, type))
5812                                                 return log_oom();
5813                                         type = NULL;
5814                                         continue;
5815                                 }
5816
5817                                 /* It's much nicer to use --state= for
5818                                  * load states, but let's support this
5819                                  * in --types= too for compatibility
5820                                  * with old versions */
5821                                 if (unit_load_state_from_string(optarg) >= 0) {
5822                                         if (strv_push(&arg_states, type) < 0)
5823                                                 return log_oom();
5824                                         type = NULL;
5825                                         continue;
5826                                 }
5827
5828                                 log_error("Unknown unit type or load state '%s'.", type);
5829                                 log_info("Use -t help to see a list of allowed values.");
5830                                 return -EINVAL;
5831                         }
5832
5833                         break;
5834                 }
5835
5836                 case 'p': {
5837                         /* Make sure that if the empty property list
5838                            was specified, we won't show any properties. */
5839                         if (isempty(optarg) && !arg_properties) {
5840                                 arg_properties = new0(char*, 1);
5841                                 if (!arg_properties)
5842                                         return log_oom();
5843                         } else {
5844                                 char *word, *state;
5845                                 size_t size;
5846
5847                                 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
5848                                         char *prop;
5849
5850                                         prop = strndup(word, size);
5851                                         if (!prop)
5852                                                 return log_oom();
5853
5854                                         if (strv_consume(&arg_properties, prop) < 0)
5855                                                 return log_oom();
5856                                 }
5857                         }
5858
5859                         /* If the user asked for a particular
5860                          * property, show it to him, even if it is
5861                          * empty. */
5862                         arg_all = true;
5863
5864                         break;
5865                 }
5866
5867                 case 'a':
5868                         arg_all = true;
5869                         break;
5870
5871                 case ARG_REVERSE:
5872                         arg_dependency = DEPENDENCY_REVERSE;
5873                         break;
5874
5875                 case ARG_AFTER:
5876                         arg_dependency = DEPENDENCY_AFTER;
5877                         break;
5878
5879                 case ARG_BEFORE:
5880                         arg_dependency = DEPENDENCY_BEFORE;
5881                         break;
5882
5883                 case ARG_SHOW_TYPES:
5884                         arg_show_types = true;
5885                         break;
5886
5887                 case ARG_JOB_MODE:
5888                         arg_job_mode = optarg;
5889                         break;
5890
5891                 case ARG_FAIL:
5892                         arg_job_mode = "fail";
5893                         break;
5894
5895                 case ARG_IRREVERSIBLE:
5896                         arg_job_mode = "replace-irreversibly";
5897                         break;
5898
5899                 case ARG_IGNORE_DEPENDENCIES:
5900                         arg_job_mode = "ignore-dependencies";
5901                         break;
5902
5903                 case ARG_USER:
5904                         arg_scope = UNIT_FILE_USER;
5905                         break;
5906
5907                 case ARG_SYSTEM:
5908                         arg_scope = UNIT_FILE_SYSTEM;
5909                         break;
5910
5911                 case ARG_GLOBAL:
5912                         arg_scope = UNIT_FILE_GLOBAL;
5913                         break;
5914
5915                 case ARG_NO_BLOCK:
5916                         arg_no_block = true;
5917                         break;
5918
5919                 case ARG_NO_LEGEND:
5920                         arg_no_legend = true;
5921                         break;
5922
5923                 case ARG_NO_PAGER:
5924                         arg_no_pager = true;
5925                         break;
5926
5927                 case ARG_NO_WALL:
5928                         arg_no_wall = true;
5929                         break;
5930
5931                 case ARG_ROOT:
5932                         arg_root = optarg;
5933                         break;
5934
5935                 case 'l':
5936                         arg_full = true;
5937                         break;
5938
5939                 case ARG_FAILED:
5940                         if (strv_extend(&arg_states, "failed") < 0)
5941                                 return log_oom();
5942
5943                         break;
5944
5945                 case 'q':
5946                         arg_quiet = true;
5947                         break;
5948
5949                 case ARG_FORCE:
5950                         arg_force ++;
5951                         break;
5952
5953                 case 'f':
5954                         arg_force ++;
5955                         break;
5956
5957                 case ARG_NO_RELOAD:
5958                         arg_no_reload = true;
5959                         break;
5960
5961                 case ARG_KILL_WHO:
5962                         arg_kill_who = optarg;
5963                         break;
5964
5965                 case 's':
5966                         if ((arg_signal = signal_from_string_try_harder(optarg)) < 0) {
5967                                 log_error("Failed to parse signal string %s.", optarg);
5968                                 return -EINVAL;
5969                         }
5970                         break;
5971
5972                 case ARG_NO_ASK_PASSWORD:
5973                         arg_ask_password = false;
5974                         break;
5975
5976                 case 'H':
5977                         arg_transport = BUS_TRANSPORT_REMOTE;
5978                         arg_host = optarg;
5979                         break;
5980
5981                 case 'M':
5982                         arg_transport = BUS_TRANSPORT_CONTAINER;
5983                         arg_host = optarg;
5984                         break;
5985
5986                 case ARG_RUNTIME:
5987                         arg_runtime = true;
5988                         break;
5989
5990                 case 'n':
5991                         if (safe_atou(optarg, &arg_lines) < 0) {
5992                                 log_error("Failed to parse lines '%s'", optarg);
5993                                 return -EINVAL;
5994                         }
5995                         break;
5996
5997                 case 'o':
5998                         arg_output = output_mode_from_string(optarg);
5999                         if (arg_output < 0) {
6000                                 log_error("Unknown output '%s'.", optarg);
6001                                 return -EINVAL;
6002                         }
6003                         break;
6004
6005                 case 'i':
6006                         arg_ignore_inhibitors = true;
6007                         break;
6008
6009                 case ARG_PLAIN:
6010                         arg_plain = true;
6011                         break;
6012
6013                 case ARG_STATE: {
6014                         char *word, *state;
6015                         size_t size;
6016
6017                         FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
6018                                 char *s;
6019
6020                                 s = strndup(word, size);
6021                                 if (!s)
6022                                         return log_oom();
6023
6024                                 if (strv_consume(&arg_states, s) < 0)
6025                                         return log_oom();
6026                         }
6027                         break;
6028                 }
6029
6030                 case 'r':
6031                         if (geteuid() != 0) {
6032                                 log_error("--recursive requires root privileges.");
6033                                 return -EPERM;
6034                         }
6035
6036                         arg_recursive = true;
6037                         break;
6038
6039                 case ARG_PRESET_MODE:
6040
6041                         arg_preset_mode = unit_file_preset_mode_from_string(optarg);
6042                         if (arg_preset_mode < 0) {
6043                                 log_error("Failed to parse preset mode: %s.", optarg);
6044                                 return -EINVAL;
6045                         }
6046
6047                         break;
6048
6049                 case '?':
6050                         return -EINVAL;
6051
6052                 default:
6053                         assert_not_reached("Unhandled option");
6054                 }
6055         }
6056
6057         if (arg_transport != BUS_TRANSPORT_LOCAL && arg_scope != UNIT_FILE_SYSTEM) {
6058                 log_error("Cannot access user instance remotely.");
6059                 return -EINVAL;
6060         }
6061
6062         return 1;
6063 }
6064
6065 static int halt_parse_argv(int argc, char *argv[]) {
6066
6067         enum {
6068                 ARG_HELP = 0x100,
6069                 ARG_HALT,
6070                 ARG_REBOOT,
6071                 ARG_NO_WALL
6072         };
6073
6074         static const struct option options[] = {
6075                 { "help",      no_argument,       NULL, ARG_HELP    },
6076                 { "halt",      no_argument,       NULL, ARG_HALT    },
6077                 { "poweroff",  no_argument,       NULL, 'p'         },
6078                 { "reboot",    no_argument,       NULL, ARG_REBOOT  },
6079                 { "force",     no_argument,       NULL, 'f'         },
6080                 { "wtmp-only", no_argument,       NULL, 'w'         },
6081                 { "no-wtmp",   no_argument,       NULL, 'd'         },
6082                 { "no-wall",   no_argument,       NULL, ARG_NO_WALL },
6083                 {}
6084         };
6085
6086         int c, r, runlevel;
6087
6088         assert(argc >= 0);
6089         assert(argv);
6090
6091         if (utmp_get_runlevel(&runlevel, NULL) >= 0)
6092                 if (runlevel == '0' || runlevel == '6')
6093                         arg_force = 2;
6094
6095         while ((c = getopt_long(argc, argv, "pfwdnih", options, NULL)) >= 0) {
6096                 switch (c) {
6097
6098                 case ARG_HELP:
6099                         return halt_help();
6100
6101                 case ARG_HALT:
6102                         arg_action = ACTION_HALT;
6103                         break;
6104
6105                 case 'p':
6106                         if (arg_action != ACTION_REBOOT)
6107                                 arg_action = ACTION_POWEROFF;
6108                         break;
6109
6110                 case ARG_REBOOT:
6111                         arg_action = ACTION_REBOOT;
6112                         break;
6113
6114                 case 'f':
6115                         arg_force = 2;
6116                         break;
6117
6118                 case 'w':
6119                         arg_dry = true;
6120                         break;
6121
6122                 case 'd':
6123                         arg_no_wtmp = true;
6124                         break;
6125
6126                 case ARG_NO_WALL:
6127                         arg_no_wall = true;
6128                         break;
6129
6130                 case 'i':
6131                 case 'h':
6132                 case 'n':
6133                         /* Compatibility nops */
6134                         break;
6135
6136                 case '?':
6137                         return -EINVAL;
6138
6139                 default:
6140                         assert_not_reached("Unhandled option");
6141                 }
6142         }
6143
6144         if (arg_action == ACTION_REBOOT && (argc == optind || argc == optind + 1)) {
6145                 r = update_reboot_param_file(argc == optind + 1 ? argv[optind] : NULL);
6146                 if (r < 0)
6147                         return r;
6148         } else if (optind < argc) {
6149                 log_error("Too many arguments.");
6150                 return -EINVAL;
6151         }
6152
6153         return 1;
6154 }
6155
6156 static int parse_time_spec(const char *t, usec_t *_u) {
6157         assert(t);
6158         assert(_u);
6159
6160         if (streq(t, "now"))
6161                 *_u = 0;
6162         else if (!strchr(t, ':')) {
6163                 uint64_t u;
6164
6165                 if (safe_atou64(t, &u) < 0)
6166                         return -EINVAL;
6167
6168                 *_u = now(CLOCK_REALTIME) + USEC_PER_MINUTE * u;
6169         } else {
6170                 char *e = NULL;
6171                 long hour, minute;
6172                 struct tm tm = {};
6173                 time_t s;
6174                 usec_t n;
6175
6176                 errno = 0;
6177                 hour = strtol(t, &e, 10);
6178                 if (errno > 0 || *e != ':' || hour < 0 || hour > 23)
6179                         return -EINVAL;
6180
6181                 minute = strtol(e+1, &e, 10);
6182                 if (errno > 0 || *e != 0 || minute < 0 || minute > 59)
6183                         return -EINVAL;
6184
6185                 n = now(CLOCK_REALTIME);
6186                 s = (time_t) (n / USEC_PER_SEC);
6187
6188                 assert_se(localtime_r(&s, &tm));
6189
6190                 tm.tm_hour = (int) hour;
6191                 tm.tm_min = (int) minute;
6192                 tm.tm_sec = 0;
6193
6194                 assert_se(s = mktime(&tm));
6195
6196                 *_u = (usec_t) s * USEC_PER_SEC;
6197
6198                 while (*_u <= n)
6199                         *_u += USEC_PER_DAY;
6200         }
6201
6202         return 0;
6203 }
6204
6205 static int shutdown_parse_argv(int argc, char *argv[]) {
6206
6207         enum {
6208                 ARG_HELP = 0x100,
6209                 ARG_NO_WALL
6210         };
6211
6212         static const struct option options[] = {
6213                 { "help",      no_argument,       NULL, ARG_HELP    },
6214                 { "halt",      no_argument,       NULL, 'H'         },
6215                 { "poweroff",  no_argument,       NULL, 'P'         },
6216                 { "reboot",    no_argument,       NULL, 'r'         },
6217                 { "kexec",     no_argument,       NULL, 'K'         }, /* not documented extension */
6218                 { "no-wall",   no_argument,       NULL, ARG_NO_WALL },
6219                 {}
6220         };
6221
6222         int c, r;
6223
6224         assert(argc >= 0);
6225         assert(argv);
6226
6227         while ((c = getopt_long(argc, argv, "HPrhkt:afFc", options, NULL)) >= 0) {
6228                 switch (c) {
6229
6230                 case ARG_HELP:
6231                         return shutdown_help();
6232
6233                 case 'H':
6234                         arg_action = ACTION_HALT;
6235                         break;
6236
6237                 case 'P':
6238                         arg_action = ACTION_POWEROFF;
6239                         break;
6240
6241                 case 'r':
6242                         if (kexec_loaded())
6243                                 arg_action = ACTION_KEXEC;
6244                         else
6245                                 arg_action = ACTION_REBOOT;
6246                         break;
6247
6248                 case 'K':
6249                         arg_action = ACTION_KEXEC;
6250                         break;
6251
6252                 case 'h':
6253                         if (arg_action != ACTION_HALT)
6254                                 arg_action = ACTION_POWEROFF;
6255                         break;
6256
6257                 case 'k':
6258                         arg_dry = true;
6259                         break;
6260
6261                 case ARG_NO_WALL:
6262                         arg_no_wall = true;
6263                         break;
6264
6265                 case 't':
6266                 case 'a':
6267                         /* Compatibility nops */
6268                         break;
6269
6270                 case 'c':
6271                         arg_action = ACTION_CANCEL_SHUTDOWN;
6272                         break;
6273
6274                 case '?':
6275                         return -EINVAL;
6276
6277                 default:
6278                         assert_not_reached("Unhandled option");
6279                 }
6280         }
6281
6282         if (argc > optind && arg_action != ACTION_CANCEL_SHUTDOWN) {
6283                 r = parse_time_spec(argv[optind], &arg_when);
6284                 if (r < 0) {
6285                         log_error("Failed to parse time specification: %s", argv[optind]);
6286                         return r;
6287                 }
6288         } else
6289                 arg_when = now(CLOCK_REALTIME) + USEC_PER_MINUTE;
6290
6291         if (argc > optind && arg_action == ACTION_CANCEL_SHUTDOWN)
6292                 /* No time argument for shutdown cancel */
6293                 arg_wall = argv + optind;
6294         else if (argc > optind + 1)
6295                 /* We skip the time argument */
6296                 arg_wall = argv + optind + 1;
6297
6298         optind = argc;
6299
6300         return 1;
6301 }
6302
6303 static int telinit_parse_argv(int argc, char *argv[]) {
6304
6305         enum {
6306                 ARG_HELP = 0x100,
6307                 ARG_NO_WALL
6308         };
6309
6310         static const struct option options[] = {
6311                 { "help",      no_argument,       NULL, ARG_HELP    },
6312                 { "no-wall",   no_argument,       NULL, ARG_NO_WALL },
6313                 {}
6314         };
6315
6316         static const struct {
6317                 char from;
6318                 enum action to;
6319         } table[] = {
6320                 { '0', ACTION_POWEROFF },
6321                 { '6', ACTION_REBOOT },
6322                 { '1', ACTION_RESCUE },
6323                 { '2', ACTION_RUNLEVEL2 },
6324                 { '3', ACTION_RUNLEVEL3 },
6325                 { '4', ACTION_RUNLEVEL4 },
6326                 { '5', ACTION_RUNLEVEL5 },
6327                 { 's', ACTION_RESCUE },
6328                 { 'S', ACTION_RESCUE },
6329                 { 'q', ACTION_RELOAD },
6330                 { 'Q', ACTION_RELOAD },
6331                 { 'u', ACTION_REEXEC },
6332                 { 'U', ACTION_REEXEC }
6333         };
6334
6335         unsigned i;
6336         int c;
6337
6338         assert(argc >= 0);
6339         assert(argv);
6340
6341         while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0) {
6342                 switch (c) {
6343
6344                 case ARG_HELP:
6345                         return telinit_help();
6346
6347                 case ARG_NO_WALL:
6348                         arg_no_wall = true;
6349                         break;
6350
6351                 case '?':
6352                         return -EINVAL;
6353
6354                 default:
6355                         assert_not_reached("Unhandled option");
6356                 }
6357         }
6358
6359         if (optind >= argc) {
6360                 telinit_help();
6361                 return -EINVAL;
6362         }
6363
6364         if (optind + 1 < argc) {
6365                 log_error("Too many arguments.");
6366                 return -EINVAL;
6367         }
6368
6369         if (strlen(argv[optind]) != 1) {
6370                 log_error("Expected single character argument.");
6371                 return -EINVAL;
6372         }
6373
6374         for (i = 0; i < ELEMENTSOF(table); i++)
6375                 if (table[i].from == argv[optind][0])
6376                         break;
6377
6378         if (i >= ELEMENTSOF(table)) {
6379                 log_error("Unknown command '%s'.", argv[optind]);
6380                 return -EINVAL;
6381         }
6382
6383         arg_action = table[i].to;
6384
6385         optind ++;
6386
6387         return 1;
6388 }
6389
6390 static int runlevel_parse_argv(int argc, char *argv[]) {
6391
6392         enum {
6393                 ARG_HELP = 0x100,
6394         };
6395
6396         static const struct option options[] = {
6397                 { "help",      no_argument,       NULL, ARG_HELP    },
6398                 {}
6399         };
6400
6401         int c;
6402
6403         assert(argc >= 0);
6404         assert(argv);
6405
6406         while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0) {
6407                 switch (c) {
6408
6409                 case ARG_HELP:
6410                         return runlevel_help();
6411
6412                 case '?':
6413                         return -EINVAL;
6414
6415                 default:
6416                         assert_not_reached("Unhandled option");
6417                 }
6418         }
6419
6420         if (optind < argc) {
6421                 log_error("Too many arguments.");
6422                 return -EINVAL;
6423         }
6424
6425         return 1;
6426 }
6427
6428 static int parse_argv(int argc, char *argv[]) {
6429         assert(argc >= 0);
6430         assert(argv);
6431
6432         if (program_invocation_short_name) {
6433
6434                 if (strstr(program_invocation_short_name, "halt")) {
6435                         arg_action = ACTION_HALT;
6436                         return halt_parse_argv(argc, argv);
6437                 } else if (strstr(program_invocation_short_name, "poweroff")) {
6438                         arg_action = ACTION_POWEROFF;
6439                         return halt_parse_argv(argc, argv);
6440                 } else if (strstr(program_invocation_short_name, "reboot")) {
6441                         if (kexec_loaded())
6442                                 arg_action = ACTION_KEXEC;
6443                         else
6444                                 arg_action = ACTION_REBOOT;
6445                         return halt_parse_argv(argc, argv);
6446                 } else if (strstr(program_invocation_short_name, "shutdown")) {
6447                         arg_action = ACTION_POWEROFF;
6448                         return shutdown_parse_argv(argc, argv);
6449                 } else if (strstr(program_invocation_short_name, "init")) {
6450
6451                         if (sd_booted() > 0) {
6452                                 arg_action = _ACTION_INVALID;
6453                                 return telinit_parse_argv(argc, argv);
6454                         } else {
6455                                 /* Hmm, so some other init system is
6456                                  * running, we need to forward this
6457                                  * request to it. For now we simply
6458                                  * guess that it is Upstart. */
6459
6460                                 execv(TELINIT, argv);
6461
6462                                 log_error("Couldn't find an alternative telinit implementation to spawn.");
6463                                 return -EIO;
6464                         }
6465
6466                 } else if (strstr(program_invocation_short_name, "runlevel")) {
6467                         arg_action = ACTION_RUNLEVEL;
6468                         return runlevel_parse_argv(argc, argv);
6469                 }
6470         }
6471
6472         arg_action = ACTION_SYSTEMCTL;
6473         return systemctl_parse_argv(argc, argv);
6474 }
6475
6476 _pure_ static int action_to_runlevel(void) {
6477
6478         static const char table[_ACTION_MAX] = {
6479                 [ACTION_HALT] =      '0',
6480                 [ACTION_POWEROFF] =  '0',
6481                 [ACTION_REBOOT] =    '6',
6482                 [ACTION_RUNLEVEL2] = '2',
6483                 [ACTION_RUNLEVEL3] = '3',
6484                 [ACTION_RUNLEVEL4] = '4',
6485                 [ACTION_RUNLEVEL5] = '5',
6486                 [ACTION_RESCUE] =    '1'
6487         };
6488
6489         assert(arg_action < _ACTION_MAX);
6490
6491         return table[arg_action];
6492 }
6493
6494 static int talk_initctl(void) {
6495
6496         struct init_request request = {
6497                 .magic = INIT_MAGIC,
6498                 .sleeptime  = 0,
6499                 .cmd = INIT_CMD_RUNLVL
6500         };
6501
6502         _cleanup_close_ int fd = -1;
6503         char rl;
6504         int r;
6505
6506         rl = action_to_runlevel();
6507         if (!rl)
6508                 return 0;
6509
6510         request.runlevel = rl;
6511
6512         fd = open(INIT_FIFO, O_WRONLY|O_NDELAY|O_CLOEXEC|O_NOCTTY);
6513         if (fd < 0) {
6514                 if (errno == ENOENT)
6515                         return 0;
6516
6517                 log_error("Failed to open "INIT_FIFO": %m");
6518                 return -errno;
6519         }
6520
6521         errno = 0;
6522         r = loop_write(fd, &request, sizeof(request), false) != sizeof(request);
6523         if (r) {
6524                 log_error("Failed to write to "INIT_FIFO": %m");
6525                 return errno > 0 ? -errno : -EIO;
6526         }
6527
6528         return 1;
6529 }
6530
6531 static int systemctl_main(sd_bus *bus, int argc, char *argv[], int bus_error) {
6532
6533         static const struct {
6534                 const char* verb;
6535                 const enum {
6536                         MORE,
6537                         LESS,
6538                         EQUAL
6539                 } argc_cmp;
6540                 const int argc;
6541                 int (* const dispatch)(sd_bus *bus, char **args);
6542                 const enum {
6543                         NOBUS = 1,
6544                         FORCE,
6545                 } bus;
6546         } verbs[] = {
6547                 { "list-units",            MORE,  0, list_units        },
6548                 { "list-unit-files",       MORE,  1, list_unit_files,  NOBUS },
6549                 { "list-sockets",          MORE,  1, list_sockets      },
6550                 { "list-timers",           MORE,  1, list_timers       },
6551                 { "list-jobs",             MORE,  1, list_jobs         },
6552                 { "list-machines",         MORE,  1, list_machines     },
6553                 { "clear-jobs",            EQUAL, 1, daemon_reload     },
6554                 { "cancel",                MORE,  2, cancel_job        },
6555                 { "start",                 MORE,  2, start_unit        },
6556                 { "stop",                  MORE,  2, start_unit        },
6557                 { "condstop",              MORE,  2, start_unit        }, /* For compatibility with ALTLinux */
6558                 { "reload",                MORE,  2, start_unit        },
6559                 { "restart",               MORE,  2, start_unit        },
6560                 { "try-restart",           MORE,  2, start_unit        },
6561                 { "reload-or-restart",     MORE,  2, start_unit        },
6562                 { "reload-or-try-restart", MORE,  2, start_unit        },
6563                 { "force-reload",          MORE,  2, start_unit        }, /* For compatibility with SysV */
6564                 { "condreload",            MORE,  2, start_unit        }, /* For compatibility with ALTLinux */
6565                 { "condrestart",           MORE,  2, start_unit        }, /* For compatibility with RH */
6566                 { "isolate",               EQUAL, 2, start_unit        },
6567                 { "kill",                  MORE,  2, kill_unit         },
6568                 { "is-active",             MORE,  2, check_unit_active },
6569                 { "check",                 MORE,  2, check_unit_active },
6570                 { "is-failed",             MORE,  2, check_unit_failed },
6571                 { "show",                  MORE,  1, show              },
6572                 { "cat",                   MORE,  2, cat               },
6573                 { "status",                MORE,  1, show              },
6574                 { "help",                  MORE,  2, show              },
6575                 { "snapshot",              LESS,  2, snapshot          },
6576                 { "delete",                MORE,  2, delete_snapshot   },
6577                 { "daemon-reload",         EQUAL, 1, daemon_reload     },
6578                 { "daemon-reexec",         EQUAL, 1, daemon_reload     },
6579                 { "show-environment",      EQUAL, 1, show_environment  },
6580                 { "set-environment",       MORE,  2, set_environment   },
6581                 { "unset-environment",     MORE,  2, set_environment   },
6582                 { "import-environment",    MORE,  1, import_environment},
6583                 { "halt",                  EQUAL, 1, start_special,    FORCE },
6584                 { "poweroff",              EQUAL, 1, start_special,    FORCE },
6585                 { "reboot",                EQUAL, 1, start_special,    FORCE },
6586                 { "kexec",                 EQUAL, 1, start_special     },
6587                 { "suspend",               EQUAL, 1, start_special     },
6588                 { "hibernate",             EQUAL, 1, start_special     },
6589                 { "hybrid-sleep",          EQUAL, 1, start_special     },
6590                 { "default",               EQUAL, 1, start_special     },
6591                 { "rescue",                EQUAL, 1, start_special     },
6592                 { "emergency",             EQUAL, 1, start_special     },
6593                 { "exit",                  EQUAL, 1, start_special     },
6594                 { "reset-failed",          MORE,  1, reset_failed      },
6595                 { "enable",                MORE,  2, enable_unit,      NOBUS },
6596                 { "disable",               MORE,  2, enable_unit,      NOBUS },
6597                 { "is-enabled",            MORE,  2, unit_is_enabled,  NOBUS },
6598                 { "reenable",              MORE,  2, enable_unit,      NOBUS },
6599                 { "preset",                MORE,  2, enable_unit,      NOBUS },
6600                 { "preset-all",            EQUAL, 1, preset_all,       NOBUS },
6601                 { "mask",                  MORE,  2, enable_unit,      NOBUS },
6602                 { "unmask",                MORE,  2, enable_unit,      NOBUS },
6603                 { "link",                  MORE,  2, enable_unit,      NOBUS },
6604                 { "switch-root",           MORE,  2, switch_root       },
6605                 { "list-dependencies",     LESS,  2, list_dependencies },
6606                 { "set-default",           EQUAL, 2, set_default,      NOBUS },
6607                 { "get-default",           EQUAL, 1, get_default,      NOBUS },
6608                 { "set-property",          MORE,  3, set_property      },
6609                 { "is-system-running",     EQUAL, 1, is_system_running },
6610                 {}
6611         }, *verb = verbs;
6612
6613         int left;
6614
6615         assert(argc >= 0);
6616         assert(argv);
6617
6618         left = argc - optind;
6619
6620         /* Special rule: no arguments (left == 0) means "list-units" */
6621         if (left > 0) {
6622                 if (streq(argv[optind], "help") && !argv[optind+1]) {
6623                         log_error("This command expects one or more "
6624                                   "unit names. Did you mean --help?");
6625                         return -EINVAL;
6626                 }
6627
6628                 for (; verb->verb; verb++)
6629                         if (streq(argv[optind], verb->verb))
6630                                 goto found;
6631
6632                 log_error("Unknown operation '%s'.", argv[optind]);
6633                 return -EINVAL;
6634         }
6635 found:
6636
6637         switch (verb->argc_cmp) {
6638
6639         case EQUAL:
6640                 if (left != verb->argc) {
6641                         log_error("Invalid number of arguments.");
6642                         return -EINVAL;
6643                 }
6644
6645                 break;
6646
6647         case MORE:
6648                 if (left < verb->argc) {
6649                         log_error("Too few arguments.");
6650                         return -EINVAL;
6651                 }
6652
6653                 break;
6654
6655         case LESS:
6656                 if (left > verb->argc) {
6657                         log_error("Too many arguments.");
6658                         return -EINVAL;
6659                 }
6660
6661                 break;
6662
6663         default:
6664                 assert_not_reached("Unknown comparison operator.");
6665         }
6666
6667         /* Require a bus connection for all operations but
6668          * enable/disable */
6669         if (verb->bus == NOBUS) {
6670                 if (!bus && !avoid_bus()) {
6671                         log_error("Failed to get D-Bus connection: %s", strerror(-bus_error));
6672                         return -EIO;
6673                 }
6674
6675         } else {
6676                 if (running_in_chroot() > 0) {
6677                         log_info("Running in chroot, ignoring request.");
6678                         return 0;
6679                 }
6680
6681                 if ((verb->bus != FORCE || arg_force <= 0) && !bus) {
6682                         log_error("Failed to get D-Bus connection: %s", strerror(-bus_error));
6683                         return -EIO;
6684                 }
6685         }
6686
6687         return verb->dispatch(bus, argv + optind);
6688 }
6689
6690 static int send_shutdownd(usec_t t, char mode, bool dry_run, bool warn, const char *message) {
6691
6692         struct sd_shutdown_command c = {
6693                 .usec = t,
6694                 .mode = mode,
6695                 .dry_run = dry_run,
6696                 .warn_wall = warn,
6697         };
6698
6699         union sockaddr_union sockaddr = {
6700                 .un.sun_family = AF_UNIX,
6701                 .un.sun_path = "/run/systemd/shutdownd",
6702         };
6703
6704         struct iovec iovec[2] = {{
6705                  .iov_base = (char*) &c,
6706                  .iov_len = offsetof(struct sd_shutdown_command, wall_message),
6707         }};
6708
6709         struct msghdr msghdr = {
6710                 .msg_name = &sockaddr,
6711                 .msg_namelen = offsetof(struct sockaddr_un, sun_path)
6712                                + strlen("/run/systemd/shutdownd"),
6713                 .msg_iov = iovec,
6714                 .msg_iovlen = 1,
6715         };
6716
6717         _cleanup_close_ int fd;
6718
6719         fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
6720         if (fd < 0)
6721                 return -errno;
6722
6723         if (!isempty(message)) {
6724                 iovec[1].iov_base = (char*) message;
6725                 iovec[1].iov_len = strlen(message);
6726                 msghdr.msg_iovlen++;
6727         }
6728
6729         if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) < 0)
6730                 return -errno;
6731
6732         return 0;
6733 }
6734
6735 static int reload_with_fallback(sd_bus *bus) {
6736
6737         if (bus) {
6738                 /* First, try systemd via D-Bus. */
6739                 if (daemon_reload(bus, NULL) >= 0)
6740                         return 0;
6741         }
6742
6743         /* Nothing else worked, so let's try signals */
6744         assert(arg_action == ACTION_RELOAD || arg_action == ACTION_REEXEC);
6745
6746         if (kill(1, arg_action == ACTION_RELOAD ? SIGHUP : SIGTERM) < 0) {
6747                 log_error("kill() failed: %m");
6748                 return -errno;
6749         }
6750
6751         return 0;
6752 }
6753
6754 static int start_with_fallback(sd_bus *bus) {
6755
6756         if (bus) {
6757                 /* First, try systemd via D-Bus. */
6758                 if (start_unit(bus, NULL) >= 0)
6759                         goto done;
6760         }
6761
6762         /* Nothing else worked, so let's try
6763          * /dev/initctl */
6764         if (talk_initctl() > 0)
6765                 goto done;
6766
6767         log_error("Failed to talk to init daemon.");
6768         return -EIO;
6769
6770 done:
6771         warn_wall(arg_action);
6772         return 0;
6773 }
6774
6775 static int halt_now(enum action a) {
6776
6777 /* Make sure C-A-D is handled by the kernel from this
6778          * point on... */
6779         reboot(RB_ENABLE_CAD);
6780
6781         switch (a) {
6782
6783         case ACTION_HALT:
6784                 log_info("Halting.");
6785                 reboot(RB_HALT_SYSTEM);
6786                 return -errno;
6787
6788         case ACTION_POWEROFF:
6789                 log_info("Powering off.");
6790                 reboot(RB_POWER_OFF);
6791                 return -errno;
6792
6793         case ACTION_REBOOT: {
6794                 _cleanup_free_ char *param = NULL;
6795
6796                 if (read_one_line_file(REBOOT_PARAM_FILE, &param) >= 0) {
6797                         log_info("Rebooting with argument '%s'.", param);
6798                         syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
6799                                 LINUX_REBOOT_CMD_RESTART2, param);
6800                 }
6801
6802                 log_info("Rebooting.");
6803                 reboot(RB_AUTOBOOT);
6804                 return -errno;
6805         }
6806
6807         default:
6808                 assert_not_reached("Unknown action.");
6809         }
6810 }
6811
6812 static int halt_main(sd_bus *bus) {
6813         int r;
6814
6815         r = check_inhibitors(bus, arg_action);
6816         if (r < 0)
6817                 return r;
6818
6819         if (geteuid() != 0) {
6820                 /* Try logind if we are a normal user and no special
6821                  * mode applies. Maybe PolicyKit allows us to shutdown
6822                  * the machine. */
6823
6824                 if (arg_when <= 0 &&
6825                     !arg_dry &&
6826                     arg_force <= 0 &&
6827                     (arg_action == ACTION_POWEROFF ||
6828                      arg_action == ACTION_REBOOT)) {
6829                         r = reboot_with_logind(bus, arg_action);
6830                         if (r >= 0)
6831                                 return r;
6832                 }
6833
6834                 log_error("Must be root.");
6835                 return -EPERM;
6836         }
6837
6838         if (arg_when > 0) {
6839                 _cleanup_free_ char *m;
6840
6841                 m = strv_join(arg_wall, " ");
6842                 if (!m)
6843                         return log_oom();
6844
6845                 r = send_shutdownd(arg_when,
6846                                    arg_action == ACTION_HALT     ? 'H' :
6847                                    arg_action == ACTION_POWEROFF ? 'P' :
6848                                    arg_action == ACTION_KEXEC    ? 'K' :
6849                                                                    'r',
6850                                    arg_dry,
6851                                    !arg_no_wall,
6852                                    m);
6853
6854                 if (r < 0)
6855                         log_warning("Failed to talk to shutdownd, proceeding with immediate shutdown: %s", strerror(-r));
6856                 else {
6857                         char date[FORMAT_TIMESTAMP_MAX];
6858
6859                         log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.",
6860                                  format_timestamp(date, sizeof(date), arg_when));
6861                         return 0;
6862                 }
6863         }
6864
6865         if (!arg_dry && !arg_force)
6866                 return start_with_fallback(bus);
6867
6868         if (!arg_no_wtmp) {
6869                 if (sd_booted() > 0)
6870                         log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
6871                 else {
6872                         r = utmp_put_shutdown();
6873                         if (r < 0)
6874                                 log_warning("Failed to write utmp record: %s", strerror(-r));
6875                 }
6876         }
6877
6878         if (arg_dry)
6879                 return 0;
6880
6881         r = halt_now(arg_action);
6882         log_error("Failed to reboot: %s", strerror(-r));
6883
6884         return r;
6885 }
6886
6887 static int runlevel_main(void) {
6888         int r, runlevel, previous;
6889
6890         r = utmp_get_runlevel(&runlevel, &previous);
6891         if (r < 0) {
6892                 puts("unknown");
6893                 return r;
6894         }
6895
6896         printf("%c %c\n",
6897                previous <= 0 ? 'N' : previous,
6898                runlevel <= 0 ? 'N' : runlevel);
6899
6900         return 0;
6901 }
6902
6903 int main(int argc, char*argv[]) {
6904         _cleanup_bus_unref_ sd_bus *bus = NULL;
6905         int r;
6906
6907         setlocale(LC_ALL, "");
6908         log_parse_environment();
6909         log_open();
6910
6911         /* Explicitly not on_tty() to avoid setting cached value.
6912          * This becomes relevant for piping output which might be
6913          * ellipsized. */
6914         original_stdout_is_tty = isatty(STDOUT_FILENO);
6915
6916         r = parse_argv(argc, argv);
6917         if (r <= 0)
6918                 goto finish;
6919
6920         /* /sbin/runlevel doesn't need to communicate via D-Bus, so
6921          * let's shortcut this */
6922         if (arg_action == ACTION_RUNLEVEL) {
6923                 r = runlevel_main();
6924                 goto finish;
6925         }
6926
6927         if (running_in_chroot() > 0 && arg_action != ACTION_SYSTEMCTL) {
6928                 log_info("Running in chroot, ignoring request.");
6929                 r = 0;
6930                 goto finish;
6931         }
6932
6933         if (!avoid_bus())
6934                 r = bus_open_transport_systemd(arg_transport, arg_host, arg_scope != UNIT_FILE_SYSTEM, &bus);
6935
6936         /* systemctl_main() will print an error message for the bus
6937          * connection, but only if it needs to */
6938
6939         switch (arg_action) {
6940
6941         case ACTION_SYSTEMCTL:
6942                 r = systemctl_main(bus, argc, argv, r);
6943                 break;
6944
6945         case ACTION_HALT:
6946         case ACTION_POWEROFF:
6947         case ACTION_REBOOT:
6948         case ACTION_KEXEC:
6949                 r = halt_main(bus);
6950                 break;
6951
6952         case ACTION_RUNLEVEL2:
6953         case ACTION_RUNLEVEL3:
6954         case ACTION_RUNLEVEL4:
6955         case ACTION_RUNLEVEL5:
6956         case ACTION_RESCUE:
6957         case ACTION_EMERGENCY:
6958         case ACTION_DEFAULT:
6959                 r = start_with_fallback(bus);
6960                 break;
6961
6962         case ACTION_RELOAD:
6963         case ACTION_REEXEC:
6964                 r = reload_with_fallback(bus);
6965                 break;
6966
6967         case ACTION_CANCEL_SHUTDOWN: {
6968                 _cleanup_free_ char *m = NULL;
6969
6970                 if (arg_wall) {
6971                         m = strv_join(arg_wall, " ");
6972                         if (!m) {
6973                                 r = log_oom();
6974                                 goto finish;
6975                         }
6976                 }
6977
6978                 r = send_shutdownd(arg_when, SD_SHUTDOWN_NONE, false, !arg_no_wall, m);
6979                 if (r < 0)
6980                         log_warning("Failed to talk to shutdownd, shutdown hasn't been cancelled: %s", strerror(-r));
6981                 break;
6982         }
6983
6984         case ACTION_RUNLEVEL:
6985         case _ACTION_INVALID:
6986         default:
6987                 assert_not_reached("Unknown action");
6988         }
6989
6990 finish:
6991         pager_close();
6992         ask_password_agent_close();
6993         polkit_agent_close();
6994
6995         strv_free(arg_types);
6996         strv_free(arg_states);
6997         strv_free(arg_properties);
6998
6999         return r < 0 ? EXIT_FAILURE : r;
7000 }