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