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