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