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