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