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