chiark / gitweb /
15d46bdfdecd852f2cb4a66efe92fa0b40fa25d7
[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;
2150         char **name;
2151         int r = 0;
2152         char **names, *strv[] = {NULL, NULL}; /* at most one name */
2153
2154         assert(bus);
2155
2156         ask_password_agent_open_if_enabled();
2157
2158         if (arg_action == ACTION_SYSTEMCTL) {
2159                 enum action action;
2160                 method =
2161                         streq(args[0], "stop") ||
2162                         streq(args[0], "condstop")              ? "StopUnit" :
2163                         streq(args[0], "reload")                ? "ReloadUnit" :
2164                         streq(args[0], "restart")               ? "RestartUnit" :
2165
2166                         streq(args[0], "try-restart")           ||
2167                         streq(args[0], "condrestart")           ? "TryRestartUnit" :
2168
2169                         streq(args[0], "reload-or-restart")     ? "ReloadOrRestartUnit" :
2170
2171                         streq(args[0], "reload-or-try-restart") ||
2172                         streq(args[0], "condreload")            ||
2173                         streq(args[0], "force-reload")          ? "ReloadOrTryRestartUnit" :
2174                                                                   "StartUnit";
2175                 action = verb_to_action(args[0]);
2176
2177                 mode = streq(args[0], "isolate") ? "isolate" :
2178                        action_table[action].mode ?: arg_job_mode;
2179
2180                 strv[0] = (char*) action_table[action].target;
2181         } else {
2182                 assert(arg_action < ELEMENTSOF(action_table));
2183                 assert(action_table[arg_action].target);
2184
2185                 method = "StartUnit";
2186
2187                 mode = action_table[arg_action].mode;
2188                 strv[0] = (char*) action_table[arg_action].target;
2189         }
2190
2191         if (strv[0])
2192                 names = strv;
2193         else
2194                 names = args + 1;
2195
2196         if (!arg_no_block) {
2197                 r = enable_wait_for_jobs(bus);
2198                 if (r < 0) {
2199                         log_error("Could not watch jobs: %s", strerror(-r));
2200                         return r;
2201                 }
2202
2203                 s = set_new(string_hash_func, string_compare_func);
2204                 if (!s)
2205                         return log_oom();
2206         }
2207
2208         STRV_FOREACH(name, names) {
2209                 int q;
2210
2211                 q = start_unit_one(bus, method, *name, mode, &error, s);
2212                 if (r == 0 && q < 0) {
2213                         r = translate_bus_error_to_exit_status(q, &error);
2214                         sd_bus_error_free(&error);
2215                 }
2216         }
2217
2218         if (!arg_no_block) {
2219                 int q;
2220
2221                 q = wait_for_jobs(bus, s);
2222                 if (q < 0)
2223                         return q;
2224
2225                 /* When stopping units, warn if they can still be triggered by
2226                  * another active unit (socket, path, timer) */
2227                 if (!arg_quiet && streq(method, "StopUnit"))
2228                         STRV_FOREACH(name, names)
2229                                 check_triggering_units(bus, *name);
2230         }
2231
2232         return r;
2233 }
2234
2235 /* Ask systemd-logind, which might grant access to unprivileged users
2236  * through PolicyKit */
2237 static int reboot_with_logind(sd_bus *bus, enum action a) {
2238 #ifdef HAVE_LOGIND
2239         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2240         const char *method;
2241         int r;
2242
2243         if (!bus)
2244                 return -EIO;
2245
2246         polkit_agent_open_if_enabled();
2247
2248         switch (a) {
2249
2250         case ACTION_REBOOT:
2251                 method = "Reboot";
2252                 break;
2253
2254         case ACTION_POWEROFF:
2255                 method = "PowerOff";
2256                 break;
2257
2258         case ACTION_SUSPEND:
2259                 method = "Suspend";
2260                 break;
2261
2262         case ACTION_HIBERNATE:
2263                 method = "Hibernate";
2264                 break;
2265
2266         case ACTION_HYBRID_SLEEP:
2267                 method = "HybridSleep";
2268                 break;
2269
2270         default:
2271                 return -EINVAL;
2272         }
2273
2274         r = sd_bus_call_method(
2275                         bus,
2276                         "org.freedesktop.login1",
2277                         "/org/freedesktop/login1",
2278                         "org.freedesktop.login1.Manager",
2279                         method,
2280                         &error,
2281                         NULL,
2282                         "b", true);
2283         if (r < 0)
2284                 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
2285
2286         return r;
2287 #else
2288         return -ENOSYS;
2289 #endif
2290 }
2291
2292 static int check_inhibitors(sd_bus *bus, enum action a) {
2293 #ifdef HAVE_LOGIND
2294         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2295         _cleanup_strv_free_ char **sessions = NULL;
2296         const char *what, *who, *why, *mode;
2297         uint32_t uid, pid;
2298         unsigned c = 0;
2299         char **s;
2300         int r;
2301
2302         if (!bus)
2303                 return 0;
2304
2305         if (arg_ignore_inhibitors || arg_force > 0)
2306                 return 0;
2307
2308         if (arg_when > 0)
2309                 return 0;
2310
2311         if (geteuid() == 0)
2312                 return 0;
2313
2314         if (!on_tty())
2315                 return 0;
2316
2317         r = sd_bus_call_method(
2318                         bus,
2319                         "org.freedesktop.login1",
2320                         "/org/freedesktop/login1",
2321                         "org.freedesktop.login1.Manager",
2322                         "ListInhibitors",
2323                         NULL,
2324                         &reply,
2325                         NULL);
2326         if (r < 0)
2327                 /* If logind is not around, then there are no inhibitors... */
2328                 return 0;
2329
2330         r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssuu)");
2331         if (r < 0)
2332                 return bus_log_parse_error(r);
2333
2334         while ((r = sd_bus_message_read(reply, "(ssssuu)", &what, &who, &why, &mode, &uid, &pid)) > 0) {
2335                 _cleanup_free_ char *comm = NULL, *user = NULL;
2336                 _cleanup_strv_free_ char **sv = NULL;
2337
2338                 if (!streq(mode, "block"))
2339                         continue;
2340
2341                 sv = strv_split(what, ":");
2342                 if (!sv)
2343                         return log_oom();
2344
2345                 if (!strv_contains(sv,
2346                                   a == ACTION_HALT ||
2347                                   a == ACTION_POWEROFF ||
2348                                   a == ACTION_REBOOT ||
2349                                   a == ACTION_KEXEC ? "shutdown" : "sleep"))
2350                         continue;
2351
2352                 get_process_comm(pid, &comm);
2353                 user = uid_to_name(uid);
2354
2355                 log_warning("Operation inhibited by \"%s\" (PID %lu \"%s\", user %s), reason is \"%s\".",
2356                             who, (unsigned long) pid, strna(comm), strna(user), why);
2357
2358                 c++;
2359         }
2360         if (r < 0)
2361                 return bus_log_parse_error(r);
2362
2363         r = sd_bus_message_exit_container(reply);
2364         if (r < 0)
2365                 return bus_log_parse_error(r);
2366
2367         /* Check for current sessions */
2368         sd_get_sessions(&sessions);
2369         STRV_FOREACH(s, sessions) {
2370                 _cleanup_free_ char *type = NULL, *tty = NULL, *seat = NULL, *user = NULL, *service = NULL, *class = NULL;
2371
2372                 if (sd_session_get_uid(*s, &uid) < 0 || uid == getuid())
2373                         continue;
2374
2375                 if (sd_session_get_class(*s, &class) < 0 || !streq(class, "user"))
2376                         continue;
2377
2378                 if (sd_session_get_type(*s, &type) < 0 || (!streq(type, "x11") && !streq(type, "tty")))
2379                         continue;
2380
2381                 sd_session_get_tty(*s, &tty);
2382                 sd_session_get_seat(*s, &seat);
2383                 sd_session_get_service(*s, &service);
2384                 user = uid_to_name(uid);
2385
2386                 log_warning("User %s is logged in on %s.", strna(user), isempty(tty) ? (isempty(seat) ? strna(service) : seat) : tty);
2387                 c++;
2388         }
2389
2390         if (c <= 0)
2391                 return 0;
2392
2393         log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
2394                   action_table[a].verb);
2395
2396         return -EPERM;
2397 #else
2398         return 0;
2399 #endif
2400 }
2401
2402 static int start_special(sd_bus *bus, char **args) {
2403         enum action a;
2404         int r;
2405
2406         assert(args);
2407
2408         a = verb_to_action(args[0]);
2409
2410         r = check_inhibitors(bus, a);
2411         if (r < 0)
2412                 return r;
2413
2414         if (arg_force >= 2 && geteuid() != 0) {
2415                 log_error("Must be root.");
2416                 return -EPERM;
2417         }
2418
2419         if (arg_force >= 2 &&
2420             (a == ACTION_HALT ||
2421              a == ACTION_POWEROFF ||
2422              a == ACTION_REBOOT))
2423                 return halt_now(a);
2424
2425         if (arg_force >= 1 &&
2426             (a == ACTION_HALT ||
2427              a == ACTION_POWEROFF ||
2428              a == ACTION_REBOOT ||
2429              a == ACTION_KEXEC ||
2430              a == ACTION_EXIT))
2431                 return daemon_reload(bus, args);
2432
2433         /* first try logind, to allow authentication with polkit */
2434         if (geteuid() != 0 &&
2435             (a == ACTION_POWEROFF ||
2436              a == ACTION_REBOOT ||
2437              a == ACTION_SUSPEND ||
2438              a == ACTION_HIBERNATE ||
2439              a == ACTION_HYBRID_SLEEP)) {
2440                 r = reboot_with_logind(bus, a);
2441                 if (r >= 0)
2442                         return r;
2443         }
2444
2445         r = start_unit(bus, args);
2446         if (r == EXIT_SUCCESS)
2447                 warn_wall(a);
2448
2449         return r;
2450 }
2451
2452 static int check_unit_active(sd_bus *bus, char **args) {
2453         char **name;
2454         int r = 3; /* According to LSB: "program is not running" */
2455
2456         assert(bus);
2457         assert(args);
2458
2459         STRV_FOREACH(name, args+1) {
2460                 int state;
2461
2462                 state = check_one_unit(bus, *name, "active\0reloading\0", arg_quiet);
2463                 if (state < 0)
2464                         return state;
2465                 if (state > 0)
2466                         r = 0;
2467         }
2468
2469         return r;
2470 }
2471
2472 static int check_unit_failed(sd_bus *bus, char **args) {
2473         char **name;
2474         int r = 1;
2475
2476         assert(bus);
2477         assert(args);
2478
2479         STRV_FOREACH(name, args+1) {
2480                 int state;
2481
2482                 state = check_one_unit(bus, *name, "failed\0", arg_quiet);
2483                 if (state < 0)
2484                         return state;
2485                 if (state > 0)
2486                         r = 0;
2487         }
2488
2489         return r;
2490 }
2491
2492 static int kill_unit(sd_bus *bus, char **args) {
2493         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2494         char **name;
2495         int r = 0;
2496
2497         assert(bus);
2498         assert(args);
2499
2500         if (!arg_kill_who)
2501                 arg_kill_who = "all";
2502
2503         STRV_FOREACH(name, args+1) {
2504                 _cleanup_free_ char *n = NULL;
2505
2506                 n = unit_name_mangle(*name);
2507                 if (!n)
2508                         return log_oom();
2509
2510                 r = sd_bus_call_method(
2511                                 bus,
2512                                 "org.freedesktop.systemd1",
2513                                 "/org/freedesktop/systemd1",
2514                                 "org.freedesktop.systemd1.Manager",
2515                                 "KillUnit",
2516                                 &error,
2517                                 NULL,
2518                                 "ssi", n, arg_kill_who, arg_signal);
2519                 if (r < 0) {
2520                         log_error("Failed to kill unit %s: %s", n, bus_error_message(&error, r));
2521                         return r;
2522                 }
2523         }
2524
2525         return 0;
2526 }
2527
2528 typedef struct ExecStatusInfo {
2529         char *name;
2530
2531         char *path;
2532         char **argv;
2533
2534         bool ignore;
2535
2536         usec_t start_timestamp;
2537         usec_t exit_timestamp;
2538         pid_t pid;
2539         int code;
2540         int status;
2541
2542         LIST_FIELDS(struct ExecStatusInfo, exec);
2543 } ExecStatusInfo;
2544
2545 static void exec_status_info_free(ExecStatusInfo *i) {
2546         assert(i);
2547
2548         free(i->name);
2549         free(i->path);
2550         strv_free(i->argv);
2551         free(i);
2552 }
2553
2554 static int exec_status_info_deserialize(sd_bus_message *m, ExecStatusInfo *i) {
2555         uint64_t start_timestamp, exit_timestamp, start_timestamp_monotonic, exit_timestamp_monotonic;
2556         const char *path;
2557         uint32_t pid;
2558         int32_t code, status;
2559         int ignore, r;
2560
2561         assert(m);
2562         assert(i);
2563
2564         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_STRUCT, "sasbttttuii");
2565         if (r < 0)
2566                 return bus_log_parse_error(r);
2567         else if (r == 0)
2568                 return 0;
2569
2570         r = sd_bus_message_read(m, "s", &path);
2571         if (r < 0)
2572                 return bus_log_parse_error(r);
2573
2574         i->path = strdup(path);
2575         if (!i->path)
2576                 return log_oom();
2577
2578         r = sd_bus_message_read_strv(m, &i->argv);
2579         if (r < 0)
2580                 return bus_log_parse_error(r);
2581
2582         r = sd_bus_message_read(m,
2583                                 "bttttuii",
2584                                 &ignore,
2585                                 &start_timestamp, &start_timestamp_monotonic,
2586                                 &exit_timestamp, &exit_timestamp_monotonic,
2587                                 &pid,
2588                                 &code, &status);
2589         if (r < 0)
2590                 return bus_log_parse_error(r);
2591
2592         i->ignore = ignore;
2593         i->start_timestamp = (usec_t) start_timestamp;
2594         i->exit_timestamp = (usec_t) exit_timestamp;
2595         i->pid = (pid_t) pid;
2596         i->code = code;
2597         i->status = status;
2598
2599         r = sd_bus_message_exit_container(m);
2600         if (r < 0)
2601                 return bus_log_parse_error(r);
2602
2603         return 1;
2604 }
2605
2606 typedef struct UnitStatusInfo {
2607         const char *id;
2608         const char *load_state;
2609         const char *active_state;
2610         const char *sub_state;
2611         const char *unit_file_state;
2612
2613         const char *description;
2614         const char *following;
2615
2616         char **documentation;
2617
2618         const char *fragment_path;
2619         const char *source_path;
2620         const char *control_group;
2621
2622         char **dropin_paths;
2623
2624         const char *load_error;
2625         const char *result;
2626
2627         usec_t inactive_exit_timestamp;
2628         usec_t inactive_exit_timestamp_monotonic;
2629         usec_t active_enter_timestamp;
2630         usec_t active_exit_timestamp;
2631         usec_t inactive_enter_timestamp;
2632
2633         bool need_daemon_reload;
2634
2635         /* Service */
2636         pid_t main_pid;
2637         pid_t control_pid;
2638         const char *status_text;
2639         const char *pid_file;
2640         bool running:1;
2641
2642         usec_t start_timestamp;
2643         usec_t exit_timestamp;
2644
2645         int exit_code, exit_status;
2646
2647         usec_t condition_timestamp;
2648         bool condition_result;
2649         bool failed_condition_trigger;
2650         bool failed_condition_negate;
2651         const char *failed_condition;
2652         const char *failed_condition_param;
2653
2654         /* Socket */
2655         unsigned n_accepted;
2656         unsigned n_connections;
2657         bool accept;
2658
2659         /* Pairs of type, path */
2660         char **listen;
2661
2662         /* Device */
2663         const char *sysfs_path;
2664
2665         /* Mount, Automount */
2666         const char *where;
2667
2668         /* Swap */
2669         const char *what;
2670
2671         LIST_HEAD(ExecStatusInfo, exec);
2672 } UnitStatusInfo;
2673
2674 static void print_status_info(
2675                 UnitStatusInfo *i,
2676                 bool *ellipsized) {
2677
2678         ExecStatusInfo *p;
2679         const char *on, *off, *ss;
2680         usec_t timestamp;
2681         char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
2682         char since2[FORMAT_TIMESTAMP_MAX], *s2;
2683         const char *path;
2684         int flags =
2685                 arg_all * OUTPUT_SHOW_ALL |
2686                 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
2687                 on_tty() * OUTPUT_COLOR |
2688                 !arg_quiet * OUTPUT_WARN_CUTOFF |
2689                 arg_full * OUTPUT_FULL_WIDTH;
2690         char **t, **t2;
2691
2692         assert(i);
2693
2694         /* This shows pretty information about a unit. See
2695          * print_property() for a low-level property printer */
2696
2697         printf("%s", strna(i->id));
2698
2699         if (i->description && !streq_ptr(i->id, i->description))
2700                 printf(" - %s", i->description);
2701
2702         printf("\n");
2703
2704         if (i->following)
2705                 printf("   Follow: unit currently follows state of %s\n", i->following);
2706
2707         if (streq_ptr(i->load_state, "error")) {
2708                 on = ansi_highlight_red();
2709                 off = ansi_highlight_off();
2710         } else
2711                 on = off = "";
2712
2713         path = i->source_path ? i->source_path : i->fragment_path;
2714
2715         if (i->load_error)
2716                 printf("   Loaded: %s%s%s (Reason: %s)\n",
2717                        on, strna(i->load_state), off, i->load_error);
2718         else if (path && i->unit_file_state)
2719                 printf("   Loaded: %s%s%s (%s; %s)\n",
2720                        on, strna(i->load_state), off, path, i->unit_file_state);
2721         else if (path)
2722                 printf("   Loaded: %s%s%s (%s)\n",
2723                        on, strna(i->load_state), off, path);
2724         else
2725                 printf("   Loaded: %s%s%s\n",
2726                        on, strna(i->load_state), off);
2727
2728         if (!strv_isempty(i->dropin_paths)) {
2729                 _cleanup_free_ char *dir = NULL;
2730                 bool last = false;
2731                 char ** dropin;
2732
2733                 STRV_FOREACH(dropin, i->dropin_paths) {
2734                         if (! dir || last) {
2735                                 printf(dir ? "        " : "  Drop-In: ");
2736
2737                                 free(dir);
2738                                 dir = NULL;
2739
2740                                 if (path_get_parent(*dropin, &dir) < 0) {
2741                                         log_oom();
2742                                         return;
2743                                 }
2744
2745                                 printf("%s\n           %s", dir,
2746                                        draw_special_char(DRAW_TREE_RIGHT));
2747                         }
2748
2749                         last = ! (*(dropin + 1) && startswith(*(dropin + 1), dir));
2750
2751                         printf("%s%s", basename(*dropin), last ? "\n" : ", ");
2752                 }
2753         }
2754
2755         ss = streq_ptr(i->active_state, i->sub_state) ? NULL : i->sub_state;
2756
2757         if (streq_ptr(i->active_state, "failed")) {
2758                 on = ansi_highlight_red();
2759                 off = ansi_highlight_off();
2760         } else if (streq_ptr(i->active_state, "active") || streq_ptr(i->active_state, "reloading")) {
2761                 on = ansi_highlight_green();
2762                 off = ansi_highlight_off();
2763         } else
2764                 on = off = "";
2765
2766         if (ss)
2767                 printf("   Active: %s%s (%s)%s",
2768                        on, strna(i->active_state), ss, off);
2769         else
2770                 printf("   Active: %s%s%s",
2771                        on, strna(i->active_state), off);
2772
2773         if (!isempty(i->result) && !streq(i->result, "success"))
2774                 printf(" (Result: %s)", i->result);
2775
2776         timestamp = (streq_ptr(i->active_state, "active")      ||
2777                      streq_ptr(i->active_state, "reloading"))   ? i->active_enter_timestamp :
2778                     (streq_ptr(i->active_state, "inactive")    ||
2779                      streq_ptr(i->active_state, "failed"))      ? i->inactive_enter_timestamp :
2780                     streq_ptr(i->active_state, "activating")    ? i->inactive_exit_timestamp :
2781                                                                   i->active_exit_timestamp;
2782
2783         s1 = format_timestamp_relative(since1, sizeof(since1), timestamp);
2784         s2 = format_timestamp(since2, sizeof(since2), timestamp);
2785
2786         if (s1)
2787                 printf(" since %s; %s\n", s2, s1);
2788         else if (s2)
2789                 printf(" since %s\n", s2);
2790         else
2791                 printf("\n");
2792
2793         if (!i->condition_result && i->condition_timestamp > 0) {
2794                 s1 = format_timestamp_relative(since1, sizeof(since1), i->condition_timestamp);
2795                 s2 = format_timestamp(since2, sizeof(since2), i->condition_timestamp);
2796
2797                 printf("           start condition failed at %s%s%s\n",
2798                        s2, s1 ? "; " : "", s1 ? s1 : "");
2799                 if (i->failed_condition_trigger)
2800                         printf("           none of the trigger conditions were met\n");
2801                 else if (i->failed_condition)
2802                         printf("           %s=%s%s was not met\n",
2803                                i->failed_condition,
2804                                i->failed_condition_negate ? "!" : "",
2805                                i->failed_condition_param);
2806         }
2807
2808         if (i->sysfs_path)
2809                 printf("   Device: %s\n", i->sysfs_path);
2810         if (i->where)
2811                 printf("    Where: %s\n", i->where);
2812         if (i->what)
2813                 printf("     What: %s\n", i->what);
2814
2815         STRV_FOREACH(t, i->documentation)
2816                 printf(" %*s %s\n", 9, t == i->documentation ? "Docs:" : "", *t);
2817
2818         STRV_FOREACH_PAIR(t, t2, i->listen)
2819                 printf(" %*s %s (%s)\n", 9, t == i->listen ? "Listen:" : "", *t2, *t);
2820
2821         if (i->accept)
2822                 printf(" Accepted: %u; Connected: %u\n", i->n_accepted, i->n_connections);
2823
2824         LIST_FOREACH(exec, p, i->exec) {
2825                 _cleanup_free_ char *argv = NULL;
2826                 bool good;
2827
2828                 /* Only show exited processes here */
2829                 if (p->code == 0)
2830                         continue;
2831
2832                 argv = strv_join(p->argv, " ");
2833                 printf("  Process: %u %s=%s ", p->pid, p->name, strna(argv));
2834
2835                 good = is_clean_exit_lsb(p->code, p->status, NULL);
2836                 if (!good) {
2837                         on = ansi_highlight_red();
2838                         off = ansi_highlight_off();
2839                 } else
2840                         on = off = "";
2841
2842                 printf("%s(code=%s, ", on, sigchld_code_to_string(p->code));
2843
2844                 if (p->code == CLD_EXITED) {
2845                         const char *c;
2846
2847                         printf("status=%i", p->status);
2848
2849                         c = exit_status_to_string(p->status, EXIT_STATUS_SYSTEMD);
2850                         if (c)
2851                                 printf("/%s", c);
2852
2853                 } else
2854                         printf("signal=%s", signal_to_string(p->status));
2855
2856                 printf(")%s\n", off);
2857
2858                 if (i->main_pid == p->pid &&
2859                     i->start_timestamp == p->start_timestamp &&
2860                     i->exit_timestamp == p->start_timestamp)
2861                         /* Let's not show this twice */
2862                         i->main_pid = 0;
2863
2864                 if (p->pid == i->control_pid)
2865                         i->control_pid = 0;
2866         }
2867
2868         if (i->main_pid > 0 || i->control_pid > 0) {
2869                 if (i->main_pid > 0) {
2870                         printf(" Main PID: %u", (unsigned) i->main_pid);
2871
2872                         if (i->running) {
2873                                 _cleanup_free_ char *comm = NULL;
2874                                 get_process_comm(i->main_pid, &comm);
2875                                 if (comm)
2876                                         printf(" (%s)", comm);
2877                         } else if (i->exit_code > 0) {
2878                                 printf(" (code=%s, ", sigchld_code_to_string(i->exit_code));
2879
2880                                 if (i->exit_code == CLD_EXITED) {
2881                                         const char *c;
2882
2883                                         printf("status=%i", i->exit_status);
2884
2885                                         c = exit_status_to_string(i->exit_status, EXIT_STATUS_SYSTEMD);
2886                                         if (c)
2887                                                 printf("/%s", c);
2888
2889                                 } else
2890                                         printf("signal=%s", signal_to_string(i->exit_status));
2891                                 printf(")");
2892                         }
2893
2894                         if (i->control_pid > 0)
2895                                 printf(";");
2896                 }
2897
2898                 if (i->control_pid > 0) {
2899                         _cleanup_free_ char *c = NULL;
2900
2901                         printf(" %8s: %u", i->main_pid ? "" : " Control", (unsigned) i->control_pid);
2902
2903                         get_process_comm(i->control_pid, &c);
2904                         if (c)
2905                                 printf(" (%s)", c);
2906                 }
2907
2908                 printf("\n");
2909         }
2910
2911         if (i->status_text)
2912                 printf("   Status: \"%s\"\n", i->status_text);
2913
2914         if (i->control_group &&
2915             (i->main_pid > 0 || i->control_pid > 0 || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, i->control_group, false) == 0)) {
2916                 unsigned c;
2917
2918                 printf("   CGroup: %s\n", i->control_group);
2919
2920                 if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_CONTAINER) {
2921                         unsigned k = 0;
2922                         pid_t extra[2];
2923                         char prefix[] = "           ";
2924
2925                         c = columns();
2926                         if (c > sizeof(prefix) - 1)
2927                                 c -= sizeof(prefix) - 1;
2928                         else
2929                                 c = 0;
2930
2931                         if (i->main_pid > 0)
2932                                 extra[k++] = i->main_pid;
2933
2934                         if (i->control_pid > 0)
2935                                 extra[k++] = i->control_pid;
2936
2937                         show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, i->control_group, prefix,
2938                                                       c, false, extra, k, flags);
2939                 }
2940         }
2941
2942         if (i->id && arg_transport == BUS_TRANSPORT_LOCAL) {
2943                 printf("\n");
2944                 show_journal_by_unit(stdout,
2945                                      i->id,
2946                                      arg_output,
2947                                      0,
2948                                      i->inactive_exit_timestamp_monotonic,
2949                                      arg_lines,
2950                                      getuid(),
2951                                      flags,
2952                                      arg_scope == UNIT_FILE_SYSTEM,
2953                                      ellipsized);
2954         }
2955
2956         if (i->need_daemon_reload)
2957                 printf("\n%sWarning:%s Unit file changed on disk, 'systemctl %sdaemon-reload' recommended.\n",
2958                        ansi_highlight_red(),
2959                        ansi_highlight_off(),
2960                        arg_scope == UNIT_FILE_SYSTEM ? "" : "--user ");
2961 }
2962
2963 static void show_unit_help(UnitStatusInfo *i) {
2964         char **p;
2965
2966         assert(i);
2967
2968         if (!i->documentation) {
2969                 log_info("Documentation for %s not known.", i->id);
2970                 return;
2971         }
2972
2973         STRV_FOREACH(p, i->documentation) {
2974
2975                 if (startswith(*p, "man:")) {
2976                         const char *args[4] = { "man", NULL, NULL, NULL };
2977                         _cleanup_free_ char *page = NULL, *section = NULL;
2978                         char *e = NULL;
2979                         pid_t pid;
2980                         size_t k;
2981
2982                         k = strlen(*p);
2983
2984                         if ((*p)[k-1] == ')')
2985                                 e = strrchr(*p, '(');
2986
2987                         if (e) {
2988                                 page = strndup((*p) + 4, e - *p - 4);
2989                                 section = strndup(e + 1, *p + k - e - 2);
2990                                 if (!page || !section) {
2991                                         log_oom();
2992                                         return;
2993                                 }
2994
2995                                 args[1] = section;
2996                                 args[2] = page;
2997                         } else
2998                                 args[1] = *p + 4;
2999
3000                         pid = fork();
3001                         if (pid < 0) {
3002                                 log_error("Failed to fork: %m");
3003                                 continue;
3004                         }
3005
3006                         if (pid == 0) {
3007                                 /* Child */
3008                                 execvp(args[0], (char**) args);
3009                                 log_error("Failed to execute man: %m");
3010                                 _exit(EXIT_FAILURE);
3011                         }
3012
3013                         wait_for_terminate(pid, NULL);
3014                 } else
3015                         log_info("Can't show: %s", *p);
3016         }
3017 }
3018
3019 static int status_property(const char *name, sd_bus_message *m, UnitStatusInfo *i, const char *contents) {
3020         int r;
3021
3022         assert(name);
3023         assert(m);
3024         assert(i);
3025
3026         switch (contents[0]) {
3027
3028         case SD_BUS_TYPE_STRING: {
3029                 const char *s;
3030
3031                 r = sd_bus_message_read(m, "s", &s);
3032                 if (r < 0)
3033                         return bus_log_parse_error(r);
3034
3035                 if (!isempty(s)) {
3036                         if (streq(name, "Id"))
3037                                 i->id = s;
3038                         else if (streq(name, "LoadState"))
3039                                 i->load_state = s;
3040                         else if (streq(name, "ActiveState"))
3041                                 i->active_state = s;
3042                         else if (streq(name, "SubState"))
3043                                 i->sub_state = s;
3044                         else if (streq(name, "Description"))
3045                                 i->description = s;
3046                         else if (streq(name, "FragmentPath"))
3047                                 i->fragment_path = s;
3048                         else if (streq(name, "SourcePath"))
3049                                 i->source_path = s;
3050 #ifndef NOLEGACY
3051                         else if (streq(name, "DefaultControlGroup")) {
3052                                 const char *e;
3053                                 e = startswith(s, SYSTEMD_CGROUP_CONTROLLER ":");
3054                                 if (e)
3055                                         i->control_group = e;
3056                         }
3057 #endif
3058                         else if (streq(name, "ControlGroup"))
3059                                 i->control_group = s;
3060                         else if (streq(name, "StatusText"))
3061                                 i->status_text = s;
3062                         else if (streq(name, "PIDFile"))
3063                                 i->pid_file = s;
3064                         else if (streq(name, "SysFSPath"))
3065                                 i->sysfs_path = s;
3066                         else if (streq(name, "Where"))
3067                                 i->where = s;
3068                         else if (streq(name, "What"))
3069                                 i->what = s;
3070                         else if (streq(name, "Following"))
3071                                 i->following = s;
3072                         else if (streq(name, "UnitFileState"))
3073                                 i->unit_file_state = s;
3074                         else if (streq(name, "Result"))
3075                                 i->result = s;
3076                 }
3077
3078                 break;
3079         }
3080
3081         case SD_BUS_TYPE_BOOLEAN: {
3082                 int b;
3083
3084                 r = sd_bus_message_read(m, "b", &b);
3085                 if (r < 0)
3086                         return bus_log_parse_error(r);
3087
3088                 if (streq(name, "Accept"))
3089                         i->accept = b;
3090                 else if (streq(name, "NeedDaemonReload"))
3091                         i->need_daemon_reload = b;
3092                 else if (streq(name, "ConditionResult"))
3093                         i->condition_result = b;
3094
3095                 break;
3096         }
3097
3098         case SD_BUS_TYPE_UINT32: {
3099                 uint32_t u;
3100
3101                 r = sd_bus_message_read(m, "u", &u);
3102                 if (r < 0)
3103                         return bus_log_parse_error(r);
3104
3105                 if (streq(name, "MainPID")) {
3106                         if (u > 0) {
3107                                 i->main_pid = (pid_t) u;
3108                                 i->running = true;
3109                         }
3110                 } else if (streq(name, "ControlPID"))
3111                         i->control_pid = (pid_t) u;
3112                 else if (streq(name, "ExecMainPID")) {
3113                         if (u > 0)
3114                                 i->main_pid = (pid_t) u;
3115                 } else if (streq(name, "NAccepted"))
3116                         i->n_accepted = u;
3117                 else if (streq(name, "NConnections"))
3118                         i->n_connections = u;
3119
3120                 break;
3121         }
3122
3123         case SD_BUS_TYPE_INT32: {
3124                 int32_t j;
3125
3126                 r = sd_bus_message_read(m, "i", &j);
3127                 if (r < 0)
3128                         return bus_log_parse_error(r);
3129
3130                 if (streq(name, "ExecMainCode"))
3131                         i->exit_code = (int) j;
3132                 else if (streq(name, "ExecMainStatus"))
3133                         i->exit_status = (int) j;
3134
3135                 break;
3136         }
3137
3138         case SD_BUS_TYPE_UINT64: {
3139                 uint64_t u;
3140
3141                 r = sd_bus_message_read(m, "t", &u);
3142                 if (r < 0)
3143                         return bus_log_parse_error(r);
3144
3145                 if (streq(name, "ExecMainStartTimestamp"))
3146                         i->start_timestamp = (usec_t) u;
3147                 else if (streq(name, "ExecMainExitTimestamp"))
3148                         i->exit_timestamp = (usec_t) u;
3149                 else if (streq(name, "ActiveEnterTimestamp"))
3150                         i->active_enter_timestamp = (usec_t) u;
3151                 else if (streq(name, "InactiveEnterTimestamp"))
3152                         i->inactive_enter_timestamp = (usec_t) u;
3153                 else if (streq(name, "InactiveExitTimestamp"))
3154                         i->inactive_exit_timestamp = (usec_t) u;
3155                 else if (streq(name, "InactiveExitTimestampMonotonic"))
3156                         i->inactive_exit_timestamp_monotonic = (usec_t) u;
3157                 else if (streq(name, "ActiveExitTimestamp"))
3158                         i->active_exit_timestamp = (usec_t) u;
3159                 else if (streq(name, "ConditionTimestamp"))
3160                         i->condition_timestamp = (usec_t) u;
3161
3162                 break;
3163         }
3164
3165         case SD_BUS_TYPE_ARRAY:
3166
3167                 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3168                         _cleanup_free_ ExecStatusInfo *info = NULL;
3169
3170                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3171                         if (r < 0)
3172                                 return bus_log_parse_error(r);
3173
3174                         info = new0(ExecStatusInfo, 1);
3175                         if (!info)
3176                                 return log_oom();
3177
3178                         while ((r = exec_status_info_deserialize(m, info)) > 0) {
3179
3180                                 info->name = strdup(name);
3181                                 if (!info->name)
3182                                         log_oom();
3183
3184                                 LIST_PREPEND(exec, i->exec, info);
3185
3186                                 info = new0(ExecStatusInfo, 1);
3187                                 if (!info)
3188                                         log_oom();
3189                         }
3190
3191                         if (r < 0)
3192                                 return bus_log_parse_error(r);
3193
3194                         r = sd_bus_message_exit_container(m);
3195                         if (r < 0)
3196                                 return bus_log_parse_error(r);
3197
3198                         return 0;
3199
3200                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3201                         const char *type, *path;
3202
3203                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3204                         if (r < 0)
3205                                 return bus_log_parse_error(r);
3206
3207                         while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0) {
3208
3209                                 r = strv_extend(&i->listen, type);
3210                                 if (r < 0)
3211                                         return r;
3212
3213                                 r = strv_extend(&i->listen, path);
3214                                 if (r < 0)
3215                                         return r;
3216                         }
3217                         if (r < 0)
3218                                 return bus_log_parse_error(r);
3219
3220                         r = sd_bus_message_exit_container(m);
3221                         if (r < 0)
3222                                 return bus_log_parse_error(r);
3223
3224                         return 0;
3225
3226                 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "DropInPaths")) {
3227
3228                         r = sd_bus_message_read_strv(m, &i->dropin_paths);
3229                         if (r < 0)
3230                                 return bus_log_parse_error(r);
3231
3232                 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Documentation")) {
3233
3234                         r = sd_bus_message_read_strv(m, &i->documentation);
3235                         if (r < 0)
3236                                 return bus_log_parse_error(r);
3237
3238                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Conditions")) {
3239                         const char *cond, *param;
3240                         int trigger, negate;
3241                         int32_t state;
3242
3243                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
3244                         if (r < 0)
3245                                 return bus_log_parse_error(r);
3246
3247                         while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, &param, &state)) > 0) {
3248                                 log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
3249                                 if (state < 0 && (!trigger || !i->failed_condition)) {
3250                                         i->failed_condition = cond;
3251                                         i->failed_condition_trigger = trigger;
3252                                         i->failed_condition_negate = negate;
3253                                         i->failed_condition_param = param;
3254                                 }
3255                         }
3256                         if (r < 0)
3257                                 return bus_log_parse_error(r);
3258
3259                         r = sd_bus_message_exit_container(m);
3260                         if (r < 0)
3261                                 return bus_log_parse_error(r);
3262
3263                 } else
3264                         goto skip;
3265
3266                 break;
3267
3268         case SD_BUS_TYPE_STRUCT_BEGIN:
3269
3270                 if (streq(name, "LoadError")) {
3271                         const char *n, *message;
3272
3273                         r = sd_bus_message_read(m, "(ss)", &n, &message);
3274                         if (r < 0)
3275                                 return bus_log_parse_error(r);
3276
3277                         if (!isempty(message))
3278                                 i->load_error = message;
3279                 } else
3280                         goto skip;
3281
3282                 break;
3283
3284         default:
3285                 goto skip;
3286         }
3287
3288         return 0;
3289
3290 skip:
3291         r = sd_bus_message_skip(m, contents);
3292         if (r < 0)
3293                 return bus_log_parse_error(r);
3294
3295         return 0;
3296 }
3297
3298 static int print_property(const char *name, sd_bus_message *m, const char *contents) {
3299         int r;
3300
3301         assert(name);
3302         assert(m);
3303
3304         /* This is a low-level property printer, see
3305          * print_status_info() for the nicer output */
3306
3307         if (arg_properties && !strv_find(arg_properties, name)) {
3308                 /* skip what we didn't read */
3309                 r = sd_bus_message_skip(m, contents);
3310                 return r;
3311         }
3312
3313         switch (contents[0]) {
3314
3315         case SD_BUS_TYPE_STRUCT_BEGIN:
3316
3317                 if (contents[1] == SD_BUS_TYPE_UINT32 && streq(name, "Job")) {
3318                         uint32_t u;
3319
3320                         r = sd_bus_message_read(m, "(uo)", &u, NULL);
3321                         if (r < 0)
3322                                 return bus_log_parse_error(r);
3323
3324                         if (u > 0)
3325                                 printf("%s=%u\n", name, (unsigned) u);
3326                         else if (arg_all)
3327                                 printf("%s=\n", name);
3328
3329                         return 0;
3330
3331                 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Unit")) {
3332                         const char *s;
3333
3334                         r = sd_bus_message_read(m, "(so)", &s, NULL);
3335                         if (r < 0)
3336                                 return bus_log_parse_error(r);
3337
3338                         if (arg_all || !isempty(s))
3339                                 printf("%s=%s\n", name, s);
3340
3341                         return 0;
3342
3343                 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "LoadError")) {
3344                         const char *a = NULL, *b = NULL;
3345
3346                         r = sd_bus_message_read(m, "(ss)", &a, &b);
3347                         if (r < 0)
3348                                 return bus_log_parse_error(r);
3349
3350                         if (arg_all || !isempty(a) || !isempty(b))
3351                                 printf("%s=%s \"%s\"\n", name, strempty(a), strempty(b));
3352
3353                         return 0;
3354                 }
3355
3356                 break;
3357
3358         case SD_BUS_TYPE_ARRAY:
3359
3360                 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "EnvironmentFiles")) {
3361                         const char *path;
3362                         int ignore;
3363
3364                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sb)");
3365                         if (r < 0)
3366                                 return bus_log_parse_error(r);
3367
3368                         while ((r = sd_bus_message_read(m, "(sb)", &path, &ignore)) > 0)
3369                                 printf("EnvironmentFile=%s (ignore_errors=%s)\n", path, yes_no(ignore));
3370
3371                         if (r < 0)
3372                                 return bus_log_parse_error(r);
3373
3374                         r = sd_bus_message_exit_container(m);
3375                         if (r < 0)
3376                                 return bus_log_parse_error(r);
3377
3378                         return 0;
3379
3380                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Paths")) {
3381                         const char *type, *path;
3382
3383                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3384                         if (r < 0)
3385                                 return bus_log_parse_error(r);
3386
3387                         while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
3388                                 printf("%s=%s\n", type, path);
3389                         if (r < 0)
3390                                 return bus_log_parse_error(r);
3391
3392                         r = sd_bus_message_exit_container(m);
3393                         if (r < 0)
3394                                 return bus_log_parse_error(r);
3395
3396                         return 0;
3397
3398                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3399                         const char *type, *path;
3400
3401                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3402                         if (r < 0)
3403                                 return bus_log_parse_error(r);
3404
3405                         while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
3406                                 printf("Listen%s=%s\n", type, path);
3407                         if (r < 0)
3408                                 return bus_log_parse_error(r);
3409
3410                         r = sd_bus_message_exit_container(m);
3411                         if (r < 0)
3412                                 return bus_log_parse_error(r);
3413
3414                         return 0;
3415
3416                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Timers")) {
3417                         const char *base;
3418                         uint64_t value, next_elapse;
3419
3420                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(stt)");
3421                         if (r < 0)
3422                                 return bus_log_parse_error(r);
3423
3424                         while ((r = sd_bus_message_read(m, "(stt)", &base, &value, &next_elapse)) > 0) {
3425                                 char timespan1[FORMAT_TIMESPAN_MAX], timespan2[FORMAT_TIMESPAN_MAX];
3426
3427                                 printf("%s={ value=%s ; next_elapse=%s }\n",
3428                                        base,
3429                                        format_timespan(timespan1, sizeof(timespan1), value, 0),
3430                                        format_timespan(timespan2, sizeof(timespan2), next_elapse, 0));
3431                         }
3432                         if (r < 0)
3433                                 return bus_log_parse_error(r);
3434
3435                         r = sd_bus_message_exit_container(m);
3436                         if (r < 0)
3437                                 return bus_log_parse_error(r);
3438
3439                         return 0;
3440
3441                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3442                         ExecStatusInfo info = {};
3443
3444                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3445                         if (r < 0)
3446                                 return bus_log_parse_error(r);
3447
3448                         while ((r = exec_status_info_deserialize(m, &info)) > 0) {
3449                                 char timestamp1[FORMAT_TIMESTAMP_MAX], timestamp2[FORMAT_TIMESTAMP_MAX];
3450                                 _cleanup_free_ char *tt;
3451
3452                                 tt = strv_join(info.argv, " ");
3453
3454                                 printf("%s={ path=%s ; argv[]=%s ; ignore_errors=%s ; start_time=[%s] ; stop_time=[%s] ; pid=%u ; code=%s ; status=%i%s%s }\n",
3455                                        name,
3456                                        strna(info.path),
3457                                        strna(tt),
3458                                        yes_no(info.ignore),
3459                                        strna(format_timestamp(timestamp1, sizeof(timestamp1), info.start_timestamp)),
3460                                        strna(format_timestamp(timestamp2, sizeof(timestamp2), info.exit_timestamp)),
3461                                        (unsigned) info. pid,
3462                                        sigchld_code_to_string(info.code),
3463                                        info.status,
3464                                        info.code == CLD_EXITED ? "" : "/",
3465                                        strempty(info.code == CLD_EXITED ? NULL : signal_to_string(info.status)));
3466
3467                                 free(info.path);
3468                                 strv_free(info.argv);
3469                                 zero(info);
3470                         }
3471
3472                         r = sd_bus_message_exit_container(m);
3473                         if (r < 0)
3474                                 return bus_log_parse_error(r);
3475
3476                         return 0;
3477
3478                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "DeviceAllow")) {
3479                         const char *path, *rwm;
3480
3481                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3482                         if (r < 0)
3483                                 return bus_log_parse_error(r);
3484
3485                         while ((r = sd_bus_message_read(m, "(ss)", &path, &rwm)) > 0)
3486                                 printf("%s=%s %s\n", name, strna(path), strna(rwm));
3487                         if (r < 0)
3488                                 return bus_log_parse_error(r);
3489
3490                         r = sd_bus_message_exit_container(m);
3491                         if (r < 0)
3492                                 return bus_log_parse_error(r);
3493
3494                         return 0;
3495
3496                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "BlockIODeviceWeight")) {
3497                         const char *path;
3498                         uint64_t weight;
3499
3500                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
3501                         if (r < 0)
3502                                 return bus_log_parse_error(r);
3503
3504                         while ((r = sd_bus_message_read(m, "(st)", &path, &weight)) > 0)
3505                                 printf("%s=%s %" PRIu64 "\n", name, strna(path), weight);
3506                         if (r < 0)
3507                                 return bus_log_parse_error(r);
3508
3509                         r = sd_bus_message_exit_container(m);
3510                         if (r < 0)
3511                                 return bus_log_parse_error(r);
3512
3513                         return 0;
3514
3515                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && (streq(name, "BlockIOReadBandwidth") || streq(name, "BlockIOWriteBandwidth"))) {
3516                         const char *path;
3517                         uint64_t bandwidth;
3518
3519                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
3520                         if (r < 0)
3521                                 return bus_log_parse_error(r);
3522
3523                         while ((r = sd_bus_message_read(m, "(st)", &path, &bandwidth)) > 0)
3524                                 printf("%s=%s %" PRIu64 "\n", name, strna(path), bandwidth);
3525                         if (r < 0)
3526                                 return bus_log_parse_error(r);
3527
3528                         r = sd_bus_message_exit_container(m);
3529                         if (r < 0)
3530                                 return bus_log_parse_error(r);
3531
3532                         return 0;
3533                 }
3534
3535                 break;
3536         }
3537
3538         r = bus_print_property(name, m, arg_all);
3539         if (r < 0)
3540                 return bus_log_parse_error(r);
3541
3542         if (r == 0) {
3543                 r = sd_bus_message_skip(m, contents);
3544                 if (r < 0)
3545                         return bus_log_parse_error(r);
3546
3547                 if (arg_all)
3548                         printf("%s=[unprintable]\n", name);
3549         }
3550
3551         return 0;
3552 }
3553
3554 static int show_one(
3555                 const char *verb,
3556                 sd_bus *bus,
3557                 const char *path,
3558                 bool show_properties,
3559                 bool *new_line,
3560                 bool *ellipsized) {
3561
3562         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3563         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3564         UnitStatusInfo info = {};
3565         ExecStatusInfo *p;
3566         int r;
3567
3568         assert(path);
3569         assert(new_line);
3570
3571         r = sd_bus_call_method(
3572                         bus,
3573                         "org.freedesktop.systemd1",
3574                         path,
3575                         "org.freedesktop.DBus.Properties",
3576                         "GetAll",
3577                         &error,
3578                         &reply,
3579                         "s", "");
3580         if (r < 0) {
3581                 log_error("Failed to get properties: %s", bus_error_message(&error, r));
3582                 return r;
3583         }
3584
3585         r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
3586         if (r < 0)
3587                 return bus_log_parse_error(r);
3588
3589         if (*new_line)
3590                 printf("\n");
3591
3592         *new_line = true;
3593
3594         while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
3595                 const char *name, *contents;
3596
3597                 r = sd_bus_message_read(reply, "s", &name);
3598                 if (r < 0)
3599                         return bus_log_parse_error(r);
3600
3601                 r = sd_bus_message_peek_type(reply, NULL, &contents);
3602                 if (r < 0)
3603                         return bus_log_parse_error(r);
3604
3605                 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, contents);
3606                 if (r < 0)
3607                         return bus_log_parse_error(r);
3608
3609                 if (show_properties)
3610                         r = print_property(name, reply, contents);
3611                 else
3612                         r = status_property(name, reply, &info, contents);
3613                 if (r < 0)
3614                         return r;
3615
3616                 r = sd_bus_message_exit_container(reply);
3617                 if (r < 0)
3618                         return bus_log_parse_error(r);
3619
3620                 r = sd_bus_message_exit_container(reply);
3621                 if (r < 0)
3622                         return bus_log_parse_error(r);
3623         }
3624         if (r < 0)
3625                 return bus_log_parse_error(r);
3626
3627         r = sd_bus_message_exit_container(reply);
3628         if (r < 0)
3629                 return bus_log_parse_error(r);
3630
3631         r = 0;
3632
3633         if (!show_properties) {
3634                 if (streq(verb, "help"))
3635                         show_unit_help(&info);
3636                 else
3637                         print_status_info(&info, ellipsized);
3638         }
3639
3640         strv_free(info.documentation);
3641         strv_free(info.dropin_paths);
3642         strv_free(info.listen);
3643
3644         if (!streq_ptr(info.active_state, "active") &&
3645             !streq_ptr(info.active_state, "reloading") &&
3646             streq(verb, "status")) {
3647                 /* According to LSB: "program not running" */
3648                 /* 0: program is running or service is OK
3649                  * 1: program is dead and /var/run pid file exists
3650                  * 2: program is dead and /var/lock lock file exists
3651                  * 3: program is not running
3652                  * 4: program or service status is unknown
3653                  */
3654                 if (info.pid_file && access(info.pid_file, F_OK) == 0)
3655                         r = 1;
3656                 else
3657                         r = 3;
3658         }
3659
3660         while ((p = info.exec)) {
3661                 LIST_REMOVE(exec, info.exec, p);
3662                 exec_status_info_free(p);
3663         }
3664
3665         return r;
3666 }
3667
3668 static int get_unit_dbus_path_by_pid(
3669                 sd_bus *bus,
3670                 uint32_t pid,
3671                 char **unit) {
3672
3673         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3674         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3675         char *u;
3676         int r;
3677
3678         r = sd_bus_call_method(
3679                         bus,
3680                         "org.freedesktop.systemd1",
3681                         "/org/freedesktop/systemd1",
3682                         "org.freedesktop.systemd1.Manager",
3683                         "GetUnitByPID",
3684                         &error,
3685                         &reply,
3686                         "u", pid);
3687         if (r < 0) {
3688                 log_error("Failed to get unit for PID %lu: %s", (unsigned long) pid, bus_error_message(&error, r));
3689                 return r;
3690         }
3691
3692         r = sd_bus_message_read(reply, "o", &u);
3693         if (r < 0)
3694                 return bus_log_parse_error(r);
3695
3696         u = strdup(u);
3697         if (!u)
3698                 return log_oom();
3699
3700         *unit = u;
3701         return 0;
3702 }
3703
3704 static int show_all(
3705                 const char* verb,
3706                 sd_bus *bus,
3707                 bool show_properties,
3708                 bool *new_line,
3709                 bool *ellipsized) {
3710
3711         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3712         _cleanup_free_ UnitInfo *unit_infos = NULL;
3713         const UnitInfo *u;
3714         unsigned c;
3715         int r;
3716
3717         r = get_unit_list(bus, &reply, &unit_infos);
3718         if (r < 0)
3719                 return r;
3720
3721         pager_open_if_enabled();
3722
3723         c = (unsigned) r;
3724
3725         qsort_safe(unit_infos, c, sizeof(UnitInfo), compare_unit_info);
3726
3727         for (u = unit_infos; u < unit_infos + c; u++) {
3728                 _cleanup_free_ char *p = NULL;
3729
3730                 if (!output_show_unit(u, NULL))
3731                         continue;
3732
3733                 p = unit_dbus_path_from_name(u->id);
3734                 if (!p)
3735                         return log_oom();
3736
3737                 r = show_one(verb, bus, p, show_properties, new_line, ellipsized);
3738                 if (r != 0)
3739                         return r;
3740         }
3741
3742         return 0;
3743 }
3744
3745 static int cat(sd_bus *bus, char **args) {
3746         _cleanup_free_ char *unit = NULL, *n = NULL;
3747         int r = 0;
3748         char **name;
3749         bool first = true;
3750
3751         assert(bus);
3752         assert(args);
3753
3754         pager_open_if_enabled();
3755
3756         STRV_FOREACH(name, args+1) {
3757                 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3758                 _cleanup_strv_free_ char **dropin_paths = NULL;
3759                 _cleanup_free_ char *fragment_path = NULL;
3760                 char **path;
3761
3762                 n = unit_name_mangle(*name);
3763                 if (!n)
3764                         return log_oom();
3765
3766                 unit = unit_dbus_path_from_name(n);
3767                 if (!unit)
3768                         return log_oom();
3769
3770                 if (need_daemon_reload(bus, n) > 0)
3771                         log_warning("Unit file of %s changed on disk. Run 'systemctl%s daemon-reload'.",
3772                                     n, arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
3773
3774                 r = sd_bus_get_property_string(
3775                                 bus,
3776                                 "org.freedesktop.systemd1",
3777                                 unit,
3778                                 "org.freedesktop.systemd1.Unit",
3779                                 "FragmentPath",
3780                                 &error,
3781                                 &fragment_path);
3782                 if (r < 0) {
3783                         log_warning("Failed to get FragmentPath: %s", bus_error_message(&error, r));
3784                         continue;
3785                 }
3786
3787                 r = sd_bus_get_property_strv(
3788                                 bus,
3789                                 "org.freedesktop.systemd1",
3790                                 unit,
3791                                 "org.freedesktop.systemd1.Unit",
3792                                 "DropInPaths",
3793                                 &error,
3794                                 &dropin_paths);
3795                 if (r < 0) {
3796                         log_warning("Failed to get DropInPaths: %s", bus_error_message(&error, r));
3797                         continue;
3798                 }
3799
3800                 if (first)
3801                         first = false;
3802                 else
3803                         puts("");
3804
3805                 if (!isempty(fragment_path)) {
3806                         printf("%s# %s%s\n",
3807                                ansi_highlight_blue(),
3808                                fragment_path,
3809                                ansi_highlight_off());
3810                         fflush(stdout);
3811
3812                         r = sendfile_full(STDOUT_FILENO, fragment_path);
3813                         if (r < 0) {
3814                                 log_warning("Failed to cat %s: %s", fragment_path, strerror(-r));
3815                                 continue;
3816                         }
3817                 }
3818
3819                 STRV_FOREACH(path, dropin_paths) {
3820                         printf("%s%s# %s%s\n",
3821                                isempty(fragment_path) && path == dropin_paths ? "" : "\n",
3822                                ansi_highlight_blue(),
3823                                *path,
3824                                ansi_highlight_off());
3825                         fflush(stdout);
3826
3827                         r = sendfile_full(STDOUT_FILENO, *path);
3828                         if (r < 0) {
3829                                 log_warning("Failed to cat %s: %s", *path, strerror(-r));
3830                                 continue;
3831                         }
3832                 }
3833         }
3834
3835         return r < 0 ? r : 0;
3836 }
3837
3838 static int show(sd_bus *bus, char **args) {
3839         int r, ret = 0;
3840         bool show_properties, show_status, new_line = false;
3841         char **name;
3842         bool ellipsized = false;
3843
3844         assert(bus);
3845         assert(args);
3846
3847         show_properties = streq(args[0], "show");
3848         show_status = streq(args[0], "status");
3849
3850         if (show_properties)
3851                 pager_open_if_enabled();
3852
3853         /* If no argument is specified inspect the manager itself */
3854
3855         if (show_properties && strv_length(args) <= 1)
3856                 return show_one(args[0], bus, "/org/freedesktop/systemd1", show_properties, &new_line, &ellipsized);
3857
3858         if (show_status && strv_length(args) <= 1)
3859                 ret = show_all(args[0], bus, false, &new_line, &ellipsized);
3860         else
3861                 STRV_FOREACH(name, args+1) {
3862                         _cleanup_free_ char *unit = NULL;
3863                         uint32_t id;
3864
3865                         if (safe_atou32(*name, &id) < 0) {
3866                                 _cleanup_free_ char *n = NULL;
3867                                 /* Interpret as unit name */
3868
3869                                 n = unit_name_mangle(*name);
3870                                 if (!n)
3871                                         return log_oom();
3872
3873                                 unit = unit_dbus_path_from_name(n);
3874                                 if (!unit)
3875                                         return log_oom();
3876
3877                         } else if (show_properties) {
3878                                 /* Interpret as job id */
3879                                 if (asprintf(&unit, "/org/freedesktop/systemd1/job/%u", id) < 0)
3880                                         return log_oom();
3881
3882                         } else {
3883                                 /* Interpret as PID */
3884                                 r = get_unit_dbus_path_by_pid(bus, id, &unit);
3885                                 if (r < 0) {
3886                                         ret = r;
3887                                         continue;
3888                                 }
3889                         }
3890
3891                         show_one(args[0], bus, unit, show_properties, &new_line, &ellipsized);
3892                 }
3893
3894         if (ellipsized && !arg_quiet)
3895                 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
3896
3897         return ret;
3898 }
3899
3900 static int append_assignment(sd_bus_message *m, const char *assignment) {
3901         const char *eq;
3902         char *field;
3903         int r;
3904
3905         assert(m);
3906         assert(assignment);
3907
3908         eq = strchr(assignment, '=');
3909         if (!eq) {
3910                 log_error("Not an assignment: %s", assignment);
3911                 return -EINVAL;
3912         }
3913
3914         field = strndupa(assignment, eq - assignment);
3915         eq ++;
3916
3917         r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, field);
3918         if (r < 0)
3919                 return bus_log_create_error(r);
3920
3921         if (streq(field, "CPUAccounting") ||
3922             streq(field, "MemoryAccounting") ||
3923             streq(field, "BlockIOAccounting")) {
3924
3925                 r = parse_boolean(eq);
3926                 if (r < 0) {
3927                         log_error("Failed to parse boolean assignment %s.", assignment);
3928                         return -EINVAL;
3929                 }
3930
3931                 r = sd_bus_message_append(m, "v", "b", r);
3932
3933         } else if (streq(field, "MemoryLimit")) {
3934                 off_t bytes;
3935
3936                 r = parse_bytes(eq, &bytes);
3937                 if (r < 0) {
3938                         log_error("Failed to parse bytes specification %s", assignment);
3939                         return -EINVAL;
3940                 }
3941
3942                 r = sd_bus_message_append(m, "v", "t", (uint64_t) bytes);
3943
3944         } else if (streq(field, "CPUShares") || streq(field, "BlockIOWeight")) {
3945                 uint64_t u;
3946
3947                 r = safe_atou64(eq, &u);
3948                 if (r < 0) {
3949                         log_error("Failed to parse %s value %s.", field, eq);
3950                         return -EINVAL;
3951                 }
3952
3953                 r = sd_bus_message_append(m, "v", "t", u);
3954
3955         } else if (streq(field, "DevicePolicy"))
3956                 r = sd_bus_message_append(m, "v", "s", eq);
3957
3958         else if (streq(field, "DeviceAllow")) {
3959
3960                 if (isempty(eq))
3961                         r = sd_bus_message_append(m, "v", "a(ss)", 0);
3962                 else {
3963                         const char *path, *rwm;
3964                         char *e;
3965
3966                         e = strchr(eq, ' ');
3967                         if (e) {
3968                                 path = strndupa(eq, e - eq);
3969                                 rwm = e+1;
3970                         } else {
3971                                 path = eq;
3972                                 rwm = "";
3973                         }
3974
3975                         if (!path_startswith(path, "/dev")) {
3976                                 log_error("%s is not a device file in /dev.", path);
3977                                 return -EINVAL;
3978                         }
3979
3980                         r = sd_bus_message_append(m, "v", "a(ss)", 1, path, rwm);
3981                 }
3982
3983         } else if (streq(field, "BlockIOReadBandwidth") || streq(field, "BlockIOWriteBandwidth")) {
3984
3985                 if (isempty(eq))
3986                         r = sd_bus_message_append(m, "v", "a(st)", 0);
3987                 else {
3988                         const char *path, *bandwidth;
3989                         off_t bytes;
3990                         char *e;
3991
3992                         e = strchr(eq, ' ');
3993                         if (e) {
3994                                 path = strndupa(eq, e - eq);
3995                                 bandwidth = e+1;
3996                         } else {
3997                                 log_error("Failed to parse %s value %s.", field, eq);
3998                                 return -EINVAL;
3999                         }
4000
4001                         if (!path_startswith(path, "/dev")) {
4002                                 log_error("%s is not a device file in /dev.", path);
4003                                 return -EINVAL;
4004                         }
4005
4006                         r = parse_bytes(bandwidth, &bytes);
4007                         if (r < 0) {
4008                                 log_error("Failed to parse byte value %s.", bandwidth);
4009                                 return -EINVAL;
4010                         }
4011
4012                         r = sd_bus_message_append(m, "v", "a(st)", 1, path, (uint64_t) bytes);
4013                 }
4014
4015         } else if (streq(field, "BlockIODeviceWeight")) {
4016
4017                 if (isempty(eq))
4018                         r = sd_bus_message_append(m, "v", "a(st)", 0);
4019                 else {
4020                         const char *path, *weight;
4021                         uint64_t u;
4022                         char *e;
4023
4024                         e = strchr(eq, ' ');
4025                         if (e) {
4026                                 path = strndupa(eq, e - eq);
4027                                 weight = e+1;
4028                         } else {
4029                                 log_error("Failed to parse %s value %s.", field, eq);
4030                                 return -EINVAL;
4031                         }
4032
4033                         if (!path_startswith(path, "/dev")) {
4034                                 log_error("%s is not a device file in /dev.", path);
4035                                 return -EINVAL;
4036                         }
4037
4038                         r = safe_atou64(weight, &u);
4039                         if (r < 0) {
4040                                 log_error("Failed to parse %s value %s.", field, weight);
4041                                 return -EINVAL;
4042                         }
4043                         r = sd_bus_message_append(m, "v", "a(st)", path, u);
4044                 }
4045
4046         } else {
4047                 log_error("Unknown assignment %s.", assignment);
4048                 return -EINVAL;
4049         }
4050
4051         if (r < 0)
4052                 return bus_log_create_error(r);
4053
4054         return 0;
4055 }
4056
4057 static int set_property(sd_bus *bus, char **args) {
4058         _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4059         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4060         _cleanup_free_ char *n = NULL;
4061         char **i;
4062         int r;
4063
4064         r = sd_bus_message_new_method_call(
4065                         bus,
4066                         "org.freedesktop.systemd1",
4067                         "/org/freedesktop/systemd1",
4068                         "org.freedesktop.systemd1.Manager",
4069                         "SetUnitProperties",
4070                         &m);
4071         if (r < 0)
4072                 return bus_log_create_error(r);
4073
4074         n = unit_name_mangle(args[1]);
4075         if (!n)
4076                 return log_oom();
4077
4078         r = sd_bus_message_append(m, "sb", n, arg_runtime);
4079         if (r < 0)
4080                 return bus_log_create_error(r);
4081
4082         r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, "(sv)");
4083         if (r < 0)
4084                 return bus_log_create_error(r);
4085
4086         STRV_FOREACH(i, args + 2) {
4087                 r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv");
4088                 if (r < 0)
4089                         return bus_log_create_error(r);
4090
4091                 r = append_assignment(m, *i);
4092                 if (r < 0)
4093                         return r;
4094
4095                 r = sd_bus_message_close_container(m);
4096                 if (r < 0)
4097                         return bus_log_create_error(r);
4098         }
4099
4100         r = sd_bus_message_close_container(m);
4101         if (r < 0)
4102                 return bus_log_create_error(r);
4103
4104         r = sd_bus_call(bus, m, 0, &error, NULL);
4105         if (r < 0) {
4106                 log_error("Failed to set unit properties on %s: %s", n, bus_error_message(&error, r));
4107                 return r;
4108         }
4109
4110         return 0;
4111 }
4112
4113 static int snapshot(sd_bus *bus, char **args) {
4114         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4115         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4116         _cleanup_free_ char *n = NULL, *id = NULL;
4117         const char *path;
4118         int r;
4119
4120         if (strv_length(args) > 1)
4121                 n = unit_name_mangle_with_suffix(args[1], ".snapshot");
4122         else
4123                 n = strdup("");
4124         if (!n)
4125                 return log_oom();
4126
4127         r = sd_bus_call_method(
4128                         bus,
4129                         "org.freedesktop.systemd1",
4130                         "/org/freedesktop/systemd1",
4131                         "org.freedesktop.systemd1.Manager",
4132                         "CreateSnapshot",
4133                         &error,
4134                         &reply,
4135                         "sb", n, false);
4136         if (r < 0) {
4137                 log_error("Failed to create snapshot: %s", bus_error_message(&error, r));
4138                 return r;
4139         }
4140
4141         r = sd_bus_message_read(reply, "o", &path);
4142         if (r < 0)
4143                 return bus_log_parse_error(r);
4144
4145         r = sd_bus_get_property_string(
4146                         bus,
4147                         "org.freedesktop.systemd1",
4148                         path,
4149                         "org.freedesktop.systemd1.Unit",
4150                         "Id",
4151                         &error,
4152                         &id);
4153         if (r < 0) {
4154                 log_error("Failed to get ID of snapshot: %s", bus_error_message(&error, r));
4155                 return r;
4156         }
4157
4158         if (!arg_quiet)
4159                 puts(id);
4160
4161         return 0;
4162 }
4163
4164 static int delete_snapshot(sd_bus *bus, char **args) {
4165         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4166         char **name;
4167         int r;
4168
4169         assert(args);
4170
4171         STRV_FOREACH(name, args+1) {
4172                 _cleanup_free_ char *n = NULL;
4173
4174                 n = unit_name_mangle_with_suffix(*name, ".snapshot");
4175                 if (!n)
4176                         return log_oom();
4177
4178                 r = sd_bus_call_method(
4179                                 bus,
4180                                 "org.freedesktop.systemd1",
4181                                 "/org/freedesktop/systemd1",
4182                                 "org.freedesktop.systemd1.Manager",
4183                                 "RemoveSnapshot",
4184                                 &error,
4185                                 NULL,
4186                                 "s", n);
4187                 if (r < 0) {
4188                         log_error("Failed to remove snapshot %s: %s", n, bus_error_message(&error, r));
4189                         return r;
4190                 }
4191         }
4192
4193         return 0;
4194 }
4195
4196 static int daemon_reload(sd_bus *bus, char **args) {
4197         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4198         const char *method;
4199         int r;
4200
4201         if (arg_action == ACTION_RELOAD)
4202                 method = "Reload";
4203         else if (arg_action == ACTION_REEXEC)
4204                 method = "Reexecute";
4205         else {
4206                 assert(arg_action == ACTION_SYSTEMCTL);
4207
4208                 method =
4209                         streq(args[0], "clear-jobs")    ||
4210                         streq(args[0], "cancel")        ? "ClearJobs" :
4211                         streq(args[0], "daemon-reexec") ? "Reexecute" :
4212                         streq(args[0], "reset-failed")  ? "ResetFailed" :
4213                         streq(args[0], "halt")          ? "Halt" :
4214                         streq(args[0], "poweroff")      ? "PowerOff" :
4215                         streq(args[0], "reboot")        ? "Reboot" :
4216                         streq(args[0], "kexec")         ? "KExec" :
4217                         streq(args[0], "exit")          ? "Exit" :
4218                                     /* "daemon-reload" */ "Reload";
4219         }
4220
4221         r = sd_bus_call_method(
4222                         bus,
4223                         "org.freedesktop.systemd1",
4224                         "/org/freedesktop/systemd1",
4225                         "org.freedesktop.systemd1.Manager",
4226                         method,
4227                         &error,
4228                         NULL,
4229                         NULL);
4230
4231         if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
4232                 /* There's always a fallback possible for
4233                  * legacy actions. */
4234                 r = -EADDRNOTAVAIL;
4235         else if ((r == -ETIMEDOUT || r == -ECONNRESET) && streq(method, "Reexecute"))
4236                 /* On reexecution, we expect a disconnect, not a
4237                  * reply */
4238                 r = 0;
4239         else if (r < 0)
4240                 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
4241
4242         return r < 0 ? r : 0;
4243 }
4244
4245 static int reset_failed(sd_bus *bus, char **args) {
4246         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4247         char **name;
4248         int r;
4249
4250         if (strv_length(args) <= 1)
4251                 return daemon_reload(bus, args);
4252
4253         STRV_FOREACH(name, args+1) {
4254                 _cleanup_free_ char *n;
4255
4256                 n = unit_name_mangle(*name);
4257                 if (!n)
4258                         return log_oom();
4259
4260                 r = sd_bus_call_method(
4261                                 bus,
4262                                 "org.freedesktop.systemd1",
4263                                 "/org/freedesktop/systemd1",
4264                                 "org.freedesktop.systemd1.Manager",
4265                                 "ResetFailedUnit",
4266                                 &error,
4267                                 NULL,
4268                                 "s", n);
4269                 if (r < 0) {
4270                         log_error("Failed to reset failed state of unit %s: %s", n, bus_error_message(&error, r));
4271                         return r;
4272                 }
4273         }
4274
4275         return 0;
4276 }
4277
4278 static int show_environment(sd_bus *bus, char **args) {
4279         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4280         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4281         const char *text;
4282         int r;
4283
4284         pager_open_if_enabled();
4285
4286         r = sd_bus_get_property(
4287                         bus,
4288                         "org.freedesktop.systemd1",
4289                         "/org/freedesktop/systemd1",
4290                         "org.freedesktop.systemd1.Manager",
4291                         "Environment",
4292                         &error,
4293                         &reply,
4294                         "as");
4295         if (r < 0) {
4296                 log_error("Failed to get environment: %s", bus_error_message(&error, r));
4297                 return r;
4298         }
4299
4300         r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "s");
4301         if (r < 0)
4302                 return bus_log_parse_error(r);
4303
4304         while ((r = sd_bus_message_read_basic(reply, SD_BUS_TYPE_STRING, &text)) > 0)
4305                 puts(text);
4306         if (r < 0)
4307                 return bus_log_parse_error(r);
4308
4309         r = sd_bus_message_exit_container(reply);
4310         if (r < 0)
4311                 return bus_log_parse_error(r);
4312
4313         return 0;
4314 }
4315
4316 static int switch_root(sd_bus *bus, char **args) {
4317         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4318         _cleanup_free_ char *init = NULL;
4319         const char *root;
4320         unsigned l;
4321         int r;
4322
4323         l = strv_length(args);
4324         if (l < 2 || l > 3) {
4325                 log_error("Wrong number of arguments.");
4326                 return -EINVAL;
4327         }
4328
4329         root = args[1];
4330
4331         if (l >= 3)
4332                 init = strdup(args[2]);
4333         else {
4334                 parse_env_file("/proc/cmdline", WHITESPACE,
4335                                "init", &init,
4336                                NULL);
4337
4338                 if (!init)
4339                         init = strdup("");
4340         }
4341
4342         if (!init)
4343                 return log_oom();
4344
4345         log_debug("switching root - root: %s; init: %s", root, init);
4346
4347         r = sd_bus_call_method(
4348                         bus,
4349                         "org.freedesktop.systemd1",
4350                         "/org/freedesktop/systemd1",
4351                         "org.freedesktop.systemd1.Manager",
4352                         "SwitchRoot",
4353                         &error,
4354                         NULL,
4355                         "ss", root, init);
4356         if (r < 0) {
4357                 log_error("Failed to switch root: %s", bus_error_message(&error, r));
4358                 return r;
4359         }
4360
4361         return 0;
4362 }
4363
4364 static int set_environment(sd_bus *bus, char **args) {
4365         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4366         _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4367         const char *method;
4368         int r;
4369
4370         assert(bus);
4371         assert(args);
4372
4373         method = streq(args[0], "set-environment")
4374                 ? "SetEnvironment"
4375                 : "UnsetEnvironment";
4376
4377         r = sd_bus_message_new_method_call(
4378                         bus,
4379                         "org.freedesktop.systemd1",
4380                         "/org/freedesktop/systemd1",
4381                         "org.freedesktop.systemd1.Manager",
4382                         method,
4383                         &m);
4384         if (r < 0)
4385                 return bus_log_create_error(r);
4386
4387         r = sd_bus_message_append_strv(m, args + 1);
4388         if (r < 0)
4389                 return bus_log_create_error(r);
4390
4391         r = sd_bus_call(bus, m, 0, &error, NULL);
4392         if (r < 0) {
4393                 log_error("Failed to set environment: %s", bus_error_message(&error, r));
4394                 return r;
4395         }
4396
4397         return 0;
4398 }
4399
4400 static int enable_sysv_units(const char *verb, char **args) {
4401         int r = 0;
4402
4403 #if defined(HAVE_SYSV_COMPAT) && defined(HAVE_CHKCONFIG)
4404         unsigned f = 1, t = 1;
4405         _cleanup_lookup_paths_free_ LookupPaths paths = {};
4406
4407         if (arg_scope != UNIT_FILE_SYSTEM)
4408                 return 0;
4409
4410         if (!streq(verb, "enable") &&
4411             !streq(verb, "disable") &&
4412             !streq(verb, "is-enabled"))
4413                 return 0;
4414
4415         /* Processes all SysV units, and reshuffles the array so that
4416          * afterwards only the native units remain */
4417
4418         r = lookup_paths_init(&paths, SYSTEMD_SYSTEM, false, NULL, NULL, NULL);
4419         if (r < 0)
4420                 return r;
4421
4422         r = 0;
4423         for (f = 0; args[f]; f++) {
4424                 const char *name;
4425                 _cleanup_free_ char *p = NULL, *q = NULL;
4426                 bool found_native = false, found_sysv;
4427                 unsigned c = 1;
4428                 const char *argv[6] = { "/sbin/chkconfig", NULL, NULL, NULL, NULL };
4429                 char **k, *l;
4430                 int j;
4431                 pid_t pid;
4432                 siginfo_t status;
4433
4434                 name = args[f];
4435
4436                 if (!endswith(name, ".service"))
4437                         continue;
4438
4439                 if (path_is_absolute(name))
4440                         continue;
4441
4442                 STRV_FOREACH(k, paths.unit_path) {
4443                         if (!isempty(arg_root))
4444                                 asprintf(&p, "%s/%s/%s", arg_root, *k, name);
4445                         else
4446                                 asprintf(&p, "%s/%s", *k, name);
4447
4448                         if (!p) {
4449                                 r = log_oom();
4450                                 goto finish;
4451                         }
4452
4453                         found_native = access(p, F_OK) >= 0;
4454                         free(p);
4455                         p = NULL;
4456
4457                         if (found_native)
4458                                 break;
4459                 }
4460
4461                 if (found_native)
4462                         continue;
4463
4464                 if (!isempty(arg_root))
4465                         asprintf(&p, "%s/" SYSTEM_SYSVINIT_PATH "/%s", arg_root, name);
4466                 else
4467                         asprintf(&p, SYSTEM_SYSVINIT_PATH "/%s", name);
4468                 if (!p) {
4469                         r = log_oom();
4470                         goto finish;
4471                 }
4472
4473                 p[strlen(p) - sizeof(".service") + 1] = 0;
4474                 found_sysv = access(p, F_OK) >= 0;
4475
4476                 if (!found_sysv)
4477                         continue;
4478
4479                 /* Mark this entry, so that we don't try enabling it as native unit */
4480                 args[f] = (char*) "";
4481
4482                 log_info("%s is not a native service, redirecting to /sbin/chkconfig.", name);
4483
4484                 if (!isempty(arg_root))
4485                         argv[c++] = q = strappend("--root=", arg_root);
4486
4487                 argv[c++] = basename(p);
4488                 argv[c++] =
4489                         streq(verb, "enable") ? "on" :
4490                         streq(verb, "disable") ? "off" : "--level=5";
4491                 argv[c] = NULL;
4492
4493                 l = strv_join((char**)argv, " ");
4494                 if (!l) {
4495                         r = log_oom();
4496                         goto finish;
4497                 }
4498
4499                 log_info("Executing %s", l);
4500                 free(l);
4501
4502                 pid = fork();
4503                 if (pid < 0) {
4504                         log_error("Failed to fork: %m");
4505                         r = -errno;
4506                         goto finish;
4507                 } else if (pid == 0) {
4508                         /* Child */
4509
4510                         execv(argv[0], (char**) argv);
4511                         _exit(EXIT_FAILURE);
4512                 }
4513
4514                 j = wait_for_terminate(pid, &status);
4515                 if (j < 0) {
4516                         log_error("Failed to wait for child: %s", strerror(-r));
4517                         r = j;
4518                         goto finish;
4519                 }
4520
4521                 if (status.si_code == CLD_EXITED) {
4522                         if (streq(verb, "is-enabled")) {
4523                                 if (status.si_status == 0) {
4524                                         if (!arg_quiet)
4525                                                 puts("enabled");
4526                                         r = 1;
4527                                 } else {
4528                                         if (!arg_quiet)
4529                                                 puts("disabled");
4530                                 }
4531
4532                         } else if (status.si_status != 0) {
4533                                 r = -EINVAL;
4534                                 goto finish;
4535                         }
4536                 } else {
4537                         r = -EPROTO;
4538                         goto finish;
4539                 }
4540         }
4541
4542 finish:
4543         /* Drop all SysV units */
4544         for (f = 0, t = 0; args[f]; f++) {
4545
4546                 if (isempty(args[f]))
4547                         continue;
4548
4549                 args[t++] = args[f];
4550         }
4551
4552         args[t] = NULL;
4553
4554 #endif
4555         return r;
4556 }
4557
4558 static int mangle_names(char **original_names, char ***mangled_names) {
4559         char **i, **l, **name;
4560
4561         l = new(char*, strv_length(original_names) + 1);
4562         if (!l)
4563                 return log_oom();
4564
4565         i = l;
4566         STRV_FOREACH(name, original_names) {
4567
4568                 /* When enabling units qualified path names are OK,
4569                  * too, hence allow them explicitly. */
4570
4571                 if (is_path(*name))
4572                         *i = strdup(*name);
4573                 else
4574                         *i = unit_name_mangle(*name);
4575
4576                 if (!*i) {
4577                         strv_free(l);
4578                         return log_oom();
4579                 }
4580
4581                 i++;
4582         }
4583
4584         *i = NULL;
4585         *mangled_names = l;
4586
4587         return 0;
4588 }
4589
4590 static int enable_unit(sd_bus *bus, char **args) {
4591         _cleanup_strv_free_ char **mangled_names = NULL;
4592         const char *verb = args[0];
4593         UnitFileChange *changes = NULL;
4594         unsigned n_changes = 0;
4595         int carries_install_info = -1;
4596         int r;
4597
4598         if (!args[1])
4599                 return 0;
4600
4601         r = mangle_names(args+1, &mangled_names);
4602         if (r < 0)
4603                 return r;
4604
4605         r = enable_sysv_units(verb, mangled_names);
4606         if (r < 0)
4607                 return r;
4608
4609         if (!bus || avoid_bus()) {
4610                 if (streq(verb, "enable")) {
4611                         r = unit_file_enable(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes);
4612                         carries_install_info = r;
4613                 } else if (streq(verb, "disable"))
4614                         r = unit_file_disable(arg_scope, arg_runtime, arg_root, mangled_names, &changes, &n_changes);
4615                 else if (streq(verb, "reenable")) {
4616                         r = unit_file_reenable(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes);
4617                         carries_install_info = r;
4618                 } else if (streq(verb, "link"))
4619                         r = unit_file_link(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes);
4620                 else if (streq(verb, "preset")) {
4621                         r = unit_file_preset(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes);
4622                         carries_install_info = r;
4623                 } else if (streq(verb, "mask"))
4624                         r = unit_file_mask(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes);
4625                 else if (streq(verb, "unmask"))
4626                         r = unit_file_unmask(arg_scope, arg_runtime, arg_root, mangled_names, &changes, &n_changes);
4627                 else
4628                         assert_not_reached("Unknown verb");
4629
4630                 if (r < 0) {
4631                         log_error("Operation failed: %s", strerror(-r));
4632                         goto finish;
4633                 }
4634
4635                 if (!arg_quiet)
4636                         dump_unit_file_changes(changes, n_changes);
4637
4638                 r = 0;
4639         } else {
4640                 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
4641                 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4642                 int expect_carries_install_info = false;
4643                 bool send_force = true;
4644                 const char *method;
4645
4646                 if (streq(verb, "enable")) {
4647                         method = "EnableUnitFiles";
4648                         expect_carries_install_info = true;
4649                 } else if (streq(verb, "disable")) {
4650                         method = "DisableUnitFiles";
4651                         send_force = false;
4652                 } else if (streq(verb, "reenable")) {
4653                         method = "ReenableUnitFiles";
4654                         expect_carries_install_info = true;
4655                 } else if (streq(verb, "link"))
4656                         method = "LinkUnitFiles";
4657                 else if (streq(verb, "preset")) {
4658                         method = "PresetUnitFiles";
4659                         expect_carries_install_info = true;
4660                 } else if (streq(verb, "mask"))
4661                         method = "MaskUnitFiles";
4662                 else if (streq(verb, "unmask")) {
4663                         method = "UnmaskUnitFiles";
4664                         send_force = false;
4665                 } else
4666                         assert_not_reached("Unknown verb");
4667
4668                 r = sd_bus_message_new_method_call(
4669                                 bus,
4670                                 "org.freedesktop.systemd1",
4671                                 "/org/freedesktop/systemd1",
4672                                 "org.freedesktop.systemd1.Manager",
4673                                 method,
4674                                 &m);
4675                 if (r < 0)
4676                         return bus_log_create_error(r);
4677
4678                 r = sd_bus_message_append_strv(m, mangled_names);
4679                 if (r < 0)
4680                         return bus_log_create_error(r);
4681
4682                 r = sd_bus_message_append(m, "b", arg_runtime);
4683                 if (r < 0)
4684                         return bus_log_create_error(r);
4685
4686                 if (send_force) {
4687                         r = sd_bus_message_append(m, "b", arg_force);
4688                         if (r < 0)
4689                                 return bus_log_create_error(r);
4690                 }
4691
4692                 r = sd_bus_call(bus, m, 0, &error, &reply);
4693                 if (r < 0) {
4694                         log_error("Failed to execute operation: %s", bus_error_message(&error, r));
4695                         return r;
4696                 }
4697
4698                 if (expect_carries_install_info) {
4699                         r = sd_bus_message_read(reply, "b", &carries_install_info);
4700                         if (r < 0)
4701                                 return bus_log_parse_error(r);
4702                 }
4703
4704                 r = deserialize_and_dump_unit_file_changes(reply);
4705                 if (r < 0)
4706                         return r;
4707
4708                 /* Try to reload if enabeld */
4709                 if (!arg_no_reload)
4710                         r = daemon_reload(bus, args);
4711                 else
4712                         r = 0;
4713         }
4714
4715         if (carries_install_info == 0)
4716                 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
4717                             "using systemctl.\n"
4718                             "Possible reasons for having this kind of units are:\n"
4719                             "1) A unit may be statically enabled by being symlinked from another unit's\n"
4720                             "   .wants/ or .requires/ directory.\n"
4721                             "2) A unit's purpose may be to act as a helper for some other unit which has\n"
4722                             "   a requirement dependency on it.\n"
4723                             "3) A unit may be started when needed via activation (socket, path, timer,\n"
4724                             "   D-Bus, udev, scripted systemctl call, ...).\n");
4725
4726 finish:
4727         unit_file_changes_free(changes, n_changes);
4728
4729         return r;
4730 }
4731
4732 static int unit_is_enabled(sd_bus *bus, char **args) {
4733
4734         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4735         _cleanup_strv_free_ char **mangled_names = NULL;
4736         bool enabled;
4737         char **name;
4738         int r;
4739
4740         r = mangle_names(args+1, &mangled_names);
4741         if (r < 0)
4742                 return r;
4743
4744         r = enable_sysv_units(args[0], mangled_names);
4745         if (r < 0)
4746                 return r;
4747
4748         enabled = r > 0;
4749
4750         if (!bus || avoid_bus()) {
4751
4752                 STRV_FOREACH(name, mangled_names) {
4753                         UnitFileState state;
4754
4755                         state = unit_file_get_state(arg_scope, arg_root, *name);
4756                         if (state < 0) {
4757                                 log_error("Failed to get unit file state for %s: %s", *name, strerror(-state));
4758                                 return state;
4759                         }
4760
4761                         if (state == UNIT_FILE_ENABLED ||
4762                             state == UNIT_FILE_ENABLED_RUNTIME ||
4763                             state == UNIT_FILE_STATIC)
4764                                 enabled = true;
4765
4766                         if (!arg_quiet)
4767                                 puts(unit_file_state_to_string(state));
4768                 }
4769
4770         } else {
4771                 STRV_FOREACH(name, mangled_names) {
4772                         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4773                         const char *s;
4774
4775                         r = sd_bus_call_method(
4776                                         bus,
4777                                         "org.freedesktop.systemd1",
4778                                         "/org/freedesktop/systemd1",
4779                                         "org.freedesktop.systemd1.Manager",
4780                                         "GetUnitFileState",
4781                                         &error,
4782                                         &reply,
4783                                         "s", *name);
4784                         if (r < 0) {
4785                                 log_error("Failed to get unit file state for %s: %s", *name, bus_error_message(&error, r));
4786                                 return r;
4787                         }
4788
4789                         r = sd_bus_message_read(reply, "s", &s);
4790                         if (r < 0)
4791                                 return bus_log_parse_error(r);
4792
4793                         if (streq(s, "enabled") ||
4794                             streq(s, "enabled-runtime") ||
4795                             streq(s, "static"))
4796                                 enabled = true;
4797
4798                         if (!arg_quiet)
4799                                 puts(s);
4800                 }
4801         }
4802
4803         return !enabled;
4804 }
4805
4806 static int systemctl_help(void) {
4807
4808         pager_open_if_enabled();
4809
4810         printf("%s [OPTIONS...] {COMMAND} ...\n\n"
4811                "Query or send control commands to the systemd manager.\n\n"
4812                "  -h --help           Show this help\n"
4813                "     --version        Show package version\n"
4814                "     --system         Connect to system manager\n"
4815                "     --user           Connect to user service manager\n"
4816                "  -H --host=[USER@]HOST\n"
4817                "                      Operate on remote host\n"
4818                "  -M --machine=CONTAINER\n"
4819                "                      Operate on local container\n"
4820                "  -t --type=TYPE      List only units of a particular type\n"
4821                "     --state=STATE    List only units with particular LOAD or SUB or ACTIVE state\n"
4822                "  -p --property=NAME  Show only properties by this name\n"
4823                "  -a --all            Show all loaded units/properties, including dead/empty\n"
4824                "                      ones. To list all units installed on the system, use\n"
4825                "                      the 'list-unit-files' command instead.\n"
4826                "  -l --full           Don't ellipsize unit names on output\n"
4827                "     --reverse        Show reverse dependencies with 'list-dependencies'\n"
4828                "     --job-mode=MODE  Specify how to deal with already queued jobs, when\n"
4829                "                      queueing a new job\n"
4830                "     --show-types     When showing sockets, explicitly show their type\n"
4831                "  -i --ignore-inhibitors\n"
4832                "                      When shutting down or sleeping, ignore inhibitors\n"
4833                "     --kill-who=WHO   Who to send signal to\n"
4834                "  -s --signal=SIGNAL  Which signal to send\n"
4835                "  -q --quiet          Suppress output\n"
4836                "     --no-block       Do not wait until operation finished\n"
4837                "     --no-wall        Don't send wall message before halt/power-off/reboot\n"
4838                "     --no-reload      When enabling/disabling unit files, don't reload daemon\n"
4839                "                      configuration\n"
4840                "     --no-legend      Do not print a legend (column headers and hints)\n"
4841                "     --no-pager       Do not pipe output into a pager\n"
4842                "     --no-ask-password\n"
4843                "                      Do not ask for system passwords\n"
4844                "     --global         Enable/disable unit files globally\n"
4845                "     --runtime        Enable unit files only temporarily until next reboot\n"
4846                "  -f --force          When enabling unit files, override existing symlinks\n"
4847                "                      When shutting down, execute action immediately\n"
4848                "     --root=PATH      Enable unit files in the specified root directory\n"
4849                "  -n --lines=INTEGER  Number of journal entries to show\n"
4850                "  -o --output=STRING  Change journal output mode (short, short-monotonic,\n"
4851                "                      verbose, export, json, json-pretty, json-sse, cat)\n"
4852                "     --plain          Print unit dependencies as a list instead of a tree\n\n"
4853                "Unit Commands:\n"
4854                "  list-units [PATTERN...]         List loaded units\n"
4855                "  list-sockets [PATTERN...]       List loaded sockets ordered by address\n"
4856                "  list-timers [PATTERN...]        List loaded timers ordered by next elapse\n"
4857                "  start NAME...                   Start (activate) one or more units\n"
4858                "  stop NAME...                    Stop (deactivate) one or more units\n"
4859                "  reload NAME...                  Reload one or more units\n"
4860                "  restart NAME...                 Start or restart one or more units\n"
4861                "  try-restart NAME...             Restart one or more units if active\n"
4862                "  reload-or-restart NAME...       Reload one or more units if possible,\n"
4863                "                                  otherwise start or restart\n"
4864                "  reload-or-try-restart NAME...   Reload one or more units if possible,\n"
4865                "                                  otherwise restart if active\n"
4866                "  isolate NAME                    Start one unit and stop all others\n"
4867                "  kill NAME...                    Send signal to processes of a unit\n"
4868                "  is-active NAME...               Check whether units are active\n"
4869                "  is-failed NAME...               Check whether units are failed\n"
4870                "  status [NAME...|PID...]         Show runtime status of one or more units\n"
4871                "  show [NAME...|JOB...]           Show properties of one or more\n"
4872                "                                  units/jobs or the manager\n"
4873                "  cat NAME...                     Show files and drop-ins of one or more units\n"
4874                "  set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
4875                "  help NAME...|PID...             Show manual for one or more units\n"
4876                "  reset-failed [NAME...]          Reset failed state for all, one, or more\n"
4877                "                                  units\n"
4878                "  list-dependencies [NAME]        Recursively show units which are required\n"
4879                "                                  or wanted by this unit or by which this\n"
4880                "                                  unit is required or wanted\n\n"
4881                "Unit File Commands:\n"
4882                "  list-unit-files [PATTERN...]    List installed unit files\n"
4883                "  enable NAME...                  Enable one or more unit files\n"
4884                "  disable NAME...                 Disable one or more unit files\n"
4885                "  reenable NAME...                Reenable one or more unit files\n"
4886                "  preset NAME...                  Enable/disable one or more unit files\n"
4887                "                                  based on preset configuration\n"
4888                "  is-enabled NAME...              Check whether unit files are enabled\n\n"
4889                "  mask NAME...                    Mask one or more units\n"
4890                "  unmask NAME...                  Unmask one or more units\n"
4891                "  link PATH...                    Link one or more units files into\n"
4892                "                                  the search path\n"
4893                "  get-default                     Get the name of the default target\n"
4894                "  set-default NAME                Set the default target\n\n"
4895                "Job Commands:\n"
4896                "  list-jobs [PATTERN...]          List jobs\n"
4897                "  cancel [JOB...]                 Cancel all, one, or more jobs\n\n"
4898                "Snapshot Commands:\n"
4899                "  snapshot [NAME]                 Create a snapshot\n"
4900                "  delete NAME...                  Remove one or more snapshots\n\n"
4901                "Environment Commands:\n"
4902                "  show-environment                Dump environment\n"
4903                "  set-environment NAME=VALUE...   Set one or more environment variables\n"
4904                "  unset-environment NAME...       Unset one or more environment variables\n\n"
4905                "Manager Lifecycle Commands:\n"
4906                "  daemon-reload                   Reload systemd manager configuration\n"
4907                "  daemon-reexec                   Reexecute systemd manager\n\n"
4908                "System Commands:\n"
4909                "  default                         Enter system default mode\n"
4910                "  rescue                          Enter system rescue mode\n"
4911                "  emergency                       Enter system emergency mode\n"
4912                "  halt                            Shut down and halt the system\n"
4913                "  poweroff                        Shut down and power-off the system\n"
4914                "  reboot [ARG]                    Shut down and reboot the system\n"
4915                "  kexec                           Shut down and reboot the system with kexec\n"
4916                "  exit                            Request user instance exit\n"
4917                "  switch-root ROOT [INIT]         Change to a different root file system\n"
4918                "  suspend                         Suspend the system\n"
4919                "  hibernate                       Hibernate the system\n"
4920                "  hybrid-sleep                    Hibernate and suspend the system\n",
4921                program_invocation_short_name);
4922
4923         return 0;
4924 }
4925
4926 static int halt_help(void) {
4927
4928         printf("%s [OPTIONS...]%s\n\n"
4929                "%s the system.\n\n"
4930                "     --help      Show this help\n"
4931                "     --halt      Halt the machine\n"
4932                "  -p --poweroff  Switch off the machine\n"
4933                "     --reboot    Reboot the machine\n"
4934                "  -f --force     Force immediate halt/power-off/reboot\n"
4935                "  -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
4936                "  -d --no-wtmp   Don't write wtmp record\n"
4937                "     --no-wall   Don't send wall message before halt/power-off/reboot\n",
4938                program_invocation_short_name,
4939                arg_action == ACTION_REBOOT   ? " [ARG]" : "",
4940                arg_action == ACTION_REBOOT   ? "Reboot" :
4941                arg_action == ACTION_POWEROFF ? "Power off" :
4942                                                "Halt");
4943
4944         return 0;
4945 }
4946
4947 static int shutdown_help(void) {
4948
4949         printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
4950                "Shut down the system.\n\n"
4951                "     --help      Show this help\n"
4952                "  -H --halt      Halt the machine\n"
4953                "  -P --poweroff  Power-off the machine\n"
4954                "  -r --reboot    Reboot the machine\n"
4955                "  -h             Equivalent to --poweroff, overridden by --halt\n"
4956                "  -k             Don't halt/power-off/reboot, just send warnings\n"
4957                "     --no-wall   Don't send wall message before halt/power-off/reboot\n"
4958                "  -c             Cancel a pending shutdown\n",
4959                program_invocation_short_name);
4960
4961         return 0;
4962 }
4963
4964 static int telinit_help(void) {
4965
4966         printf("%s [OPTIONS...] {COMMAND}\n\n"
4967                "Send control commands to the init daemon.\n\n"
4968                "     --help      Show this help\n"
4969                "     --no-wall   Don't send wall message before halt/power-off/reboot\n\n"
4970                "Commands:\n"
4971                "  0              Power-off the machine\n"
4972                "  6              Reboot the machine\n"
4973                "  2, 3, 4, 5     Start runlevelX.target unit\n"
4974                "  1, s, S        Enter rescue mode\n"
4975                "  q, Q           Reload init daemon configuration\n"
4976                "  u, U           Reexecute init daemon\n",
4977                program_invocation_short_name);
4978
4979         return 0;
4980 }
4981
4982 static int runlevel_help(void) {
4983
4984         printf("%s [OPTIONS...]\n\n"
4985                "Prints the previous and current runlevel of the init system.\n\n"
4986                "     --help      Show this help\n",
4987                program_invocation_short_name);
4988
4989         return 0;
4990 }
4991
4992 static int help_types(void) {
4993         int i;
4994         const char *t;
4995
4996         puts("Available unit types:");
4997         for (i = 0; i < _UNIT_TYPE_MAX; i++) {
4998                 t = unit_type_to_string(i);
4999                 if (t)
5000                         puts(t);
5001         }
5002
5003         return 0;
5004 }
5005
5006 static int systemctl_parse_argv(int argc, char *argv[]) {
5007
5008         enum {
5009                 ARG_FAIL = 0x100,
5010                 ARG_REVERSE,
5011                 ARG_AFTER,
5012                 ARG_BEFORE,
5013                 ARG_SHOW_TYPES,
5014                 ARG_IRREVERSIBLE,
5015                 ARG_IGNORE_DEPENDENCIES,
5016                 ARG_VERSION,
5017                 ARG_USER,
5018                 ARG_SYSTEM,
5019                 ARG_GLOBAL,
5020                 ARG_NO_BLOCK,
5021                 ARG_NO_LEGEND,
5022                 ARG_NO_PAGER,
5023                 ARG_NO_WALL,
5024                 ARG_ROOT,
5025                 ARG_NO_RELOAD,
5026                 ARG_KILL_WHO,
5027                 ARG_NO_ASK_PASSWORD,
5028                 ARG_FAILED,
5029                 ARG_RUNTIME,
5030                 ARG_FORCE,
5031                 ARG_PLAIN,
5032                 ARG_STATE,
5033                 ARG_JOB_MODE
5034         };
5035
5036         static const struct option options[] = {
5037                 { "help",                no_argument,       NULL, 'h'                     },
5038                 { "version",             no_argument,       NULL, ARG_VERSION             },
5039                 { "type",                required_argument, NULL, 't'                     },
5040                 { "property",            required_argument, NULL, 'p'                     },
5041                 { "all",                 no_argument,       NULL, 'a'                     },
5042                 { "reverse",             no_argument,       NULL, ARG_REVERSE             },
5043                 { "after",               no_argument,       NULL, ARG_AFTER               },
5044                 { "before",              no_argument,       NULL, ARG_BEFORE              },
5045                 { "show-types",          no_argument,       NULL, ARG_SHOW_TYPES          },
5046                 { "failed",              no_argument,       NULL, ARG_FAILED              }, /* compatibility only */
5047                 { "full",                no_argument,       NULL, 'l'                     },
5048                 { "job-mode",            required_argument, NULL, ARG_JOB_MODE            },
5049                 { "fail",                no_argument,       NULL, ARG_FAIL                }, /* compatibility only */
5050                 { "irreversible",        no_argument,       NULL, ARG_IRREVERSIBLE        }, /* compatibility only */
5051                 { "ignore-dependencies", no_argument,       NULL, ARG_IGNORE_DEPENDENCIES }, /* compatibility only */
5052                 { "ignore-inhibitors",   no_argument,       NULL, 'i'                     },
5053                 { "user",                no_argument,       NULL, ARG_USER                },
5054                 { "system",              no_argument,       NULL, ARG_SYSTEM              },
5055                 { "global",              no_argument,       NULL, ARG_GLOBAL              },
5056                 { "no-block",            no_argument,       NULL, ARG_NO_BLOCK            },
5057                 { "no-legend",           no_argument,       NULL, ARG_NO_LEGEND           },
5058                 { "no-pager",            no_argument,       NULL, ARG_NO_PAGER            },
5059                 { "no-wall",             no_argument,       NULL, ARG_NO_WALL             },
5060                 { "quiet",               no_argument,       NULL, 'q'                     },
5061                 { "root",                required_argument, NULL, ARG_ROOT                },
5062                 { "force",               no_argument,       NULL, ARG_FORCE               },
5063                 { "no-reload",           no_argument,       NULL, ARG_NO_RELOAD           },
5064                 { "kill-who",            required_argument, NULL, ARG_KILL_WHO            },
5065                 { "signal",              required_argument, NULL, 's'                     },
5066                 { "no-ask-password",     no_argument,       NULL, ARG_NO_ASK_PASSWORD     },
5067                 { "host",                required_argument, NULL, 'H'                     },
5068                 { "machine",             required_argument, NULL, 'M'                     },
5069                 { "runtime",             no_argument,       NULL, ARG_RUNTIME             },
5070                 { "lines",               required_argument, NULL, 'n'                     },
5071                 { "output",              required_argument, NULL, 'o'                     },
5072                 { "plain",               no_argument,       NULL, ARG_PLAIN               },
5073                 { "state",               required_argument, NULL, ARG_STATE               },
5074                 {}
5075         };
5076
5077         int c;
5078
5079         assert(argc >= 0);
5080         assert(argv);
5081
5082         while ((c = getopt_long(argc, argv, "ht:p:alqfs:H:M:n:o:i", options, NULL)) >= 0) {
5083
5084                 switch (c) {
5085
5086                 case 'h':
5087                         return systemctl_help();
5088
5089                 case ARG_VERSION:
5090                         puts(PACKAGE_STRING);
5091                         puts(SYSTEMD_FEATURES);
5092                         return 0;
5093
5094                 case 't': {
5095                         char *word, *state;
5096                         size_t size;
5097
5098                         FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
5099                                 _cleanup_free_ char *type;
5100
5101                                 type = strndup(word, size);
5102                                 if (!type)
5103                                         return -ENOMEM;
5104
5105                                 if (streq(type, "help")) {
5106                                         help_types();
5107                                         return 0;
5108                                 }
5109
5110                                 if (unit_type_from_string(type) >= 0) {
5111                                         if (strv_push(&arg_types, type))
5112                                                 return log_oom();
5113                                         type = NULL;
5114                                         continue;
5115                                 }
5116
5117                                 /* It's much nicer to use --state= for
5118                                  * load states, but let's support this
5119                                  * in --types= too for compatibility
5120                                  * with old versions */
5121                                 if (unit_load_state_from_string(optarg) >= 0) {
5122                                         if (strv_push(&arg_states, type) < 0)
5123                                                 return log_oom();
5124                                         type = NULL;
5125                                         continue;
5126                                 }
5127
5128                                 log_error("Unknown unit type or load state '%s'.", type);
5129                                 log_info("Use -t help to see a list of allowed values.");
5130                                 return -EINVAL;
5131                         }
5132
5133                         break;
5134                 }
5135
5136                 case 'p': {
5137                         /* Make sure that if the empty property list
5138                            was specified, we won't show any properties. */
5139                         if (isempty(optarg) && !arg_properties) {
5140                                 arg_properties = new0(char*, 1);
5141                                 if (!arg_properties)
5142                                         return log_oom();
5143                         } else {
5144                                 char *word, *state;
5145                                 size_t size;
5146
5147                                 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
5148                                         char *prop;
5149
5150                                         prop = strndup(word, size);
5151                                         if (!prop)
5152                                                 return log_oom();
5153
5154                                         if (strv_push(&arg_properties, prop) < 0) {
5155                                                 free(prop);
5156                                                 return log_oom();
5157                                         }
5158                                 }
5159                         }
5160
5161                         /* If the user asked for a particular
5162                          * property, show it to him, even if it is
5163                          * empty. */
5164                         arg_all = true;
5165
5166                         break;
5167                 }
5168
5169                 case 'a':
5170                         arg_all = true;
5171                         break;
5172
5173                 case ARG_REVERSE:
5174                         arg_dependency = DEPENDENCY_REVERSE;
5175                         break;
5176
5177                 case ARG_AFTER:
5178                         arg_dependency = DEPENDENCY_AFTER;
5179                         break;
5180
5181                 case ARG_BEFORE:
5182                         arg_dependency = DEPENDENCY_BEFORE;
5183                         break;
5184
5185                 case ARG_SHOW_TYPES:
5186                         arg_show_types = true;
5187                         break;
5188
5189                 case ARG_JOB_MODE:
5190                         arg_job_mode = optarg;
5191                         break;
5192
5193                 case ARG_FAIL:
5194                         arg_job_mode = "fail";
5195                         break;
5196
5197                 case ARG_IRREVERSIBLE:
5198                         arg_job_mode = "replace-irreversibly";
5199                         break;
5200
5201                 case ARG_IGNORE_DEPENDENCIES:
5202                         arg_job_mode = "ignore-dependencies";
5203                         break;
5204
5205                 case ARG_USER:
5206                         arg_scope = UNIT_FILE_USER;
5207                         break;
5208
5209                 case ARG_SYSTEM:
5210                         arg_scope = UNIT_FILE_SYSTEM;
5211                         break;
5212
5213                 case ARG_GLOBAL:
5214                         arg_scope = UNIT_FILE_GLOBAL;
5215                         break;
5216
5217                 case ARG_NO_BLOCK:
5218                         arg_no_block = true;
5219                         break;
5220
5221                 case ARG_NO_LEGEND:
5222                         arg_no_legend = true;
5223                         break;
5224
5225                 case ARG_NO_PAGER:
5226                         arg_no_pager = true;
5227                         break;
5228
5229                 case ARG_NO_WALL:
5230                         arg_no_wall = true;
5231                         break;
5232
5233                 case ARG_ROOT:
5234                         arg_root = optarg;
5235                         break;
5236
5237                 case 'l':
5238                         arg_full = true;
5239                         break;
5240
5241                 case ARG_FAILED:
5242                         if (strv_extend(&arg_states, "failed") < 0)
5243                                 return log_oom();
5244
5245                         break;
5246
5247                 case 'q':
5248                         arg_quiet = true;
5249                         break;
5250
5251                 case ARG_FORCE:
5252                         arg_force ++;
5253                         break;
5254
5255                 case 'f':
5256                         arg_force ++;
5257                         break;
5258
5259                 case ARG_NO_RELOAD:
5260                         arg_no_reload = true;
5261                         break;
5262
5263                 case ARG_KILL_WHO:
5264                         arg_kill_who = optarg;
5265                         break;
5266
5267                 case 's':
5268                         if ((arg_signal = signal_from_string_try_harder(optarg)) < 0) {
5269                                 log_error("Failed to parse signal string %s.", optarg);
5270                                 return -EINVAL;
5271                         }
5272                         break;
5273
5274                 case ARG_NO_ASK_PASSWORD:
5275                         arg_ask_password = false;
5276                         break;
5277
5278                 case 'H':
5279                         arg_transport = BUS_TRANSPORT_REMOTE;
5280                         arg_host = optarg;
5281                         break;
5282
5283                 case 'M':
5284                         arg_transport = BUS_TRANSPORT_CONTAINER;
5285                         arg_host = optarg;
5286                         break;
5287
5288                 case ARG_RUNTIME:
5289                         arg_runtime = true;
5290                         break;
5291
5292                 case 'n':
5293                         if (safe_atou(optarg, &arg_lines) < 0) {
5294                                 log_error("Failed to parse lines '%s'", optarg);
5295                                 return -EINVAL;
5296                         }
5297                         break;
5298
5299                 case 'o':
5300                         arg_output = output_mode_from_string(optarg);
5301                         if (arg_output < 0) {
5302                                 log_error("Unknown output '%s'.", optarg);
5303                                 return -EINVAL;
5304                         }
5305                         break;
5306
5307                 case 'i':
5308                         arg_ignore_inhibitors = true;
5309                         break;
5310
5311                 case ARG_PLAIN:
5312                         arg_plain = true;
5313                         break;
5314
5315                 case ARG_STATE: {
5316                         char *word, *state;
5317                         size_t size;
5318
5319                         FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
5320                                 char *s;
5321
5322                                 s = strndup(word, size);
5323                                 if (!s)
5324                                         return log_oom();
5325
5326                                 if (strv_push(&arg_states, s) < 0) {
5327                                         free(s);
5328                                         return log_oom();
5329                                 }
5330                         }
5331                         break;
5332                 }
5333
5334                 case '?':
5335                         return -EINVAL;
5336
5337                 default:
5338                         assert_not_reached("Unhandled option");
5339                 }
5340         }
5341
5342         if (arg_transport != BUS_TRANSPORT_LOCAL && arg_scope != UNIT_FILE_SYSTEM) {
5343                 log_error("Cannot access user instance remotely.");
5344                 return -EINVAL;
5345         }
5346
5347         return 1;
5348 }
5349
5350 static int halt_parse_argv(int argc, char *argv[]) {
5351
5352         enum {
5353                 ARG_HELP = 0x100,
5354                 ARG_HALT,
5355                 ARG_REBOOT,
5356                 ARG_NO_WALL
5357         };
5358
5359         static const struct option options[] = {
5360                 { "help",      no_argument,       NULL, ARG_HELP    },
5361                 { "halt",      no_argument,       NULL, ARG_HALT    },
5362                 { "poweroff",  no_argument,       NULL, 'p'         },
5363                 { "reboot",    no_argument,       NULL, ARG_REBOOT  },
5364                 { "force",     no_argument,       NULL, 'f'         },
5365                 { "wtmp-only", no_argument,       NULL, 'w'         },
5366                 { "no-wtmp",   no_argument,       NULL, 'd'         },
5367                 { "no-wall",   no_argument,       NULL, ARG_NO_WALL },
5368                 {}
5369         };
5370
5371         int c, r, runlevel;
5372
5373         assert(argc >= 0);
5374         assert(argv);
5375
5376         if (utmp_get_runlevel(&runlevel, NULL) >= 0)
5377                 if (runlevel == '0' || runlevel == '6')
5378                         arg_force = 2;
5379
5380         while ((c = getopt_long(argc, argv, "pfwdnih", options, NULL)) >= 0) {
5381                 switch (c) {
5382
5383                 case ARG_HELP:
5384                         return halt_help();
5385
5386                 case ARG_HALT:
5387                         arg_action = ACTION_HALT;
5388                         break;
5389
5390                 case 'p':
5391                         if (arg_action != ACTION_REBOOT)
5392                                 arg_action = ACTION_POWEROFF;
5393                         break;
5394
5395                 case ARG_REBOOT:
5396                         arg_action = ACTION_REBOOT;
5397                         break;
5398
5399                 case 'f':
5400                         arg_force = 2;
5401                         break;
5402
5403                 case 'w':
5404                         arg_dry = true;
5405                         break;
5406
5407                 case 'd':
5408                         arg_no_wtmp = true;
5409                         break;
5410
5411                 case ARG_NO_WALL:
5412                         arg_no_wall = true;
5413                         break;
5414
5415                 case 'i':
5416                 case 'h':
5417                 case 'n':
5418                         /* Compatibility nops */
5419                         break;
5420
5421                 case '?':
5422                         return -EINVAL;
5423
5424                 default:
5425                         assert_not_reached("Unhandled option");
5426                 }
5427         }
5428
5429         if (arg_action == ACTION_REBOOT && argc == optind + 1) {
5430                 r = write_string_file(REBOOT_PARAM_FILE, argv[optind]);
5431                 if (r < 0) {
5432                         log_error("Failed to write reboot param to "
5433                                   REBOOT_PARAM_FILE": %s", strerror(-r));
5434                         return r;
5435                 }
5436         } else if (optind < argc) {
5437                 log_error("Too many arguments.");
5438                 return -EINVAL;
5439         }
5440
5441         return 1;
5442 }
5443
5444 static int parse_time_spec(const char *t, usec_t *_u) {
5445         assert(t);
5446         assert(_u);
5447
5448         if (streq(t, "now"))
5449                 *_u = 0;
5450         else if (!strchr(t, ':')) {
5451                 uint64_t u;
5452
5453                 if (safe_atou64(t, &u) < 0)
5454                         return -EINVAL;
5455
5456                 *_u = now(CLOCK_REALTIME) + USEC_PER_MINUTE * u;
5457         } else {
5458                 char *e = NULL;
5459                 long hour, minute;
5460                 struct tm tm = {};
5461                 time_t s;
5462                 usec_t n;
5463
5464                 errno = 0;
5465                 hour = strtol(t, &e, 10);
5466                 if (errno > 0 || *e != ':' || hour < 0 || hour > 23)
5467                         return -EINVAL;
5468
5469                 minute = strtol(e+1, &e, 10);
5470                 if (errno > 0 || *e != 0 || minute < 0 || minute > 59)
5471                         return -EINVAL;
5472
5473                 n = now(CLOCK_REALTIME);
5474                 s = (time_t) (n / USEC_PER_SEC);
5475
5476                 assert_se(localtime_r(&s, &tm));
5477
5478                 tm.tm_hour = (int) hour;
5479                 tm.tm_min = (int) minute;
5480                 tm.tm_sec = 0;
5481
5482                 assert_se(s = mktime(&tm));
5483
5484                 *_u = (usec_t) s * USEC_PER_SEC;
5485
5486                 while (*_u <= n)
5487                         *_u += USEC_PER_DAY;
5488         }
5489
5490         return 0;
5491 }
5492
5493 static int shutdown_parse_argv(int argc, char *argv[]) {
5494
5495         enum {
5496                 ARG_HELP = 0x100,
5497                 ARG_NO_WALL
5498         };
5499
5500         static const struct option options[] = {
5501                 { "help",      no_argument,       NULL, ARG_HELP    },
5502                 { "halt",      no_argument,       NULL, 'H'         },
5503                 { "poweroff",  no_argument,       NULL, 'P'         },
5504                 { "reboot",    no_argument,       NULL, 'r'         },
5505                 { "kexec",     no_argument,       NULL, 'K'         }, /* not documented extension */
5506                 { "no-wall",   no_argument,       NULL, ARG_NO_WALL },
5507                 {}
5508         };
5509
5510         int c, r;
5511
5512         assert(argc >= 0);
5513         assert(argv);
5514
5515         while ((c = getopt_long(argc, argv, "HPrhkt:afFc", options, NULL)) >= 0) {
5516                 switch (c) {
5517
5518                 case ARG_HELP:
5519                         return shutdown_help();
5520
5521                 case 'H':
5522                         arg_action = ACTION_HALT;
5523                         break;
5524
5525                 case 'P':
5526                         arg_action = ACTION_POWEROFF;
5527                         break;
5528
5529                 case 'r':
5530                         if (kexec_loaded())
5531                                 arg_action = ACTION_KEXEC;
5532                         else
5533                                 arg_action = ACTION_REBOOT;
5534                         break;
5535
5536                 case 'K':
5537                         arg_action = ACTION_KEXEC;
5538                         break;
5539
5540                 case 'h':
5541                         if (arg_action != ACTION_HALT)
5542                                 arg_action = ACTION_POWEROFF;
5543                         break;
5544
5545                 case 'k':
5546                         arg_dry = true;
5547                         break;
5548
5549                 case ARG_NO_WALL:
5550                         arg_no_wall = true;
5551                         break;
5552
5553                 case 't':
5554                 case 'a':
5555                         /* Compatibility nops */
5556                         break;
5557
5558                 case 'c':
5559                         arg_action = ACTION_CANCEL_SHUTDOWN;
5560                         break;
5561
5562                 case '?':
5563                         return -EINVAL;
5564
5565                 default:
5566                         assert_not_reached("Unhandled option");
5567                 }
5568         }
5569
5570         if (argc > optind && arg_action != ACTION_CANCEL_SHUTDOWN) {
5571                 r = parse_time_spec(argv[optind], &arg_when);
5572                 if (r < 0) {
5573                         log_error("Failed to parse time specification: %s", argv[optind]);
5574                         return r;
5575                 }
5576         } else
5577                 arg_when = now(CLOCK_REALTIME) + USEC_PER_MINUTE;
5578
5579         if (argc > optind && arg_action == ACTION_CANCEL_SHUTDOWN)
5580                 /* No time argument for shutdown cancel */
5581                 arg_wall = argv + optind;
5582         else if (argc > optind + 1)
5583                 /* We skip the time argument */
5584                 arg_wall = argv + optind + 1;
5585
5586         optind = argc;
5587
5588         return 1;
5589 }
5590
5591 static int telinit_parse_argv(int argc, char *argv[]) {
5592
5593         enum {
5594                 ARG_HELP = 0x100,
5595                 ARG_NO_WALL
5596         };
5597
5598         static const struct option options[] = {
5599                 { "help",      no_argument,       NULL, ARG_HELP    },
5600                 { "no-wall",   no_argument,       NULL, ARG_NO_WALL },
5601                 {}
5602         };
5603
5604         static const struct {
5605                 char from;
5606                 enum action to;
5607         } table[] = {
5608                 { '0', ACTION_POWEROFF },
5609                 { '6', ACTION_REBOOT },
5610                 { '1', ACTION_RESCUE },
5611                 { '2', ACTION_RUNLEVEL2 },
5612                 { '3', ACTION_RUNLEVEL3 },
5613                 { '4', ACTION_RUNLEVEL4 },
5614                 { '5', ACTION_RUNLEVEL5 },
5615                 { 's', ACTION_RESCUE },
5616                 { 'S', ACTION_RESCUE },
5617                 { 'q', ACTION_RELOAD },
5618                 { 'Q', ACTION_RELOAD },
5619                 { 'u', ACTION_REEXEC },
5620                 { 'U', ACTION_REEXEC }
5621         };
5622
5623         unsigned i;
5624         int c;
5625
5626         assert(argc >= 0);
5627         assert(argv);
5628
5629         while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0) {
5630                 switch (c) {
5631
5632                 case ARG_HELP:
5633                         return telinit_help();
5634
5635                 case ARG_NO_WALL:
5636                         arg_no_wall = true;
5637                         break;
5638
5639                 case '?':
5640                         return -EINVAL;
5641
5642                 default:
5643                         assert_not_reached("Unhandled option");
5644                 }
5645         }
5646
5647         if (optind >= argc) {
5648                 telinit_help();
5649                 return -EINVAL;
5650         }
5651
5652         if (optind + 1 < argc) {
5653                 log_error("Too many arguments.");
5654                 return -EINVAL;
5655         }
5656
5657         if (strlen(argv[optind]) != 1) {
5658                 log_error("Expected single character argument.");
5659                 return -EINVAL;
5660         }
5661
5662         for (i = 0; i < ELEMENTSOF(table); i++)
5663                 if (table[i].from == argv[optind][0])
5664                         break;
5665
5666         if (i >= ELEMENTSOF(table)) {
5667                 log_error("Unknown command '%s'.", argv[optind]);
5668                 return -EINVAL;
5669         }
5670
5671         arg_action = table[i].to;
5672
5673         optind ++;
5674
5675         return 1;
5676 }
5677
5678 static int runlevel_parse_argv(int argc, char *argv[]) {
5679
5680         enum {
5681                 ARG_HELP = 0x100,
5682         };
5683
5684         static const struct option options[] = {
5685                 { "help",      no_argument,       NULL, ARG_HELP    },
5686                 {}
5687         };
5688
5689         int c;
5690
5691         assert(argc >= 0);
5692         assert(argv);
5693
5694         while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0) {
5695                 switch (c) {
5696
5697                 case ARG_HELP:
5698                         return runlevel_help();
5699                         return 0;
5700
5701                 case '?':
5702                         return -EINVAL;
5703
5704                 default:
5705                         assert_not_reached("Unhandled option");
5706                 }
5707         }
5708
5709         if (optind < argc) {
5710                 log_error("Too many arguments.");
5711                 return -EINVAL;
5712         }
5713
5714         return 1;
5715 }
5716
5717 static int parse_argv(int argc, char *argv[]) {
5718         assert(argc >= 0);
5719         assert(argv);
5720
5721         if (program_invocation_short_name) {
5722
5723                 if (strstr(program_invocation_short_name, "halt")) {
5724                         arg_action = ACTION_HALT;
5725                         return halt_parse_argv(argc, argv);
5726                 } else if (strstr(program_invocation_short_name, "poweroff")) {
5727                         arg_action = ACTION_POWEROFF;
5728                         return halt_parse_argv(argc, argv);
5729                 } else if (strstr(program_invocation_short_name, "reboot")) {
5730                         if (kexec_loaded())
5731                                 arg_action = ACTION_KEXEC;
5732                         else
5733                                 arg_action = ACTION_REBOOT;
5734                         return halt_parse_argv(argc, argv);
5735                 } else if (strstr(program_invocation_short_name, "shutdown")) {
5736                         arg_action = ACTION_POWEROFF;
5737                         return shutdown_parse_argv(argc, argv);
5738                 } else if (strstr(program_invocation_short_name, "init")) {
5739
5740                         if (sd_booted() > 0) {
5741                                 arg_action = _ACTION_INVALID;
5742                                 return telinit_parse_argv(argc, argv);
5743                         } else {
5744                                 /* Hmm, so some other init system is
5745                                  * running, we need to forward this
5746                                  * request to it. For now we simply
5747                                  * guess that it is Upstart. */
5748
5749                                 execv(TELINIT, argv);
5750
5751                                 log_error("Couldn't find an alternative telinit implementation to spawn.");
5752                                 return -EIO;
5753                         }
5754
5755                 } else if (strstr(program_invocation_short_name, "runlevel")) {
5756                         arg_action = ACTION_RUNLEVEL;
5757                         return runlevel_parse_argv(argc, argv);
5758                 }
5759         }
5760
5761         arg_action = ACTION_SYSTEMCTL;
5762         return systemctl_parse_argv(argc, argv);
5763 }
5764
5765 _pure_ static int action_to_runlevel(void) {
5766
5767         static const char table[_ACTION_MAX] = {
5768                 [ACTION_HALT] =      '0',
5769                 [ACTION_POWEROFF] =  '0',
5770                 [ACTION_REBOOT] =    '6',
5771                 [ACTION_RUNLEVEL2] = '2',
5772                 [ACTION_RUNLEVEL3] = '3',
5773                 [ACTION_RUNLEVEL4] = '4',
5774                 [ACTION_RUNLEVEL5] = '5',
5775                 [ACTION_RESCUE] =    '1'
5776         };
5777
5778         assert(arg_action < _ACTION_MAX);
5779
5780         return table[arg_action];
5781 }
5782
5783 static int talk_initctl(void) {
5784
5785         struct init_request request = {
5786                 .magic = INIT_MAGIC,
5787                 .sleeptime  = 0,
5788                 .cmd = INIT_CMD_RUNLVL
5789         };
5790
5791         _cleanup_close_ int fd = -1;
5792         char rl;
5793         int r;
5794
5795         rl = action_to_runlevel();
5796         if (!rl)
5797                 return 0;
5798
5799         request.runlevel = rl;
5800
5801         fd = open(INIT_FIFO, O_WRONLY|O_NDELAY|O_CLOEXEC|O_NOCTTY);
5802         if (fd < 0) {
5803                 if (errno == ENOENT)
5804                         return 0;
5805
5806                 log_error("Failed to open "INIT_FIFO": %m");
5807                 return -errno;
5808         }
5809
5810         errno = 0;
5811         r = loop_write(fd, &request, sizeof(request), false) != sizeof(request);
5812         if (r) {
5813                 log_error("Failed to write to "INIT_FIFO": %m");
5814                 return errno > 0 ? -errno : -EIO;
5815         }
5816
5817         return 1;
5818 }
5819
5820 static int systemctl_main(sd_bus *bus, int argc, char *argv[], int bus_error) {
5821
5822         static const struct {
5823                 const char* verb;
5824                 const enum {
5825                         MORE,
5826                         LESS,
5827                         EQUAL
5828                 } argc_cmp;
5829                 const int argc;
5830                 int (* const dispatch)(sd_bus *bus, char **args);
5831                 const enum {
5832                         NOBUS = 1,
5833                         FORCE,
5834                 } bus;
5835         } verbs[] = {
5836                 { "list-units",            MORE,  0, list_units        },
5837                 { "list-unit-files",       MORE,  1, list_unit_files,  NOBUS },
5838                 { "list-sockets",          MORE,  1, list_sockets      },
5839                 { "list-timers",           MORE,  1, list_timers       },
5840                 { "list-jobs",             MORE,  1, list_jobs         },
5841                 { "clear-jobs",            EQUAL, 1, daemon_reload     },
5842                 { "cancel",                MORE,  2, cancel_job        },
5843                 { "start",                 MORE,  2, start_unit        },
5844                 { "stop",                  MORE,  2, start_unit        },
5845                 { "condstop",              MORE,  2, start_unit        }, /* For compatibility with ALTLinux */
5846                 { "reload",                MORE,  2, start_unit        },
5847                 { "restart",               MORE,  2, start_unit        },
5848                 { "try-restart",           MORE,  2, start_unit        },
5849                 { "reload-or-restart",     MORE,  2, start_unit        },
5850                 { "reload-or-try-restart", MORE,  2, start_unit        },
5851                 { "force-reload",          MORE,  2, start_unit        }, /* For compatibility with SysV */
5852                 { "condreload",            MORE,  2, start_unit        }, /* For compatibility with ALTLinux */
5853                 { "condrestart",           MORE,  2, start_unit        }, /* For compatibility with RH */
5854                 { "isolate",               EQUAL, 2, start_unit        },
5855                 { "kill",                  MORE,  2, kill_unit         },
5856                 { "is-active",             MORE,  2, check_unit_active },
5857                 { "check",                 MORE,  2, check_unit_active },
5858                 { "is-failed",             MORE,  2, check_unit_failed },
5859                 { "show",                  MORE,  1, show              },
5860                 { "cat",                   MORE,  2, cat               },
5861                 { "status",                MORE,  1, show              },
5862                 { "help",                  MORE,  2, show              },
5863                 { "snapshot",              LESS,  2, snapshot          },
5864                 { "delete",                MORE,  2, delete_snapshot   },
5865                 { "daemon-reload",         EQUAL, 1, daemon_reload     },
5866                 { "daemon-reexec",         EQUAL, 1, daemon_reload     },
5867                 { "show-environment",      EQUAL, 1, show_environment  },
5868                 { "set-environment",       MORE,  2, set_environment   },
5869                 { "unset-environment",     MORE,  2, set_environment   },
5870                 { "halt",                  EQUAL, 1, start_special,    FORCE },
5871                 { "poweroff",              EQUAL, 1, start_special,    FORCE },
5872                 { "reboot",                EQUAL, 1, start_special,    FORCE },
5873                 { "kexec",                 EQUAL, 1, start_special     },
5874                 { "suspend",               EQUAL, 1, start_special     },
5875                 { "hibernate",             EQUAL, 1, start_special     },
5876                 { "hybrid-sleep",          EQUAL, 1, start_special     },
5877                 { "default",               EQUAL, 1, start_special     },
5878                 { "rescue",                EQUAL, 1, start_special     },
5879                 { "emergency",             EQUAL, 1, start_special     },
5880                 { "exit",                  EQUAL, 1, start_special     },
5881                 { "reset-failed",          MORE,  1, reset_failed      },
5882                 { "enable",                MORE,  2, enable_unit,      NOBUS },
5883                 { "disable",               MORE,  2, enable_unit,      NOBUS },
5884                 { "is-enabled",            MORE,  2, unit_is_enabled,  NOBUS },
5885                 { "reenable",              MORE,  2, enable_unit,      NOBUS },
5886                 { "preset",                MORE,  2, enable_unit,      NOBUS },
5887                 { "mask",                  MORE,  2, enable_unit,      NOBUS },
5888                 { "unmask",                MORE,  2, enable_unit,      NOBUS },
5889                 { "link",                  MORE,  2, enable_unit,      NOBUS },
5890                 { "switch-root",           MORE,  2, switch_root       },
5891                 { "list-dependencies",     LESS,  2, list_dependencies },
5892                 { "set-default",           EQUAL, 2, set_default,      NOBUS },
5893                 { "get-default",           EQUAL, 1, get_default,      NOBUS },
5894                 { "set-property",          MORE,  3, set_property      },
5895                 {}
5896         }, *verb = verbs;
5897
5898         int left;
5899
5900         assert(argc >= 0);
5901         assert(argv);
5902
5903         left = argc - optind;
5904
5905         /* Special rule: no arguments (left == 0) means "list-units" */
5906         if (left > 0) {
5907                 if (streq(argv[optind], "help") && !argv[optind+1]) {
5908                         log_error("This command expects one or more "
5909                                   "unit names. Did you mean --help?");
5910                         return -EINVAL;
5911                 }
5912
5913                 for (; verb->verb; verb++)
5914                         if (streq(argv[optind], verb->verb))
5915                                 goto found;
5916
5917                 log_error("Unknown operation '%s'.", argv[optind]);
5918                 return -EINVAL;
5919         }
5920 found:
5921
5922         switch (verb->argc_cmp) {
5923
5924         case EQUAL:
5925                 if (left != verb->argc) {
5926                         log_error("Invalid number of arguments.");
5927                         return -EINVAL;
5928                 }
5929
5930                 break;
5931
5932         case MORE:
5933                 if (left < verb->argc) {
5934                         log_error("Too few arguments.");
5935                         return -EINVAL;
5936                 }
5937
5938                 break;
5939
5940         case LESS:
5941                 if (left > verb->argc) {
5942                         log_error("Too many arguments.");
5943                         return -EINVAL;
5944                 }
5945
5946                 break;
5947
5948         default:
5949                 assert_not_reached("Unknown comparison operator.");
5950         }
5951
5952         /* Require a bus connection for all operations but
5953          * enable/disable */
5954         if (verb->bus == NOBUS) {
5955                 if (!bus && !avoid_bus()) {
5956                         log_error("Failed to get D-Bus connection: %s", strerror(-bus_error));
5957                         return -EIO;
5958                 }
5959
5960         } else {
5961                 if (running_in_chroot() > 0) {
5962                         log_info("Running in chroot, ignoring request.");
5963                         return 0;
5964                 }
5965
5966                 if ((verb->bus != FORCE || arg_force <= 0) && !bus) {
5967                         log_error("Failed to get D-Bus connection: %s", strerror(-bus_error));
5968                         return -EIO;
5969                 }
5970         }
5971
5972         return verb->dispatch(bus, argv + optind);
5973 }
5974
5975 static int send_shutdownd(usec_t t, char mode, bool dry_run, bool warn, const char *message) {
5976
5977         struct sd_shutdown_command c = {
5978                 .usec = t,
5979                 .mode = mode,
5980                 .dry_run = dry_run,
5981                 .warn_wall = warn,
5982         };
5983
5984         union sockaddr_union sockaddr = {
5985                 .un.sun_family = AF_UNIX,
5986                 .un.sun_path = "/run/systemd/shutdownd",
5987         };
5988
5989         struct iovec iovec[2] = {{
5990                  .iov_base = (char*) &c,
5991                  .iov_len = offsetof(struct sd_shutdown_command, wall_message),
5992         }};
5993
5994         struct msghdr msghdr = {
5995                 .msg_name = &sockaddr,
5996                 .msg_namelen = offsetof(struct sockaddr_un, sun_path)
5997                                + sizeof("/run/systemd/shutdownd") - 1,
5998                 .msg_iov = iovec,
5999                 .msg_iovlen = 1,
6000         };
6001
6002         _cleanup_close_ int fd;
6003
6004         fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
6005         if (fd < 0)
6006                 return -errno;
6007
6008         if (!isempty(message)) {
6009                 iovec[1].iov_base = (char*) message;
6010                 iovec[1].iov_len = strlen(message);
6011                 msghdr.msg_iovlen++;
6012         }
6013
6014         if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) < 0)
6015                 return -errno;
6016
6017         return 0;
6018 }
6019
6020 static int reload_with_fallback(sd_bus *bus) {
6021
6022         if (bus) {
6023                 /* First, try systemd via D-Bus. */
6024                 if (daemon_reload(bus, NULL) >= 0)
6025                         return 0;
6026         }
6027
6028         /* Nothing else worked, so let's try signals */
6029         assert(arg_action == ACTION_RELOAD || arg_action == ACTION_REEXEC);
6030
6031         if (kill(1, arg_action == ACTION_RELOAD ? SIGHUP : SIGTERM) < 0) {
6032                 log_error("kill() failed: %m");
6033                 return -errno;
6034         }
6035
6036         return 0;
6037 }
6038
6039 static int start_with_fallback(sd_bus *bus) {
6040
6041         if (bus) {
6042                 /* First, try systemd via D-Bus. */
6043                 if (start_unit(bus, NULL) >= 0)
6044                         goto done;
6045         }
6046
6047         /* Nothing else worked, so let's try
6048          * /dev/initctl */
6049         if (talk_initctl() > 0)
6050                 goto done;
6051
6052         log_error("Failed to talk to init daemon.");
6053         return -EIO;
6054
6055 done:
6056         warn_wall(arg_action);
6057         return 0;
6058 }
6059
6060 static int halt_now(enum action a) {
6061
6062 /* Make sure C-A-D is handled by the kernel from this
6063          * point on... */
6064         reboot(RB_ENABLE_CAD);
6065
6066         switch (a) {
6067
6068         case ACTION_HALT:
6069                 log_info("Halting.");
6070                 reboot(RB_HALT_SYSTEM);
6071                 return -errno;
6072
6073         case ACTION_POWEROFF:
6074                 log_info("Powering off.");
6075                 reboot(RB_POWER_OFF);
6076                 return -errno;
6077
6078         case ACTION_REBOOT: {
6079                 _cleanup_free_ char *param = NULL;
6080
6081                 if (read_one_line_file(REBOOT_PARAM_FILE, &param) >= 0) {
6082                         log_info("Rebooting with argument '%s'.", param);
6083                         syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
6084                                 LINUX_REBOOT_CMD_RESTART2, param);
6085                 }
6086
6087                 log_info("Rebooting.");
6088                 reboot(RB_AUTOBOOT);
6089                 return -errno;
6090         }
6091
6092         default:
6093                 assert_not_reached("Unknown action.");
6094         }
6095 }
6096
6097 static int halt_main(sd_bus *bus) {
6098         int r;
6099
6100         r = check_inhibitors(bus, arg_action);
6101         if (r < 0)
6102                 return r;
6103
6104         if (geteuid() != 0) {
6105                 /* Try logind if we are a normal user and no special
6106                  * mode applies. Maybe PolicyKit allows us to shutdown
6107                  * the machine. */
6108
6109                 if (arg_when <= 0 &&
6110                     !arg_dry &&
6111                     arg_force <= 0 &&
6112                     (arg_action == ACTION_POWEROFF ||
6113                      arg_action == ACTION_REBOOT)) {
6114                         r = reboot_with_logind(bus, arg_action);
6115                         if (r >= 0)
6116                                 return r;
6117                 }
6118
6119                 log_error("Must be root.");
6120                 return -EPERM;
6121         }
6122
6123         if (arg_when > 0) {
6124                 _cleanup_free_ char *m;
6125
6126                 m = strv_join(arg_wall, " ");
6127                 if (!m)
6128                         return log_oom();
6129
6130                 r = send_shutdownd(arg_when,
6131                                    arg_action == ACTION_HALT     ? 'H' :
6132                                    arg_action == ACTION_POWEROFF ? 'P' :
6133                                    arg_action == ACTION_KEXEC    ? 'K' :
6134                                                                    'r',
6135                                    arg_dry,
6136                                    !arg_no_wall,
6137                                    m);
6138
6139                 if (r < 0)
6140                         log_warning("Failed to talk to shutdownd, proceeding with immediate shutdown: %s", strerror(-r));
6141                 else {
6142                         char date[FORMAT_TIMESTAMP_MAX];
6143
6144                         log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.",
6145                                  format_timestamp(date, sizeof(date), arg_when));
6146                         return 0;
6147                 }
6148         }
6149
6150         if (!arg_dry && !arg_force)
6151                 return start_with_fallback(bus);
6152
6153         if (!arg_no_wtmp) {
6154                 if (sd_booted() > 0)
6155                         log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
6156                 else {
6157                         r = utmp_put_shutdown();
6158                         if (r < 0)
6159                                 log_warning("Failed to write utmp record: %s", strerror(-r));
6160                 }
6161         }
6162
6163         if (arg_dry)
6164                 return 0;
6165
6166         r = halt_now(arg_action);
6167         log_error("Failed to reboot: %s", strerror(-r));
6168
6169         return r;
6170 }
6171
6172 static int runlevel_main(void) {
6173         int r, runlevel, previous;
6174
6175         r = utmp_get_runlevel(&runlevel, &previous);
6176         if (r < 0) {
6177                 puts("unknown");
6178                 return r;
6179         }
6180
6181         printf("%c %c\n",
6182                previous <= 0 ? 'N' : previous,
6183                runlevel <= 0 ? 'N' : runlevel);
6184
6185         return 0;
6186 }
6187
6188 int main(int argc, char*argv[]) {
6189         _cleanup_bus_unref_ sd_bus *bus = NULL;
6190         int r;
6191
6192         setlocale(LC_ALL, "");
6193         log_parse_environment();
6194         log_open();
6195
6196         /* Explicitly not on_tty() to avoid setting cached value.
6197          * This becomes relevant for piping output which might be
6198          * ellipsized. */
6199         original_stdout_is_tty = isatty(STDOUT_FILENO);
6200
6201         r = parse_argv(argc, argv);
6202         if (r <= 0)
6203                 goto finish;
6204
6205         /* /sbin/runlevel doesn't need to communicate via D-Bus, so
6206          * let's shortcut this */
6207         if (arg_action == ACTION_RUNLEVEL) {
6208                 r = runlevel_main();
6209                 goto finish;
6210         }
6211
6212         if (running_in_chroot() > 0 && arg_action != ACTION_SYSTEMCTL) {
6213                 log_info("Running in chroot, ignoring request.");
6214                 r = 0;
6215                 goto finish;
6216         }
6217
6218         if (!avoid_bus())
6219                 r = bus_open_transport_systemd(arg_transport, arg_host, arg_scope != UNIT_FILE_SYSTEM, &bus);
6220
6221         /* systemctl_main() will print an error message for the bus
6222          * connection, but only if it needs to */
6223
6224         switch (arg_action) {
6225
6226         case ACTION_SYSTEMCTL:
6227                 r = systemctl_main(bus, argc, argv, r);
6228                 break;
6229
6230         case ACTION_HALT:
6231         case ACTION_POWEROFF:
6232         case ACTION_REBOOT:
6233         case ACTION_KEXEC:
6234                 r = halt_main(bus);
6235                 break;
6236
6237         case ACTION_RUNLEVEL2:
6238         case ACTION_RUNLEVEL3:
6239         case ACTION_RUNLEVEL4:
6240         case ACTION_RUNLEVEL5:
6241         case ACTION_RESCUE:
6242         case ACTION_EMERGENCY:
6243         case ACTION_DEFAULT:
6244                 r = start_with_fallback(bus);
6245                 break;
6246
6247         case ACTION_RELOAD:
6248         case ACTION_REEXEC:
6249                 r = reload_with_fallback(bus);
6250                 break;
6251
6252         case ACTION_CANCEL_SHUTDOWN: {
6253                 _cleanup_free_ char *m = NULL;
6254
6255                 if (arg_wall) {
6256                         m = strv_join(arg_wall, " ");
6257                         if (!m) {
6258                                 r = log_oom();
6259                                 goto finish;
6260                         }
6261                 }
6262
6263                 r = send_shutdownd(arg_when, SD_SHUTDOWN_NONE, false, !arg_no_wall, m);
6264                 if (r < 0)
6265                         log_warning("Failed to talk to shutdownd, shutdown hasn't been cancelled: %s", strerror(-r));
6266                 break;
6267         }
6268
6269         case ACTION_RUNLEVEL:
6270         case _ACTION_INVALID:
6271         default:
6272                 assert_not_reached("Unknown action");
6273         }
6274
6275 finish:
6276         pager_close();
6277         ask_password_agent_close();
6278         polkit_agent_close();
6279
6280         strv_free(arg_types);
6281         strv_free(arg_states);
6282         strv_free(arg_properties);
6283
6284         return r < 0 ? EXIT_FAILURE : r;
6285 }