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