chiark / gitweb /
machinectl: add new "start" verb to start a container as a service in nspawn
[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 deserialize_and_dump_unit_file_changes(sd_bus_message *m) {
1955         const char *type, *path, *source;
1956         int r;
1957
1958         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sss)");
1959         if (r < 0)
1960                 return bus_log_parse_error(r);
1961
1962         while ((r = sd_bus_message_read(m, "(sss)", &type, &path, &source)) > 0) {
1963                 if (!arg_quiet) {
1964                         if (streq(type, "symlink"))
1965                                 log_info("Created symlink from %s to %s.", path, source);
1966                         else
1967                                 log_info("Removed symlink %s.", path);
1968                 }
1969         }
1970         if (r < 0)
1971                 return bus_log_parse_error(r);
1972
1973         r = sd_bus_message_exit_container(m);
1974         if (r < 0)
1975                 return bus_log_parse_error(r);
1976
1977         return 0;
1978 }
1979
1980 static int set_default(sd_bus *bus, char **args) {
1981         _cleanup_free_ char *unit = NULL;
1982         UnitFileChange *changes = NULL;
1983         unsigned n_changes = 0;
1984         int r;
1985
1986         unit = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".target");
1987         if (!unit)
1988                 return log_oom();
1989
1990         if (!bus || avoid_bus()) {
1991                 r = unit_file_set_default(arg_scope, arg_root, unit, true, &changes, &n_changes);
1992                 if (r < 0)
1993                         return log_error_errno(r, "Failed to set default target: %m");
1994
1995                 if (!arg_quiet)
1996                         dump_unit_file_changes(changes, n_changes);
1997
1998                 r = 0;
1999         } else {
2000                 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
2001                 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2002
2003                 r = sd_bus_message_new_method_call(
2004                                 bus,
2005                                 &m,
2006                                 "org.freedesktop.systemd1",
2007                                 "/org/freedesktop/systemd1",
2008                                 "org.freedesktop.systemd1.Manager",
2009                                 "SetDefaultTarget");
2010                 if (r < 0)
2011                         return bus_log_create_error(r);
2012
2013                 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
2014                 if (r < 0)
2015                         return bus_log_create_error(r);
2016
2017                 r = sd_bus_message_append(m, "sb", unit, 1);
2018                 if (r < 0)
2019                         return bus_log_create_error(r);
2020
2021                 r = sd_bus_call(bus, m, 0, &error, &reply);
2022                 if (r < 0) {
2023                         log_error("Failed to set default target: %s", bus_error_message(&error, -r));
2024                         return r;
2025                 }
2026
2027                 r = deserialize_and_dump_unit_file_changes(reply);
2028                 if (r < 0)
2029                         return r;
2030
2031                 /* Try to reload if enabled */
2032                 if (!arg_no_reload)
2033                         r = daemon_reload(bus, args);
2034                 else
2035                         r = 0;
2036         }
2037
2038         unit_file_changes_free(changes, n_changes);
2039
2040         return r;
2041 }
2042
2043 struct job_info {
2044         uint32_t id;
2045         const char *name, *type, *state;
2046 };
2047
2048 static void output_jobs_list(const struct job_info* jobs, unsigned n, bool skipped) {
2049         unsigned id_len, unit_len, type_len, state_len;
2050         const struct job_info *j;
2051         const char *on, *off;
2052         bool shorten = false;
2053
2054         assert(n == 0 || jobs);
2055
2056         if (n == 0) {
2057                 on = ansi_highlight_green();
2058                 off = ansi_highlight_off();
2059
2060                 printf("%sNo jobs %s.%s\n", on, skipped ? "listed" : "running", off);
2061                 return;
2062         }
2063
2064         pager_open_if_enabled();
2065
2066         id_len = strlen("JOB");
2067         unit_len = strlen("UNIT");
2068         type_len = strlen("TYPE");
2069         state_len = strlen("STATE");
2070
2071         for (j = jobs; j < jobs + n; j++) {
2072                 uint32_t id = j->id;
2073                 assert(j->name && j->type && j->state);
2074
2075                 id_len = MAX(id_len, DECIMAL_STR_WIDTH(id));
2076                 unit_len = MAX(unit_len, strlen(j->name));
2077                 type_len = MAX(type_len, strlen(j->type));
2078                 state_len = MAX(state_len, strlen(j->state));
2079         }
2080
2081         if (!arg_full && id_len + 1 + unit_len + type_len + 1 + state_len > columns()) {
2082                 unit_len = MAX(33u, columns() - id_len - type_len - state_len - 3);
2083                 shorten = true;
2084         }
2085
2086         if (!arg_no_legend)
2087                 printf("%*s %-*s %-*s %-*s\n",
2088                        id_len, "JOB",
2089                        unit_len, "UNIT",
2090                        type_len, "TYPE",
2091                        state_len, "STATE");
2092
2093         for (j = jobs; j < jobs + n; j++) {
2094                 _cleanup_free_ char *e = NULL;
2095
2096                 if (streq(j->state, "running")) {
2097                         on = ansi_highlight();
2098                         off = ansi_highlight_off();
2099                 } else
2100                         on = off = "";
2101
2102                 e = shorten ? ellipsize(j->name, unit_len, 33) : NULL;
2103                 printf("%*u %s%-*s%s %-*s %s%-*s%s\n",
2104                        id_len, j->id,
2105                        on, unit_len, e ? e : j->name, off,
2106                        type_len, j->type,
2107                        on, state_len, j->state, off);
2108         }
2109
2110         if (!arg_no_legend) {
2111                 on = ansi_highlight();
2112                 off = ansi_highlight_off();
2113
2114                 printf("\n%s%u jobs listed%s.\n", on, n, off);
2115         }
2116 }
2117
2118 static bool output_show_job(struct job_info *job, char **patterns) {
2119         char **pattern;
2120
2121         assert(job);
2122
2123         if (strv_isempty(patterns))
2124                 return true;
2125
2126         STRV_FOREACH(pattern, patterns)
2127                 if (fnmatch(*pattern, job->name, FNM_NOESCAPE) == 0)
2128                         return true;
2129         return false;
2130 }
2131
2132 static int list_jobs(sd_bus *bus, char **args) {
2133         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2134         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2135         const char *name, *type, *state, *job_path, *unit_path;
2136         _cleanup_free_ struct job_info *jobs = NULL;
2137         size_t size = 0;
2138         unsigned c = 0;
2139         uint32_t id;
2140         int r;
2141         bool skipped = false;
2142
2143         r = sd_bus_call_method(
2144                         bus,
2145                         "org.freedesktop.systemd1",
2146                         "/org/freedesktop/systemd1",
2147                         "org.freedesktop.systemd1.Manager",
2148                         "ListJobs",
2149                         &error,
2150                         &reply,
2151                         NULL);
2152         if (r < 0) {
2153                 log_error("Failed to list jobs: %s", bus_error_message(&error, r));
2154                 return r;
2155         }
2156
2157         r = sd_bus_message_enter_container(reply, 'a', "(usssoo)");
2158         if (r < 0)
2159                 return bus_log_parse_error(r);
2160
2161         while ((r = sd_bus_message_read(reply, "(usssoo)", &id, &name, &type, &state, &job_path, &unit_path)) > 0) {
2162                 struct job_info job = { id, name, type, state };
2163
2164                 if (!output_show_job(&job, strv_skip_first(args))) {
2165                         skipped = true;
2166                         continue;
2167                 }
2168
2169                 if (!GREEDY_REALLOC(jobs, size, c + 1))
2170                         return log_oom();
2171
2172                 jobs[c++] = job;
2173         }
2174         if (r < 0)
2175                 return bus_log_parse_error(r);
2176
2177         r = sd_bus_message_exit_container(reply);
2178         if (r < 0)
2179                 return bus_log_parse_error(r);
2180
2181         output_jobs_list(jobs, c, skipped);
2182         return r;
2183 }
2184
2185 static int cancel_job(sd_bus *bus, char **args) {
2186         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2187         char **name;
2188         int r = 0;
2189
2190         assert(args);
2191
2192         if (strv_length(args) <= 1)
2193                 return daemon_reload(bus, args);
2194
2195         STRV_FOREACH(name, args+1) {
2196                 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
2197                 uint32_t id;
2198                 int q;
2199
2200                 q = safe_atou32(*name, &id);
2201                 if (q < 0)
2202                         return log_error_errno(q, "Failed to parse job id \"%s\": %m", *name);
2203
2204                 q = sd_bus_message_new_method_call(
2205                                 bus,
2206                                 &m,
2207                                 "org.freedesktop.systemd1",
2208                                 "/org/freedesktop/systemd1",
2209                                 "org.freedesktop.systemd1.Manager",
2210                                 "CancelJob");
2211                 if (q < 0)
2212                         return bus_log_create_error(q);
2213
2214                 q = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
2215                 if (q < 0)
2216                         return bus_log_create_error(1);
2217
2218                 q = sd_bus_message_append(m, "u", id);
2219                 if (q < 0)
2220                         return bus_log_create_error(q);
2221
2222                 q = sd_bus_call(bus, m, 0, &error, NULL);
2223                 if (q < 0) {
2224                         log_error("Failed to cancel job %"PRIu32": %s", id, bus_error_message(&error, q));
2225                         if (r == 0)
2226                                 r = q;
2227                 }
2228         }
2229
2230         return r;
2231 }
2232
2233 static int need_daemon_reload(sd_bus *bus, const char *unit) {
2234         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2235         const char *path;
2236         int b, r;
2237
2238         /* We ignore all errors here, since this is used to show a
2239          * warning only */
2240
2241         /* We don't use unit_dbus_path_from_name() directly since we
2242          * don't want to load the unit if it isn't loaded. */
2243
2244         r = sd_bus_call_method(
2245                         bus,
2246                         "org.freedesktop.systemd1",
2247                         "/org/freedesktop/systemd1",
2248                         "org.freedesktop.systemd1.Manager",
2249                         "GetUnit",
2250                         NULL,
2251                         &reply,
2252                         "s", unit);
2253         if (r < 0)
2254                 return r;
2255
2256         r = sd_bus_message_read(reply, "o", &path);
2257         if (r < 0)
2258                 return r;
2259
2260         r = sd_bus_get_property_trivial(
2261                         bus,
2262                         "org.freedesktop.systemd1",
2263                         path,
2264                         "org.freedesktop.systemd1.Unit",
2265                         "NeedDaemonReload",
2266                         NULL,
2267                         'b', &b);
2268         if (r < 0)
2269                 return r;
2270
2271         return b;
2272 }
2273
2274 static void warn_unit_file_changed(const char *name) {
2275         log_warning("%sWarning:%s %s changed on disk. Run 'systemctl%s daemon-reload' to reload units.",
2276                     ansi_highlight_red(),
2277                     ansi_highlight_off(),
2278                     name,
2279                     arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
2280 }
2281
2282 static int unit_file_find_path(LookupPaths *lp, const char *unit_name, char **unit_path) {
2283         char **p;
2284
2285         assert(lp);
2286         assert(unit_name);
2287         assert(unit_path);
2288
2289         STRV_FOREACH(p, lp->unit_path) {
2290                 _cleanup_free_ char *path;
2291
2292                 path = path_join(arg_root, *p, unit_name);
2293                 if (!path)
2294                         return log_oom();
2295
2296                 if (access(path, F_OK) == 0) {
2297                         *unit_path = path;
2298                         path = NULL;
2299                         return 1;
2300                 }
2301         }
2302
2303         return 0;
2304 }
2305
2306 static int unit_find_paths(sd_bus *bus,
2307                            const char *unit_name,
2308                            bool avoid_bus_cache,
2309                            LookupPaths *lp,
2310                            char **fragment_path,
2311                            char ***dropin_paths) {
2312         int r;
2313
2314         /**
2315          * Finds where the unit is defined on disk. Returns 0 if the unit
2316          * is not found. Returns 1 if it is found, and sets
2317          * - the path to the unit in *path, if it exists on disk,
2318          * - and a strv of existing drop-ins in *dropins,
2319          *   if the arg is not NULL and any dropins were found.
2320          */
2321
2322         assert(unit_name);
2323         assert(fragment_path);
2324         assert(lp);
2325
2326         if (!avoid_bus_cache && !unit_name_is_template(unit_name)) {
2327                 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2328                 _cleanup_free_ char *unit = NULL;
2329                 _cleanup_free_ char *path = NULL;
2330                 _cleanup_strv_free_ char **dropins = NULL;
2331
2332                 unit = unit_dbus_path_from_name(unit_name);
2333                 if (!unit)
2334                         return log_oom();
2335
2336                 if (need_daemon_reload(bus, unit_name) > 0)
2337                         warn_unit_file_changed(unit_name);
2338
2339                 r = sd_bus_get_property_string(
2340                                 bus,
2341                                 "org.freedesktop.systemd1",
2342                                 unit,
2343                                 "org.freedesktop.systemd1.Unit",
2344                                 "FragmentPath",
2345                                 &error,
2346                                 &path);
2347                 if (r < 0)
2348                         return log_error_errno(r, "Failed to get FragmentPath: %s", bus_error_message(&error, r));
2349
2350                 r = sd_bus_get_property_strv(
2351                                 bus,
2352                                 "org.freedesktop.systemd1",
2353                                 unit,
2354                                 "org.freedesktop.systemd1.Unit",
2355                                 "DropInPaths",
2356                                 &error,
2357                                 &dropins);
2358                 if (r < 0)
2359                         return log_error_errno(r, "Failed to get DropInPaths: %s", bus_error_message(&error, r));
2360
2361                 r = 0;
2362                 if (!isempty(path)) {
2363                         *fragment_path = path;
2364                         path = NULL;
2365                         r = 1;
2366                 }
2367
2368                 if (dropin_paths && !strv_isempty(dropins)) {
2369                         *dropin_paths = dropins;
2370                         dropins = NULL;
2371                         r = 1;
2372                 }
2373         } else {
2374                 _cleanup_set_free_ Set *names;
2375
2376                 names = set_new(NULL);
2377                 if (!names)
2378                         return -ENOMEM;
2379
2380                 r = set_put(names, unit_name);
2381                 if (r < 0)
2382                         return r;
2383
2384                 r = unit_file_find_path(lp, unit_name, fragment_path);
2385                 if (r < 0)
2386                         return r;
2387
2388                 if (r == 0) {
2389                         _cleanup_free_ char *template;
2390
2391                         template = unit_name_template(unit_name);
2392                         if (!template)
2393                                 return log_oom();
2394
2395                         if (!streq(template, unit_name)) {
2396                                 r = unit_file_find_path(lp, template, fragment_path);
2397                                 if (r < 0)
2398                                         return r;
2399                         }
2400                 }
2401
2402                 if (dropin_paths)
2403                         r = unit_file_find_dropin_paths(lp->unit_path, NULL, names, dropin_paths);
2404         }
2405
2406         return r;
2407 }
2408
2409 static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet) {
2410         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2411         _cleanup_free_ char *n = NULL, *state = NULL;
2412         const char *path;
2413         int r;
2414
2415         assert(name);
2416
2417         n = unit_name_mangle(name, MANGLE_NOGLOB);
2418         if (!n)
2419                 return log_oom();
2420
2421         /* We don't use unit_dbus_path_from_name() directly since we
2422          * don't want to load the unit if it isn't loaded. */
2423
2424         r = sd_bus_call_method(
2425                         bus,
2426                         "org.freedesktop.systemd1",
2427                         "/org/freedesktop/systemd1",
2428                         "org.freedesktop.systemd1.Manager",
2429                         "GetUnit",
2430                         NULL,
2431                         &reply,
2432                         "s", n);
2433         if (r < 0) {
2434                 if (!quiet)
2435                         puts("unknown");
2436                 return 0;
2437         }
2438
2439         r = sd_bus_message_read(reply, "o", &path);
2440         if (r < 0)
2441                 return bus_log_parse_error(r);
2442
2443         r = sd_bus_get_property_string(
2444                         bus,
2445                         "org.freedesktop.systemd1",
2446                         path,
2447                         "org.freedesktop.systemd1.Unit",
2448                         "ActiveState",
2449                         NULL,
2450                         &state);
2451         if (r < 0) {
2452                 if (!quiet)
2453                         puts("unknown");
2454                 return 0;
2455         }
2456
2457         if (!quiet)
2458                 puts(state);
2459
2460         return nulstr_contains(good_states, state);
2461 }
2462
2463 static int check_triggering_units(
2464                 sd_bus *bus,
2465                 const char *name) {
2466
2467         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2468         _cleanup_free_ char *path = NULL, *n = NULL, *state = NULL;
2469         _cleanup_strv_free_ char **triggered_by = NULL;
2470         bool print_warning_label = true;
2471         char **i;
2472         int r;
2473
2474         n = unit_name_mangle(name, MANGLE_NOGLOB);
2475         if (!n)
2476                 return log_oom();
2477
2478         path = unit_dbus_path_from_name(n);
2479         if (!path)
2480                 return log_oom();
2481
2482         r = sd_bus_get_property_string(
2483                         bus,
2484                         "org.freedesktop.systemd1",
2485                         path,
2486                         "org.freedesktop.systemd1.Unit",
2487                         "LoadState",
2488                         &error,
2489                         &state);
2490         if (r < 0) {
2491                 log_error("Failed to get load state of %s: %s", n, bus_error_message(&error, r));
2492                 return r;
2493         }
2494
2495         if (streq(state, "masked"))
2496                 return 0;
2497
2498         r = sd_bus_get_property_strv(
2499                         bus,
2500                         "org.freedesktop.systemd1",
2501                         path,
2502                         "org.freedesktop.systemd1.Unit",
2503                         "TriggeredBy",
2504                         &error,
2505                         &triggered_by);
2506         if (r < 0) {
2507                 log_error("Failed to get triggered by array of %s: %s", n, bus_error_message(&error, r));
2508                 return r;
2509         }
2510
2511         STRV_FOREACH(i, triggered_by) {
2512                 r = check_one_unit(bus, *i, "active\0reloading\0", true);
2513                 if (r < 0)
2514                         return log_error_errno(r, "Failed to check unit: %m");
2515
2516                 if (r == 0)
2517                         continue;
2518
2519                 if (print_warning_label) {
2520                         log_warning("Warning: Stopping %s, but it can still be activated by:", n);
2521                         print_warning_label = false;
2522                 }
2523
2524                 log_warning("  %s", *i);
2525         }
2526
2527         return 0;
2528 }
2529
2530 static const struct {
2531         const char *verb;
2532         const char *method;
2533 } unit_actions[] = {
2534         { "start",                 "StartUnit" },
2535         { "stop",                  "StopUnit" },
2536         { "condstop",              "StopUnit" },
2537         { "reload",                "ReloadUnit" },
2538         { "restart",               "RestartUnit" },
2539         { "try-restart",           "TryRestartUnit" },
2540         { "condrestart",           "TryRestartUnit" },
2541         { "reload-or-restart",     "ReloadOrRestartUnit" },
2542         { "reload-or-try-restart", "ReloadOrTryRestartUnit" },
2543         { "condreload",            "ReloadOrTryRestartUnit" },
2544         { "force-reload",          "ReloadOrTryRestartUnit" }
2545 };
2546
2547 static const char *verb_to_method(const char *verb) {
2548        uint i;
2549
2550        for (i = 0; i < ELEMENTSOF(unit_actions); i++)
2551                 if (streq_ptr(unit_actions[i].verb, verb))
2552                         return unit_actions[i].method;
2553
2554        return "StartUnit";
2555 }
2556
2557 static const char *method_to_verb(const char *method) {
2558        uint i;
2559
2560        for (i = 0; i < ELEMENTSOF(unit_actions); i++)
2561                 if (streq_ptr(unit_actions[i].method, method))
2562                         return unit_actions[i].verb;
2563
2564        return "n/a";
2565 }
2566
2567 static int start_unit_one(
2568                 sd_bus *bus,
2569                 const char *method,
2570                 const char *name,
2571                 const char *mode,
2572                 sd_bus_error *error,
2573                 BusWaitForJobs *w) {
2574
2575         _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
2576         const char *path;
2577         int r;
2578
2579         assert(method);
2580         assert(name);
2581         assert(mode);
2582         assert(error);
2583
2584         log_debug("Calling manager for %s on %s, %s", method, name, mode);
2585
2586         r = sd_bus_message_new_method_call(
2587                         bus,
2588                         &m,
2589                         "org.freedesktop.systemd1",
2590                         "/org/freedesktop/systemd1",
2591                         "org.freedesktop.systemd1.Manager",
2592                         method);
2593         if (r < 0)
2594                 return bus_log_create_error(r);
2595
2596         r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
2597         if (r < 0)
2598                 return bus_log_create_error(r);
2599
2600         r = sd_bus_message_append(m, "ss", name, mode);
2601         if (r < 0)
2602                 return bus_log_create_error(r);
2603
2604         r = sd_bus_call(bus, m, 0, error, &reply);
2605         if (r < 0) {
2606                 const char *verb;
2607
2608                 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
2609                         /* There's always a fallback possible for
2610                          * legacy actions. */
2611                         return -EADDRNOTAVAIL;
2612
2613                 verb = method_to_verb(method);
2614
2615                 log_error("Failed to %s %s: %s", verb, name, bus_error_message(error, r));
2616                 return r;
2617         }
2618
2619         r = sd_bus_message_read(reply, "o", &path);
2620         if (r < 0)
2621                 return bus_log_parse_error(r);
2622
2623         if (need_daemon_reload(bus, name) > 0)
2624                 warn_unit_file_changed(name);
2625
2626         if (w) {
2627                 log_debug("Adding %s to the set", path);
2628                 r = bus_wait_for_jobs_add(w, path);
2629                 if (r < 0)
2630                         return log_oom();
2631         }
2632
2633         return 0;
2634 }
2635
2636 static int expand_names(sd_bus *bus, char **names, const char* suffix, char ***ret) {
2637
2638         _cleanup_strv_free_ char **mangled = NULL, **globs = NULL;
2639         char **name;
2640         int r = 0, i;
2641
2642         STRV_FOREACH(name, names) {
2643                 char *t;
2644
2645                 if (suffix)
2646                         t = unit_name_mangle_with_suffix(*name, MANGLE_GLOB, suffix);
2647                 else
2648                         t = unit_name_mangle(*name, MANGLE_GLOB);
2649                 if (!t)
2650                         return log_oom();
2651
2652                 if (string_is_glob(t))
2653                         r = strv_consume(&globs, t);
2654                 else
2655                         r = strv_consume(&mangled, t);
2656                 if (r < 0)
2657                         return log_oom();
2658         }
2659
2660         /* Query the manager only if any of the names are a glob, since
2661          * this is fairly expensive */
2662         if (!strv_isempty(globs)) {
2663                 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2664                 _cleanup_free_ UnitInfo *unit_infos = NULL;
2665
2666                 if (!bus)
2667                         return log_error_errno(ENOTSUP, "Unit name globbing without bus is not implemented.");
2668
2669                 r = get_unit_list(bus, NULL, globs, &unit_infos, 0, &reply);
2670                 if (r < 0)
2671                         return r;
2672
2673                 for (i = 0; i < r; i++)
2674                         if (strv_extend(&mangled, unit_infos[i].id) < 0)
2675                                 return log_oom();
2676         }
2677
2678         *ret = mangled;
2679         mangled = NULL; /* do not free */
2680
2681         return 0;
2682 }
2683
2684 static const struct {
2685         const char *target;
2686         const char *verb;
2687         const char *mode;
2688 } action_table[_ACTION_MAX] = {
2689         [ACTION_HALT]         = { SPECIAL_HALT_TARGET,         "halt",         "replace-irreversibly" },
2690         [ACTION_POWEROFF]     = { SPECIAL_POWEROFF_TARGET,     "poweroff",     "replace-irreversibly" },
2691         [ACTION_REBOOT]       = { SPECIAL_REBOOT_TARGET,       "reboot",       "replace-irreversibly" },
2692         [ACTION_KEXEC]        = { SPECIAL_KEXEC_TARGET,        "kexec",        "replace-irreversibly" },
2693         [ACTION_RUNLEVEL2]    = { SPECIAL_RUNLEVEL2_TARGET,    NULL,           "isolate" },
2694         [ACTION_RUNLEVEL3]    = { SPECIAL_RUNLEVEL3_TARGET,    NULL,           "isolate" },
2695         [ACTION_RUNLEVEL4]    = { SPECIAL_RUNLEVEL4_TARGET,    NULL,           "isolate" },
2696         [ACTION_RUNLEVEL5]    = { SPECIAL_RUNLEVEL5_TARGET,    NULL,           "isolate" },
2697         [ACTION_RESCUE]       = { SPECIAL_RESCUE_TARGET,       "rescue",       "isolate" },
2698         [ACTION_EMERGENCY]    = { SPECIAL_EMERGENCY_TARGET,    "emergency",    "isolate" },
2699         [ACTION_DEFAULT]      = { SPECIAL_DEFAULT_TARGET,      "default",      "isolate" },
2700         [ACTION_EXIT]         = { SPECIAL_EXIT_TARGET,         "exit",         "replace-irreversibly" },
2701         [ACTION_SUSPEND]      = { SPECIAL_SUSPEND_TARGET,      "suspend",      "replace-irreversibly" },
2702         [ACTION_HIBERNATE]    = { SPECIAL_HIBERNATE_TARGET,    "hibernate",    "replace-irreversibly" },
2703         [ACTION_HYBRID_SLEEP] = { SPECIAL_HYBRID_SLEEP_TARGET, "hybrid-sleep", "replace-irreversibly" },
2704 };
2705
2706 static enum action verb_to_action(const char *verb) {
2707         enum action i;
2708
2709         for (i = _ACTION_INVALID; i < _ACTION_MAX; i++)
2710                 if (streq_ptr(action_table[i].verb, verb))
2711                         return i;
2712
2713         return _ACTION_INVALID;
2714 }
2715
2716 static int start_unit(sd_bus *bus, char **args) {
2717         _cleanup_(bus_wait_for_jobs_freep) BusWaitForJobs *w = NULL;
2718         const char *method, *mode, *one_name, *suffix = NULL;
2719         _cleanup_strv_free_ char **names = NULL;
2720         char **name;
2721         int r = 0;
2722
2723         assert(bus);
2724
2725         ask_password_agent_open_if_enabled();
2726
2727         if (arg_action == ACTION_SYSTEMCTL) {
2728                 enum action action;
2729                 method = verb_to_method(args[0]);
2730                 action = verb_to_action(args[0]);
2731
2732                 if (streq(args[0], "isolate")) {
2733                         mode = "isolate";
2734                         suffix = ".target";
2735                 } else
2736                         mode = action_table[action].mode ?: arg_job_mode;
2737
2738                 one_name = action_table[action].target;
2739         } else {
2740                 assert(arg_action < ELEMENTSOF(action_table));
2741                 assert(action_table[arg_action].target);
2742
2743                 method = "StartUnit";
2744
2745                 mode = action_table[arg_action].mode;
2746                 one_name = action_table[arg_action].target;
2747         }
2748
2749         if (one_name)
2750                 names = strv_new(one_name, NULL);
2751         else {
2752                 r = expand_names(bus, args + 1, suffix, &names);
2753                 if (r < 0)
2754                         log_error_errno(r, "Failed to expand names: %m");
2755         }
2756
2757         if (!arg_no_block) {
2758                 r = bus_wait_for_jobs_new(bus, &w);
2759                 if (r < 0)
2760                         return log_error_errno(r, "Could not watch jobs: %m");
2761         }
2762
2763         STRV_FOREACH(name, names) {
2764                 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2765                 int q;
2766
2767                 q = start_unit_one(bus, method, *name, mode, &error, w);
2768                 if (r >= 0 && q < 0)
2769                         r = translate_bus_error_to_exit_status(q, &error);
2770         }
2771
2772         if (!arg_no_block) {
2773                 int q;
2774
2775                 q = bus_wait_for_jobs(w, arg_quiet);
2776                 if (q < 0)
2777                         return q;
2778
2779                 /* When stopping units, warn if they can still be triggered by
2780                  * another active unit (socket, path, timer) */
2781                 if (!arg_quiet && streq(method, "StopUnit"))
2782                         STRV_FOREACH(name, names)
2783                                 check_triggering_units(bus, *name);
2784         }
2785
2786         return r;
2787 }
2788
2789 /* Ask systemd-logind, which might grant access to unprivileged users
2790  * through PolicyKit */
2791 static int reboot_with_logind(sd_bus *bus, enum action a) {
2792 #ifdef HAVE_LOGIND
2793         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2794         const char *method;
2795         int r;
2796
2797         if (!bus)
2798                 return -EIO;
2799
2800         polkit_agent_open_if_enabled();
2801
2802         switch (a) {
2803
2804         case ACTION_REBOOT:
2805                 method = "Reboot";
2806                 break;
2807
2808         case ACTION_POWEROFF:
2809                 method = "PowerOff";
2810                 break;
2811
2812         case ACTION_SUSPEND:
2813                 method = "Suspend";
2814                 break;
2815
2816         case ACTION_HIBERNATE:
2817                 method = "Hibernate";
2818                 break;
2819
2820         case ACTION_HYBRID_SLEEP:
2821                 method = "HybridSleep";
2822                 break;
2823
2824         default:
2825                 return -EINVAL;
2826         }
2827
2828         r = sd_bus_call_method(
2829                         bus,
2830                         "org.freedesktop.login1",
2831                         "/org/freedesktop/login1",
2832                         "org.freedesktop.login1.Manager",
2833                         method,
2834                         &error,
2835                         NULL,
2836                         "b", arg_ask_password);
2837         if (r < 0)
2838                 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
2839
2840         return r;
2841 #else
2842         return -ENOSYS;
2843 #endif
2844 }
2845
2846 static int check_inhibitors(sd_bus *bus, enum action a) {
2847 #ifdef HAVE_LOGIND
2848         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2849         _cleanup_strv_free_ char **sessions = NULL;
2850         const char *what, *who, *why, *mode;
2851         uint32_t uid, pid;
2852         unsigned c = 0;
2853         char **s;
2854         int r;
2855
2856         if (!bus)
2857                 return 0;
2858
2859         if (arg_ignore_inhibitors || arg_force > 0)
2860                 return 0;
2861
2862         if (arg_when > 0)
2863                 return 0;
2864
2865         if (geteuid() == 0)
2866                 return 0;
2867
2868         if (!on_tty())
2869                 return 0;
2870
2871         r = sd_bus_call_method(
2872                         bus,
2873                         "org.freedesktop.login1",
2874                         "/org/freedesktop/login1",
2875                         "org.freedesktop.login1.Manager",
2876                         "ListInhibitors",
2877                         NULL,
2878                         &reply,
2879                         NULL);
2880         if (r < 0)
2881                 /* If logind is not around, then there are no inhibitors... */
2882                 return 0;
2883
2884         r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssuu)");
2885         if (r < 0)
2886                 return bus_log_parse_error(r);
2887
2888         while ((r = sd_bus_message_read(reply, "(ssssuu)", &what, &who, &why, &mode, &uid, &pid)) > 0) {
2889                 _cleanup_free_ char *comm = NULL, *user = NULL;
2890                 _cleanup_strv_free_ char **sv = NULL;
2891
2892                 if (!streq(mode, "block"))
2893                         continue;
2894
2895                 sv = strv_split(what, ":");
2896                 if (!sv)
2897                         return log_oom();
2898
2899                 if (!strv_contains(sv,
2900                                   a == ACTION_HALT ||
2901                                   a == ACTION_POWEROFF ||
2902                                   a == ACTION_REBOOT ||
2903                                   a == ACTION_KEXEC ? "shutdown" : "sleep"))
2904                         continue;
2905
2906                 get_process_comm(pid, &comm);
2907                 user = uid_to_name(uid);
2908
2909                 log_warning("Operation inhibited by \"%s\" (PID "PID_FMT" \"%s\", user %s), reason is \"%s\".",
2910                             who, pid, strna(comm), strna(user), why);
2911
2912                 c++;
2913         }
2914         if (r < 0)
2915                 return bus_log_parse_error(r);
2916
2917         r = sd_bus_message_exit_container(reply);
2918         if (r < 0)
2919                 return bus_log_parse_error(r);
2920
2921         /* Check for current sessions */
2922         sd_get_sessions(&sessions);
2923         STRV_FOREACH(s, sessions) {
2924                 _cleanup_free_ char *type = NULL, *tty = NULL, *seat = NULL, *user = NULL, *service = NULL, *class = NULL;
2925
2926                 if (sd_session_get_uid(*s, &uid) < 0 || uid == getuid())
2927                         continue;
2928
2929                 if (sd_session_get_class(*s, &class) < 0 || !streq(class, "user"))
2930                         continue;
2931
2932                 if (sd_session_get_type(*s, &type) < 0 || (!streq(type, "x11") && !streq(type, "tty")))
2933                         continue;
2934
2935                 sd_session_get_tty(*s, &tty);
2936                 sd_session_get_seat(*s, &seat);
2937                 sd_session_get_service(*s, &service);
2938                 user = uid_to_name(uid);
2939
2940                 log_warning("User %s is logged in on %s.", strna(user), isempty(tty) ? (isempty(seat) ? strna(service) : seat) : tty);
2941                 c++;
2942         }
2943
2944         if (c <= 0)
2945                 return 0;
2946
2947         log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
2948                   action_table[a].verb);
2949
2950         return -EPERM;
2951 #else
2952         return 0;
2953 #endif
2954 }
2955
2956 static int start_special(sd_bus *bus, char **args) {
2957         enum action a;
2958         int r;
2959
2960         assert(args);
2961
2962         a = verb_to_action(args[0]);
2963
2964         r = check_inhibitors(bus, a);
2965         if (r < 0)
2966                 return r;
2967
2968         if (arg_force >= 2 && geteuid() != 0) {
2969                 log_error("Must be root.");
2970                 return -EPERM;
2971         }
2972
2973         if (arg_force >= 2 &&
2974             (a == ACTION_HALT ||
2975              a == ACTION_POWEROFF ||
2976              a == ACTION_REBOOT))
2977                 return halt_now(a);
2978
2979         if (arg_force >= 1 &&
2980             (a == ACTION_HALT ||
2981              a == ACTION_POWEROFF ||
2982              a == ACTION_REBOOT ||
2983              a == ACTION_KEXEC ||
2984              a == ACTION_EXIT))
2985                 return daemon_reload(bus, args);
2986
2987         /* first try logind, to allow authentication with polkit */
2988         if (geteuid() != 0 &&
2989             (a == ACTION_POWEROFF ||
2990              a == ACTION_REBOOT ||
2991              a == ACTION_SUSPEND ||
2992              a == ACTION_HIBERNATE ||
2993              a == ACTION_HYBRID_SLEEP)) {
2994                 r = reboot_with_logind(bus, a);
2995                 if (r >= 0)
2996                         return r;
2997         }
2998
2999         r = start_unit(bus, args);
3000         if (r == EXIT_SUCCESS)
3001                 warn_wall(a);
3002
3003         return r;
3004 }
3005
3006 static int check_unit_generic(sd_bus *bus, int code, const char *good_states, char **args) {
3007         _cleanup_strv_free_ char **names = NULL;
3008         char **name;
3009         int r;
3010
3011         assert(bus);
3012         assert(args);
3013
3014         r = expand_names(bus, args, NULL, &names);
3015         if (r < 0)
3016                 return log_error_errno(r, "Failed to expand names: %m");
3017
3018         STRV_FOREACH(name, names) {
3019                 int state;
3020
3021                 state = check_one_unit(bus, *name, good_states, arg_quiet);
3022                 if (state < 0)
3023                         return state;
3024                 if (state == 0)
3025                         r = code;
3026         }
3027
3028         return r;
3029 }
3030
3031 static int check_unit_active(sd_bus *bus, char **args) {
3032         /* According to LSB: 3, "program is not running" */
3033         return check_unit_generic(bus, 3, "active\0reloading\0", args + 1);
3034 }
3035
3036 static int check_unit_failed(sd_bus *bus, char **args) {
3037         return check_unit_generic(bus, 1, "failed\0", args + 1);
3038 }
3039
3040 static int kill_unit(sd_bus *bus, char **args) {
3041         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3042         _cleanup_strv_free_ char **names = NULL;
3043         char **name;
3044         int r, q;
3045
3046         assert(bus);
3047         assert(args);
3048
3049         if (!arg_kill_who)
3050                 arg_kill_who = "all";
3051
3052         r = expand_names(bus, args + 1, NULL, &names);
3053         if (r < 0)
3054                 log_error_errno(r, "Failed to expand names: %m");
3055
3056         STRV_FOREACH(name, names) {
3057                 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
3058
3059                 q = sd_bus_message_new_method_call(
3060                                 bus,
3061                                 &m,
3062                                 "org.freedesktop.systemd1",
3063                                 "/org/freedesktop/systemd1",
3064                                 "org.freedesktop.systemd1.Manager",
3065                                 "KillUnit");
3066                 if (q < 0)
3067                         return bus_log_create_error(q);
3068
3069                 q = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
3070                 if (q < 0)
3071                         return bus_log_create_error(q);
3072
3073                 q = sd_bus_message_append(m, "ssi", *names, arg_kill_who, arg_signal);
3074                 if (q < 0)
3075                         return bus_log_create_error(q);
3076
3077                 q = sd_bus_call(bus, m, 0, &error, NULL);
3078                 if (q < 0) {
3079                         log_error("Failed to kill unit %s: %s", *names, bus_error_message(&error, q));
3080                         if (r == 0)
3081                                 r = q;
3082                 }
3083         }
3084
3085         return r;
3086 }
3087
3088 typedef struct ExecStatusInfo {
3089         char *name;
3090
3091         char *path;
3092         char **argv;
3093
3094         bool ignore;
3095
3096         usec_t start_timestamp;
3097         usec_t exit_timestamp;
3098         pid_t pid;
3099         int code;
3100         int status;
3101
3102         LIST_FIELDS(struct ExecStatusInfo, exec);
3103 } ExecStatusInfo;
3104
3105 static void exec_status_info_free(ExecStatusInfo *i) {
3106         assert(i);
3107
3108         free(i->name);
3109         free(i->path);
3110         strv_free(i->argv);
3111         free(i);
3112 }
3113
3114 static int exec_status_info_deserialize(sd_bus_message *m, ExecStatusInfo *i) {
3115         uint64_t start_timestamp, exit_timestamp, start_timestamp_monotonic, exit_timestamp_monotonic;
3116         const char *path;
3117         uint32_t pid;
3118         int32_t code, status;
3119         int ignore, r;
3120
3121         assert(m);
3122         assert(i);
3123
3124         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_STRUCT, "sasbttttuii");
3125         if (r < 0)
3126                 return bus_log_parse_error(r);
3127         else if (r == 0)
3128                 return 0;
3129
3130         r = sd_bus_message_read(m, "s", &path);
3131         if (r < 0)
3132                 return bus_log_parse_error(r);
3133
3134         i->path = strdup(path);
3135         if (!i->path)
3136                 return log_oom();
3137
3138         r = sd_bus_message_read_strv(m, &i->argv);
3139         if (r < 0)
3140                 return bus_log_parse_error(r);
3141
3142         r = sd_bus_message_read(m,
3143                                 "bttttuii",
3144                                 &ignore,
3145                                 &start_timestamp, &start_timestamp_monotonic,
3146                                 &exit_timestamp, &exit_timestamp_monotonic,
3147                                 &pid,
3148                                 &code, &status);
3149         if (r < 0)
3150                 return bus_log_parse_error(r);
3151
3152         i->ignore = ignore;
3153         i->start_timestamp = (usec_t) start_timestamp;
3154         i->exit_timestamp = (usec_t) exit_timestamp;
3155         i->pid = (pid_t) pid;
3156         i->code = code;
3157         i->status = status;
3158
3159         r = sd_bus_message_exit_container(m);
3160         if (r < 0)
3161                 return bus_log_parse_error(r);
3162
3163         return 1;
3164 }
3165
3166 typedef struct UnitStatusInfo {
3167         const char *id;
3168         const char *load_state;
3169         const char *active_state;
3170         const char *sub_state;
3171         const char *unit_file_state;
3172         const char *unit_file_preset;
3173
3174         const char *description;
3175         const char *following;
3176
3177         char **documentation;
3178
3179         const char *fragment_path;
3180         const char *source_path;
3181         const char *control_group;
3182
3183         char **dropin_paths;
3184
3185         const char *load_error;
3186         const char *result;
3187
3188         usec_t inactive_exit_timestamp;
3189         usec_t inactive_exit_timestamp_monotonic;
3190         usec_t active_enter_timestamp;
3191         usec_t active_exit_timestamp;
3192         usec_t inactive_enter_timestamp;
3193
3194         bool need_daemon_reload;
3195
3196         /* Service */
3197         pid_t main_pid;
3198         pid_t control_pid;
3199         const char *status_text;
3200         const char *pid_file;
3201         bool running:1;
3202         int status_errno;
3203
3204         usec_t start_timestamp;
3205         usec_t exit_timestamp;
3206
3207         int exit_code, exit_status;
3208
3209         usec_t condition_timestamp;
3210         bool condition_result;
3211         bool failed_condition_trigger;
3212         bool failed_condition_negate;
3213         const char *failed_condition;
3214         const char *failed_condition_parameter;
3215
3216         usec_t assert_timestamp;
3217         bool assert_result;
3218         bool failed_assert_trigger;
3219         bool failed_assert_negate;
3220         const char *failed_assert;
3221         const char *failed_assert_parameter;
3222
3223         /* Socket */
3224         unsigned n_accepted;
3225         unsigned n_connections;
3226         bool accept;
3227
3228         /* Pairs of type, path */
3229         char **listen;
3230
3231         /* Device */
3232         const char *sysfs_path;
3233
3234         /* Mount, Automount */
3235         const char *where;
3236
3237         /* Swap */
3238         const char *what;
3239
3240         LIST_HEAD(ExecStatusInfo, exec);
3241 } UnitStatusInfo;
3242
3243 static void print_status_info(
3244                 UnitStatusInfo *i,
3245                 bool *ellipsized) {
3246
3247         ExecStatusInfo *p;
3248         const char *active_on, *active_off, *on, *off, *ss;
3249         usec_t timestamp;
3250         char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
3251         char since2[FORMAT_TIMESTAMP_MAX], *s2;
3252         const char *path;
3253         int flags =
3254                 arg_all * OUTPUT_SHOW_ALL |
3255                 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
3256                 on_tty() * OUTPUT_COLOR |
3257                 !arg_quiet * OUTPUT_WARN_CUTOFF |
3258                 arg_full * OUTPUT_FULL_WIDTH;
3259         char **t, **t2;
3260
3261         assert(i);
3262
3263         /* This shows pretty information about a unit. See
3264          * print_property() for a low-level property printer */
3265
3266         if (streq_ptr(i->active_state, "failed")) {
3267                 active_on = ansi_highlight_red();
3268                 active_off = ansi_highlight_off();
3269         } else if (streq_ptr(i->active_state, "active") || streq_ptr(i->active_state, "reloading")) {
3270                 active_on = ansi_highlight_green();
3271                 active_off = ansi_highlight_off();
3272         } else
3273                 active_on = active_off = "";
3274
3275         printf("%s%s%s %s", active_on, draw_special_char(DRAW_BLACK_CIRCLE), active_off, strna(i->id));
3276
3277         if (i->description && !streq_ptr(i->id, i->description))
3278                 printf(" - %s", i->description);
3279
3280         printf("\n");
3281
3282         if (i->following)
3283                 printf("   Follow: unit currently follows state of %s\n", i->following);
3284
3285         if (streq_ptr(i->load_state, "error")) {
3286                 on = ansi_highlight_red();
3287                 off = ansi_highlight_off();
3288         } else
3289                 on = off = "";
3290
3291         path = i->source_path ? i->source_path : i->fragment_path;
3292
3293         if (i->load_error)
3294                 printf("   Loaded: %s%s%s (Reason: %s)\n",
3295                        on, strna(i->load_state), off, i->load_error);
3296         else if (path && !isempty(i->unit_file_state) && !isempty(i->unit_file_preset))
3297                 printf("   Loaded: %s%s%s (%s; %s; vendor preset: %s)\n",
3298                        on, strna(i->load_state), off, path, i->unit_file_state, i->unit_file_preset);
3299         else if (path && !isempty(i->unit_file_state))
3300                 printf("   Loaded: %s%s%s (%s; %s)\n",
3301                        on, strna(i->load_state), off, path, i->unit_file_state);
3302         else if (path)
3303                 printf("   Loaded: %s%s%s (%s)\n",
3304                        on, strna(i->load_state), off, path);
3305         else
3306                 printf("   Loaded: %s%s%s\n",
3307                        on, strna(i->load_state), off);
3308
3309         if (!strv_isempty(i->dropin_paths)) {
3310                 _cleanup_free_ char *dir = NULL;
3311                 bool last = false;
3312                 char ** dropin;
3313
3314                 STRV_FOREACH(dropin, i->dropin_paths) {
3315                         if (! dir || last) {
3316                                 printf(dir ? "        " : "  Drop-In: ");
3317
3318                                 free(dir);
3319                                 dir = NULL;
3320
3321                                 if (path_get_parent(*dropin, &dir) < 0) {
3322                                         log_oom();
3323                                         return;
3324                                 }
3325
3326                                 printf("%s\n           %s", dir,
3327                                        draw_special_char(DRAW_TREE_RIGHT));
3328                         }
3329
3330                         last = ! (*(dropin + 1) && startswith(*(dropin + 1), dir));
3331
3332                         printf("%s%s", basename(*dropin), last ? "\n" : ", ");
3333                 }
3334         }
3335
3336         ss = streq_ptr(i->active_state, i->sub_state) ? NULL : i->sub_state;
3337         if (ss)
3338                 printf("   Active: %s%s (%s)%s",
3339                        active_on, strna(i->active_state), ss, active_off);
3340         else
3341                 printf("   Active: %s%s%s",
3342                        active_on, strna(i->active_state), active_off);
3343
3344         if (!isempty(i->result) && !streq(i->result, "success"))
3345                 printf(" (Result: %s)", i->result);
3346
3347         timestamp = (streq_ptr(i->active_state, "active")      ||
3348                      streq_ptr(i->active_state, "reloading"))   ? i->active_enter_timestamp :
3349                     (streq_ptr(i->active_state, "inactive")    ||
3350                      streq_ptr(i->active_state, "failed"))      ? i->inactive_enter_timestamp :
3351                     streq_ptr(i->active_state, "activating")    ? i->inactive_exit_timestamp :
3352                                                                   i->active_exit_timestamp;
3353
3354         s1 = format_timestamp_relative(since1, sizeof(since1), timestamp);
3355         s2 = format_timestamp(since2, sizeof(since2), timestamp);
3356
3357         if (s1)
3358                 printf(" since %s; %s\n", s2, s1);
3359         else if (s2)
3360                 printf(" since %s\n", s2);
3361         else
3362                 printf("\n");
3363
3364         if (!i->condition_result && i->condition_timestamp > 0) {
3365                 s1 = format_timestamp_relative(since1, sizeof(since1), i->condition_timestamp);
3366                 s2 = format_timestamp(since2, sizeof(since2), i->condition_timestamp);
3367
3368                 printf("Condition: start %scondition failed%s at %s%s%s\n",
3369                        ansi_highlight_yellow(), ansi_highlight_off(),
3370                        s2, s1 ? "; " : "", s1 ? s1 : "");
3371                 if (i->failed_condition_trigger)
3372                         printf("           none of the trigger conditions were met\n");
3373                 else if (i->failed_condition)
3374                         printf("           %s=%s%s was not met\n",
3375                                i->failed_condition,
3376                                i->failed_condition_negate ? "!" : "",
3377                                i->failed_condition_parameter);
3378         }
3379
3380         if (!i->assert_result && i->assert_timestamp > 0) {
3381                 s1 = format_timestamp_relative(since1, sizeof(since1), i->assert_timestamp);
3382                 s2 = format_timestamp(since2, sizeof(since2), i->assert_timestamp);
3383
3384                 printf("   Assert: start %sassertion failed%s at %s%s%s\n",
3385                        ansi_highlight_red(), ansi_highlight_off(),
3386                        s2, s1 ? "; " : "", s1 ? s1 : "");
3387                 if (i->failed_assert_trigger)
3388                         printf("           none of the trigger assertions were met\n");
3389                 else if (i->failed_assert)
3390                         printf("           %s=%s%s was not met\n",
3391                                i->failed_assert,
3392                                i->failed_assert_negate ? "!" : "",
3393                                i->failed_assert_parameter);
3394         }
3395
3396         if (i->sysfs_path)
3397                 printf("   Device: %s\n", i->sysfs_path);
3398         if (i->where)
3399                 printf("    Where: %s\n", i->where);
3400         if (i->what)
3401                 printf("     What: %s\n", i->what);
3402
3403         STRV_FOREACH(t, i->documentation)
3404                 printf(" %*s %s\n", 9, t == i->documentation ? "Docs:" : "", *t);
3405
3406         STRV_FOREACH_PAIR(t, t2, i->listen)
3407                 printf(" %*s %s (%s)\n", 9, t == i->listen ? "Listen:" : "", *t2, *t);
3408
3409         if (i->accept)
3410                 printf(" Accepted: %u; Connected: %u\n", i->n_accepted, i->n_connections);
3411
3412         LIST_FOREACH(exec, p, i->exec) {
3413                 _cleanup_free_ char *argv = NULL;
3414                 bool good;
3415
3416                 /* Only show exited processes here */
3417                 if (p->code == 0)
3418                         continue;
3419
3420                 argv = strv_join(p->argv, " ");
3421                 printf("  Process: %u %s=%s ", p->pid, p->name, strna(argv));
3422
3423                 good = is_clean_exit_lsb(p->code, p->status, NULL);
3424                 if (!good) {
3425                         on = ansi_highlight_red();
3426                         off = ansi_highlight_off();
3427                 } else
3428                         on = off = "";
3429
3430                 printf("%s(code=%s, ", on, sigchld_code_to_string(p->code));
3431
3432                 if (p->code == CLD_EXITED) {
3433                         const char *c;
3434
3435                         printf("status=%i", p->status);
3436
3437                         c = exit_status_to_string(p->status, EXIT_STATUS_SYSTEMD);
3438                         if (c)
3439                                 printf("/%s", c);
3440
3441                 } else
3442                         printf("signal=%s", signal_to_string(p->status));
3443
3444                 printf(")%s\n", off);
3445
3446                 if (i->main_pid == p->pid &&
3447                     i->start_timestamp == p->start_timestamp &&
3448                     i->exit_timestamp == p->start_timestamp)
3449                         /* Let's not show this twice */
3450                         i->main_pid = 0;
3451
3452                 if (p->pid == i->control_pid)
3453                         i->control_pid = 0;
3454         }
3455
3456         if (i->main_pid > 0 || i->control_pid > 0) {
3457                 if (i->main_pid > 0) {
3458                         printf(" Main PID: "PID_FMT, i->main_pid);
3459
3460                         if (i->running) {
3461                                 _cleanup_free_ char *comm = NULL;
3462                                 get_process_comm(i->main_pid, &comm);
3463                                 if (comm)
3464                                         printf(" (%s)", comm);
3465                         } else if (i->exit_code > 0) {
3466                                 printf(" (code=%s, ", sigchld_code_to_string(i->exit_code));
3467
3468                                 if (i->exit_code == CLD_EXITED) {
3469                                         const char *c;
3470
3471                                         printf("status=%i", i->exit_status);
3472
3473                                         c = exit_status_to_string(i->exit_status, EXIT_STATUS_SYSTEMD);
3474                                         if (c)
3475                                                 printf("/%s", c);
3476
3477                                 } else
3478                                         printf("signal=%s", signal_to_string(i->exit_status));
3479                                 printf(")");
3480                         }
3481
3482                         if (i->control_pid > 0)
3483                                 printf(";");
3484                 }
3485
3486                 if (i->control_pid > 0) {
3487                         _cleanup_free_ char *c = NULL;
3488
3489                         printf(" %8s: "PID_FMT, i->main_pid ? "" : " Control", i->control_pid);
3490
3491                         get_process_comm(i->control_pid, &c);
3492                         if (c)
3493                                 printf(" (%s)", c);
3494                 }
3495
3496                 printf("\n");
3497         }
3498
3499         if (i->status_text)
3500                 printf("   Status: \"%s\"\n", i->status_text);
3501         if (i->status_errno > 0)
3502                 printf("    Error: %i (%s)\n", i->status_errno, strerror(i->status_errno));
3503
3504         if (i->control_group &&
3505             (i->main_pid > 0 || i->control_pid > 0 ||
3506              ((arg_transport != BUS_TRANSPORT_LOCAL && arg_transport != BUS_TRANSPORT_MACHINE) || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, i->control_group, false) == 0))) {
3507                 unsigned c;
3508
3509                 printf("   CGroup: %s\n", i->control_group);
3510
3511                 if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_MACHINE) {
3512                         unsigned k = 0;
3513                         pid_t extra[2];
3514                         static const char prefix[] = "           ";
3515
3516                         c = columns();
3517                         if (c > sizeof(prefix) - 1)
3518                                 c -= sizeof(prefix) - 1;
3519                         else
3520                                 c = 0;
3521
3522                         if (i->main_pid > 0)
3523                                 extra[k++] = i->main_pid;
3524
3525                         if (i->control_pid > 0)
3526                                 extra[k++] = i->control_pid;
3527
3528                         show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, i->control_group, prefix, c, false, extra, k, flags);
3529                 }
3530         }
3531
3532         if (i->id && arg_transport == BUS_TRANSPORT_LOCAL) {
3533                 show_journal_by_unit(stdout,
3534                                      i->id,
3535                                      arg_output,
3536                                      0,
3537                                      i->inactive_exit_timestamp_monotonic,
3538                                      arg_lines,
3539                                      getuid(),
3540                                      flags | OUTPUT_BEGIN_NEWLINE,
3541                                      arg_scope == UNIT_FILE_SYSTEM,
3542                                      ellipsized);
3543         }
3544
3545         if (i->need_daemon_reload)
3546                 warn_unit_file_changed(i->id);
3547 }
3548
3549 static void show_unit_help(UnitStatusInfo *i) {
3550         char **p;
3551
3552         assert(i);
3553
3554         if (!i->documentation) {
3555                 log_info("Documentation for %s not known.", i->id);
3556                 return;
3557         }
3558
3559         STRV_FOREACH(p, i->documentation)
3560                 if (startswith(*p, "man:"))
3561                         show_man_page(*p + 4, false);
3562                 else
3563                         log_info("Can't show: %s", *p);
3564 }
3565
3566 static int status_property(const char *name, sd_bus_message *m, UnitStatusInfo *i, const char *contents) {
3567         int r;
3568
3569         assert(name);
3570         assert(m);
3571         assert(i);
3572
3573         switch (contents[0]) {
3574
3575         case SD_BUS_TYPE_STRING: {
3576                 const char *s;
3577
3578                 r = sd_bus_message_read(m, "s", &s);
3579                 if (r < 0)
3580                         return bus_log_parse_error(r);
3581
3582                 if (!isempty(s)) {
3583                         if (streq(name, "Id"))
3584                                 i->id = s;
3585                         else if (streq(name, "LoadState"))
3586                                 i->load_state = s;
3587                         else if (streq(name, "ActiveState"))
3588                                 i->active_state = s;
3589                         else if (streq(name, "SubState"))
3590                                 i->sub_state = s;
3591                         else if (streq(name, "Description"))
3592                                 i->description = s;
3593                         else if (streq(name, "FragmentPath"))
3594                                 i->fragment_path = s;
3595                         else if (streq(name, "SourcePath"))
3596                                 i->source_path = s;
3597 #ifndef NOLEGACY
3598                         else if (streq(name, "DefaultControlGroup")) {
3599                                 const char *e;
3600                                 e = startswith(s, SYSTEMD_CGROUP_CONTROLLER ":");
3601                                 if (e)
3602                                         i->control_group = e;
3603                         }
3604 #endif
3605                         else if (streq(name, "ControlGroup"))
3606                                 i->control_group = s;
3607                         else if (streq(name, "StatusText"))
3608                                 i->status_text = s;
3609                         else if (streq(name, "PIDFile"))
3610                                 i->pid_file = s;
3611                         else if (streq(name, "SysFSPath"))
3612                                 i->sysfs_path = s;
3613                         else if (streq(name, "Where"))
3614                                 i->where = s;
3615                         else if (streq(name, "What"))
3616                                 i->what = s;
3617                         else if (streq(name, "Following"))
3618                                 i->following = s;
3619                         else if (streq(name, "UnitFileState"))
3620                                 i->unit_file_state = s;
3621                         else if (streq(name, "UnitFilePreset"))
3622                                 i->unit_file_preset = s;
3623                         else if (streq(name, "Result"))
3624                                 i->result = s;
3625                 }
3626
3627                 break;
3628         }
3629
3630         case SD_BUS_TYPE_BOOLEAN: {
3631                 int b;
3632
3633                 r = sd_bus_message_read(m, "b", &b);
3634                 if (r < 0)
3635                         return bus_log_parse_error(r);
3636
3637                 if (streq(name, "Accept"))
3638                         i->accept = b;
3639                 else if (streq(name, "NeedDaemonReload"))
3640                         i->need_daemon_reload = b;
3641                 else if (streq(name, "ConditionResult"))
3642                         i->condition_result = b;
3643                 else if (streq(name, "AssertResult"))
3644                         i->assert_result = b;
3645
3646                 break;
3647         }
3648
3649         case SD_BUS_TYPE_UINT32: {
3650                 uint32_t u;
3651
3652                 r = sd_bus_message_read(m, "u", &u);
3653                 if (r < 0)
3654                         return bus_log_parse_error(r);
3655
3656                 if (streq(name, "MainPID")) {
3657                         if (u > 0) {
3658                                 i->main_pid = (pid_t) u;
3659                                 i->running = true;
3660                         }
3661                 } else if (streq(name, "ControlPID"))
3662                         i->control_pid = (pid_t) u;
3663                 else if (streq(name, "ExecMainPID")) {
3664                         if (u > 0)
3665                                 i->main_pid = (pid_t) u;
3666                 } else if (streq(name, "NAccepted"))
3667                         i->n_accepted = u;
3668                 else if (streq(name, "NConnections"))
3669                         i->n_connections = u;
3670
3671                 break;
3672         }
3673
3674         case SD_BUS_TYPE_INT32: {
3675                 int32_t j;
3676
3677                 r = sd_bus_message_read(m, "i", &j);
3678                 if (r < 0)
3679                         return bus_log_parse_error(r);
3680
3681                 if (streq(name, "ExecMainCode"))
3682                         i->exit_code = (int) j;
3683                 else if (streq(name, "ExecMainStatus"))
3684                         i->exit_status = (int) j;
3685                 else if (streq(name, "StatusErrno"))
3686                         i->status_errno = (int) j;
3687
3688                 break;
3689         }
3690
3691         case SD_BUS_TYPE_UINT64: {
3692                 uint64_t u;
3693
3694                 r = sd_bus_message_read(m, "t", &u);
3695                 if (r < 0)
3696                         return bus_log_parse_error(r);
3697
3698                 if (streq(name, "ExecMainStartTimestamp"))
3699                         i->start_timestamp = (usec_t) u;
3700                 else if (streq(name, "ExecMainExitTimestamp"))
3701                         i->exit_timestamp = (usec_t) u;
3702                 else if (streq(name, "ActiveEnterTimestamp"))
3703                         i->active_enter_timestamp = (usec_t) u;
3704                 else if (streq(name, "InactiveEnterTimestamp"))
3705                         i->inactive_enter_timestamp = (usec_t) u;
3706                 else if (streq(name, "InactiveExitTimestamp"))
3707                         i->inactive_exit_timestamp = (usec_t) u;
3708                 else if (streq(name, "InactiveExitTimestampMonotonic"))
3709                         i->inactive_exit_timestamp_monotonic = (usec_t) u;
3710                 else if (streq(name, "ActiveExitTimestamp"))
3711                         i->active_exit_timestamp = (usec_t) u;
3712                 else if (streq(name, "ConditionTimestamp"))
3713                         i->condition_timestamp = (usec_t) u;
3714                 else if (streq(name, "AssertTimestamp"))
3715                         i->assert_timestamp = (usec_t) u;
3716
3717                 break;
3718         }
3719
3720         case SD_BUS_TYPE_ARRAY:
3721
3722                 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3723                         _cleanup_free_ ExecStatusInfo *info = NULL;
3724
3725                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3726                         if (r < 0)
3727                                 return bus_log_parse_error(r);
3728
3729                         info = new0(ExecStatusInfo, 1);
3730                         if (!info)
3731                                 return log_oom();
3732
3733                         while ((r = exec_status_info_deserialize(m, info)) > 0) {
3734
3735                                 info->name = strdup(name);
3736                                 if (!info->name)
3737                                         log_oom();
3738
3739                                 LIST_PREPEND(exec, i->exec, info);
3740
3741                                 info = new0(ExecStatusInfo, 1);
3742                                 if (!info)
3743                                         log_oom();
3744                         }
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_STRUCT_BEGIN && streq(name, "Listen")) {
3756                         const char *type, *path;
3757
3758                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3759                         if (r < 0)
3760                                 return bus_log_parse_error(r);
3761
3762                         while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0) {
3763
3764                                 r = strv_extend(&i->listen, type);
3765                                 if (r < 0)
3766                                         return r;
3767
3768                                 r = strv_extend(&i->listen, path);
3769                                 if (r < 0)
3770                                         return r;
3771                         }
3772                         if (r < 0)
3773                                 return bus_log_parse_error(r);
3774
3775                         r = sd_bus_message_exit_container(m);
3776                         if (r < 0)
3777                                 return bus_log_parse_error(r);
3778
3779                         return 0;
3780
3781                 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "DropInPaths")) {
3782
3783                         r = sd_bus_message_read_strv(m, &i->dropin_paths);
3784                         if (r < 0)
3785                                 return bus_log_parse_error(r);
3786
3787                 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Documentation")) {
3788
3789                         r = sd_bus_message_read_strv(m, &i->documentation);
3790                         if (r < 0)
3791                                 return bus_log_parse_error(r);
3792
3793                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Conditions")) {
3794                         const char *cond, *param;
3795                         int trigger, negate;
3796                         int32_t state;
3797
3798                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
3799                         if (r < 0)
3800                                 return bus_log_parse_error(r);
3801
3802                         while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, &param, &state)) > 0) {
3803                                 log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
3804                                 if (state < 0 && (!trigger || !i->failed_condition)) {
3805                                         i->failed_condition = cond;
3806                                         i->failed_condition_trigger = trigger;
3807                                         i->failed_condition_negate = negate;
3808                                         i->failed_condition_parameter = param;
3809                                 }
3810                         }
3811                         if (r < 0)
3812                                 return bus_log_parse_error(r);
3813
3814                         r = sd_bus_message_exit_container(m);
3815                         if (r < 0)
3816                                 return bus_log_parse_error(r);
3817
3818                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Asserts")) {
3819                         const char *cond, *param;
3820                         int trigger, negate;
3821                         int32_t state;
3822
3823                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
3824                         if (r < 0)
3825                                 return bus_log_parse_error(r);
3826
3827                         while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, &param, &state)) > 0) {
3828                                 log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
3829                                 if (state < 0 && (!trigger || !i->failed_assert)) {
3830                                         i->failed_assert = cond;
3831                                         i->failed_assert_trigger = trigger;
3832                                         i->failed_assert_negate = negate;
3833                                         i->failed_assert_parameter = param;
3834                                 }
3835                         }
3836                         if (r < 0)
3837                                 return bus_log_parse_error(r);
3838
3839                         r = sd_bus_message_exit_container(m);
3840                         if (r < 0)
3841                                 return bus_log_parse_error(r);
3842
3843                 } else
3844                         goto skip;
3845
3846                 break;
3847
3848         case SD_BUS_TYPE_STRUCT_BEGIN:
3849
3850                 if (streq(name, "LoadError")) {
3851                         const char *n, *message;
3852
3853                         r = sd_bus_message_read(m, "(ss)", &n, &message);
3854                         if (r < 0)
3855                                 return bus_log_parse_error(r);
3856
3857                         if (!isempty(message))
3858                                 i->load_error = message;
3859                 } else
3860                         goto skip;
3861
3862                 break;
3863
3864         default:
3865                 goto skip;
3866         }
3867
3868         return 0;
3869
3870 skip:
3871         r = sd_bus_message_skip(m, contents);
3872         if (r < 0)
3873                 return bus_log_parse_error(r);
3874
3875         return 0;
3876 }
3877
3878 static int print_property(const char *name, sd_bus_message *m, const char *contents) {
3879         int r;
3880
3881         assert(name);
3882         assert(m);
3883
3884         /* This is a low-level property printer, see
3885          * print_status_info() for the nicer output */
3886
3887         if (arg_properties && !strv_find(arg_properties, name)) {
3888                 /* skip what we didn't read */
3889                 r = sd_bus_message_skip(m, contents);
3890                 return r;
3891         }
3892
3893         switch (contents[0]) {
3894
3895         case SD_BUS_TYPE_STRUCT_BEGIN:
3896
3897                 if (contents[1] == SD_BUS_TYPE_UINT32 && streq(name, "Job")) {
3898                         uint32_t u;
3899
3900                         r = sd_bus_message_read(m, "(uo)", &u, NULL);
3901                         if (r < 0)
3902                                 return bus_log_parse_error(r);
3903
3904                         if (u > 0)
3905                                 printf("%s=%"PRIu32"\n", name, u);
3906                         else if (arg_all)
3907                                 printf("%s=\n", name);
3908
3909                         return 0;
3910
3911                 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Unit")) {
3912                         const char *s;
3913
3914                         r = sd_bus_message_read(m, "(so)", &s, NULL);
3915                         if (r < 0)
3916                                 return bus_log_parse_error(r);
3917
3918                         if (arg_all || !isempty(s))
3919                                 printf("%s=%s\n", name, s);
3920
3921                         return 0;
3922
3923                 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "LoadError")) {
3924                         const char *a = NULL, *b = NULL;
3925
3926                         r = sd_bus_message_read(m, "(ss)", &a, &b);
3927                         if (r < 0)
3928                                 return bus_log_parse_error(r);
3929
3930                         if (arg_all || !isempty(a) || !isempty(b))
3931                                 printf("%s=%s \"%s\"\n", name, strempty(a), strempty(b));
3932
3933                         return 0;
3934                 } else if (streq_ptr(name, "SystemCallFilter")) {
3935                         _cleanup_strv_free_ char **l = NULL;
3936                         int whitelist;
3937
3938                         r = sd_bus_message_enter_container(m, 'r', "bas");
3939                         if (r < 0)
3940                                 return bus_log_parse_error(r);
3941
3942                         r = sd_bus_message_read(m, "b", &whitelist);
3943                         if (r < 0)
3944                                 return bus_log_parse_error(r);
3945
3946                         r = sd_bus_message_read_strv(m, &l);
3947                         if (r < 0)
3948                                 return bus_log_parse_error(r);
3949
3950                         r = sd_bus_message_exit_container(m);
3951                         if (r < 0)
3952                                 return bus_log_parse_error(r);
3953
3954                         if (arg_all || whitelist || !strv_isempty(l)) {
3955                                 bool first = true;
3956                                 char **i;
3957
3958                                 fputs(name, stdout);
3959                                 fputc('=', stdout);
3960
3961                                 if (!whitelist)
3962                                         fputc('~', stdout);
3963
3964                                 STRV_FOREACH(i, l) {
3965                                         if (first)
3966                                                 first = false;
3967                                         else
3968                                                 fputc(' ', stdout);
3969
3970                                         fputs(*i, stdout);
3971                                 }
3972                                 fputc('\n', stdout);
3973                         }
3974
3975                         return 0;
3976                 }
3977
3978                 break;
3979
3980         case SD_BUS_TYPE_ARRAY:
3981
3982                 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "EnvironmentFiles")) {
3983                         const char *path;
3984                         int ignore;
3985
3986                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sb)");
3987                         if (r < 0)
3988                                 return bus_log_parse_error(r);
3989
3990                         while ((r = sd_bus_message_read(m, "(sb)", &path, &ignore)) > 0)
3991                                 printf("EnvironmentFile=%s (ignore_errors=%s)\n", path, yes_no(ignore));
3992
3993                         if (r < 0)
3994                                 return bus_log_parse_error(r);
3995
3996                         r = sd_bus_message_exit_container(m);
3997                         if (r < 0)
3998                                 return bus_log_parse_error(r);
3999
4000                         return 0;
4001
4002                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Paths")) {
4003                         const char *type, *path;
4004
4005                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
4006                         if (r < 0)
4007                                 return bus_log_parse_error(r);
4008
4009                         while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
4010                                 printf("%s=%s\n", type, path);
4011                         if (r < 0)
4012                                 return bus_log_parse_error(r);
4013
4014                         r = sd_bus_message_exit_container(m);
4015                         if (r < 0)
4016                                 return bus_log_parse_error(r);
4017
4018                         return 0;
4019
4020                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
4021                         const char *type, *path;
4022
4023                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
4024                         if (r < 0)
4025                                 return bus_log_parse_error(r);
4026
4027                         while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
4028                                 printf("Listen%s=%s\n", type, path);
4029                         if (r < 0)
4030                                 return bus_log_parse_error(r);
4031
4032                         r = sd_bus_message_exit_container(m);
4033                         if (r < 0)
4034                                 return bus_log_parse_error(r);
4035
4036                         return 0;
4037
4038                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Timers")) {
4039                         const char *base;
4040                         uint64_t value, next_elapse;
4041
4042                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(stt)");
4043                         if (r < 0)
4044                                 return bus_log_parse_error(r);
4045
4046                         while ((r = sd_bus_message_read(m, "(stt)", &base, &value, &next_elapse)) > 0) {
4047                                 char timespan1[FORMAT_TIMESPAN_MAX], timespan2[FORMAT_TIMESPAN_MAX];
4048
4049                                 printf("%s={ value=%s ; next_elapse=%s }\n",
4050                                        base,
4051                                        format_timespan(timespan1, sizeof(timespan1), value, 0),
4052                                        format_timespan(timespan2, sizeof(timespan2), next_elapse, 0));
4053                         }
4054                         if (r < 0)
4055                                 return bus_log_parse_error(r);
4056
4057                         r = sd_bus_message_exit_container(m);
4058                         if (r < 0)
4059                                 return bus_log_parse_error(r);
4060
4061                         return 0;
4062
4063                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
4064                         ExecStatusInfo info = {};
4065
4066                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
4067                         if (r < 0)
4068                                 return bus_log_parse_error(r);
4069
4070                         while ((r = exec_status_info_deserialize(m, &info)) > 0) {
4071                                 char timestamp1[FORMAT_TIMESTAMP_MAX], timestamp2[FORMAT_TIMESTAMP_MAX];
4072                                 _cleanup_free_ char *tt;
4073
4074                                 tt = strv_join(info.argv, " ");
4075
4076                                 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",
4077                                        name,
4078                                        strna(info.path),
4079                                        strna(tt),
4080                                        yes_no(info.ignore),
4081                                        strna(format_timestamp(timestamp1, sizeof(timestamp1), info.start_timestamp)),
4082                                        strna(format_timestamp(timestamp2, sizeof(timestamp2), info.exit_timestamp)),
4083                                        info.pid,
4084                                        sigchld_code_to_string(info.code),
4085                                        info.status,
4086                                        info.code == CLD_EXITED ? "" : "/",
4087                                        strempty(info.code == CLD_EXITED ? NULL : signal_to_string(info.status)));
4088
4089                                 free(info.path);
4090                                 strv_free(info.argv);
4091                                 zero(info);
4092                         }
4093
4094                         r = sd_bus_message_exit_container(m);
4095                         if (r < 0)
4096                                 return bus_log_parse_error(r);
4097
4098                         return 0;
4099
4100                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "DeviceAllow")) {
4101                         const char *path, *rwm;
4102
4103                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
4104                         if (r < 0)
4105                                 return bus_log_parse_error(r);
4106
4107                         while ((r = sd_bus_message_read(m, "(ss)", &path, &rwm)) > 0)
4108                                 printf("%s=%s %s\n", name, strna(path), strna(rwm));
4109                         if (r < 0)
4110                                 return bus_log_parse_error(r);
4111
4112                         r = sd_bus_message_exit_container(m);
4113                         if (r < 0)
4114                                 return bus_log_parse_error(r);
4115
4116                         return 0;
4117
4118                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "BlockIODeviceWeight")) {
4119                         const char *path;
4120                         uint64_t weight;
4121
4122                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
4123                         if (r < 0)
4124                                 return bus_log_parse_error(r);
4125
4126                         while ((r = sd_bus_message_read(m, "(st)", &path, &weight)) > 0)
4127                                 printf("%s=%s %" PRIu64 "\n", name, strna(path), weight);
4128                         if (r < 0)
4129                                 return bus_log_parse_error(r);
4130
4131                         r = sd_bus_message_exit_container(m);
4132                         if (r < 0)
4133                                 return bus_log_parse_error(r);
4134
4135                         return 0;
4136
4137                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && (streq(name, "BlockIOReadBandwidth") || streq(name, "BlockIOWriteBandwidth"))) {
4138                         const char *path;
4139                         uint64_t bandwidth;
4140
4141                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
4142                         if (r < 0)
4143                                 return bus_log_parse_error(r);
4144
4145                         while ((r = sd_bus_message_read(m, "(st)", &path, &bandwidth)) > 0)
4146                                 printf("%s=%s %" PRIu64 "\n", name, strna(path), bandwidth);
4147                         if (r < 0)
4148                                 return bus_log_parse_error(r);
4149
4150                         r = sd_bus_message_exit_container(m);
4151                         if (r < 0)
4152                                 return bus_log_parse_error(r);
4153
4154                         return 0;
4155                 }
4156
4157                 break;
4158         }
4159
4160         r = bus_print_property(name, m, arg_all);
4161         if (r < 0)
4162                 return bus_log_parse_error(r);
4163
4164         if (r == 0) {
4165                 r = sd_bus_message_skip(m, contents);
4166                 if (r < 0)
4167                         return bus_log_parse_error(r);
4168
4169                 if (arg_all)
4170                         printf("%s=[unprintable]\n", name);
4171         }
4172
4173         return 0;
4174 }
4175
4176 static int show_one(
4177                 const char *verb,
4178                 sd_bus *bus,
4179                 const char *path,
4180                 bool show_properties,
4181                 bool *new_line,
4182                 bool *ellipsized) {
4183
4184         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4185         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4186         UnitStatusInfo info = {};
4187         ExecStatusInfo *p;
4188         int r;
4189
4190         assert(path);
4191         assert(new_line);
4192
4193         log_debug("Showing one %s", path);
4194
4195         r = sd_bus_call_method(
4196                         bus,
4197                         "org.freedesktop.systemd1",
4198                         path,
4199                         "org.freedesktop.DBus.Properties",
4200                         "GetAll",
4201                         &error,
4202                         &reply,
4203                         "s", "");
4204         if (r < 0) {
4205                 log_error("Failed to get properties: %s", bus_error_message(&error, r));
4206                 return r;
4207         }
4208
4209         r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
4210         if (r < 0)
4211                 return bus_log_parse_error(r);
4212
4213         if (*new_line)
4214                 printf("\n");
4215
4216         *new_line = true;
4217
4218         while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
4219                 const char *name, *contents;
4220
4221                 r = sd_bus_message_read(reply, "s", &name);
4222                 if (r < 0)
4223                         return bus_log_parse_error(r);
4224
4225                 r = sd_bus_message_peek_type(reply, NULL, &contents);
4226                 if (r < 0)
4227                         return bus_log_parse_error(r);
4228
4229                 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, contents);
4230                 if (r < 0)
4231                         return bus_log_parse_error(r);
4232
4233                 if (show_properties)
4234                         r = print_property(name, reply, contents);
4235                 else
4236                         r = status_property(name, reply, &info, contents);
4237                 if (r < 0)
4238                         return r;
4239
4240                 r = sd_bus_message_exit_container(reply);
4241                 if (r < 0)
4242                         return bus_log_parse_error(r);
4243
4244                 r = sd_bus_message_exit_container(reply);
4245                 if (r < 0)
4246                         return bus_log_parse_error(r);
4247         }
4248         if (r < 0)
4249                 return bus_log_parse_error(r);
4250
4251         r = sd_bus_message_exit_container(reply);
4252         if (r < 0)
4253                 return bus_log_parse_error(r);
4254
4255         r = 0;
4256
4257         if (!show_properties) {
4258                 if (streq(verb, "help"))
4259                         show_unit_help(&info);
4260                 else
4261                         print_status_info(&info, ellipsized);
4262         }
4263
4264         strv_free(info.documentation);
4265         strv_free(info.dropin_paths);
4266         strv_free(info.listen);
4267
4268         if (!streq_ptr(info.active_state, "active") &&
4269             !streq_ptr(info.active_state, "reloading") &&
4270             streq(verb, "status")) {
4271                 /* According to LSB: "program not running" */
4272                 /* 0: program is running or service is OK
4273                  * 1: program is dead and /run PID file exists
4274                  * 2: program is dead and /run/lock lock file exists
4275                  * 3: program is not running
4276                  * 4: program or service status is unknown
4277                  */
4278                 if (info.pid_file && access(info.pid_file, F_OK) == 0)
4279                         r = 1;
4280                 else
4281                         r = 3;
4282         }
4283
4284         while ((p = info.exec)) {
4285                 LIST_REMOVE(exec, info.exec, p);
4286                 exec_status_info_free(p);
4287         }
4288
4289         return r;
4290 }
4291
4292 static int get_unit_dbus_path_by_pid(
4293                 sd_bus *bus,
4294                 uint32_t pid,
4295                 char **unit) {
4296
4297         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4298         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4299         char *u;
4300         int r;
4301
4302         r = sd_bus_call_method(
4303                         bus,
4304                         "org.freedesktop.systemd1",
4305                         "/org/freedesktop/systemd1",
4306                         "org.freedesktop.systemd1.Manager",
4307                         "GetUnitByPID",
4308                         &error,
4309                         &reply,
4310                         "u", pid);
4311         if (r < 0) {
4312                 log_error("Failed to get unit for PID "PID_FMT": %s", pid, bus_error_message(&error, r));
4313                 return r;
4314         }
4315
4316         r = sd_bus_message_read(reply, "o", &u);
4317         if (r < 0)
4318                 return bus_log_parse_error(r);
4319
4320         u = strdup(u);
4321         if (!u)
4322                 return log_oom();
4323
4324         *unit = u;
4325         return 0;
4326 }
4327
4328 static int show_all(
4329                 const char* verb,
4330                 sd_bus *bus,
4331                 bool show_properties,
4332                 bool *new_line,
4333                 bool *ellipsized) {
4334
4335         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4336         _cleanup_free_ UnitInfo *unit_infos = NULL;
4337         const UnitInfo *u;
4338         unsigned c;
4339         int r, ret = 0;
4340
4341         r = get_unit_list(bus, NULL, NULL, &unit_infos, 0, &reply);
4342         if (r < 0)
4343                 return r;
4344
4345         pager_open_if_enabled();
4346
4347         c = (unsigned) r;
4348
4349         qsort_safe(unit_infos, c, sizeof(UnitInfo), compare_unit_info);
4350
4351         for (u = unit_infos; u < unit_infos + c; u++) {
4352                 _cleanup_free_ char *p = NULL;
4353
4354                 p = unit_dbus_path_from_name(u->id);
4355                 if (!p)
4356                         return log_oom();
4357
4358                 r = show_one(verb, bus, p, show_properties, new_line, ellipsized);
4359                 if (r < 0)
4360                         return r;
4361                 else if (r > 0 && ret == 0)
4362                         ret = r;
4363         }
4364
4365         return ret;
4366 }
4367
4368 static int show_system_status(sd_bus *bus) {
4369         char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], since2[FORMAT_TIMESTAMP_MAX];
4370         _cleanup_free_ char *hn = NULL;
4371         struct machine_info mi = {};
4372         const char *on, *off;
4373         int r;
4374
4375         hn = gethostname_malloc();
4376         if (!hn)
4377                 return log_oom();
4378
4379         r = bus_map_all_properties(bus, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map, &mi);
4380         if (r < 0)
4381                 return log_error_errno(r, "Failed to read server status: %m");
4382
4383         if (streq_ptr(mi.state, "degraded")) {
4384                 on = ansi_highlight_red();
4385                 off = ansi_highlight_off();
4386         } else if (!streq_ptr(mi.state, "running")) {
4387                 on = ansi_highlight_yellow();
4388                 off = ansi_highlight_off();
4389         } else
4390                 on = off = "";
4391
4392         printf("%s%s%s %s\n", on, draw_special_char(DRAW_BLACK_CIRCLE), off, arg_host ? arg_host : hn);
4393
4394         printf("    State: %s%s%s\n",
4395                on, strna(mi.state), off);
4396
4397         printf("     Jobs: %u queued\n", mi.n_jobs);
4398         printf("   Failed: %u units\n", mi.n_failed_units);
4399
4400         printf("    Since: %s; %s\n",
4401                format_timestamp(since2, sizeof(since2), mi.timestamp),
4402                format_timestamp_relative(since1, sizeof(since1), mi.timestamp));
4403
4404         printf("   CGroup: %s\n", mi.control_group ?: "/");
4405         if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_MACHINE) {
4406                 int flags =
4407                         arg_all * OUTPUT_SHOW_ALL |
4408                         (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
4409                         on_tty() * OUTPUT_COLOR |
4410                         !arg_quiet * OUTPUT_WARN_CUTOFF |
4411                         arg_full * OUTPUT_FULL_WIDTH;
4412
4413                 static const char prefix[] = "           ";
4414                 unsigned c;
4415
4416                 c = columns();
4417                 if (c > sizeof(prefix) - 1)
4418                         c -= sizeof(prefix) - 1;
4419                 else
4420                         c = 0;
4421
4422                 show_cgroup(SYSTEMD_CGROUP_CONTROLLER, strempty(mi.control_group), prefix, c, false, flags);
4423         }
4424
4425         free(mi.state);
4426         free(mi.control_group);
4427
4428         return 0;
4429 }
4430
4431 static int show(sd_bus *bus, char **args) {
4432         bool show_properties, show_status, new_line = false;
4433         bool ellipsized = false;
4434         int r, ret = 0;
4435
4436         assert(bus);
4437         assert(args);
4438
4439         show_properties = streq(args[0], "show");
4440         show_status = streq(args[0], "status");
4441
4442         if (show_properties)
4443                 pager_open_if_enabled();
4444
4445         /* If no argument is specified inspect the manager itself */
4446
4447         if (show_properties && strv_length(args) <= 1)
4448                 return show_one(args[0], bus, "/org/freedesktop/systemd1", show_properties, &new_line, &ellipsized);
4449
4450         if (show_status && strv_length(args) <= 1) {
4451
4452                 pager_open_if_enabled();
4453                 show_system_status(bus);
4454                 new_line = true;
4455
4456                 if (arg_all)
4457                         ret = show_all(args[0], bus, false, &new_line, &ellipsized);
4458         } else {
4459                 _cleanup_free_ char **patterns = NULL;
4460                 char **name;
4461
4462                 STRV_FOREACH(name, args + 1) {
4463                         _cleanup_free_ char *unit = NULL;
4464                         uint32_t id;
4465
4466                         if (safe_atou32(*name, &id) < 0) {
4467                                 if (strv_push(&patterns, *name) < 0)
4468                                         return log_oom();
4469
4470                                 continue;
4471                         } else if (show_properties) {
4472                                 /* Interpret as job id */
4473                                 if (asprintf(&unit, "/org/freedesktop/systemd1/job/%u", id) < 0)
4474                                         return log_oom();
4475
4476                         } else {
4477                                 /* Interpret as PID */
4478                                 r = get_unit_dbus_path_by_pid(bus, id, &unit);
4479                                 if (r < 0) {
4480                                         ret = r;
4481                                         continue;
4482                                 }
4483                         }
4484
4485                         r = show_one(args[0], bus, unit, show_properties,
4486                                      &new_line, &ellipsized);
4487                         if (r < 0)
4488                                 return r;
4489                         else if (r > 0 && ret == 0)
4490                                 ret = r;
4491                 }
4492
4493                 if (!strv_isempty(patterns)) {
4494                         _cleanup_strv_free_ char **names = NULL;
4495
4496                         r = expand_names(bus, patterns, NULL, &names);
4497                         if (r < 0)
4498                                 log_error_errno(r, "Failed to expand names: %m");
4499
4500                         STRV_FOREACH(name, names) {
4501                                 _cleanup_free_ char *unit;
4502
4503                                 unit = unit_dbus_path_from_name(*name);
4504                                 if (!unit)
4505                                         return log_oom();
4506
4507                                 r = show_one(args[0], bus, unit, show_properties,
4508                                              &new_line, &ellipsized);
4509                                 if (r < 0)
4510                                         return r;
4511                                 else if (r > 0 && ret == 0)
4512                                         ret = r;
4513                         }
4514                 }
4515         }
4516
4517         if (ellipsized && !arg_quiet)
4518                 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
4519
4520         return ret;
4521 }
4522
4523 static int init_home_and_lookup_paths(char **user_home, char **user_runtime, LookupPaths *lp) {
4524         int r;
4525
4526         assert(user_home);
4527         assert(user_runtime);
4528         assert(lp);
4529
4530         if (arg_scope == UNIT_FILE_USER) {
4531                 r = user_config_home(user_home);
4532                 if (r < 0)
4533                         return log_error_errno(r, "Failed to query XDG_CONFIG_HOME: %m");
4534                 else if (r == 0)
4535                         return log_error_errno(ENOTDIR, "Cannot find units: $XDG_CONFIG_HOME and $HOME are not set.");
4536
4537                 r = user_runtime_dir(user_runtime);
4538                 if (r < 0)
4539                         return log_error_errno(r, "Failed to query XDG_CONFIG_HOME: %m");
4540                 else if (r == 0)
4541                         return log_error_errno(ENOTDIR, "Cannot find units: $XDG_RUNTIME_DIR is not set.");
4542         }
4543
4544         r = lookup_paths_init(lp,
4545                               arg_scope == UNIT_FILE_SYSTEM ? SYSTEMD_SYSTEM : SYSTEMD_USER,
4546                               arg_scope == UNIT_FILE_USER,
4547                               arg_root,
4548                               NULL, NULL, NULL);
4549         if (r < 0)
4550                 return log_error_errno(r, "Failed to lookup unit lookup paths: %m");
4551
4552         return 0;
4553 }
4554
4555 static int cat(sd_bus *bus, char **args) {
4556         _cleanup_free_ char *user_home = NULL;
4557         _cleanup_free_ char *user_runtime = NULL;
4558         _cleanup_lookup_paths_free_ LookupPaths lp = {};
4559         _cleanup_strv_free_ char **names = NULL;
4560         char **name;
4561         bool first = true, avoid_bus_cache;
4562         int r = 0;
4563
4564         assert(args);
4565
4566         r = init_home_and_lookup_paths(&user_home, &user_runtime, &lp);
4567         if (r < 0)
4568                 return r;
4569
4570         r = expand_names(bus, args + 1, NULL, &names);
4571         if (r < 0)
4572                 log_error_errno(r, "Failed to expand names: %m");
4573
4574         avoid_bus_cache = !bus || avoid_bus();
4575
4576         pager_open_if_enabled();
4577
4578         STRV_FOREACH(name, names) {
4579                 _cleanup_free_ char *fragment_path = NULL;
4580                 _cleanup_strv_free_ char **dropin_paths = NULL;
4581                 char **path;
4582
4583                 r = unit_find_paths(bus, *name, avoid_bus_cache, &lp, &fragment_path, &dropin_paths);
4584                 if (r < 0)
4585                         return r;
4586                 else if (r == 0) {
4587                         log_warning("Unit %s does not have any files on disk", *name);
4588                         continue;
4589                 }
4590
4591                 if (first)
4592                         first = false;
4593                 else
4594                         puts("");
4595
4596                 if (fragment_path) {
4597                         printf("%s# %s%s\n",
4598                                ansi_highlight_blue(),
4599                                fragment_path,
4600                                ansi_highlight_off());
4601                         fflush(stdout);
4602
4603                         r = copy_file_fd(fragment_path, STDOUT_FILENO, false);
4604                         if (r < 0) {
4605                                 log_warning_errno(r, "Failed to cat %s: %m", fragment_path);
4606                                 continue;
4607                         }
4608                 }
4609
4610                 STRV_FOREACH(path, dropin_paths) {
4611                         printf("%s%s# %s%s\n",
4612                                isempty(fragment_path) && path == dropin_paths ? "" : "\n",
4613                                ansi_highlight_blue(),
4614                                *path,
4615                                ansi_highlight_off());
4616                         fflush(stdout);
4617
4618                         r = copy_file_fd(*path, STDOUT_FILENO, false);
4619                         if (r < 0) {
4620                                 log_warning_errno(r, "Failed to cat %s: %m", *path);
4621                                 continue;
4622                         }
4623                 }
4624         }
4625
4626         return r < 0 ? r : 0;
4627 }
4628
4629 static int set_property(sd_bus *bus, char **args) {
4630         _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4631         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4632         _cleanup_free_ char *n = NULL;
4633         char **i;
4634         int r;
4635
4636         r = sd_bus_message_new_method_call(
4637                         bus,
4638                         &m,
4639                         "org.freedesktop.systemd1",
4640                         "/org/freedesktop/systemd1",
4641                         "org.freedesktop.systemd1.Manager",
4642                         "SetUnitProperties");
4643         if (r < 0)
4644                 return bus_log_create_error(r);
4645
4646         r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4647         if (r < 0)
4648                 return bus_log_create_error(r);
4649
4650         n = unit_name_mangle(args[1], MANGLE_NOGLOB);
4651         if (!n)
4652                 return log_oom();
4653
4654         r = sd_bus_message_append(m, "sb", n, arg_runtime);
4655         if (r < 0)
4656                 return bus_log_create_error(r);
4657
4658         r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, "(sv)");
4659         if (r < 0)
4660                 return bus_log_create_error(r);
4661
4662         STRV_FOREACH(i, args + 2) {
4663                 r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv");
4664                 if (r < 0)
4665                         return bus_log_create_error(r);
4666
4667                 r = bus_append_unit_property_assignment(m, *i);
4668                 if (r < 0)
4669                         return r;
4670
4671                 r = sd_bus_message_close_container(m);
4672                 if (r < 0)
4673                         return bus_log_create_error(r);
4674         }
4675
4676         r = sd_bus_message_close_container(m);
4677         if (r < 0)
4678                 return bus_log_create_error(r);
4679
4680         r = sd_bus_call(bus, m, 0, &error, NULL);
4681         if (r < 0) {
4682                 log_error("Failed to set unit properties on %s: %s", n, bus_error_message(&error, r));
4683                 return r;
4684         }
4685
4686         return 0;
4687 }
4688
4689 static int snapshot(sd_bus *bus, char **args) {
4690         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4691         _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
4692         _cleanup_free_ char *n = NULL, *id = NULL;
4693         const char *path;
4694         int r;
4695
4696         if (strv_length(args) > 1)
4697                 n = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".snapshot");
4698         else
4699                 n = strdup("");
4700         if (!n)
4701                 return log_oom();
4702
4703         r = sd_bus_message_new_method_call(
4704                         bus,
4705                         &m,
4706                         "org.freedesktop.systemd1",
4707                         "/org/freedesktop/systemd1",
4708                         "org.freedesktop.systemd1.Manager",
4709                         "CreateSnapshot");
4710         if (r < 0)
4711                 return bus_log_create_error(r);
4712
4713         r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4714         if (r < 0)
4715                 return bus_log_create_error(r);
4716
4717         r = sd_bus_message_append(m, "sb", n, false);
4718         if (r < 0)
4719                 return bus_log_create_error(r);
4720
4721         r = sd_bus_call(bus, m, 0, &error, &reply);
4722         if (r < 0) {
4723                 log_error("Failed to create snapshot: %s", bus_error_message(&error, r));
4724                 return r;
4725         }
4726
4727         r = sd_bus_message_read(reply, "o", &path);
4728         if (r < 0)
4729                 return bus_log_parse_error(r);
4730
4731         r = sd_bus_get_property_string(
4732                         bus,
4733                         "org.freedesktop.systemd1",
4734                         path,
4735                         "org.freedesktop.systemd1.Unit",
4736                         "Id",
4737                         &error,
4738                         &id);
4739         if (r < 0) {
4740                 log_error("Failed to get ID of snapshot: %s", bus_error_message(&error, r));
4741                 return r;
4742         }
4743
4744         if (!arg_quiet)
4745                 puts(id);
4746
4747         return 0;
4748 }
4749
4750 static int delete_snapshot(sd_bus *bus, char **args) {
4751         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4752         _cleanup_strv_free_ char **names = NULL;
4753         char **name;
4754         int r;
4755
4756         assert(args);
4757
4758         r = expand_names(bus, args + 1, ".snapshot", &names);
4759         if (r < 0)
4760                 log_error_errno(r, "Failed to expand names: %m");
4761
4762         STRV_FOREACH(name, names) {
4763                 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4764                 int q;
4765
4766                 q = sd_bus_message_new_method_call(
4767                                 bus,
4768                                 &m,
4769                                 "org.freedesktop.systemd1",
4770                                 "/org/freedesktop/systemd1",
4771                                 "org.freedesktop.systemd1.Manager",
4772                                 "RemoveSnapshot");
4773                 if (q < 0)
4774                         return bus_log_create_error(q);
4775
4776                 q = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4777                 if (q < 0)
4778                         return bus_log_create_error(q);
4779
4780                 q = sd_bus_message_append(m, "s", *name);
4781                 if (q < 0)
4782                         return bus_log_create_error(q);
4783
4784                 q = sd_bus_call(bus, m, 0, &error, NULL);
4785                 if (q < 0) {
4786                         log_error("Failed to remove snapshot %s: %s", *name, bus_error_message(&error, q));
4787                         if (r == 0)
4788                                 r = q;
4789                 }
4790         }
4791
4792         return r;
4793 }
4794
4795 static int daemon_reload(sd_bus *bus, char **args) {
4796         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4797         _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4798         const char *method;
4799         int r;
4800
4801         if (arg_action == ACTION_RELOAD)
4802                 method = "Reload";
4803         else if (arg_action == ACTION_REEXEC)
4804                 method = "Reexecute";
4805         else {
4806                 assert(arg_action == ACTION_SYSTEMCTL);
4807
4808                 method =
4809                         streq(args[0], "clear-jobs")    ||
4810                         streq(args[0], "cancel")        ? "ClearJobs" :
4811                         streq(args[0], "daemon-reexec") ? "Reexecute" :
4812                         streq(args[0], "reset-failed")  ? "ResetFailed" :
4813                         streq(args[0], "halt")          ? "Halt" :
4814                         streq(args[0], "poweroff")      ? "PowerOff" :
4815                         streq(args[0], "reboot")        ? "Reboot" :
4816                         streq(args[0], "kexec")         ? "KExec" :
4817                         streq(args[0], "exit")          ? "Exit" :
4818                                     /* "daemon-reload" */ "Reload";
4819         }
4820
4821         r = sd_bus_message_new_method_call(
4822                         bus,
4823                         &m,
4824                         "org.freedesktop.systemd1",
4825                         "/org/freedesktop/systemd1",
4826                         "org.freedesktop.systemd1.Manager",
4827                         method);
4828         if (r < 0)
4829                 return bus_log_create_error(r);
4830
4831         r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4832         if (r < 0)
4833                 return bus_log_create_error(r);
4834
4835         r = sd_bus_call(bus, m, 0, &error, NULL);
4836         if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
4837                 /* There's always a fallback possible for
4838                  * legacy actions. */
4839                 r = -EADDRNOTAVAIL;
4840         else if ((r == -ETIMEDOUT || r == -ECONNRESET) && streq(method, "Reexecute"))
4841                 /* On reexecution, we expect a disconnect, not a
4842                  * reply */
4843                 r = 0;
4844         else if (r < 0)
4845                 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
4846
4847         return r < 0 ? r : 0;
4848 }
4849
4850 static int reset_failed(sd_bus *bus, char **args) {
4851         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4852         _cleanup_strv_free_ char **names = NULL;
4853         char **name;
4854         int r, q;
4855
4856         if (strv_length(args) <= 1)
4857                 return daemon_reload(bus, args);
4858
4859         r = expand_names(bus, args + 1, NULL, &names);
4860         if (r < 0)
4861                 log_error_errno(r, "Failed to expand names: %m");
4862
4863         STRV_FOREACH(name, names) {
4864                 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4865
4866                 q = sd_bus_message_new_method_call(
4867                                 bus,
4868                                 &m,
4869                                 "org.freedesktop.systemd1",
4870                                 "/org/freedesktop/systemd1",
4871                                 "org.freedesktop.systemd1.Manager",
4872                                 "ResetFailedUnit");
4873                 if (q < 0)
4874                         return bus_log_create_error(q);
4875
4876                 q = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4877                 if (q < 0)
4878                         return bus_log_create_error(q);
4879
4880                 q = sd_bus_message_append(m, "s", *name);
4881                 if (q < 0)
4882                         return bus_log_create_error(q);
4883
4884                 q = sd_bus_call(bus, m, 0, &error, NULL);
4885                 if (q < 0) {
4886                         log_error("Failed to reset failed state of unit %s: %s", *name, bus_error_message(&error, q));
4887                         if (r == 0)
4888                                 r = q;
4889                 }
4890         }
4891
4892         return r;
4893 }
4894
4895 static int show_environment(sd_bus *bus, char **args) {
4896         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4897         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4898         const char *text;
4899         int r;
4900
4901         pager_open_if_enabled();
4902
4903         r = sd_bus_get_property(
4904                         bus,
4905                         "org.freedesktop.systemd1",
4906                         "/org/freedesktop/systemd1",
4907                         "org.freedesktop.systemd1.Manager",
4908                         "Environment",
4909                         &error,
4910                         &reply,
4911                         "as");
4912         if (r < 0) {
4913                 log_error("Failed to get environment: %s", bus_error_message(&error, r));
4914                 return r;
4915         }
4916
4917         r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "s");
4918         if (r < 0)
4919                 return bus_log_parse_error(r);
4920
4921         while ((r = sd_bus_message_read_basic(reply, SD_BUS_TYPE_STRING, &text)) > 0)
4922                 puts(text);
4923         if (r < 0)
4924                 return bus_log_parse_error(r);
4925
4926         r = sd_bus_message_exit_container(reply);
4927         if (r < 0)
4928                 return bus_log_parse_error(r);
4929
4930         return 0;
4931 }
4932
4933 static int switch_root(sd_bus *bus, char **args) {
4934         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4935         _cleanup_free_ char *cmdline_init = NULL;
4936         const char *root, *init;
4937         unsigned l;
4938         int r;
4939
4940         l = strv_length(args);
4941         if (l < 2 || l > 3) {
4942                 log_error("Wrong number of arguments.");
4943                 return -EINVAL;
4944         }
4945
4946         root = args[1];
4947
4948         if (l >= 3)
4949                 init = args[2];
4950         else {
4951                 r = parse_env_file("/proc/cmdline", WHITESPACE,
4952                                    "init", &cmdline_init,
4953                                    NULL);
4954                 if (r < 0)
4955                         log_debug_errno(r, "Failed to parse /proc/cmdline: %m");
4956
4957                 init = cmdline_init;
4958         }
4959
4960         if (isempty(init))
4961                 init = NULL;
4962
4963         if (init) {
4964                 const char *root_systemd_path = NULL, *root_init_path = NULL;
4965
4966                 root_systemd_path = strappenda(root, "/" SYSTEMD_BINARY_PATH);
4967                 root_init_path = strappenda(root, "/", init);
4968
4969                 /* If the passed init is actually the same as the
4970                  * systemd binary, then let's suppress it. */
4971                 if (files_same(root_init_path, root_systemd_path) > 0)
4972                         init = NULL;
4973         }
4974
4975         log_debug("Switching root - root: %s; init: %s", root, strna(init));
4976
4977         r = sd_bus_call_method(
4978                         bus,
4979                         "org.freedesktop.systemd1",
4980                         "/org/freedesktop/systemd1",
4981                         "org.freedesktop.systemd1.Manager",
4982                         "SwitchRoot",
4983                         &error,
4984                         NULL,
4985                         "ss", root, init);
4986         if (r < 0) {
4987                 log_error("Failed to switch root: %s", bus_error_message(&error, r));
4988                 return r;
4989         }
4990
4991         return 0;
4992 }
4993
4994 static int set_environment(sd_bus *bus, char **args) {
4995         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4996         _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4997         const char *method;
4998         int r;
4999
5000         assert(bus);
5001         assert(args);
5002
5003         method = streq(args[0], "set-environment")
5004                 ? "SetEnvironment"
5005                 : "UnsetEnvironment";
5006
5007         r = sd_bus_message_new_method_call(
5008                         bus,
5009                         &m,
5010                         "org.freedesktop.systemd1",
5011                         "/org/freedesktop/systemd1",
5012                         "org.freedesktop.systemd1.Manager",
5013                         method);
5014         if (r < 0)
5015                 return bus_log_create_error(r);
5016
5017         r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5018         if (r < 0)
5019                 return bus_log_create_error(r);
5020
5021         r = sd_bus_message_append_strv(m, args + 1);
5022         if (r < 0)
5023                 return bus_log_create_error(r);
5024
5025         r = sd_bus_call(bus, m, 0, &error, NULL);
5026         if (r < 0) {
5027                 log_error("Failed to set environment: %s", bus_error_message(&error, r));
5028                 return r;
5029         }
5030
5031         return 0;
5032 }
5033
5034 static int import_environment(sd_bus *bus, char **args) {
5035         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5036         _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
5037         int r;
5038
5039         assert(bus);
5040         assert(args);
5041
5042         r = sd_bus_message_new_method_call(
5043                         bus,
5044                         &m,
5045                         "org.freedesktop.systemd1",
5046                         "/org/freedesktop/systemd1",
5047                         "org.freedesktop.systemd1.Manager",
5048                         "SetEnvironment");
5049         if (r < 0)
5050                 return bus_log_create_error(r);
5051
5052         r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5053         if (r < 0)
5054                 return bus_log_create_error(r);
5055
5056         if (strv_isempty(args + 1))
5057                 r = sd_bus_message_append_strv(m, environ);
5058         else {
5059                 char **a, **b;
5060
5061                 r = sd_bus_message_open_container(m, 'a', "s");
5062                 if (r < 0)
5063                         return bus_log_create_error(r);
5064
5065                 STRV_FOREACH(a, args + 1) {
5066
5067                         if (!env_name_is_valid(*a)) {
5068                                 log_error("Not a valid environment variable name: %s", *a);
5069                                 return -EINVAL;
5070                         }
5071
5072                         STRV_FOREACH(b, environ) {
5073                                 const char *eq;
5074
5075                                 eq = startswith(*b, *a);
5076                                 if (eq && *eq == '=') {
5077
5078                                         r = sd_bus_message_append(m, "s", *b);
5079                                         if (r < 0)
5080                                                 return bus_log_create_error(r);
5081
5082                                         break;
5083                                 }
5084                         }
5085                 }
5086
5087                 r = sd_bus_message_close_container(m);
5088         }
5089         if (r < 0)
5090                 return bus_log_create_error(r);
5091
5092         r = sd_bus_call(bus, m, 0, &error, NULL);
5093         if (r < 0) {
5094                 log_error("Failed to import environment: %s", bus_error_message(&error, r));
5095                 return r;
5096         }
5097
5098         return 0;
5099 }
5100
5101 static int enable_sysv_units(const char *verb, char **args) {
5102         int r = 0;
5103
5104 #if defined(HAVE_SYSV_COMPAT) && defined(HAVE_CHKCONFIG)
5105         unsigned f = 0;
5106         _cleanup_lookup_paths_free_ LookupPaths paths = {};
5107
5108         if (arg_scope != UNIT_FILE_SYSTEM)
5109                 return 0;
5110
5111         if (!streq(verb, "enable") &&
5112             !streq(verb, "disable") &&
5113             !streq(verb, "is-enabled"))
5114                 return 0;
5115
5116         /* Processes all SysV units, and reshuffles the array so that
5117          * afterwards only the native units remain */
5118
5119         r = lookup_paths_init(&paths, SYSTEMD_SYSTEM, false, arg_root, NULL, NULL, NULL);
5120         if (r < 0)
5121                 return r;
5122
5123         r = 0;
5124         while (args[f]) {
5125                 const char *name;
5126                 _cleanup_free_ char *p = NULL, *q = NULL, *l = NULL;
5127                 bool found_native = false, found_sysv;
5128                 unsigned c = 1;
5129                 const char *argv[6] = { "/sbin/chkconfig", NULL, NULL, NULL, NULL };
5130                 char **k;
5131                 int j;
5132                 pid_t pid;
5133                 siginfo_t status;
5134
5135                 name = args[f++];
5136
5137                 if (!endswith(name, ".service"))
5138                         continue;
5139
5140                 if (path_is_absolute(name))
5141                         continue;
5142
5143                 STRV_FOREACH(k, paths.unit_path) {
5144                         _cleanup_free_ char *path = NULL;
5145
5146                         path = path_join(arg_root, *k, name);
5147                         if (!path)
5148                                 return log_oom();
5149
5150                         found_native = access(path, F_OK) >= 0;
5151                         if (found_native)
5152                                 break;
5153                 }
5154
5155                 if (found_native)
5156                         continue;
5157
5158                 p = path_join(arg_root, SYSTEM_SYSVINIT_PATH, name);
5159                 if (!p)
5160                         return log_oom();
5161
5162                 p[strlen(p) - strlen(".service")] = 0;
5163                 found_sysv = access(p, F_OK) >= 0;
5164                 if (!found_sysv)
5165                         continue;
5166
5167                 log_info("%s is not a native service, redirecting to /sbin/chkconfig.", name);
5168
5169                 if (!isempty(arg_root))
5170                         argv[c++] = q = strappend("--root=", arg_root);
5171
5172                 argv[c++] = basename(p);
5173                 argv[c++] =
5174                         streq(verb, "enable") ? "on" :
5175                         streq(verb, "disable") ? "off" : "--level=5";
5176                 argv[c] = NULL;
5177
5178                 l = strv_join((char**)argv, " ");
5179                 if (!l)
5180                         return log_oom();
5181
5182                 log_info("Executing %s", l);
5183
5184                 pid = fork();
5185                 if (pid < 0)
5186                         return log_error_errno(errno, "Failed to fork: %m");
5187                 else if (pid == 0) {
5188                         /* Child */
5189
5190                         execv(argv[0], (char**) argv);
5191                         _exit(EXIT_FAILURE);
5192                 }
5193
5194                 j = wait_for_terminate(pid, &status);
5195                 if (j < 0) {
5196                         log_error_errno(r, "Failed to wait for child: %m");
5197                         return j;
5198                 }
5199
5200                 if (status.si_code == CLD_EXITED) {
5201                         if (streq(verb, "is-enabled")) {
5202                                 if (status.si_status == 0) {
5203                                         if (!arg_quiet)
5204                                                 puts("enabled");
5205                                         r = 1;
5206                                 } else {
5207                                         if (!arg_quiet)
5208                                                 puts("disabled");
5209                                 }
5210
5211                         } else if (status.si_status != 0)
5212                                 return -EINVAL;
5213                 } else
5214                         return -EPROTO;
5215
5216                 /* Remove this entry, so that we don't try enabling it as native unit */
5217                 assert(f > 0 && streq(args[f-1], name));
5218                 assert_se(strv_remove(args + f - 1, name));
5219         }
5220
5221 #endif
5222         return r;
5223 }
5224
5225 static int mangle_names(char **original_names, char ***mangled_names) {
5226         char **i, **l, **name;
5227
5228         l = new(char*, strv_length(original_names) + 1);
5229         if (!l)
5230                 return log_oom();
5231
5232         i = l;
5233         STRV_FOREACH(name, original_names) {
5234
5235                 /* When enabling units qualified path names are OK,
5236                  * too, hence allow them explicitly. */
5237
5238                 if (is_path(*name))
5239                         *i = strdup(*name);
5240                 else
5241                         *i = unit_name_mangle(*name, MANGLE_NOGLOB);
5242
5243                 if (!*i) {
5244                         strv_free(l);
5245                         return log_oom();
5246                 }
5247
5248                 i++;
5249         }
5250
5251         *i = NULL;
5252         *mangled_names = l;
5253
5254         return 0;
5255 }
5256
5257 static int enable_unit(sd_bus *bus, char **args) {
5258         _cleanup_strv_free_ char **names = NULL;
5259         const char *verb = args[0];
5260         UnitFileChange *changes = NULL;
5261         unsigned n_changes = 0;
5262         int carries_install_info = -1;
5263         int r;
5264
5265         if (!args[1])
5266                 return 0;
5267
5268         r = mangle_names(args+1, &names);
5269         if (r < 0)
5270                 return r;
5271
5272         r = enable_sysv_units(verb, names);
5273         if (r < 0)
5274                 return r;
5275
5276         /* If the operation was fully executed by the SysV compat,
5277          * let's finish early */
5278         if (strv_isempty(names))
5279                 return 0;
5280
5281         if (!bus || avoid_bus()) {
5282                 if (streq(verb, "enable")) {
5283                         r = unit_file_enable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5284                         carries_install_info = r;
5285                 } else if (streq(verb, "disable"))
5286                         r = unit_file_disable(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
5287                 else if (streq(verb, "reenable")) {
5288                         r = unit_file_reenable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5289                         carries_install_info = r;
5290                 } else if (streq(verb, "link"))
5291                         r = unit_file_link(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5292                 else if (streq(verb, "preset")) {
5293                         r = unit_file_preset(arg_scope, arg_runtime, arg_root, names, arg_preset_mode, arg_force, &changes, &n_changes);
5294                         carries_install_info = r;
5295                 } else if (streq(verb, "mask"))
5296                         r = unit_file_mask(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5297                 else if (streq(verb, "unmask"))
5298                         r = unit_file_unmask(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
5299                 else
5300                         assert_not_reached("Unknown verb");
5301
5302                 if (r < 0) {
5303                         log_error_errno(r, "Operation failed: %m");
5304                         goto finish;
5305                 }
5306
5307                 if (!arg_quiet)
5308                         dump_unit_file_changes(changes, n_changes);
5309
5310                 r = 0;
5311         } else {
5312                 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
5313                 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5314                 int expect_carries_install_info = false;
5315                 bool send_force = true, send_preset_mode = false;
5316                 const char *method;
5317
5318                 if (streq(verb, "enable")) {
5319                         method = "EnableUnitFiles";
5320                         expect_carries_install_info = true;
5321                 } else if (streq(verb, "disable")) {
5322                         method = "DisableUnitFiles";
5323                         send_force = false;
5324                 } else if (streq(verb, "reenable")) {
5325                         method = "ReenableUnitFiles";
5326                         expect_carries_install_info = true;
5327                 } else if (streq(verb, "link"))
5328                         method = "LinkUnitFiles";
5329                 else if (streq(verb, "preset")) {
5330
5331                         if (arg_preset_mode != UNIT_FILE_PRESET_FULL) {
5332                                 method = "PresetUnitFilesWithMode";
5333                                 send_preset_mode = true;
5334                         } else
5335                                 method = "PresetUnitFiles";
5336
5337                         expect_carries_install_info = true;
5338                 } else if (streq(verb, "mask"))
5339                         method = "MaskUnitFiles";
5340                 else if (streq(verb, "unmask")) {
5341                         method = "UnmaskUnitFiles";
5342                         send_force = false;
5343                 } else
5344                         assert_not_reached("Unknown verb");
5345
5346                 r = sd_bus_message_new_method_call(
5347                                 bus,
5348                                 &m,
5349                                 "org.freedesktop.systemd1",
5350                                 "/org/freedesktop/systemd1",
5351                                 "org.freedesktop.systemd1.Manager",
5352                                 method);
5353                 if (r < 0)
5354                         return bus_log_create_error(r);
5355
5356                 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5357                 if (r < 0)
5358                         return bus_log_create_error(r);
5359
5360                 r = sd_bus_message_append_strv(m, names);
5361                 if (r < 0)
5362                         return bus_log_create_error(r);
5363
5364                 if (send_preset_mode) {
5365                         r = sd_bus_message_append(m, "s", unit_file_preset_mode_to_string(arg_preset_mode));
5366                         if (r < 0)
5367                                 return bus_log_create_error(r);
5368                 }
5369
5370                 r = sd_bus_message_append(m, "b", arg_runtime);
5371                 if (r < 0)
5372                         return bus_log_create_error(r);
5373
5374                 if (send_force) {
5375                         r = sd_bus_message_append(m, "b", arg_force);
5376                         if (r < 0)
5377                                 return bus_log_create_error(r);
5378                 }
5379
5380                 r = sd_bus_call(bus, m, 0, &error, &reply);
5381                 if (r < 0) {
5382                         log_error("Failed to execute operation: %s", bus_error_message(&error, r));
5383                         return r;
5384                 }
5385
5386                 if (expect_carries_install_info) {
5387                         r = sd_bus_message_read(reply, "b", &carries_install_info);
5388                         if (r < 0)
5389                                 return bus_log_parse_error(r);
5390                 }
5391
5392                 r = deserialize_and_dump_unit_file_changes(reply);
5393                 if (r < 0)
5394                         return r;
5395
5396                 /* Try to reload if enabled */
5397                 if (!arg_no_reload)
5398                         r = daemon_reload(bus, args);
5399                 else
5400                         r = 0;
5401         }
5402
5403         if (carries_install_info == 0)
5404                 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
5405                             "using systemctl.\n"
5406                             "Possible reasons for having this kind of units are:\n"
5407                             "1) A unit may be statically enabled by being symlinked from another unit's\n"
5408                             "   .wants/ or .requires/ directory.\n"
5409                             "2) A unit's purpose may be to act as a helper for some other unit which has\n"
5410                             "   a requirement dependency on it.\n"
5411                             "3) A unit may be started when needed via activation (socket, path, timer,\n"
5412                             "   D-Bus, udev, scripted systemctl call, ...).\n");
5413
5414 finish:
5415         unit_file_changes_free(changes, n_changes);
5416
5417         return r;
5418 }
5419
5420 static int add_dependency(sd_bus *bus, char **args) {
5421         _cleanup_strv_free_ char **names = NULL;
5422         _cleanup_free_ char *target = NULL;
5423         const char *verb = args[0];
5424         UnitDependency dep;
5425         int r = 0;
5426
5427         if (!args[1])
5428                 return 0;
5429
5430         target = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".target");
5431         if (!target)
5432                 return log_oom();
5433
5434         r = mangle_names(args+2, &names);
5435         if (r < 0)
5436                 return r;
5437
5438         if (streq(verb, "add-wants"))
5439                 dep = UNIT_WANTS;
5440         else if (streq(verb, "add-requires"))
5441                 dep = UNIT_REQUIRES;
5442         else
5443                 assert_not_reached("Unknown verb");
5444
5445         if (!bus || avoid_bus()) {
5446                 UnitFileChange *changes = NULL;
5447                 unsigned n_changes = 0;
5448
5449                 r = unit_file_add_dependency(arg_scope, arg_runtime, arg_root, names, target, dep, arg_force, &changes, &n_changes);
5450
5451                 if (r < 0)
5452                         return log_error_errno(r, "Can't add dependency: %m");
5453
5454                 if (!arg_quiet)
5455                         dump_unit_file_changes(changes, n_changes);
5456
5457                 unit_file_changes_free(changes, n_changes);
5458
5459         } else {
5460                 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
5461                 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5462
5463                 r = sd_bus_message_new_method_call(
5464                                 bus,
5465                                 &m,
5466                                 "org.freedesktop.systemd1",
5467                                 "/org/freedesktop/systemd1",
5468                                 "org.freedesktop.systemd1.Manager",
5469                                 "AddDependencyUnitFiles");
5470                 if (r < 0)
5471                         return bus_log_create_error(r);
5472
5473                 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5474                 if (r < 0)
5475                         return bus_log_create_error(r);
5476
5477                 r = sd_bus_message_append_strv(m, names);
5478                 if (r < 0)
5479                         return bus_log_create_error(r);
5480
5481                 r = sd_bus_message_append(m, "ssbb", target, unit_dependency_to_string(dep), arg_runtime, arg_force);
5482                 if (r < 0)
5483                         return bus_log_create_error(r);
5484
5485                 r = sd_bus_call(bus, m, 0, &error, &reply);
5486                 if (r < 0) {
5487                         log_error("Failed to execute operation: %s", bus_error_message(&error, r));
5488                         return r;
5489                 }
5490
5491                 r = deserialize_and_dump_unit_file_changes(reply);
5492                 if (r < 0)
5493                         return r;
5494
5495                 if (!arg_no_reload)
5496                         r = daemon_reload(bus, args);
5497                 else
5498                         r = 0;
5499         }
5500
5501         return r;
5502 }
5503
5504 static int preset_all(sd_bus *bus, char **args) {
5505         UnitFileChange *changes = NULL;
5506         unsigned n_changes = 0;
5507         int r;
5508
5509         if (!bus || avoid_bus()) {
5510
5511                 r = unit_file_preset_all(arg_scope, arg_runtime, arg_root, arg_preset_mode, arg_force, &changes, &n_changes);
5512                 if (r < 0) {
5513                         log_error_errno(r, "Operation failed: %m");
5514                         goto finish;
5515                 }
5516
5517                 if (!arg_quiet)
5518                         dump_unit_file_changes(changes, n_changes);
5519
5520                 r = 0;
5521
5522         } else {
5523                 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
5524                 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5525
5526                 r = sd_bus_message_new_method_call(
5527                                 bus,
5528                                 &m,
5529                                 "org.freedesktop.systemd1",
5530                                 "/org/freedesktop/systemd1",
5531                                 "org.freedesktop.systemd1.Manager",
5532                                 "PresetAllUnitFiles");
5533                 if (r < 0)
5534                         return bus_log_create_error(r);
5535
5536                 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5537                 if (r < 0)
5538                         return bus_log_create_error(r);
5539
5540                 r = sd_bus_message_append(
5541                                 m,
5542                                 "sbb",
5543                                 unit_file_preset_mode_to_string(arg_preset_mode),
5544                                 arg_runtime,
5545                                 arg_force);
5546                 if (r < 0)
5547                         return bus_log_create_error(r);
5548
5549                 r = sd_bus_call(bus, m, 0, &error, &reply);
5550                 if (r < 0) {
5551                         log_error("Failed to execute operation: %s", bus_error_message(&error, r));
5552                         return r;
5553                 }
5554
5555                 r = deserialize_and_dump_unit_file_changes(reply);
5556                 if (r < 0)
5557                         return r;
5558
5559                 if (!arg_no_reload)
5560                         r = daemon_reload(bus, args);
5561                 else
5562                         r = 0;
5563         }
5564
5565 finish:
5566         unit_file_changes_free(changes, n_changes);
5567
5568         return r;
5569 }
5570
5571 static int unit_is_enabled(sd_bus *bus, char **args) {
5572
5573         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5574         _cleanup_strv_free_ char **names = NULL;
5575         bool enabled;
5576         char **name;
5577         int r;
5578
5579         r = mangle_names(args+1, &names);
5580         if (r < 0)
5581                 return r;
5582
5583         r = enable_sysv_units(args[0], names);
5584         if (r < 0)
5585                 return r;
5586
5587         enabled = r > 0;
5588
5589         if (!bus || avoid_bus()) {
5590
5591                 STRV_FOREACH(name, names) {
5592                         UnitFileState state;
5593
5594                         state = unit_file_get_state(arg_scope, arg_root, *name);
5595                         if (state < 0)
5596                                 return log_error_errno(state, "Failed to get unit file state for %s: %m", *name);
5597
5598                         if (state == UNIT_FILE_ENABLED ||
5599                             state == UNIT_FILE_ENABLED_RUNTIME ||
5600                             state == UNIT_FILE_STATIC ||
5601                             state == UNIT_FILE_INDIRECT)
5602                                 enabled = true;
5603
5604                         if (!arg_quiet)
5605                                 puts(unit_file_state_to_string(state));
5606                 }
5607
5608         } else {
5609                 STRV_FOREACH(name, names) {
5610                         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
5611                         const char *s;
5612
5613                         r = sd_bus_call_method(
5614                                         bus,
5615                                         "org.freedesktop.systemd1",
5616                                         "/org/freedesktop/systemd1",
5617                                         "org.freedesktop.systemd1.Manager",
5618                                         "GetUnitFileState",
5619                                         &error,
5620                                         &reply,
5621                                         "s", *name);
5622                         if (r < 0) {
5623                                 log_error("Failed to get unit file state for %s: %s", *name, bus_error_message(&error, r));
5624                                 return r;
5625                         }
5626
5627                         r = sd_bus_message_read(reply, "s", &s);
5628                         if (r < 0)
5629                                 return bus_log_parse_error(r);
5630
5631                         if (STR_IN_SET(s, "enabled", "enabled-runtime", "static", "indirect"))
5632                                 enabled = true;
5633
5634                         if (!arg_quiet)
5635                                 puts(s);
5636                 }
5637         }
5638
5639         return !enabled;
5640 }
5641
5642 static int is_system_running(sd_bus *bus, char **args) {
5643         _cleanup_free_ char *state = NULL;
5644         int r;
5645
5646         r = sd_bus_get_property_string(
5647                         bus,
5648                         "org.freedesktop.systemd1",
5649                         "/org/freedesktop/systemd1",
5650                         "org.freedesktop.systemd1.Manager",
5651                         "SystemState",
5652                         NULL,
5653                         &state);
5654         if (r < 0) {
5655                 if (!arg_quiet)
5656                         puts("unknown");
5657                 return 0;
5658         }
5659
5660         if (!arg_quiet)
5661                 puts(state);
5662
5663         return streq(state, "running") ? EXIT_SUCCESS : EXIT_FAILURE;
5664 }
5665
5666 static int create_edit_temp_file(const char *new_path, const char *original_path, char **ret_tmp_fn) {
5667         char *t;
5668         int r;
5669
5670         assert(new_path);
5671         assert(original_path);
5672         assert(ret_tmp_fn);
5673
5674         r = tempfn_random(new_path, &t);
5675         if (r < 0)
5676                 return log_error_errno(r, "Failed to determine temporary filename for %s: %m", new_path);
5677
5678         r = mkdir_parents(new_path, 0755);
5679         if (r < 0) {
5680                 log_error_errno(r, "Failed to create directories for %s: %m", new_path);
5681                 free(t);
5682                 return r;
5683         }
5684
5685         r = copy_file(original_path, t, 0, 0644);
5686         if (r == -ENOENT) {
5687                 r = touch(t);
5688                 if (r < 0) {
5689                         log_error_errno(r, "Failed to create temporary file %s: %m", t);
5690                         free(t);
5691                         return r;
5692                 }
5693         } else if (r < 0) {
5694                 log_error_errno(r, "Failed to copy %s to %s: %m", original_path, t);
5695                 free(t);
5696                 return r;
5697         }
5698
5699         *ret_tmp_fn = t;
5700
5701         return 0;
5702 }
5703
5704 static int get_file_to_edit(const char *name, const char *user_home, const char *user_runtime, char **ret_path) {
5705         _cleanup_free_ char *path = NULL, *path2 = NULL, *run = NULL;
5706
5707         switch (arg_scope) {
5708                 case UNIT_FILE_SYSTEM:
5709                         path = path_join(arg_root, SYSTEM_CONFIG_UNIT_PATH, name);
5710                         if (arg_runtime)
5711                                 run = path_join(arg_root, "/run/systemd/system/", name);
5712                         break;
5713                 case UNIT_FILE_GLOBAL:
5714                         path = path_join(arg_root, USER_CONFIG_UNIT_PATH, name);
5715                         if (arg_runtime)
5716                                 run = path_join(arg_root, "/run/systemd/user/", name);
5717                         break;
5718                 case UNIT_FILE_USER:
5719                         assert(user_home);
5720                         assert(user_runtime);
5721
5722                         path = path_join(arg_root, user_home, name);
5723                         if (arg_runtime) {
5724                                 path2 = path_join(arg_root, USER_CONFIG_UNIT_PATH, name);
5725                                 if (!path2)
5726                                         return log_oom();
5727                                 run = path_join(arg_root, user_runtime, name);
5728                         }
5729                         break;
5730                 default:
5731                         assert_not_reached("Invalid scope");
5732         }
5733         if (!path || (arg_runtime && !run))
5734                 return log_oom();
5735
5736         if (arg_runtime) {
5737                 if (access(path, F_OK) >= 0)
5738                         return log_error_errno(EEXIST, "Refusing to create \"%s\" because it would be overriden by \"%s\" anyway.",
5739                                                run, path);
5740                 if (path2 && access(path2, F_OK) >= 0)
5741                         return log_error_errno(EEXIST, "Refusing to create \"%s\" because it would be overriden by \"%s\" anyway.",
5742                                                run, path2);
5743                 *ret_path = run;
5744                 run = NULL;
5745         } else {
5746                 *ret_path = path;
5747                 path = NULL;
5748         }
5749
5750         return 0;
5751 }
5752
5753
5754 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) {
5755         char *tmp_new_path, *ending;
5756         char *tmp_tmp_path;
5757         int r;
5758
5759         assert(unit_name);
5760         assert(ret_new_path);
5761         assert(ret_tmp_path);
5762
5763         ending = strappenda(unit_name, ".d/override.conf");
5764         r = get_file_to_edit(ending, user_home, user_runtime, &tmp_new_path);
5765         if (r < 0)
5766                 return r;
5767
5768         r = create_edit_temp_file(tmp_new_path, tmp_new_path, &tmp_tmp_path);
5769         if (r < 0) {
5770                 free(tmp_new_path);
5771                 return r;
5772         }
5773
5774         *ret_new_path = tmp_new_path;
5775         *ret_tmp_path = tmp_tmp_path;
5776
5777         return 0;
5778 }
5779
5780 static int unit_file_create_copy(const char *unit_name,
5781                                  const char *fragment_path,
5782                                  const char *user_home,
5783                                  const char *user_runtime,
5784                                  char **ret_new_path,
5785                                  char **ret_tmp_path) {
5786         char *tmp_new_path;
5787         char *tmp_tmp_path;
5788         int r;
5789
5790         assert(fragment_path);
5791         assert(unit_name);
5792         assert(ret_new_path);
5793         assert(ret_tmp_path);
5794
5795         r = get_file_to_edit(unit_name, user_home, user_runtime, &tmp_new_path);
5796         if (r < 0)
5797                 return r;
5798
5799         if (!path_equal(fragment_path, tmp_new_path) && access(tmp_new_path, F_OK) == 0) {
5800                 char response;
5801
5802                 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);
5803                 if (r < 0) {
5804                         free(tmp_new_path);
5805                         return r;
5806                 }
5807                 if (response != 'y') {
5808                         log_warning("%s ignored", unit_name);
5809                         free(tmp_new_path);
5810                         return -1;
5811                 }
5812         }
5813
5814         r = create_edit_temp_file(tmp_new_path, fragment_path, &tmp_tmp_path);
5815         if (r < 0) {
5816                 log_error_errno(r, "Failed to create temporary file for %s: %m", tmp_new_path);
5817                 free(tmp_new_path);
5818                 return r;
5819         }
5820
5821         *ret_new_path = tmp_new_path;
5822         *ret_tmp_path = tmp_tmp_path;
5823
5824         return 0;
5825 }
5826
5827 static int run_editor(char **paths) {
5828         pid_t pid;
5829         int r;
5830
5831         assert(paths);
5832
5833         pid = fork();
5834         if (pid < 0) {
5835                 log_error_errno(errno, "Failed to fork: %m");
5836                 return -errno;
5837         }
5838
5839         if (pid == 0) {
5840                 const char **args;
5841                 char **backup_editors = STRV_MAKE("nano", "vim", "vi");
5842                 char *editor;
5843                 char **tmp_path, **original_path, **p;
5844                 unsigned i = 1;
5845                 size_t argc;
5846
5847                 argc = strv_length(paths)/2 + 1;
5848                 args = newa(const char*, argc + 1);
5849
5850                 args[0] = NULL;
5851                 STRV_FOREACH_PAIR(original_path, tmp_path, paths) {
5852                         args[i] = *tmp_path;
5853                         i++;
5854                 }
5855                 args[argc] = NULL;
5856
5857                 /* SYSTEMD_EDITOR takes precedence over EDITOR which takes precedence over VISUAL
5858                  * If neither SYSTEMD_EDITOR nor EDITOR nor VISUAL are present,
5859                  * we try to execute well known editors
5860                  */
5861                 editor = getenv("SYSTEMD_EDITOR");
5862                 if (!editor)
5863                         editor = getenv("EDITOR");
5864                 if (!editor)
5865                         editor = getenv("VISUAL");
5866
5867                 if (!isempty(editor)) {
5868                         args[0] = editor;
5869                         execvp(editor, (char* const*) args);
5870                 }
5871
5872                 STRV_FOREACH(p, backup_editors) {
5873                         args[0] = *p;
5874                         execvp(*p, (char* const*) args);
5875                         /* We do not fail if the editor doesn't exist
5876                          * because we want to try each one of them before
5877                          * failing.
5878                          */
5879                         if (errno != ENOENT) {
5880                                 log_error("Failed to execute %s: %m", editor);
5881                                 _exit(EXIT_FAILURE);
5882                         }
5883                 }
5884
5885                 log_error("Cannot edit unit(s), no editor available. Please set either $SYSTEMD_EDITOR or $EDITOR or $VISUAL.");
5886                 _exit(EXIT_FAILURE);
5887         }
5888
5889         r = wait_for_terminate_and_warn("editor", pid, true);
5890         if (r < 0)
5891                 return log_error_errno(r, "Failed to wait for child: %m");
5892
5893         return r;
5894 }
5895
5896 static int find_paths_to_edit(sd_bus *bus, char **names, char ***paths) {
5897         _cleanup_free_ char *user_home = NULL;
5898         _cleanup_free_ char *user_runtime = NULL;
5899         _cleanup_lookup_paths_free_ LookupPaths lp = {};
5900         bool avoid_bus_cache;
5901         char **name;
5902         int r;
5903
5904         assert(names);
5905         assert(paths);
5906
5907         r = init_home_and_lookup_paths(&user_home, &user_runtime, &lp);
5908         if (r < 0)
5909                 return r;
5910
5911         avoid_bus_cache = !bus || avoid_bus();
5912
5913         STRV_FOREACH(name, names) {
5914                 _cleanup_free_ char *path = NULL;
5915                 char *new_path, *tmp_path;
5916
5917                 r = unit_find_paths(bus, *name, avoid_bus_cache, &lp, &path, NULL);
5918                 if (r < 0)
5919                         return r;
5920                 else if (r == 0 || !path)
5921                         // FIXME: support units with path==NULL (no FragmentPath)
5922                         return log_error_errno(ENOENT, "Unit %s not found, cannot edit.", *name);
5923
5924                 if (arg_full)
5925                         r = unit_file_create_copy(*name, path, user_home, user_runtime, &new_path, &tmp_path);
5926                 else
5927                         r = unit_file_create_dropin(*name, user_home, user_runtime, &new_path, &tmp_path);
5928                 if (r < 0)
5929                         return r;
5930
5931                 r = strv_push_pair(paths, new_path, tmp_path);
5932                 if (r < 0)
5933                         return log_oom();
5934         }
5935
5936         return 0;
5937 }
5938
5939 static int edit(sd_bus *bus, char **args) {
5940         _cleanup_strv_free_ char **names = NULL;
5941         _cleanup_strv_free_ char **paths = NULL;
5942         char **original, **tmp;
5943         int r;
5944
5945         assert(args);
5946
5947         if (!on_tty()) {
5948                 log_error("Cannot edit units if we are not on a tty");
5949                 return -EINVAL;
5950         }
5951
5952         if (arg_transport != BUS_TRANSPORT_LOCAL) {
5953                 log_error("Cannot remotely edit units");
5954                 return -EINVAL;
5955         }
5956
5957         r = expand_names(bus, args + 1, NULL, &names);
5958         if (r < 0)
5959                 return log_error_errno(r, "Failed to expand names: %m");
5960
5961         if (!names) {
5962                 log_error("No unit name found by expanding names");
5963                 return -ENOENT;
5964         }
5965
5966         r = find_paths_to_edit(bus, names, &paths);
5967         if (r < 0)
5968                 return r;
5969
5970         if (strv_isempty(paths)) {
5971                 log_error("Cannot find any units to edit");
5972                 return -ENOENT;
5973         }
5974
5975         r = run_editor(paths);
5976         if (r < 0)
5977                 goto end;
5978
5979         STRV_FOREACH_PAIR(original, tmp, paths) {
5980                 /* If the temporary file is empty we ignore it.
5981                  * It's useful if the user wants to cancel its modification
5982                  */
5983                 if (null_or_empty_path(*tmp)) {
5984                         log_warning("Edition of %s canceled: temporary file empty", *original);
5985                         continue;
5986                 }
5987                 r = rename(*tmp, *original);
5988                 if (r < 0) {
5989                         r = log_error_errno(errno, "Failed to rename %s to %s: %m", *tmp, *original);
5990                         goto end;
5991                 }
5992         }
5993
5994         if (!arg_no_reload && bus && !avoid_bus())
5995                 r = daemon_reload(bus, args);
5996
5997 end:
5998         STRV_FOREACH_PAIR(original, tmp, paths)
5999                 unlink_noerrno(*tmp);
6000
6001         return r;
6002 }
6003
6004 static void systemctl_help(void) {
6005
6006         pager_open_if_enabled();
6007
6008         printf("%s [OPTIONS...] {COMMAND} ...\n\n"
6009                "Query or send control commands to the systemd manager.\n\n"
6010                "  -h --help           Show this help\n"
6011                "     --version        Show package version\n"
6012                "     --system         Connect to system manager\n"
6013                "     --user           Connect to user service manager\n"
6014                "  -H --host=[USER@]HOST\n"
6015                "                      Operate on remote host\n"
6016                "  -M --machine=CONTAINER\n"
6017                "                      Operate on local container\n"
6018                "  -t --type=TYPE      List only units of a particular type\n"
6019                "     --state=STATE    List only units with particular LOAD or SUB or ACTIVE state\n"
6020                "  -p --property=NAME  Show only properties by this name\n"
6021                "  -a --all            Show all loaded units/properties, including dead/empty\n"
6022                "                      ones. To list all units installed on the system, use\n"
6023                "                      the 'list-unit-files' command instead.\n"
6024                "  -l --full           Don't ellipsize unit names on output\n"
6025                "  -r --recursive      Show unit list of host and local containers\n"
6026                "     --reverse        Show reverse dependencies with 'list-dependencies'\n"
6027                "     --job-mode=MODE  Specify how to deal with already queued jobs, when\n"
6028                "                      queueing a new job\n"
6029                "     --show-types     When showing sockets, explicitly show their type\n"
6030                "  -i --ignore-inhibitors\n"
6031                "                      When shutting down or sleeping, ignore inhibitors\n"
6032                "     --kill-who=WHO   Who to send signal to\n"
6033                "  -s --signal=SIGNAL  Which signal to send\n"
6034                "  -q --quiet          Suppress output\n"
6035                "     --no-block       Do not wait until operation finished\n"
6036                "     --no-wall        Don't send wall message before halt/power-off/reboot\n"
6037                "     --no-reload      When enabling/disabling unit files, don't reload daemon\n"
6038                "                      configuration\n"
6039                "     --no-legend      Do not print a legend (column headers and hints)\n"
6040                "     --no-pager       Do not pipe output into a pager\n"
6041                "     --no-ask-password\n"
6042                "                      Do not ask for system passwords\n"
6043                "     --global         Enable/disable unit files globally\n"
6044                "     --runtime        Enable unit files only temporarily until next reboot\n"
6045                "  -f --force          When enabling unit files, override existing symlinks\n"
6046                "                      When shutting down, execute action immediately\n"
6047                "     --preset-mode=   Specifies whether fully apply presets, or only enable,\n"
6048                "                      or only disable\n"
6049                "     --root=PATH      Enable unit files in the specified root directory\n"
6050                "  -n --lines=INTEGER  Number of journal entries to show\n"
6051                "  -o --output=STRING  Change journal output mode (short, short-monotonic,\n"
6052                "                      verbose, export, json, json-pretty, json-sse, cat)\n"
6053                "     --plain          Print unit dependencies as a list instead of a tree\n\n"
6054                "Unit Commands:\n"
6055                "  list-units [PATTERN...]         List loaded units\n"
6056                "  list-sockets [PATTERN...]       List loaded sockets ordered by address\n"
6057                "  list-timers [PATTERN...]        List loaded timers ordered by next elapse\n"
6058                "  start NAME...                   Start (activate) one or more units\n"
6059                "  stop NAME...                    Stop (deactivate) one or more units\n"
6060                "  reload NAME...                  Reload one or more units\n"
6061                "  restart NAME...                 Start or restart one or more units\n"
6062                "  try-restart NAME...             Restart one or more units if active\n"
6063                "  reload-or-restart NAME...       Reload one or more units if possible,\n"
6064                "                                  otherwise start or restart\n"
6065                "  reload-or-try-restart NAME...   Reload one or more units if possible,\n"
6066                "                                  otherwise restart if active\n"
6067                "  isolate NAME                    Start one unit and stop all others\n"
6068                "  kill NAME...                    Send signal to processes of a unit\n"
6069                "  is-active PATTERN...            Check whether units are active\n"
6070                "  is-failed PATTERN...            Check whether units are failed\n"
6071                "  status [PATTERN...|PID...]      Show runtime status of one or more units\n"
6072                "  show [PATTERN...|JOB...]        Show properties of one or more\n"
6073                "                                  units/jobs or the manager\n"
6074                "  cat PATTERN...                  Show files and drop-ins of one or more units\n"
6075                "  set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
6076                "  help PATTERN...|PID...          Show manual for one or more units\n"
6077                "  reset-failed [PATTERN...]       Reset failed state for all, one, or more\n"
6078                "                                  units\n"
6079                "  list-dependencies [NAME]        Recursively show units which are required\n"
6080                "                                  or wanted by this unit or by which this\n"
6081                "                                  unit is required or wanted\n\n"
6082                "Unit File Commands:\n"
6083                "  list-unit-files [PATTERN...]    List installed unit files\n"
6084                "  enable NAME...                  Enable one or more unit files\n"
6085                "  disable NAME...                 Disable one or more unit files\n"
6086                "  reenable NAME...                Reenable one or more unit files\n"
6087                "  preset NAME...                  Enable/disable one or more unit files\n"
6088                "                                  based on preset configuration\n"
6089                "  preset-all                      Enable/disable all unit files based on\n"
6090                "                                  preset configuration\n"
6091                "  is-enabled NAME...              Check whether unit files are enabled\n\n"
6092                "  mask NAME...                    Mask one or more units\n"
6093                "  unmask NAME...                  Unmask one or more units\n"
6094                "  link PATH...                    Link one or more units files into\n"
6095                "                                  the search path\n"
6096                "  add-wants TARGET NAME...        Add 'Wants' dependency for the target\n"
6097                "                                  on specified one or more units\n"
6098                "  add-requires TARGET NAME...     Add 'Requires' dependency for the target\n"
6099                "                                  on specified one or more units\n"
6100                "  get-default                     Get the name of the default target\n"
6101                "  set-default NAME                Set the default target\n"
6102                "  edit NAME...                    Edit one or more unit files\n"
6103                "\n"
6104                "Machine Commands:\n"
6105                "  list-machines [PATTERN...]      List local containers and host\n\n"
6106                "Job Commands:\n"
6107                "  list-jobs [PATTERN...]          List jobs\n"
6108                "  cancel [JOB...]                 Cancel all, one, or more jobs\n\n"
6109                "Snapshot Commands:\n"
6110                "  snapshot [NAME]                 Create a snapshot\n"
6111                "  delete NAME...                  Remove one or more snapshots\n\n"
6112                "Environment Commands:\n"
6113                "  show-environment                Dump environment\n"
6114                "  set-environment NAME=VALUE...   Set one or more environment variables\n"
6115                "  unset-environment NAME...       Unset one or more environment variables\n"
6116                "  import-environment NAME...      Import all, one or more environment variables\n\n"
6117                "Manager Lifecycle Commands:\n"
6118                "  daemon-reload                   Reload systemd manager configuration\n"
6119                "  daemon-reexec                   Reexecute systemd manager\n\n"
6120                "System Commands:\n"
6121                "  is-system-running               Check whether system is fully running\n"
6122                "  default                         Enter system default mode\n"
6123                "  rescue                          Enter system rescue mode\n"
6124                "  emergency                       Enter system emergency mode\n"
6125                "  halt                            Shut down and halt the system\n"
6126                "  poweroff                        Shut down and power-off the system\n"
6127                "  reboot [ARG]                    Shut down and reboot the system\n"
6128                "  kexec                           Shut down and reboot the system with kexec\n"
6129                "  exit                            Request user instance exit\n"
6130                "  switch-root ROOT [INIT]         Change to a different root file system\n"
6131                "  suspend                         Suspend the system\n"
6132                "  hibernate                       Hibernate the system\n"
6133                "  hybrid-sleep                    Hibernate and suspend the system\n",
6134                program_invocation_short_name);
6135 }
6136
6137 static void halt_help(void) {
6138         printf("%s [OPTIONS...]%s\n\n"
6139                "%s the system.\n\n"
6140                "     --help      Show this help\n"
6141                "     --halt      Halt the machine\n"
6142                "  -p --poweroff  Switch off the machine\n"
6143                "     --reboot    Reboot the machine\n"
6144                "  -f --force     Force immediate halt/power-off/reboot\n"
6145                "  -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
6146                "  -d --no-wtmp   Don't write wtmp record\n"
6147                "     --no-wall   Don't send wall message before halt/power-off/reboot\n",
6148                program_invocation_short_name,
6149                arg_action == ACTION_REBOOT   ? " [ARG]" : "",
6150                arg_action == ACTION_REBOOT   ? "Reboot" :
6151                arg_action == ACTION_POWEROFF ? "Power off" :
6152                                                "Halt");
6153 }
6154
6155 static void shutdown_help(void) {
6156         printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
6157                "Shut down the system.\n\n"
6158                "     --help      Show this help\n"
6159                "  -H --halt      Halt the machine\n"
6160                "  -P --poweroff  Power-off the machine\n"
6161                "  -r --reboot    Reboot the machine\n"
6162                "  -h             Equivalent to --poweroff, overridden by --halt\n"
6163                "  -k             Don't halt/power-off/reboot, just send warnings\n"
6164                "     --no-wall   Don't send wall message before halt/power-off/reboot\n"
6165                "  -c             Cancel a pending shutdown\n",
6166                program_invocation_short_name);
6167 }
6168
6169 static void telinit_help(void) {
6170         printf("%s [OPTIONS...] {COMMAND}\n\n"
6171                "Send control commands to the init daemon.\n\n"
6172                "     --help      Show this help\n"
6173                "     --no-wall   Don't send wall message before halt/power-off/reboot\n\n"
6174                "Commands:\n"
6175                "  0              Power-off the machine\n"
6176                "  6              Reboot the machine\n"
6177                "  2, 3, 4, 5     Start runlevelX.target unit\n"
6178                "  1, s, S        Enter rescue mode\n"
6179                "  q, Q           Reload init daemon configuration\n"
6180                "  u, U           Reexecute init daemon\n",
6181                program_invocation_short_name);
6182 }
6183
6184 static void runlevel_help(void) {
6185         printf("%s [OPTIONS...]\n\n"
6186                "Prints the previous and current runlevel of the init system.\n\n"
6187                "     --help      Show this help\n",
6188                program_invocation_short_name);
6189 }
6190
6191 static void help_types(void) {
6192         int i;
6193         const char *t;
6194
6195         if (!arg_no_legend)
6196                 puts("Available unit types:");
6197         for (i = 0; i < _UNIT_TYPE_MAX; i++) {
6198                 t = unit_type_to_string(i);
6199                 if (t)
6200                         puts(t);
6201         }
6202 }
6203
6204 static int systemctl_parse_argv(int argc, char *argv[]) {
6205
6206         enum {
6207                 ARG_FAIL = 0x100,
6208                 ARG_REVERSE,
6209                 ARG_AFTER,
6210                 ARG_BEFORE,
6211                 ARG_SHOW_TYPES,
6212                 ARG_IRREVERSIBLE,
6213                 ARG_IGNORE_DEPENDENCIES,
6214                 ARG_VERSION,
6215                 ARG_USER,
6216                 ARG_SYSTEM,
6217                 ARG_GLOBAL,
6218                 ARG_NO_BLOCK,
6219                 ARG_NO_LEGEND,
6220                 ARG_NO_PAGER,
6221                 ARG_NO_WALL,
6222                 ARG_ROOT,
6223                 ARG_NO_RELOAD,
6224                 ARG_KILL_WHO,
6225                 ARG_NO_ASK_PASSWORD,
6226                 ARG_FAILED,
6227                 ARG_RUNTIME,
6228                 ARG_FORCE,
6229                 ARG_PLAIN,
6230                 ARG_STATE,
6231                 ARG_JOB_MODE,
6232                 ARG_PRESET_MODE,
6233         };
6234
6235         static const struct option options[] = {
6236                 { "help",                no_argument,       NULL, 'h'                     },
6237                 { "version",             no_argument,       NULL, ARG_VERSION             },
6238                 { "type",                required_argument, NULL, 't'                     },
6239                 { "property",            required_argument, NULL, 'p'                     },
6240                 { "all",                 no_argument,       NULL, 'a'                     },
6241                 { "reverse",             no_argument,       NULL, ARG_REVERSE             },
6242                 { "after",               no_argument,       NULL, ARG_AFTER               },
6243                 { "before",              no_argument,       NULL, ARG_BEFORE              },
6244                 { "show-types",          no_argument,       NULL, ARG_SHOW_TYPES          },
6245                 { "failed",              no_argument,       NULL, ARG_FAILED              }, /* compatibility only */
6246                 { "full",                no_argument,       NULL, 'l'                     },
6247                 { "job-mode",            required_argument, NULL, ARG_JOB_MODE            },
6248                 { "fail",                no_argument,       NULL, ARG_FAIL                }, /* compatibility only */
6249                 { "irreversible",        no_argument,       NULL, ARG_IRREVERSIBLE        }, /* compatibility only */
6250                 { "ignore-dependencies", no_argument,       NULL, ARG_IGNORE_DEPENDENCIES }, /* compatibility only */
6251                 { "ignore-inhibitors",   no_argument,       NULL, 'i'                     },
6252                 { "user",                no_argument,       NULL, ARG_USER                },
6253                 { "system",              no_argument,       NULL, ARG_SYSTEM              },
6254                 { "global",              no_argument,       NULL, ARG_GLOBAL              },
6255                 { "no-block",            no_argument,       NULL, ARG_NO_BLOCK            },
6256                 { "no-legend",           no_argument,       NULL, ARG_NO_LEGEND           },
6257                 { "no-pager",            no_argument,       NULL, ARG_NO_PAGER            },
6258                 { "no-wall",             no_argument,       NULL, ARG_NO_WALL             },
6259                 { "quiet",               no_argument,       NULL, 'q'                     },
6260                 { "root",                required_argument, NULL, ARG_ROOT                },
6261                 { "force",               no_argument,       NULL, ARG_FORCE               },
6262                 { "no-reload",           no_argument,       NULL, ARG_NO_RELOAD           },
6263                 { "kill-who",            required_argument, NULL, ARG_KILL_WHO            },
6264                 { "signal",              required_argument, NULL, 's'                     },
6265                 { "no-ask-password",     no_argument,       NULL, ARG_NO_ASK_PASSWORD     },
6266                 { "host",                required_argument, NULL, 'H'                     },
6267                 { "machine",             required_argument, NULL, 'M'                     },
6268                 { "runtime",             no_argument,       NULL, ARG_RUNTIME             },
6269                 { "lines",               required_argument, NULL, 'n'                     },
6270                 { "output",              required_argument, NULL, 'o'                     },
6271                 { "plain",               no_argument,       NULL, ARG_PLAIN               },
6272                 { "state",               required_argument, NULL, ARG_STATE               },
6273                 { "recursive",           no_argument,       NULL, 'r'                     },
6274                 { "preset-mode",         required_argument, NULL, ARG_PRESET_MODE         },
6275                 {}
6276         };
6277
6278         int c;
6279
6280         assert(argc >= 0);
6281         assert(argv);
6282
6283         while ((c = getopt_long(argc, argv, "ht:p:alqfs:H:M:n:o:ir", options, NULL)) >= 0)
6284
6285                 switch (c) {
6286
6287                 case 'h':
6288                         systemctl_help();
6289                         return 0;
6290
6291                 case ARG_VERSION:
6292                         puts(PACKAGE_STRING);
6293                         puts(SYSTEMD_FEATURES);
6294                         return 0;
6295
6296                 case 't': {
6297                         const char *word, *state;
6298                         size_t size;
6299
6300                         FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
6301                                 _cleanup_free_ char *type;
6302
6303                                 type = strndup(word, size);
6304                                 if (!type)
6305                                         return -ENOMEM;
6306
6307                                 if (streq(type, "help")) {
6308                                         help_types();
6309                                         return 0;
6310                                 }
6311
6312                                 if (unit_type_from_string(type) >= 0) {
6313                                         if (strv_push(&arg_types, type))
6314                                                 return log_oom();
6315                                         type = NULL;
6316                                         continue;
6317                                 }
6318
6319                                 /* It's much nicer to use --state= for
6320                                  * load states, but let's support this
6321                                  * in --types= too for compatibility
6322                                  * with old versions */
6323                                 if (unit_load_state_from_string(optarg) >= 0) {
6324                                         if (strv_push(&arg_states, type) < 0)
6325                                                 return log_oom();
6326                                         type = NULL;
6327                                         continue;
6328                                 }
6329
6330                                 log_error("Unknown unit type or load state '%s'.", type);
6331                                 log_info("Use -t help to see a list of allowed values.");
6332                                 return -EINVAL;
6333                         }
6334
6335                         break;
6336                 }
6337
6338                 case 'p': {
6339                         /* Make sure that if the empty property list
6340                            was specified, we won't show any properties. */
6341                         if (isempty(optarg) && !arg_properties) {
6342                                 arg_properties = new0(char*, 1);
6343                                 if (!arg_properties)
6344                                         return log_oom();
6345                         } else {
6346                                 const char *word, *state;
6347                                 size_t size;
6348
6349                                 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
6350                                         char *prop;
6351
6352                                         prop = strndup(word, size);
6353                                         if (!prop)
6354                                                 return log_oom();
6355
6356                                         if (strv_consume(&arg_properties, prop) < 0)
6357                                                 return log_oom();
6358                                 }
6359                         }
6360
6361                         /* If the user asked for a particular
6362                          * property, show it to him, even if it is
6363                          * empty. */
6364                         arg_all = true;
6365
6366                         break;
6367                 }
6368
6369                 case 'a':
6370                         arg_all = true;
6371                         break;
6372
6373                 case ARG_REVERSE:
6374                         arg_dependency = DEPENDENCY_REVERSE;
6375                         break;
6376
6377                 case ARG_AFTER:
6378                         arg_dependency = DEPENDENCY_AFTER;
6379                         break;
6380
6381                 case ARG_BEFORE:
6382                         arg_dependency = DEPENDENCY_BEFORE;
6383                         break;
6384
6385                 case ARG_SHOW_TYPES:
6386                         arg_show_types = true;
6387                         break;
6388
6389                 case ARG_JOB_MODE:
6390                         arg_job_mode = optarg;
6391                         break;
6392
6393                 case ARG_FAIL:
6394                         arg_job_mode = "fail";
6395                         break;
6396
6397                 case ARG_IRREVERSIBLE:
6398                         arg_job_mode = "replace-irreversibly";
6399                         break;
6400
6401                 case ARG_IGNORE_DEPENDENCIES:
6402                         arg_job_mode = "ignore-dependencies";
6403                         break;
6404
6405                 case ARG_USER:
6406                         arg_scope = UNIT_FILE_USER;
6407                         break;
6408
6409                 case ARG_SYSTEM:
6410                         arg_scope = UNIT_FILE_SYSTEM;
6411                         break;
6412
6413                 case ARG_GLOBAL:
6414                         arg_scope = UNIT_FILE_GLOBAL;
6415                         break;
6416
6417                 case ARG_NO_BLOCK:
6418                         arg_no_block = true;
6419                         break;
6420
6421                 case ARG_NO_LEGEND:
6422                         arg_no_legend = true;
6423                         break;
6424
6425                 case ARG_NO_PAGER:
6426                         arg_no_pager = true;
6427                         break;
6428
6429                 case ARG_NO_WALL:
6430                         arg_no_wall = true;
6431                         break;
6432
6433                 case ARG_ROOT:
6434                         arg_root = optarg;
6435                         break;
6436
6437                 case 'l':
6438                         arg_full = true;
6439                         break;
6440
6441                 case ARG_FAILED:
6442                         if (strv_extend(&arg_states, "failed") < 0)
6443                                 return log_oom();
6444
6445                         break;
6446
6447                 case 'q':
6448                         arg_quiet = true;
6449                         break;
6450
6451                 case ARG_FORCE:
6452                         arg_force ++;
6453                         break;
6454
6455                 case 'f':
6456                         arg_force ++;
6457                         break;
6458
6459                 case ARG_NO_RELOAD:
6460                         arg_no_reload = true;
6461                         break;
6462
6463                 case ARG_KILL_WHO:
6464                         arg_kill_who = optarg;
6465                         break;
6466
6467                 case 's':
6468                         if ((arg_signal = signal_from_string_try_harder(optarg)) < 0) {
6469                                 log_error("Failed to parse signal string %s.", optarg);
6470                                 return -EINVAL;
6471                         }
6472                         break;
6473
6474                 case ARG_NO_ASK_PASSWORD:
6475                         arg_ask_password = false;
6476                         break;
6477
6478                 case 'H':
6479                         arg_transport = BUS_TRANSPORT_REMOTE;
6480                         arg_host = optarg;
6481                         break;
6482
6483                 case 'M':
6484                         arg_transport = BUS_TRANSPORT_MACHINE;
6485                         arg_host = optarg;
6486                         break;
6487
6488                 case ARG_RUNTIME:
6489                         arg_runtime = true;
6490                         break;
6491
6492                 case 'n':
6493                         if (safe_atou(optarg, &arg_lines) < 0) {
6494                                 log_error("Failed to parse lines '%s'", optarg);
6495                                 return -EINVAL;
6496                         }
6497                         break;
6498
6499                 case 'o':
6500                         arg_output = output_mode_from_string(optarg);
6501                         if (arg_output < 0) {
6502                                 log_error("Unknown output '%s'.", optarg);
6503                                 return -EINVAL;
6504                         }
6505                         break;
6506
6507                 case 'i':
6508                         arg_ignore_inhibitors = true;
6509                         break;
6510
6511                 case ARG_PLAIN:
6512                         arg_plain = true;
6513                         break;
6514
6515                 case ARG_STATE: {
6516                         const char *word, *state;
6517                         size_t size;
6518
6519                         FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
6520                                 char *s;
6521
6522                                 s = strndup(word, size);
6523                                 if (!s)
6524                                         return log_oom();
6525
6526                                 if (strv_consume(&arg_states, s) < 0)
6527                                         return log_oom();
6528                         }
6529                         break;
6530                 }
6531
6532                 case 'r':
6533                         if (geteuid() != 0) {
6534                                 log_error("--recursive requires root privileges.");
6535                                 return -EPERM;
6536                         }
6537
6538                         arg_recursive = true;
6539                         break;
6540
6541                 case ARG_PRESET_MODE:
6542
6543                         arg_preset_mode = unit_file_preset_mode_from_string(optarg);
6544                         if (arg_preset_mode < 0) {
6545                                 log_error("Failed to parse preset mode: %s.", optarg);
6546                                 return -EINVAL;
6547                         }
6548
6549                         break;
6550
6551                 case '?':
6552                         return -EINVAL;
6553
6554                 default:
6555                         assert_not_reached("Unhandled option");
6556                 }
6557
6558         if (arg_transport != BUS_TRANSPORT_LOCAL && arg_scope != UNIT_FILE_SYSTEM) {
6559                 log_error("Cannot access user instance remotely.");
6560                 return -EINVAL;
6561         }
6562
6563         return 1;
6564 }
6565
6566 static int halt_parse_argv(int argc, char *argv[]) {
6567
6568         enum {
6569                 ARG_HELP = 0x100,
6570                 ARG_HALT,
6571                 ARG_REBOOT,
6572                 ARG_NO_WALL
6573         };
6574
6575         static const struct option options[] = {
6576                 { "help",      no_argument,       NULL, ARG_HELP    },
6577                 { "halt",      no_argument,       NULL, ARG_HALT    },
6578                 { "poweroff",  no_argument,       NULL, 'p'         },
6579                 { "reboot",    no_argument,       NULL, ARG_REBOOT  },
6580                 { "force",     no_argument,       NULL, 'f'         },
6581                 { "wtmp-only", no_argument,       NULL, 'w'         },
6582                 { "no-wtmp",   no_argument,       NULL, 'd'         },
6583                 { "no-wall",   no_argument,       NULL, ARG_NO_WALL },
6584                 {}
6585         };
6586
6587         int c, r, runlevel;
6588
6589         assert(argc >= 0);
6590         assert(argv);
6591
6592         if (utmp_get_runlevel(&runlevel, NULL) >= 0)
6593                 if (runlevel == '0' || runlevel == '6')
6594                         arg_force = 2;
6595
6596         while ((c = getopt_long(argc, argv, "pfwdnih", options, NULL)) >= 0)
6597                 switch (c) {
6598
6599                 case ARG_HELP:
6600                         halt_help();
6601                         return 0;
6602
6603                 case ARG_HALT:
6604                         arg_action = ACTION_HALT;
6605                         break;
6606
6607                 case 'p':
6608                         if (arg_action != ACTION_REBOOT)
6609                                 arg_action = ACTION_POWEROFF;
6610                         break;
6611
6612                 case ARG_REBOOT:
6613                         arg_action = ACTION_REBOOT;
6614                         break;
6615
6616                 case 'f':
6617                         arg_force = 2;
6618                         break;
6619
6620                 case 'w':
6621                         arg_dry = true;
6622                         break;
6623
6624                 case 'd':
6625                         arg_no_wtmp = true;
6626                         break;
6627
6628                 case ARG_NO_WALL:
6629                         arg_no_wall = true;
6630                         break;
6631
6632                 case 'i':
6633                 case 'h':
6634                 case 'n':
6635                         /* Compatibility nops */
6636                         break;
6637
6638                 case '?':
6639                         return -EINVAL;
6640
6641                 default:
6642                         assert_not_reached("Unhandled option");
6643                 }
6644
6645         if (arg_action == ACTION_REBOOT && (argc == optind || argc == optind + 1)) {
6646                 r = update_reboot_param_file(argc == optind + 1 ? argv[optind] : NULL);
6647                 if (r < 0)
6648                         return r;
6649         } else if (optind < argc) {
6650                 log_error("Too many arguments.");
6651                 return -EINVAL;
6652         }
6653
6654         return 1;
6655 }
6656
6657 static int parse_time_spec(const char *t, usec_t *_u) {
6658         assert(t);
6659         assert(_u);
6660
6661         if (streq(t, "now"))
6662                 *_u = 0;
6663         else if (!strchr(t, ':')) {
6664                 uint64_t u;
6665
6666                 if (safe_atou64(t, &u) < 0)
6667                         return -EINVAL;
6668
6669                 *_u = now(CLOCK_REALTIME) + USEC_PER_MINUTE * u;
6670         } else {
6671                 char *e = NULL;
6672                 long hour, minute;
6673                 struct tm tm = {};
6674                 time_t s;
6675                 usec_t n;
6676
6677                 errno = 0;
6678                 hour = strtol(t, &e, 10);
6679                 if (errno > 0 || *e != ':' || hour < 0 || hour > 23)
6680                         return -EINVAL;
6681
6682                 minute = strtol(e+1, &e, 10);
6683                 if (errno > 0 || *e != 0 || minute < 0 || minute > 59)
6684                         return -EINVAL;
6685
6686                 n = now(CLOCK_REALTIME);
6687                 s = (time_t) (n / USEC_PER_SEC);
6688
6689                 assert_se(localtime_r(&s, &tm));
6690
6691                 tm.tm_hour = (int) hour;
6692                 tm.tm_min = (int) minute;
6693                 tm.tm_sec = 0;
6694
6695                 assert_se(s = mktime(&tm));
6696
6697                 *_u = (usec_t) s * USEC_PER_SEC;
6698
6699                 while (*_u <= n)
6700                         *_u += USEC_PER_DAY;
6701         }
6702
6703         return 0;
6704 }
6705
6706 static int shutdown_parse_argv(int argc, char *argv[]) {
6707
6708         enum {
6709                 ARG_HELP = 0x100,
6710                 ARG_NO_WALL
6711         };
6712
6713         static const struct option options[] = {
6714                 { "help",      no_argument,       NULL, ARG_HELP    },
6715                 { "halt",      no_argument,       NULL, 'H'         },
6716                 { "poweroff",  no_argument,       NULL, 'P'         },
6717                 { "reboot",    no_argument,       NULL, 'r'         },
6718                 { "kexec",     no_argument,       NULL, 'K'         }, /* not documented extension */
6719                 { "no-wall",   no_argument,       NULL, ARG_NO_WALL },
6720                 {}
6721         };
6722
6723         int c, r;
6724
6725         assert(argc >= 0);
6726         assert(argv);
6727
6728         while ((c = getopt_long(argc, argv, "HPrhkKt:afFc", options, NULL)) >= 0)
6729                 switch (c) {
6730
6731                 case ARG_HELP:
6732                         shutdown_help();
6733                         return 0;
6734
6735                 case 'H':
6736                         arg_action = ACTION_HALT;
6737                         break;
6738
6739                 case 'P':
6740                         arg_action = ACTION_POWEROFF;
6741                         break;
6742
6743                 case 'r':
6744                         if (kexec_loaded())
6745                                 arg_action = ACTION_KEXEC;
6746                         else
6747                                 arg_action = ACTION_REBOOT;
6748                         break;
6749
6750                 case 'K':
6751                         arg_action = ACTION_KEXEC;
6752                         break;
6753
6754                 case 'h':
6755                         if (arg_action != ACTION_HALT)
6756                                 arg_action = ACTION_POWEROFF;
6757                         break;
6758
6759                 case 'k':
6760                         arg_dry = true;
6761                         break;
6762
6763                 case ARG_NO_WALL:
6764                         arg_no_wall = true;
6765                         break;
6766
6767                 case 't':
6768                 case 'a':
6769                 case 'f':
6770                 case 'F':
6771                         /* Compatibility nops */
6772                         break;
6773
6774                 case 'c':
6775                         arg_action = ACTION_CANCEL_SHUTDOWN;
6776                         break;
6777
6778                 case '?':
6779                         return -EINVAL;
6780
6781                 default:
6782                         assert_not_reached("Unhandled option");
6783                 }
6784
6785         if (argc > optind && arg_action != ACTION_CANCEL_SHUTDOWN) {
6786                 r = parse_time_spec(argv[optind], &arg_when);
6787                 if (r < 0) {
6788                         log_error("Failed to parse time specification: %s", argv[optind]);
6789                         return r;
6790                 }
6791         } else
6792                 arg_when = now(CLOCK_REALTIME) + USEC_PER_MINUTE;
6793
6794         if (argc > optind && arg_action == ACTION_CANCEL_SHUTDOWN)
6795                 /* No time argument for shutdown cancel */
6796                 arg_wall = argv + optind;
6797         else if (argc > optind + 1)
6798                 /* We skip the time argument */
6799                 arg_wall = argv + optind + 1;
6800
6801         optind = argc;
6802
6803         return 1;
6804 }
6805
6806 static int telinit_parse_argv(int argc, char *argv[]) {
6807
6808         enum {
6809                 ARG_HELP = 0x100,
6810                 ARG_NO_WALL
6811         };
6812
6813         static const struct option options[] = {
6814                 { "help",      no_argument,       NULL, ARG_HELP    },
6815                 { "no-wall",   no_argument,       NULL, ARG_NO_WALL },
6816                 {}
6817         };
6818
6819         static const struct {
6820                 char from;
6821                 enum action to;
6822         } table[] = {
6823                 { '0', ACTION_POWEROFF },
6824                 { '6', ACTION_REBOOT },
6825                 { '1', ACTION_RESCUE },
6826                 { '2', ACTION_RUNLEVEL2 },
6827                 { '3', ACTION_RUNLEVEL3 },
6828                 { '4', ACTION_RUNLEVEL4 },
6829                 { '5', ACTION_RUNLEVEL5 },
6830                 { 's', ACTION_RESCUE },
6831                 { 'S', ACTION_RESCUE },
6832                 { 'q', ACTION_RELOAD },
6833                 { 'Q', ACTION_RELOAD },
6834                 { 'u', ACTION_REEXEC },
6835                 { 'U', ACTION_REEXEC }
6836         };
6837
6838         unsigned i;
6839         int c;
6840
6841         assert(argc >= 0);
6842         assert(argv);
6843
6844         while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0)
6845                 switch (c) {
6846
6847                 case ARG_HELP:
6848                         telinit_help();
6849                         return 0;
6850
6851                 case ARG_NO_WALL:
6852                         arg_no_wall = true;
6853                         break;
6854
6855                 case '?':
6856                         return -EINVAL;
6857
6858                 default:
6859                         assert_not_reached("Unhandled option");
6860                 }
6861
6862         if (optind >= argc) {
6863                 log_error("%s: required argument missing.",
6864                           program_invocation_short_name);
6865                 return -EINVAL;
6866         }
6867
6868         if (optind + 1 < argc) {
6869                 log_error("Too many arguments.");
6870                 return -EINVAL;
6871         }
6872
6873         if (strlen(argv[optind]) != 1) {
6874                 log_error("Expected single character argument.");
6875                 return -EINVAL;
6876         }
6877
6878         for (i = 0; i < ELEMENTSOF(table); i++)
6879                 if (table[i].from == argv[optind][0])
6880                         break;
6881
6882         if (i >= ELEMENTSOF(table)) {
6883                 log_error("Unknown command '%s'.", argv[optind]);
6884                 return -EINVAL;
6885         }
6886
6887         arg_action = table[i].to;
6888
6889         optind ++;
6890
6891         return 1;
6892 }
6893
6894 static int runlevel_parse_argv(int argc, char *argv[]) {
6895
6896         enum {
6897                 ARG_HELP = 0x100,
6898         };
6899
6900         static const struct option options[] = {
6901                 { "help",      no_argument,       NULL, ARG_HELP    },
6902                 {}
6903         };
6904
6905         int c;
6906
6907         assert(argc >= 0);
6908         assert(argv);
6909
6910         while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0)
6911                 switch (c) {
6912
6913                 case ARG_HELP:
6914                         runlevel_help();
6915                         return 0;
6916
6917                 case '?':
6918                         return -EINVAL;
6919
6920                 default:
6921                         assert_not_reached("Unhandled option");
6922                 }
6923
6924         if (optind < argc) {
6925                 log_error("Too many arguments.");
6926                 return -EINVAL;
6927         }
6928
6929         return 1;
6930 }
6931
6932 static int parse_argv(int argc, char *argv[]) {
6933         assert(argc >= 0);
6934         assert(argv);
6935
6936         if (program_invocation_short_name) {
6937
6938                 if (strstr(program_invocation_short_name, "halt")) {
6939                         arg_action = ACTION_HALT;
6940                         return halt_parse_argv(argc, argv);
6941                 } else if (strstr(program_invocation_short_name, "poweroff")) {
6942                         arg_action = ACTION_POWEROFF;
6943                         return halt_parse_argv(argc, argv);
6944                 } else if (strstr(program_invocation_short_name, "reboot")) {
6945                         if (kexec_loaded())
6946                                 arg_action = ACTION_KEXEC;
6947                         else
6948                                 arg_action = ACTION_REBOOT;
6949                         return halt_parse_argv(argc, argv);
6950                 } else if (strstr(program_invocation_short_name, "shutdown")) {
6951                         arg_action = ACTION_POWEROFF;
6952                         return shutdown_parse_argv(argc, argv);
6953                 } else if (strstr(program_invocation_short_name, "init")) {
6954
6955                         if (sd_booted() > 0) {
6956                                 arg_action = _ACTION_INVALID;
6957                                 return telinit_parse_argv(argc, argv);
6958                         } else {
6959                                 /* Hmm, so some other init system is
6960                                  * running, we need to forward this
6961                                  * request to it. For now we simply
6962                                  * guess that it is Upstart. */
6963
6964                                 execv(TELINIT, argv);
6965
6966                                 log_error("Couldn't find an alternative telinit implementation to spawn.");
6967                                 return -EIO;
6968                         }
6969
6970                 } else if (strstr(program_invocation_short_name, "runlevel")) {
6971                         arg_action = ACTION_RUNLEVEL;
6972                         return runlevel_parse_argv(argc, argv);
6973                 }
6974         }
6975
6976         arg_action = ACTION_SYSTEMCTL;
6977         return systemctl_parse_argv(argc, argv);
6978 }
6979
6980 _pure_ static int action_to_runlevel(void) {
6981
6982         static const char table[_ACTION_MAX] = {
6983                 [ACTION_HALT] =      '0',
6984                 [ACTION_POWEROFF] =  '0',
6985                 [ACTION_REBOOT] =    '6',
6986                 [ACTION_RUNLEVEL2] = '2',
6987                 [ACTION_RUNLEVEL3] = '3',
6988                 [ACTION_RUNLEVEL4] = '4',
6989                 [ACTION_RUNLEVEL5] = '5',
6990                 [ACTION_RESCUE] =    '1'
6991         };
6992
6993         assert(arg_action < _ACTION_MAX);
6994
6995         return table[arg_action];
6996 }
6997
6998 static int talk_initctl(void) {
6999
7000         struct init_request request = {
7001                 .magic = INIT_MAGIC,
7002                 .sleeptime  = 0,
7003                 .cmd = INIT_CMD_RUNLVL
7004         };
7005
7006         _cleanup_close_ int fd = -1;
7007         char rl;
7008         int r;
7009
7010         rl = action_to_runlevel();
7011         if (!rl)
7012                 return 0;
7013
7014         request.runlevel = rl;
7015
7016         fd = open(INIT_FIFO, O_WRONLY|O_NDELAY|O_CLOEXEC|O_NOCTTY);
7017         if (fd < 0) {
7018                 if (errno == ENOENT)
7019                         return 0;
7020
7021                 log_error_errno(errno, "Failed to open "INIT_FIFO": %m");
7022                 return -errno;
7023         }
7024
7025         r = loop_write(fd, &request, sizeof(request), false);
7026         if (r < 0)
7027                 return log_error_errno(r, "Failed to write to "INIT_FIFO": %m");
7028
7029         return 1;
7030 }
7031
7032 static int systemctl_main(sd_bus *bus, int argc, char *argv[], int bus_error) {
7033
7034         static const struct {
7035                 const char* verb;
7036                 const enum {
7037                         MORE,
7038                         LESS,
7039                         EQUAL
7040                 } argc_cmp;
7041                 const int argc;
7042                 int (* const dispatch)(sd_bus *bus, char **args);
7043                 const enum {
7044                         NOBUS = 1,
7045                         FORCE,
7046                 } bus;
7047         } verbs[] = {
7048                 { "list-units",            MORE,  0, list_units        },
7049                 { "list-unit-files",       MORE,  1, list_unit_files,  NOBUS },
7050                 { "list-sockets",          MORE,  1, list_sockets      },
7051                 { "list-timers",           MORE,  1, list_timers       },
7052                 { "list-jobs",             MORE,  1, list_jobs         },
7053                 { "list-machines",         MORE,  1, list_machines     },
7054                 { "clear-jobs",            EQUAL, 1, daemon_reload     },
7055                 { "cancel",                MORE,  2, cancel_job        },
7056                 { "start",                 MORE,  2, start_unit        },
7057                 { "stop",                  MORE,  2, start_unit        },
7058                 { "condstop",              MORE,  2, start_unit        }, /* For compatibility with ALTLinux */
7059                 { "reload",                MORE,  2, start_unit        },
7060                 { "restart",               MORE,  2, start_unit        },
7061                 { "try-restart",           MORE,  2, start_unit        },
7062                 { "reload-or-restart",     MORE,  2, start_unit        },
7063                 { "reload-or-try-restart", MORE,  2, start_unit        },
7064                 { "force-reload",          MORE,  2, start_unit        }, /* For compatibility with SysV */
7065                 { "condreload",            MORE,  2, start_unit        }, /* For compatibility with ALTLinux */
7066                 { "condrestart",           MORE,  2, start_unit        }, /* For compatibility with RH */
7067                 { "isolate",               EQUAL, 2, start_unit        },
7068                 { "kill",                  MORE,  2, kill_unit         },
7069                 { "is-active",             MORE,  2, check_unit_active },
7070                 { "check",                 MORE,  2, check_unit_active },
7071                 { "is-failed",             MORE,  2, check_unit_failed },
7072                 { "show",                  MORE,  1, show              },
7073                 { "cat",                   MORE,  2, cat,              NOBUS },
7074                 { "status",                MORE,  1, show              },
7075                 { "help",                  MORE,  2, show              },
7076                 { "snapshot",              LESS,  2, snapshot          },
7077                 { "delete",                MORE,  2, delete_snapshot   },
7078                 { "daemon-reload",         EQUAL, 1, daemon_reload     },
7079                 { "daemon-reexec",         EQUAL, 1, daemon_reload     },
7080                 { "show-environment",      EQUAL, 1, show_environment  },
7081                 { "set-environment",       MORE,  2, set_environment   },
7082                 { "unset-environment",     MORE,  2, set_environment   },
7083                 { "import-environment",    MORE,  1, import_environment},
7084                 { "halt",                  EQUAL, 1, start_special,    FORCE },
7085                 { "poweroff",              EQUAL, 1, start_special,    FORCE },
7086                 { "reboot",                EQUAL, 1, start_special,    FORCE },
7087                 { "kexec",                 EQUAL, 1, start_special     },
7088                 { "suspend",               EQUAL, 1, start_special     },
7089                 { "hibernate",             EQUAL, 1, start_special     },
7090                 { "hybrid-sleep",          EQUAL, 1, start_special     },
7091                 { "default",               EQUAL, 1, start_special     },
7092                 { "rescue",                EQUAL, 1, start_special     },
7093                 { "emergency",             EQUAL, 1, start_special     },
7094                 { "exit",                  EQUAL, 1, start_special     },
7095                 { "reset-failed",          MORE,  1, reset_failed      },
7096                 { "enable",                MORE,  2, enable_unit,      NOBUS },
7097                 { "disable",               MORE,  2, enable_unit,      NOBUS },
7098                 { "is-enabled",            MORE,  2, unit_is_enabled,  NOBUS },
7099                 { "reenable",              MORE,  2, enable_unit,      NOBUS },
7100                 { "preset",                MORE,  2, enable_unit,      NOBUS },
7101                 { "preset-all",            EQUAL, 1, preset_all,       NOBUS },
7102                 { "mask",                  MORE,  2, enable_unit,      NOBUS },
7103                 { "unmask",                MORE,  2, enable_unit,      NOBUS },
7104                 { "link",                  MORE,  2, enable_unit,      NOBUS },
7105                 { "switch-root",           MORE,  2, switch_root       },
7106                 { "list-dependencies",     LESS,  2, list_dependencies },
7107                 { "set-default",           EQUAL, 2, set_default,      NOBUS },
7108                 { "get-default",           EQUAL, 1, get_default,      NOBUS },
7109                 { "set-property",          MORE,  3, set_property      },
7110                 { "is-system-running",     EQUAL, 1, is_system_running },
7111                 { "add-wants",             MORE,  3, add_dependency,   NOBUS },
7112                 { "add-requires",          MORE,  3, add_dependency,   NOBUS },
7113                 { "edit",                  MORE,  2, edit,             NOBUS },
7114                 {}
7115         }, *verb = verbs;
7116
7117         int left;
7118
7119         assert(argc >= 0);
7120         assert(argv);
7121
7122         left = argc - optind;
7123
7124         /* Special rule: no arguments (left == 0) means "list-units" */
7125         if (left > 0) {
7126                 if (streq(argv[optind], "help") && !argv[optind+1]) {
7127                         log_error("This command expects one or more "
7128                                   "unit names. Did you mean --help?");
7129                         return -EINVAL;
7130                 }
7131
7132                 for (; verb->verb; verb++)
7133                         if (streq(argv[optind], verb->verb))
7134                                 goto found;
7135
7136                 log_error("Unknown operation '%s'.", argv[optind]);
7137                 return -EINVAL;
7138         }
7139 found:
7140
7141         switch (verb->argc_cmp) {
7142
7143         case EQUAL:
7144                 if (left != verb->argc) {
7145                         log_error("Invalid number of arguments.");
7146                         return -EINVAL;
7147                 }
7148
7149                 break;
7150
7151         case MORE:
7152                 if (left < verb->argc) {
7153                         log_error("Too few arguments.");
7154                         return -EINVAL;
7155                 }
7156
7157                 break;
7158
7159         case LESS:
7160                 if (left > verb->argc) {
7161                         log_error("Too many arguments.");
7162                         return -EINVAL;
7163                 }
7164
7165                 break;
7166
7167         default:
7168                 assert_not_reached("Unknown comparison operator.");
7169         }
7170
7171         /* Require a bus connection for all operations but
7172          * enable/disable */
7173         if (verb->bus == NOBUS) {
7174                 if (!bus && !avoid_bus()) {
7175                         log_error_errno(bus_error, "Failed to get D-Bus connection: %m");
7176                         return -EIO;
7177                 }
7178
7179         } else {
7180                 if (running_in_chroot() > 0) {
7181                         log_info("Running in chroot, ignoring request.");
7182                         return 0;
7183                 }
7184
7185                 if ((verb->bus != FORCE || arg_force <= 0) && !bus) {
7186                         log_error_errno(bus_error, "Failed to get D-Bus connection: %m");
7187                         return -EIO;
7188                 }
7189         }
7190
7191         return verb->dispatch(bus, argv + optind);
7192 }
7193
7194 static int send_shutdownd(usec_t t, char mode, bool dry_run, bool warn, const char *message) {
7195
7196         struct sd_shutdown_command c = {
7197                 .usec = t,
7198                 .mode = mode,
7199                 .dry_run = dry_run,
7200                 .warn_wall = warn,
7201         };
7202
7203         union sockaddr_union sockaddr = {
7204                 .un.sun_family = AF_UNIX,
7205                 .un.sun_path = "/run/systemd/shutdownd",
7206         };
7207
7208         struct iovec iovec[2] = {{
7209                  .iov_base = (char*) &c,
7210                  .iov_len = offsetof(struct sd_shutdown_command, wall_message),
7211         }};
7212
7213         struct msghdr msghdr = {
7214                 .msg_name = &sockaddr,
7215                 .msg_namelen = offsetof(struct sockaddr_un, sun_path)
7216                                + strlen("/run/systemd/shutdownd"),
7217                 .msg_iov = iovec,
7218                 .msg_iovlen = 1,
7219         };
7220
7221         _cleanup_close_ int fd;
7222
7223         fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
7224         if (fd < 0)
7225                 return -errno;
7226
7227         if (!isempty(message)) {
7228                 iovec[1].iov_base = (char*) message;
7229                 iovec[1].iov_len = strlen(message);
7230                 msghdr.msg_iovlen++;
7231         }
7232
7233         if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) < 0)
7234                 return -errno;
7235
7236         return 0;
7237 }
7238
7239 static int reload_with_fallback(sd_bus *bus) {
7240
7241         if (bus) {
7242                 /* First, try systemd via D-Bus. */
7243                 if (daemon_reload(bus, NULL) >= 0)
7244                         return 0;
7245         }
7246
7247         /* Nothing else worked, so let's try signals */
7248         assert(arg_action == ACTION_RELOAD || arg_action == ACTION_REEXEC);
7249
7250         if (kill(1, arg_action == ACTION_RELOAD ? SIGHUP : SIGTERM) < 0)
7251                 return log_error_errno(errno, "kill() failed: %m");
7252
7253         return 0;
7254 }
7255
7256 static int start_with_fallback(sd_bus *bus) {
7257
7258         if (bus) {
7259                 /* First, try systemd via D-Bus. */
7260                 if (start_unit(bus, NULL) >= 0)
7261                         goto done;
7262         }
7263
7264         /* Nothing else worked, so let's try
7265          * /dev/initctl */
7266         if (talk_initctl() > 0)
7267                 goto done;
7268
7269         log_error("Failed to talk to init daemon.");
7270         return -EIO;
7271
7272 done:
7273         warn_wall(arg_action);
7274         return 0;
7275 }
7276
7277 static int halt_now(enum action a) {
7278
7279         /* The kernel will automaticall flush ATA disks and suchlike
7280          * on reboot(), but the file systems need to be synce'd
7281          * explicitly in advance. */
7282         sync();
7283
7284         /* Make sure C-A-D is handled by the kernel from this point
7285          * on... */
7286         reboot(RB_ENABLE_CAD);
7287
7288         switch (a) {
7289
7290         case ACTION_HALT:
7291                 log_info("Halting.");
7292                 reboot(RB_HALT_SYSTEM);
7293                 return -errno;
7294
7295         case ACTION_POWEROFF:
7296                 log_info("Powering off.");
7297                 reboot(RB_POWER_OFF);
7298                 return -errno;
7299
7300         case ACTION_REBOOT: {
7301                 _cleanup_free_ char *param = NULL;
7302
7303                 if (read_one_line_file(REBOOT_PARAM_FILE, &param) >= 0) {
7304                         log_info("Rebooting with argument '%s'.", param);
7305                         syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
7306                                 LINUX_REBOOT_CMD_RESTART2, param);
7307                 }
7308
7309                 log_info("Rebooting.");
7310                 reboot(RB_AUTOBOOT);
7311                 return -errno;
7312         }
7313
7314         default:
7315                 assert_not_reached("Unknown action.");
7316         }
7317 }
7318
7319 static int halt_main(sd_bus *bus) {
7320         int r;
7321
7322         r = check_inhibitors(bus, arg_action);
7323         if (r < 0)
7324                 return r;
7325
7326         if (geteuid() != 0) {
7327                 /* Try logind if we are a normal user and no special
7328                  * mode applies. Maybe PolicyKit allows us to shutdown
7329                  * the machine. */
7330
7331                 if (arg_when <= 0 &&
7332                     !arg_dry &&
7333                     arg_force <= 0 &&
7334                     (arg_action == ACTION_POWEROFF ||
7335                      arg_action == ACTION_REBOOT)) {
7336                         r = reboot_with_logind(bus, arg_action);
7337                         if (r >= 0)
7338                                 return r;
7339                 }
7340
7341                 log_error("Must be root.");
7342                 return -EPERM;
7343         }
7344
7345         if (arg_when > 0) {
7346                 _cleanup_free_ char *m;
7347
7348                 m = strv_join(arg_wall, " ");
7349                 if (!m)
7350                         return log_oom();
7351
7352                 r = send_shutdownd(arg_when,
7353                                    arg_action == ACTION_HALT     ? 'H' :
7354                                    arg_action == ACTION_POWEROFF ? 'P' :
7355                                    arg_action == ACTION_KEXEC    ? 'K' :
7356                                                                    'r',
7357                                    arg_dry,
7358                                    !arg_no_wall,
7359                                    m);
7360
7361                 if (r < 0)
7362                         log_warning_errno(r, "Failed to talk to shutdownd, proceeding with immediate shutdown: %m");
7363                 else {
7364                         char date[FORMAT_TIMESTAMP_MAX];
7365
7366                         log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.",
7367                                  format_timestamp(date, sizeof(date), arg_when));
7368                         return 0;
7369                 }
7370         }
7371
7372         if (!arg_dry && !arg_force)
7373                 return start_with_fallback(bus);
7374
7375         if (!arg_no_wtmp) {
7376                 if (sd_booted() > 0)
7377                         log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
7378                 else {
7379                         r = utmp_put_shutdown();
7380                         if (r < 0)
7381                                 log_warning_errno(r, "Failed to write utmp record: %m");
7382                 }
7383         }
7384
7385         if (arg_dry)
7386                 return 0;
7387
7388         r = halt_now(arg_action);
7389         log_error_errno(r, "Failed to reboot: %m");
7390
7391         return r;
7392 }
7393
7394 static int runlevel_main(void) {
7395         int r, runlevel, previous;
7396
7397         r = utmp_get_runlevel(&runlevel, &previous);
7398         if (r < 0) {
7399                 puts("unknown");
7400                 return r;
7401         }
7402
7403         printf("%c %c\n",
7404                previous <= 0 ? 'N' : previous,
7405                runlevel <= 0 ? 'N' : runlevel);
7406
7407         return 0;
7408 }
7409
7410 int main(int argc, char*argv[]) {
7411         _cleanup_bus_close_unref_ sd_bus *bus = NULL;
7412         int r;
7413
7414         setlocale(LC_ALL, "");
7415         log_parse_environment();
7416         log_open();
7417
7418         /* Explicitly not on_tty() to avoid setting cached value.
7419          * This becomes relevant for piping output which might be
7420          * ellipsized. */
7421         original_stdout_is_tty = isatty(STDOUT_FILENO);
7422
7423         r = parse_argv(argc, argv);
7424         if (r <= 0)
7425                 goto finish;
7426
7427         /* /sbin/runlevel doesn't need to communicate via D-Bus, so
7428          * let's shortcut this */
7429         if (arg_action == ACTION_RUNLEVEL) {
7430                 r = runlevel_main();
7431                 goto finish;
7432         }
7433
7434         if (running_in_chroot() > 0 && arg_action != ACTION_SYSTEMCTL) {
7435                 log_info("Running in chroot, ignoring request.");
7436                 r = 0;
7437                 goto finish;
7438         }
7439
7440         if (!avoid_bus())
7441                 r = bus_open_transport_systemd(arg_transport, arg_host, arg_scope != UNIT_FILE_SYSTEM, &bus);
7442
7443         /* systemctl_main() will print an error message for the bus
7444          * connection, but only if it needs to */
7445
7446         switch (arg_action) {
7447
7448         case ACTION_SYSTEMCTL:
7449                 r = systemctl_main(bus, argc, argv, r);
7450                 break;
7451
7452         case ACTION_HALT:
7453         case ACTION_POWEROFF:
7454         case ACTION_REBOOT:
7455         case ACTION_KEXEC:
7456                 r = halt_main(bus);
7457                 break;
7458
7459         case ACTION_RUNLEVEL2:
7460         case ACTION_RUNLEVEL3:
7461         case ACTION_RUNLEVEL4:
7462         case ACTION_RUNLEVEL5:
7463         case ACTION_RESCUE:
7464         case ACTION_EMERGENCY:
7465         case ACTION_DEFAULT:
7466                 r = start_with_fallback(bus);
7467                 break;
7468
7469         case ACTION_RELOAD:
7470         case ACTION_REEXEC:
7471                 r = reload_with_fallback(bus);
7472                 break;
7473
7474         case ACTION_CANCEL_SHUTDOWN: {
7475                 _cleanup_free_ char *m = NULL;
7476
7477                 if (arg_wall) {
7478                         m = strv_join(arg_wall, " ");
7479                         if (!m) {
7480                                 r = log_oom();
7481                                 goto finish;
7482                         }
7483                 }
7484
7485                 r = send_shutdownd(arg_when, SD_SHUTDOWN_NONE, false, !arg_no_wall, m);
7486                 if (r < 0)
7487                         log_warning_errno(r, "Failed to talk to shutdownd, shutdown hasn't been cancelled: %m");
7488                 break;
7489         }
7490
7491         case ACTION_RUNLEVEL:
7492         case _ACTION_INVALID:
7493         default:
7494                 assert_not_reached("Unknown action");
7495         }
7496
7497 finish:
7498         pager_close();
7499         ask_password_agent_close();
7500         polkit_agent_close();
7501
7502         strv_free(arg_types);
7503         strv_free(arg_states);
7504         strv_free(arg_properties);
7505
7506         return r < 0 ? EXIT_FAILURE : r;
7507 }