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