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