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