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