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