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