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