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