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