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