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