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