chiark / gitweb /
systemctl: do not show dots with --plain
[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         LIST_HEAD(ExecStatusInfo, exec);
3228 } UnitStatusInfo;
3229
3230 static void print_status_info(
3231                 UnitStatusInfo *i,
3232                 bool *ellipsized) {
3233
3234         ExecStatusInfo *p;
3235         const char *active_on, *active_off, *on, *off, *ss;
3236         usec_t timestamp;
3237         char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
3238         char since2[FORMAT_TIMESTAMP_MAX], *s2;
3239         const char *path;
3240         char **t, **t2;
3241
3242         assert(i);
3243
3244         /* This shows pretty information about a unit. See
3245          * print_property() for a low-level property printer */
3246
3247         if (streq_ptr(i->active_state, "failed")) {
3248                 active_on = ansi_highlight_red();
3249                 active_off = ansi_highlight_off();
3250         } else if (streq_ptr(i->active_state, "active") || streq_ptr(i->active_state, "reloading")) {
3251                 active_on = ansi_highlight_green();
3252                 active_off = ansi_highlight_off();
3253         } else
3254                 active_on = active_off = "";
3255
3256         printf("%s%s%s %s", active_on, draw_special_char(DRAW_BLACK_CIRCLE), active_off, strna(i->id));
3257
3258         if (i->description && !streq_ptr(i->id, i->description))
3259                 printf(" - %s", i->description);
3260
3261         printf("\n");
3262
3263         if (i->following)
3264                 printf("   Follow: unit currently follows state of %s\n", i->following);
3265
3266         if (streq_ptr(i->load_state, "error")) {
3267                 on = ansi_highlight_red();
3268                 off = ansi_highlight_off();
3269         } else
3270                 on = off = "";
3271
3272         path = i->source_path ? i->source_path : i->fragment_path;
3273
3274         if (i->load_error)
3275                 printf("   Loaded: %s%s%s (Reason: %s)\n",
3276                        on, strna(i->load_state), off, i->load_error);
3277         else if (path && !isempty(i->unit_file_state) && !isempty(i->unit_file_preset))
3278                 printf("   Loaded: %s%s%s (%s; %s; vendor preset: %s)\n",
3279                        on, strna(i->load_state), off, path, i->unit_file_state, i->unit_file_preset);
3280         else if (path && !isempty(i->unit_file_state))
3281                 printf("   Loaded: %s%s%s (%s; %s)\n",
3282                        on, strna(i->load_state), off, path, i->unit_file_state);
3283         else if (path)
3284                 printf("   Loaded: %s%s%s (%s)\n",
3285                        on, strna(i->load_state), off, path);
3286         else
3287                 printf("   Loaded: %s%s%s\n",
3288                        on, strna(i->load_state), off);
3289
3290         if (!strv_isempty(i->dropin_paths)) {
3291                 _cleanup_free_ char *dir = NULL;
3292                 bool last = false;
3293                 char ** dropin;
3294
3295                 STRV_FOREACH(dropin, i->dropin_paths) {
3296                         if (! dir || last) {
3297                                 printf(dir ? "        " : "  Drop-In: ");
3298
3299                                 free(dir);
3300                                 dir = NULL;
3301
3302                                 if (path_get_parent(*dropin, &dir) < 0) {
3303                                         log_oom();
3304                                         return;
3305                                 }
3306
3307                                 printf("%s\n           %s", dir,
3308                                        draw_special_char(DRAW_TREE_RIGHT));
3309                         }
3310
3311                         last = ! (*(dropin + 1) && startswith(*(dropin + 1), dir));
3312
3313                         printf("%s%s", basename(*dropin), last ? "\n" : ", ");
3314                 }
3315         }
3316
3317         ss = streq_ptr(i->active_state, i->sub_state) ? NULL : i->sub_state;
3318         if (ss)
3319                 printf("   Active: %s%s (%s)%s",
3320                        active_on, strna(i->active_state), ss, active_off);
3321         else
3322                 printf("   Active: %s%s%s",
3323                        active_on, strna(i->active_state), active_off);
3324
3325         if (!isempty(i->result) && !streq(i->result, "success"))
3326                 printf(" (Result: %s)", i->result);
3327
3328         timestamp = (streq_ptr(i->active_state, "active")      ||
3329                      streq_ptr(i->active_state, "reloading"))   ? i->active_enter_timestamp :
3330                     (streq_ptr(i->active_state, "inactive")    ||
3331                      streq_ptr(i->active_state, "failed"))      ? i->inactive_enter_timestamp :
3332                     streq_ptr(i->active_state, "activating")    ? i->inactive_exit_timestamp :
3333                                                                   i->active_exit_timestamp;
3334
3335         s1 = format_timestamp_relative(since1, sizeof(since1), timestamp);
3336         s2 = format_timestamp(since2, sizeof(since2), timestamp);
3337
3338         if (s1)
3339                 printf(" since %s; %s\n", s2, s1);
3340         else if (s2)
3341                 printf(" since %s\n", s2);
3342         else
3343                 printf("\n");
3344
3345         if (!i->condition_result && i->condition_timestamp > 0) {
3346                 s1 = format_timestamp_relative(since1, sizeof(since1), i->condition_timestamp);
3347                 s2 = format_timestamp(since2, sizeof(since2), i->condition_timestamp);
3348
3349                 printf("Condition: start %scondition failed%s at %s%s%s\n",
3350                        ansi_highlight_yellow(), ansi_highlight_off(),
3351                        s2, s1 ? "; " : "", s1 ? s1 : "");
3352                 if (i->failed_condition_trigger)
3353                         printf("           none of the trigger conditions were met\n");
3354                 else if (i->failed_condition)
3355                         printf("           %s=%s%s was not met\n",
3356                                i->failed_condition,
3357                                i->failed_condition_negate ? "!" : "",
3358                                i->failed_condition_parameter);
3359         }
3360
3361         if (!i->assert_result && i->assert_timestamp > 0) {
3362                 s1 = format_timestamp_relative(since1, sizeof(since1), i->assert_timestamp);
3363                 s2 = format_timestamp(since2, sizeof(since2), i->assert_timestamp);
3364
3365                 printf("   Assert: start %sassertion failed%s at %s%s%s\n",
3366                        ansi_highlight_red(), ansi_highlight_off(),
3367                        s2, s1 ? "; " : "", s1 ? s1 : "");
3368                 if (i->failed_assert_trigger)
3369                         printf("           none of the trigger assertions were met\n");
3370                 else if (i->failed_assert)
3371                         printf("           %s=%s%s was not met\n",
3372                                i->failed_assert,
3373                                i->failed_assert_negate ? "!" : "",
3374                                i->failed_assert_parameter);
3375         }
3376
3377         if (i->sysfs_path)
3378                 printf("   Device: %s\n", i->sysfs_path);
3379         if (i->where)
3380                 printf("    Where: %s\n", i->where);
3381         if (i->what)
3382                 printf("     What: %s\n", i->what);
3383
3384         STRV_FOREACH(t, i->documentation)
3385                 printf(" %*s %s\n", 9, t == i->documentation ? "Docs:" : "", *t);
3386
3387         STRV_FOREACH_PAIR(t, t2, i->listen)
3388                 printf(" %*s %s (%s)\n", 9, t == i->listen ? "Listen:" : "", *t2, *t);
3389
3390         if (i->accept)
3391                 printf(" Accepted: %u; Connected: %u\n", i->n_accepted, i->n_connections);
3392
3393         LIST_FOREACH(exec, p, i->exec) {
3394                 _cleanup_free_ char *argv = NULL;
3395                 bool good;
3396
3397                 /* Only show exited processes here */
3398                 if (p->code == 0)
3399                         continue;
3400
3401                 argv = strv_join(p->argv, " ");
3402                 printf("  Process: %u %s=%s ", p->pid, p->name, strna(argv));
3403
3404                 good = is_clean_exit_lsb(p->code, p->status, NULL);
3405                 if (!good) {
3406                         on = ansi_highlight_red();
3407                         off = ansi_highlight_off();
3408                 } else
3409                         on = off = "";
3410
3411                 printf("%s(code=%s, ", on, sigchld_code_to_string(p->code));
3412
3413                 if (p->code == CLD_EXITED) {
3414                         const char *c;
3415
3416                         printf("status=%i", p->status);
3417
3418                         c = exit_status_to_string(p->status, EXIT_STATUS_SYSTEMD);
3419                         if (c)
3420                                 printf("/%s", c);
3421
3422                 } else
3423                         printf("signal=%s", signal_to_string(p->status));
3424
3425                 printf(")%s\n", off);
3426
3427                 if (i->main_pid == p->pid &&
3428                     i->start_timestamp == p->start_timestamp &&
3429                     i->exit_timestamp == p->start_timestamp)
3430                         /* Let's not show this twice */
3431                         i->main_pid = 0;
3432
3433                 if (p->pid == i->control_pid)
3434                         i->control_pid = 0;
3435         }
3436
3437         if (i->main_pid > 0 || i->control_pid > 0) {
3438                 if (i->main_pid > 0) {
3439                         printf(" Main PID: "PID_FMT, i->main_pid);
3440
3441                         if (i->running) {
3442                                 _cleanup_free_ char *comm = NULL;
3443                                 get_process_comm(i->main_pid, &comm);
3444                                 if (comm)
3445                                         printf(" (%s)", comm);
3446                         } else if (i->exit_code > 0) {
3447                                 printf(" (code=%s, ", sigchld_code_to_string(i->exit_code));
3448
3449                                 if (i->exit_code == CLD_EXITED) {
3450                                         const char *c;
3451
3452                                         printf("status=%i", i->exit_status);
3453
3454                                         c = exit_status_to_string(i->exit_status, EXIT_STATUS_SYSTEMD);
3455                                         if (c)
3456                                                 printf("/%s", c);
3457
3458                                 } else
3459                                         printf("signal=%s", signal_to_string(i->exit_status));
3460                                 printf(")");
3461                         }
3462
3463                         if (i->control_pid > 0)
3464                                 printf(";");
3465                 }
3466
3467                 if (i->control_pid > 0) {
3468                         _cleanup_free_ char *c = NULL;
3469
3470                         printf(" %8s: "PID_FMT, i->main_pid ? "" : " Control", i->control_pid);
3471
3472                         get_process_comm(i->control_pid, &c);
3473                         if (c)
3474                                 printf(" (%s)", c);
3475                 }
3476
3477                 printf("\n");
3478         }
3479
3480         if (i->status_text)
3481                 printf("   Status: \"%s\"\n", i->status_text);
3482         if (i->status_errno > 0)
3483                 printf("    Error: %i (%s)\n", i->status_errno, strerror(i->status_errno));
3484
3485         if (i->control_group &&
3486             (i->main_pid > 0 || i->control_pid > 0 ||
3487              ((arg_transport != BUS_TRANSPORT_LOCAL && arg_transport != BUS_TRANSPORT_MACHINE) || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, i->control_group, false) == 0))) {
3488                 unsigned c;
3489
3490                 printf("   CGroup: %s\n", i->control_group);
3491
3492                 if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_MACHINE) {
3493                         unsigned k = 0;
3494                         pid_t extra[2];
3495                         static const char prefix[] = "           ";
3496
3497                         c = columns();
3498                         if (c > sizeof(prefix) - 1)
3499                                 c -= sizeof(prefix) - 1;
3500                         else
3501                                 c = 0;
3502
3503                         if (i->main_pid > 0)
3504                                 extra[k++] = i->main_pid;
3505
3506                         if (i->control_pid > 0)
3507                                 extra[k++] = i->control_pid;
3508
3509                         show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, i->control_group, prefix, c, false, extra, k, get_output_flags());
3510                 }
3511         }
3512
3513         if (i->id && arg_transport == BUS_TRANSPORT_LOCAL) {
3514                 show_journal_by_unit(
3515                                 stdout,
3516                                 i->id,
3517                                 arg_output,
3518                                 0,
3519                                 i->inactive_exit_timestamp_monotonic,
3520                                 arg_lines,
3521                                 getuid(),
3522                                 get_output_flags() | OUTPUT_BEGIN_NEWLINE,
3523                                 SD_JOURNAL_LOCAL_ONLY,
3524                                 arg_scope == UNIT_FILE_SYSTEM,
3525                                 ellipsized);
3526         }
3527
3528         if (i->need_daemon_reload)
3529                 warn_unit_file_changed(i->id);
3530 }
3531
3532 static void show_unit_help(UnitStatusInfo *i) {
3533         char **p;
3534
3535         assert(i);
3536
3537         if (!i->documentation) {
3538                 log_info("Documentation for %s not known.", i->id);
3539                 return;
3540         }
3541
3542         STRV_FOREACH(p, i->documentation)
3543                 if (startswith(*p, "man:"))
3544                         show_man_page(*p + 4, false);
3545                 else
3546                         log_info("Can't show: %s", *p);
3547 }
3548
3549 static int status_property(const char *name, sd_bus_message *m, UnitStatusInfo *i, const char *contents) {
3550         int r;
3551
3552         assert(name);
3553         assert(m);
3554         assert(i);
3555
3556         switch (contents[0]) {
3557
3558         case SD_BUS_TYPE_STRING: {
3559                 const char *s;
3560
3561                 r = sd_bus_message_read(m, "s", &s);
3562                 if (r < 0)
3563                         return bus_log_parse_error(r);
3564
3565                 if (!isempty(s)) {
3566                         if (streq(name, "Id"))
3567                                 i->id = s;
3568                         else if (streq(name, "LoadState"))
3569                                 i->load_state = s;
3570                         else if (streq(name, "ActiveState"))
3571                                 i->active_state = s;
3572                         else if (streq(name, "SubState"))
3573                                 i->sub_state = s;
3574                         else if (streq(name, "Description"))
3575                                 i->description = s;
3576                         else if (streq(name, "FragmentPath"))
3577                                 i->fragment_path = s;
3578                         else if (streq(name, "SourcePath"))
3579                                 i->source_path = s;
3580 #ifndef NOLEGACY
3581                         else if (streq(name, "DefaultControlGroup")) {
3582                                 const char *e;
3583                                 e = startswith(s, SYSTEMD_CGROUP_CONTROLLER ":");
3584                                 if (e)
3585                                         i->control_group = e;
3586                         }
3587 #endif
3588                         else if (streq(name, "ControlGroup"))
3589                                 i->control_group = s;
3590                         else if (streq(name, "StatusText"))
3591                                 i->status_text = s;
3592                         else if (streq(name, "PIDFile"))
3593                                 i->pid_file = s;
3594                         else if (streq(name, "SysFSPath"))
3595                                 i->sysfs_path = s;
3596                         else if (streq(name, "Where"))
3597                                 i->where = s;
3598                         else if (streq(name, "What"))
3599                                 i->what = s;
3600                         else if (streq(name, "Following"))
3601                                 i->following = s;
3602                         else if (streq(name, "UnitFileState"))
3603                                 i->unit_file_state = s;
3604                         else if (streq(name, "UnitFilePreset"))
3605                                 i->unit_file_preset = s;
3606                         else if (streq(name, "Result"))
3607                                 i->result = s;
3608                 }
3609
3610                 break;
3611         }
3612
3613         case SD_BUS_TYPE_BOOLEAN: {
3614                 int b;
3615
3616                 r = sd_bus_message_read(m, "b", &b);
3617                 if (r < 0)
3618                         return bus_log_parse_error(r);
3619
3620                 if (streq(name, "Accept"))
3621                         i->accept = b;
3622                 else if (streq(name, "NeedDaemonReload"))
3623                         i->need_daemon_reload = b;
3624                 else if (streq(name, "ConditionResult"))
3625                         i->condition_result = b;
3626                 else if (streq(name, "AssertResult"))
3627                         i->assert_result = b;
3628
3629                 break;
3630         }
3631
3632         case SD_BUS_TYPE_UINT32: {
3633                 uint32_t u;
3634
3635                 r = sd_bus_message_read(m, "u", &u);
3636                 if (r < 0)
3637                         return bus_log_parse_error(r);
3638
3639                 if (streq(name, "MainPID")) {
3640                         if (u > 0) {
3641                                 i->main_pid = (pid_t) u;
3642                                 i->running = true;
3643                         }
3644                 } else if (streq(name, "ControlPID"))
3645                         i->control_pid = (pid_t) u;
3646                 else if (streq(name, "ExecMainPID")) {
3647                         if (u > 0)
3648                                 i->main_pid = (pid_t) u;
3649                 } else if (streq(name, "NAccepted"))
3650                         i->n_accepted = u;
3651                 else if (streq(name, "NConnections"))
3652                         i->n_connections = u;
3653
3654                 break;
3655         }
3656
3657         case SD_BUS_TYPE_INT32: {
3658                 int32_t j;
3659
3660                 r = sd_bus_message_read(m, "i", &j);
3661                 if (r < 0)
3662                         return bus_log_parse_error(r);
3663
3664                 if (streq(name, "ExecMainCode"))
3665                         i->exit_code = (int) j;
3666                 else if (streq(name, "ExecMainStatus"))
3667                         i->exit_status = (int) j;
3668                 else if (streq(name, "StatusErrno"))
3669                         i->status_errno = (int) j;
3670
3671                 break;
3672         }
3673
3674         case SD_BUS_TYPE_UINT64: {
3675                 uint64_t u;
3676
3677                 r = sd_bus_message_read(m, "t", &u);
3678                 if (r < 0)
3679                         return bus_log_parse_error(r);
3680
3681                 if (streq(name, "ExecMainStartTimestamp"))
3682                         i->start_timestamp = (usec_t) u;
3683                 else if (streq(name, "ExecMainExitTimestamp"))
3684                         i->exit_timestamp = (usec_t) u;
3685                 else if (streq(name, "ActiveEnterTimestamp"))
3686                         i->active_enter_timestamp = (usec_t) u;
3687                 else if (streq(name, "InactiveEnterTimestamp"))
3688                         i->inactive_enter_timestamp = (usec_t) u;
3689                 else if (streq(name, "InactiveExitTimestamp"))
3690                         i->inactive_exit_timestamp = (usec_t) u;
3691                 else if (streq(name, "InactiveExitTimestampMonotonic"))
3692                         i->inactive_exit_timestamp_monotonic = (usec_t) u;
3693                 else if (streq(name, "ActiveExitTimestamp"))
3694                         i->active_exit_timestamp = (usec_t) u;
3695                 else if (streq(name, "ConditionTimestamp"))
3696                         i->condition_timestamp = (usec_t) u;
3697                 else if (streq(name, "AssertTimestamp"))
3698                         i->assert_timestamp = (usec_t) u;
3699
3700                 break;
3701         }
3702
3703         case SD_BUS_TYPE_ARRAY:
3704
3705                 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3706                         _cleanup_free_ ExecStatusInfo *info = NULL;
3707
3708                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3709                         if (r < 0)
3710                                 return bus_log_parse_error(r);
3711
3712                         info = new0(ExecStatusInfo, 1);
3713                         if (!info)
3714                                 return log_oom();
3715
3716                         while ((r = exec_status_info_deserialize(m, info)) > 0) {
3717
3718                                 info->name = strdup(name);
3719                                 if (!info->name)
3720                                         log_oom();
3721
3722                                 LIST_PREPEND(exec, i->exec, info);
3723
3724                                 info = new0(ExecStatusInfo, 1);
3725                                 if (!info)
3726                                         log_oom();
3727                         }
3728
3729                         if (r < 0)
3730                                 return bus_log_parse_error(r);
3731
3732                         r = sd_bus_message_exit_container(m);
3733                         if (r < 0)
3734                                 return bus_log_parse_error(r);
3735
3736                         return 0;
3737
3738                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3739                         const char *type, *path;
3740
3741                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3742                         if (r < 0)
3743                                 return bus_log_parse_error(r);
3744
3745                         while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0) {
3746
3747                                 r = strv_extend(&i->listen, type);
3748                                 if (r < 0)
3749                                         return r;
3750
3751                                 r = strv_extend(&i->listen, path);
3752                                 if (r < 0)
3753                                         return r;
3754                         }
3755                         if (r < 0)
3756                                 return bus_log_parse_error(r);
3757
3758                         r = sd_bus_message_exit_container(m);
3759                         if (r < 0)
3760                                 return bus_log_parse_error(r);
3761
3762                         return 0;
3763
3764                 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "DropInPaths")) {
3765
3766                         r = sd_bus_message_read_strv(m, &i->dropin_paths);
3767                         if (r < 0)
3768                                 return bus_log_parse_error(r);
3769
3770                 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Documentation")) {
3771
3772                         r = sd_bus_message_read_strv(m, &i->documentation);
3773                         if (r < 0)
3774                                 return bus_log_parse_error(r);
3775
3776                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Conditions")) {
3777                         const char *cond, *param;
3778                         int trigger, negate;
3779                         int32_t state;
3780
3781                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
3782                         if (r < 0)
3783                                 return bus_log_parse_error(r);
3784
3785                         while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, &param, &state)) > 0) {
3786                                 log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
3787                                 if (state < 0 && (!trigger || !i->failed_condition)) {
3788                                         i->failed_condition = cond;
3789                                         i->failed_condition_trigger = trigger;
3790                                         i->failed_condition_negate = negate;
3791                                         i->failed_condition_parameter = param;
3792                                 }
3793                         }
3794                         if (r < 0)
3795                                 return bus_log_parse_error(r);
3796
3797                         r = sd_bus_message_exit_container(m);
3798                         if (r < 0)
3799                                 return bus_log_parse_error(r);
3800
3801                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Asserts")) {
3802                         const char *cond, *param;
3803                         int trigger, negate;
3804                         int32_t state;
3805
3806                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
3807                         if (r < 0)
3808                                 return bus_log_parse_error(r);
3809
3810                         while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, &param, &state)) > 0) {
3811                                 log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
3812                                 if (state < 0 && (!trigger || !i->failed_assert)) {
3813                                         i->failed_assert = cond;
3814                                         i->failed_assert_trigger = trigger;
3815                                         i->failed_assert_negate = negate;
3816                                         i->failed_assert_parameter = param;
3817                                 }
3818                         }
3819                         if (r < 0)
3820                                 return bus_log_parse_error(r);
3821
3822                         r = sd_bus_message_exit_container(m);
3823                         if (r < 0)
3824                                 return bus_log_parse_error(r);
3825
3826                 } else
3827                         goto skip;
3828
3829                 break;
3830
3831         case SD_BUS_TYPE_STRUCT_BEGIN:
3832
3833                 if (streq(name, "LoadError")) {
3834                         const char *n, *message;
3835
3836                         r = sd_bus_message_read(m, "(ss)", &n, &message);
3837                         if (r < 0)
3838                                 return bus_log_parse_error(r);
3839
3840                         if (!isempty(message))
3841                                 i->load_error = message;
3842                 } else
3843                         goto skip;
3844
3845                 break;
3846
3847         default:
3848                 goto skip;
3849         }
3850
3851         return 0;
3852
3853 skip:
3854         r = sd_bus_message_skip(m, contents);
3855         if (r < 0)
3856                 return bus_log_parse_error(r);
3857
3858         return 0;
3859 }
3860
3861 static int print_property(const char *name, sd_bus_message *m, const char *contents) {
3862         int r;
3863
3864         assert(name);
3865         assert(m);
3866
3867         /* This is a low-level property printer, see
3868          * print_status_info() for the nicer output */
3869
3870         if (arg_properties && !strv_find(arg_properties, name)) {
3871                 /* skip what we didn't read */
3872                 r = sd_bus_message_skip(m, contents);
3873                 return r;
3874         }
3875
3876         switch (contents[0]) {
3877
3878         case SD_BUS_TYPE_STRUCT_BEGIN:
3879
3880                 if (contents[1] == SD_BUS_TYPE_UINT32 && streq(name, "Job")) {
3881                         uint32_t u;
3882
3883                         r = sd_bus_message_read(m, "(uo)", &u, NULL);
3884                         if (r < 0)
3885                                 return bus_log_parse_error(r);
3886
3887                         if (u > 0)
3888                                 printf("%s=%"PRIu32"\n", name, u);
3889                         else if (arg_all)
3890                                 printf("%s=\n", name);
3891
3892                         return 0;
3893
3894                 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Unit")) {
3895                         const char *s;
3896
3897                         r = sd_bus_message_read(m, "(so)", &s, NULL);
3898                         if (r < 0)
3899                                 return bus_log_parse_error(r);
3900
3901                         if (arg_all || !isempty(s))
3902                                 printf("%s=%s\n", name, s);
3903
3904                         return 0;
3905
3906                 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "LoadError")) {
3907                         const char *a = NULL, *b = NULL;
3908
3909                         r = sd_bus_message_read(m, "(ss)", &a, &b);
3910                         if (r < 0)
3911                                 return bus_log_parse_error(r);
3912
3913                         if (arg_all || !isempty(a) || !isempty(b))
3914                                 printf("%s=%s \"%s\"\n", name, strempty(a), strempty(b));
3915
3916                         return 0;
3917                 } else if (streq_ptr(name, "SystemCallFilter")) {
3918                         _cleanup_strv_free_ char **l = NULL;
3919                         int whitelist;
3920
3921                         r = sd_bus_message_enter_container(m, 'r', "bas");
3922                         if (r < 0)
3923                                 return bus_log_parse_error(r);
3924
3925                         r = sd_bus_message_read(m, "b", &whitelist);
3926                         if (r < 0)
3927                                 return bus_log_parse_error(r);
3928
3929                         r = sd_bus_message_read_strv(m, &l);
3930                         if (r < 0)
3931                                 return bus_log_parse_error(r);
3932
3933                         r = sd_bus_message_exit_container(m);
3934                         if (r < 0)
3935                                 return bus_log_parse_error(r);
3936
3937                         if (arg_all || whitelist || !strv_isempty(l)) {
3938                                 bool first = true;
3939                                 char **i;
3940
3941                                 fputs(name, stdout);
3942                                 fputc('=', stdout);
3943
3944                                 if (!whitelist)
3945                                         fputc('~', stdout);
3946
3947                                 STRV_FOREACH(i, l) {
3948                                         if (first)
3949                                                 first = false;
3950                                         else
3951                                                 fputc(' ', stdout);
3952
3953                                         fputs(*i, stdout);
3954                                 }
3955                                 fputc('\n', stdout);
3956                         }
3957
3958                         return 0;
3959                 }
3960
3961                 break;
3962
3963         case SD_BUS_TYPE_ARRAY:
3964
3965                 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "EnvironmentFiles")) {
3966                         const char *path;
3967                         int ignore;
3968
3969                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sb)");
3970                         if (r < 0)
3971                                 return bus_log_parse_error(r);
3972
3973                         while ((r = sd_bus_message_read(m, "(sb)", &path, &ignore)) > 0)
3974                                 printf("EnvironmentFile=%s (ignore_errors=%s)\n", path, yes_no(ignore));
3975
3976                         if (r < 0)
3977                                 return bus_log_parse_error(r);
3978
3979                         r = sd_bus_message_exit_container(m);
3980                         if (r < 0)
3981                                 return bus_log_parse_error(r);
3982
3983                         return 0;
3984
3985                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Paths")) {
3986                         const char *type, *path;
3987
3988                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3989                         if (r < 0)
3990                                 return bus_log_parse_error(r);
3991
3992                         while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
3993                                 printf("%s=%s\n", type, path);
3994                         if (r < 0)
3995                                 return bus_log_parse_error(r);
3996
3997                         r = sd_bus_message_exit_container(m);
3998                         if (r < 0)
3999                                 return bus_log_parse_error(r);
4000
4001                         return 0;
4002
4003                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
4004                         const char *type, *path;
4005
4006                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
4007                         if (r < 0)
4008                                 return bus_log_parse_error(r);
4009
4010                         while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
4011                                 printf("Listen%s=%s\n", type, path);
4012                         if (r < 0)
4013                                 return bus_log_parse_error(r);
4014
4015                         r = sd_bus_message_exit_container(m);
4016                         if (r < 0)
4017                                 return bus_log_parse_error(r);
4018
4019                         return 0;
4020
4021                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Timers")) {
4022                         const char *base;
4023                         uint64_t value, next_elapse;
4024
4025                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(stt)");
4026                         if (r < 0)
4027                                 return bus_log_parse_error(r);
4028
4029                         while ((r = sd_bus_message_read(m, "(stt)", &base, &value, &next_elapse)) > 0) {
4030                                 char timespan1[FORMAT_TIMESPAN_MAX], timespan2[FORMAT_TIMESPAN_MAX];
4031
4032                                 printf("%s={ value=%s ; next_elapse=%s }\n",
4033                                        base,
4034                                        format_timespan(timespan1, sizeof(timespan1), value, 0),
4035                                        format_timespan(timespan2, sizeof(timespan2), next_elapse, 0));
4036                         }
4037                         if (r < 0)
4038                                 return bus_log_parse_error(r);
4039
4040                         r = sd_bus_message_exit_container(m);
4041                         if (r < 0)
4042                                 return bus_log_parse_error(r);
4043
4044                         return 0;
4045
4046                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
4047                         ExecStatusInfo info = {};
4048
4049                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
4050                         if (r < 0)
4051                                 return bus_log_parse_error(r);
4052
4053                         while ((r = exec_status_info_deserialize(m, &info)) > 0) {
4054                                 char timestamp1[FORMAT_TIMESTAMP_MAX], timestamp2[FORMAT_TIMESTAMP_MAX];
4055                                 _cleanup_free_ char *tt;
4056
4057                                 tt = strv_join(info.argv, " ");
4058
4059                                 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",
4060                                        name,
4061                                        strna(info.path),
4062                                        strna(tt),
4063                                        yes_no(info.ignore),
4064                                        strna(format_timestamp(timestamp1, sizeof(timestamp1), info.start_timestamp)),
4065                                        strna(format_timestamp(timestamp2, sizeof(timestamp2), info.exit_timestamp)),
4066                                        info.pid,
4067                                        sigchld_code_to_string(info.code),
4068                                        info.status,
4069                                        info.code == CLD_EXITED ? "" : "/",
4070                                        strempty(info.code == CLD_EXITED ? NULL : signal_to_string(info.status)));
4071
4072                                 free(info.path);
4073                                 strv_free(info.argv);
4074                                 zero(info);
4075                         }
4076
4077                         r = sd_bus_message_exit_container(m);
4078                         if (r < 0)
4079                                 return bus_log_parse_error(r);
4080
4081                         return 0;
4082
4083                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "DeviceAllow")) {
4084                         const char *path, *rwm;
4085
4086                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
4087                         if (r < 0)
4088                                 return bus_log_parse_error(r);
4089
4090                         while ((r = sd_bus_message_read(m, "(ss)", &path, &rwm)) > 0)
4091                                 printf("%s=%s %s\n", name, strna(path), strna(rwm));
4092                         if (r < 0)
4093                                 return bus_log_parse_error(r);
4094
4095                         r = sd_bus_message_exit_container(m);
4096                         if (r < 0)
4097                                 return bus_log_parse_error(r);
4098
4099                         return 0;
4100
4101                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "BlockIODeviceWeight")) {
4102                         const char *path;
4103                         uint64_t weight;
4104
4105                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
4106                         if (r < 0)
4107                                 return bus_log_parse_error(r);
4108
4109                         while ((r = sd_bus_message_read(m, "(st)", &path, &weight)) > 0)
4110                                 printf("%s=%s %" PRIu64 "\n", name, strna(path), weight);
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, "BlockIOReadBandwidth") || streq(name, "BlockIOWriteBandwidth"))) {
4121                         const char *path;
4122                         uint64_t bandwidth;
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, &bandwidth)) > 0)
4129                                 printf("%s=%s %" PRIu64 "\n", name, strna(path), bandwidth);
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
4140                 break;
4141         }
4142
4143         r = bus_print_property(name, m, arg_all);
4144         if (r < 0)
4145                 return bus_log_parse_error(r);
4146
4147         if (r == 0) {
4148                 r = sd_bus_message_skip(m, contents);
4149                 if (r < 0)
4150                         return bus_log_parse_error(r);
4151
4152                 if (arg_all)
4153                         printf("%s=[unprintable]\n", name);
4154         }
4155
4156         return 0;
4157 }
4158
4159 static int show_one(
4160                 const char *verb,
4161                 sd_bus *bus,
4162                 const char *path,
4163                 bool show_properties,
4164                 bool *new_line,
4165                 bool *ellipsized) {
4166
4167         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4168         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4169         UnitStatusInfo info = {};
4170         ExecStatusInfo *p;
4171         int r;
4172
4173         assert(path);
4174         assert(new_line);
4175
4176         log_debug("Showing one %s", path);
4177
4178         r = sd_bus_call_method(
4179                         bus,
4180                         "org.freedesktop.systemd1",
4181                         path,
4182                         "org.freedesktop.DBus.Properties",
4183                         "GetAll",
4184                         &error,
4185                         &reply,
4186                         "s", "");
4187         if (r < 0) {
4188                 log_error("Failed to get properties: %s", bus_error_message(&error, r));
4189                 return r;
4190         }
4191
4192         r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
4193         if (r < 0)
4194                 return bus_log_parse_error(r);
4195
4196         if (*new_line)
4197                 printf("\n");
4198
4199         *new_line = true;
4200
4201         while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
4202                 const char *name, *contents;
4203
4204                 r = sd_bus_message_read(reply, "s", &name);
4205                 if (r < 0)
4206                         return bus_log_parse_error(r);
4207
4208                 r = sd_bus_message_peek_type(reply, NULL, &contents);
4209                 if (r < 0)
4210                         return bus_log_parse_error(r);
4211
4212                 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, contents);
4213                 if (r < 0)
4214                         return bus_log_parse_error(r);
4215
4216                 if (show_properties)
4217                         r = print_property(name, reply, contents);
4218                 else
4219                         r = status_property(name, reply, &info, contents);
4220                 if (r < 0)
4221                         return r;
4222
4223                 r = sd_bus_message_exit_container(reply);
4224                 if (r < 0)
4225                         return bus_log_parse_error(r);
4226
4227                 r = sd_bus_message_exit_container(reply);
4228                 if (r < 0)
4229                         return bus_log_parse_error(r);
4230         }
4231         if (r < 0)
4232                 return bus_log_parse_error(r);
4233
4234         r = sd_bus_message_exit_container(reply);
4235         if (r < 0)
4236                 return bus_log_parse_error(r);
4237
4238         r = 0;
4239
4240         if (!show_properties) {
4241                 if (streq(verb, "help"))
4242                         show_unit_help(&info);
4243                 else
4244                         print_status_info(&info, ellipsized);
4245         }
4246
4247         strv_free(info.documentation);
4248         strv_free(info.dropin_paths);
4249         strv_free(info.listen);
4250
4251         if (!streq_ptr(info.active_state, "active") &&
4252             !streq_ptr(info.active_state, "reloading") &&
4253             streq(verb, "status")) {
4254                 /* According to LSB: "program not running" */
4255                 /* 0: program is running or service is OK
4256                  * 1: program is dead and /run PID file exists
4257                  * 2: program is dead and /run/lock lock file exists
4258                  * 3: program is not running
4259                  * 4: program or service status is unknown
4260                  */
4261                 if (info.pid_file && access(info.pid_file, F_OK) == 0)
4262                         r = 1;
4263                 else
4264                         r = 3;
4265         }
4266
4267         while ((p = info.exec)) {
4268                 LIST_REMOVE(exec, info.exec, p);
4269                 exec_status_info_free(p);
4270         }
4271
4272         return r;
4273 }
4274
4275 static int get_unit_dbus_path_by_pid(
4276                 sd_bus *bus,
4277                 uint32_t pid,
4278                 char **unit) {
4279
4280         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4281         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4282         char *u;
4283         int r;
4284
4285         r = sd_bus_call_method(
4286                         bus,
4287                         "org.freedesktop.systemd1",
4288                         "/org/freedesktop/systemd1",
4289                         "org.freedesktop.systemd1.Manager",
4290                         "GetUnitByPID",
4291                         &error,
4292                         &reply,
4293                         "u", pid);
4294         if (r < 0) {
4295                 log_error("Failed to get unit for PID "PID_FMT": %s", pid, bus_error_message(&error, r));
4296                 return r;
4297         }
4298
4299         r = sd_bus_message_read(reply, "o", &u);
4300         if (r < 0)
4301                 return bus_log_parse_error(r);
4302
4303         u = strdup(u);
4304         if (!u)
4305                 return log_oom();
4306
4307         *unit = u;
4308         return 0;
4309 }
4310
4311 static int show_all(
4312                 const char* verb,
4313                 sd_bus *bus,
4314                 bool show_properties,
4315                 bool *new_line,
4316                 bool *ellipsized) {
4317
4318         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4319         _cleanup_free_ UnitInfo *unit_infos = NULL;
4320         const UnitInfo *u;
4321         unsigned c;
4322         int r, ret = 0;
4323
4324         r = get_unit_list(bus, NULL, NULL, &unit_infos, 0, &reply);
4325         if (r < 0)
4326                 return r;
4327
4328         pager_open_if_enabled();
4329
4330         c = (unsigned) r;
4331
4332         qsort_safe(unit_infos, c, sizeof(UnitInfo), compare_unit_info);
4333
4334         for (u = unit_infos; u < unit_infos + c; u++) {
4335                 _cleanup_free_ char *p = NULL;
4336
4337                 p = unit_dbus_path_from_name(u->id);
4338                 if (!p)
4339                         return log_oom();
4340
4341                 r = show_one(verb, bus, p, show_properties, new_line, ellipsized);
4342                 if (r < 0)
4343                         return r;
4344                 else if (r > 0 && ret == 0)
4345                         ret = r;
4346         }
4347
4348         return ret;
4349 }
4350
4351 static int show_system_status(sd_bus *bus) {
4352         char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], since2[FORMAT_TIMESTAMP_MAX];
4353         _cleanup_free_ char *hn = NULL;
4354         struct machine_info mi = {};
4355         const char *on, *off;
4356         int r;
4357
4358         hn = gethostname_malloc();
4359         if (!hn)
4360                 return log_oom();
4361
4362         r = bus_map_all_properties(bus, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map, &mi);
4363         if (r < 0)
4364                 return log_error_errno(r, "Failed to read server status: %m");
4365
4366         if (streq_ptr(mi.state, "degraded")) {
4367                 on = ansi_highlight_red();
4368                 off = ansi_highlight_off();
4369         } else if (!streq_ptr(mi.state, "running")) {
4370                 on = ansi_highlight_yellow();
4371                 off = ansi_highlight_off();
4372         } else
4373                 on = off = "";
4374
4375         printf("%s%s%s %s\n", on, draw_special_char(DRAW_BLACK_CIRCLE), off, arg_host ? arg_host : hn);
4376
4377         printf("    State: %s%s%s\n",
4378                on, strna(mi.state), off);
4379
4380         printf("     Jobs: %u queued\n", mi.n_jobs);
4381         printf("   Failed: %u units\n", mi.n_failed_units);
4382
4383         printf("    Since: %s; %s\n",
4384                format_timestamp(since2, sizeof(since2), mi.timestamp),
4385                format_timestamp_relative(since1, sizeof(since1), mi.timestamp));
4386
4387         printf("   CGroup: %s\n", mi.control_group ?: "/");
4388         if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_MACHINE) {
4389                 static const char prefix[] = "           ";
4390                 unsigned c;
4391
4392                 c = columns();
4393                 if (c > sizeof(prefix) - 1)
4394                         c -= sizeof(prefix) - 1;
4395                 else
4396                         c = 0;
4397
4398                 show_cgroup(SYSTEMD_CGROUP_CONTROLLER, strempty(mi.control_group), prefix, c, false, get_output_flags());
4399         }
4400
4401         free(mi.state);
4402         free(mi.control_group);
4403
4404         return 0;
4405 }
4406
4407 static int show(sd_bus *bus, char **args) {
4408         bool show_properties, show_status, new_line = false;
4409         bool ellipsized = false;
4410         int r, ret = 0;
4411
4412         assert(bus);
4413         assert(args);
4414
4415         show_properties = streq(args[0], "show");
4416         show_status = streq(args[0], "status");
4417
4418         if (show_properties)
4419                 pager_open_if_enabled();
4420
4421         /* If no argument is specified inspect the manager itself */
4422
4423         if (show_properties && strv_length(args) <= 1)
4424                 return show_one(args[0], bus, "/org/freedesktop/systemd1", show_properties, &new_line, &ellipsized);
4425
4426         if (show_status && strv_length(args) <= 1) {
4427
4428                 pager_open_if_enabled();
4429                 show_system_status(bus);
4430                 new_line = true;
4431
4432                 if (arg_all)
4433                         ret = show_all(args[0], bus, false, &new_line, &ellipsized);
4434         } else {
4435                 _cleanup_free_ char **patterns = NULL;
4436                 char **name;
4437
4438                 STRV_FOREACH(name, args + 1) {
4439                         _cleanup_free_ char *unit = NULL;
4440                         uint32_t id;
4441
4442                         if (safe_atou32(*name, &id) < 0) {
4443                                 if (strv_push(&patterns, *name) < 0)
4444                                         return log_oom();
4445
4446                                 continue;
4447                         } else if (show_properties) {
4448                                 /* Interpret as job id */
4449                                 if (asprintf(&unit, "/org/freedesktop/systemd1/job/%u", id) < 0)
4450                                         return log_oom();
4451
4452                         } else {
4453                                 /* Interpret as PID */
4454                                 r = get_unit_dbus_path_by_pid(bus, id, &unit);
4455                                 if (r < 0) {
4456                                         ret = r;
4457                                         continue;
4458                                 }
4459                         }
4460
4461                         r = show_one(args[0], bus, unit, show_properties,
4462                                      &new_line, &ellipsized);
4463                         if (r < 0)
4464                                 return r;
4465                         else if (r > 0 && ret == 0)
4466                                 ret = r;
4467                 }
4468
4469                 if (!strv_isempty(patterns)) {
4470                         _cleanup_strv_free_ char **names = NULL;
4471
4472                         r = expand_names(bus, patterns, NULL, &names);
4473                         if (r < 0)
4474                                 log_error_errno(r, "Failed to expand names: %m");
4475
4476                         STRV_FOREACH(name, names) {
4477                                 _cleanup_free_ char *unit;
4478
4479                                 unit = unit_dbus_path_from_name(*name);
4480                                 if (!unit)
4481                                         return log_oom();
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         }
4492
4493         if (ellipsized && !arg_quiet)
4494                 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
4495
4496         return ret;
4497 }
4498
4499 static int init_home_and_lookup_paths(char **user_home, char **user_runtime, LookupPaths *lp) {
4500         int r;
4501
4502         assert(user_home);
4503         assert(user_runtime);
4504         assert(lp);
4505
4506         if (arg_scope == UNIT_FILE_USER) {
4507                 r = user_config_home(user_home);
4508                 if (r < 0)
4509                         return log_error_errno(r, "Failed to query XDG_CONFIG_HOME: %m");
4510                 else if (r == 0)
4511                         return log_error_errno(ENOTDIR, "Cannot find units: $XDG_CONFIG_HOME and $HOME are not set.");
4512
4513                 r = user_runtime_dir(user_runtime);
4514                 if (r < 0)
4515                         return log_error_errno(r, "Failed to query XDG_CONFIG_HOME: %m");
4516                 else if (r == 0)
4517                         return log_error_errno(ENOTDIR, "Cannot find units: $XDG_RUNTIME_DIR is not set.");
4518         }
4519
4520         r = lookup_paths_init_from_scope(lp, arg_scope, arg_root);
4521         if (r < 0)
4522                 return log_error_errno(r, "Failed to lookup unit lookup paths: %m");
4523
4524         return 0;
4525 }
4526
4527 static int cat(sd_bus *bus, char **args) {
4528         _cleanup_free_ char *user_home = NULL;
4529         _cleanup_free_ char *user_runtime = NULL;
4530         _cleanup_lookup_paths_free_ LookupPaths lp = {};
4531         _cleanup_strv_free_ char **names = NULL;
4532         char **name;
4533         bool first = true, avoid_bus_cache;
4534         int r = 0;
4535
4536         assert(args);
4537
4538         r = init_home_and_lookup_paths(&user_home, &user_runtime, &lp);
4539         if (r < 0)
4540                 return r;
4541
4542         r = expand_names(bus, args + 1, NULL, &names);
4543         if (r < 0)
4544                 log_error_errno(r, "Failed to expand names: %m");
4545
4546         avoid_bus_cache = !bus || avoid_bus();
4547
4548         pager_open_if_enabled();
4549
4550         STRV_FOREACH(name, names) {
4551                 _cleanup_free_ char *fragment_path = NULL;
4552                 _cleanup_strv_free_ char **dropin_paths = NULL;
4553                 char **path;
4554
4555                 r = unit_find_paths(bus, *name, avoid_bus_cache, &lp, &fragment_path, &dropin_paths);
4556                 if (r < 0)
4557                         return r;
4558                 else if (r == 0) {
4559                         log_warning("Unit %s does not have any files on disk", *name);
4560                         continue;
4561                 }
4562
4563                 if (first)
4564                         first = false;
4565                 else
4566                         puts("");
4567
4568                 if (fragment_path) {
4569                         printf("%s# %s%s\n",
4570                                ansi_highlight_blue(),
4571                                fragment_path,
4572                                ansi_highlight_off());
4573                         fflush(stdout);
4574
4575                         r = copy_file_fd(fragment_path, STDOUT_FILENO, false);
4576                         if (r < 0) {
4577                                 log_warning_errno(r, "Failed to cat %s: %m", fragment_path);
4578                                 continue;
4579                         }
4580                 }
4581
4582                 STRV_FOREACH(path, dropin_paths) {
4583                         printf("%s%s# %s%s\n",
4584                                isempty(fragment_path) && path == dropin_paths ? "" : "\n",
4585                                ansi_highlight_blue(),
4586                                *path,
4587                                ansi_highlight_off());
4588                         fflush(stdout);
4589
4590                         r = copy_file_fd(*path, STDOUT_FILENO, false);
4591                         if (r < 0) {
4592                                 log_warning_errno(r, "Failed to cat %s: %m", *path);
4593                                 continue;
4594                         }
4595                 }
4596         }
4597
4598         return r < 0 ? r : 0;
4599 }
4600
4601 static int set_property(sd_bus *bus, char **args) {
4602         _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4603         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4604         _cleanup_free_ char *n = NULL;
4605         char **i;
4606         int r;
4607
4608         polkit_agent_open_if_enabled();
4609
4610         r = sd_bus_message_new_method_call(
4611                         bus,
4612                         &m,
4613                         "org.freedesktop.systemd1",
4614                         "/org/freedesktop/systemd1",
4615                         "org.freedesktop.systemd1.Manager",
4616                         "SetUnitProperties");
4617         if (r < 0)
4618                 return bus_log_create_error(r);
4619
4620         r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4621         if (r < 0)
4622                 return bus_log_create_error(r);
4623
4624         n = unit_name_mangle(args[1], MANGLE_NOGLOB);
4625         if (!n)
4626                 return log_oom();
4627
4628         r = sd_bus_message_append(m, "sb", n, arg_runtime);
4629         if (r < 0)
4630                 return bus_log_create_error(r);
4631
4632         r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, "(sv)");
4633         if (r < 0)
4634                 return bus_log_create_error(r);
4635
4636         STRV_FOREACH(i, args + 2) {
4637                 r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv");
4638                 if (r < 0)
4639                         return bus_log_create_error(r);
4640
4641                 r = bus_append_unit_property_assignment(m, *i);
4642                 if (r < 0)
4643                         return r;
4644
4645                 r = sd_bus_message_close_container(m);
4646                 if (r < 0)
4647                         return bus_log_create_error(r);
4648         }
4649
4650         r = sd_bus_message_close_container(m);
4651         if (r < 0)
4652                 return bus_log_create_error(r);
4653
4654         r = sd_bus_call(bus, m, 0, &error, NULL);
4655         if (r < 0) {
4656                 log_error("Failed to set unit properties on %s: %s", n, bus_error_message(&error, r));
4657                 return r;
4658         }
4659
4660         return 0;
4661 }
4662
4663 static int snapshot(sd_bus *bus, char **args) {
4664         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4665         _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
4666         _cleanup_free_ char *n = NULL, *id = NULL;
4667         const char *path;
4668         int r;
4669
4670         polkit_agent_open_if_enabled();
4671
4672         if (strv_length(args) > 1)
4673                 n = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".snapshot");
4674         else
4675                 n = strdup("");
4676         if (!n)
4677                 return log_oom();
4678
4679         r = sd_bus_message_new_method_call(
4680                         bus,
4681                         &m,
4682                         "org.freedesktop.systemd1",
4683                         "/org/freedesktop/systemd1",
4684                         "org.freedesktop.systemd1.Manager",
4685                         "CreateSnapshot");
4686         if (r < 0)
4687                 return bus_log_create_error(r);
4688
4689         r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4690         if (r < 0)
4691                 return bus_log_create_error(r);
4692
4693         r = sd_bus_message_append(m, "sb", n, false);
4694         if (r < 0)
4695                 return bus_log_create_error(r);
4696
4697         r = sd_bus_call(bus, m, 0, &error, &reply);
4698         if (r < 0) {
4699                 log_error("Failed to create snapshot: %s", bus_error_message(&error, r));
4700                 return r;
4701         }
4702
4703         r = sd_bus_message_read(reply, "o", &path);
4704         if (r < 0)
4705                 return bus_log_parse_error(r);
4706
4707         r = sd_bus_get_property_string(
4708                         bus,
4709                         "org.freedesktop.systemd1",
4710                         path,
4711                         "org.freedesktop.systemd1.Unit",
4712                         "Id",
4713                         &error,
4714                         &id);
4715         if (r < 0) {
4716                 log_error("Failed to get ID of snapshot: %s", bus_error_message(&error, r));
4717                 return r;
4718         }
4719
4720         if (!arg_quiet)
4721                 puts(id);
4722
4723         return 0;
4724 }
4725
4726 static int delete_snapshot(sd_bus *bus, char **args) {
4727         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4728         _cleanup_strv_free_ char **names = NULL;
4729         char **name;
4730         int r;
4731
4732         assert(args);
4733
4734         polkit_agent_open_if_enabled();
4735
4736         r = expand_names(bus, args + 1, ".snapshot", &names);
4737         if (r < 0)
4738                 log_error_errno(r, "Failed to expand names: %m");
4739
4740         STRV_FOREACH(name, names) {
4741                 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4742                 int q;
4743
4744                 q = sd_bus_message_new_method_call(
4745                                 bus,
4746                                 &m,
4747                                 "org.freedesktop.systemd1",
4748                                 "/org/freedesktop/systemd1",
4749                                 "org.freedesktop.systemd1.Manager",
4750                                 "RemoveSnapshot");
4751                 if (q < 0)
4752                         return bus_log_create_error(q);
4753
4754                 q = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4755                 if (q < 0)
4756                         return bus_log_create_error(q);
4757
4758                 q = sd_bus_message_append(m, "s", *name);
4759                 if (q < 0)
4760                         return bus_log_create_error(q);
4761
4762                 q = sd_bus_call(bus, m, 0, &error, NULL);
4763                 if (q < 0) {
4764                         log_error("Failed to remove snapshot %s: %s", *name, bus_error_message(&error, q));
4765                         if (r == 0)
4766                                 r = q;
4767                 }
4768         }
4769
4770         return r;
4771 }
4772
4773 static int daemon_reload(sd_bus *bus, char **args) {
4774         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4775         _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4776         const char *method;
4777         int r;
4778
4779         polkit_agent_open_if_enabled();
4780
4781         if (arg_action == ACTION_RELOAD)
4782                 method = "Reload";
4783         else if (arg_action == ACTION_REEXEC)
4784                 method = "Reexecute";
4785         else {
4786                 assert(arg_action == ACTION_SYSTEMCTL);
4787
4788                 method =
4789                         streq(args[0], "clear-jobs")    ||
4790                         streq(args[0], "cancel")        ? "ClearJobs" :
4791                         streq(args[0], "daemon-reexec") ? "Reexecute" :
4792                         streq(args[0], "reset-failed")  ? "ResetFailed" :
4793                         streq(args[0], "halt")          ? "Halt" :
4794                         streq(args[0], "poweroff")      ? "PowerOff" :
4795                         streq(args[0], "reboot")        ? "Reboot" :
4796                         streq(args[0], "kexec")         ? "KExec" :
4797                         streq(args[0], "exit")          ? "Exit" :
4798                                     /* "daemon-reload" */ "Reload";
4799         }
4800
4801         r = sd_bus_message_new_method_call(
4802                         bus,
4803                         &m,
4804                         "org.freedesktop.systemd1",
4805                         "/org/freedesktop/systemd1",
4806                         "org.freedesktop.systemd1.Manager",
4807                         method);
4808         if (r < 0)
4809                 return bus_log_create_error(r);
4810
4811         r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4812         if (r < 0)
4813                 return bus_log_create_error(r);
4814
4815         r = sd_bus_call(bus, m, 0, &error, NULL);
4816         if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
4817                 /* There's always a fallback possible for
4818                  * legacy actions. */
4819                 r = -EADDRNOTAVAIL;
4820         else if ((r == -ETIMEDOUT || r == -ECONNRESET) && streq(method, "Reexecute"))
4821                 /* On reexecution, we expect a disconnect, not a
4822                  * reply */
4823                 r = 0;
4824         else if (r < 0)
4825                 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
4826
4827         return r < 0 ? r : 0;
4828 }
4829
4830 static int reset_failed(sd_bus *bus, char **args) {
4831         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4832         _cleanup_strv_free_ char **names = NULL;
4833         char **name;
4834         int r, q;
4835
4836         if (strv_length(args) <= 1)
4837                 return daemon_reload(bus, args);
4838
4839         polkit_agent_open_if_enabled();
4840
4841         r = expand_names(bus, args + 1, NULL, &names);
4842         if (r < 0)
4843                 log_error_errno(r, "Failed to expand names: %m");
4844
4845         STRV_FOREACH(name, names) {
4846                 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4847
4848                 q = sd_bus_message_new_method_call(
4849                                 bus,
4850                                 &m,
4851                                 "org.freedesktop.systemd1",
4852                                 "/org/freedesktop/systemd1",
4853                                 "org.freedesktop.systemd1.Manager",
4854                                 "ResetFailedUnit");
4855                 if (q < 0)
4856                         return bus_log_create_error(q);
4857
4858                 q = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4859                 if (q < 0)
4860                         return bus_log_create_error(q);
4861
4862                 q = sd_bus_message_append(m, "s", *name);
4863                 if (q < 0)
4864                         return bus_log_create_error(q);
4865
4866                 q = sd_bus_call(bus, m, 0, &error, NULL);
4867                 if (q < 0) {
4868                         log_error("Failed to reset failed state of unit %s: %s", *name, bus_error_message(&error, q));
4869                         if (r == 0)
4870                                 r = q;
4871                 }
4872         }
4873
4874         return r;
4875 }
4876
4877 static int show_environment(sd_bus *bus, char **args) {
4878         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4879         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4880         const char *text;
4881         int r;
4882
4883         pager_open_if_enabled();
4884
4885         r = sd_bus_get_property(
4886                         bus,
4887                         "org.freedesktop.systemd1",
4888                         "/org/freedesktop/systemd1",
4889                         "org.freedesktop.systemd1.Manager",
4890                         "Environment",
4891                         &error,
4892                         &reply,
4893                         "as");
4894         if (r < 0) {
4895                 log_error("Failed to get environment: %s", bus_error_message(&error, r));
4896                 return r;
4897         }
4898
4899         r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "s");
4900         if (r < 0)
4901                 return bus_log_parse_error(r);
4902
4903         while ((r = sd_bus_message_read_basic(reply, SD_BUS_TYPE_STRING, &text)) > 0)
4904                 puts(text);
4905         if (r < 0)
4906                 return bus_log_parse_error(r);
4907
4908         r = sd_bus_message_exit_container(reply);
4909         if (r < 0)
4910                 return bus_log_parse_error(r);
4911
4912         return 0;
4913 }
4914
4915 static int switch_root(sd_bus *bus, char **args) {
4916         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4917         _cleanup_free_ char *cmdline_init = NULL;
4918         const char *root, *init;
4919         unsigned l;
4920         int r;
4921
4922         l = strv_length(args);
4923         if (l < 2 || l > 3) {
4924                 log_error("Wrong number of arguments.");
4925                 return -EINVAL;
4926         }
4927
4928         root = args[1];
4929
4930         if (l >= 3)
4931                 init = args[2];
4932         else {
4933                 r = parse_env_file("/proc/cmdline", WHITESPACE,
4934                                    "init", &cmdline_init,
4935                                    NULL);
4936                 if (r < 0)
4937                         log_debug_errno(r, "Failed to parse /proc/cmdline: %m");
4938
4939                 init = cmdline_init;
4940         }
4941
4942         if (isempty(init))
4943                 init = NULL;
4944
4945         if (init) {
4946                 const char *root_systemd_path = NULL, *root_init_path = NULL;
4947
4948                 root_systemd_path = strappenda(root, "/" SYSTEMD_BINARY_PATH);
4949                 root_init_path = strappenda(root, "/", init);
4950
4951                 /* If the passed init is actually the same as the
4952                  * systemd binary, then let's suppress it. */
4953                 if (files_same(root_init_path, root_systemd_path) > 0)
4954                         init = NULL;
4955         }
4956
4957         log_debug("Switching root - root: %s; init: %s", root, strna(init));
4958
4959         r = sd_bus_call_method(
4960                         bus,
4961                         "org.freedesktop.systemd1",
4962                         "/org/freedesktop/systemd1",
4963                         "org.freedesktop.systemd1.Manager",
4964                         "SwitchRoot",
4965                         &error,
4966                         NULL,
4967                         "ss", root, init);
4968         if (r < 0) {
4969                 log_error("Failed to switch root: %s", bus_error_message(&error, r));
4970                 return r;
4971         }
4972
4973         return 0;
4974 }
4975
4976 static int set_environment(sd_bus *bus, char **args) {
4977         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4978         _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4979         const char *method;
4980         int r;
4981
4982         assert(bus);
4983         assert(args);
4984
4985         method = streq(args[0], "set-environment")
4986                 ? "SetEnvironment"
4987                 : "UnsetEnvironment";
4988
4989         r = sd_bus_message_new_method_call(
4990                         bus,
4991                         &m,
4992                         "org.freedesktop.systemd1",
4993                         "/org/freedesktop/systemd1",
4994                         "org.freedesktop.systemd1.Manager",
4995                         method);
4996         if (r < 0)
4997                 return bus_log_create_error(r);
4998
4999         r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5000         if (r < 0)
5001                 return bus_log_create_error(r);
5002
5003         r = sd_bus_message_append_strv(m, args + 1);
5004         if (r < 0)
5005                 return bus_log_create_error(r);
5006
5007         r = sd_bus_call(bus, m, 0, &error, NULL);
5008         if (r < 0) {
5009                 log_error("Failed to set environment: %s", bus_error_message(&error, r));
5010                 return r;
5011         }
5012
5013         return 0;
5014 }
5015
5016 static int import_environment(sd_bus *bus, char **args) {
5017         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5018         _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
5019         int r;
5020
5021         assert(bus);
5022         assert(args);
5023
5024         r = sd_bus_message_new_method_call(
5025                         bus,
5026                         &m,
5027                         "org.freedesktop.systemd1",
5028                         "/org/freedesktop/systemd1",
5029                         "org.freedesktop.systemd1.Manager",
5030                         "SetEnvironment");
5031         if (r < 0)
5032                 return bus_log_create_error(r);
5033
5034         r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5035         if (r < 0)
5036                 return bus_log_create_error(r);
5037
5038         if (strv_isempty(args + 1))
5039                 r = sd_bus_message_append_strv(m, environ);
5040         else {
5041                 char **a, **b;
5042
5043                 r = sd_bus_message_open_container(m, 'a', "s");
5044                 if (r < 0)
5045                         return bus_log_create_error(r);
5046
5047                 STRV_FOREACH(a, args + 1) {
5048
5049                         if (!env_name_is_valid(*a)) {
5050                                 log_error("Not a valid environment variable name: %s", *a);
5051                                 return -EINVAL;
5052                         }
5053
5054                         STRV_FOREACH(b, environ) {
5055                                 const char *eq;
5056
5057                                 eq = startswith(*b, *a);
5058                                 if (eq && *eq == '=') {
5059
5060                                         r = sd_bus_message_append(m, "s", *b);
5061                                         if (r < 0)
5062                                                 return bus_log_create_error(r);
5063
5064                                         break;
5065                                 }
5066                         }
5067                 }
5068
5069                 r = sd_bus_message_close_container(m);
5070         }
5071         if (r < 0)
5072                 return bus_log_create_error(r);
5073
5074         r = sd_bus_call(bus, m, 0, &error, NULL);
5075         if (r < 0) {
5076                 log_error("Failed to import environment: %s", bus_error_message(&error, r));
5077                 return r;
5078         }
5079
5080         return 0;
5081 }
5082
5083 static int enable_sysv_units(const char *verb, char **args) {
5084         int r = 0;
5085
5086 #if defined(HAVE_SYSV_COMPAT) && defined(HAVE_CHKCONFIG)
5087         unsigned f = 0;
5088         _cleanup_lookup_paths_free_ LookupPaths paths = {};
5089
5090         if (arg_scope != UNIT_FILE_SYSTEM)
5091                 return 0;
5092
5093         if (!streq(verb, "enable") &&
5094             !streq(verb, "disable") &&
5095             !streq(verb, "is-enabled"))
5096                 return 0;
5097
5098         /* Processes all SysV units, and reshuffles the array so that
5099          * afterwards only the native units remain */
5100
5101         r = lookup_paths_init(&paths, SYSTEMD_SYSTEM, false, arg_root, NULL, NULL, NULL);
5102         if (r < 0)
5103                 return r;
5104
5105         r = 0;
5106         while (args[f]) {
5107                 const char *name;
5108                 _cleanup_free_ char *p = NULL, *q = NULL, *l = NULL;
5109                 bool found_native = false, found_sysv;
5110                 unsigned c = 1;
5111                 const char *argv[6] = { "/sbin/chkconfig", NULL, NULL, NULL, NULL };
5112                 char **k;
5113                 int j;
5114                 pid_t pid;
5115                 siginfo_t status;
5116
5117                 name = args[f++];
5118
5119                 if (!endswith(name, ".service"))
5120                         continue;
5121
5122                 if (path_is_absolute(name))
5123                         continue;
5124
5125                 STRV_FOREACH(k, paths.unit_path) {
5126                         _cleanup_free_ char *path = NULL;
5127
5128                         path = path_join(arg_root, *k, name);
5129                         if (!path)
5130                                 return log_oom();
5131
5132                         found_native = access(path, F_OK) >= 0;
5133                         if (found_native)
5134                                 break;
5135                 }
5136
5137                 if (found_native)
5138                         continue;
5139
5140                 p = path_join(arg_root, SYSTEM_SYSVINIT_PATH, name);
5141                 if (!p)
5142                         return log_oom();
5143
5144                 p[strlen(p) - strlen(".service")] = 0;
5145                 found_sysv = access(p, F_OK) >= 0;
5146                 if (!found_sysv)
5147                         continue;
5148
5149                 log_info("%s is not a native service, redirecting to /sbin/chkconfig.", name);
5150
5151                 if (!isempty(arg_root))
5152                         argv[c++] = q = strappend("--root=", arg_root);
5153
5154                 argv[c++] = basename(p);
5155                 argv[c++] =
5156                         streq(verb, "enable") ? "on" :
5157                         streq(verb, "disable") ? "off" : "--level=5";
5158                 argv[c] = NULL;
5159
5160                 l = strv_join((char**)argv, " ");
5161                 if (!l)
5162                         return log_oom();
5163
5164                 log_info("Executing %s", l);
5165
5166                 pid = fork();
5167                 if (pid < 0)
5168                         return log_error_errno(errno, "Failed to fork: %m");
5169                 else if (pid == 0) {
5170                         /* Child */
5171
5172                         execv(argv[0], (char**) argv);
5173                         _exit(EXIT_FAILURE);
5174                 }
5175
5176                 j = wait_for_terminate(pid, &status);
5177                 if (j < 0) {
5178                         log_error_errno(r, "Failed to wait for child: %m");
5179                         return j;
5180                 }
5181
5182                 if (status.si_code == CLD_EXITED) {
5183                         if (streq(verb, "is-enabled")) {
5184                                 if (status.si_status == 0) {
5185                                         if (!arg_quiet)
5186                                                 puts("enabled");
5187                                         r = 1;
5188                                 } else {
5189                                         if (!arg_quiet)
5190                                                 puts("disabled");
5191                                 }
5192
5193                         } else if (status.si_status != 0)
5194                                 return -EINVAL;
5195                 } else
5196                         return -EPROTO;
5197
5198                 /* Remove this entry, so that we don't try enabling it as native unit */
5199                 assert(f > 0);
5200                 f--;
5201                 assert(args[f] == name);
5202                 strv_remove(args, name);
5203         }
5204
5205 #endif
5206         return r;
5207 }
5208
5209 static int mangle_names(char **original_names, char ***mangled_names) {
5210         char **i, **l, **name;
5211
5212         l = new(char*, strv_length(original_names) + 1);
5213         if (!l)
5214                 return log_oom();
5215
5216         i = l;
5217         STRV_FOREACH(name, original_names) {
5218
5219                 /* When enabling units qualified path names are OK,
5220                  * too, hence allow them explicitly. */
5221
5222                 if (is_path(*name))
5223                         *i = strdup(*name);
5224                 else
5225                         *i = unit_name_mangle(*name, MANGLE_NOGLOB);
5226
5227                 if (!*i) {
5228                         strv_free(l);
5229                         return log_oom();
5230                 }
5231
5232                 i++;
5233         }
5234
5235         *i = NULL;
5236         *mangled_names = l;
5237
5238         return 0;
5239 }
5240
5241 static int enable_unit(sd_bus *bus, char **args) {
5242         _cleanup_strv_free_ char **names = NULL;
5243         const char *verb = args[0];
5244         UnitFileChange *changes = NULL;
5245         unsigned n_changes = 0;
5246         int carries_install_info = -1;
5247         int r;
5248
5249         if (!args[1])
5250                 return 0;
5251
5252         r = mangle_names(args+1, &names);
5253         if (r < 0)
5254                 return r;
5255
5256         r = enable_sysv_units(verb, names);
5257         if (r < 0)
5258                 return r;
5259
5260         /* If the operation was fully executed by the SysV compat,
5261          * let's finish early */
5262         if (strv_isempty(names))
5263                 return 0;
5264
5265         if (!bus || avoid_bus()) {
5266                 if (streq(verb, "enable")) {
5267                         r = unit_file_enable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5268                         carries_install_info = r;
5269                 } else if (streq(verb, "disable"))
5270                         r = unit_file_disable(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
5271                 else if (streq(verb, "reenable")) {
5272                         r = unit_file_reenable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5273                         carries_install_info = r;
5274                 } else if (streq(verb, "link"))
5275                         r = unit_file_link(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5276                 else if (streq(verb, "preset")) {
5277                         r = unit_file_preset(arg_scope, arg_runtime, arg_root, names, arg_preset_mode, arg_force, &changes, &n_changes);
5278                         carries_install_info = r;
5279                 } else if (streq(verb, "mask"))
5280                         r = unit_file_mask(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5281                 else if (streq(verb, "unmask"))
5282                         r = unit_file_unmask(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
5283                 else
5284                         assert_not_reached("Unknown verb");
5285
5286                 if (r < 0) {
5287                         log_error_errno(r, "Operation failed: %m");
5288                         goto finish;
5289                 }
5290
5291                 if (!arg_quiet)
5292                         dump_unit_file_changes(changes, n_changes);
5293
5294                 r = 0;
5295         } else {
5296                 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
5297                 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5298                 int expect_carries_install_info = false;
5299                 bool send_force = true, send_preset_mode = false;
5300                 const char *method;
5301
5302                 polkit_agent_open_if_enabled();
5303
5304                 if (streq(verb, "enable")) {
5305                         method = "EnableUnitFiles";
5306                         expect_carries_install_info = true;
5307                 } else if (streq(verb, "disable")) {
5308                         method = "DisableUnitFiles";
5309                         send_force = false;
5310                 } else if (streq(verb, "reenable")) {
5311                         method = "ReenableUnitFiles";
5312                         expect_carries_install_info = true;
5313                 } else if (streq(verb, "link"))
5314                         method = "LinkUnitFiles";
5315                 else if (streq(verb, "preset")) {
5316
5317                         if (arg_preset_mode != UNIT_FILE_PRESET_FULL) {
5318                                 method = "PresetUnitFilesWithMode";
5319                                 send_preset_mode = true;
5320                         } else
5321                                 method = "PresetUnitFiles";
5322
5323                         expect_carries_install_info = true;
5324                 } else if (streq(verb, "mask"))
5325                         method = "MaskUnitFiles";
5326                 else if (streq(verb, "unmask")) {
5327                         method = "UnmaskUnitFiles";
5328                         send_force = false;
5329                 } else
5330                         assert_not_reached("Unknown verb");
5331
5332                 r = sd_bus_message_new_method_call(
5333                                 bus,
5334                                 &m,
5335                                 "org.freedesktop.systemd1",
5336                                 "/org/freedesktop/systemd1",
5337                                 "org.freedesktop.systemd1.Manager",
5338                                 method);
5339                 if (r < 0)
5340                         return bus_log_create_error(r);
5341
5342                 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5343                 if (r < 0)
5344                         return bus_log_create_error(r);
5345
5346                 r = sd_bus_message_append_strv(m, names);
5347                 if (r < 0)
5348                         return bus_log_create_error(r);
5349
5350                 if (send_preset_mode) {
5351                         r = sd_bus_message_append(m, "s", unit_file_preset_mode_to_string(arg_preset_mode));
5352                         if (r < 0)
5353                                 return bus_log_create_error(r);
5354                 }
5355
5356                 r = sd_bus_message_append(m, "b", arg_runtime);
5357                 if (r < 0)
5358                         return bus_log_create_error(r);
5359
5360                 if (send_force) {
5361                         r = sd_bus_message_append(m, "b", arg_force);
5362                         if (r < 0)
5363                                 return bus_log_create_error(r);
5364                 }
5365
5366                 r = sd_bus_call(bus, m, 0, &error, &reply);
5367                 if (r < 0) {
5368                         log_error("Failed to execute operation: %s", bus_error_message(&error, r));
5369                         return r;
5370                 }
5371
5372                 if (expect_carries_install_info) {
5373                         r = sd_bus_message_read(reply, "b", &carries_install_info);
5374                         if (r < 0)
5375                                 return bus_log_parse_error(r);
5376                 }
5377
5378                 r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet);
5379                 if (r < 0)
5380                         return r;
5381
5382                 /* Try to reload if enabled */
5383                 if (!arg_no_reload)
5384                         r = daemon_reload(bus, args);
5385                 else
5386                         r = 0;
5387         }
5388
5389         if (carries_install_info == 0)
5390                 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
5391                             "using systemctl.\n"
5392                             "Possible reasons for having this kind of units are:\n"
5393                             "1) A unit may be statically enabled by being symlinked from another unit's\n"
5394                             "   .wants/ or .requires/ directory.\n"
5395                             "2) A unit's purpose may be to act as a helper for some other unit which has\n"
5396                             "   a requirement dependency on it.\n"
5397                             "3) A unit may be started when needed via activation (socket, path, timer,\n"
5398                             "   D-Bus, udev, scripted systemctl call, ...).\n");
5399
5400 finish:
5401         unit_file_changes_free(changes, n_changes);
5402
5403         return r;
5404 }
5405
5406 static int add_dependency(sd_bus *bus, char **args) {
5407         _cleanup_strv_free_ char **names = NULL;
5408         _cleanup_free_ char *target = NULL;
5409         const char *verb = args[0];
5410         UnitDependency dep;
5411         int r = 0;
5412
5413         if (!args[1])
5414                 return 0;
5415
5416         target = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".target");
5417         if (!target)
5418                 return log_oom();
5419
5420         r = mangle_names(args+2, &names);
5421         if (r < 0)
5422                 return r;
5423
5424         if (streq(verb, "add-wants"))
5425                 dep = UNIT_WANTS;
5426         else if (streq(verb, "add-requires"))
5427                 dep = UNIT_REQUIRES;
5428         else
5429                 assert_not_reached("Unknown verb");
5430
5431         if (!bus || avoid_bus()) {
5432                 UnitFileChange *changes = NULL;
5433                 unsigned n_changes = 0;
5434
5435                 r = unit_file_add_dependency(arg_scope, arg_runtime, arg_root, names, target, dep, arg_force, &changes, &n_changes);
5436
5437                 if (r < 0)
5438                         return log_error_errno(r, "Can't add dependency: %m");
5439
5440                 if (!arg_quiet)
5441                         dump_unit_file_changes(changes, n_changes);
5442
5443                 unit_file_changes_free(changes, n_changes);
5444
5445         } else {
5446                 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
5447                 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5448
5449                 polkit_agent_open_if_enabled();
5450
5451                 r = sd_bus_message_new_method_call(
5452                                 bus,
5453                                 &m,
5454                                 "org.freedesktop.systemd1",
5455                                 "/org/freedesktop/systemd1",
5456                                 "org.freedesktop.systemd1.Manager",
5457                                 "AddDependencyUnitFiles");
5458                 if (r < 0)
5459                         return bus_log_create_error(r);
5460
5461                 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5462                 if (r < 0)
5463                         return bus_log_create_error(r);
5464
5465                 r = sd_bus_message_append_strv(m, names);
5466                 if (r < 0)
5467                         return bus_log_create_error(r);
5468
5469                 r = sd_bus_message_append(m, "ssbb", target, unit_dependency_to_string(dep), arg_runtime, arg_force);
5470                 if (r < 0)
5471                         return bus_log_create_error(r);
5472
5473                 r = sd_bus_call(bus, m, 0, &error, &reply);
5474                 if (r < 0) {
5475                         log_error("Failed to execute operation: %s", bus_error_message(&error, r));
5476                         return r;
5477                 }
5478
5479                 r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet);
5480                 if (r < 0)
5481                         return r;
5482
5483                 if (!arg_no_reload)
5484                         r = daemon_reload(bus, args);
5485                 else
5486                         r = 0;
5487         }
5488
5489         return r;
5490 }
5491
5492 static int preset_all(sd_bus *bus, char **args) {
5493         UnitFileChange *changes = NULL;
5494         unsigned n_changes = 0;
5495         int r;
5496
5497         if (!bus || avoid_bus()) {
5498
5499                 r = unit_file_preset_all(arg_scope, arg_runtime, arg_root, arg_preset_mode, arg_force, &changes, &n_changes);
5500                 if (r < 0) {
5501                         log_error_errno(r, "Operation failed: %m");
5502                         goto finish;
5503                 }
5504
5505                 if (!arg_quiet)
5506                         dump_unit_file_changes(changes, n_changes);
5507
5508                 r = 0;
5509
5510         } else {
5511                 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
5512                 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5513
5514                 polkit_agent_open_if_enabled();
5515
5516                 r = sd_bus_message_new_method_call(
5517                                 bus,
5518                                 &m,
5519                                 "org.freedesktop.systemd1",
5520                                 "/org/freedesktop/systemd1",
5521                                 "org.freedesktop.systemd1.Manager",
5522                                 "PresetAllUnitFiles");
5523                 if (r < 0)
5524                         return bus_log_create_error(r);
5525
5526                 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5527                 if (r < 0)
5528                         return bus_log_create_error(r);
5529
5530                 r = sd_bus_message_append(
5531                                 m,
5532                                 "sbb",
5533                                 unit_file_preset_mode_to_string(arg_preset_mode),
5534                                 arg_runtime,
5535                                 arg_force);
5536                 if (r < 0)
5537                         return bus_log_create_error(r);
5538
5539                 r = sd_bus_call(bus, m, 0, &error, &reply);
5540                 if (r < 0) {
5541                         log_error("Failed to execute operation: %s", bus_error_message(&error, r));
5542                         return r;
5543                 }
5544
5545                 r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet);
5546                 if (r < 0)
5547                         return r;
5548
5549                 if (!arg_no_reload)
5550                         r = daemon_reload(bus, args);
5551                 else
5552                         r = 0;
5553         }
5554
5555 finish:
5556         unit_file_changes_free(changes, n_changes);
5557
5558         return r;
5559 }
5560
5561 static int unit_is_enabled(sd_bus *bus, char **args) {
5562
5563         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5564         _cleanup_strv_free_ char **names = NULL;
5565         bool enabled;
5566         char **name;
5567         int r;
5568
5569         r = mangle_names(args+1, &names);
5570         if (r < 0)
5571                 return r;
5572
5573         r = enable_sysv_units(args[0], names);
5574         if (r < 0)
5575                 return r;
5576
5577         enabled = r > 0;
5578
5579         if (!bus || avoid_bus()) {
5580
5581                 STRV_FOREACH(name, names) {
5582                         UnitFileState state;
5583
5584                         state = unit_file_get_state(arg_scope, arg_root, *name);
5585                         if (state < 0)
5586                                 return log_error_errno(state, "Failed to get unit file state for %s: %m", *name);
5587
5588                         if (state == UNIT_FILE_ENABLED ||
5589                             state == UNIT_FILE_ENABLED_RUNTIME ||
5590                             state == UNIT_FILE_STATIC ||
5591                             state == UNIT_FILE_INDIRECT)
5592                                 enabled = true;
5593
5594                         if (!arg_quiet)
5595                                 puts(unit_file_state_to_string(state));
5596                 }
5597
5598         } else {
5599                 STRV_FOREACH(name, names) {
5600                         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
5601                         const char *s;
5602
5603                         r = sd_bus_call_method(
5604                                         bus,
5605                                         "org.freedesktop.systemd1",
5606                                         "/org/freedesktop/systemd1",
5607                                         "org.freedesktop.systemd1.Manager",
5608                                         "GetUnitFileState",
5609                                         &error,
5610                                         &reply,
5611                                         "s", *name);
5612                         if (r < 0) {
5613                                 log_error("Failed to get unit file state for %s: %s", *name, bus_error_message(&error, r));
5614                                 return r;
5615                         }
5616
5617                         r = sd_bus_message_read(reply, "s", &s);
5618                         if (r < 0)
5619                                 return bus_log_parse_error(r);
5620
5621                         if (STR_IN_SET(s, "enabled", "enabled-runtime", "static", "indirect"))
5622                                 enabled = true;
5623
5624                         if (!arg_quiet)
5625                                 puts(s);
5626                 }
5627         }
5628
5629         return !enabled;
5630 }
5631
5632 static int is_system_running(sd_bus *bus, char **args) {
5633         _cleanup_free_ char *state = NULL;
5634         int r;
5635
5636         r = sd_bus_get_property_string(
5637                         bus,
5638                         "org.freedesktop.systemd1",
5639                         "/org/freedesktop/systemd1",
5640                         "org.freedesktop.systemd1.Manager",
5641                         "SystemState",
5642                         NULL,
5643                         &state);
5644         if (r < 0) {
5645                 if (!arg_quiet)
5646                         puts("unknown");
5647                 return 0;
5648         }
5649
5650         if (!arg_quiet)
5651                 puts(state);
5652
5653         return streq(state, "running") ? EXIT_SUCCESS : EXIT_FAILURE;
5654 }
5655
5656 static int create_edit_temp_file(const char *new_path, const char *original_path, char **ret_tmp_fn) {
5657         char *t;
5658         int r;
5659
5660         assert(new_path);
5661         assert(original_path);
5662         assert(ret_tmp_fn);
5663
5664         r = tempfn_random(new_path, &t);
5665         if (r < 0)
5666                 return log_error_errno(r, "Failed to determine temporary filename for %s: %m", new_path);
5667
5668         r = mkdir_parents(new_path, 0755);
5669         if (r < 0) {
5670                 log_error_errno(r, "Failed to create directories for %s: %m", new_path);
5671                 free(t);
5672                 return r;
5673         }
5674
5675         r = copy_file(original_path, t, 0, 0644, 0);
5676         if (r == -ENOENT) {
5677                 r = touch(t);
5678                 if (r < 0) {
5679                         log_error_errno(r, "Failed to create temporary file %s: %m", t);
5680                         free(t);
5681                         return r;
5682                 }
5683         } else if (r < 0) {
5684                 log_error_errno(r, "Failed to copy %s to %s: %m", original_path, t);
5685                 free(t);
5686                 return r;
5687         }
5688
5689         *ret_tmp_fn = t;
5690
5691         return 0;
5692 }
5693
5694 static int get_file_to_edit(const char *name, const char *user_home, const char *user_runtime, char **ret_path) {
5695         _cleanup_free_ char *path = NULL, *path2 = NULL, *run = NULL;
5696
5697         switch (arg_scope) {
5698                 case UNIT_FILE_SYSTEM:
5699                         path = path_join(arg_root, SYSTEM_CONFIG_UNIT_PATH, name);
5700                         if (arg_runtime)
5701                                 run = path_join(arg_root, "/run/systemd/system/", name);
5702                         break;
5703                 case UNIT_FILE_GLOBAL:
5704                         path = path_join(arg_root, USER_CONFIG_UNIT_PATH, name);
5705                         if (arg_runtime)
5706                                 run = path_join(arg_root, "/run/systemd/user/", name);
5707                         break;
5708                 case UNIT_FILE_USER:
5709                         assert(user_home);
5710                         assert(user_runtime);
5711
5712                         path = path_join(arg_root, user_home, name);
5713                         if (arg_runtime) {
5714                                 path2 = path_join(arg_root, USER_CONFIG_UNIT_PATH, name);
5715                                 if (!path2)
5716                                         return log_oom();
5717                                 run = path_join(arg_root, user_runtime, name);
5718                         }
5719                         break;
5720                 default:
5721                         assert_not_reached("Invalid scope");
5722         }
5723         if (!path || (arg_runtime && !run))
5724                 return log_oom();
5725
5726         if (arg_runtime) {
5727                 if (access(path, F_OK) >= 0)
5728                         return log_error_errno(EEXIST, "Refusing to create \"%s\" because it would be overriden by \"%s\" anyway.",
5729                                                run, path);
5730                 if (path2 && access(path2, F_OK) >= 0)
5731                         return log_error_errno(EEXIST, "Refusing to create \"%s\" because it would be overriden by \"%s\" anyway.",
5732                                                run, path2);
5733                 *ret_path = run;
5734                 run = NULL;
5735         } else {
5736                 *ret_path = path;
5737                 path = NULL;
5738         }
5739
5740         return 0;
5741 }
5742
5743
5744 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) {
5745         char *tmp_new_path, *ending;
5746         char *tmp_tmp_path;
5747         int r;
5748
5749         assert(unit_name);
5750         assert(ret_new_path);
5751         assert(ret_tmp_path);
5752
5753         ending = strappenda(unit_name, ".d/override.conf");
5754         r = get_file_to_edit(ending, user_home, user_runtime, &tmp_new_path);
5755         if (r < 0)
5756                 return r;
5757
5758         r = create_edit_temp_file(tmp_new_path, tmp_new_path, &tmp_tmp_path);
5759         if (r < 0) {
5760                 free(tmp_new_path);
5761                 return r;
5762         }
5763
5764         *ret_new_path = tmp_new_path;
5765         *ret_tmp_path = tmp_tmp_path;
5766
5767         return 0;
5768 }
5769
5770 static int unit_file_create_copy(const char *unit_name,
5771                                  const char *fragment_path,
5772                                  const char *user_home,
5773                                  const char *user_runtime,
5774                                  char **ret_new_path,
5775                                  char **ret_tmp_path) {
5776         char *tmp_new_path;
5777         char *tmp_tmp_path;
5778         int r;
5779
5780         assert(fragment_path);
5781         assert(unit_name);
5782         assert(ret_new_path);
5783         assert(ret_tmp_path);
5784
5785         r = get_file_to_edit(unit_name, user_home, user_runtime, &tmp_new_path);
5786         if (r < 0)
5787                 return r;
5788
5789         if (!path_equal(fragment_path, tmp_new_path) && access(tmp_new_path, F_OK) == 0) {
5790                 char response;
5791
5792                 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);
5793                 if (r < 0) {
5794                         free(tmp_new_path);
5795                         return r;
5796                 }
5797                 if (response != 'y') {
5798                         log_warning("%s ignored", unit_name);
5799                         free(tmp_new_path);
5800                         return -1;
5801                 }
5802         }
5803
5804         r = create_edit_temp_file(tmp_new_path, fragment_path, &tmp_tmp_path);
5805         if (r < 0) {
5806                 log_error_errno(r, "Failed to create temporary file for %s: %m", tmp_new_path);
5807                 free(tmp_new_path);
5808                 return r;
5809         }
5810
5811         *ret_new_path = tmp_new_path;
5812         *ret_tmp_path = tmp_tmp_path;
5813
5814         return 0;
5815 }
5816
5817 static int run_editor(char **paths) {
5818         pid_t pid;
5819         int r;
5820
5821         assert(paths);
5822
5823         pid = fork();
5824         if (pid < 0) {
5825                 log_error_errno(errno, "Failed to fork: %m");
5826                 return -errno;
5827         }
5828
5829         if (pid == 0) {
5830                 const char **args;
5831                 char **backup_editors = STRV_MAKE("nano", "vim", "vi");
5832                 char *editor;
5833                 char **tmp_path, **original_path, **p;
5834                 unsigned i = 1;
5835                 size_t argc;
5836
5837                 argc = strv_length(paths)/2 + 1;
5838                 args = newa(const char*, argc + 1);
5839
5840                 args[0] = NULL;
5841                 STRV_FOREACH_PAIR(original_path, tmp_path, paths) {
5842                         args[i] = *tmp_path;
5843                         i++;
5844                 }
5845                 args[argc] = NULL;
5846
5847                 /* SYSTEMD_EDITOR takes precedence over EDITOR which takes precedence over VISUAL
5848                  * If neither SYSTEMD_EDITOR nor EDITOR nor VISUAL are present,
5849                  * we try to execute well known editors
5850                  */
5851                 editor = getenv("SYSTEMD_EDITOR");
5852                 if (!editor)
5853                         editor = getenv("EDITOR");
5854                 if (!editor)
5855                         editor = getenv("VISUAL");
5856
5857                 if (!isempty(editor)) {
5858                         args[0] = editor;
5859                         execvp(editor, (char* const*) args);
5860                 }
5861
5862                 STRV_FOREACH(p, backup_editors) {
5863                         args[0] = *p;
5864                         execvp(*p, (char* const*) args);
5865                         /* We do not fail if the editor doesn't exist
5866                          * because we want to try each one of them before
5867                          * failing.
5868                          */
5869                         if (errno != ENOENT) {
5870                                 log_error("Failed to execute %s: %m", editor);
5871                                 _exit(EXIT_FAILURE);
5872                         }
5873                 }
5874
5875                 log_error("Cannot edit unit(s), no editor available. Please set either $SYSTEMD_EDITOR or $EDITOR or $VISUAL.");
5876                 _exit(EXIT_FAILURE);
5877         }
5878
5879         r = wait_for_terminate_and_warn("editor", pid, true);
5880         if (r < 0)
5881                 return log_error_errno(r, "Failed to wait for child: %m");
5882
5883         return r;
5884 }
5885
5886 static int find_paths_to_edit(sd_bus *bus, char **names, char ***paths) {
5887         _cleanup_free_ char *user_home = NULL;
5888         _cleanup_free_ char *user_runtime = NULL;
5889         _cleanup_lookup_paths_free_ LookupPaths lp = {};
5890         bool avoid_bus_cache;
5891         char **name;
5892         int r;
5893
5894         assert(names);
5895         assert(paths);
5896
5897         r = init_home_and_lookup_paths(&user_home, &user_runtime, &lp);
5898         if (r < 0)
5899                 return r;
5900
5901         avoid_bus_cache = !bus || avoid_bus();
5902
5903         STRV_FOREACH(name, names) {
5904                 _cleanup_free_ char *path = NULL;
5905                 char *new_path, *tmp_path;
5906
5907                 r = unit_find_paths(bus, *name, avoid_bus_cache, &lp, &path, NULL);
5908                 if (r < 0)
5909                         return r;
5910                 else if (r == 0 || !path)
5911                         // FIXME: support units with path==NULL (no FragmentPath)
5912                         return log_error_errno(ENOENT, "Unit %s not found, cannot edit.", *name);
5913
5914                 if (arg_full)
5915                         r = unit_file_create_copy(*name, path, user_home, user_runtime, &new_path, &tmp_path);
5916                 else
5917                         r = unit_file_create_dropin(*name, user_home, user_runtime, &new_path, &tmp_path);
5918                 if (r < 0)
5919                         return r;
5920
5921                 r = strv_push_pair(paths, new_path, tmp_path);
5922                 if (r < 0)
5923                         return log_oom();
5924         }
5925
5926         return 0;
5927 }
5928
5929 static int edit(sd_bus *bus, char **args) {
5930         _cleanup_strv_free_ char **names = NULL;
5931         _cleanup_strv_free_ char **paths = NULL;
5932         char **original, **tmp;
5933         int r;
5934
5935         assert(args);
5936
5937         if (!on_tty()) {
5938                 log_error("Cannot edit units if we are not on a tty");
5939                 return -EINVAL;
5940         }
5941
5942         if (arg_transport != BUS_TRANSPORT_LOCAL) {
5943                 log_error("Cannot remotely edit units");
5944                 return -EINVAL;
5945         }
5946
5947         r = expand_names(bus, args + 1, NULL, &names);
5948         if (r < 0)
5949                 return log_error_errno(r, "Failed to expand names: %m");
5950
5951         if (!names) {
5952                 log_error("No unit name found by expanding names");
5953                 return -ENOENT;
5954         }
5955
5956         r = find_paths_to_edit(bus, names, &paths);
5957         if (r < 0)
5958                 return r;
5959
5960         if (strv_isempty(paths)) {
5961                 log_error("Cannot find any units to edit");
5962                 return -ENOENT;
5963         }
5964
5965         r = run_editor(paths);
5966         if (r < 0)
5967                 goto end;
5968
5969         STRV_FOREACH_PAIR(original, tmp, paths) {
5970                 /* If the temporary file is empty we ignore it.
5971                  * It's useful if the user wants to cancel its modification
5972                  */
5973                 if (null_or_empty_path(*tmp)) {
5974                         log_warning("Edition of %s canceled: temporary file empty", *original);
5975                         continue;
5976                 }
5977                 r = rename(*tmp, *original);
5978                 if (r < 0) {
5979                         r = log_error_errno(errno, "Failed to rename %s to %s: %m", *tmp, *original);
5980                         goto end;
5981                 }
5982         }
5983
5984         if (!arg_no_reload && bus && !avoid_bus())
5985                 r = daemon_reload(bus, args);
5986
5987 end:
5988         STRV_FOREACH_PAIR(original, tmp, paths)
5989                 unlink_noerrno(*tmp);
5990
5991         return r;
5992 }
5993
5994 static void systemctl_help(void) {
5995
5996         pager_open_if_enabled();
5997
5998         printf("%s [OPTIONS...] {COMMAND} ...\n\n"
5999                "Query or send control commands to the systemd manager.\n\n"
6000                "  -h --help           Show this help\n"
6001                "     --version        Show package version\n"
6002                "     --system         Connect to system manager\n"
6003                "     --user           Connect to user service manager\n"
6004                "  -H --host=[USER@]HOST\n"
6005                "                      Operate on remote host\n"
6006                "  -M --machine=CONTAINER\n"
6007                "                      Operate on local container\n"
6008                "  -t --type=TYPE      List units of a particular type\n"
6009                "     --state=STATE    List units with particular LOAD or SUB or ACTIVE state\n"
6010                "  -p --property=NAME  Show only properties by this name\n"
6011                "  -a --all            Show all loaded units/properties, including dead/empty\n"
6012                "                      ones. To list all units installed on the system, use\n"
6013                "                      the 'list-unit-files' command instead.\n"
6014                "  -l --full           Don't ellipsize unit names on output\n"
6015                "  -r --recursive      Show unit list of host and local containers\n"
6016                "     --reverse        Show reverse dependencies with 'list-dependencies'\n"
6017                "     --job-mode=MODE  Specify how to deal with already queued jobs, when\n"
6018                "                      queueing a new job\n"
6019                "     --show-types     When showing sockets, explicitly show their type\n"
6020                "  -i --ignore-inhibitors\n"
6021                "                      When shutting down or sleeping, ignore inhibitors\n"
6022                "     --kill-who=WHO   Who to send signal to\n"
6023                "  -s --signal=SIGNAL  Which signal to send\n"
6024                "  -q --quiet          Suppress output\n"
6025                "     --no-block       Do not wait until operation finished\n"
6026                "     --no-wall        Don't send wall message before halt/power-off/reboot\n"
6027                "     --no-reload      Don't reload daemon after en-/dis-abling unit files\n"
6028                "     --no-legend      Do not print a legend (column headers and hints)\n"
6029                "     --no-pager       Do not pipe output into a pager\n"
6030                "     --no-ask-password\n"
6031                "                      Do not ask for system passwords\n"
6032                "     --global         Enable/disable unit files globally\n"
6033                "     --runtime        Enable unit files only temporarily until next reboot\n"
6034                "  -f --force          When enabling unit files, override existing symlinks\n"
6035                "                      When shutting down, execute action immediately\n"
6036                "     --preset-mode=   Apply only enable, only disable, or all presets\n"
6037                "     --root=PATH      Enable unit files in the specified root directory\n"
6038                "  -n --lines=INTEGER  Number of journal entries to show\n"
6039                "  -o --output=STRING  Change journal output mode (short, short-iso,\n"
6040                "                              short-precise, short-monotonic, verbose,\n"
6041                "                              export, json, json-pretty, json-sse, cat)\n"
6042                "     --plain          Print unit dependencies as a list instead of a tree\n\n"
6043                "Unit Commands:\n"
6044                "  list-units [PATTERN...]         List loaded units\n"
6045                "  list-sockets [PATTERN...]       List loaded sockets ordered by address\n"
6046                "  list-timers [PATTERN...]        List loaded timers ordered by next elapse\n"
6047                "  start NAME...                   Start (activate) one or more units\n"
6048                "  stop NAME...                    Stop (deactivate) one or more units\n"
6049                "  reload NAME...                  Reload one or more units\n"
6050                "  restart NAME...                 Start or restart one or more units\n"
6051                "  try-restart NAME...             Restart one or more units if active\n"
6052                "  reload-or-restart NAME...       Reload one or more units if possible,\n"
6053                "                                  otherwise start or restart\n"
6054                "  reload-or-try-restart NAME...   Reload one or more units if possible,\n"
6055                "                                  otherwise restart if active\n"
6056                "  isolate NAME                    Start one unit and stop all others\n"
6057                "  kill NAME...                    Send signal to processes of a unit\n"
6058                "  is-active PATTERN...            Check whether units are active\n"
6059                "  is-failed PATTERN...            Check whether units are failed\n"
6060                "  status [PATTERN...|PID...]      Show runtime status of one or more units\n"
6061                "  show [PATTERN...|JOB...]        Show properties of one or more\n"
6062                "                                  units/jobs or the manager\n"
6063                "  cat PATTERN...                  Show files and drop-ins of one or more units\n"
6064                "  set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
6065                "  help PATTERN...|PID...          Show manual for one or more units\n"
6066                "  reset-failed [PATTERN...]       Reset failed state for all, one, or more\n"
6067                "                                  units\n"
6068                "  list-dependencies [NAME]        Recursively show units which are required\n"
6069                "                                  or wanted by this unit or by which this\n"
6070                "                                  unit is required or wanted\n\n"
6071                "Unit File Commands:\n"
6072                "  list-unit-files [PATTERN...]    List installed unit files\n"
6073                "  enable NAME...                  Enable one or more unit files\n"
6074                "  disable NAME...                 Disable one or more unit files\n"
6075                "  reenable NAME...                Reenable one or more unit files\n"
6076                "  preset NAME...                  Enable/disable one or more unit files\n"
6077                "                                  based on preset configuration\n"
6078                "  preset-all                      Enable/disable all unit files based on\n"
6079                "                                  preset configuration\n"
6080                "  is-enabled NAME...              Check whether unit files are enabled\n"
6081                "  mask NAME...                    Mask one or more units\n"
6082                "  unmask NAME...                  Unmask one or more units\n"
6083                "  link PATH...                    Link one or more units files into\n"
6084                "                                  the search path\n"
6085                "  add-wants TARGET NAME...        Add 'Wants' dependency for the target\n"
6086                "                                  on specified one or more units\n"
6087                "  add-requires TARGET NAME...     Add 'Requires' dependency for the target\n"
6088                "                                  on specified one or more units\n"
6089                "  edit NAME...                    Edit one or more unit files\n"
6090                "  get-default                     Get the name of the default target\n"
6091                "  set-default NAME                Set the default target\n\n"
6092                "Machine Commands:\n"
6093                "  list-machines [PATTERN...]      List local containers and host\n\n"
6094                "Job Commands:\n"
6095                "  list-jobs [PATTERN...]          List jobs\n"
6096                "  cancel [JOB...]                 Cancel all, one, or more jobs\n\n"
6097                "Snapshot Commands:\n"
6098                "  snapshot [NAME]                 Create a snapshot\n"
6099                "  delete NAME...                  Remove one or more snapshots\n\n"
6100                "Environment Commands:\n"
6101                "  show-environment                Dump environment\n"
6102                "  set-environment NAME=VALUE...   Set one or more environment variables\n"
6103                "  unset-environment NAME...       Unset one or more environment variables\n"
6104                "  import-environment [NAME...]    Import all or some environment variables\n\n"
6105                "Manager Lifecycle Commands:\n"
6106                "  daemon-reload                   Reload systemd manager configuration\n"
6107                "  daemon-reexec                   Reexecute systemd manager\n\n"
6108                "System Commands:\n"
6109                "  is-system-running               Check whether system is fully running\n"
6110                "  default                         Enter system default mode\n"
6111                "  rescue                          Enter system rescue mode\n"
6112                "  emergency                       Enter system emergency mode\n"
6113                "  halt                            Shut down and halt the system\n"
6114                "  poweroff                        Shut down and power-off the system\n"
6115                "  reboot [ARG]                    Shut down and reboot the system\n"
6116                "  kexec                           Shut down and reboot the system with kexec\n"
6117                "  exit                            Request user instance exit\n"
6118                "  switch-root ROOT [INIT]         Change to a different root file system\n"
6119                "  suspend                         Suspend the system\n"
6120                "  hibernate                       Hibernate the system\n"
6121                "  hybrid-sleep                    Hibernate and suspend the system\n",
6122                program_invocation_short_name);
6123 }
6124
6125 static void halt_help(void) {
6126         printf("%s [OPTIONS...]%s\n\n"
6127                "%s the system.\n\n"
6128                "     --help      Show this help\n"
6129                "     --halt      Halt the machine\n"
6130                "  -p --poweroff  Switch off the machine\n"
6131                "     --reboot    Reboot the machine\n"
6132                "  -f --force     Force immediate halt/power-off/reboot\n"
6133                "  -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
6134                "  -d --no-wtmp   Don't write wtmp record\n"
6135                "     --no-wall   Don't send wall message before halt/power-off/reboot\n",
6136                program_invocation_short_name,
6137                arg_action == ACTION_REBOOT   ? " [ARG]" : "",
6138                arg_action == ACTION_REBOOT   ? "Reboot" :
6139                arg_action == ACTION_POWEROFF ? "Power off" :
6140                                                "Halt");
6141 }
6142
6143 static void shutdown_help(void) {
6144         printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
6145                "Shut down the system.\n\n"
6146                "     --help      Show this help\n"
6147                "  -H --halt      Halt the machine\n"
6148                "  -P --poweroff  Power-off the machine\n"
6149                "  -r --reboot    Reboot the machine\n"
6150                "  -h             Equivalent to --poweroff, overridden by --halt\n"
6151                "  -k             Don't halt/power-off/reboot, just send warnings\n"
6152                "     --no-wall   Don't send wall message before halt/power-off/reboot\n"
6153                "  -c             Cancel a pending shutdown\n",
6154                program_invocation_short_name);
6155 }
6156
6157 static void telinit_help(void) {
6158         printf("%s [OPTIONS...] {COMMAND}\n\n"
6159                "Send control commands to the init daemon.\n\n"
6160                "     --help      Show this help\n"
6161                "     --no-wall   Don't send wall message before halt/power-off/reboot\n\n"
6162                "Commands:\n"
6163                "  0              Power-off the machine\n"
6164                "  6              Reboot the machine\n"
6165                "  2, 3, 4, 5     Start runlevelX.target unit\n"
6166                "  1, s, S        Enter rescue mode\n"
6167                "  q, Q           Reload init daemon configuration\n"
6168                "  u, U           Reexecute init daemon\n",
6169                program_invocation_short_name);
6170 }
6171
6172 static void runlevel_help(void) {
6173         printf("%s [OPTIONS...]\n\n"
6174                "Prints the previous and current runlevel of the init system.\n\n"
6175                "     --help      Show this help\n",
6176                program_invocation_short_name);
6177 }
6178
6179 static void help_types(void) {
6180         int i;
6181         const char *t;
6182
6183         if (!arg_no_legend)
6184                 puts("Available unit types:");
6185         for (i = 0; i < _UNIT_TYPE_MAX; i++) {
6186                 t = unit_type_to_string(i);
6187                 if (t)
6188                         puts(t);
6189         }
6190 }
6191
6192 static int systemctl_parse_argv(int argc, char *argv[]) {
6193
6194         enum {
6195                 ARG_FAIL = 0x100,
6196                 ARG_REVERSE,
6197                 ARG_AFTER,
6198                 ARG_BEFORE,
6199                 ARG_SHOW_TYPES,
6200                 ARG_IRREVERSIBLE,
6201                 ARG_IGNORE_DEPENDENCIES,
6202                 ARG_VERSION,
6203                 ARG_USER,
6204                 ARG_SYSTEM,
6205                 ARG_GLOBAL,
6206                 ARG_NO_BLOCK,
6207                 ARG_NO_LEGEND,
6208                 ARG_NO_PAGER,
6209                 ARG_NO_WALL,
6210                 ARG_ROOT,
6211                 ARG_NO_RELOAD,
6212                 ARG_KILL_WHO,
6213                 ARG_NO_ASK_PASSWORD,
6214                 ARG_FAILED,
6215                 ARG_RUNTIME,
6216                 ARG_FORCE,
6217                 ARG_PLAIN,
6218                 ARG_STATE,
6219                 ARG_JOB_MODE,
6220                 ARG_PRESET_MODE,
6221         };
6222
6223         static const struct option options[] = {
6224                 { "help",                no_argument,       NULL, 'h'                     },
6225                 { "version",             no_argument,       NULL, ARG_VERSION             },
6226                 { "type",                required_argument, NULL, 't'                     },
6227                 { "property",            required_argument, NULL, 'p'                     },
6228                 { "all",                 no_argument,       NULL, 'a'                     },
6229                 { "reverse",             no_argument,       NULL, ARG_REVERSE             },
6230                 { "after",               no_argument,       NULL, ARG_AFTER               },
6231                 { "before",              no_argument,       NULL, ARG_BEFORE              },
6232                 { "show-types",          no_argument,       NULL, ARG_SHOW_TYPES          },
6233                 { "failed",              no_argument,       NULL, ARG_FAILED              }, /* compatibility only */
6234                 { "full",                no_argument,       NULL, 'l'                     },
6235                 { "job-mode",            required_argument, NULL, ARG_JOB_MODE            },
6236                 { "fail",                no_argument,       NULL, ARG_FAIL                }, /* compatibility only */
6237                 { "irreversible",        no_argument,       NULL, ARG_IRREVERSIBLE        }, /* compatibility only */
6238                 { "ignore-dependencies", no_argument,       NULL, ARG_IGNORE_DEPENDENCIES }, /* compatibility only */
6239                 { "ignore-inhibitors",   no_argument,       NULL, 'i'                     },
6240                 { "user",                no_argument,       NULL, ARG_USER                },
6241                 { "system",              no_argument,       NULL, ARG_SYSTEM              },
6242                 { "global",              no_argument,       NULL, ARG_GLOBAL              },
6243                 { "no-block",            no_argument,       NULL, ARG_NO_BLOCK            },
6244                 { "no-legend",           no_argument,       NULL, ARG_NO_LEGEND           },
6245                 { "no-pager",            no_argument,       NULL, ARG_NO_PAGER            },
6246                 { "no-wall",             no_argument,       NULL, ARG_NO_WALL             },
6247                 { "quiet",               no_argument,       NULL, 'q'                     },
6248                 { "root",                required_argument, NULL, ARG_ROOT                },
6249                 { "force",               no_argument,       NULL, ARG_FORCE               },
6250                 { "no-reload",           no_argument,       NULL, ARG_NO_RELOAD           },
6251                 { "kill-who",            required_argument, NULL, ARG_KILL_WHO            },
6252                 { "signal",              required_argument, NULL, 's'                     },
6253                 { "no-ask-password",     no_argument,       NULL, ARG_NO_ASK_PASSWORD     },
6254                 { "host",                required_argument, NULL, 'H'                     },
6255                 { "machine",             required_argument, NULL, 'M'                     },
6256                 { "runtime",             no_argument,       NULL, ARG_RUNTIME             },
6257                 { "lines",               required_argument, NULL, 'n'                     },
6258                 { "output",              required_argument, NULL, 'o'                     },
6259                 { "plain",               no_argument,       NULL, ARG_PLAIN               },
6260                 { "state",               required_argument, NULL, ARG_STATE               },
6261                 { "recursive",           no_argument,       NULL, 'r'                     },
6262                 { "preset-mode",         required_argument, NULL, ARG_PRESET_MODE         },
6263                 {}
6264         };
6265
6266         int c;
6267
6268         assert(argc >= 0);
6269         assert(argv);
6270
6271         while ((c = getopt_long(argc, argv, "ht:p:alqfs:H:M:n:o:ir", options, NULL)) >= 0)
6272
6273                 switch (c) {
6274
6275                 case 'h':
6276                         systemctl_help();
6277                         return 0;
6278
6279                 case ARG_VERSION:
6280                         puts(PACKAGE_STRING);
6281                         puts(SYSTEMD_FEATURES);
6282                         return 0;
6283
6284                 case 't': {
6285                         const char *word, *state;
6286                         size_t size;
6287
6288                         FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
6289                                 _cleanup_free_ char *type;
6290
6291                                 type = strndup(word, size);
6292                                 if (!type)
6293                                         return -ENOMEM;
6294
6295                                 if (streq(type, "help")) {
6296                                         help_types();
6297                                         return 0;
6298                                 }
6299
6300                                 if (unit_type_from_string(type) >= 0) {
6301                                         if (strv_push(&arg_types, type))
6302                                                 return log_oom();
6303                                         type = NULL;
6304                                         continue;
6305                                 }
6306
6307                                 /* It's much nicer to use --state= for
6308                                  * load states, but let's support this
6309                                  * in --types= too for compatibility
6310                                  * with old versions */
6311                                 if (unit_load_state_from_string(optarg) >= 0) {
6312                                         if (strv_push(&arg_states, type) < 0)
6313                                                 return log_oom();
6314                                         type = NULL;
6315                                         continue;
6316                                 }
6317
6318                                 log_error("Unknown unit type or load state '%s'.", type);
6319                                 log_info("Use -t help to see a list of allowed values.");
6320                                 return -EINVAL;
6321                         }
6322
6323                         break;
6324                 }
6325
6326                 case 'p': {
6327                         /* Make sure that if the empty property list
6328                            was specified, we won't show any properties. */
6329                         if (isempty(optarg) && !arg_properties) {
6330                                 arg_properties = new0(char*, 1);
6331                                 if (!arg_properties)
6332                                         return log_oom();
6333                         } else {
6334                                 const char *word, *state;
6335                                 size_t size;
6336
6337                                 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
6338                                         char *prop;
6339
6340                                         prop = strndup(word, size);
6341                                         if (!prop)
6342                                                 return log_oom();
6343
6344                                         if (strv_consume(&arg_properties, prop) < 0)
6345                                                 return log_oom();
6346                                 }
6347                         }
6348
6349                         /* If the user asked for a particular
6350                          * property, show it to him, even if it is
6351                          * empty. */
6352                         arg_all = true;
6353
6354                         break;
6355                 }
6356
6357                 case 'a':
6358                         arg_all = true;
6359                         break;
6360
6361                 case ARG_REVERSE:
6362                         arg_dependency = DEPENDENCY_REVERSE;
6363                         break;
6364
6365                 case ARG_AFTER:
6366                         arg_dependency = DEPENDENCY_AFTER;
6367                         break;
6368
6369                 case ARG_BEFORE:
6370                         arg_dependency = DEPENDENCY_BEFORE;
6371                         break;
6372
6373                 case ARG_SHOW_TYPES:
6374                         arg_show_types = true;
6375                         break;
6376
6377                 case ARG_JOB_MODE:
6378                         arg_job_mode = optarg;
6379                         break;
6380
6381                 case ARG_FAIL:
6382                         arg_job_mode = "fail";
6383                         break;
6384
6385                 case ARG_IRREVERSIBLE:
6386                         arg_job_mode = "replace-irreversibly";
6387                         break;
6388
6389                 case ARG_IGNORE_DEPENDENCIES:
6390                         arg_job_mode = "ignore-dependencies";
6391                         break;
6392
6393                 case ARG_USER:
6394                         arg_scope = UNIT_FILE_USER;
6395                         break;
6396
6397                 case ARG_SYSTEM:
6398                         arg_scope = UNIT_FILE_SYSTEM;
6399                         break;
6400
6401                 case ARG_GLOBAL:
6402                         arg_scope = UNIT_FILE_GLOBAL;
6403                         break;
6404
6405                 case ARG_NO_BLOCK:
6406                         arg_no_block = true;
6407                         break;
6408
6409                 case ARG_NO_LEGEND:
6410                         arg_no_legend = true;
6411                         break;
6412
6413                 case ARG_NO_PAGER:
6414                         arg_no_pager = true;
6415                         break;
6416
6417                 case ARG_NO_WALL:
6418                         arg_no_wall = true;
6419                         break;
6420
6421                 case ARG_ROOT:
6422                         arg_root = optarg;
6423                         break;
6424
6425                 case 'l':
6426                         arg_full = true;
6427                         break;
6428
6429                 case ARG_FAILED:
6430                         if (strv_extend(&arg_states, "failed") < 0)
6431                                 return log_oom();
6432
6433                         break;
6434
6435                 case 'q':
6436                         arg_quiet = true;
6437                         break;
6438
6439                 case ARG_FORCE:
6440                         arg_force ++;
6441                         break;
6442
6443                 case 'f':
6444                         arg_force ++;
6445                         break;
6446
6447                 case ARG_NO_RELOAD:
6448                         arg_no_reload = true;
6449                         break;
6450
6451                 case ARG_KILL_WHO:
6452                         arg_kill_who = optarg;
6453                         break;
6454
6455                 case 's':
6456                         if ((arg_signal = signal_from_string_try_harder(optarg)) < 0) {
6457                                 log_error("Failed to parse signal string %s.", optarg);
6458                                 return -EINVAL;
6459                         }
6460                         break;
6461
6462                 case ARG_NO_ASK_PASSWORD:
6463                         arg_ask_password = false;
6464                         break;
6465
6466                 case 'H':
6467                         arg_transport = BUS_TRANSPORT_REMOTE;
6468                         arg_host = optarg;
6469                         break;
6470
6471                 case 'M':
6472                         arg_transport = BUS_TRANSPORT_MACHINE;
6473                         arg_host = optarg;
6474                         break;
6475
6476                 case ARG_RUNTIME:
6477                         arg_runtime = true;
6478                         break;
6479
6480                 case 'n':
6481                         if (safe_atou(optarg, &arg_lines) < 0) {
6482                                 log_error("Failed to parse lines '%s'", optarg);
6483                                 return -EINVAL;
6484                         }
6485                         break;
6486
6487                 case 'o':
6488                         arg_output = output_mode_from_string(optarg);
6489                         if (arg_output < 0) {
6490                                 log_error("Unknown output '%s'.", optarg);
6491                                 return -EINVAL;
6492                         }
6493                         break;
6494
6495                 case 'i':
6496                         arg_ignore_inhibitors = true;
6497                         break;
6498
6499                 case ARG_PLAIN:
6500                         arg_plain = true;
6501                         break;
6502
6503                 case ARG_STATE: {
6504                         const char *word, *state;
6505                         size_t size;
6506
6507                         FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
6508                                 char *s;
6509
6510                                 s = strndup(word, size);
6511                                 if (!s)
6512                                         return log_oom();
6513
6514                                 if (strv_consume(&arg_states, s) < 0)
6515                                         return log_oom();
6516                         }
6517                         break;
6518                 }
6519
6520                 case 'r':
6521                         if (geteuid() != 0) {
6522                                 log_error("--recursive requires root privileges.");
6523                                 return -EPERM;
6524                         }
6525
6526                         arg_recursive = true;
6527                         break;
6528
6529                 case ARG_PRESET_MODE:
6530
6531                         arg_preset_mode = unit_file_preset_mode_from_string(optarg);
6532                         if (arg_preset_mode < 0) {
6533                                 log_error("Failed to parse preset mode: %s.", optarg);
6534                                 return -EINVAL;
6535                         }
6536
6537                         break;
6538
6539                 case '?':
6540                         return -EINVAL;
6541
6542                 default:
6543                         assert_not_reached("Unhandled option");
6544                 }
6545
6546         if (arg_transport != BUS_TRANSPORT_LOCAL && arg_scope != UNIT_FILE_SYSTEM) {
6547                 log_error("Cannot access user instance remotely.");
6548                 return -EINVAL;
6549         }
6550
6551         return 1;
6552 }
6553
6554 static int halt_parse_argv(int argc, char *argv[]) {
6555
6556         enum {
6557                 ARG_HELP = 0x100,
6558                 ARG_HALT,
6559                 ARG_REBOOT,
6560                 ARG_NO_WALL
6561         };
6562
6563         static const struct option options[] = {
6564                 { "help",      no_argument,       NULL, ARG_HELP    },
6565                 { "halt",      no_argument,       NULL, ARG_HALT    },
6566                 { "poweroff",  no_argument,       NULL, 'p'         },
6567                 { "reboot",    no_argument,       NULL, ARG_REBOOT  },
6568                 { "force",     no_argument,       NULL, 'f'         },
6569                 { "wtmp-only", no_argument,       NULL, 'w'         },
6570                 { "no-wtmp",   no_argument,       NULL, 'd'         },
6571                 { "no-wall",   no_argument,       NULL, ARG_NO_WALL },
6572                 {}
6573         };
6574
6575         int c, r, runlevel;
6576
6577         assert(argc >= 0);
6578         assert(argv);
6579
6580         if (utmp_get_runlevel(&runlevel, NULL) >= 0)
6581                 if (runlevel == '0' || runlevel == '6')
6582                         arg_force = 2;
6583
6584         while ((c = getopt_long(argc, argv, "pfwdnih", options, NULL)) >= 0)
6585                 switch (c) {
6586
6587                 case ARG_HELP:
6588                         halt_help();
6589                         return 0;
6590
6591                 case ARG_HALT:
6592                         arg_action = ACTION_HALT;
6593                         break;
6594
6595                 case 'p':
6596                         if (arg_action != ACTION_REBOOT)
6597                                 arg_action = ACTION_POWEROFF;
6598                         break;
6599
6600                 case ARG_REBOOT:
6601                         arg_action = ACTION_REBOOT;
6602                         break;
6603
6604                 case 'f':
6605                         arg_force = 2;
6606                         break;
6607
6608                 case 'w':
6609                         arg_dry = true;
6610                         break;
6611
6612                 case 'd':
6613                         arg_no_wtmp = true;
6614                         break;
6615
6616                 case ARG_NO_WALL:
6617                         arg_no_wall = true;
6618                         break;
6619
6620                 case 'i':
6621                 case 'h':
6622                 case 'n':
6623                         /* Compatibility nops */
6624                         break;
6625
6626                 case '?':
6627                         return -EINVAL;
6628
6629                 default:
6630                         assert_not_reached("Unhandled option");
6631                 }
6632
6633         if (arg_action == ACTION_REBOOT && (argc == optind || argc == optind + 1)) {
6634                 r = update_reboot_param_file(argc == optind + 1 ? argv[optind] : NULL);
6635                 if (r < 0)
6636                         return r;
6637         } else if (optind < argc) {
6638                 log_error("Too many arguments.");
6639                 return -EINVAL;
6640         }
6641
6642         return 1;
6643 }
6644
6645 static int parse_time_spec(const char *t, usec_t *_u) {
6646         assert(t);
6647         assert(_u);
6648
6649         if (streq(t, "now"))
6650                 *_u = 0;
6651         else if (!strchr(t, ':')) {
6652                 uint64_t u;
6653
6654                 if (safe_atou64(t, &u) < 0)
6655                         return -EINVAL;
6656
6657                 *_u = now(CLOCK_REALTIME) + USEC_PER_MINUTE * u;
6658         } else {
6659                 char *e = NULL;
6660                 long hour, minute;
6661                 struct tm tm = {};
6662                 time_t s;
6663                 usec_t n;
6664
6665                 errno = 0;
6666                 hour = strtol(t, &e, 10);
6667                 if (errno > 0 || *e != ':' || hour < 0 || hour > 23)
6668                         return -EINVAL;
6669
6670                 minute = strtol(e+1, &e, 10);
6671                 if (errno > 0 || *e != 0 || minute < 0 || minute > 59)
6672                         return -EINVAL;
6673
6674                 n = now(CLOCK_REALTIME);
6675                 s = (time_t) (n / USEC_PER_SEC);
6676
6677                 assert_se(localtime_r(&s, &tm));
6678
6679                 tm.tm_hour = (int) hour;
6680                 tm.tm_min = (int) minute;
6681                 tm.tm_sec = 0;
6682
6683                 assert_se(s = mktime(&tm));
6684
6685                 *_u = (usec_t) s * USEC_PER_SEC;
6686
6687                 while (*_u <= n)
6688                         *_u += USEC_PER_DAY;
6689         }
6690
6691         return 0;
6692 }
6693
6694 static int shutdown_parse_argv(int argc, char *argv[]) {
6695
6696         enum {
6697                 ARG_HELP = 0x100,
6698                 ARG_NO_WALL
6699         };
6700
6701         static const struct option options[] = {
6702                 { "help",      no_argument,       NULL, ARG_HELP    },
6703                 { "halt",      no_argument,       NULL, 'H'         },
6704                 { "poweroff",  no_argument,       NULL, 'P'         },
6705                 { "reboot",    no_argument,       NULL, 'r'         },
6706                 { "kexec",     no_argument,       NULL, 'K'         }, /* not documented extension */
6707                 { "no-wall",   no_argument,       NULL, ARG_NO_WALL },
6708                 {}
6709         };
6710
6711         int c, r;
6712
6713         assert(argc >= 0);
6714         assert(argv);
6715
6716         while ((c = getopt_long(argc, argv, "HPrhkKt:afFc", options, NULL)) >= 0)
6717                 switch (c) {
6718
6719                 case ARG_HELP:
6720                         shutdown_help();
6721                         return 0;
6722
6723                 case 'H':
6724                         arg_action = ACTION_HALT;
6725                         break;
6726
6727                 case 'P':
6728                         arg_action = ACTION_POWEROFF;
6729                         break;
6730
6731                 case 'r':
6732                         if (kexec_loaded())
6733                                 arg_action = ACTION_KEXEC;
6734                         else
6735                                 arg_action = ACTION_REBOOT;
6736                         break;
6737
6738                 case 'K':
6739                         arg_action = ACTION_KEXEC;
6740                         break;
6741
6742                 case 'h':
6743                         if (arg_action != ACTION_HALT)
6744                                 arg_action = ACTION_POWEROFF;
6745                         break;
6746
6747                 case 'k':
6748                         arg_dry = true;
6749                         break;
6750
6751                 case ARG_NO_WALL:
6752                         arg_no_wall = true;
6753                         break;
6754
6755                 case 't':
6756                 case 'a':
6757                 case 'f':
6758                 case 'F':
6759                         /* Compatibility nops */
6760                         break;
6761
6762                 case 'c':
6763                         arg_action = ACTION_CANCEL_SHUTDOWN;
6764                         break;
6765
6766                 case '?':
6767                         return -EINVAL;
6768
6769                 default:
6770                         assert_not_reached("Unhandled option");
6771                 }
6772
6773         if (argc > optind && arg_action != ACTION_CANCEL_SHUTDOWN) {
6774                 r = parse_time_spec(argv[optind], &arg_when);
6775                 if (r < 0) {
6776                         log_error("Failed to parse time specification: %s", argv[optind]);
6777                         return r;
6778                 }
6779         } else
6780                 arg_when = now(CLOCK_REALTIME) + USEC_PER_MINUTE;
6781
6782         if (argc > optind && arg_action == ACTION_CANCEL_SHUTDOWN)
6783                 /* No time argument for shutdown cancel */
6784                 arg_wall = argv + optind;
6785         else if (argc > optind + 1)
6786                 /* We skip the time argument */
6787                 arg_wall = argv + optind + 1;
6788
6789         optind = argc;
6790
6791         return 1;
6792 }
6793
6794 static int telinit_parse_argv(int argc, char *argv[]) {
6795
6796         enum {
6797                 ARG_HELP = 0x100,
6798                 ARG_NO_WALL
6799         };
6800
6801         static const struct option options[] = {
6802                 { "help",      no_argument,       NULL, ARG_HELP    },
6803                 { "no-wall",   no_argument,       NULL, ARG_NO_WALL },
6804                 {}
6805         };
6806
6807         static const struct {
6808                 char from;
6809                 enum action to;
6810         } table[] = {
6811                 { '0', ACTION_POWEROFF },
6812                 { '6', ACTION_REBOOT },
6813                 { '1', ACTION_RESCUE },
6814                 { '2', ACTION_RUNLEVEL2 },
6815                 { '3', ACTION_RUNLEVEL3 },
6816                 { '4', ACTION_RUNLEVEL4 },
6817                 { '5', ACTION_RUNLEVEL5 },
6818                 { 's', ACTION_RESCUE },
6819                 { 'S', ACTION_RESCUE },
6820                 { 'q', ACTION_RELOAD },
6821                 { 'Q', ACTION_RELOAD },
6822                 { 'u', ACTION_REEXEC },
6823                 { 'U', ACTION_REEXEC }
6824         };
6825
6826         unsigned i;
6827         int c;
6828
6829         assert(argc >= 0);
6830         assert(argv);
6831
6832         while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0)
6833                 switch (c) {
6834
6835                 case ARG_HELP:
6836                         telinit_help();
6837                         return 0;
6838
6839                 case ARG_NO_WALL:
6840                         arg_no_wall = true;
6841                         break;
6842
6843                 case '?':
6844                         return -EINVAL;
6845
6846                 default:
6847                         assert_not_reached("Unhandled option");
6848                 }
6849
6850         if (optind >= argc) {
6851                 log_error("%s: required argument missing.",
6852                           program_invocation_short_name);
6853                 return -EINVAL;
6854         }
6855
6856         if (optind + 1 < argc) {
6857                 log_error("Too many arguments.");
6858                 return -EINVAL;
6859         }
6860
6861         if (strlen(argv[optind]) != 1) {
6862                 log_error("Expected single character argument.");
6863                 return -EINVAL;
6864         }
6865
6866         for (i = 0; i < ELEMENTSOF(table); i++)
6867                 if (table[i].from == argv[optind][0])
6868                         break;
6869
6870         if (i >= ELEMENTSOF(table)) {
6871                 log_error("Unknown command '%s'.", argv[optind]);
6872                 return -EINVAL;
6873         }
6874
6875         arg_action = table[i].to;
6876
6877         optind ++;
6878
6879         return 1;
6880 }
6881
6882 static int runlevel_parse_argv(int argc, char *argv[]) {
6883
6884         enum {
6885                 ARG_HELP = 0x100,
6886         };
6887
6888         static const struct option options[] = {
6889                 { "help",      no_argument,       NULL, ARG_HELP    },
6890                 {}
6891         };
6892
6893         int c;
6894
6895         assert(argc >= 0);
6896         assert(argv);
6897
6898         while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0)
6899                 switch (c) {
6900
6901                 case ARG_HELP:
6902                         runlevel_help();
6903                         return 0;
6904
6905                 case '?':
6906                         return -EINVAL;
6907
6908                 default:
6909                         assert_not_reached("Unhandled option");
6910                 }
6911
6912         if (optind < argc) {
6913                 log_error("Too many arguments.");
6914                 return -EINVAL;
6915         }
6916
6917         return 1;
6918 }
6919
6920 static int parse_argv(int argc, char *argv[]) {
6921         assert(argc >= 0);
6922         assert(argv);
6923
6924         if (program_invocation_short_name) {
6925
6926                 if (strstr(program_invocation_short_name, "halt")) {
6927                         arg_action = ACTION_HALT;
6928                         return halt_parse_argv(argc, argv);
6929                 } else if (strstr(program_invocation_short_name, "poweroff")) {
6930                         arg_action = ACTION_POWEROFF;
6931                         return halt_parse_argv(argc, argv);
6932                 } else if (strstr(program_invocation_short_name, "reboot")) {
6933                         if (kexec_loaded())
6934                                 arg_action = ACTION_KEXEC;
6935                         else
6936                                 arg_action = ACTION_REBOOT;
6937                         return halt_parse_argv(argc, argv);
6938                 } else if (strstr(program_invocation_short_name, "shutdown")) {
6939                         arg_action = ACTION_POWEROFF;
6940                         return shutdown_parse_argv(argc, argv);
6941                 } else if (strstr(program_invocation_short_name, "init")) {
6942
6943                         if (sd_booted() > 0) {
6944                                 arg_action = _ACTION_INVALID;
6945                                 return telinit_parse_argv(argc, argv);
6946                         } else {
6947                                 /* Hmm, so some other init system is
6948                                  * running, we need to forward this
6949                                  * request to it. For now we simply
6950                                  * guess that it is Upstart. */
6951
6952                                 execv(TELINIT, argv);
6953
6954                                 log_error("Couldn't find an alternative telinit implementation to spawn.");
6955                                 return -EIO;
6956                         }
6957
6958                 } else if (strstr(program_invocation_short_name, "runlevel")) {
6959                         arg_action = ACTION_RUNLEVEL;
6960                         return runlevel_parse_argv(argc, argv);
6961                 }
6962         }
6963
6964         arg_action = ACTION_SYSTEMCTL;
6965         return systemctl_parse_argv(argc, argv);
6966 }
6967
6968 _pure_ static int action_to_runlevel(void) {
6969
6970         static const char table[_ACTION_MAX] = {
6971                 [ACTION_HALT] =      '0',
6972                 [ACTION_POWEROFF] =  '0',
6973                 [ACTION_REBOOT] =    '6',
6974                 [ACTION_RUNLEVEL2] = '2',
6975                 [ACTION_RUNLEVEL3] = '3',
6976                 [ACTION_RUNLEVEL4] = '4',
6977                 [ACTION_RUNLEVEL5] = '5',
6978                 [ACTION_RESCUE] =    '1'
6979         };
6980
6981         assert(arg_action < _ACTION_MAX);
6982
6983         return table[arg_action];
6984 }
6985
6986 static int talk_initctl(void) {
6987
6988         struct init_request request = {
6989                 .magic = INIT_MAGIC,
6990                 .sleeptime  = 0,
6991                 .cmd = INIT_CMD_RUNLVL
6992         };
6993
6994         _cleanup_close_ int fd = -1;
6995         char rl;
6996         int r;
6997
6998         rl = action_to_runlevel();
6999         if (!rl)
7000                 return 0;
7001
7002         request.runlevel = rl;
7003
7004         fd = open(INIT_FIFO, O_WRONLY|O_NDELAY|O_CLOEXEC|O_NOCTTY);
7005         if (fd < 0) {
7006                 if (errno == ENOENT)
7007                         return 0;
7008
7009                 log_error_errno(errno, "Failed to open "INIT_FIFO": %m");
7010                 return -errno;
7011         }
7012
7013         r = loop_write(fd, &request, sizeof(request), false);
7014         if (r < 0)
7015                 return log_error_errno(r, "Failed to write to "INIT_FIFO": %m");
7016
7017         return 1;
7018 }
7019
7020 static int systemctl_main(sd_bus *bus, int argc, char *argv[], int bus_error) {
7021
7022         static const struct {
7023                 const char* verb;
7024                 const enum {
7025                         MORE,
7026                         LESS,
7027                         EQUAL
7028                 } argc_cmp;
7029                 const int argc;
7030                 int (* const dispatch)(sd_bus *bus, char **args);
7031                 const enum {
7032                         NOBUS = 1,
7033                         FORCE,
7034                 } bus;
7035         } verbs[] = {
7036                 { "list-units",            MORE,  0, list_units        },
7037                 { "list-unit-files",       MORE,  1, list_unit_files,  NOBUS },
7038                 { "list-sockets",          MORE,  1, list_sockets      },
7039                 { "list-timers",           MORE,  1, list_timers       },
7040                 { "list-jobs",             MORE,  1, list_jobs         },
7041                 { "list-machines",         MORE,  1, list_machines     },
7042                 { "clear-jobs",            EQUAL, 1, daemon_reload     },
7043                 { "cancel",                MORE,  2, cancel_job        },
7044                 { "start",                 MORE,  2, start_unit        },
7045                 { "stop",                  MORE,  2, start_unit        },
7046                 { "condstop",              MORE,  2, start_unit        }, /* For compatibility with ALTLinux */
7047                 { "reload",                MORE,  2, start_unit        },
7048                 { "restart",               MORE,  2, start_unit        },
7049                 { "try-restart",           MORE,  2, start_unit        },
7050                 { "reload-or-restart",     MORE,  2, start_unit        },
7051                 { "reload-or-try-restart", MORE,  2, start_unit        },
7052                 { "force-reload",          MORE,  2, start_unit        }, /* For compatibility with SysV */
7053                 { "condreload",            MORE,  2, start_unit        }, /* For compatibility with ALTLinux */
7054                 { "condrestart",           MORE,  2, start_unit        }, /* For compatibility with RH */
7055                 { "isolate",               EQUAL, 2, start_unit        },
7056                 { "kill",                  MORE,  2, kill_unit         },
7057                 { "is-active",             MORE,  2, check_unit_active },
7058                 { "check",                 MORE,  2, check_unit_active },
7059                 { "is-failed",             MORE,  2, check_unit_failed },
7060                 { "show",                  MORE,  1, show              },
7061                 { "cat",                   MORE,  2, cat,              NOBUS },
7062                 { "status",                MORE,  1, show              },
7063                 { "help",                  MORE,  2, show              },
7064                 { "snapshot",              LESS,  2, snapshot          },
7065                 { "delete",                MORE,  2, delete_snapshot   },
7066                 { "daemon-reload",         EQUAL, 1, daemon_reload     },
7067                 { "daemon-reexec",         EQUAL, 1, daemon_reload     },
7068                 { "show-environment",      EQUAL, 1, show_environment  },
7069                 { "set-environment",       MORE,  2, set_environment   },
7070                 { "unset-environment",     MORE,  2, set_environment   },
7071                 { "import-environment",    MORE,  1, import_environment},
7072                 { "halt",                  EQUAL, 1, start_special,    FORCE },
7073                 { "poweroff",              EQUAL, 1, start_special,    FORCE },
7074                 { "reboot",                EQUAL, 1, start_special,    FORCE },
7075                 { "kexec",                 EQUAL, 1, start_special     },
7076                 { "suspend",               EQUAL, 1, start_special     },
7077                 { "hibernate",             EQUAL, 1, start_special     },
7078                 { "hybrid-sleep",          EQUAL, 1, start_special     },
7079                 { "default",               EQUAL, 1, start_special     },
7080                 { "rescue",                EQUAL, 1, start_special     },
7081                 { "emergency",             EQUAL, 1, start_special     },
7082                 { "exit",                  EQUAL, 1, start_special     },
7083                 { "reset-failed",          MORE,  1, reset_failed      },
7084                 { "enable",                MORE,  2, enable_unit,      NOBUS },
7085                 { "disable",               MORE,  2, enable_unit,      NOBUS },
7086                 { "is-enabled",            MORE,  2, unit_is_enabled,  NOBUS },
7087                 { "reenable",              MORE,  2, enable_unit,      NOBUS },
7088                 { "preset",                MORE,  2, enable_unit,      NOBUS },
7089                 { "preset-all",            EQUAL, 1, preset_all,       NOBUS },
7090                 { "mask",                  MORE,  2, enable_unit,      NOBUS },
7091                 { "unmask",                MORE,  2, enable_unit,      NOBUS },
7092                 { "link",                  MORE,  2, enable_unit,      NOBUS },
7093                 { "switch-root",           MORE,  2, switch_root       },
7094                 { "list-dependencies",     LESS,  2, list_dependencies },
7095                 { "set-default",           EQUAL, 2, set_default,      NOBUS },
7096                 { "get-default",           EQUAL, 1, get_default,      NOBUS },
7097                 { "set-property",          MORE,  3, set_property      },
7098                 { "is-system-running",     EQUAL, 1, is_system_running },
7099                 { "add-wants",             MORE,  3, add_dependency,   NOBUS },
7100                 { "add-requires",          MORE,  3, add_dependency,   NOBUS },
7101                 { "edit",                  MORE,  2, edit,             NOBUS },
7102                 {}
7103         }, *verb = verbs;
7104
7105         int left;
7106
7107         assert(argc >= 0);
7108         assert(argv);
7109
7110         left = argc - optind;
7111
7112         /* Special rule: no arguments (left == 0) means "list-units" */
7113         if (left > 0) {
7114                 if (streq(argv[optind], "help") && !argv[optind+1]) {
7115                         log_error("This command expects one or more "
7116                                   "unit names. Did you mean --help?");
7117                         return -EINVAL;
7118                 }
7119
7120                 for (; verb->verb; verb++)
7121                         if (streq(argv[optind], verb->verb))
7122                                 goto found;
7123
7124                 log_error("Unknown operation '%s'.", argv[optind]);
7125                 return -EINVAL;
7126         }
7127 found:
7128
7129         switch (verb->argc_cmp) {
7130
7131         case EQUAL:
7132                 if (left != verb->argc) {
7133                         log_error("Invalid number of arguments.");
7134                         return -EINVAL;
7135                 }
7136
7137                 break;
7138
7139         case MORE:
7140                 if (left < verb->argc) {
7141                         log_error("Too few arguments.");
7142                         return -EINVAL;
7143                 }
7144
7145                 break;
7146
7147         case LESS:
7148                 if (left > verb->argc) {
7149                         log_error("Too many arguments.");
7150                         return -EINVAL;
7151                 }
7152
7153                 break;
7154
7155         default:
7156                 assert_not_reached("Unknown comparison operator.");
7157         }
7158
7159         /* Require a bus connection for all operations but
7160          * enable/disable */
7161         if (verb->bus == NOBUS) {
7162                 if (!bus && !avoid_bus()) {
7163                         log_error_errno(bus_error, "Failed to get D-Bus connection: %m");
7164                         return -EIO;
7165                 }
7166
7167         } else {
7168                 if (running_in_chroot() > 0) {
7169                         log_info("Running in chroot, ignoring request.");
7170                         return 0;
7171                 }
7172
7173                 if ((verb->bus != FORCE || arg_force <= 0) && !bus) {
7174                         log_error_errno(bus_error, "Failed to get D-Bus connection: %m");
7175                         return -EIO;
7176                 }
7177         }
7178
7179         return verb->dispatch(bus, argv + optind);
7180 }
7181
7182 static int send_shutdownd(usec_t t, char mode, bool dry_run, bool warn, const char *message) {
7183
7184         struct sd_shutdown_command c = {
7185                 .usec = t,
7186                 .mode = mode,
7187                 .dry_run = dry_run,
7188                 .warn_wall = warn,
7189         };
7190
7191         union sockaddr_union sockaddr = {
7192                 .un.sun_family = AF_UNIX,
7193                 .un.sun_path = "/run/systemd/shutdownd",
7194         };
7195
7196         struct iovec iovec[2] = {{
7197                  .iov_base = (char*) &c,
7198                  .iov_len = offsetof(struct sd_shutdown_command, wall_message),
7199         }};
7200
7201         struct msghdr msghdr = {
7202                 .msg_name = &sockaddr,
7203                 .msg_namelen = offsetof(struct sockaddr_un, sun_path)
7204                                + strlen("/run/systemd/shutdownd"),
7205                 .msg_iov = iovec,
7206                 .msg_iovlen = 1,
7207         };
7208
7209         _cleanup_close_ int fd;
7210
7211         fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
7212         if (fd < 0)
7213                 return -errno;
7214
7215         if (!isempty(message)) {
7216                 iovec[1].iov_base = (char*) message;
7217                 iovec[1].iov_len = strlen(message);
7218                 msghdr.msg_iovlen++;
7219         }
7220
7221         if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) < 0)
7222                 return -errno;
7223
7224         return 0;
7225 }
7226
7227 static int reload_with_fallback(sd_bus *bus) {
7228
7229         if (bus) {
7230                 /* First, try systemd via D-Bus. */
7231                 if (daemon_reload(bus, NULL) >= 0)
7232                         return 0;
7233         }
7234
7235         /* Nothing else worked, so let's try signals */
7236         assert(arg_action == ACTION_RELOAD || arg_action == ACTION_REEXEC);
7237
7238         if (kill(1, arg_action == ACTION_RELOAD ? SIGHUP : SIGTERM) < 0)
7239                 return log_error_errno(errno, "kill() failed: %m");
7240
7241         return 0;
7242 }
7243
7244 static int start_with_fallback(sd_bus *bus) {
7245
7246         if (bus) {
7247                 /* First, try systemd via D-Bus. */
7248                 if (start_unit(bus, NULL) >= 0)
7249                         goto done;
7250         }
7251
7252         /* Nothing else worked, so let's try
7253          * /dev/initctl */
7254         if (talk_initctl() > 0)
7255                 goto done;
7256
7257         log_error("Failed to talk to init daemon.");
7258         return -EIO;
7259
7260 done:
7261         warn_wall(arg_action);
7262         return 0;
7263 }
7264
7265 static int halt_now(enum action a) {
7266
7267         /* The kernel will automaticall flush ATA disks and suchlike
7268          * on reboot(), but the file systems need to be synce'd
7269          * explicitly in advance. */
7270         sync();
7271
7272         /* Make sure C-A-D is handled by the kernel from this point
7273          * on... */
7274         reboot(RB_ENABLE_CAD);
7275
7276         switch (a) {
7277
7278         case ACTION_HALT:
7279                 log_info("Halting.");
7280                 reboot(RB_HALT_SYSTEM);
7281                 return -errno;
7282
7283         case ACTION_POWEROFF:
7284                 log_info("Powering off.");
7285                 reboot(RB_POWER_OFF);
7286                 return -errno;
7287
7288         case ACTION_REBOOT: {
7289                 _cleanup_free_ char *param = NULL;
7290
7291                 if (read_one_line_file(REBOOT_PARAM_FILE, &param) >= 0) {
7292                         log_info("Rebooting with argument '%s'.", param);
7293                         syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
7294                                 LINUX_REBOOT_CMD_RESTART2, param);
7295                 }
7296
7297                 log_info("Rebooting.");
7298                 reboot(RB_AUTOBOOT);
7299                 return -errno;
7300         }
7301
7302         default:
7303                 assert_not_reached("Unknown action.");
7304         }
7305 }
7306
7307 static int halt_main(sd_bus *bus) {
7308         int r;
7309
7310         r = check_inhibitors(bus, arg_action);
7311         if (r < 0)
7312                 return r;
7313
7314         if (geteuid() != 0) {
7315                 /* Try logind if we are a normal user and no special
7316                  * mode applies. Maybe PolicyKit allows us to shutdown
7317                  * the machine. */
7318
7319                 if (arg_when <= 0 &&
7320                     !arg_dry &&
7321                     arg_force <= 0 &&
7322                     (arg_action == ACTION_POWEROFF ||
7323                      arg_action == ACTION_REBOOT)) {
7324                         r = reboot_with_logind(bus, arg_action);
7325                         if (r >= 0)
7326                                 return r;
7327                 }
7328
7329                 log_error("Must be root.");
7330                 return -EPERM;
7331         }
7332
7333         if (arg_when > 0) {
7334                 _cleanup_free_ char *m;
7335
7336                 m = strv_join(arg_wall, " ");
7337                 if (!m)
7338                         return log_oom();
7339
7340                 r = send_shutdownd(arg_when,
7341                                    arg_action == ACTION_HALT     ? 'H' :
7342                                    arg_action == ACTION_POWEROFF ? 'P' :
7343                                    arg_action == ACTION_KEXEC    ? 'K' :
7344                                                                    'r',
7345                                    arg_dry,
7346                                    !arg_no_wall,
7347                                    m);
7348
7349                 if (r < 0)
7350                         log_warning_errno(r, "Failed to talk to shutdownd, proceeding with immediate shutdown: %m");
7351                 else {
7352                         char date[FORMAT_TIMESTAMP_MAX];
7353
7354                         log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.",
7355                                  format_timestamp(date, sizeof(date), arg_when));
7356                         return 0;
7357                 }
7358         }
7359
7360         if (!arg_dry && !arg_force)
7361                 return start_with_fallback(bus);
7362
7363         if (!arg_no_wtmp) {
7364                 if (sd_booted() > 0)
7365                         log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
7366                 else {
7367                         r = utmp_put_shutdown();
7368                         if (r < 0)
7369                                 log_warning_errno(r, "Failed to write utmp record: %m");
7370                 }
7371         }
7372
7373         if (arg_dry)
7374                 return 0;
7375
7376         r = halt_now(arg_action);
7377         log_error_errno(r, "Failed to reboot: %m");
7378
7379         return r;
7380 }
7381
7382 static int runlevel_main(void) {
7383         int r, runlevel, previous;
7384
7385         r = utmp_get_runlevel(&runlevel, &previous);
7386         if (r < 0) {
7387                 puts("unknown");
7388                 return r;
7389         }
7390
7391         printf("%c %c\n",
7392                previous <= 0 ? 'N' : previous,
7393                runlevel <= 0 ? 'N' : runlevel);
7394
7395         return 0;
7396 }
7397
7398 int main(int argc, char*argv[]) {
7399         _cleanup_bus_close_unref_ sd_bus *bus = NULL;
7400         int r;
7401
7402         setlocale(LC_ALL, "");
7403         log_parse_environment();
7404         log_open();
7405
7406         /* Explicitly not on_tty() to avoid setting cached value.
7407          * This becomes relevant for piping output which might be
7408          * ellipsized. */
7409         original_stdout_is_tty = isatty(STDOUT_FILENO);
7410
7411         r = parse_argv(argc, argv);
7412         if (r <= 0)
7413                 goto finish;
7414
7415         /* /sbin/runlevel doesn't need to communicate via D-Bus, so
7416          * let's shortcut this */
7417         if (arg_action == ACTION_RUNLEVEL) {
7418                 r = runlevel_main();
7419                 goto finish;
7420         }
7421
7422         if (running_in_chroot() > 0 && arg_action != ACTION_SYSTEMCTL) {
7423                 log_info("Running in chroot, ignoring request.");
7424                 r = 0;
7425                 goto finish;
7426         }
7427
7428         /* Increase max number of open files to 16K if we can, we
7429          * might needs this when browsing journal files, which might
7430          * be split up into many files. */
7431         setrlimit_closest(RLIMIT_NOFILE, &RLIMIT_MAKE_CONST(16384));
7432
7433         if (!avoid_bus())
7434                 r = bus_open_transport_systemd(arg_transport, arg_host, arg_scope != UNIT_FILE_SYSTEM, &bus);
7435
7436         /* systemctl_main() will print an error message for the bus
7437          * connection, but only if it needs to */
7438
7439         switch (arg_action) {
7440
7441         case ACTION_SYSTEMCTL:
7442                 r = systemctl_main(bus, argc, argv, r);
7443                 break;
7444
7445         case ACTION_HALT:
7446         case ACTION_POWEROFF:
7447         case ACTION_REBOOT:
7448         case ACTION_KEXEC:
7449                 r = halt_main(bus);
7450                 break;
7451
7452         case ACTION_RUNLEVEL2:
7453         case ACTION_RUNLEVEL3:
7454         case ACTION_RUNLEVEL4:
7455         case ACTION_RUNLEVEL5:
7456         case ACTION_RESCUE:
7457         case ACTION_EMERGENCY:
7458         case ACTION_DEFAULT:
7459                 r = start_with_fallback(bus);
7460                 break;
7461
7462         case ACTION_RELOAD:
7463         case ACTION_REEXEC:
7464                 r = reload_with_fallback(bus);
7465                 break;
7466
7467         case ACTION_CANCEL_SHUTDOWN: {
7468                 _cleanup_free_ char *m = NULL;
7469
7470                 if (arg_wall) {
7471                         m = strv_join(arg_wall, " ");
7472                         if (!m) {
7473                                 r = log_oom();
7474                                 goto finish;
7475                         }
7476                 }
7477
7478                 r = send_shutdownd(arg_when, SD_SHUTDOWN_NONE, false, !arg_no_wall, m);
7479                 if (r < 0)
7480                         log_warning_errno(r, "Failed to talk to shutdownd, shutdown hasn't been cancelled: %m");
7481                 break;
7482         }
7483
7484         case ACTION_RUNLEVEL:
7485         case _ACTION_INVALID:
7486         default:
7487                 assert_not_reached("Unknown action");
7488         }
7489
7490 finish:
7491         pager_close();
7492         ask_password_agent_close();
7493         polkit_agent_close();
7494
7495         strv_free(arg_types);
7496         strv_free(arg_states);
7497         strv_free(arg_properties);
7498
7499         return r < 0 ? EXIT_FAILURE : r;
7500 }