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