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