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