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