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