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