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