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