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