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