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