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