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