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