chiark / gitweb /
systemctl: when invokes as "reboot -f", sync()
[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_parameter;
3275
3276         usec_t assert_timestamp;
3277         bool assert_result;
3278         bool failed_assert_trigger;
3279         bool failed_assert_negate;
3280         const char *failed_assert;
3281         const char *failed_assert_parameter;
3282
3283         /* Socket */
3284         unsigned n_accepted;
3285         unsigned n_connections;
3286         bool accept;
3287
3288         /* Pairs of type, path */
3289         char **listen;
3290
3291         /* Device */
3292         const char *sysfs_path;
3293
3294         /* Mount, Automount */
3295         const char *where;
3296
3297         /* Swap */
3298         const char *what;
3299
3300         LIST_HEAD(ExecStatusInfo, exec);
3301 } UnitStatusInfo;
3302
3303 static void print_status_info(
3304                 UnitStatusInfo *i,
3305                 bool *ellipsized) {
3306
3307         ExecStatusInfo *p;
3308         const char *active_on, *active_off, *on, *off, *ss;
3309         usec_t timestamp;
3310         char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
3311         char since2[FORMAT_TIMESTAMP_MAX], *s2;
3312         const char *path;
3313         int flags =
3314                 arg_all * OUTPUT_SHOW_ALL |
3315                 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
3316                 on_tty() * OUTPUT_COLOR |
3317                 !arg_quiet * OUTPUT_WARN_CUTOFF |
3318                 arg_full * OUTPUT_FULL_WIDTH;
3319         char **t, **t2;
3320
3321         assert(i);
3322
3323         /* This shows pretty information about a unit. See
3324          * print_property() for a low-level property printer */
3325
3326         if (streq_ptr(i->active_state, "failed")) {
3327                 active_on = ansi_highlight_red();
3328                 active_off = ansi_highlight_off();
3329         } else if (streq_ptr(i->active_state, "active") || streq_ptr(i->active_state, "reloading")) {
3330                 active_on = ansi_highlight_green();
3331                 active_off = ansi_highlight_off();
3332         } else
3333                 active_on = active_off = "";
3334
3335         printf("%s%s%s %s", active_on, draw_special_char(DRAW_BLACK_CIRCLE), active_off, strna(i->id));
3336
3337         if (i->description && !streq_ptr(i->id, i->description))
3338                 printf(" - %s", i->description);
3339
3340         printf("\n");
3341
3342         if (i->following)
3343                 printf("   Follow: unit currently follows state of %s\n", i->following);
3344
3345         if (streq_ptr(i->load_state, "error")) {
3346                 on = ansi_highlight_red();
3347                 off = ansi_highlight_off();
3348         } else
3349                 on = off = "";
3350
3351         path = i->source_path ? i->source_path : i->fragment_path;
3352
3353         if (i->load_error)
3354                 printf("   Loaded: %s%s%s (Reason: %s)\n",
3355                        on, strna(i->load_state), off, i->load_error);
3356         else if (path && i->unit_file_state)
3357                 printf("   Loaded: %s%s%s (%s; %s)\n",
3358                        on, strna(i->load_state), off, path, i->unit_file_state);
3359         else if (path)
3360                 printf("   Loaded: %s%s%s (%s)\n",
3361                        on, strna(i->load_state), off, path);
3362         else
3363                 printf("   Loaded: %s%s%s\n",
3364                        on, strna(i->load_state), off);
3365
3366         if (!strv_isempty(i->dropin_paths)) {
3367                 _cleanup_free_ char *dir = NULL;
3368                 bool last = false;
3369                 char ** dropin;
3370
3371                 STRV_FOREACH(dropin, i->dropin_paths) {
3372                         if (! dir || last) {
3373                                 printf(dir ? "        " : "  Drop-In: ");
3374
3375                                 free(dir);
3376                                 dir = NULL;
3377
3378                                 if (path_get_parent(*dropin, &dir) < 0) {
3379                                         log_oom();
3380                                         return;
3381                                 }
3382
3383                                 printf("%s\n           %s", dir,
3384                                        draw_special_char(DRAW_TREE_RIGHT));
3385                         }
3386
3387                         last = ! (*(dropin + 1) && startswith(*(dropin + 1), dir));
3388
3389                         printf("%s%s", basename(*dropin), last ? "\n" : ", ");
3390                 }
3391         }
3392
3393         ss = streq_ptr(i->active_state, i->sub_state) ? NULL : i->sub_state;
3394         if (ss)
3395                 printf("   Active: %s%s (%s)%s",
3396                        active_on, strna(i->active_state), ss, active_off);
3397         else
3398                 printf("   Active: %s%s%s",
3399                        active_on, strna(i->active_state), active_off);
3400
3401         if (!isempty(i->result) && !streq(i->result, "success"))
3402                 printf(" (Result: %s)", i->result);
3403
3404         timestamp = (streq_ptr(i->active_state, "active")      ||
3405                      streq_ptr(i->active_state, "reloading"))   ? i->active_enter_timestamp :
3406                     (streq_ptr(i->active_state, "inactive")    ||
3407                      streq_ptr(i->active_state, "failed"))      ? i->inactive_enter_timestamp :
3408                     streq_ptr(i->active_state, "activating")    ? i->inactive_exit_timestamp :
3409                                                                   i->active_exit_timestamp;
3410
3411         s1 = format_timestamp_relative(since1, sizeof(since1), timestamp);
3412         s2 = format_timestamp(since2, sizeof(since2), timestamp);
3413
3414         if (s1)
3415                 printf(" since %s; %s\n", s2, s1);
3416         else if (s2)
3417                 printf(" since %s\n", s2);
3418         else
3419                 printf("\n");
3420
3421         if (!i->condition_result && i->condition_timestamp > 0) {
3422                 s1 = format_timestamp_relative(since1, sizeof(since1), i->condition_timestamp);
3423                 s2 = format_timestamp(since2, sizeof(since2), i->condition_timestamp);
3424
3425                 printf("Condition: start %scondition failed%s at %s%s%s\n",
3426                        ansi_highlight_yellow(), ansi_highlight_off(),
3427                        s2, s1 ? "; " : "", s1 ? s1 : "");
3428                 if (i->failed_condition_trigger)
3429                         printf("           none of the trigger conditions were met\n");
3430                 else if (i->failed_condition)
3431                         printf("           %s=%s%s was not met\n",
3432                                i->failed_condition,
3433                                i->failed_condition_negate ? "!" : "",
3434                                i->failed_condition_parameter);
3435         }
3436
3437         if (!i->assert_result && i->assert_timestamp > 0) {
3438                 s1 = format_timestamp_relative(since1, sizeof(since1), i->assert_timestamp);
3439                 s2 = format_timestamp(since2, sizeof(since2), i->assert_timestamp);
3440
3441                 printf("   Assert: start %sassertion failed%s at %s%s%s\n",
3442                        ansi_highlight_red(), ansi_highlight_off(),
3443                        s2, s1 ? "; " : "", s1 ? s1 : "");
3444                 if (i->failed_assert_trigger)
3445                         printf("           none of the trigger assertions were met\n");
3446                 else if (i->failed_assert)
3447                         printf("           %s=%s%s was not met\n",
3448                                i->failed_assert,
3449                                i->failed_assert_negate ? "!" : "",
3450                                i->failed_assert_parameter);
3451         }
3452
3453         if (i->sysfs_path)
3454                 printf("   Device: %s\n", i->sysfs_path);
3455         if (i->where)
3456                 printf("    Where: %s\n", i->where);
3457         if (i->what)
3458                 printf("     What: %s\n", i->what);
3459
3460         STRV_FOREACH(t, i->documentation)
3461                 printf(" %*s %s\n", 9, t == i->documentation ? "Docs:" : "", *t);
3462
3463         STRV_FOREACH_PAIR(t, t2, i->listen)
3464                 printf(" %*s %s (%s)\n", 9, t == i->listen ? "Listen:" : "", *t2, *t);
3465
3466         if (i->accept)
3467                 printf(" Accepted: %u; Connected: %u\n", i->n_accepted, i->n_connections);
3468
3469         LIST_FOREACH(exec, p, i->exec) {
3470                 _cleanup_free_ char *argv = NULL;
3471                 bool good;
3472
3473                 /* Only show exited processes here */
3474                 if (p->code == 0)
3475                         continue;
3476
3477                 argv = strv_join(p->argv, " ");
3478                 printf("  Process: %u %s=%s ", p->pid, p->name, strna(argv));
3479
3480                 good = is_clean_exit_lsb(p->code, p->status, NULL);
3481                 if (!good) {
3482                         on = ansi_highlight_red();
3483                         off = ansi_highlight_off();
3484                 } else
3485                         on = off = "";
3486
3487                 printf("%s(code=%s, ", on, sigchld_code_to_string(p->code));
3488
3489                 if (p->code == CLD_EXITED) {
3490                         const char *c;
3491
3492                         printf("status=%i", p->status);
3493
3494                         c = exit_status_to_string(p->status, EXIT_STATUS_SYSTEMD);
3495                         if (c)
3496                                 printf("/%s", c);
3497
3498                 } else
3499                         printf("signal=%s", signal_to_string(p->status));
3500
3501                 printf(")%s\n", off);
3502
3503                 if (i->main_pid == p->pid &&
3504                     i->start_timestamp == p->start_timestamp &&
3505                     i->exit_timestamp == p->start_timestamp)
3506                         /* Let's not show this twice */
3507                         i->main_pid = 0;
3508
3509                 if (p->pid == i->control_pid)
3510                         i->control_pid = 0;
3511         }
3512
3513         if (i->main_pid > 0 || i->control_pid > 0) {
3514                 if (i->main_pid > 0) {
3515                         printf(" Main PID: "PID_FMT, i->main_pid);
3516
3517                         if (i->running) {
3518                                 _cleanup_free_ char *comm = NULL;
3519                                 get_process_comm(i->main_pid, &comm);
3520                                 if (comm)
3521                                         printf(" (%s)", comm);
3522                         } else if (i->exit_code > 0) {
3523                                 printf(" (code=%s, ", sigchld_code_to_string(i->exit_code));
3524
3525                                 if (i->exit_code == CLD_EXITED) {
3526                                         const char *c;
3527
3528                                         printf("status=%i", i->exit_status);
3529
3530                                         c = exit_status_to_string(i->exit_status, EXIT_STATUS_SYSTEMD);
3531                                         if (c)
3532                                                 printf("/%s", c);
3533
3534                                 } else
3535                                         printf("signal=%s", signal_to_string(i->exit_status));
3536                                 printf(")");
3537                         }
3538
3539                         if (i->control_pid > 0)
3540                                 printf(";");
3541                 }
3542
3543                 if (i->control_pid > 0) {
3544                         _cleanup_free_ char *c = NULL;
3545
3546                         printf(" %8s: "PID_FMT, i->main_pid ? "" : " Control", i->control_pid);
3547
3548                         get_process_comm(i->control_pid, &c);
3549                         if (c)
3550                                 printf(" (%s)", c);
3551                 }
3552
3553                 printf("\n");
3554         }
3555
3556         if (i->status_text)
3557                 printf("   Status: \"%s\"\n", i->status_text);
3558         if (i->status_errno > 0)
3559                 printf("    Error: %i (%s)\n", i->status_errno, strerror(i->status_errno));
3560
3561         if (i->control_group &&
3562             (i->main_pid > 0 || i->control_pid > 0 ||
3563              ((arg_transport != BUS_TRANSPORT_LOCAL && arg_transport != BUS_TRANSPORT_CONTAINER) || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, i->control_group, false) == 0))) {
3564                 unsigned c;
3565
3566                 printf("   CGroup: %s\n", i->control_group);
3567
3568                 if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_CONTAINER) {
3569                         unsigned k = 0;
3570                         pid_t extra[2];
3571                         static const char prefix[] = "           ";
3572
3573                         c = columns();
3574                         if (c > sizeof(prefix) - 1)
3575                                 c -= sizeof(prefix) - 1;
3576                         else
3577                                 c = 0;
3578
3579                         if (i->main_pid > 0)
3580                                 extra[k++] = i->main_pid;
3581
3582                         if (i->control_pid > 0)
3583                                 extra[k++] = i->control_pid;
3584
3585                         show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, i->control_group, prefix, c, false, extra, k, flags);
3586                 }
3587         }
3588
3589         if (i->id && arg_transport == BUS_TRANSPORT_LOCAL) {
3590                 show_journal_by_unit(stdout,
3591                                      i->id,
3592                                      arg_output,
3593                                      0,
3594                                      i->inactive_exit_timestamp_monotonic,
3595                                      arg_lines,
3596                                      getuid(),
3597                                      flags | OUTPUT_BEGIN_NEWLINE,
3598                                      arg_scope == UNIT_FILE_SYSTEM,
3599                                      ellipsized);
3600         }
3601
3602         if (i->need_daemon_reload)
3603                 printf("\n%sWarning:%s Unit file changed on disk, 'systemctl %sdaemon-reload' recommended.\n",
3604                        ansi_highlight_red(),
3605                        ansi_highlight_off(),
3606                        arg_scope == UNIT_FILE_SYSTEM ? "" : "--user ");
3607 }
3608
3609 static void show_unit_help(UnitStatusInfo *i) {
3610         char **p;
3611
3612         assert(i);
3613
3614         if (!i->documentation) {
3615                 log_info("Documentation for %s not known.", i->id);
3616                 return;
3617         }
3618
3619         STRV_FOREACH(p, i->documentation)
3620                 if (startswith(*p, "man:"))
3621                         show_man_page(*p + 4, false);
3622                 else
3623                         log_info("Can't show: %s", *p);
3624 }
3625
3626 static int status_property(const char *name, sd_bus_message *m, UnitStatusInfo *i, const char *contents) {
3627         int r;
3628
3629         assert(name);
3630         assert(m);
3631         assert(i);
3632
3633         switch (contents[0]) {
3634
3635         case SD_BUS_TYPE_STRING: {
3636                 const char *s;
3637
3638                 r = sd_bus_message_read(m, "s", &s);
3639                 if (r < 0)
3640                         return bus_log_parse_error(r);
3641
3642                 if (!isempty(s)) {
3643                         if (streq(name, "Id"))
3644                                 i->id = s;
3645                         else if (streq(name, "LoadState"))
3646                                 i->load_state = s;
3647                         else if (streq(name, "ActiveState"))
3648                                 i->active_state = s;
3649                         else if (streq(name, "SubState"))
3650                                 i->sub_state = s;
3651                         else if (streq(name, "Description"))
3652                                 i->description = s;
3653                         else if (streq(name, "FragmentPath"))
3654                                 i->fragment_path = s;
3655                         else if (streq(name, "SourcePath"))
3656                                 i->source_path = s;
3657 #ifndef NOLEGACY
3658                         else if (streq(name, "DefaultControlGroup")) {
3659                                 const char *e;
3660                                 e = startswith(s, SYSTEMD_CGROUP_CONTROLLER ":");
3661                                 if (e)
3662                                         i->control_group = e;
3663                         }
3664 #endif
3665                         else if (streq(name, "ControlGroup"))
3666                                 i->control_group = s;
3667                         else if (streq(name, "StatusText"))
3668                                 i->status_text = s;
3669                         else if (streq(name, "PIDFile"))
3670                                 i->pid_file = s;
3671                         else if (streq(name, "SysFSPath"))
3672                                 i->sysfs_path = s;
3673                         else if (streq(name, "Where"))
3674                                 i->where = s;
3675                         else if (streq(name, "What"))
3676                                 i->what = s;
3677                         else if (streq(name, "Following"))
3678                                 i->following = s;
3679                         else if (streq(name, "UnitFileState"))
3680                                 i->unit_file_state = s;
3681                         else if (streq(name, "Result"))
3682                                 i->result = s;
3683                 }
3684
3685                 break;
3686         }
3687
3688         case SD_BUS_TYPE_BOOLEAN: {
3689                 int b;
3690
3691                 r = sd_bus_message_read(m, "b", &b);
3692                 if (r < 0)
3693                         return bus_log_parse_error(r);
3694
3695                 if (streq(name, "Accept"))
3696                         i->accept = b;
3697                 else if (streq(name, "NeedDaemonReload"))
3698                         i->need_daemon_reload = b;
3699                 else if (streq(name, "ConditionResult"))
3700                         i->condition_result = b;
3701                 else if (streq(name, "AssertResult"))
3702                         i->assert_result = b;
3703
3704                 break;
3705         }
3706
3707         case SD_BUS_TYPE_UINT32: {
3708                 uint32_t u;
3709
3710                 r = sd_bus_message_read(m, "u", &u);
3711                 if (r < 0)
3712                         return bus_log_parse_error(r);
3713
3714                 if (streq(name, "MainPID")) {
3715                         if (u > 0) {
3716                                 i->main_pid = (pid_t) u;
3717                                 i->running = true;
3718                         }
3719                 } else if (streq(name, "ControlPID"))
3720                         i->control_pid = (pid_t) u;
3721                 else if (streq(name, "ExecMainPID")) {
3722                         if (u > 0)
3723                                 i->main_pid = (pid_t) u;
3724                 } else if (streq(name, "NAccepted"))
3725                         i->n_accepted = u;
3726                 else if (streq(name, "NConnections"))
3727                         i->n_connections = u;
3728
3729                 break;
3730         }
3731
3732         case SD_BUS_TYPE_INT32: {
3733                 int32_t j;
3734
3735                 r = sd_bus_message_read(m, "i", &j);
3736                 if (r < 0)
3737                         return bus_log_parse_error(r);
3738
3739                 if (streq(name, "ExecMainCode"))
3740                         i->exit_code = (int) j;
3741                 else if (streq(name, "ExecMainStatus"))
3742                         i->exit_status = (int) j;
3743                 else if (streq(name, "StatusErrno"))
3744                         i->status_errno = (int) j;
3745
3746                 break;
3747         }
3748
3749         case SD_BUS_TYPE_UINT64: {
3750                 uint64_t u;
3751
3752                 r = sd_bus_message_read(m, "t", &u);
3753                 if (r < 0)
3754                         return bus_log_parse_error(r);
3755
3756                 if (streq(name, "ExecMainStartTimestamp"))
3757                         i->start_timestamp = (usec_t) u;
3758                 else if (streq(name, "ExecMainExitTimestamp"))
3759                         i->exit_timestamp = (usec_t) u;
3760                 else if (streq(name, "ActiveEnterTimestamp"))
3761                         i->active_enter_timestamp = (usec_t) u;
3762                 else if (streq(name, "InactiveEnterTimestamp"))
3763                         i->inactive_enter_timestamp = (usec_t) u;
3764                 else if (streq(name, "InactiveExitTimestamp"))
3765                         i->inactive_exit_timestamp = (usec_t) u;
3766                 else if (streq(name, "InactiveExitTimestampMonotonic"))
3767                         i->inactive_exit_timestamp_monotonic = (usec_t) u;
3768                 else if (streq(name, "ActiveExitTimestamp"))
3769                         i->active_exit_timestamp = (usec_t) u;
3770                 else if (streq(name, "ConditionTimestamp"))
3771                         i->condition_timestamp = (usec_t) u;
3772                 else if (streq(name, "AssertTimestamp"))
3773                         i->assert_timestamp = (usec_t) u;
3774
3775                 break;
3776         }
3777
3778         case SD_BUS_TYPE_ARRAY:
3779
3780                 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3781                         _cleanup_free_ ExecStatusInfo *info = NULL;
3782
3783                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3784                         if (r < 0)
3785                                 return bus_log_parse_error(r);
3786
3787                         info = new0(ExecStatusInfo, 1);
3788                         if (!info)
3789                                 return log_oom();
3790
3791                         while ((r = exec_status_info_deserialize(m, info)) > 0) {
3792
3793                                 info->name = strdup(name);
3794                                 if (!info->name)
3795                                         log_oom();
3796
3797                                 LIST_PREPEND(exec, i->exec, info);
3798
3799                                 info = new0(ExecStatusInfo, 1);
3800                                 if (!info)
3801                                         log_oom();
3802                         }
3803
3804                         if (r < 0)
3805                                 return bus_log_parse_error(r);
3806
3807                         r = sd_bus_message_exit_container(m);
3808                         if (r < 0)
3809                                 return bus_log_parse_error(r);
3810
3811                         return 0;
3812
3813                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3814                         const char *type, *path;
3815
3816                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3817                         if (r < 0)
3818                                 return bus_log_parse_error(r);
3819
3820                         while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0) {
3821
3822                                 r = strv_extend(&i->listen, type);
3823                                 if (r < 0)
3824                                         return r;
3825
3826                                 r = strv_extend(&i->listen, path);
3827                                 if (r < 0)
3828                                         return r;
3829                         }
3830                         if (r < 0)
3831                                 return bus_log_parse_error(r);
3832
3833                         r = sd_bus_message_exit_container(m);
3834                         if (r < 0)
3835                                 return bus_log_parse_error(r);
3836
3837                         return 0;
3838
3839                 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "DropInPaths")) {
3840
3841                         r = sd_bus_message_read_strv(m, &i->dropin_paths);
3842                         if (r < 0)
3843                                 return bus_log_parse_error(r);
3844
3845                 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Documentation")) {
3846
3847                         r = sd_bus_message_read_strv(m, &i->documentation);
3848                         if (r < 0)
3849                                 return bus_log_parse_error(r);
3850
3851                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Conditions")) {
3852                         const char *cond, *param;
3853                         int trigger, negate;
3854                         int32_t state;
3855
3856                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
3857                         if (r < 0)
3858                                 return bus_log_parse_error(r);
3859
3860                         while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, &param, &state)) > 0) {
3861                                 log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
3862                                 if (state < 0 && (!trigger || !i->failed_condition)) {
3863                                         i->failed_condition = cond;
3864                                         i->failed_condition_trigger = trigger;
3865                                         i->failed_condition_negate = negate;
3866                                         i->failed_condition_parameter = param;
3867                                 }
3868                         }
3869                         if (r < 0)
3870                                 return bus_log_parse_error(r);
3871
3872                         r = sd_bus_message_exit_container(m);
3873                         if (r < 0)
3874                                 return bus_log_parse_error(r);
3875
3876                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Asserts")) {
3877                         const char *cond, *param;
3878                         int trigger, negate;
3879                         int32_t state;
3880
3881                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
3882                         if (r < 0)
3883                                 return bus_log_parse_error(r);
3884
3885                         while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, &param, &state)) > 0) {
3886                                 log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
3887                                 if (state < 0 && (!trigger || !i->failed_assert)) {
3888                                         i->failed_assert = cond;
3889                                         i->failed_assert_trigger = trigger;
3890                                         i->failed_assert_negate = negate;
3891                                         i->failed_assert_parameter = param;
3892                                 }
3893                         }
3894                         if (r < 0)
3895                                 return bus_log_parse_error(r);
3896
3897                         r = sd_bus_message_exit_container(m);
3898                         if (r < 0)
3899                                 return bus_log_parse_error(r);
3900
3901                 } else
3902                         goto skip;
3903
3904                 break;
3905
3906         case SD_BUS_TYPE_STRUCT_BEGIN:
3907
3908                 if (streq(name, "LoadError")) {
3909                         const char *n, *message;
3910
3911                         r = sd_bus_message_read(m, "(ss)", &n, &message);
3912                         if (r < 0)
3913                                 return bus_log_parse_error(r);
3914
3915                         if (!isempty(message))
3916                                 i->load_error = message;
3917                 } else
3918                         goto skip;
3919
3920                 break;
3921
3922         default:
3923                 goto skip;
3924         }
3925
3926         return 0;
3927
3928 skip:
3929         r = sd_bus_message_skip(m, contents);
3930         if (r < 0)
3931                 return bus_log_parse_error(r);
3932
3933         return 0;
3934 }
3935
3936 static int print_property(const char *name, sd_bus_message *m, const char *contents) {
3937         int r;
3938
3939         assert(name);
3940         assert(m);
3941
3942         /* This is a low-level property printer, see
3943          * print_status_info() for the nicer output */
3944
3945         if (arg_properties && !strv_find(arg_properties, name)) {
3946                 /* skip what we didn't read */
3947                 r = sd_bus_message_skip(m, contents);
3948                 return r;
3949         }
3950
3951         switch (contents[0]) {
3952
3953         case SD_BUS_TYPE_STRUCT_BEGIN:
3954
3955                 if (contents[1] == SD_BUS_TYPE_UINT32 && streq(name, "Job")) {
3956                         uint32_t u;
3957
3958                         r = sd_bus_message_read(m, "(uo)", &u, NULL);
3959                         if (r < 0)
3960                                 return bus_log_parse_error(r);
3961
3962                         if (u > 0)
3963                                 printf("%s=%"PRIu32"\n", name, u);
3964                         else if (arg_all)
3965                                 printf("%s=\n", name);
3966
3967                         return 0;
3968
3969                 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Unit")) {
3970                         const char *s;
3971
3972                         r = sd_bus_message_read(m, "(so)", &s, NULL);
3973                         if (r < 0)
3974                                 return bus_log_parse_error(r);
3975
3976                         if (arg_all || !isempty(s))
3977                                 printf("%s=%s\n", name, s);
3978
3979                         return 0;
3980
3981                 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "LoadError")) {
3982                         const char *a = NULL, *b = NULL;
3983
3984                         r = sd_bus_message_read(m, "(ss)", &a, &b);
3985                         if (r < 0)
3986                                 return bus_log_parse_error(r);
3987
3988                         if (arg_all || !isempty(a) || !isempty(b))
3989                                 printf("%s=%s \"%s\"\n", name, strempty(a), strempty(b));
3990
3991                         return 0;
3992                 } else if (streq_ptr(name, "SystemCallFilter")) {
3993                         _cleanup_strv_free_ char **l = NULL;
3994                         int whitelist;
3995
3996                         r = sd_bus_message_enter_container(m, 'r', "bas");
3997                         if (r < 0)
3998                                 return bus_log_parse_error(r);
3999
4000                         r = sd_bus_message_read(m, "b", &whitelist);
4001                         if (r < 0)
4002                                 return bus_log_parse_error(r);
4003
4004                         r = sd_bus_message_read_strv(m, &l);
4005                         if (r < 0)
4006                                 return bus_log_parse_error(r);
4007
4008                         r = sd_bus_message_exit_container(m);
4009                         if (r < 0)
4010                                 return bus_log_parse_error(r);
4011
4012                         if (arg_all || whitelist || !strv_isempty(l)) {
4013                                 bool first = true;
4014                                 char **i;
4015
4016                                 fputs(name, stdout);
4017                                 fputc('=', stdout);
4018
4019                                 if (!whitelist)
4020                                         fputc('~', stdout);
4021
4022                                 STRV_FOREACH(i, l) {
4023                                         if (first)
4024                                                 first = false;
4025                                         else
4026                                                 fputc(' ', stdout);
4027
4028                                         fputs(*i, stdout);
4029                                 }
4030                                 fputc('\n', stdout);
4031                         }
4032
4033                         return 0;
4034                 }
4035
4036                 break;
4037
4038         case SD_BUS_TYPE_ARRAY:
4039
4040                 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "EnvironmentFiles")) {
4041                         const char *path;
4042                         int ignore;
4043
4044                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sb)");
4045                         if (r < 0)
4046                                 return bus_log_parse_error(r);
4047
4048                         while ((r = sd_bus_message_read(m, "(sb)", &path, &ignore)) > 0)
4049                                 printf("EnvironmentFile=%s (ignore_errors=%s)\n", path, yes_no(ignore));
4050
4051                         if (r < 0)
4052                                 return bus_log_parse_error(r);
4053
4054                         r = sd_bus_message_exit_container(m);
4055                         if (r < 0)
4056                                 return bus_log_parse_error(r);
4057
4058                         return 0;
4059
4060                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Paths")) {
4061                         const char *type, *path;
4062
4063                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
4064                         if (r < 0)
4065                                 return bus_log_parse_error(r);
4066
4067                         while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
4068                                 printf("%s=%s\n", type, path);
4069                         if (r < 0)
4070                                 return bus_log_parse_error(r);
4071
4072                         r = sd_bus_message_exit_container(m);
4073                         if (r < 0)
4074                                 return bus_log_parse_error(r);
4075
4076                         return 0;
4077
4078                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
4079                         const char *type, *path;
4080
4081                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
4082                         if (r < 0)
4083                                 return bus_log_parse_error(r);
4084
4085                         while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
4086                                 printf("Listen%s=%s\n", type, path);
4087                         if (r < 0)
4088                                 return bus_log_parse_error(r);
4089
4090                         r = sd_bus_message_exit_container(m);
4091                         if (r < 0)
4092                                 return bus_log_parse_error(r);
4093
4094                         return 0;
4095
4096                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Timers")) {
4097                         const char *base;
4098                         uint64_t value, next_elapse;
4099
4100                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(stt)");
4101                         if (r < 0)
4102                                 return bus_log_parse_error(r);
4103
4104                         while ((r = sd_bus_message_read(m, "(stt)", &base, &value, &next_elapse)) > 0) {
4105                                 char timespan1[FORMAT_TIMESPAN_MAX], timespan2[FORMAT_TIMESPAN_MAX];
4106
4107                                 printf("%s={ value=%s ; next_elapse=%s }\n",
4108                                        base,
4109                                        format_timespan(timespan1, sizeof(timespan1), value, 0),
4110                                        format_timespan(timespan2, sizeof(timespan2), next_elapse, 0));
4111                         }
4112                         if (r < 0)
4113                                 return bus_log_parse_error(r);
4114
4115                         r = sd_bus_message_exit_container(m);
4116                         if (r < 0)
4117                                 return bus_log_parse_error(r);
4118
4119                         return 0;
4120
4121                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
4122                         ExecStatusInfo info = {};
4123
4124                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
4125                         if (r < 0)
4126                                 return bus_log_parse_error(r);
4127
4128                         while ((r = exec_status_info_deserialize(m, &info)) > 0) {
4129                                 char timestamp1[FORMAT_TIMESTAMP_MAX], timestamp2[FORMAT_TIMESTAMP_MAX];
4130                                 _cleanup_free_ char *tt;
4131
4132                                 tt = strv_join(info.argv, " ");
4133
4134                                 printf("%s={ path=%s ; argv[]=%s ; ignore_errors=%s ; start_time=[%s] ; stop_time=[%s] ; pid="PID_FMT" ; code=%s ; status=%i%s%s }\n",
4135                                        name,
4136                                        strna(info.path),
4137                                        strna(tt),
4138                                        yes_no(info.ignore),
4139                                        strna(format_timestamp(timestamp1, sizeof(timestamp1), info.start_timestamp)),
4140                                        strna(format_timestamp(timestamp2, sizeof(timestamp2), info.exit_timestamp)),
4141                                        info.pid,
4142                                        sigchld_code_to_string(info.code),
4143                                        info.status,
4144                                        info.code == CLD_EXITED ? "" : "/",
4145                                        strempty(info.code == CLD_EXITED ? NULL : signal_to_string(info.status)));
4146
4147                                 free(info.path);
4148                                 strv_free(info.argv);
4149                                 zero(info);
4150                         }
4151
4152                         r = sd_bus_message_exit_container(m);
4153                         if (r < 0)
4154                                 return bus_log_parse_error(r);
4155
4156                         return 0;
4157
4158                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "DeviceAllow")) {
4159                         const char *path, *rwm;
4160
4161                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
4162                         if (r < 0)
4163                                 return bus_log_parse_error(r);
4164
4165                         while ((r = sd_bus_message_read(m, "(ss)", &path, &rwm)) > 0)
4166                                 printf("%s=%s %s\n", name, strna(path), strna(rwm));
4167                         if (r < 0)
4168                                 return bus_log_parse_error(r);
4169
4170                         r = sd_bus_message_exit_container(m);
4171                         if (r < 0)
4172                                 return bus_log_parse_error(r);
4173
4174                         return 0;
4175
4176                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "BlockIODeviceWeight")) {
4177                         const char *path;
4178                         uint64_t weight;
4179
4180                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
4181                         if (r < 0)
4182                                 return bus_log_parse_error(r);
4183
4184                         while ((r = sd_bus_message_read(m, "(st)", &path, &weight)) > 0)
4185                                 printf("%s=%s %" PRIu64 "\n", name, strna(path), weight);
4186                         if (r < 0)
4187                                 return bus_log_parse_error(r);
4188
4189                         r = sd_bus_message_exit_container(m);
4190                         if (r < 0)
4191                                 return bus_log_parse_error(r);
4192
4193                         return 0;
4194
4195                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && (streq(name, "BlockIOReadBandwidth") || streq(name, "BlockIOWriteBandwidth"))) {
4196                         const char *path;
4197                         uint64_t bandwidth;
4198
4199                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
4200                         if (r < 0)
4201                                 return bus_log_parse_error(r);
4202
4203                         while ((r = sd_bus_message_read(m, "(st)", &path, &bandwidth)) > 0)
4204                                 printf("%s=%s %" PRIu64 "\n", name, strna(path), bandwidth);
4205                         if (r < 0)
4206                                 return bus_log_parse_error(r);
4207
4208                         r = sd_bus_message_exit_container(m);
4209                         if (r < 0)
4210                                 return bus_log_parse_error(r);
4211
4212                         return 0;
4213                 }
4214
4215                 break;
4216         }
4217
4218         r = bus_print_property(name, m, arg_all);
4219         if (r < 0)
4220                 return bus_log_parse_error(r);
4221
4222         if (r == 0) {
4223                 r = sd_bus_message_skip(m, contents);
4224                 if (r < 0)
4225                         return bus_log_parse_error(r);
4226
4227                 if (arg_all)
4228                         printf("%s=[unprintable]\n", name);
4229         }
4230
4231         return 0;
4232 }
4233
4234 static int show_one(
4235                 const char *verb,
4236                 sd_bus *bus,
4237                 const char *path,
4238                 bool show_properties,
4239                 bool *new_line,
4240                 bool *ellipsized) {
4241
4242         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4243         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4244         UnitStatusInfo info = {};
4245         ExecStatusInfo *p;
4246         int r;
4247
4248         assert(path);
4249         assert(new_line);
4250
4251         log_debug("Showing one %s", path);
4252
4253         r = sd_bus_call_method(
4254                         bus,
4255                         "org.freedesktop.systemd1",
4256                         path,
4257                         "org.freedesktop.DBus.Properties",
4258                         "GetAll",
4259                         &error,
4260                         &reply,
4261                         "s", "");
4262         if (r < 0) {
4263                 log_error("Failed to get properties: %s", bus_error_message(&error, r));
4264                 return r;
4265         }
4266
4267         r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
4268         if (r < 0)
4269                 return bus_log_parse_error(r);
4270
4271         if (*new_line)
4272                 printf("\n");
4273
4274         *new_line = true;
4275
4276         while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
4277                 const char *name, *contents;
4278
4279                 r = sd_bus_message_read(reply, "s", &name);
4280                 if (r < 0)
4281                         return bus_log_parse_error(r);
4282
4283                 r = sd_bus_message_peek_type(reply, NULL, &contents);
4284                 if (r < 0)
4285                         return bus_log_parse_error(r);
4286
4287                 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, contents);
4288                 if (r < 0)
4289                         return bus_log_parse_error(r);
4290
4291                 if (show_properties)
4292                         r = print_property(name, reply, contents);
4293                 else
4294                         r = status_property(name, reply, &info, contents);
4295                 if (r < 0)
4296                         return r;
4297
4298                 r = sd_bus_message_exit_container(reply);
4299                 if (r < 0)
4300                         return bus_log_parse_error(r);
4301
4302                 r = sd_bus_message_exit_container(reply);
4303                 if (r < 0)
4304                         return bus_log_parse_error(r);
4305         }
4306         if (r < 0)
4307                 return bus_log_parse_error(r);
4308
4309         r = sd_bus_message_exit_container(reply);
4310         if (r < 0)
4311                 return bus_log_parse_error(r);
4312
4313         r = 0;
4314
4315         if (!show_properties) {
4316                 if (streq(verb, "help"))
4317                         show_unit_help(&info);
4318                 else
4319                         print_status_info(&info, ellipsized);
4320         }
4321
4322         strv_free(info.documentation);
4323         strv_free(info.dropin_paths);
4324         strv_free(info.listen);
4325
4326         if (!streq_ptr(info.active_state, "active") &&
4327             !streq_ptr(info.active_state, "reloading") &&
4328             streq(verb, "status")) {
4329                 /* According to LSB: "program not running" */
4330                 /* 0: program is running or service is OK
4331                  * 1: program is dead and /run PID file exists
4332                  * 2: program is dead and /run/lock lock file exists
4333                  * 3: program is not running
4334                  * 4: program or service status is unknown
4335                  */
4336                 if (info.pid_file && access(info.pid_file, F_OK) == 0)
4337                         r = 1;
4338                 else
4339                         r = 3;
4340         }
4341
4342         while ((p = info.exec)) {
4343                 LIST_REMOVE(exec, info.exec, p);
4344                 exec_status_info_free(p);
4345         }
4346
4347         return r;
4348 }
4349
4350 static int get_unit_dbus_path_by_pid(
4351                 sd_bus *bus,
4352                 uint32_t pid,
4353                 char **unit) {
4354
4355         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4356         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4357         char *u;
4358         int r;
4359
4360         r = sd_bus_call_method(
4361                         bus,
4362                         "org.freedesktop.systemd1",
4363                         "/org/freedesktop/systemd1",
4364                         "org.freedesktop.systemd1.Manager",
4365                         "GetUnitByPID",
4366                         &error,
4367                         &reply,
4368                         "u", pid);
4369         if (r < 0) {
4370                 log_error("Failed to get unit for PID "PID_FMT": %s", pid, bus_error_message(&error, r));
4371                 return r;
4372         }
4373
4374         r = sd_bus_message_read(reply, "o", &u);
4375         if (r < 0)
4376                 return bus_log_parse_error(r);
4377
4378         u = strdup(u);
4379         if (!u)
4380                 return log_oom();
4381
4382         *unit = u;
4383         return 0;
4384 }
4385
4386 static int show_all(
4387                 const char* verb,
4388                 sd_bus *bus,
4389                 bool show_properties,
4390                 bool *new_line,
4391                 bool *ellipsized) {
4392
4393         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4394         _cleanup_free_ UnitInfo *unit_infos = NULL;
4395         const UnitInfo *u;
4396         unsigned c;
4397         int r, ret = 0;
4398
4399         r = get_unit_list(bus, NULL, NULL, &unit_infos, 0, &reply);
4400         if (r < 0)
4401                 return r;
4402
4403         pager_open_if_enabled();
4404
4405         c = (unsigned) r;
4406
4407         qsort_safe(unit_infos, c, sizeof(UnitInfo), compare_unit_info);
4408
4409         for (u = unit_infos; u < unit_infos + c; u++) {
4410                 _cleanup_free_ char *p = NULL;
4411
4412                 p = unit_dbus_path_from_name(u->id);
4413                 if (!p)
4414                         return log_oom();
4415
4416                 r = show_one(verb, bus, p, show_properties, new_line, ellipsized);
4417                 if (r < 0)
4418                         return r;
4419                 else if (r > 0 && ret == 0)
4420                         ret = r;
4421         }
4422
4423         return ret;
4424 }
4425
4426 static int show_system_status(sd_bus *bus) {
4427         char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], since2[FORMAT_TIMESTAMP_MAX];
4428         _cleanup_free_ char *hn = NULL;
4429         struct machine_info mi = {};
4430         const char *on, *off;
4431         int r;
4432
4433         hn = gethostname_malloc();
4434         if (!hn)
4435                 return log_oom();
4436
4437         r = bus_map_all_properties(bus, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map, &mi);
4438         if (r < 0) {
4439                 log_error("Failed to read server status: %s", strerror(-r));
4440                 return r;
4441         }
4442
4443         if (streq_ptr(mi.state, "degraded")) {
4444                 on = ansi_highlight_red();
4445                 off = ansi_highlight_off();
4446         } else if (!streq_ptr(mi.state, "running")) {
4447                 on = ansi_highlight_yellow();
4448                 off = ansi_highlight_off();
4449         } else
4450                 on = off = "";
4451
4452         printf("%s%s%s %s\n", on, draw_special_char(DRAW_BLACK_CIRCLE), off, arg_host ? arg_host : hn);
4453
4454         printf("    State: %s%s%s\n",
4455                on, strna(mi.state), off);
4456
4457         printf("     Jobs: %u queued\n", mi.n_jobs);
4458         printf("   Failed: %u units\n", mi.n_failed_units);
4459
4460         printf("    Since: %s; %s\n",
4461                format_timestamp(since2, sizeof(since2), mi.timestamp),
4462                format_timestamp_relative(since1, sizeof(since1), mi.timestamp));
4463
4464         printf("   CGroup: %s\n", mi.control_group ?: "/");
4465         if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_CONTAINER) {
4466                 int flags =
4467                         arg_all * OUTPUT_SHOW_ALL |
4468                         (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
4469                         on_tty() * OUTPUT_COLOR |
4470                         !arg_quiet * OUTPUT_WARN_CUTOFF |
4471                         arg_full * OUTPUT_FULL_WIDTH;
4472
4473                 static const char prefix[] = "           ";
4474                 unsigned c;
4475
4476                 c = columns();
4477                 if (c > sizeof(prefix) - 1)
4478                         c -= sizeof(prefix) - 1;
4479                 else
4480                         c = 0;
4481
4482                 show_cgroup(SYSTEMD_CGROUP_CONTROLLER, strempty(mi.control_group), prefix, c, false, flags);
4483         }
4484
4485         free(mi.state);
4486         free(mi.control_group);
4487
4488         return 0;
4489 }
4490
4491 static int show(sd_bus *bus, char **args) {
4492         bool show_properties, show_status, new_line = false;
4493         bool ellipsized = false;
4494         int r, ret = 0;
4495
4496         assert(bus);
4497         assert(args);
4498
4499         show_properties = streq(args[0], "show");
4500         show_status = streq(args[0], "status");
4501
4502         if (show_properties)
4503                 pager_open_if_enabled();
4504
4505         /* If no argument is specified inspect the manager itself */
4506
4507         if (show_properties && strv_length(args) <= 1)
4508                 return show_one(args[0], bus, "/org/freedesktop/systemd1", show_properties, &new_line, &ellipsized);
4509
4510         if (show_status && strv_length(args) <= 1) {
4511
4512                 pager_open_if_enabled();
4513                 show_system_status(bus);
4514                 new_line = true;
4515
4516                 if (arg_all)
4517                         ret = show_all(args[0], bus, false, &new_line, &ellipsized);
4518         } else {
4519                 _cleanup_free_ char **patterns = NULL;
4520                 char **name;
4521
4522                 STRV_FOREACH(name, args + 1) {
4523                         _cleanup_free_ char *unit = NULL;
4524                         uint32_t id;
4525
4526                         if (safe_atou32(*name, &id) < 0) {
4527                                 if (strv_push(&patterns, *name) < 0)
4528                                         return log_oom();
4529
4530                                 continue;
4531                         } else if (show_properties) {
4532                                 /* Interpret as job id */
4533                                 if (asprintf(&unit, "/org/freedesktop/systemd1/job/%u", id) < 0)
4534                                         return log_oom();
4535
4536                         } else {
4537                                 /* Interpret as PID */
4538                                 r = get_unit_dbus_path_by_pid(bus, id, &unit);
4539                                 if (r < 0) {
4540                                         ret = r;
4541                                         continue;
4542                                 }
4543                         }
4544
4545                         r = show_one(args[0], bus, unit, show_properties,
4546                                      &new_line, &ellipsized);
4547                         if (r < 0)
4548                                 return r;
4549                         else if (r > 0 && ret == 0)
4550                                 ret = r;
4551                 }
4552
4553                 if (!strv_isempty(patterns)) {
4554                         _cleanup_strv_free_ char **names = NULL;
4555
4556                         r = expand_names(bus, patterns, NULL, &names);
4557                         if (r < 0)
4558                                 log_error("Failed to expand names: %s", strerror(-r));
4559
4560                         STRV_FOREACH(name, names) {
4561                                 _cleanup_free_ char *unit;
4562
4563                                 unit = unit_dbus_path_from_name(*name);
4564                                 if (!unit)
4565                                         return log_oom();
4566
4567                                 r = show_one(args[0], bus, unit, show_properties,
4568                                              &new_line, &ellipsized);
4569                                 if (r < 0)
4570                                         return r;
4571                                 else if (r > 0 && ret == 0)
4572                                         ret = r;
4573                         }
4574                 }
4575         }
4576
4577         if (ellipsized && !arg_quiet)
4578                 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
4579
4580         return ret;
4581 }
4582
4583 static int cat(sd_bus *bus, char **args) {
4584         _cleanup_strv_free_ char **names = NULL;
4585         char **name;
4586         bool first = true;
4587         int r = 0;
4588
4589         assert(bus);
4590         assert(args);
4591
4592         r = expand_names(bus, args + 1, NULL, &names);
4593         if (r < 0)
4594                 log_error("Failed to expand names: %s", strerror(-r));
4595
4596         pager_open_if_enabled();
4597
4598         STRV_FOREACH(name, names) {
4599                 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4600                 _cleanup_strv_free_ char **dropin_paths = NULL;
4601                 _cleanup_free_ char *fragment_path = NULL, *unit = NULL;
4602                 char **path;
4603
4604                 unit = unit_dbus_path_from_name(*name);
4605                 if (!unit)
4606                         return log_oom();
4607
4608                 if (need_daemon_reload(bus, *name) > 0)
4609                         log_warning("Unit file of %s changed on disk. Run 'systemctl%s daemon-reload'.",
4610                                     *name, arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
4611
4612                 r = sd_bus_get_property_string(
4613                                 bus,
4614                                 "org.freedesktop.systemd1",
4615                                 unit,
4616                                 "org.freedesktop.systemd1.Unit",
4617                                 "FragmentPath",
4618                                 &error,
4619                                 &fragment_path);
4620                 if (r < 0) {
4621                         log_warning("Failed to get FragmentPath: %s", bus_error_message(&error, r));
4622                         continue;
4623                 }
4624
4625                 r = sd_bus_get_property_strv(
4626                                 bus,
4627                                 "org.freedesktop.systemd1",
4628                                 unit,
4629                                 "org.freedesktop.systemd1.Unit",
4630                                 "DropInPaths",
4631                                 &error,
4632                                 &dropin_paths);
4633                 if (r < 0) {
4634                         log_warning("Failed to get DropInPaths: %s", bus_error_message(&error, r));
4635                         continue;
4636                 }
4637
4638                 if (first)
4639                         first = false;
4640                 else
4641                         puts("");
4642
4643                 if (!isempty(fragment_path)) {
4644                         printf("%s# %s%s\n",
4645                                ansi_highlight_blue(),
4646                                fragment_path,
4647                                ansi_highlight_off());
4648                         fflush(stdout);
4649
4650                         r = sendfile_full(STDOUT_FILENO, fragment_path);
4651                         if (r < 0) {
4652                                 log_warning("Failed to cat %s: %s", fragment_path, strerror(-r));
4653                                 continue;
4654                         }
4655                 }
4656
4657                 STRV_FOREACH(path, dropin_paths) {
4658                         printf("%s%s# %s%s\n",
4659                                isempty(fragment_path) && path == dropin_paths ? "" : "\n",
4660                                ansi_highlight_blue(),
4661                                *path,
4662                                ansi_highlight_off());
4663                         fflush(stdout);
4664
4665                         r = sendfile_full(STDOUT_FILENO, *path);
4666                         if (r < 0) {
4667                                 log_warning("Failed to cat %s: %s", *path, strerror(-r));
4668                                 continue;
4669                         }
4670                 }
4671         }
4672
4673         return r < 0 ? r : 0;
4674 }
4675
4676 static int set_property(sd_bus *bus, char **args) {
4677         _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4678         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4679         _cleanup_free_ char *n = NULL;
4680         char **i;
4681         int r;
4682
4683         r = sd_bus_message_new_method_call(
4684                         bus,
4685                         &m,
4686                         "org.freedesktop.systemd1",
4687                         "/org/freedesktop/systemd1",
4688                         "org.freedesktop.systemd1.Manager",
4689                         "SetUnitProperties");
4690         if (r < 0)
4691                 return bus_log_create_error(r);
4692
4693         r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4694         if (r < 0)
4695                 return bus_log_create_error(r);
4696
4697         n = unit_name_mangle(args[1], MANGLE_NOGLOB);
4698         if (!n)
4699                 return log_oom();
4700
4701         r = sd_bus_message_append(m, "sb", n, arg_runtime);
4702         if (r < 0)
4703                 return bus_log_create_error(r);
4704
4705         r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, "(sv)");
4706         if (r < 0)
4707                 return bus_log_create_error(r);
4708
4709         STRV_FOREACH(i, args + 2) {
4710                 r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv");
4711                 if (r < 0)
4712                         return bus_log_create_error(r);
4713
4714                 r = bus_append_unit_property_assignment(m, *i);
4715                 if (r < 0)
4716                         return r;
4717
4718                 r = sd_bus_message_close_container(m);
4719                 if (r < 0)
4720                         return bus_log_create_error(r);
4721         }
4722
4723         r = sd_bus_message_close_container(m);
4724         if (r < 0)
4725                 return bus_log_create_error(r);
4726
4727         r = sd_bus_call(bus, m, 0, &error, NULL);
4728         if (r < 0) {
4729                 log_error("Failed to set unit properties on %s: %s", n, bus_error_message(&error, r));
4730                 return r;
4731         }
4732
4733         return 0;
4734 }
4735
4736 static int snapshot(sd_bus *bus, char **args) {
4737         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4738         _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
4739         _cleanup_free_ char *n = NULL, *id = NULL;
4740         const char *path;
4741         int r;
4742
4743         if (strv_length(args) > 1)
4744                 n = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".snapshot");
4745         else
4746                 n = strdup("");
4747         if (!n)
4748                 return log_oom();
4749
4750         r = sd_bus_message_new_method_call(
4751                         bus,
4752                         &m,
4753                         "org.freedesktop.systemd1",
4754                         "/org/freedesktop/systemd1",
4755                         "org.freedesktop.systemd1.Manager",
4756                         "CreateSnapshot");
4757         if (r < 0)
4758                 return bus_log_create_error(r);
4759
4760         r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4761         if (r < 0)
4762                 return bus_log_create_error(r);
4763
4764         r = sd_bus_message_append(m, "sb", n, false);
4765         if (r < 0)
4766                 return bus_log_create_error(r);
4767
4768         r = sd_bus_call(bus, m, 0, &error, &reply);
4769         if (r < 0) {
4770                 log_error("Failed to create snapshot: %s", bus_error_message(&error, r));
4771                 return r;
4772         }
4773
4774         r = sd_bus_message_read(reply, "o", &path);
4775         if (r < 0)
4776                 return bus_log_parse_error(r);
4777
4778         r = sd_bus_get_property_string(
4779                         bus,
4780                         "org.freedesktop.systemd1",
4781                         path,
4782                         "org.freedesktop.systemd1.Unit",
4783                         "Id",
4784                         &error,
4785                         &id);
4786         if (r < 0) {
4787                 log_error("Failed to get ID of snapshot: %s", bus_error_message(&error, r));
4788                 return r;
4789         }
4790
4791         if (!arg_quiet)
4792                 puts(id);
4793
4794         return 0;
4795 }
4796
4797 static int delete_snapshot(sd_bus *bus, char **args) {
4798         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4799         _cleanup_strv_free_ char **names = NULL;
4800         char **name;
4801         int r;
4802
4803         assert(args);
4804
4805         r = expand_names(bus, args + 1, ".snapshot", &names);
4806         if (r < 0)
4807                 log_error("Failed to expand names: %s", strerror(-r));
4808
4809         STRV_FOREACH(name, names) {
4810                 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4811                 int q;
4812
4813                 q = sd_bus_message_new_method_call(
4814                                 bus,
4815                                 &m,
4816                                 "org.freedesktop.systemd1",
4817                                 "/org/freedesktop/systemd1",
4818                                 "org.freedesktop.systemd1.Manager",
4819                                 "RemoveSnapshot");
4820                 if (q < 0)
4821                         return bus_log_create_error(q);
4822
4823                 q = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4824                 if (q < 0)
4825                         return bus_log_create_error(q);
4826
4827                 q = sd_bus_message_append(m, "s", *name);
4828                 if (q < 0)
4829                         return bus_log_create_error(q);
4830
4831                 q = sd_bus_call(bus, m, 0, &error, NULL);
4832                 if (q < 0) {
4833                         log_error("Failed to remove snapshot %s: %s", *name, bus_error_message(&error, q));
4834                         if (r == 0)
4835                                 r = q;
4836                 }
4837         }
4838
4839         return r;
4840 }
4841
4842 static int daemon_reload(sd_bus *bus, char **args) {
4843         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4844         _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4845         const char *method;
4846         int r;
4847
4848         if (arg_action == ACTION_RELOAD)
4849                 method = "Reload";
4850         else if (arg_action == ACTION_REEXEC)
4851                 method = "Reexecute";
4852         else {
4853                 assert(arg_action == ACTION_SYSTEMCTL);
4854
4855                 method =
4856                         streq(args[0], "clear-jobs")    ||
4857                         streq(args[0], "cancel")        ? "ClearJobs" :
4858                         streq(args[0], "daemon-reexec") ? "Reexecute" :
4859                         streq(args[0], "reset-failed")  ? "ResetFailed" :
4860                         streq(args[0], "halt")          ? "Halt" :
4861                         streq(args[0], "poweroff")      ? "PowerOff" :
4862                         streq(args[0], "reboot")        ? "Reboot" :
4863                         streq(args[0], "kexec")         ? "KExec" :
4864                         streq(args[0], "exit")          ? "Exit" :
4865                                     /* "daemon-reload" */ "Reload";
4866         }
4867
4868         r = sd_bus_message_new_method_call(
4869                         bus,
4870                         &m,
4871                         "org.freedesktop.systemd1",
4872                         "/org/freedesktop/systemd1",
4873                         "org.freedesktop.systemd1.Manager",
4874                         method);
4875         if (r < 0)
4876                 return bus_log_create_error(r);
4877
4878         r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4879         if (r < 0)
4880                 return bus_log_create_error(r);
4881
4882         r = sd_bus_call(bus, m, 0, &error, NULL);
4883         if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
4884                 /* There's always a fallback possible for
4885                  * legacy actions. */
4886                 r = -EADDRNOTAVAIL;
4887         else if ((r == -ETIMEDOUT || r == -ECONNRESET) && streq(method, "Reexecute"))
4888                 /* On reexecution, we expect a disconnect, not a
4889                  * reply */
4890                 r = 0;
4891         else if (r < 0)
4892                 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
4893
4894         return r < 0 ? r : 0;
4895 }
4896
4897 static int reset_failed(sd_bus *bus, char **args) {
4898         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4899         _cleanup_strv_free_ char **names = NULL;
4900         char **name;
4901         int r, q;
4902
4903         if (strv_length(args) <= 1)
4904                 return daemon_reload(bus, args);
4905
4906         r = expand_names(bus, args + 1, NULL, &names);
4907         if (r < 0)
4908                 log_error("Failed to expand names: %s", strerror(-r));
4909
4910         STRV_FOREACH(name, names) {
4911                 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4912
4913                 q = sd_bus_message_new_method_call(
4914                                 bus,
4915                                 &m,
4916                                 "org.freedesktop.systemd1",
4917                                 "/org/freedesktop/systemd1",
4918                                 "org.freedesktop.systemd1.Manager",
4919                                 "ResetFailedUnit");
4920                 if (q < 0)
4921                         return bus_log_create_error(q);
4922
4923                 q = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4924                 if (q < 0)
4925                         return bus_log_create_error(q);
4926
4927                 q = sd_bus_message_append(m, "s", *name);
4928                 if (q < 0)
4929                         return bus_log_create_error(q);
4930
4931                 q = sd_bus_call(bus, m, 0, &error, NULL);
4932                 if (q < 0) {
4933                         log_error("Failed to reset failed state of unit %s: %s", *name, bus_error_message(&error, q));
4934                         if (r == 0)
4935                                 r = q;
4936                 }
4937         }
4938
4939         return r;
4940 }
4941
4942 static int show_environment(sd_bus *bus, char **args) {
4943         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4944         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4945         const char *text;
4946         int r;
4947
4948         pager_open_if_enabled();
4949
4950         r = sd_bus_get_property(
4951                         bus,
4952                         "org.freedesktop.systemd1",
4953                         "/org/freedesktop/systemd1",
4954                         "org.freedesktop.systemd1.Manager",
4955                         "Environment",
4956                         &error,
4957                         &reply,
4958                         "as");
4959         if (r < 0) {
4960                 log_error("Failed to get environment: %s", bus_error_message(&error, r));
4961                 return r;
4962         }
4963
4964         r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "s");
4965         if (r < 0)
4966                 return bus_log_parse_error(r);
4967
4968         while ((r = sd_bus_message_read_basic(reply, SD_BUS_TYPE_STRING, &text)) > 0)
4969                 puts(text);
4970         if (r < 0)
4971                 return bus_log_parse_error(r);
4972
4973         r = sd_bus_message_exit_container(reply);
4974         if (r < 0)
4975                 return bus_log_parse_error(r);
4976
4977         return 0;
4978 }
4979
4980 static int switch_root(sd_bus *bus, char **args) {
4981         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4982         _cleanup_free_ char *cmdline_init = NULL;
4983         const char *root, *init;
4984         unsigned l;
4985         int r;
4986
4987         l = strv_length(args);
4988         if (l < 2 || l > 3) {
4989                 log_error("Wrong number of arguments.");
4990                 return -EINVAL;
4991         }
4992
4993         root = args[1];
4994
4995         if (l >= 3)
4996                 init = args[2];
4997         else {
4998                 r = parse_env_file("/proc/cmdline", WHITESPACE,
4999                                    "init", &cmdline_init,
5000                                    NULL);
5001                 if (r < 0)
5002                         log_debug("Failed to parse /proc/cmdline: %s", strerror(-r));
5003
5004                 init = cmdline_init;
5005         }
5006
5007         if (isempty(init))
5008                 init = NULL;
5009
5010         if (init) {
5011                 const char *root_systemd_path = NULL, *root_init_path = NULL;
5012
5013                 root_systemd_path = strappenda(root, "/" SYSTEMD_BINARY_PATH);
5014                 root_init_path = strappenda(root, "/", init);
5015
5016                 /* If the passed init is actually the same as the
5017                  * systemd binary, then let's suppress it. */
5018                 if (files_same(root_init_path, root_systemd_path) > 0)
5019                         init = NULL;
5020         }
5021
5022         log_debug("Switching root - root: %s; init: %s", root, strna(init));
5023
5024         r = sd_bus_call_method(
5025                         bus,
5026                         "org.freedesktop.systemd1",
5027                         "/org/freedesktop/systemd1",
5028                         "org.freedesktop.systemd1.Manager",
5029                         "SwitchRoot",
5030                         &error,
5031                         NULL,
5032                         "ss", root, init);
5033         if (r < 0) {
5034                 log_error("Failed to switch root: %s", bus_error_message(&error, r));
5035                 return r;
5036         }
5037
5038         return 0;
5039 }
5040
5041 static int set_environment(sd_bus *bus, char **args) {
5042         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5043         _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
5044         const char *method;
5045         int r;
5046
5047         assert(bus);
5048         assert(args);
5049
5050         method = streq(args[0], "set-environment")
5051                 ? "SetEnvironment"
5052                 : "UnsetEnvironment";
5053
5054         r = sd_bus_message_new_method_call(
5055                         bus,
5056                         &m,
5057                         "org.freedesktop.systemd1",
5058                         "/org/freedesktop/systemd1",
5059                         "org.freedesktop.systemd1.Manager",
5060                         method);
5061         if (r < 0)
5062                 return bus_log_create_error(r);
5063
5064         r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5065         if (r < 0)
5066                 return bus_log_create_error(r);
5067
5068         r = sd_bus_message_append_strv(m, args + 1);
5069         if (r < 0)
5070                 return bus_log_create_error(r);
5071
5072         r = sd_bus_call(bus, m, 0, &error, NULL);
5073         if (r < 0) {
5074                 log_error("Failed to set environment: %s", bus_error_message(&error, r));
5075                 return r;
5076         }
5077
5078         return 0;
5079 }
5080
5081 static int import_environment(sd_bus *bus, char **args) {
5082         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5083         _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
5084         int r;
5085
5086         assert(bus);
5087         assert(args);
5088
5089         r = sd_bus_message_new_method_call(
5090                         bus,
5091                         &m,
5092                         "org.freedesktop.systemd1",
5093                         "/org/freedesktop/systemd1",
5094                         "org.freedesktop.systemd1.Manager",
5095                         "SetEnvironment");
5096         if (r < 0)
5097                 return bus_log_create_error(r);
5098
5099         r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5100         if (r < 0)
5101                 return bus_log_create_error(r);
5102
5103         if (strv_isempty(args + 1))
5104                 r = sd_bus_message_append_strv(m, environ);
5105         else {
5106                 char **a, **b;
5107
5108                 r = sd_bus_message_open_container(m, 'a', "s");
5109                 if (r < 0)
5110                         return bus_log_create_error(r);
5111
5112                 STRV_FOREACH(a, args + 1) {
5113
5114                         if (!env_name_is_valid(*a)) {
5115                                 log_error("Not a valid environment variable name: %s", *a);
5116                                 return -EINVAL;
5117                         }
5118
5119                         STRV_FOREACH(b, environ) {
5120                                 const char *eq;
5121
5122                                 eq = startswith(*b, *a);
5123                                 if (eq && *eq == '=') {
5124
5125                                         r = sd_bus_message_append(m, "s", *b);
5126                                         if (r < 0)
5127                                                 return bus_log_create_error(r);
5128
5129                                         break;
5130                                 }
5131                         }
5132                 }
5133
5134                 r = sd_bus_message_close_container(m);
5135         }
5136         if (r < 0)
5137                 return bus_log_create_error(r);
5138
5139         r = sd_bus_call(bus, m, 0, &error, NULL);
5140         if (r < 0) {
5141                 log_error("Failed to import environment: %s", bus_error_message(&error, r));
5142                 return r;
5143         }
5144
5145         return 0;
5146 }
5147
5148 static int enable_sysv_units(const char *verb, char **args) {
5149         int r = 0;
5150
5151 #if defined(HAVE_SYSV_COMPAT) && defined(HAVE_CHKCONFIG)
5152         unsigned f = 1, t = 1;
5153         _cleanup_lookup_paths_free_ LookupPaths paths = {};
5154
5155         if (arg_scope != UNIT_FILE_SYSTEM)
5156                 return 0;
5157
5158         if (!streq(verb, "enable") &&
5159             !streq(verb, "disable") &&
5160             !streq(verb, "is-enabled"))
5161                 return 0;
5162
5163         /* Processes all SysV units, and reshuffles the array so that
5164          * afterwards only the native units remain */
5165
5166         r = lookup_paths_init(&paths, SYSTEMD_SYSTEM, false, arg_root, NULL, NULL, NULL);
5167         if (r < 0)
5168                 return r;
5169
5170         r = 0;
5171         for (f = 0; args[f]; f++) {
5172                 const char *name;
5173                 _cleanup_free_ char *p = NULL, *q = NULL, *l = NULL;
5174                 bool found_native = false, found_sysv;
5175                 unsigned c = 1;
5176                 const char *argv[6] = { "/sbin/chkconfig", NULL, NULL, NULL, NULL };
5177                 char **k;
5178                 int j;
5179                 pid_t pid;
5180                 siginfo_t status;
5181
5182                 name = args[f];
5183
5184                 if (!endswith(name, ".service"))
5185                         continue;
5186
5187                 if (path_is_absolute(name))
5188                         continue;
5189
5190                 STRV_FOREACH(k, paths.unit_path) {
5191                         _cleanup_free_ char *path = NULL;
5192
5193                         path = path_join(arg_root, *k, name);
5194                         if (!path)
5195                                 return log_oom();
5196
5197                         found_native = access(path, F_OK) >= 0;
5198                         if (found_native)
5199                                 break;
5200                 }
5201
5202                 if (found_native)
5203                         continue;
5204
5205                 p = path_join(arg_root, SYSTEM_SYSVINIT_PATH, name);
5206                 if (!p)
5207                         return log_oom();
5208
5209                 p[strlen(p) - strlen(".service")] = 0;
5210                 found_sysv = access(p, F_OK) >= 0;
5211                 if (!found_sysv)
5212                         continue;
5213
5214                 /* Mark this entry, so that we don't try enabling it as native unit */
5215                 args[f] = (char*) "";
5216
5217                 log_info("%s is not a native service, redirecting to /sbin/chkconfig.", name);
5218
5219                 if (!isempty(arg_root))
5220                         argv[c++] = q = strappend("--root=", arg_root);
5221
5222                 argv[c++] = basename(p);
5223                 argv[c++] =
5224                         streq(verb, "enable") ? "on" :
5225                         streq(verb, "disable") ? "off" : "--level=5";
5226                 argv[c] = NULL;
5227
5228                 l = strv_join((char**)argv, " ");
5229                 if (!l)
5230                         return log_oom();
5231
5232                 log_info("Executing %s", l);
5233
5234                 pid = fork();
5235                 if (pid < 0) {
5236                         log_error("Failed to fork: %m");
5237                         return -errno;
5238                 } else if (pid == 0) {
5239                         /* Child */
5240
5241                         execv(argv[0], (char**) argv);
5242                         _exit(EXIT_FAILURE);
5243                 }
5244
5245                 j = wait_for_terminate(pid, &status);
5246                 if (j < 0) {
5247                         log_error("Failed to wait for child: %s", strerror(-r));
5248                         return j;
5249                 }
5250
5251                 if (status.si_code == CLD_EXITED) {
5252                         if (streq(verb, "is-enabled")) {
5253                                 if (status.si_status == 0) {
5254                                         if (!arg_quiet)
5255                                                 puts("enabled");
5256                                         r = 1;
5257                                 } else {
5258                                         if (!arg_quiet)
5259                                                 puts("disabled");
5260                                 }
5261
5262                         } else if (status.si_status != 0)
5263                                 return -EINVAL;
5264                 } else
5265                         return -EPROTO;
5266         }
5267
5268         /* Drop all SysV units */
5269         for (f = 0, t = 0; args[f]; f++) {
5270
5271                 if (isempty(args[f]))
5272                         continue;
5273
5274                 args[t++] = args[f];
5275         }
5276
5277         args[t] = NULL;
5278
5279 #endif
5280         return r;
5281 }
5282
5283 static int mangle_names(char **original_names, char ***mangled_names) {
5284         char **i, **l, **name;
5285
5286         l = new(char*, strv_length(original_names) + 1);
5287         if (!l)
5288                 return log_oom();
5289
5290         i = l;
5291         STRV_FOREACH(name, original_names) {
5292
5293                 /* When enabling units qualified path names are OK,
5294                  * too, hence allow them explicitly. */
5295
5296                 if (is_path(*name))
5297                         *i = strdup(*name);
5298                 else
5299                         *i = unit_name_mangle(*name, MANGLE_NOGLOB);
5300
5301                 if (!*i) {
5302                         strv_free(l);
5303                         return log_oom();
5304                 }
5305
5306                 i++;
5307         }
5308
5309         *i = NULL;
5310         *mangled_names = l;
5311
5312         return 0;
5313 }
5314
5315 static int enable_unit(sd_bus *bus, char **args) {
5316         _cleanup_strv_free_ char **names = NULL;
5317         const char *verb = args[0];
5318         UnitFileChange *changes = NULL;
5319         unsigned n_changes = 0;
5320         int carries_install_info = -1;
5321         int r;
5322
5323         if (!args[1])
5324                 return 0;
5325
5326         r = mangle_names(args+1, &names);
5327         if (r < 0)
5328                 return r;
5329
5330         r = enable_sysv_units(verb, names);
5331         if (r < 0)
5332                 return r;
5333
5334         /* If the operation was fully executed by the SysV compat,
5335          * let's finish early */
5336         if (strv_isempty(names))
5337                 return 0;
5338
5339         if (!bus || avoid_bus()) {
5340                 if (streq(verb, "enable")) {
5341                         r = unit_file_enable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5342                         carries_install_info = r;
5343                 } else if (streq(verb, "disable"))
5344                         r = unit_file_disable(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
5345                 else if (streq(verb, "reenable")) {
5346                         r = unit_file_reenable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5347                         carries_install_info = r;
5348                 } else if (streq(verb, "link"))
5349                         r = unit_file_link(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5350                 else if (streq(verb, "preset")) {
5351                         r = unit_file_preset(arg_scope, arg_runtime, arg_root, names, arg_preset_mode, arg_force, &changes, &n_changes);
5352                         carries_install_info = r;
5353                 } else if (streq(verb, "mask"))
5354                         r = unit_file_mask(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5355                 else if (streq(verb, "unmask"))
5356                         r = unit_file_unmask(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
5357                 else
5358                         assert_not_reached("Unknown verb");
5359
5360                 if (r < 0) {
5361                         log_error("Operation failed: %s", strerror(-r));
5362                         goto finish;
5363                 }
5364
5365                 if (!arg_quiet)
5366                         dump_unit_file_changes(changes, n_changes);
5367
5368                 r = 0;
5369         } else {
5370                 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
5371                 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5372                 int expect_carries_install_info = false;
5373                 bool send_force = true, send_preset_mode = false;
5374                 const char *method;
5375
5376                 if (streq(verb, "enable")) {
5377                         method = "EnableUnitFiles";
5378                         expect_carries_install_info = true;
5379                 } else if (streq(verb, "disable")) {
5380                         method = "DisableUnitFiles";
5381                         send_force = false;
5382                 } else if (streq(verb, "reenable")) {
5383                         method = "ReenableUnitFiles";
5384                         expect_carries_install_info = true;
5385                 } else if (streq(verb, "link"))
5386                         method = "LinkUnitFiles";
5387                 else if (streq(verb, "preset")) {
5388
5389                         if (arg_preset_mode != UNIT_FILE_PRESET_FULL) {
5390                                 method = "PresetUnitFilesWithMode";
5391                                 send_preset_mode = true;
5392                         } else
5393                                 method = "PresetUnitFiles";
5394
5395                         expect_carries_install_info = true;
5396                 } else if (streq(verb, "mask"))
5397                         method = "MaskUnitFiles";
5398                 else if (streq(verb, "unmask")) {
5399                         method = "UnmaskUnitFiles";
5400                         send_force = false;
5401                 } else
5402                         assert_not_reached("Unknown verb");
5403
5404                 r = sd_bus_message_new_method_call(
5405                                 bus,
5406                                 &m,
5407                                 "org.freedesktop.systemd1",
5408                                 "/org/freedesktop/systemd1",
5409                                 "org.freedesktop.systemd1.Manager",
5410                                 method);
5411                 if (r < 0)
5412                         return bus_log_create_error(r);
5413
5414                 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5415                 if (r < 0)
5416                         return bus_log_create_error(r);
5417
5418                 r = sd_bus_message_append_strv(m, names);
5419                 if (r < 0)
5420                         return bus_log_create_error(r);
5421
5422                 if (send_preset_mode) {
5423                         r = sd_bus_message_append(m, "s", unit_file_preset_mode_to_string(arg_preset_mode));
5424                         if (r < 0)
5425                                 return bus_log_create_error(r);
5426                 }
5427
5428                 r = sd_bus_message_append(m, "b", arg_runtime);
5429                 if (r < 0)
5430                         return bus_log_create_error(r);
5431
5432                 if (send_force) {
5433                         r = sd_bus_message_append(m, "b", arg_force);
5434                         if (r < 0)
5435                                 return bus_log_create_error(r);
5436                 }
5437
5438                 r = sd_bus_call(bus, m, 0, &error, &reply);
5439                 if (r < 0) {
5440                         log_error("Failed to execute operation: %s", bus_error_message(&error, r));
5441                         return r;
5442                 }
5443
5444                 if (expect_carries_install_info) {
5445                         r = sd_bus_message_read(reply, "b", &carries_install_info);
5446                         if (r < 0)
5447                                 return bus_log_parse_error(r);
5448                 }
5449
5450                 r = deserialize_and_dump_unit_file_changes(reply);
5451                 if (r < 0)
5452                         return r;
5453
5454                 /* Try to reload if enabled */
5455                 if (!arg_no_reload)
5456                         r = daemon_reload(bus, args);
5457                 else
5458                         r = 0;
5459         }
5460
5461         if (carries_install_info == 0)
5462                 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
5463                             "using systemctl.\n"
5464                             "Possible reasons for having this kind of units are:\n"
5465                             "1) A unit may be statically enabled by being symlinked from another unit's\n"
5466                             "   .wants/ or .requires/ directory.\n"
5467                             "2) A unit's purpose may be to act as a helper for some other unit which has\n"
5468                             "   a requirement dependency on it.\n"
5469                             "3) A unit may be started when needed via activation (socket, path, timer,\n"
5470                             "   D-Bus, udev, scripted systemctl call, ...).\n");
5471
5472 finish:
5473         unit_file_changes_free(changes, n_changes);
5474
5475         return r;
5476 }
5477
5478 static int add_dependency(sd_bus *bus, char **args) {
5479         _cleanup_strv_free_ char **names = NULL;
5480         _cleanup_free_ char *target = NULL;
5481         const char *verb = args[0];
5482         UnitDependency dep;
5483         int r = 0;
5484
5485         if (!args[1])
5486                 return 0;
5487
5488         target = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".target");
5489         if (!target)
5490                 return log_oom();
5491
5492         r = mangle_names(args+2, &names);
5493         if (r < 0)
5494                 return r;
5495
5496         if (streq(verb, "add-wants"))
5497                 dep = UNIT_WANTS;
5498         else if (streq(verb, "add-requires"))
5499                 dep = UNIT_REQUIRES;
5500         else
5501                 assert_not_reached("Unknown verb");
5502
5503         if (!bus || avoid_bus()) {
5504                 UnitFileChange *changes = NULL;
5505                 unsigned n_changes = 0;
5506
5507                 r = unit_file_add_dependency(arg_scope, arg_runtime, arg_root, names, target, dep, arg_force, &changes, &n_changes);
5508
5509                 if (r < 0) {
5510                         log_error("Can't add dependency: %s", strerror(-r));
5511                         return r;
5512                 }
5513
5514                 if (!arg_quiet)
5515                         dump_unit_file_changes(changes, n_changes);
5516
5517                 unit_file_changes_free(changes, n_changes);
5518
5519         } else {
5520                 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
5521                 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5522
5523                 r = sd_bus_message_new_method_call(
5524                                 bus,
5525                                 &m,
5526                                 "org.freedesktop.systemd1",
5527                                 "/org/freedesktop/systemd1",
5528                                 "org.freedesktop.systemd1.Manager",
5529                                 "AddDependencyUnitFiles");
5530                 if (r < 0)
5531                         return bus_log_create_error(r);
5532
5533                 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5534                 if (r < 0)
5535                         return bus_log_create_error(r);
5536
5537                 r = sd_bus_message_append_strv(m, names);
5538                 if (r < 0)
5539                         return bus_log_create_error(r);
5540
5541                 r = sd_bus_message_append(m, "ssbb", target, unit_dependency_to_string(dep), arg_runtime, arg_force);
5542                 if (r < 0)
5543                         return bus_log_create_error(r);
5544
5545                 r = sd_bus_call(bus, m, 0, &error, &reply);
5546                 if (r < 0) {
5547                         log_error("Failed to execute operation: %s", bus_error_message(&error, r));
5548                         return r;
5549                 }
5550
5551                 r = deserialize_and_dump_unit_file_changes(reply);
5552                 if (r < 0)
5553                         return r;
5554
5555                 if (!arg_no_reload)
5556                         r = daemon_reload(bus, args);
5557                 else
5558                         r = 0;
5559         }
5560
5561         return r;
5562 }
5563
5564 static int preset_all(sd_bus *bus, char **args) {
5565         UnitFileChange *changes = NULL;
5566         unsigned n_changes = 0;
5567         int r;
5568
5569         if (!bus || avoid_bus()) {
5570
5571                 r = unit_file_preset_all(arg_scope, arg_runtime, arg_root, arg_preset_mode, arg_force, &changes, &n_changes);
5572                 if (r < 0) {
5573                         log_error("Operation failed: %s", strerror(-r));
5574                         goto finish;
5575                 }
5576
5577                 if (!arg_quiet)
5578                         dump_unit_file_changes(changes, n_changes);
5579
5580                 r = 0;
5581
5582         } else {
5583                 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
5584                 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5585
5586                 r = sd_bus_message_new_method_call(
5587                                 bus,
5588                                 &m,
5589                                 "org.freedesktop.systemd1",
5590                                 "/org/freedesktop/systemd1",
5591                                 "org.freedesktop.systemd1.Manager",
5592                                 "PresetAllUnitFiles");
5593                 if (r < 0)
5594                         return bus_log_create_error(r);
5595
5596                 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5597                 if (r < 0)
5598                         return bus_log_create_error(r);
5599
5600                 r = sd_bus_message_append(
5601                                 m,
5602                                 "sbb",
5603                                 unit_file_preset_mode_to_string(arg_preset_mode),
5604                                 arg_runtime,
5605                                 arg_force);
5606                 if (r < 0)
5607                         return bus_log_create_error(r);
5608
5609                 r = sd_bus_call(bus, m, 0, &error, &reply);
5610                 if (r < 0) {
5611                         log_error("Failed to execute operation: %s", bus_error_message(&error, r));
5612                         return r;
5613                 }
5614
5615                 r = deserialize_and_dump_unit_file_changes(reply);
5616                 if (r < 0)
5617                         return r;
5618
5619                 if (!arg_no_reload)
5620                         r = daemon_reload(bus, args);
5621                 else
5622                         r = 0;
5623         }
5624
5625 finish:
5626         unit_file_changes_free(changes, n_changes);
5627
5628         return r;
5629 }
5630
5631 static int unit_is_enabled(sd_bus *bus, char **args) {
5632
5633         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5634         _cleanup_strv_free_ char **names = NULL;
5635         bool enabled;
5636         char **name;
5637         int r;
5638
5639         r = mangle_names(args+1, &names);
5640         if (r < 0)
5641                 return r;
5642
5643         r = enable_sysv_units(args[0], names);
5644         if (r < 0)
5645                 return r;
5646
5647         enabled = r > 0;
5648
5649         if (!bus || avoid_bus()) {
5650
5651                 STRV_FOREACH(name, names) {
5652                         UnitFileState state;
5653
5654                         state = unit_file_get_state(arg_scope, arg_root, *name);
5655                         if (state < 0) {
5656                                 log_error("Failed to get unit file state for %s: %s", *name, strerror(-state));
5657                                 return state;
5658                         }
5659
5660                         if (state == UNIT_FILE_ENABLED ||
5661                             state == UNIT_FILE_ENABLED_RUNTIME ||
5662                             state == UNIT_FILE_STATIC)
5663                                 enabled = true;
5664
5665                         if (!arg_quiet)
5666                                 puts(unit_file_state_to_string(state));
5667                 }
5668
5669         } else {
5670                 STRV_FOREACH(name, names) {
5671                         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
5672                         const char *s;
5673
5674                         r = sd_bus_call_method(
5675                                         bus,
5676                                         "org.freedesktop.systemd1",
5677                                         "/org/freedesktop/systemd1",
5678                                         "org.freedesktop.systemd1.Manager",
5679                                         "GetUnitFileState",
5680                                         &error,
5681                                         &reply,
5682                                         "s", *name);
5683                         if (r < 0) {
5684                                 log_error("Failed to get unit file state for %s: %s", *name, bus_error_message(&error, r));
5685                                 return r;
5686                         }
5687
5688                         r = sd_bus_message_read(reply, "s", &s);
5689                         if (r < 0)
5690                                 return bus_log_parse_error(r);
5691
5692                         if (streq(s, "enabled") ||
5693                             streq(s, "enabled-runtime") ||
5694                             streq(s, "static"))
5695                                 enabled = true;
5696
5697                         if (!arg_quiet)
5698                                 puts(s);
5699                 }
5700         }
5701
5702         return !enabled;
5703 }
5704
5705 static int is_system_running(sd_bus *bus, char **args) {
5706         _cleanup_free_ char *state = NULL;
5707         int r;
5708
5709         r = sd_bus_get_property_string(
5710                         bus,
5711                         "org.freedesktop.systemd1",
5712                         "/org/freedesktop/systemd1",
5713                         "org.freedesktop.systemd1.Manager",
5714                         "SystemState",
5715                         NULL,
5716                         &state);
5717         if (r < 0) {
5718                 if (!arg_quiet)
5719                         puts("unknown");
5720                 return 0;
5721         }
5722
5723         if (!arg_quiet)
5724                 puts(state);
5725
5726         return streq(state, "running") ? EXIT_SUCCESS : EXIT_FAILURE;
5727 }
5728
5729 static void systemctl_help(void) {
5730
5731         pager_open_if_enabled();
5732
5733         printf("%s [OPTIONS...] {COMMAND} ...\n\n"
5734                "Query or send control commands to the systemd manager.\n\n"
5735                "  -h --help           Show this help\n"
5736                "     --version        Show package version\n"
5737                "     --system         Connect to system manager\n"
5738                "     --user           Connect to user service manager\n"
5739                "  -H --host=[USER@]HOST\n"
5740                "                      Operate on remote host\n"
5741                "  -M --machine=CONTAINER\n"
5742                "                      Operate on local container\n"
5743                "  -t --type=TYPE      List only units of a particular type\n"
5744                "     --state=STATE    List only units with particular LOAD or SUB or ACTIVE state\n"
5745                "  -p --property=NAME  Show only properties by this name\n"
5746                "  -a --all            Show all loaded units/properties, including dead/empty\n"
5747                "                      ones. To list all units installed on the system, use\n"
5748                "                      the 'list-unit-files' command instead.\n"
5749                "  -l --full           Don't ellipsize unit names on output\n"
5750                "  -r --recursive      Show unit list of host and local containers\n"
5751                "     --reverse        Show reverse dependencies with 'list-dependencies'\n"
5752                "     --job-mode=MODE  Specify how to deal with already queued jobs, when\n"
5753                "                      queueing a new job\n"
5754                "     --show-types     When showing sockets, explicitly show their type\n"
5755                "  -i --ignore-inhibitors\n"
5756                "                      When shutting down or sleeping, ignore inhibitors\n"
5757                "     --kill-who=WHO   Who to send signal to\n"
5758                "  -s --signal=SIGNAL  Which signal to send\n"
5759                "  -q --quiet          Suppress output\n"
5760                "     --no-block       Do not wait until operation finished\n"
5761                "     --no-wall        Don't send wall message before halt/power-off/reboot\n"
5762                "     --no-reload      When enabling/disabling unit files, don't reload daemon\n"
5763                "                      configuration\n"
5764                "     --no-legend      Do not print a legend (column headers and hints)\n"
5765                "     --no-pager       Do not pipe output into a pager\n"
5766                "     --no-ask-password\n"
5767                "                      Do not ask for system passwords\n"
5768                "     --global         Enable/disable unit files globally\n"
5769                "     --runtime        Enable unit files only temporarily until next reboot\n"
5770                "  -f --force          When enabling unit files, override existing symlinks\n"
5771                "                      When shutting down, execute action immediately\n"
5772                "     --preset-mode=   Specifies whether fully apply presets, or only enable,\n"
5773                "                      or only disable\n"
5774                "     --root=PATH      Enable unit files in the specified root directory\n"
5775                "  -n --lines=INTEGER  Number of journal entries to show\n"
5776                "  -o --output=STRING  Change journal output mode (short, short-monotonic,\n"
5777                "                      verbose, export, json, json-pretty, json-sse, cat)\n"
5778                "     --plain          Print unit dependencies as a list instead of a tree\n\n"
5779                "Unit Commands:\n"
5780                "  list-units [PATTERN...]         List loaded units\n"
5781                "  list-sockets [PATTERN...]       List loaded sockets ordered by address\n"
5782                "  list-timers [PATTERN...]        List loaded timers ordered by next elapse\n"
5783                "  start NAME...                   Start (activate) one or more units\n"
5784                "  stop NAME...                    Stop (deactivate) one or more units\n"
5785                "  reload NAME...                  Reload one or more units\n"
5786                "  restart NAME...                 Start or restart one or more units\n"
5787                "  try-restart NAME...             Restart one or more units if active\n"
5788                "  reload-or-restart NAME...       Reload one or more units if possible,\n"
5789                "                                  otherwise start or restart\n"
5790                "  reload-or-try-restart NAME...   Reload one or more units if possible,\n"
5791                "                                  otherwise restart if active\n"
5792                "  isolate NAME                    Start one unit and stop all others\n"
5793                "  kill NAME...                    Send signal to processes of a unit\n"
5794                "  is-active PATTERN...            Check whether units are active\n"
5795                "  is-failed PATTERN...            Check whether units are failed\n"
5796                "  status [PATTERN...|PID...]      Show runtime status of one or more units\n"
5797                "  show [PATTERN...|JOB...]        Show properties of one or more\n"
5798                "                                  units/jobs or the manager\n"
5799                "  cat PATTERN...                  Show files and drop-ins of one or more units\n"
5800                "  set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
5801                "  help PATTERN...|PID...          Show manual for one or more units\n"
5802                "  reset-failed [PATTERN...]       Reset failed state for all, one, or more\n"
5803                "                                  units\n"
5804                "  list-dependencies [NAME]        Recursively show units which are required\n"
5805                "                                  or wanted by this unit or by which this\n"
5806                "                                  unit is required or wanted\n\n"
5807                "Unit File Commands:\n"
5808                "  list-unit-files [PATTERN...]    List installed unit files\n"
5809                "  enable NAME...                  Enable one or more unit files\n"
5810                "  disable NAME...                 Disable one or more unit files\n"
5811                "  reenable NAME...                Reenable one or more unit files\n"
5812                "  preset NAME...                  Enable/disable one or more unit files\n"
5813                "                                  based on preset configuration\n"
5814                "  preset-all                      Enable/disable all unit files based on\n"
5815                "                                  preset configuration\n"
5816                "  is-enabled NAME...              Check whether unit files are enabled\n\n"
5817                "  mask NAME...                    Mask one or more units\n"
5818                "  unmask NAME...                  Unmask one or more units\n"
5819                "  link PATH...                    Link one or more units files into\n"
5820                "                                  the search path\n"
5821                "  add-wants TARGET NAME...        Add 'Wants' dependency for the target\n"
5822                "                                  on specified one or more units\n"
5823                "  add-requires TARGET NAME...     Add 'Requires' dependency for the target\n"
5824                "                                  on specified one or more units\n"
5825                "  get-default                     Get the name of the default target\n"
5826                "  set-default NAME                Set the default target\n\n"
5827                "Machine Commands:\n"
5828                "  list-machines [PATTERN...]      List local containers and host\n\n"
5829                "Job Commands:\n"
5830                "  list-jobs [PATTERN...]          List jobs\n"
5831                "  cancel [JOB...]                 Cancel all, one, or more jobs\n\n"
5832                "Snapshot Commands:\n"
5833                "  snapshot [NAME]                 Create a snapshot\n"
5834                "  delete NAME...                  Remove one or more snapshots\n\n"
5835                "Environment Commands:\n"
5836                "  show-environment                Dump environment\n"
5837                "  set-environment NAME=VALUE...   Set one or more environment variables\n"
5838                "  unset-environment NAME...       Unset one or more environment variables\n"
5839                "  import-environment NAME...      Import all, one or more environment variables\n\n"
5840                "Manager Lifecycle Commands:\n"
5841                "  daemon-reload                   Reload systemd manager configuration\n"
5842                "  daemon-reexec                   Reexecute systemd manager\n\n"
5843                "System Commands:\n"
5844                "  is-system-running               Check whether system is fully running\n"
5845                "  default                         Enter system default mode\n"
5846                "  rescue                          Enter system rescue mode\n"
5847                "  emergency                       Enter system emergency mode\n"
5848                "  halt                            Shut down and halt the system\n"
5849                "  poweroff                        Shut down and power-off the system\n"
5850                "  reboot [ARG]                    Shut down and reboot the system\n"
5851                "  kexec                           Shut down and reboot the system with kexec\n"
5852                "  exit                            Request user instance exit\n"
5853                "  switch-root ROOT [INIT]         Change to a different root file system\n"
5854                "  suspend                         Suspend the system\n"
5855                "  hibernate                       Hibernate the system\n"
5856                "  hybrid-sleep                    Hibernate and suspend the system\n",
5857                program_invocation_short_name);
5858 }
5859
5860 static void halt_help(void) {
5861         printf("%s [OPTIONS...]%s\n\n"
5862                "%s the system.\n\n"
5863                "     --help      Show this help\n"
5864                "     --halt      Halt the machine\n"
5865                "  -p --poweroff  Switch off the machine\n"
5866                "     --reboot    Reboot the machine\n"
5867                "  -f --force     Force immediate halt/power-off/reboot\n"
5868                "  -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
5869                "  -d --no-wtmp   Don't write wtmp record\n"
5870                "     --no-wall   Don't send wall message before halt/power-off/reboot\n",
5871                program_invocation_short_name,
5872                arg_action == ACTION_REBOOT   ? " [ARG]" : "",
5873                arg_action == ACTION_REBOOT   ? "Reboot" :
5874                arg_action == ACTION_POWEROFF ? "Power off" :
5875                                                "Halt");
5876 }
5877
5878 static void shutdown_help(void) {
5879         printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
5880                "Shut down the system.\n\n"
5881                "     --help      Show this help\n"
5882                "  -H --halt      Halt the machine\n"
5883                "  -P --poweroff  Power-off the machine\n"
5884                "  -r --reboot    Reboot the machine\n"
5885                "  -h             Equivalent to --poweroff, overridden by --halt\n"
5886                "  -k             Don't halt/power-off/reboot, just send warnings\n"
5887                "     --no-wall   Don't send wall message before halt/power-off/reboot\n"
5888                "  -c             Cancel a pending shutdown\n",
5889                program_invocation_short_name);
5890 }
5891
5892 static void telinit_help(void) {
5893         printf("%s [OPTIONS...] {COMMAND}\n\n"
5894                "Send control commands to the init daemon.\n\n"
5895                "     --help      Show this help\n"
5896                "     --no-wall   Don't send wall message before halt/power-off/reboot\n\n"
5897                "Commands:\n"
5898                "  0              Power-off the machine\n"
5899                "  6              Reboot the machine\n"
5900                "  2, 3, 4, 5     Start runlevelX.target unit\n"
5901                "  1, s, S        Enter rescue mode\n"
5902                "  q, Q           Reload init daemon configuration\n"
5903                "  u, U           Reexecute init daemon\n",
5904                program_invocation_short_name);
5905 }
5906
5907 static void runlevel_help(void) {
5908         printf("%s [OPTIONS...]\n\n"
5909                "Prints the previous and current runlevel of the init system.\n\n"
5910                "     --help      Show this help\n",
5911                program_invocation_short_name);
5912 }
5913
5914 static void help_types(void) {
5915         int i;
5916         const char *t;
5917
5918         if (!arg_no_legend)
5919                 puts("Available unit types:");
5920         for (i = 0; i < _UNIT_TYPE_MAX; i++) {
5921                 t = unit_type_to_string(i);
5922                 if (t)
5923                         puts(t);
5924         }
5925 }
5926
5927 static int systemctl_parse_argv(int argc, char *argv[]) {
5928
5929         enum {
5930                 ARG_FAIL = 0x100,
5931                 ARG_REVERSE,
5932                 ARG_AFTER,
5933                 ARG_BEFORE,
5934                 ARG_SHOW_TYPES,
5935                 ARG_IRREVERSIBLE,
5936                 ARG_IGNORE_DEPENDENCIES,
5937                 ARG_VERSION,
5938                 ARG_USER,
5939                 ARG_SYSTEM,
5940                 ARG_GLOBAL,
5941                 ARG_NO_BLOCK,
5942                 ARG_NO_LEGEND,
5943                 ARG_NO_PAGER,
5944                 ARG_NO_WALL,
5945                 ARG_ROOT,
5946                 ARG_NO_RELOAD,
5947                 ARG_KILL_WHO,
5948                 ARG_NO_ASK_PASSWORD,
5949                 ARG_FAILED,
5950                 ARG_RUNTIME,
5951                 ARG_FORCE,
5952                 ARG_PLAIN,
5953                 ARG_STATE,
5954                 ARG_JOB_MODE,
5955                 ARG_PRESET_MODE,
5956         };
5957
5958         static const struct option options[] = {
5959                 { "help",                no_argument,       NULL, 'h'                     },
5960                 { "version",             no_argument,       NULL, ARG_VERSION             },
5961                 { "type",                required_argument, NULL, 't'                     },
5962                 { "property",            required_argument, NULL, 'p'                     },
5963                 { "all",                 no_argument,       NULL, 'a'                     },
5964                 { "reverse",             no_argument,       NULL, ARG_REVERSE             },
5965                 { "after",               no_argument,       NULL, ARG_AFTER               },
5966                 { "before",              no_argument,       NULL, ARG_BEFORE              },
5967                 { "show-types",          no_argument,       NULL, ARG_SHOW_TYPES          },
5968                 { "failed",              no_argument,       NULL, ARG_FAILED              }, /* compatibility only */
5969                 { "full",                no_argument,       NULL, 'l'                     },
5970                 { "job-mode",            required_argument, NULL, ARG_JOB_MODE            },
5971                 { "fail",                no_argument,       NULL, ARG_FAIL                }, /* compatibility only */
5972                 { "irreversible",        no_argument,       NULL, ARG_IRREVERSIBLE        }, /* compatibility only */
5973                 { "ignore-dependencies", no_argument,       NULL, ARG_IGNORE_DEPENDENCIES }, /* compatibility only */
5974                 { "ignore-inhibitors",   no_argument,       NULL, 'i'                     },
5975                 { "user",                no_argument,       NULL, ARG_USER                },
5976                 { "system",              no_argument,       NULL, ARG_SYSTEM              },
5977                 { "global",              no_argument,       NULL, ARG_GLOBAL              },
5978                 { "no-block",            no_argument,       NULL, ARG_NO_BLOCK            },
5979                 { "no-legend",           no_argument,       NULL, ARG_NO_LEGEND           },
5980                 { "no-pager",            no_argument,       NULL, ARG_NO_PAGER            },
5981                 { "no-wall",             no_argument,       NULL, ARG_NO_WALL             },
5982                 { "quiet",               no_argument,       NULL, 'q'                     },
5983                 { "root",                required_argument, NULL, ARG_ROOT                },
5984                 { "force",               no_argument,       NULL, ARG_FORCE               },
5985                 { "no-reload",           no_argument,       NULL, ARG_NO_RELOAD           },
5986                 { "kill-who",            required_argument, NULL, ARG_KILL_WHO            },
5987                 { "signal",              required_argument, NULL, 's'                     },
5988                 { "no-ask-password",     no_argument,       NULL, ARG_NO_ASK_PASSWORD     },
5989                 { "host",                required_argument, NULL, 'H'                     },
5990                 { "machine",             required_argument, NULL, 'M'                     },
5991                 { "runtime",             no_argument,       NULL, ARG_RUNTIME             },
5992                 { "lines",               required_argument, NULL, 'n'                     },
5993                 { "output",              required_argument, NULL, 'o'                     },
5994                 { "plain",               no_argument,       NULL, ARG_PLAIN               },
5995                 { "state",               required_argument, NULL, ARG_STATE               },
5996                 { "recursive",           no_argument,       NULL, 'r'                     },
5997                 { "preset-mode",         required_argument, NULL, ARG_PRESET_MODE         },
5998                 {}
5999         };
6000
6001         int c;
6002
6003         assert(argc >= 0);
6004         assert(argv);
6005
6006         while ((c = getopt_long(argc, argv, "ht:p:alqfs:H:M:n:o:ir", options, NULL)) >= 0)
6007
6008                 switch (c) {
6009
6010                 case 'h':
6011                         systemctl_help();
6012                         return 0;
6013
6014                 case ARG_VERSION:
6015                         puts(PACKAGE_STRING);
6016                         puts(SYSTEMD_FEATURES);
6017                         return 0;
6018
6019                 case 't': {
6020                         const char *word, *state;
6021                         size_t size;
6022
6023                         FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
6024                                 _cleanup_free_ char *type;
6025
6026                                 type = strndup(word, size);
6027                                 if (!type)
6028                                         return -ENOMEM;
6029
6030                                 if (streq(type, "help")) {
6031                                         help_types();
6032                                         return 0;
6033                                 }
6034
6035                                 if (unit_type_from_string(type) >= 0) {
6036                                         if (strv_push(&arg_types, type))
6037                                                 return log_oom();
6038                                         type = NULL;
6039                                         continue;
6040                                 }
6041
6042                                 /* It's much nicer to use --state= for
6043                                  * load states, but let's support this
6044                                  * in --types= too for compatibility
6045                                  * with old versions */
6046                                 if (unit_load_state_from_string(optarg) >= 0) {
6047                                         if (strv_push(&arg_states, type) < 0)
6048                                                 return log_oom();
6049                                         type = NULL;
6050                                         continue;
6051                                 }
6052
6053                                 log_error("Unknown unit type or load state '%s'.", type);
6054                                 log_info("Use -t help to see a list of allowed values.");
6055                                 return -EINVAL;
6056                         }
6057
6058                         break;
6059                 }
6060
6061                 case 'p': {
6062                         /* Make sure that if the empty property list
6063                            was specified, we won't show any properties. */
6064                         if (isempty(optarg) && !arg_properties) {
6065                                 arg_properties = new0(char*, 1);
6066                                 if (!arg_properties)
6067                                         return log_oom();
6068                         } else {
6069                                 const char *word, *state;
6070                                 size_t size;
6071
6072                                 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
6073                                         char *prop;
6074
6075                                         prop = strndup(word, size);
6076                                         if (!prop)
6077                                                 return log_oom();
6078
6079                                         if (strv_consume(&arg_properties, prop) < 0)
6080                                                 return log_oom();
6081                                 }
6082                         }
6083
6084                         /* If the user asked for a particular
6085                          * property, show it to him, even if it is
6086                          * empty. */
6087                         arg_all = true;
6088
6089                         break;
6090                 }
6091
6092                 case 'a':
6093                         arg_all = true;
6094                         break;
6095
6096                 case ARG_REVERSE:
6097                         arg_dependency = DEPENDENCY_REVERSE;
6098                         break;
6099
6100                 case ARG_AFTER:
6101                         arg_dependency = DEPENDENCY_AFTER;
6102                         break;
6103
6104                 case ARG_BEFORE:
6105                         arg_dependency = DEPENDENCY_BEFORE;
6106                         break;
6107
6108                 case ARG_SHOW_TYPES:
6109                         arg_show_types = true;
6110                         break;
6111
6112                 case ARG_JOB_MODE:
6113                         arg_job_mode = optarg;
6114                         break;
6115
6116                 case ARG_FAIL:
6117                         arg_job_mode = "fail";
6118                         break;
6119
6120                 case ARG_IRREVERSIBLE:
6121                         arg_job_mode = "replace-irreversibly";
6122                         break;
6123
6124                 case ARG_IGNORE_DEPENDENCIES:
6125                         arg_job_mode = "ignore-dependencies";
6126                         break;
6127
6128                 case ARG_USER:
6129                         arg_scope = UNIT_FILE_USER;
6130                         break;
6131
6132                 case ARG_SYSTEM:
6133                         arg_scope = UNIT_FILE_SYSTEM;
6134                         break;
6135
6136                 case ARG_GLOBAL:
6137                         arg_scope = UNIT_FILE_GLOBAL;
6138                         break;
6139
6140                 case ARG_NO_BLOCK:
6141                         arg_no_block = true;
6142                         break;
6143
6144                 case ARG_NO_LEGEND:
6145                         arg_no_legend = true;
6146                         break;
6147
6148                 case ARG_NO_PAGER:
6149                         arg_no_pager = true;
6150                         break;
6151
6152                 case ARG_NO_WALL:
6153                         arg_no_wall = true;
6154                         break;
6155
6156                 case ARG_ROOT:
6157                         arg_root = optarg;
6158                         break;
6159
6160                 case 'l':
6161                         arg_full = true;
6162                         break;
6163
6164                 case ARG_FAILED:
6165                         if (strv_extend(&arg_states, "failed") < 0)
6166                                 return log_oom();
6167
6168                         break;
6169
6170                 case 'q':
6171                         arg_quiet = true;
6172                         break;
6173
6174                 case ARG_FORCE:
6175                         arg_force ++;
6176                         break;
6177
6178                 case 'f':
6179                         arg_force ++;
6180                         break;
6181
6182                 case ARG_NO_RELOAD:
6183                         arg_no_reload = true;
6184                         break;
6185
6186                 case ARG_KILL_WHO:
6187                         arg_kill_who = optarg;
6188                         break;
6189
6190                 case 's':
6191                         if ((arg_signal = signal_from_string_try_harder(optarg)) < 0) {
6192                                 log_error("Failed to parse signal string %s.", optarg);
6193                                 return -EINVAL;
6194                         }
6195                         break;
6196
6197                 case ARG_NO_ASK_PASSWORD:
6198                         arg_ask_password = false;
6199                         break;
6200
6201                 case 'H':
6202                         arg_transport = BUS_TRANSPORT_REMOTE;
6203                         arg_host = optarg;
6204                         break;
6205
6206                 case 'M':
6207                         arg_transport = BUS_TRANSPORT_CONTAINER;
6208                         arg_host = optarg;
6209                         break;
6210
6211                 case ARG_RUNTIME:
6212                         arg_runtime = true;
6213                         break;
6214
6215                 case 'n':
6216                         if (safe_atou(optarg, &arg_lines) < 0) {
6217                                 log_error("Failed to parse lines '%s'", optarg);
6218                                 return -EINVAL;
6219                         }
6220                         break;
6221
6222                 case 'o':
6223                         arg_output = output_mode_from_string(optarg);
6224                         if (arg_output < 0) {
6225                                 log_error("Unknown output '%s'.", optarg);
6226                                 return -EINVAL;
6227                         }
6228                         break;
6229
6230                 case 'i':
6231                         arg_ignore_inhibitors = true;
6232                         break;
6233
6234                 case ARG_PLAIN:
6235                         arg_plain = true;
6236                         break;
6237
6238                 case ARG_STATE: {
6239                         const char *word, *state;
6240                         size_t size;
6241
6242                         FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
6243                                 char *s;
6244
6245                                 s = strndup(word, size);
6246                                 if (!s)
6247                                         return log_oom();
6248
6249                                 if (strv_consume(&arg_states, s) < 0)
6250                                         return log_oom();
6251                         }
6252                         break;
6253                 }
6254
6255                 case 'r':
6256                         if (geteuid() != 0) {
6257                                 log_error("--recursive requires root privileges.");
6258                                 return -EPERM;
6259                         }
6260
6261                         arg_recursive = true;
6262                         break;
6263
6264                 case ARG_PRESET_MODE:
6265
6266                         arg_preset_mode = unit_file_preset_mode_from_string(optarg);
6267                         if (arg_preset_mode < 0) {
6268                                 log_error("Failed to parse preset mode: %s.", optarg);
6269                                 return -EINVAL;
6270                         }
6271
6272                         break;
6273
6274                 case '?':
6275                         return -EINVAL;
6276
6277                 default:
6278                         assert_not_reached("Unhandled option");
6279                 }
6280
6281         if (arg_transport != BUS_TRANSPORT_LOCAL && arg_scope != UNIT_FILE_SYSTEM) {
6282                 log_error("Cannot access user instance remotely.");
6283                 return -EINVAL;
6284         }
6285
6286         return 1;
6287 }
6288
6289 static int halt_parse_argv(int argc, char *argv[]) {
6290
6291         enum {
6292                 ARG_HELP = 0x100,
6293                 ARG_HALT,
6294                 ARG_REBOOT,
6295                 ARG_NO_WALL
6296         };
6297
6298         static const struct option options[] = {
6299                 { "help",      no_argument,       NULL, ARG_HELP    },
6300                 { "halt",      no_argument,       NULL, ARG_HALT    },
6301                 { "poweroff",  no_argument,       NULL, 'p'         },
6302                 { "reboot",    no_argument,       NULL, ARG_REBOOT  },
6303                 { "force",     no_argument,       NULL, 'f'         },
6304                 { "wtmp-only", no_argument,       NULL, 'w'         },
6305                 { "no-wtmp",   no_argument,       NULL, 'd'         },
6306                 { "no-wall",   no_argument,       NULL, ARG_NO_WALL },
6307                 {}
6308         };
6309
6310         int c, r, runlevel;
6311
6312         assert(argc >= 0);
6313         assert(argv);
6314
6315         if (utmp_get_runlevel(&runlevel, NULL) >= 0)
6316                 if (runlevel == '0' || runlevel == '6')
6317                         arg_force = 2;
6318
6319         while ((c = getopt_long(argc, argv, "pfwdnih", options, NULL)) >= 0)
6320                 switch (c) {
6321
6322                 case ARG_HELP:
6323                         halt_help();
6324                         return 0;
6325
6326                 case ARG_HALT:
6327                         arg_action = ACTION_HALT;
6328                         break;
6329
6330                 case 'p':
6331                         if (arg_action != ACTION_REBOOT)
6332                                 arg_action = ACTION_POWEROFF;
6333                         break;
6334
6335                 case ARG_REBOOT:
6336                         arg_action = ACTION_REBOOT;
6337                         break;
6338
6339                 case 'f':
6340                         arg_force = 2;
6341                         break;
6342
6343                 case 'w':
6344                         arg_dry = true;
6345                         break;
6346
6347                 case 'd':
6348                         arg_no_wtmp = true;
6349                         break;
6350
6351                 case ARG_NO_WALL:
6352                         arg_no_wall = true;
6353                         break;
6354
6355                 case 'i':
6356                 case 'h':
6357                 case 'n':
6358                         /* Compatibility nops */
6359                         break;
6360
6361                 case '?':
6362                         return -EINVAL;
6363
6364                 default:
6365                         assert_not_reached("Unhandled option");
6366                 }
6367
6368         if (arg_action == ACTION_REBOOT && (argc == optind || argc == optind + 1)) {
6369                 r = update_reboot_param_file(argc == optind + 1 ? argv[optind] : NULL);
6370                 if (r < 0)
6371                         return r;
6372         } else if (optind < argc) {
6373                 log_error("Too many arguments.");
6374                 return -EINVAL;
6375         }
6376
6377         return 1;
6378 }
6379
6380 static int parse_time_spec(const char *t, usec_t *_u) {
6381         assert(t);
6382         assert(_u);
6383
6384         if (streq(t, "now"))
6385                 *_u = 0;
6386         else if (!strchr(t, ':')) {
6387                 uint64_t u;
6388
6389                 if (safe_atou64(t, &u) < 0)
6390                         return -EINVAL;
6391
6392                 *_u = now(CLOCK_REALTIME) + USEC_PER_MINUTE * u;
6393         } else {
6394                 char *e = NULL;
6395                 long hour, minute;
6396                 struct tm tm = {};
6397                 time_t s;
6398                 usec_t n;
6399
6400                 errno = 0;
6401                 hour = strtol(t, &e, 10);
6402                 if (errno > 0 || *e != ':' || hour < 0 || hour > 23)
6403                         return -EINVAL;
6404
6405                 minute = strtol(e+1, &e, 10);
6406                 if (errno > 0 || *e != 0 || minute < 0 || minute > 59)
6407                         return -EINVAL;
6408
6409                 n = now(CLOCK_REALTIME);
6410                 s = (time_t) (n / USEC_PER_SEC);
6411
6412                 assert_se(localtime_r(&s, &tm));
6413
6414                 tm.tm_hour = (int) hour;
6415                 tm.tm_min = (int) minute;
6416                 tm.tm_sec = 0;
6417
6418                 assert_se(s = mktime(&tm));
6419
6420                 *_u = (usec_t) s * USEC_PER_SEC;
6421
6422                 while (*_u <= n)
6423                         *_u += USEC_PER_DAY;
6424         }
6425
6426         return 0;
6427 }
6428
6429 static int shutdown_parse_argv(int argc, char *argv[]) {
6430
6431         enum {
6432                 ARG_HELP = 0x100,
6433                 ARG_NO_WALL
6434         };
6435
6436         static const struct option options[] = {
6437                 { "help",      no_argument,       NULL, ARG_HELP    },
6438                 { "halt",      no_argument,       NULL, 'H'         },
6439                 { "poweroff",  no_argument,       NULL, 'P'         },
6440                 { "reboot",    no_argument,       NULL, 'r'         },
6441                 { "kexec",     no_argument,       NULL, 'K'         }, /* not documented extension */
6442                 { "no-wall",   no_argument,       NULL, ARG_NO_WALL },
6443                 {}
6444         };
6445
6446         int c, r;
6447
6448         assert(argc >= 0);
6449         assert(argv);
6450
6451         while ((c = getopt_long(argc, argv, "HPrhkt:afFc", options, NULL)) >= 0)
6452                 switch (c) {
6453
6454                 case ARG_HELP:
6455                         shutdown_help();
6456                         return 0;
6457
6458                 case 'H':
6459                         arg_action = ACTION_HALT;
6460                         break;
6461
6462                 case 'P':
6463                         arg_action = ACTION_POWEROFF;
6464                         break;
6465
6466                 case 'r':
6467                         if (kexec_loaded())
6468                                 arg_action = ACTION_KEXEC;
6469                         else
6470                                 arg_action = ACTION_REBOOT;
6471                         break;
6472
6473                 case 'K':
6474                         arg_action = ACTION_KEXEC;
6475                         break;
6476
6477                 case 'h':
6478                         if (arg_action != ACTION_HALT)
6479                                 arg_action = ACTION_POWEROFF;
6480                         break;
6481
6482                 case 'k':
6483                         arg_dry = true;
6484                         break;
6485
6486                 case ARG_NO_WALL:
6487                         arg_no_wall = true;
6488                         break;
6489
6490                 case 't':
6491                 case 'a':
6492                         /* Compatibility nops */
6493                         break;
6494
6495                 case 'c':
6496                         arg_action = ACTION_CANCEL_SHUTDOWN;
6497                         break;
6498
6499                 case '?':
6500                         return -EINVAL;
6501
6502                 default:
6503                         assert_not_reached("Unhandled option");
6504                 }
6505
6506         if (argc > optind && arg_action != ACTION_CANCEL_SHUTDOWN) {
6507                 r = parse_time_spec(argv[optind], &arg_when);
6508                 if (r < 0) {
6509                         log_error("Failed to parse time specification: %s", argv[optind]);
6510                         return r;
6511                 }
6512         } else
6513                 arg_when = now(CLOCK_REALTIME) + USEC_PER_MINUTE;
6514
6515         if (argc > optind && arg_action == ACTION_CANCEL_SHUTDOWN)
6516                 /* No time argument for shutdown cancel */
6517                 arg_wall = argv + optind;
6518         else if (argc > optind + 1)
6519                 /* We skip the time argument */
6520                 arg_wall = argv + optind + 1;
6521
6522         optind = argc;
6523
6524         return 1;
6525 }
6526
6527 static int telinit_parse_argv(int argc, char *argv[]) {
6528
6529         enum {
6530                 ARG_HELP = 0x100,
6531                 ARG_NO_WALL
6532         };
6533
6534         static const struct option options[] = {
6535                 { "help",      no_argument,       NULL, ARG_HELP    },
6536                 { "no-wall",   no_argument,       NULL, ARG_NO_WALL },
6537                 {}
6538         };
6539
6540         static const struct {
6541                 char from;
6542                 enum action to;
6543         } table[] = {
6544                 { '0', ACTION_POWEROFF },
6545                 { '6', ACTION_REBOOT },
6546                 { '1', ACTION_RESCUE },
6547                 { '2', ACTION_RUNLEVEL2 },
6548                 { '3', ACTION_RUNLEVEL3 },
6549                 { '4', ACTION_RUNLEVEL4 },
6550                 { '5', ACTION_RUNLEVEL5 },
6551                 { 's', ACTION_RESCUE },
6552                 { 'S', ACTION_RESCUE },
6553                 { 'q', ACTION_RELOAD },
6554                 { 'Q', ACTION_RELOAD },
6555                 { 'u', ACTION_REEXEC },
6556                 { 'U', ACTION_REEXEC }
6557         };
6558
6559         unsigned i;
6560         int c;
6561
6562         assert(argc >= 0);
6563         assert(argv);
6564
6565         while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0)
6566                 switch (c) {
6567
6568                 case ARG_HELP:
6569                         telinit_help();
6570                         return 0;
6571
6572                 case ARG_NO_WALL:
6573                         arg_no_wall = true;
6574                         break;
6575
6576                 case '?':
6577                         return -EINVAL;
6578
6579                 default:
6580                         assert_not_reached("Unhandled option");
6581                 }
6582
6583         if (optind >= argc) {
6584                 log_error("%s: required argument missing.",
6585                           program_invocation_short_name);
6586                 return -EINVAL;
6587         }
6588
6589         if (optind + 1 < argc) {
6590                 log_error("Too many arguments.");
6591                 return -EINVAL;
6592         }
6593
6594         if (strlen(argv[optind]) != 1) {
6595                 log_error("Expected single character argument.");
6596                 return -EINVAL;
6597         }
6598
6599         for (i = 0; i < ELEMENTSOF(table); i++)
6600                 if (table[i].from == argv[optind][0])
6601                         break;
6602
6603         if (i >= ELEMENTSOF(table)) {
6604                 log_error("Unknown command '%s'.", argv[optind]);
6605                 return -EINVAL;
6606         }
6607
6608         arg_action = table[i].to;
6609
6610         optind ++;
6611
6612         return 1;
6613 }
6614
6615 static int runlevel_parse_argv(int argc, char *argv[]) {
6616
6617         enum {
6618                 ARG_HELP = 0x100,
6619         };
6620
6621         static const struct option options[] = {
6622                 { "help",      no_argument,       NULL, ARG_HELP    },
6623                 {}
6624         };
6625
6626         int c;
6627
6628         assert(argc >= 0);
6629         assert(argv);
6630
6631         while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0)
6632                 switch (c) {
6633
6634                 case ARG_HELP:
6635                         runlevel_help();
6636                         return 0;
6637
6638                 case '?':
6639                         return -EINVAL;
6640
6641                 default:
6642                         assert_not_reached("Unhandled option");
6643                 }
6644
6645         if (optind < argc) {
6646                 log_error("Too many arguments.");
6647                 return -EINVAL;
6648         }
6649
6650         return 1;
6651 }
6652
6653 static int parse_argv(int argc, char *argv[]) {
6654         assert(argc >= 0);
6655         assert(argv);
6656
6657         if (program_invocation_short_name) {
6658
6659                 if (strstr(program_invocation_short_name, "halt")) {
6660                         arg_action = ACTION_HALT;
6661                         return halt_parse_argv(argc, argv);
6662                 } else if (strstr(program_invocation_short_name, "poweroff")) {
6663                         arg_action = ACTION_POWEROFF;
6664                         return halt_parse_argv(argc, argv);
6665                 } else if (strstr(program_invocation_short_name, "reboot")) {
6666                         if (kexec_loaded())
6667                                 arg_action = ACTION_KEXEC;
6668                         else
6669                                 arg_action = ACTION_REBOOT;
6670                         return halt_parse_argv(argc, argv);
6671                 } else if (strstr(program_invocation_short_name, "shutdown")) {
6672                         arg_action = ACTION_POWEROFF;
6673                         return shutdown_parse_argv(argc, argv);
6674                 } else if (strstr(program_invocation_short_name, "init")) {
6675
6676                         if (sd_booted() > 0) {
6677                                 arg_action = _ACTION_INVALID;
6678                                 return telinit_parse_argv(argc, argv);
6679                         } else {
6680                                 /* Hmm, so some other init system is
6681                                  * running, we need to forward this
6682                                  * request to it. For now we simply
6683                                  * guess that it is Upstart. */
6684
6685                                 execv(TELINIT, argv);
6686
6687                                 log_error("Couldn't find an alternative telinit implementation to spawn.");
6688                                 return -EIO;
6689                         }
6690
6691                 } else if (strstr(program_invocation_short_name, "runlevel")) {
6692                         arg_action = ACTION_RUNLEVEL;
6693                         return runlevel_parse_argv(argc, argv);
6694                 }
6695         }
6696
6697         arg_action = ACTION_SYSTEMCTL;
6698         return systemctl_parse_argv(argc, argv);
6699 }
6700
6701 _pure_ static int action_to_runlevel(void) {
6702
6703         static const char table[_ACTION_MAX] = {
6704                 [ACTION_HALT] =      '0',
6705                 [ACTION_POWEROFF] =  '0',
6706                 [ACTION_REBOOT] =    '6',
6707                 [ACTION_RUNLEVEL2] = '2',
6708                 [ACTION_RUNLEVEL3] = '3',
6709                 [ACTION_RUNLEVEL4] = '4',
6710                 [ACTION_RUNLEVEL5] = '5',
6711                 [ACTION_RESCUE] =    '1'
6712         };
6713
6714         assert(arg_action < _ACTION_MAX);
6715
6716         return table[arg_action];
6717 }
6718
6719 static int talk_initctl(void) {
6720
6721         struct init_request request = {
6722                 .magic = INIT_MAGIC,
6723                 .sleeptime  = 0,
6724                 .cmd = INIT_CMD_RUNLVL
6725         };
6726
6727         _cleanup_close_ int fd = -1;
6728         char rl;
6729         int r;
6730
6731         rl = action_to_runlevel();
6732         if (!rl)
6733                 return 0;
6734
6735         request.runlevel = rl;
6736
6737         fd = open(INIT_FIFO, O_WRONLY|O_NDELAY|O_CLOEXEC|O_NOCTTY);
6738         if (fd < 0) {
6739                 if (errno == ENOENT)
6740                         return 0;
6741
6742                 log_error("Failed to open "INIT_FIFO": %m");
6743                 return -errno;
6744         }
6745
6746         errno = 0;
6747         r = loop_write(fd, &request, sizeof(request), false) != sizeof(request);
6748         if (r) {
6749                 log_error("Failed to write to "INIT_FIFO": %m");
6750                 return errno > 0 ? -errno : -EIO;
6751         }
6752
6753         return 1;
6754 }
6755
6756 static int systemctl_main(sd_bus *bus, int argc, char *argv[], int bus_error) {
6757
6758         static const struct {
6759                 const char* verb;
6760                 const enum {
6761                         MORE,
6762                         LESS,
6763                         EQUAL
6764                 } argc_cmp;
6765                 const int argc;
6766                 int (* const dispatch)(sd_bus *bus, char **args);
6767                 const enum {
6768                         NOBUS = 1,
6769                         FORCE,
6770                 } bus;
6771         } verbs[] = {
6772                 { "list-units",            MORE,  0, list_units        },
6773                 { "list-unit-files",       MORE,  1, list_unit_files,  NOBUS },
6774                 { "list-sockets",          MORE,  1, list_sockets      },
6775                 { "list-timers",           MORE,  1, list_timers       },
6776                 { "list-jobs",             MORE,  1, list_jobs         },
6777                 { "list-machines",         MORE,  1, list_machines     },
6778                 { "clear-jobs",            EQUAL, 1, daemon_reload     },
6779                 { "cancel",                MORE,  2, cancel_job        },
6780                 { "start",                 MORE,  2, start_unit        },
6781                 { "stop",                  MORE,  2, start_unit        },
6782                 { "condstop",              MORE,  2, start_unit        }, /* For compatibility with ALTLinux */
6783                 { "reload",                MORE,  2, start_unit        },
6784                 { "restart",               MORE,  2, start_unit        },
6785                 { "try-restart",           MORE,  2, start_unit        },
6786                 { "reload-or-restart",     MORE,  2, start_unit        },
6787                 { "reload-or-try-restart", MORE,  2, start_unit        },
6788                 { "force-reload",          MORE,  2, start_unit        }, /* For compatibility with SysV */
6789                 { "condreload",            MORE,  2, start_unit        }, /* For compatibility with ALTLinux */
6790                 { "condrestart",           MORE,  2, start_unit        }, /* For compatibility with RH */
6791                 { "isolate",               EQUAL, 2, start_unit        },
6792                 { "kill",                  MORE,  2, kill_unit         },
6793                 { "is-active",             MORE,  2, check_unit_active },
6794                 { "check",                 MORE,  2, check_unit_active },
6795                 { "is-failed",             MORE,  2, check_unit_failed },
6796                 { "show",                  MORE,  1, show              },
6797                 { "cat",                   MORE,  2, cat               },
6798                 { "status",                MORE,  1, show              },
6799                 { "help",                  MORE,  2, show              },
6800                 { "snapshot",              LESS,  2, snapshot          },
6801                 { "delete",                MORE,  2, delete_snapshot   },
6802                 { "daemon-reload",         EQUAL, 1, daemon_reload     },
6803                 { "daemon-reexec",         EQUAL, 1, daemon_reload     },
6804                 { "show-environment",      EQUAL, 1, show_environment  },
6805                 { "set-environment",       MORE,  2, set_environment   },
6806                 { "unset-environment",     MORE,  2, set_environment   },
6807                 { "import-environment",    MORE,  1, import_environment},
6808                 { "halt",                  EQUAL, 1, start_special,    FORCE },
6809                 { "poweroff",              EQUAL, 1, start_special,    FORCE },
6810                 { "reboot",                EQUAL, 1, start_special,    FORCE },
6811                 { "kexec",                 EQUAL, 1, start_special     },
6812                 { "suspend",               EQUAL, 1, start_special     },
6813                 { "hibernate",             EQUAL, 1, start_special     },
6814                 { "hybrid-sleep",          EQUAL, 1, start_special     },
6815                 { "default",               EQUAL, 1, start_special     },
6816                 { "rescue",                EQUAL, 1, start_special     },
6817                 { "emergency",             EQUAL, 1, start_special     },
6818                 { "exit",                  EQUAL, 1, start_special     },
6819                 { "reset-failed",          MORE,  1, reset_failed      },
6820                 { "enable",                MORE,  2, enable_unit,      NOBUS },
6821                 { "disable",               MORE,  2, enable_unit,      NOBUS },
6822                 { "is-enabled",            MORE,  2, unit_is_enabled,  NOBUS },
6823                 { "reenable",              MORE,  2, enable_unit,      NOBUS },
6824                 { "preset",                MORE,  2, enable_unit,      NOBUS },
6825                 { "preset-all",            EQUAL, 1, preset_all,       NOBUS },
6826                 { "mask",                  MORE,  2, enable_unit,      NOBUS },
6827                 { "unmask",                MORE,  2, enable_unit,      NOBUS },
6828                 { "link",                  MORE,  2, enable_unit,      NOBUS },
6829                 { "switch-root",           MORE,  2, switch_root       },
6830                 { "list-dependencies",     LESS,  2, list_dependencies },
6831                 { "set-default",           EQUAL, 2, set_default,      NOBUS },
6832                 { "get-default",           EQUAL, 1, get_default,      NOBUS },
6833                 { "set-property",          MORE,  3, set_property      },
6834                 { "is-system-running",     EQUAL, 1, is_system_running },
6835                 { "add-wants",             MORE,  3, add_dependency,        NOBUS },
6836                 { "add-requires",          MORE,  3, add_dependency,        NOBUS },
6837                 {}
6838         }, *verb = verbs;
6839
6840         int left;
6841
6842         assert(argc >= 0);
6843         assert(argv);
6844
6845         left = argc - optind;
6846
6847         /* Special rule: no arguments (left == 0) means "list-units" */
6848         if (left > 0) {
6849                 if (streq(argv[optind], "help") && !argv[optind+1]) {
6850                         log_error("This command expects one or more "
6851                                   "unit names. Did you mean --help?");
6852                         return -EINVAL;
6853                 }
6854
6855                 for (; verb->verb; verb++)
6856                         if (streq(argv[optind], verb->verb))
6857                                 goto found;
6858
6859                 log_error("Unknown operation '%s'.", argv[optind]);
6860                 return -EINVAL;
6861         }
6862 found:
6863
6864         switch (verb->argc_cmp) {
6865
6866         case EQUAL:
6867                 if (left != verb->argc) {
6868                         log_error("Invalid number of arguments.");
6869                         return -EINVAL;
6870                 }
6871
6872                 break;
6873
6874         case MORE:
6875                 if (left < verb->argc) {
6876                         log_error("Too few arguments.");
6877                         return -EINVAL;
6878                 }
6879
6880                 break;
6881
6882         case LESS:
6883                 if (left > verb->argc) {
6884                         log_error("Too many arguments.");
6885                         return -EINVAL;
6886                 }
6887
6888                 break;
6889
6890         default:
6891                 assert_not_reached("Unknown comparison operator.");
6892         }
6893
6894         /* Require a bus connection for all operations but
6895          * enable/disable */
6896         if (verb->bus == NOBUS) {
6897                 if (!bus && !avoid_bus()) {
6898                         log_error("Failed to get D-Bus connection: %s", strerror(-bus_error));
6899                         return -EIO;
6900                 }
6901
6902         } else {
6903                 if (running_in_chroot() > 0) {
6904                         log_info("Running in chroot, ignoring request.");
6905                         return 0;
6906                 }
6907
6908                 if ((verb->bus != FORCE || arg_force <= 0) && !bus) {
6909                         log_error("Failed to get D-Bus connection: %s", strerror(-bus_error));
6910                         return -EIO;
6911                 }
6912         }
6913
6914         return verb->dispatch(bus, argv + optind);
6915 }
6916
6917 static int send_shutdownd(usec_t t, char mode, bool dry_run, bool warn, const char *message) {
6918
6919         struct sd_shutdown_command c = {
6920                 .usec = t,
6921                 .mode = mode,
6922                 .dry_run = dry_run,
6923                 .warn_wall = warn,
6924         };
6925
6926         union sockaddr_union sockaddr = {
6927                 .un.sun_family = AF_UNIX,
6928                 .un.sun_path = "/run/systemd/shutdownd",
6929         };
6930
6931         struct iovec iovec[2] = {{
6932                  .iov_base = (char*) &c,
6933                  .iov_len = offsetof(struct sd_shutdown_command, wall_message),
6934         }};
6935
6936         struct msghdr msghdr = {
6937                 .msg_name = &sockaddr,
6938                 .msg_namelen = offsetof(struct sockaddr_un, sun_path)
6939                                + strlen("/run/systemd/shutdownd"),
6940                 .msg_iov = iovec,
6941                 .msg_iovlen = 1,
6942         };
6943
6944         _cleanup_close_ int fd;
6945
6946         fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
6947         if (fd < 0)
6948                 return -errno;
6949
6950         if (!isempty(message)) {
6951                 iovec[1].iov_base = (char*) message;
6952                 iovec[1].iov_len = strlen(message);
6953                 msghdr.msg_iovlen++;
6954         }
6955
6956         if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) < 0)
6957                 return -errno;
6958
6959         return 0;
6960 }
6961
6962 static int reload_with_fallback(sd_bus *bus) {
6963
6964         if (bus) {
6965                 /* First, try systemd via D-Bus. */
6966                 if (daemon_reload(bus, NULL) >= 0)
6967                         return 0;
6968         }
6969
6970         /* Nothing else worked, so let's try signals */
6971         assert(arg_action == ACTION_RELOAD || arg_action == ACTION_REEXEC);
6972
6973         if (kill(1, arg_action == ACTION_RELOAD ? SIGHUP : SIGTERM) < 0) {
6974                 log_error("kill() failed: %m");
6975                 return -errno;
6976         }
6977
6978         return 0;
6979 }
6980
6981 static int start_with_fallback(sd_bus *bus) {
6982
6983         if (bus) {
6984                 /* First, try systemd via D-Bus. */
6985                 if (start_unit(bus, NULL) >= 0)
6986                         goto done;
6987         }
6988
6989         /* Nothing else worked, so let's try
6990          * /dev/initctl */
6991         if (talk_initctl() > 0)
6992                 goto done;
6993
6994         log_error("Failed to talk to init daemon.");
6995         return -EIO;
6996
6997 done:
6998         warn_wall(arg_action);
6999         return 0;
7000 }
7001
7002 static int halt_now(enum action a) {
7003
7004         /* The kernel will automaticall flush ATA disks and suchlike
7005          * on reboot(), but the file systems need to be synce'd
7006          * explicitly in advance. */
7007         sync();
7008
7009         /* Make sure C-A-D is handled by the kernel from this point
7010          * on... */
7011         reboot(RB_ENABLE_CAD);
7012
7013         switch (a) {
7014
7015         case ACTION_HALT:
7016                 log_info("Halting.");
7017                 reboot(RB_HALT_SYSTEM);
7018                 return -errno;
7019
7020         case ACTION_POWEROFF:
7021                 log_info("Powering off.");
7022                 reboot(RB_POWER_OFF);
7023                 return -errno;
7024
7025         case ACTION_REBOOT: {
7026                 _cleanup_free_ char *param = NULL;
7027
7028                 if (read_one_line_file(REBOOT_PARAM_FILE, &param) >= 0) {
7029                         log_info("Rebooting with argument '%s'.", param);
7030                         syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
7031                                 LINUX_REBOOT_CMD_RESTART2, param);
7032                 }
7033
7034                 log_info("Rebooting.");
7035                 reboot(RB_AUTOBOOT);
7036                 return -errno;
7037         }
7038
7039         default:
7040                 assert_not_reached("Unknown action.");
7041         }
7042 }
7043
7044 static int halt_main(sd_bus *bus) {
7045         int r;
7046
7047         r = check_inhibitors(bus, arg_action);
7048         if (r < 0)
7049                 return r;
7050
7051         if (geteuid() != 0) {
7052                 /* Try logind if we are a normal user and no special
7053                  * mode applies. Maybe PolicyKit allows us to shutdown
7054                  * the machine. */
7055
7056                 if (arg_when <= 0 &&
7057                     !arg_dry &&
7058                     arg_force <= 0 &&
7059                     (arg_action == ACTION_POWEROFF ||
7060                      arg_action == ACTION_REBOOT)) {
7061                         r = reboot_with_logind(bus, arg_action);
7062                         if (r >= 0)
7063                                 return r;
7064                 }
7065
7066                 log_error("Must be root.");
7067                 return -EPERM;
7068         }
7069
7070         if (arg_when > 0) {
7071                 _cleanup_free_ char *m;
7072
7073                 m = strv_join(arg_wall, " ");
7074                 if (!m)
7075                         return log_oom();
7076
7077                 r = send_shutdownd(arg_when,
7078                                    arg_action == ACTION_HALT     ? 'H' :
7079                                    arg_action == ACTION_POWEROFF ? 'P' :
7080                                    arg_action == ACTION_KEXEC    ? 'K' :
7081                                                                    'r',
7082                                    arg_dry,
7083                                    !arg_no_wall,
7084                                    m);
7085
7086                 if (r < 0)
7087                         log_warning("Failed to talk to shutdownd, proceeding with immediate shutdown: %s", strerror(-r));
7088                 else {
7089                         char date[FORMAT_TIMESTAMP_MAX];
7090
7091                         log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.",
7092                                  format_timestamp(date, sizeof(date), arg_when));
7093                         return 0;
7094                 }
7095         }
7096
7097         if (!arg_dry && !arg_force)
7098                 return start_with_fallback(bus);
7099
7100         if (!arg_no_wtmp) {
7101                 if (sd_booted() > 0)
7102                         log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
7103                 else {
7104                         r = utmp_put_shutdown();
7105                         if (r < 0)
7106                                 log_warning("Failed to write utmp record: %s", strerror(-r));
7107                 }
7108         }
7109
7110         if (arg_dry)
7111                 return 0;
7112
7113         r = halt_now(arg_action);
7114         log_error("Failed to reboot: %s", strerror(-r));
7115
7116         return r;
7117 }
7118
7119 static int runlevel_main(void) {
7120         int r, runlevel, previous;
7121
7122         r = utmp_get_runlevel(&runlevel, &previous);
7123         if (r < 0) {
7124                 puts("unknown");
7125                 return r;
7126         }
7127
7128         printf("%c %c\n",
7129                previous <= 0 ? 'N' : previous,
7130                runlevel <= 0 ? 'N' : runlevel);
7131
7132         return 0;
7133 }
7134
7135 int main(int argc, char*argv[]) {
7136         _cleanup_bus_close_unref_ sd_bus *bus = NULL;
7137         int r;
7138
7139         setlocale(LC_ALL, "");
7140         log_parse_environment();
7141         log_open();
7142
7143         /* Explicitly not on_tty() to avoid setting cached value.
7144          * This becomes relevant for piping output which might be
7145          * ellipsized. */
7146         original_stdout_is_tty = isatty(STDOUT_FILENO);
7147
7148         r = parse_argv(argc, argv);
7149         if (r <= 0)
7150                 goto finish;
7151
7152         /* /sbin/runlevel doesn't need to communicate via D-Bus, so
7153          * let's shortcut this */
7154         if (arg_action == ACTION_RUNLEVEL) {
7155                 r = runlevel_main();
7156                 goto finish;
7157         }
7158
7159         if (running_in_chroot() > 0 && arg_action != ACTION_SYSTEMCTL) {
7160                 log_info("Running in chroot, ignoring request.");
7161                 r = 0;
7162                 goto finish;
7163         }
7164
7165         if (!avoid_bus())
7166                 r = bus_open_transport_systemd(arg_transport, arg_host, arg_scope != UNIT_FILE_SYSTEM, &bus);
7167
7168         /* systemctl_main() will print an error message for the bus
7169          * connection, but only if it needs to */
7170
7171         switch (arg_action) {
7172
7173         case ACTION_SYSTEMCTL:
7174                 r = systemctl_main(bus, argc, argv, r);
7175                 break;
7176
7177         case ACTION_HALT:
7178         case ACTION_POWEROFF:
7179         case ACTION_REBOOT:
7180         case ACTION_KEXEC:
7181                 r = halt_main(bus);
7182                 break;
7183
7184         case ACTION_RUNLEVEL2:
7185         case ACTION_RUNLEVEL3:
7186         case ACTION_RUNLEVEL4:
7187         case ACTION_RUNLEVEL5:
7188         case ACTION_RESCUE:
7189         case ACTION_EMERGENCY:
7190         case ACTION_DEFAULT:
7191                 r = start_with_fallback(bus);
7192                 break;
7193
7194         case ACTION_RELOAD:
7195         case ACTION_REEXEC:
7196                 r = reload_with_fallback(bus);
7197                 break;
7198
7199         case ACTION_CANCEL_SHUTDOWN: {
7200                 _cleanup_free_ char *m = NULL;
7201
7202                 if (arg_wall) {
7203                         m = strv_join(arg_wall, " ");
7204                         if (!m) {
7205                                 r = log_oom();
7206                                 goto finish;
7207                         }
7208                 }
7209
7210                 r = send_shutdownd(arg_when, SD_SHUTDOWN_NONE, false, !arg_no_wall, m);
7211                 if (r < 0)
7212                         log_warning("Failed to talk to shutdownd, shutdown hasn't been cancelled: %s", strerror(-r));
7213                 break;
7214         }
7215
7216         case ACTION_RUNLEVEL:
7217         case _ACTION_INVALID:
7218         default:
7219                 assert_not_reached("Unknown action");
7220         }
7221
7222 finish:
7223         pager_close();
7224         ask_password_agent_close();
7225         polkit_agent_close();
7226
7227         strv_free(arg_types);
7228         strv_free(arg_states);
7229         strv_free(arg_properties);
7230
7231         return r < 0 ? EXIT_FAILURE : r;
7232 }