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