chiark / gitweb /
41f7b9f7aad1ba08e6bb127b11770e45966b703a
[elogind.git] / src / systemctl / systemctl.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright 2010 Lennart Poettering
7   Copyright 2013 Marc-Antoine Perennou
8
9   systemd is free software; you can redistribute it and/or modify it
10   under the terms of the GNU Lesser General Public License as published by
11   the Free Software Foundation; either version 2.1 of the License, or
12   (at your option) any later version.
13
14   systemd is distributed in the hope that it will be useful, but
15   WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17   Lesser General Public License for more details.
18
19   You should have received a copy of the GNU Lesser General Public License
20   along with systemd; If not, see <http://www.gnu.org/licenses/>.
21 ***/
22
23 #include <sys/reboot.h>
24 #include <linux/reboot.h>
25 #include <stdio.h>
26 #include <getopt.h>
27 #include <locale.h>
28 #include <stdbool.h>
29 #include <string.h>
30 #include <errno.h>
31 #include <unistd.h>
32 #include <fcntl.h>
33 #include <sys/socket.h>
34 #include <stddef.h>
35
36 #include "sd-daemon.h"
37 #include "sd-shutdown.h"
38 #include "sd-login.h"
39 #include "sd-bus.h"
40 #include "log.h"
41 #include "util.h"
42 #include "macro.h"
43 #include "set.h"
44 #include "utmp-wtmp.h"
45 #include "special.h"
46 #include "initreq.h"
47 #include "path-util.h"
48 #include "strv.h"
49 #include "cgroup-show.h"
50 #include "cgroup-util.h"
51 #include "list.h"
52 #include "path-lookup.h"
53 #include "exit-status.h"
54 #include "build.h"
55 #include "unit-name.h"
56 #include "pager.h"
57 #include "spawn-ask-password-agent.h"
58 #include "spawn-polkit-agent.h"
59 #include "install.h"
60 #include "logs-show.h"
61 #include "socket-util.h"
62 #include "fileio.h"
63 #include "copy.h"
64 #include "env-util.h"
65 #include "bus-util.h"
66 #include "bus-message.h"
67 #include "bus-error.h"
68 #include "bus-common-errors.h"
69 #include "mkdir.h"
70 #include "dropin.h"
71
72 static char **arg_types = NULL;
73 static char **arg_states = NULL;
74 static char **arg_properties = NULL;
75 static bool arg_all = false;
76 static enum dependency {
77         DEPENDENCY_FORWARD,
78         DEPENDENCY_REVERSE,
79         DEPENDENCY_AFTER,
80         DEPENDENCY_BEFORE,
81         _DEPENDENCY_MAX
82 } arg_dependency = DEPENDENCY_FORWARD;
83 static const char *arg_job_mode = "replace";
84 static UnitFileScope arg_scope = UNIT_FILE_SYSTEM;
85 static bool arg_no_block = false;
86 static bool arg_no_legend = false;
87 static bool arg_no_pager = false;
88 static bool arg_no_wtmp = false;
89 static bool arg_no_wall = false;
90 static bool arg_no_reload = false;
91 static bool arg_show_types = false;
92 static bool arg_ignore_inhibitors = false;
93 static bool arg_dry = false;
94 static bool arg_quiet = false;
95 static bool arg_full = false;
96 static bool arg_recursive = false;
97 static int arg_force = 0;
98 static bool arg_ask_password = true;
99 static bool arg_runtime = false;
100 static UnitFilePresetMode arg_preset_mode = UNIT_FILE_PRESET_FULL;
101 static char **arg_wall = NULL;
102 static const char *arg_kill_who = NULL;
103 static int arg_signal = SIGTERM;
104 static const char *arg_root = NULL;
105 static usec_t arg_when = 0;
106 static enum action {
107         _ACTION_INVALID,
108         ACTION_SYSTEMCTL,
109         ACTION_HALT,
110         ACTION_POWEROFF,
111         ACTION_REBOOT,
112         ACTION_KEXEC,
113         ACTION_EXIT,
114         ACTION_SUSPEND,
115         ACTION_HIBERNATE,
116         ACTION_HYBRID_SLEEP,
117         ACTION_RUNLEVEL2,
118         ACTION_RUNLEVEL3,
119         ACTION_RUNLEVEL4,
120         ACTION_RUNLEVEL5,
121         ACTION_RESCUE,
122         ACTION_EMERGENCY,
123         ACTION_DEFAULT,
124         ACTION_RELOAD,
125         ACTION_REEXEC,
126         ACTION_RUNLEVEL,
127         ACTION_CANCEL_SHUTDOWN,
128         _ACTION_MAX
129 } arg_action = ACTION_SYSTEMCTL;
130 static BusTransport arg_transport = BUS_TRANSPORT_LOCAL;
131 static char *arg_host = NULL;
132 static unsigned arg_lines = 10;
133 static OutputMode arg_output = OUTPUT_SHORT;
134 static bool arg_plain = false;
135
136 static bool original_stdout_is_tty;
137
138 static int daemon_reload(sd_bus *bus, char **args);
139 static int halt_now(enum action a);
140 static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet);
141
142 static char** strv_skip_first(char **strv) {
143         if (strv_length(strv) > 0)
144                 return strv + 1;
145         return NULL;
146 }
147
148 static void pager_open_if_enabled(void) {
149
150         if (arg_no_pager)
151                 return;
152
153         pager_open(false);
154 }
155
156 static void ask_password_agent_open_if_enabled(void) {
157
158         /* Open the password agent as a child process if necessary */
159
160         if (!arg_ask_password)
161                 return;
162
163         if (arg_scope != UNIT_FILE_SYSTEM)
164                 return;
165
166         if (arg_transport != BUS_TRANSPORT_LOCAL)
167                 return;
168
169         ask_password_agent_open();
170 }
171
172 static void polkit_agent_open_if_enabled(void) {
173
174         /* Open the polkit agent as a child process if necessary */
175
176         if (!arg_ask_password)
177                 return;
178
179         if (arg_scope != UNIT_FILE_SYSTEM)
180                 return;
181
182         if (arg_transport != BUS_TRANSPORT_LOCAL)
183                 return;
184
185         polkit_agent_open();
186 }
187
188 static OutputFlags get_output_flags(void) {
189         return
190                 arg_all * OUTPUT_SHOW_ALL |
191                 arg_full * OUTPUT_FULL_WIDTH |
192                 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
193                 on_tty() * OUTPUT_COLOR |
194                 !arg_quiet * OUTPUT_WARN_CUTOFF;
195 }
196
197 static int translate_bus_error_to_exit_status(int r, const sd_bus_error *error) {
198         assert(error);
199
200         if (!sd_bus_error_is_set(error))
201                 return r;
202
203         if (sd_bus_error_has_name(error, SD_BUS_ERROR_ACCESS_DENIED) ||
204             sd_bus_error_has_name(error, BUS_ERROR_ONLY_BY_DEPENDENCY) ||
205             sd_bus_error_has_name(error, BUS_ERROR_NO_ISOLATION) ||
206             sd_bus_error_has_name(error, BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE))
207                 return EXIT_NOPERMISSION;
208
209         if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT))
210                 return EXIT_NOTINSTALLED;
211
212         if (sd_bus_error_has_name(error, BUS_ERROR_JOB_TYPE_NOT_APPLICABLE) ||
213             sd_bus_error_has_name(error, SD_BUS_ERROR_NOT_SUPPORTED))
214                 return EXIT_NOTIMPLEMENTED;
215
216         if (sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED))
217                 return EXIT_NOTCONFIGURED;
218
219         if (r != 0)
220                 return r;
221
222         return EXIT_FAILURE;
223 }
224
225 static void warn_wall(enum action a) {
226         static const char *table[_ACTION_MAX] = {
227                 [ACTION_HALT]            = "The system is going down for system halt NOW!",
228                 [ACTION_REBOOT]          = "The system is going down for reboot NOW!",
229                 [ACTION_POWEROFF]        = "The system is going down for power-off NOW!",
230                 [ACTION_KEXEC]           = "The system is going down for kexec reboot NOW!",
231                 [ACTION_RESCUE]          = "The system is going down to rescue mode NOW!",
232                 [ACTION_EMERGENCY]       = "The system is going down to emergency mode NOW!",
233                 [ACTION_CANCEL_SHUTDOWN] = "The system shutdown has been cancelled NOW!"
234         };
235
236         if (arg_no_wall)
237                 return;
238
239         if (arg_wall) {
240                 _cleanup_free_ char *p;
241
242                 p = strv_join(arg_wall, " ");
243                 if (!p) {
244                         log_oom();
245                         return;
246                 }
247
248                 if (*p) {
249                         utmp_wall(p, NULL, NULL);
250                         return;
251                 }
252         }
253
254         if (!table[a])
255                 return;
256
257         utmp_wall(table[a], NULL, NULL);
258 }
259
260 static bool avoid_bus(void) {
261
262         if (running_in_chroot() > 0)
263                 return true;
264
265         if (sd_booted() <= 0)
266                 return true;
267
268         if (!isempty(arg_root))
269                 return true;
270
271         if (arg_scope == UNIT_FILE_GLOBAL)
272                 return true;
273
274         return false;
275 }
276
277 static int compare_unit_info(const void *a, const void *b) {
278         const UnitInfo *u = a, *v = b;
279         const char *d1, *d2;
280         int r;
281
282         /* First, order by machine */
283         if (!u->machine && v->machine)
284                 return -1;
285         if (u->machine && !v->machine)
286                 return 1;
287         if (u->machine && v->machine) {
288                 r = strcasecmp(u->machine, v->machine);
289                 if (r != 0)
290                         return r;
291         }
292
293         /* Second, order by unit type */
294         d1 = strrchr(u->id, '.');
295         d2 = strrchr(v->id, '.');
296         if (d1 && d2) {
297                 r = strcasecmp(d1, d2);
298                 if (r != 0)
299                         return r;
300         }
301
302         /* Third, order by name */
303         return strcasecmp(u->id, v->id);
304 }
305
306 static bool output_show_unit(const UnitInfo *u, char **patterns) {
307         if (!strv_fnmatch_or_empty(patterns, u->id, FNM_NOESCAPE))
308                 return false;
309
310         if (arg_types) {
311                 const char *dot;
312
313                 dot = strrchr(u->id, '.');
314                 if (!dot)
315                         return false;
316
317                 if (!strv_find(arg_types, dot+1))
318                         return false;
319         }
320
321         if (arg_all)
322                 return true;
323
324         if (u->job_id > 0)
325                 return true;
326
327         if (streq(u->active_state, "inactive") || u->following[0])
328                 return false;
329
330         return true;
331 }
332
333 static int output_units_list(const UnitInfo *unit_infos, unsigned c) {
334         unsigned circle_len = 0, id_len, max_id_len, load_len, active_len, sub_len, job_len, desc_len;
335         const UnitInfo *u;
336         unsigned n_shown = 0;
337         int job_count = 0;
338
339         max_id_len = strlen("UNIT");
340         load_len = strlen("LOAD");
341         active_len = strlen("ACTIVE");
342         sub_len = strlen("SUB");
343         job_len = strlen("JOB");
344         desc_len = 0;
345
346         for (u = unit_infos; u < unit_infos + c; u++) {
347                 max_id_len = MAX(max_id_len, strlen(u->id) + (u->machine ? strlen(u->machine)+1 : 0));
348                 load_len = MAX(load_len, strlen(u->load_state));
349                 active_len = MAX(active_len, strlen(u->active_state));
350                 sub_len = MAX(sub_len, strlen(u->sub_state));
351
352                 if (u->job_id != 0) {
353                         job_len = MAX(job_len, strlen(u->job_type));
354                         job_count++;
355                 }
356
357                 if (!arg_no_legend &&
358                     (streq(u->active_state, "failed") ||
359                      STR_IN_SET(u->load_state, "error", "not-found", "masked")))
360                         circle_len = 2;
361         }
362
363         if (!arg_full && original_stdout_is_tty) {
364                 unsigned basic_len;
365
366                 id_len = MIN(max_id_len, 25u);
367                 basic_len = circle_len + 5 + id_len + 5 + active_len + sub_len;
368
369                 if (job_count)
370                         basic_len += job_len + 1;
371
372                 if (basic_len < (unsigned) columns()) {
373                         unsigned extra_len, incr;
374                         extra_len = columns() - basic_len;
375
376                         /* Either UNIT already got 25, or is fully satisfied.
377                          * Grant up to 25 to DESC now. */
378                         incr = MIN(extra_len, 25u);
379                         desc_len += incr;
380                         extra_len -= incr;
381
382                         /* split the remaining space between UNIT and DESC,
383                          * but do not give UNIT more than it needs. */
384                         if (extra_len > 0) {
385                                 incr = MIN(extra_len / 2, max_id_len - id_len);
386                                 id_len += incr;
387                                 desc_len += extra_len - incr;
388                         }
389                 }
390         } else
391                 id_len = max_id_len;
392
393         for (u = unit_infos; u < unit_infos + c; u++) {
394                 _cleanup_free_ char *e = NULL, *j = NULL;
395                 const char *on_loaded = "", *off_loaded = "";
396                 const char *on_active = "", *off_active = "";
397                 const char *on_circle = "", *off_circle = "";
398                 const char *id;
399                 bool circle = false;
400
401                 if (!n_shown && !arg_no_legend) {
402
403                         if (circle_len > 0)
404                                 fputs("  ", stdout);
405
406                         printf("%-*s %-*s %-*s %-*s ",
407                                id_len, "UNIT",
408                                load_len, "LOAD",
409                                active_len, "ACTIVE",
410                                sub_len, "SUB");
411
412                         if (job_count)
413                                 printf("%-*s ", job_len, "JOB");
414
415                         if (!arg_full && arg_no_pager)
416                                 printf("%.*s\n", desc_len, "DESCRIPTION");
417                         else
418                                 printf("%s\n", "DESCRIPTION");
419                 }
420
421                 n_shown++;
422
423                 if (STR_IN_SET(u->load_state, "error", "not-found", "masked") && !arg_plain) {
424                         on_loaded = ansi_highlight_red();
425                         on_circle = ansi_highlight_yellow();
426                         off_loaded = off_circle = ansi_highlight_off();
427                         circle = true;
428                 } else if (streq(u->active_state, "failed") && !arg_plain) {
429                         on_circle = on_active = ansi_highlight_red();
430                         off_circle = off_active = ansi_highlight_off();
431                         circle = true;
432                 }
433
434                 if (u->machine) {
435                         j = strjoin(u->machine, ":", u->id, NULL);
436                         if (!j)
437                                 return log_oom();
438
439                         id = j;
440                 } else
441                         id = u->id;
442
443                 if (arg_full) {
444                         e = ellipsize(id, id_len, 33);
445                         if (!e)
446                                 return log_oom();
447
448                         id = e;
449                 }
450
451                 if (circle_len > 0)
452                         printf("%s%s%s ", on_circle, circle ? draw_special_char(DRAW_BLACK_CIRCLE) : " ", off_circle);
453
454                 printf("%s%-*s%s %s%-*s%s %s%-*s %-*s%s %-*s",
455                        on_active, id_len, id, off_active,
456                        on_loaded, load_len, u->load_state, off_loaded,
457                        on_active, active_len, u->active_state,
458                        sub_len, u->sub_state, off_active,
459                        job_count ? job_len + 1 : 0, u->job_id ? u->job_type : "");
460
461                 if (desc_len > 0)
462                         printf("%.*s\n", desc_len, u->description);
463                 else
464                         printf("%s\n", u->description);
465         }
466
467         if (!arg_no_legend) {
468                 const char *on, *off;
469
470                 if (n_shown) {
471                         puts("\n"
472                              "LOAD   = Reflects whether the unit definition was properly loaded.\n"
473                              "ACTIVE = The high-level unit activation state, i.e. generalization of SUB.\n"
474                              "SUB    = The low-level unit activation state, values depend on unit type.");
475                         puts(job_count ? "JOB    = Pending job for the unit.\n" : "");
476                         on = ansi_highlight();
477                         off = ansi_highlight_off();
478                 } else {
479                         on = ansi_highlight_red();
480                         off = ansi_highlight_off();
481                 }
482
483                 if (arg_all)
484                         printf("%s%u loaded units listed.%s\n"
485                                "To show all installed unit files use 'systemctl list-unit-files'.\n",
486                                on, n_shown, off);
487                 else
488                         printf("%s%u loaded units listed.%s Pass --all to see loaded but inactive units, too.\n"
489                                "To show all installed unit files use 'systemctl list-unit-files'.\n",
490                                on, n_shown, off);
491         }
492
493         return 0;
494 }
495
496 static int get_unit_list(
497                 sd_bus *bus,
498                 const char *machine,
499                 char **patterns,
500                 UnitInfo **unit_infos,
501                 int c,
502                 sd_bus_message **_reply) {
503
504         _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
505         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
506         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
507         size_t size = c;
508         int r;
509         UnitInfo u;
510
511         assert(bus);
512         assert(unit_infos);
513         assert(_reply);
514
515         r = sd_bus_message_new_method_call(
516                         bus,
517                         &m,
518                         "org.freedesktop.systemd1",
519                         "/org/freedesktop/systemd1",
520                         "org.freedesktop.systemd1.Manager",
521                         "ListUnitsFiltered");
522
523         if (r < 0)
524                 return bus_log_create_error(r);
525
526         r = sd_bus_message_append_strv(m, arg_states);
527         if (r < 0)
528                 return bus_log_create_error(r);
529
530         r = sd_bus_call(bus, m, 0, &error, &reply);
531         if (r < 0) {
532                 log_error("Failed to list units: %s", bus_error_message(&error, r));
533                 return r;
534         }
535
536         r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssssouso)");
537         if (r < 0)
538                 return bus_log_parse_error(r);
539
540         while ((r = bus_parse_unit_info(reply, &u)) > 0) {
541                 u.machine = machine;
542
543                 if (!output_show_unit(&u, patterns))
544                         continue;
545
546                 if (!GREEDY_REALLOC(*unit_infos, size, c+1))
547                         return log_oom();
548
549                 (*unit_infos)[c++] = u;
550         }
551         if (r < 0)
552                 return bus_log_parse_error(r);
553
554         r = sd_bus_message_exit_container(reply);
555         if (r < 0)
556                 return bus_log_parse_error(r);
557
558         *_reply = reply;
559         reply = NULL;
560
561         return c;
562 }
563
564 static void message_set_freep(Set **set) {
565         sd_bus_message *m;
566
567         while ((m = set_steal_first(*set)))
568                 sd_bus_message_unref(m);
569
570         set_free(*set);
571 }
572
573 static int get_unit_list_recursive(
574                 sd_bus *bus,
575                 char **patterns,
576                 UnitInfo **_unit_infos,
577                 Set **_replies,
578                 char ***_machines) {
579
580         _cleanup_free_ UnitInfo *unit_infos = NULL;
581         _cleanup_(message_set_freep) Set *replies;
582         sd_bus_message *reply;
583         int c, r;
584
585         assert(bus);
586         assert(_replies);
587         assert(_unit_infos);
588         assert(_machines);
589
590         replies = set_new(NULL);
591         if (!replies)
592                 return log_oom();
593
594         c = get_unit_list(bus, NULL, patterns, &unit_infos, 0, &reply);
595         if (c < 0)
596                 return c;
597
598         r = set_put(replies, reply);
599         if (r < 0) {
600                 sd_bus_message_unref(reply);
601                 return r;
602         }
603
604         if (arg_recursive) {
605                 _cleanup_strv_free_ char **machines = NULL;
606                 char **i;
607
608                 r = sd_get_machine_names(&machines);
609                 if (r < 0)
610                         return r;
611
612                 STRV_FOREACH(i, machines) {
613                         _cleanup_bus_close_unref_ sd_bus *container = NULL;
614                         int k;
615
616                         r = sd_bus_open_system_machine(&container, *i);
617                         if (r < 0) {
618                                 log_error_errno(r, "Failed to connect to container %s: %m", *i);
619                                 continue;
620                         }
621
622                         k = get_unit_list(container, *i, patterns, &unit_infos, c, &reply);
623                         if (k < 0)
624                                 return k;
625
626                         c = k;
627
628                         r = set_put(replies, reply);
629                         if (r < 0) {
630                                 sd_bus_message_unref(reply);
631                                 return r;
632                         }
633                 }
634
635                 *_machines = machines;
636                 machines = NULL;
637         } else
638                 *_machines = NULL;
639
640         *_unit_infos = unit_infos;
641         unit_infos = NULL;
642
643         *_replies = replies;
644         replies = NULL;
645
646         return c;
647 }
648
649 static int list_units(sd_bus *bus, char **args) {
650         _cleanup_free_ UnitInfo *unit_infos = NULL;
651         _cleanup_(message_set_freep) Set *replies = NULL;
652         _cleanup_strv_free_ char **machines = NULL;
653         int r;
654
655         pager_open_if_enabled();
656
657         r = get_unit_list_recursive(bus, strv_skip_first(args), &unit_infos, &replies, &machines);
658         if (r < 0)
659                 return r;
660
661         qsort_safe(unit_infos, r, sizeof(UnitInfo), compare_unit_info);
662         return output_units_list(unit_infos, r);
663 }
664
665 static int get_triggered_units(
666                 sd_bus *bus,
667                 const char* path,
668                 char*** ret) {
669
670         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
671         int r;
672
673         r = sd_bus_get_property_strv(
674                         bus,
675                         "org.freedesktop.systemd1",
676                         path,
677                         "org.freedesktop.systemd1.Unit",
678                         "Triggers",
679                         &error,
680                         ret);
681
682         if (r < 0)
683                 log_error("Failed to determine triggers: %s", bus_error_message(&error, r));
684
685         return 0;
686 }
687
688 static int get_listening(
689                 sd_bus *bus,
690                 const char* unit_path,
691                 char*** listening) {
692
693         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
694         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
695         const char *type, *path;
696         int r, n = 0;
697
698         r = sd_bus_get_property(
699                         bus,
700                         "org.freedesktop.systemd1",
701                         unit_path,
702                         "org.freedesktop.systemd1.Socket",
703                         "Listen",
704                         &error,
705                         &reply,
706                         "a(ss)");
707         if (r < 0) {
708                 log_error("Failed to get list of listening sockets: %s", bus_error_message(&error, r));
709                 return r;
710         }
711
712         r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ss)");
713         if (r < 0)
714                 return bus_log_parse_error(r);
715
716         while ((r = sd_bus_message_read(reply, "(ss)", &type, &path)) > 0) {
717
718                 r = strv_extend(listening, type);
719                 if (r < 0)
720                         return log_oom();
721
722                 r = strv_extend(listening, path);
723                 if (r < 0)
724                         return log_oom();
725
726                 n++;
727         }
728         if (r < 0)
729                 return bus_log_parse_error(r);
730
731         r = sd_bus_message_exit_container(reply);
732         if (r < 0)
733                 return bus_log_parse_error(r);
734
735         return n;
736 }
737
738 struct socket_info {
739         const char *machine;
740         const char* id;
741
742         char* type;
743         char* path;
744
745         /* Note: triggered is a list here, although it almost certainly
746          * will always be one unit. Nevertheless, dbus API allows for multiple
747          * values, so let's follow that. */
748         char** triggered;
749
750         /* The strv above is shared. free is set only in the first one. */
751         bool own_triggered;
752 };
753
754 static int socket_info_compare(const struct socket_info *a, const struct socket_info *b) {
755         int o;
756
757         assert(a);
758         assert(b);
759
760         if (!a->machine && b->machine)
761                 return -1;
762         if (a->machine && !b->machine)
763                 return 1;
764         if (a->machine && b->machine) {
765                 o = strcasecmp(a->machine, b->machine);
766                 if (o != 0)
767                         return o;
768         }
769
770         o = strcmp(a->path, b->path);
771         if (o == 0)
772                 o = strcmp(a->type, b->type);
773
774         return o;
775 }
776
777 static int output_sockets_list(struct socket_info *socket_infos, unsigned cs) {
778         struct socket_info *s;
779         unsigned pathlen = strlen("LISTEN"),
780                 typelen = strlen("TYPE") * arg_show_types,
781                 socklen = strlen("UNIT"),
782                 servlen = strlen("ACTIVATES");
783         const char *on, *off;
784
785         for (s = socket_infos; s < socket_infos + cs; s++) {
786                 unsigned tmp = 0;
787                 char **a;
788
789                 socklen = MAX(socklen, strlen(s->id));
790                 if (arg_show_types)
791                         typelen = MAX(typelen, strlen(s->type));
792                 pathlen = MAX(pathlen, strlen(s->path) + (s->machine ? strlen(s->machine)+1 : 0));
793
794                 STRV_FOREACH(a, s->triggered)
795                         tmp += strlen(*a) + 2*(a != s->triggered);
796                 servlen = MAX(servlen, tmp);
797         }
798
799         if (cs) {
800                 if (!arg_no_legend)
801                         printf("%-*s %-*.*s%-*s %s\n",
802                                pathlen, "LISTEN",
803                                typelen + arg_show_types, typelen + arg_show_types, "TYPE ",
804                                socklen, "UNIT",
805                                "ACTIVATES");
806
807                 for (s = socket_infos; s < socket_infos + cs; s++) {
808                         _cleanup_free_ char *j = NULL;
809                         const char *path;
810                         char **a;
811
812                         if (s->machine) {
813                                 j = strjoin(s->machine, ":", s->path, NULL);
814                                 if (!j)
815                                         return log_oom();
816                                 path = j;
817                         } else
818                                 path = s->path;
819
820                         if (arg_show_types)
821                                 printf("%-*s %-*s %-*s",
822                                        pathlen, path, typelen, s->type, socklen, s->id);
823                         else
824                                 printf("%-*s %-*s",
825                                        pathlen, path, socklen, s->id);
826                         STRV_FOREACH(a, s->triggered)
827                                 printf("%s %s",
828                                        a == s->triggered ? "" : ",", *a);
829                         printf("\n");
830                 }
831
832                 on = ansi_highlight();
833                 off = ansi_highlight_off();
834                 if (!arg_no_legend)
835                         printf("\n");
836         } else {
837                 on = ansi_highlight_red();
838                 off = ansi_highlight_off();
839         }
840
841         if (!arg_no_legend) {
842                 printf("%s%u sockets listed.%s\n", on, cs, off);
843                 if (!arg_all)
844                         printf("Pass --all to see loaded but inactive sockets, too.\n");
845         }
846
847         return 0;
848 }
849
850 static int list_sockets(sd_bus *bus, char **args) {
851         _cleanup_(message_set_freep) Set *replies = NULL;
852         _cleanup_strv_free_ char **machines = NULL;
853         _cleanup_free_ UnitInfo *unit_infos = NULL;
854         _cleanup_free_ struct socket_info *socket_infos = NULL;
855         const UnitInfo *u;
856         struct socket_info *s;
857         unsigned cs = 0;
858         size_t size = 0;
859         int r = 0, n;
860
861         pager_open_if_enabled();
862
863         n = get_unit_list_recursive(bus, strv_skip_first(args), &unit_infos, &replies, &machines);
864         if (n < 0)
865                 return n;
866
867         for (u = unit_infos; u < unit_infos + n; u++) {
868                 _cleanup_strv_free_ char **listening = NULL, **triggered = NULL;
869                 int i, c;
870
871                 if (!endswith(u->id, ".socket"))
872                         continue;
873
874                 r = get_triggered_units(bus, u->unit_path, &triggered);
875                 if (r < 0)
876                         goto cleanup;
877
878                 c = get_listening(bus, u->unit_path, &listening);
879                 if (c < 0) {
880                         r = c;
881                         goto cleanup;
882                 }
883
884                 if (!GREEDY_REALLOC(socket_infos, size, cs + c)) {
885                         r = log_oom();
886                         goto cleanup;
887                 }
888
889                 for (i = 0; i < c; i++)
890                         socket_infos[cs + i] = (struct socket_info) {
891                                 .machine = u->machine,
892                                 .id = u->id,
893                                 .type = listening[i*2],
894                                 .path = listening[i*2 + 1],
895                                 .triggered = triggered,
896                                 .own_triggered = i==0,
897                         };
898
899                 /* from this point on we will cleanup those socket_infos */
900                 cs += c;
901                 free(listening);
902                 listening = triggered = NULL; /* avoid cleanup */
903         }
904
905         qsort_safe(socket_infos, cs, sizeof(struct socket_info),
906                    (__compar_fn_t) socket_info_compare);
907
908         output_sockets_list(socket_infos, cs);
909
910  cleanup:
911         assert(cs == 0 || socket_infos);
912         for (s = socket_infos; s < socket_infos + cs; s++) {
913                 free(s->type);
914                 free(s->path);
915                 if (s->own_triggered)
916                         strv_free(s->triggered);
917         }
918
919         return r;
920 }
921
922 static int get_next_elapse(
923                 sd_bus *bus,
924                 const char *path,
925                 dual_timestamp *next) {
926
927         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
928         dual_timestamp t;
929         int r;
930
931         assert(bus);
932         assert(path);
933         assert(next);
934
935         r = sd_bus_get_property_trivial(
936                         bus,
937                         "org.freedesktop.systemd1",
938                         path,
939                         "org.freedesktop.systemd1.Timer",
940                         "NextElapseUSecMonotonic",
941                         &error,
942                         't',
943                         &t.monotonic);
944         if (r < 0) {
945                 log_error("Failed to get next elapsation time: %s", bus_error_message(&error, r));
946                 return r;
947         }
948
949         r = sd_bus_get_property_trivial(
950                         bus,
951                         "org.freedesktop.systemd1",
952                         path,
953                         "org.freedesktop.systemd1.Timer",
954                         "NextElapseUSecRealtime",
955                         &error,
956                         't',
957                         &t.realtime);
958         if (r < 0) {
959                 log_error("Failed to get next elapsation time: %s", bus_error_message(&error, r));
960                 return r;
961         }
962
963         *next = t;
964         return 0;
965 }
966
967 static int get_last_trigger(
968                 sd_bus *bus,
969                 const char *path,
970                 usec_t *last) {
971
972         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
973         int r;
974
975         assert(bus);
976         assert(path);
977         assert(last);
978
979         r = sd_bus_get_property_trivial(
980                         bus,
981                         "org.freedesktop.systemd1",
982                         path,
983                         "org.freedesktop.systemd1.Timer",
984                         "LastTriggerUSec",
985                         &error,
986                         't',
987                         last);
988         if (r < 0) {
989                 log_error("Failed to get last trigger time: %s", bus_error_message(&error, r));
990                 return r;
991         }
992
993         return 0;
994 }
995
996 struct timer_info {
997         const char* machine;
998         const char* id;
999         usec_t next_elapse;
1000         usec_t last_trigger;
1001         char** triggered;
1002 };
1003
1004 static int timer_info_compare(const struct timer_info *a, const struct timer_info *b) {
1005         int o;
1006
1007         assert(a);
1008         assert(b);
1009
1010         if (!a->machine && b->machine)
1011                 return -1;
1012         if (a->machine && !b->machine)
1013                 return 1;
1014         if (a->machine && b->machine) {
1015                 o = strcasecmp(a->machine, b->machine);
1016                 if (o != 0)
1017                         return o;
1018         }
1019
1020         if (a->next_elapse < b->next_elapse)
1021                 return -1;
1022         if (a->next_elapse > b->next_elapse)
1023                 return 1;
1024
1025         return strcmp(a->id, b->id);
1026 }
1027
1028 static int output_timers_list(struct timer_info *timer_infos, unsigned n) {
1029         struct timer_info *t;
1030         unsigned
1031                 nextlen = strlen("NEXT"),
1032                 leftlen = strlen("LEFT"),
1033                 lastlen = strlen("LAST"),
1034                 passedlen = strlen("PASSED"),
1035                 unitlen = strlen("UNIT"),
1036                 activatelen = strlen("ACTIVATES");
1037
1038         const char *on, *off;
1039
1040         assert(timer_infos || n == 0);
1041
1042         for (t = timer_infos; t < timer_infos + n; t++) {
1043                 unsigned ul = 0;
1044                 char **a;
1045
1046                 if (t->next_elapse > 0) {
1047                         char tstamp[FORMAT_TIMESTAMP_MAX] = "", trel[FORMAT_TIMESTAMP_RELATIVE_MAX] = "";
1048
1049                         format_timestamp(tstamp, sizeof(tstamp), t->next_elapse);
1050                         nextlen = MAX(nextlen, strlen(tstamp) + 1);
1051
1052                         format_timestamp_relative(trel, sizeof(trel), t->next_elapse);
1053                         leftlen = MAX(leftlen, strlen(trel));
1054                 }
1055
1056                 if (t->last_trigger > 0) {
1057                         char tstamp[FORMAT_TIMESTAMP_MAX] = "", trel[FORMAT_TIMESTAMP_RELATIVE_MAX] = "";
1058
1059                         format_timestamp(tstamp, sizeof(tstamp), t->last_trigger);
1060                         lastlen = MAX(lastlen, strlen(tstamp) + 1);
1061
1062                         format_timestamp_relative(trel, sizeof(trel), t->last_trigger);
1063                         passedlen = MAX(passedlen, strlen(trel));
1064                 }
1065
1066                 unitlen = MAX(unitlen, strlen(t->id) + (t->machine ? strlen(t->machine)+1 : 0));
1067
1068                 STRV_FOREACH(a, t->triggered)
1069                         ul += strlen(*a) + 2*(a != t->triggered);
1070
1071                 activatelen = MAX(activatelen, ul);
1072         }
1073
1074         if (n > 0) {
1075                 if (!arg_no_legend)
1076                         printf("%-*s %-*s %-*s %-*s %-*s %s\n",
1077                                nextlen,   "NEXT",
1078                                leftlen,   "LEFT",
1079                                lastlen,   "LAST",
1080                                passedlen, "PASSED",
1081                                unitlen,   "UNIT",
1082                                           "ACTIVATES");
1083
1084                 for (t = timer_infos; t < timer_infos + n; t++) {
1085                         _cleanup_free_ char *j = NULL;
1086                         const char *unit;
1087                         char tstamp1[FORMAT_TIMESTAMP_MAX] = "n/a", trel1[FORMAT_TIMESTAMP_RELATIVE_MAX] = "n/a";
1088                         char tstamp2[FORMAT_TIMESTAMP_MAX] = "n/a", trel2[FORMAT_TIMESTAMP_RELATIVE_MAX] = "n/a";
1089                         char **a;
1090
1091                         format_timestamp(tstamp1, sizeof(tstamp1), t->next_elapse);
1092                         format_timestamp_relative(trel1, sizeof(trel1), t->next_elapse);
1093
1094                         format_timestamp(tstamp2, sizeof(tstamp2), t->last_trigger);
1095                         format_timestamp_relative(trel2, sizeof(trel2), t->last_trigger);
1096
1097                         if (t->machine) {
1098                                 j = strjoin(t->machine, ":", t->id, NULL);
1099                                 if (!j)
1100                                         return log_oom();
1101                                 unit = j;
1102                         } else
1103                                 unit = t->id;
1104
1105                         printf("%-*s %-*s %-*s %-*s %-*s",
1106                                nextlen, tstamp1, leftlen, trel1, lastlen, tstamp2, passedlen, trel2, unitlen, unit);
1107
1108                         STRV_FOREACH(a, t->triggered)
1109                                 printf("%s %s",
1110                                        a == t->triggered ? "" : ",", *a);
1111                         printf("\n");
1112                 }
1113
1114                 on = ansi_highlight();
1115                 off = ansi_highlight_off();
1116                 if (!arg_no_legend)
1117                         printf("\n");
1118         } else {
1119                 on = ansi_highlight_red();
1120                 off = ansi_highlight_off();
1121         }
1122
1123         if (!arg_no_legend) {
1124                 printf("%s%u timers listed.%s\n", on, n, off);
1125                 if (!arg_all)
1126                         printf("Pass --all to see loaded but inactive timers, too.\n");
1127         }
1128
1129         return 0;
1130 }
1131
1132 static usec_t calc_next_elapse(dual_timestamp *nw, dual_timestamp *next) {
1133         usec_t next_elapse;
1134
1135         assert(nw);
1136         assert(next);
1137
1138         if (next->monotonic != USEC_INFINITY && next->monotonic > 0) {
1139                 usec_t converted;
1140
1141                 if (next->monotonic > nw->monotonic)
1142                         converted = nw->realtime + (next->monotonic - nw->monotonic);
1143                 else
1144                         converted = nw->realtime - (nw->monotonic - next->monotonic);
1145
1146                 if (next->realtime != USEC_INFINITY && next->realtime > 0)
1147                         next_elapse = MIN(converted, next->realtime);
1148                 else
1149                         next_elapse = converted;
1150
1151         } else
1152                 next_elapse = next->realtime;
1153
1154         return next_elapse;
1155 }
1156
1157 static int list_timers(sd_bus *bus, char **args) {
1158         _cleanup_(message_set_freep) Set *replies = NULL;
1159         _cleanup_strv_free_ char **machines = NULL;
1160         _cleanup_free_ struct timer_info *timer_infos = NULL;
1161         _cleanup_free_ UnitInfo *unit_infos = NULL;
1162         struct timer_info *t;
1163         const UnitInfo *u;
1164         size_t size = 0;
1165         int n, c = 0;
1166         dual_timestamp nw;
1167         int r = 0;
1168
1169         pager_open_if_enabled();
1170
1171         n = get_unit_list_recursive(bus, strv_skip_first(args), &unit_infos, &replies, &machines);
1172         if (n < 0)
1173                 return n;
1174
1175         dual_timestamp_get(&nw);
1176
1177         for (u = unit_infos; u < unit_infos + n; u++) {
1178                 _cleanup_strv_free_ char **triggered = NULL;
1179                 dual_timestamp next = {};
1180                 usec_t m, last = 0;
1181
1182                 if (!endswith(u->id, ".timer"))
1183                         continue;
1184
1185                 r = get_triggered_units(bus, u->unit_path, &triggered);
1186                 if (r < 0)
1187                         goto cleanup;
1188
1189                 r = get_next_elapse(bus, u->unit_path, &next);
1190                 if (r < 0)
1191                         goto cleanup;
1192
1193                 get_last_trigger(bus, u->unit_path, &last);
1194
1195                 if (!GREEDY_REALLOC(timer_infos, size, c+1)) {
1196                         r = log_oom();
1197                         goto cleanup;
1198                 }
1199
1200                 m = calc_next_elapse(&nw, &next);
1201
1202                 timer_infos[c++] = (struct timer_info) {
1203                         .machine = u->machine,
1204                         .id = u->id,
1205                         .next_elapse = m,
1206                         .last_trigger = last,
1207                         .triggered = triggered,
1208                 };
1209
1210                 triggered = NULL; /* avoid cleanup */
1211         }
1212
1213         qsort_safe(timer_infos, c, sizeof(struct timer_info),
1214                    (__compar_fn_t) timer_info_compare);
1215
1216         output_timers_list(timer_infos, c);
1217
1218  cleanup:
1219         for (t = timer_infos; t < timer_infos + c; t++)
1220                 strv_free(t->triggered);
1221
1222         return r;
1223 }
1224
1225 static int compare_unit_file_list(const void *a, const void *b) {
1226         const char *d1, *d2;
1227         const UnitFileList *u = a, *v = b;
1228
1229         d1 = strrchr(u->path, '.');
1230         d2 = strrchr(v->path, '.');
1231
1232         if (d1 && d2) {
1233                 int r;
1234
1235                 r = strcasecmp(d1, d2);
1236                 if (r != 0)
1237                         return r;
1238         }
1239
1240         return strcasecmp(basename(u->path), basename(v->path));
1241 }
1242
1243 static bool output_show_unit_file(const UnitFileList *u, char **patterns) {
1244         if (!strv_fnmatch_or_empty(patterns, basename(u->path), FNM_NOESCAPE))
1245                 return false;
1246
1247         if (!strv_isempty(arg_types)) {
1248                 const char *dot;
1249
1250                 dot = strrchr(u->path, '.');
1251                 if (!dot)
1252                         return false;
1253
1254                 if (!strv_find(arg_types, dot+1))
1255                         return false;
1256         }
1257
1258         if (!strv_isempty(arg_states) &&
1259             !strv_find(arg_states, unit_file_state_to_string(u->state)))
1260                 return false;
1261
1262         return true;
1263 }
1264
1265 static void output_unit_file_list(const UnitFileList *units, unsigned c) {
1266         unsigned max_id_len, id_cols, state_cols;
1267         const UnitFileList *u;
1268
1269         max_id_len = strlen("UNIT FILE");
1270         state_cols = strlen("STATE");
1271
1272         for (u = units; u < units + c; u++) {
1273                 max_id_len = MAX(max_id_len, strlen(basename(u->path)));
1274                 state_cols = MAX(state_cols, strlen(unit_file_state_to_string(u->state)));
1275         }
1276
1277         if (!arg_full) {
1278                 unsigned basic_cols;
1279
1280                 id_cols = MIN(max_id_len, 25u);
1281                 basic_cols = 1 + id_cols + state_cols;
1282                 if (basic_cols < (unsigned) columns())
1283                         id_cols += MIN(columns() - basic_cols, max_id_len - id_cols);
1284         } else
1285                 id_cols = max_id_len;
1286
1287         if (!arg_no_legend)
1288                 printf("%-*s %-*s\n",
1289                        id_cols, "UNIT FILE",
1290                        state_cols, "STATE");
1291
1292         for (u = units; u < units + c; u++) {
1293                 _cleanup_free_ char *e = NULL;
1294                 const char *on, *off;
1295                 const char *id;
1296
1297                 if (u->state == UNIT_FILE_MASKED ||
1298                     u->state == UNIT_FILE_MASKED_RUNTIME ||
1299                     u->state == UNIT_FILE_DISABLED ||
1300                     u->state == UNIT_FILE_INVALID) {
1301                         on  = ansi_highlight_red();
1302                         off = ansi_highlight_off();
1303                 } else if (u->state == UNIT_FILE_ENABLED) {
1304                         on  = ansi_highlight_green();
1305                         off = ansi_highlight_off();
1306                 } else
1307                         on = off = "";
1308
1309                 id = basename(u->path);
1310
1311                 e = arg_full ? NULL : ellipsize(id, id_cols, 33);
1312
1313                 printf("%-*s %s%-*s%s\n",
1314                        id_cols, e ? e : id,
1315                        on, state_cols, unit_file_state_to_string(u->state), off);
1316         }
1317
1318         if (!arg_no_legend)
1319                 printf("\n%u unit files listed.\n", c);
1320 }
1321
1322 static int list_unit_files(sd_bus *bus, char **args) {
1323         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1324         _cleanup_free_ UnitFileList *units = NULL;
1325         UnitFileList *unit;
1326         size_t size = 0;
1327         unsigned c = 0;
1328         const char *state;
1329         char *path;
1330         int r;
1331
1332         pager_open_if_enabled();
1333
1334         if (avoid_bus()) {
1335                 Hashmap *h;
1336                 UnitFileList *u;
1337                 Iterator i;
1338                 unsigned n_units;
1339
1340                 h = hashmap_new(&string_hash_ops);
1341                 if (!h)
1342                         return log_oom();
1343
1344                 r = unit_file_get_list(arg_scope, arg_root, h);
1345                 if (r < 0) {
1346                         unit_file_list_free(h);
1347                         log_error_errno(r, "Failed to get unit file list: %m");
1348                         return r;
1349                 }
1350
1351                 n_units = hashmap_size(h);
1352
1353                 units = new(UnitFileList, n_units);
1354                 if (!units && n_units > 0) {
1355                         unit_file_list_free(h);
1356                         return log_oom();
1357                 }
1358
1359                 HASHMAP_FOREACH(u, h, i) {
1360                         if (!output_show_unit_file(u, strv_skip_first(args)))
1361                                 continue;
1362
1363                         units[c++] = *u;
1364                         free(u);
1365                 }
1366
1367                 assert(c <= n_units);
1368                 hashmap_free(h);
1369         } else {
1370                 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1371
1372                 r = sd_bus_call_method(
1373                                 bus,
1374                                 "org.freedesktop.systemd1",
1375                                 "/org/freedesktop/systemd1",
1376                                 "org.freedesktop.systemd1.Manager",
1377                                 "ListUnitFiles",
1378                                 &error,
1379                                 &reply,
1380                                 NULL);
1381                 if (r < 0) {
1382                         log_error("Failed to list unit files: %s", bus_error_message(&error, r));
1383                         return r;
1384                 }
1385
1386                 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ss)");
1387                 if (r < 0)
1388                         return bus_log_parse_error(r);
1389
1390                 while ((r = sd_bus_message_read(reply, "(ss)", &path, &state)) > 0) {
1391
1392                         if (!GREEDY_REALLOC(units, size, c + 1))
1393                                 return log_oom();
1394
1395                         units[c] = (struct UnitFileList) {
1396                                 path,
1397                                 unit_file_state_from_string(state)
1398                         };
1399
1400                         if (output_show_unit_file(&units[c], strv_skip_first(args)))
1401                                 c ++;
1402
1403                 }
1404                 if (r < 0)
1405                         return bus_log_parse_error(r);
1406
1407                 r = sd_bus_message_exit_container(reply);
1408                 if (r < 0)
1409                         return bus_log_parse_error(r);
1410         }
1411
1412         qsort_safe(units, c, sizeof(UnitFileList), compare_unit_file_list);
1413         output_unit_file_list(units, c);
1414
1415         if (avoid_bus()) {
1416                 for (unit = units; unit < units + c; unit++)
1417                         free(unit->path);
1418         }
1419
1420         return 0;
1421 }
1422
1423 static int list_dependencies_print(const char *name, int level, unsigned int branches, bool last) {
1424         _cleanup_free_ char *n = NULL;
1425         size_t max_len = MAX(columns(),20u);
1426         size_t len = 0;
1427         int i;
1428
1429         if (!arg_plain) {
1430
1431                 for (i = level - 1; i >= 0; i--) {
1432                         len += 2;
1433                         if (len > max_len - 3 && !arg_full) {
1434                                 printf("%s...\n",max_len % 2 ? "" : " ");
1435                                 return 0;
1436                         }
1437                         printf("%s", draw_special_char(branches & (1 << i) ? DRAW_TREE_VERTICAL : DRAW_TREE_SPACE));
1438                 }
1439                 len += 2;
1440
1441                 if (len > max_len - 3 && !arg_full) {
1442                         printf("%s...\n",max_len % 2 ? "" : " ");
1443                         return 0;
1444                 }
1445
1446                 printf("%s", draw_special_char(last ? DRAW_TREE_RIGHT : DRAW_TREE_BRANCH));
1447         }
1448
1449         if (arg_full){
1450                 printf("%s\n", name);
1451                 return 0;
1452         }
1453
1454         n = ellipsize(name, max_len-len, 100);
1455         if (!n)
1456                 return log_oom();
1457
1458         printf("%s\n", n);
1459         return 0;
1460 }
1461
1462 static int list_dependencies_get_dependencies(sd_bus *bus, const char *name, char ***deps) {
1463
1464         static const char *dependencies[_DEPENDENCY_MAX] = {
1465                 [DEPENDENCY_FORWARD] = "Requires\0"
1466                                        "RequiresOverridable\0"
1467                                        "Requisite\0"
1468                                        "RequisiteOverridable\0"
1469                                        "Wants\0"
1470                                        "BindsTo\0",
1471                 [DEPENDENCY_REVERSE] = "RequiredBy\0"
1472                                        "RequiredByOverridable\0"
1473                                        "WantedBy\0"
1474                                        "PartOf\0"
1475                                        "BoundBy\0",
1476                 [DEPENDENCY_AFTER]   = "After\0",
1477                 [DEPENDENCY_BEFORE]  = "Before\0",
1478         };
1479
1480         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1481         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1482         _cleanup_strv_free_ char **ret = NULL;
1483         _cleanup_free_ char *path = NULL;
1484         int r;
1485
1486         assert(bus);
1487         assert(name);
1488         assert(deps);
1489         assert_cc(ELEMENTSOF(dependencies) == _DEPENDENCY_MAX);
1490
1491         path = unit_dbus_path_from_name(name);
1492         if (!path)
1493                 return log_oom();
1494
1495         r = sd_bus_call_method(
1496                         bus,
1497                         "org.freedesktop.systemd1",
1498                         path,
1499                         "org.freedesktop.DBus.Properties",
1500                         "GetAll",
1501                         &error,
1502                         &reply,
1503                         "s", "org.freedesktop.systemd1.Unit");
1504         if (r < 0) {
1505                 log_error("Failed to get properties of %s: %s", name, bus_error_message(&error, r));
1506                 return r;
1507         }
1508
1509         r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
1510         if (r < 0)
1511                 return bus_log_parse_error(r);
1512
1513         while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
1514                 const char *prop;
1515
1516                 r = sd_bus_message_read(reply, "s", &prop);
1517                 if (r < 0)
1518                         return bus_log_parse_error(r);
1519
1520                 if (!nulstr_contains(dependencies[arg_dependency], prop)) {
1521                         r = sd_bus_message_skip(reply, "v");
1522                         if (r < 0)
1523                                 return bus_log_parse_error(r);
1524                 } else {
1525
1526                         r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, "as");
1527                         if (r < 0)
1528                                 return bus_log_parse_error(r);
1529
1530                         r = bus_message_read_strv_extend(reply, &ret);
1531                         if (r < 0)
1532                                 return bus_log_parse_error(r);
1533
1534                         r = sd_bus_message_exit_container(reply);
1535                         if (r < 0)
1536                                 return bus_log_parse_error(r);
1537                 }
1538
1539                 r = sd_bus_message_exit_container(reply);
1540                 if (r < 0)
1541                         return bus_log_parse_error(r);
1542
1543         }
1544         if (r < 0)
1545                 return bus_log_parse_error(r);
1546
1547         r = sd_bus_message_exit_container(reply);
1548         if (r < 0)
1549                 return bus_log_parse_error(r);
1550
1551         *deps = ret;
1552         ret = NULL;
1553
1554         return 0;
1555 }
1556
1557 static int list_dependencies_compare(const void *_a, const void *_b) {
1558         const char **a = (const char**) _a, **b = (const char**) _b;
1559
1560         if (unit_name_to_type(*a) == UNIT_TARGET && unit_name_to_type(*b) != UNIT_TARGET)
1561                 return 1;
1562         if (unit_name_to_type(*a) != UNIT_TARGET && unit_name_to_type(*b) == UNIT_TARGET)
1563                 return -1;
1564
1565         return strcasecmp(*a, *b);
1566 }
1567
1568 static int list_dependencies_one(
1569                 sd_bus *bus,
1570                 const char *name,
1571                 int level,
1572                 char ***units,
1573                 unsigned int branches) {
1574
1575         _cleanup_strv_free_ char **deps = NULL;
1576         char **c;
1577         int r = 0;
1578
1579         assert(bus);
1580         assert(name);
1581         assert(units);
1582
1583         r = strv_extend(units, name);
1584         if (r < 0)
1585                 return log_oom();
1586
1587         r = list_dependencies_get_dependencies(bus, name, &deps);
1588         if (r < 0)
1589                 return r;
1590
1591         qsort_safe(deps, strv_length(deps), sizeof (char*), list_dependencies_compare);
1592
1593         STRV_FOREACH(c, deps) {
1594                 if (strv_contains(*units, *c)) {
1595                         if (!arg_plain) {
1596                                 r = list_dependencies_print("...", level + 1, (branches << 1) | (c[1] == NULL ? 0 : 1), 1);
1597                                 if (r < 0)
1598                                         return r;
1599                         }
1600                         continue;
1601                 }
1602
1603                 if (arg_plain)
1604                         printf("  ");
1605                 else {
1606                         int state;
1607                         const char *on;
1608
1609                         state = check_one_unit(bus, *c, "activating\0active\0reloading\0", true);
1610                         on = state > 0 ? ansi_highlight_green() : ansi_highlight_red();
1611                         printf("%s%s%s ", on, draw_special_char(DRAW_BLACK_CIRCLE), ansi_highlight_off());
1612                 }
1613
1614                 r = list_dependencies_print(*c, level, branches, c[1] == NULL);
1615                 if (r < 0)
1616                         return r;
1617
1618                 if (arg_all || unit_name_to_type(*c) == UNIT_TARGET) {
1619                        r = list_dependencies_one(bus, *c, level + 1, units, (branches << 1) | (c[1] == NULL ? 0 : 1));
1620                        if (r < 0)
1621                                return r;
1622                 }
1623         }
1624
1625         if (!arg_plain)
1626                 strv_remove(*units, name);
1627
1628         return 0;
1629 }
1630
1631 static int list_dependencies(sd_bus *bus, char **args) {
1632         _cleanup_strv_free_ char **units = NULL;
1633         _cleanup_free_ char *unit = NULL;
1634         const char *u;
1635
1636         assert(bus);
1637
1638         if (args[1]) {
1639                 unit = unit_name_mangle(args[1], MANGLE_NOGLOB);
1640                 if (!unit)
1641                         return log_oom();
1642                 u = unit;
1643         } else
1644                 u = SPECIAL_DEFAULT_TARGET;
1645
1646         pager_open_if_enabled();
1647
1648         puts(u);
1649
1650         return list_dependencies_one(bus, u, 0, &units, 0);
1651 }
1652
1653 struct machine_info {
1654         bool is_host;
1655         char *name;
1656         char *state;
1657         char *control_group;
1658         uint32_t n_failed_units;
1659         uint32_t n_jobs;
1660         usec_t timestamp;
1661 };
1662
1663 static const struct bus_properties_map machine_info_property_map[] = {
1664         { "SystemState",        "s", NULL, offsetof(struct machine_info, state)          },
1665         { "NJobs",              "u", NULL, offsetof(struct machine_info, n_jobs)         },
1666         { "NFailedUnits",       "u", NULL, offsetof(struct machine_info, n_failed_units) },
1667         { "ControlGroup",       "s", NULL, offsetof(struct machine_info, control_group)  },
1668         { "UserspaceTimestamp", "t", NULL, offsetof(struct machine_info, timestamp)      },
1669         {}
1670 };
1671
1672 static void free_machines_list(struct machine_info *machine_infos, int n) {
1673         int i;
1674
1675         if (!machine_infos)
1676                 return;
1677
1678         for (i = 0; i < n; i++) {
1679                 free(machine_infos[i].name);
1680                 free(machine_infos[i].state);
1681                 free(machine_infos[i].control_group);
1682         }
1683
1684         free(machine_infos);
1685 }
1686
1687 static int compare_machine_info(const void *a, const void *b) {
1688         const struct machine_info *u = a, *v = b;
1689
1690         if (u->is_host != v->is_host)
1691                 return u->is_host > v->is_host ? -1 : 1;
1692
1693         return strcasecmp(u->name, v->name);
1694 }
1695
1696 static int get_machine_properties(sd_bus *bus, struct machine_info *mi) {
1697         _cleanup_bus_close_unref_ sd_bus *container = NULL;
1698         int r;
1699
1700         assert(mi);
1701
1702         if (!bus) {
1703                 r = sd_bus_open_system_machine(&container, mi->name);
1704                 if (r < 0)
1705                         return r;
1706
1707                 bus = container;
1708         }
1709
1710         r = bus_map_all_properties(bus, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map, mi);
1711         if (r < 0)
1712                 return r;
1713
1714         return 0;
1715 }
1716
1717 static bool output_show_machine(const char *name, char **patterns) {
1718         return strv_fnmatch_or_empty(patterns, name, FNM_NOESCAPE);
1719 }
1720
1721 static int get_machine_list(
1722                 sd_bus *bus,
1723                 struct machine_info **_machine_infos,
1724                 char **patterns) {
1725
1726         struct machine_info *machine_infos = NULL;
1727         _cleanup_strv_free_ char **m = NULL;
1728         _cleanup_free_ char *hn = NULL;
1729         size_t sz = 0;
1730         char **i;
1731         int c = 0;
1732
1733         hn = gethostname_malloc();
1734         if (!hn)
1735                 return log_oom();
1736
1737         if (output_show_machine(hn, patterns)) {
1738                 if (!GREEDY_REALLOC0(machine_infos, sz, c+1))
1739                         return log_oom();
1740
1741                 machine_infos[c].is_host = true;
1742                 machine_infos[c].name = hn;
1743                 hn = NULL;
1744
1745                 get_machine_properties(bus, &machine_infos[c]);
1746                 c++;
1747         }
1748
1749         sd_get_machine_names(&m);
1750         STRV_FOREACH(i, m) {
1751                 _cleanup_free_ char *class = NULL;
1752
1753                 if (!output_show_machine(*i, patterns))
1754                         continue;
1755
1756                 sd_machine_get_class(*i, &class);
1757                 if (!streq_ptr(class, "container"))
1758                         continue;
1759
1760                 if (!GREEDY_REALLOC0(machine_infos, sz, c+1)) {
1761                         free_machines_list(machine_infos, c);
1762                         return log_oom();
1763                 }
1764
1765                 machine_infos[c].is_host = false;
1766                 machine_infos[c].name = strdup(*i);
1767                 if (!machine_infos[c].name) {
1768                         free_machines_list(machine_infos, c);
1769                         return log_oom();
1770                 }
1771
1772                 get_machine_properties(NULL, &machine_infos[c]);
1773                 c++;
1774         }
1775
1776         *_machine_infos = machine_infos;
1777         return c;
1778 }
1779
1780 static void output_machines_list(struct machine_info *machine_infos, unsigned n) {
1781         struct machine_info *m;
1782         unsigned
1783                 circle_len = 0,
1784                 namelen = sizeof("NAME") - 1,
1785                 statelen = sizeof("STATE") - 1,
1786                 failedlen = sizeof("FAILED") - 1,
1787                 jobslen = sizeof("JOBS") - 1;
1788
1789         assert(machine_infos || n == 0);
1790
1791         for (m = machine_infos; m < machine_infos + n; m++) {
1792                 namelen = MAX(namelen, strlen(m->name) + (m->is_host ? sizeof(" (host)") - 1 : 0));
1793                 statelen = MAX(statelen, m->state ? strlen(m->state) : 0);
1794                 failedlen = MAX(failedlen, DECIMAL_STR_WIDTH(m->n_failed_units));
1795                 jobslen = MAX(jobslen, DECIMAL_STR_WIDTH(m->n_jobs));
1796
1797                 if (!arg_plain && !streq_ptr(m->state, "running"))
1798                         circle_len = 2;
1799         }
1800
1801         if (!arg_no_legend) {
1802                 if (circle_len > 0)
1803                         fputs("  ", stdout);
1804
1805                 printf("%-*s %-*s %-*s %-*s\n",
1806                          namelen, "NAME",
1807                         statelen, "STATE",
1808                        failedlen, "FAILED",
1809                          jobslen, "JOBS");
1810         }
1811
1812         for (m = machine_infos; m < machine_infos + n; m++) {
1813                 const char *on_state = "", *off_state = "";
1814                 const char *on_failed = "", *off_failed = "";
1815                 bool circle = false;
1816
1817                 if (streq_ptr(m->state, "degraded")) {
1818                         on_state = ansi_highlight_red();
1819                         off_state = ansi_highlight_off();
1820                         circle = true;
1821                 } else if (!streq_ptr(m->state, "running")) {
1822                         on_state = ansi_highlight_yellow();
1823                         off_state = ansi_highlight_off();
1824                         circle = true;
1825                 }
1826
1827                 if (m->n_failed_units > 0) {
1828                         on_failed = ansi_highlight_red();
1829                         off_failed = ansi_highlight_off();
1830                 } else
1831                         on_failed = off_failed = "";
1832
1833                 if (circle_len > 0)
1834                         printf("%s%s%s ", on_state, circle ? draw_special_char(DRAW_BLACK_CIRCLE) : " ", off_state);
1835
1836                 if (m->is_host)
1837                         printf("%-*s (host) %s%-*s%s %s%*u%s %*u\n",
1838                                (int) (namelen - (sizeof(" (host)")-1)), strna(m->name),
1839                                on_state, statelen, strna(m->state), off_state,
1840                                on_failed, failedlen, m->n_failed_units, off_failed,
1841                                jobslen, m->n_jobs);
1842                 else
1843                         printf("%-*s %s%-*s%s %s%*u%s %*u\n",
1844                                namelen, strna(m->name),
1845                                on_state, statelen, strna(m->state), off_state,
1846                                on_failed, failedlen, m->n_failed_units, off_failed,
1847                                jobslen, m->n_jobs);
1848         }
1849
1850         if (!arg_no_legend)
1851                 printf("\n%u machines listed.\n", n);
1852 }
1853
1854 static int list_machines(sd_bus *bus, char **args) {
1855         struct machine_info *machine_infos = NULL;
1856         int r;
1857
1858         assert(bus);
1859
1860         if (geteuid() != 0) {
1861                 log_error("Must be root.");
1862                 return -EPERM;
1863         }
1864
1865         pager_open_if_enabled();
1866
1867         r = get_machine_list(bus, &machine_infos, strv_skip_first(args));
1868         if (r < 0)
1869                 return r;
1870
1871         qsort_safe(machine_infos, r, sizeof(struct machine_info), compare_machine_info);
1872         output_machines_list(machine_infos, r);
1873         free_machines_list(machine_infos, r);
1874
1875         return 0;
1876 }
1877
1878 static int get_default(sd_bus *bus, char **args) {
1879         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1880         _cleanup_free_ char *_path = NULL;
1881         const char *path;
1882         int r;
1883
1884         if (!bus || avoid_bus()) {
1885                 r = unit_file_get_default(arg_scope, arg_root, &_path);
1886                 if (r < 0)
1887                         return log_error_errno(r, "Failed to get default target: %m");
1888                 path = _path;
1889
1890         } else {
1891                 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1892
1893                 r = sd_bus_call_method(
1894                                 bus,
1895                                 "org.freedesktop.systemd1",
1896                                 "/org/freedesktop/systemd1",
1897                                 "org.freedesktop.systemd1.Manager",
1898                                 "GetDefaultTarget",
1899                                 &error,
1900                                 &reply,
1901                                 NULL);
1902                 if (r < 0) {
1903                         log_error("Failed to get default target: %s", bus_error_message(&error, -r));
1904                         return r;
1905                 }
1906
1907                 r = sd_bus_message_read(reply, "s", &path);
1908                 if (r < 0)
1909                         return bus_log_parse_error(r);
1910         }
1911
1912         if (path)
1913                 printf("%s\n", path);
1914
1915         return 0;
1916 }
1917
1918 static void dump_unit_file_changes(const UnitFileChange *changes, unsigned n_changes) {
1919         unsigned i;
1920
1921         assert(changes || n_changes == 0);
1922
1923         for (i = 0; i < n_changes; i++) {
1924                 if (changes[i].type == UNIT_FILE_SYMLINK)
1925                         log_info("Created symlink from %s to %s.", changes[i].path, changes[i].source);
1926                 else
1927                         log_info("Removed symlink %s.", changes[i].path);
1928         }
1929 }
1930
1931 static int set_default(sd_bus *bus, char **args) {
1932         _cleanup_free_ char *unit = NULL;
1933         UnitFileChange *changes = NULL;
1934         unsigned n_changes = 0;
1935         int r;
1936
1937         unit = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".target");
1938         if (!unit)
1939                 return log_oom();
1940
1941         if (!bus || avoid_bus()) {
1942                 r = unit_file_set_default(arg_scope, arg_root, unit, true, &changes, &n_changes);
1943                 if (r < 0)
1944                         return log_error_errno(r, "Failed to set default target: %m");
1945
1946                 if (!arg_quiet)
1947                         dump_unit_file_changes(changes, n_changes);
1948
1949                 r = 0;
1950         } else {
1951                 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1952                 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1953
1954                 polkit_agent_open_if_enabled();
1955
1956                 r = sd_bus_call_method(
1957                                 bus,
1958                                 "org.freedesktop.systemd1",
1959                                 "/org/freedesktop/systemd1",
1960                                 "org.freedesktop.systemd1.Manager",
1961                                 "SetDefaultTarget",
1962                                 &error,
1963                                 &reply,
1964                                 "sb", unit, 1);
1965                 if (r < 0) {
1966                         log_error("Failed to set default target: %s", bus_error_message(&error, -r));
1967                         return r;
1968                 }
1969
1970                 r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet);
1971                 if (r < 0)
1972                         return r;
1973
1974                 /* Try to reload if enabled */
1975                 if (!arg_no_reload)
1976                         r = daemon_reload(bus, args);
1977                 else
1978                         r = 0;
1979         }
1980
1981         unit_file_changes_free(changes, n_changes);
1982
1983         return r;
1984 }
1985
1986 struct job_info {
1987         uint32_t id;
1988         const char *name, *type, *state;
1989 };
1990
1991 static void output_jobs_list(const struct job_info* jobs, unsigned n, bool skipped) {
1992         unsigned id_len, unit_len, type_len, state_len;
1993         const struct job_info *j;
1994         const char *on, *off;
1995         bool shorten = false;
1996
1997         assert(n == 0 || jobs);
1998
1999         if (n == 0) {
2000                 if (!arg_no_legend) {
2001                         on = ansi_highlight_green();
2002                         off = ansi_highlight_off();
2003
2004                         printf("%sNo jobs %s.%s\n", on, skipped ? "listed" : "running", off);
2005                 }
2006                 return;
2007         }
2008
2009         pager_open_if_enabled();
2010
2011         id_len = strlen("JOB");
2012         unit_len = strlen("UNIT");
2013         type_len = strlen("TYPE");
2014         state_len = strlen("STATE");
2015
2016         for (j = jobs; j < jobs + n; j++) {
2017                 uint32_t id = j->id;
2018                 assert(j->name && j->type && j->state);
2019
2020                 id_len = MAX(id_len, DECIMAL_STR_WIDTH(id));
2021                 unit_len = MAX(unit_len, strlen(j->name));
2022                 type_len = MAX(type_len, strlen(j->type));
2023                 state_len = MAX(state_len, strlen(j->state));
2024         }
2025
2026         if (!arg_full && id_len + 1 + unit_len + type_len + 1 + state_len > columns()) {
2027                 unit_len = MAX(33u, columns() - id_len - type_len - state_len - 3);
2028                 shorten = true;
2029         }
2030
2031         if (!arg_no_legend)
2032                 printf("%*s %-*s %-*s %-*s\n",
2033                        id_len, "JOB",
2034                        unit_len, "UNIT",
2035                        type_len, "TYPE",
2036                        state_len, "STATE");
2037
2038         for (j = jobs; j < jobs + n; j++) {
2039                 _cleanup_free_ char *e = NULL;
2040
2041                 if (streq(j->state, "running")) {
2042                         on = ansi_highlight();
2043                         off = ansi_highlight_off();
2044                 } else
2045                         on = off = "";
2046
2047                 e = shorten ? ellipsize(j->name, unit_len, 33) : NULL;
2048                 printf("%*u %s%-*s%s %-*s %s%-*s%s\n",
2049                        id_len, j->id,
2050                        on, unit_len, e ? e : j->name, off,
2051                        type_len, j->type,
2052                        on, state_len, j->state, off);
2053         }
2054
2055         if (!arg_no_legend) {
2056                 on = ansi_highlight();
2057                 off = ansi_highlight_off();
2058
2059                 printf("\n%s%u jobs listed%s.\n", on, n, off);
2060         }
2061 }
2062
2063 static bool output_show_job(struct job_info *job, char **patterns) {
2064         return strv_fnmatch_or_empty(patterns, job->name, FNM_NOESCAPE);
2065 }
2066
2067 static int list_jobs(sd_bus *bus, char **args) {
2068         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2069         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2070         const char *name, *type, *state, *job_path, *unit_path;
2071         _cleanup_free_ struct job_info *jobs = NULL;
2072         size_t size = 0;
2073         unsigned c = 0;
2074         uint32_t id;
2075         int r;
2076         bool skipped = false;
2077
2078         r = sd_bus_call_method(
2079                         bus,
2080                         "org.freedesktop.systemd1",
2081                         "/org/freedesktop/systemd1",
2082                         "org.freedesktop.systemd1.Manager",
2083                         "ListJobs",
2084                         &error,
2085                         &reply,
2086                         NULL);
2087         if (r < 0) {
2088                 log_error("Failed to list jobs: %s", bus_error_message(&error, r));
2089                 return r;
2090         }
2091
2092         r = sd_bus_message_enter_container(reply, 'a', "(usssoo)");
2093         if (r < 0)
2094                 return bus_log_parse_error(r);
2095
2096         while ((r = sd_bus_message_read(reply, "(usssoo)", &id, &name, &type, &state, &job_path, &unit_path)) > 0) {
2097                 struct job_info job = { id, name, type, state };
2098
2099                 if (!output_show_job(&job, strv_skip_first(args))) {
2100                         skipped = true;
2101                         continue;
2102                 }
2103
2104                 if (!GREEDY_REALLOC(jobs, size, c + 1))
2105                         return log_oom();
2106
2107                 jobs[c++] = job;
2108         }
2109         if (r < 0)
2110                 return bus_log_parse_error(r);
2111
2112         r = sd_bus_message_exit_container(reply);
2113         if (r < 0)
2114                 return bus_log_parse_error(r);
2115
2116         output_jobs_list(jobs, c, skipped);
2117         return r;
2118 }
2119
2120 static int cancel_job(sd_bus *bus, char **args) {
2121         char **name;
2122         int r = 0;
2123
2124         assert(args);
2125
2126         if (strv_length(args) <= 1)
2127                 return daemon_reload(bus, args);
2128
2129         polkit_agent_open_if_enabled();
2130
2131         STRV_FOREACH(name, args+1) {
2132                 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2133                 uint32_t id;
2134                 int q;
2135
2136                 q = safe_atou32(*name, &id);
2137                 if (q < 0)
2138                         return log_error_errno(q, "Failed to parse job id \"%s\": %m", *name);
2139
2140                 q = sd_bus_call_method(
2141                                 bus,
2142                                 "org.freedesktop.systemd1",
2143                                 "/org/freedesktop/systemd1",
2144                                 "org.freedesktop.systemd1.Manager",
2145                                 "CancelJob",
2146                                 &error,
2147                                 NULL,
2148                                 "u", id);
2149                 if (q < 0) {
2150                         log_error("Failed to cancel job %"PRIu32": %s", id, bus_error_message(&error, q));
2151                         if (r == 0)
2152                                 r = q;
2153                 }
2154         }
2155
2156         return r;
2157 }
2158
2159 static int need_daemon_reload(sd_bus *bus, const char *unit) {
2160         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2161         const char *path;
2162         int b, r;
2163
2164         /* We ignore all errors here, since this is used to show a
2165          * warning only */
2166
2167         /* We don't use unit_dbus_path_from_name() directly since we
2168          * don't want to load the unit if it isn't loaded. */
2169
2170         r = sd_bus_call_method(
2171                         bus,
2172                         "org.freedesktop.systemd1",
2173                         "/org/freedesktop/systemd1",
2174                         "org.freedesktop.systemd1.Manager",
2175                         "GetUnit",
2176                         NULL,
2177                         &reply,
2178                         "s", unit);
2179         if (r < 0)
2180                 return r;
2181
2182         r = sd_bus_message_read(reply, "o", &path);
2183         if (r < 0)
2184                 return r;
2185
2186         r = sd_bus_get_property_trivial(
2187                         bus,
2188                         "org.freedesktop.systemd1",
2189                         path,
2190                         "org.freedesktop.systemd1.Unit",
2191                         "NeedDaemonReload",
2192                         NULL,
2193                         'b', &b);
2194         if (r < 0)
2195                 return r;
2196
2197         return b;
2198 }
2199
2200 static void warn_unit_file_changed(const char *name) {
2201         log_warning("%sWarning:%s %s changed on disk. Run 'systemctl%s daemon-reload' to reload units.",
2202                     ansi_highlight_red(),
2203                     ansi_highlight_off(),
2204                     name,
2205                     arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
2206 }
2207
2208 static int unit_file_find_path(LookupPaths *lp, const char *unit_name, char **unit_path) {
2209         char **p;
2210
2211         assert(lp);
2212         assert(unit_name);
2213         assert(unit_path);
2214
2215         STRV_FOREACH(p, lp->unit_path) {
2216                 _cleanup_free_ char *path;
2217
2218                 path = path_join(arg_root, *p, unit_name);
2219                 if (!path)
2220                         return log_oom();
2221
2222                 if (access(path, F_OK) == 0) {
2223                         *unit_path = path;
2224                         path = NULL;
2225                         return 1;
2226                 }
2227         }
2228
2229         return 0;
2230 }
2231
2232 static int unit_find_paths(
2233                 sd_bus *bus,
2234                 const char *unit_name,
2235                 bool avoid_bus_cache,
2236                 LookupPaths *lp,
2237                 char **fragment_path,
2238                 char ***dropin_paths) {
2239
2240         _cleanup_free_ char *path = NULL;
2241         _cleanup_strv_free_ char **dropins = NULL;
2242         int r;
2243
2244         /**
2245          * Finds where the unit is defined on disk. Returns 0 if the unit
2246          * is not found. Returns 1 if it is found, and sets
2247          * - the path to the unit in *path, if it exists on disk,
2248          * - and a strv of existing drop-ins in *dropins,
2249          *   if the arg is not NULL and any dropins were found.
2250          */
2251
2252         assert(unit_name);
2253         assert(fragment_path);
2254         assert(lp);
2255
2256         if (!avoid_bus_cache && !unit_name_is_template(unit_name)) {
2257                 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2258                 _cleanup_bus_message_unref_ sd_bus_message *unit_load_error = NULL;
2259                 _cleanup_free_ char *unit = NULL;
2260                 char *unit_load_error_name, *unit_load_error_message;
2261
2262                 unit = unit_dbus_path_from_name(unit_name);
2263                 if (!unit)
2264                         return log_oom();
2265
2266                 if (need_daemon_reload(bus, unit_name) > 0)
2267                         warn_unit_file_changed(unit_name);
2268
2269                 r = sd_bus_get_property(
2270                                 bus,
2271                                 "org.freedesktop.systemd1",
2272                                 unit,
2273                                 "org.freedesktop.systemd1.Unit",
2274                                 "LoadError",
2275                                 &error,
2276                                 &unit_load_error,
2277                                 "(ss)");
2278                 if (r < 0)
2279                         return log_error_errno(r, "Failed to get LoadError: %s", bus_error_message(&error, r));
2280
2281                 r = sd_bus_message_read(
2282                                 unit_load_error,
2283                                 "(ss)",
2284                                 &unit_load_error_name,
2285                                 &unit_load_error_message);
2286                 if (r < 0)
2287                         return bus_log_parse_error(r);
2288
2289                 if (!isempty(unit_load_error_name)) {
2290                         log_error("Unit %s is not loaded: %s", unit_name, unit_load_error_message);
2291                         return 0;
2292                 }
2293
2294                 r = sd_bus_get_property_string(
2295                                 bus,
2296                                 "org.freedesktop.systemd1",
2297                                 unit,
2298                                 "org.freedesktop.systemd1.Unit",
2299                                 "FragmentPath",
2300                                 &error,
2301                                 &path);
2302                 if (r < 0)
2303                         return log_error_errno(r, "Failed to get FragmentPath: %s", bus_error_message(&error, r));
2304
2305                 if (dropin_paths) {
2306                         r = sd_bus_get_property_strv(
2307                                         bus,
2308                                         "org.freedesktop.systemd1",
2309                                         unit,
2310                                         "org.freedesktop.systemd1.Unit",
2311                                         "DropInPaths",
2312                                         &error,
2313                                         &dropins);
2314                         if (r < 0)
2315                                 return log_error_errno(r, "Failed to get DropInPaths: %s", bus_error_message(&error, r));
2316                 }
2317         } else {
2318                 _cleanup_set_free_ Set *names;
2319
2320                 names = set_new(NULL);
2321                 if (!names)
2322                         return -ENOMEM;
2323
2324                 r = set_put(names, unit_name);
2325                 if (r < 0)
2326                         return r;
2327
2328                 r = unit_file_find_path(lp, unit_name, &path);
2329                 if (r < 0)
2330                         return r;
2331
2332                 if (r == 0) {
2333                         _cleanup_free_ char *template;
2334
2335                         template = unit_name_template(unit_name);
2336                         if (!template)
2337                                 return log_oom();
2338
2339                         if (!streq(template, unit_name)) {
2340                                 r = unit_file_find_path(lp, template, &path);
2341                                 if (r < 0)
2342                                         return r;
2343                         }
2344                 }
2345
2346                 if (dropin_paths) {
2347                         r = unit_file_find_dropin_paths(lp->unit_path, NULL, names, &dropins);
2348                         if (r < 0)
2349                                 return r;
2350                 }
2351         }
2352
2353         r = 0;
2354
2355         if (!isempty(path)) {
2356                 *fragment_path = path;
2357                 path = NULL;
2358                 r = 1;
2359         }
2360
2361         if (dropin_paths && !strv_isempty(dropins)) {
2362                 *dropin_paths = dropins;
2363                 dropins = NULL;
2364                 r = 1;
2365         }
2366
2367         if (r == 0)
2368                 log_error("No files found for %s.", unit_name);
2369
2370         return r;
2371 }
2372
2373 static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet) {
2374         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2375         _cleanup_free_ char *n = NULL, *state = NULL;
2376         const char *path;
2377         int r;
2378
2379         assert(name);
2380
2381         n = unit_name_mangle(name, MANGLE_NOGLOB);
2382         if (!n)
2383                 return log_oom();
2384
2385         /* We don't use unit_dbus_path_from_name() directly since we
2386          * don't want to load the unit if it isn't loaded. */
2387
2388         r = sd_bus_call_method(
2389                         bus,
2390                         "org.freedesktop.systemd1",
2391                         "/org/freedesktop/systemd1",
2392                         "org.freedesktop.systemd1.Manager",
2393                         "GetUnit",
2394                         NULL,
2395                         &reply,
2396                         "s", n);
2397         if (r < 0) {
2398                 if (!quiet)
2399                         puts("unknown");
2400                 return 0;
2401         }
2402
2403         r = sd_bus_message_read(reply, "o", &path);
2404         if (r < 0)
2405                 return bus_log_parse_error(r);
2406
2407         r = sd_bus_get_property_string(
2408                         bus,
2409                         "org.freedesktop.systemd1",
2410                         path,
2411                         "org.freedesktop.systemd1.Unit",
2412                         "ActiveState",
2413                         NULL,
2414                         &state);
2415         if (r < 0) {
2416                 if (!quiet)
2417                         puts("unknown");
2418                 return 0;
2419         }
2420
2421         if (!quiet)
2422                 puts(state);
2423
2424         return nulstr_contains(good_states, state);
2425 }
2426
2427 static int check_triggering_units(
2428                 sd_bus *bus,
2429                 const char *name) {
2430
2431         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2432         _cleanup_free_ char *path = NULL, *n = NULL, *state = NULL;
2433         _cleanup_strv_free_ char **triggered_by = NULL;
2434         bool print_warning_label = true;
2435         char **i;
2436         int r;
2437
2438         n = unit_name_mangle(name, MANGLE_NOGLOB);
2439         if (!n)
2440                 return log_oom();
2441
2442         path = unit_dbus_path_from_name(n);
2443         if (!path)
2444                 return log_oom();
2445
2446         r = sd_bus_get_property_string(
2447                         bus,
2448                         "org.freedesktop.systemd1",
2449                         path,
2450                         "org.freedesktop.systemd1.Unit",
2451                         "LoadState",
2452                         &error,
2453                         &state);
2454         if (r < 0) {
2455                 log_error("Failed to get load state of %s: %s", n, bus_error_message(&error, r));
2456                 return r;
2457         }
2458
2459         if (streq(state, "masked"))
2460                 return 0;
2461
2462         r = sd_bus_get_property_strv(
2463                         bus,
2464                         "org.freedesktop.systemd1",
2465                         path,
2466                         "org.freedesktop.systemd1.Unit",
2467                         "TriggeredBy",
2468                         &error,
2469                         &triggered_by);
2470         if (r < 0) {
2471                 log_error("Failed to get triggered by array of %s: %s", n, bus_error_message(&error, r));
2472                 return r;
2473         }
2474
2475         STRV_FOREACH(i, triggered_by) {
2476                 r = check_one_unit(bus, *i, "active\0reloading\0", true);
2477                 if (r < 0)
2478                         return log_error_errno(r, "Failed to check unit: %m");
2479
2480                 if (r == 0)
2481                         continue;
2482
2483                 if (print_warning_label) {
2484                         log_warning("Warning: Stopping %s, but it can still be activated by:", n);
2485                         print_warning_label = false;
2486                 }
2487
2488                 log_warning("  %s", *i);
2489         }
2490
2491         return 0;
2492 }
2493
2494 static const struct {
2495         const char *verb;
2496         const char *method;
2497 } unit_actions[] = {
2498         { "start",                 "StartUnit" },
2499         { "stop",                  "StopUnit" },
2500         { "condstop",              "StopUnit" },
2501         { "reload",                "ReloadUnit" },
2502         { "restart",               "RestartUnit" },
2503         { "try-restart",           "TryRestartUnit" },
2504         { "condrestart",           "TryRestartUnit" },
2505         { "reload-or-restart",     "ReloadOrRestartUnit" },
2506         { "reload-or-try-restart", "ReloadOrTryRestartUnit" },
2507         { "condreload",            "ReloadOrTryRestartUnit" },
2508         { "force-reload",          "ReloadOrTryRestartUnit" }
2509 };
2510
2511 static const char *verb_to_method(const char *verb) {
2512        uint i;
2513
2514        for (i = 0; i < ELEMENTSOF(unit_actions); i++)
2515                 if (streq_ptr(unit_actions[i].verb, verb))
2516                         return unit_actions[i].method;
2517
2518        return "StartUnit";
2519 }
2520
2521 static const char *method_to_verb(const char *method) {
2522        uint i;
2523
2524        for (i = 0; i < ELEMENTSOF(unit_actions); i++)
2525                 if (streq_ptr(unit_actions[i].method, method))
2526                         return unit_actions[i].verb;
2527
2528        return "n/a";
2529 }
2530
2531 static int start_unit_one(
2532                 sd_bus *bus,
2533                 const char *method,
2534                 const char *name,
2535                 const char *mode,
2536                 sd_bus_error *error,
2537                 BusWaitForJobs *w) {
2538
2539         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2540         const char *path;
2541         int r;
2542
2543         assert(method);
2544         assert(name);
2545         assert(mode);
2546         assert(error);
2547
2548         log_debug("Calling manager for %s on %s, %s", method, name, mode);
2549
2550         r = sd_bus_call_method(
2551                         bus,
2552                         "org.freedesktop.systemd1",
2553                         "/org/freedesktop/systemd1",
2554                         "org.freedesktop.systemd1.Manager",
2555                         method,
2556                         error,
2557                         &reply,
2558                         "ss", name, mode);
2559         if (r < 0) {
2560                 const char *verb;
2561
2562                 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
2563                         /* There's always a fallback possible for
2564                          * legacy actions. */
2565                         return -EADDRNOTAVAIL;
2566
2567                 verb = method_to_verb(method);
2568
2569                 log_error("Failed to %s %s: %s", verb, name, bus_error_message(error, r));
2570                 return r;
2571         }
2572
2573         r = sd_bus_message_read(reply, "o", &path);
2574         if (r < 0)
2575                 return bus_log_parse_error(r);
2576
2577         if (need_daemon_reload(bus, name) > 0)
2578                 warn_unit_file_changed(name);
2579
2580         if (w) {
2581                 log_debug("Adding %s to the set", path);
2582                 r = bus_wait_for_jobs_add(w, path);
2583                 if (r < 0)
2584                         return log_oom();
2585         }
2586
2587         return 0;
2588 }
2589
2590 static int expand_names(sd_bus *bus, char **names, const char* suffix, char ***ret) {
2591
2592         _cleanup_strv_free_ char **mangled = NULL, **globs = NULL;
2593         char **name;
2594         int r = 0, i;
2595
2596         STRV_FOREACH(name, names) {
2597                 char *t;
2598
2599                 if (suffix)
2600                         t = unit_name_mangle_with_suffix(*name, MANGLE_GLOB, suffix);
2601                 else
2602                         t = unit_name_mangle(*name, MANGLE_GLOB);
2603                 if (!t)
2604                         return log_oom();
2605
2606                 if (string_is_glob(t))
2607                         r = strv_consume(&globs, t);
2608                 else
2609                         r = strv_consume(&mangled, t);
2610                 if (r < 0)
2611                         return log_oom();
2612         }
2613
2614         /* Query the manager only if any of the names are a glob, since
2615          * this is fairly expensive */
2616         if (!strv_isempty(globs)) {
2617                 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2618                 _cleanup_free_ UnitInfo *unit_infos = NULL;
2619
2620                 if (!bus)
2621                         return log_error_errno(ENOTSUP, "Unit name globbing without bus is not implemented.");
2622
2623                 r = get_unit_list(bus, NULL, globs, &unit_infos, 0, &reply);
2624                 if (r < 0)
2625                         return r;
2626
2627                 for (i = 0; i < r; i++)
2628                         if (strv_extend(&mangled, unit_infos[i].id) < 0)
2629                                 return log_oom();
2630         }
2631
2632         *ret = mangled;
2633         mangled = NULL; /* do not free */
2634
2635         return 0;
2636 }
2637
2638 static const struct {
2639         const char *target;
2640         const char *verb;
2641         const char *mode;
2642 } action_table[_ACTION_MAX] = {
2643         [ACTION_HALT]         = { SPECIAL_HALT_TARGET,         "halt",         "replace-irreversibly" },
2644         [ACTION_POWEROFF]     = { SPECIAL_POWEROFF_TARGET,     "poweroff",     "replace-irreversibly" },
2645         [ACTION_REBOOT]       = { SPECIAL_REBOOT_TARGET,       "reboot",       "replace-irreversibly" },
2646         [ACTION_KEXEC]        = { SPECIAL_KEXEC_TARGET,        "kexec",        "replace-irreversibly" },
2647         [ACTION_RUNLEVEL2]    = { SPECIAL_MULTI_USER_TARGET,   NULL,           "isolate" },
2648         [ACTION_RUNLEVEL3]    = { SPECIAL_MULTI_USER_TARGET,   NULL,           "isolate" },
2649         [ACTION_RUNLEVEL4]    = { SPECIAL_MULTI_USER_TARGET,   NULL,           "isolate" },
2650         [ACTION_RUNLEVEL5]    = { SPECIAL_GRAPHICAL_TARGET,    NULL,           "isolate" },
2651         [ACTION_RESCUE]       = { SPECIAL_RESCUE_TARGET,       "rescue",       "isolate" },
2652         [ACTION_EMERGENCY]    = { SPECIAL_EMERGENCY_TARGET,    "emergency",    "isolate" },
2653         [ACTION_DEFAULT]      = { SPECIAL_DEFAULT_TARGET,      "default",      "isolate" },
2654         [ACTION_EXIT]         = { SPECIAL_EXIT_TARGET,         "exit",         "replace-irreversibly" },
2655         [ACTION_SUSPEND]      = { SPECIAL_SUSPEND_TARGET,      "suspend",      "replace-irreversibly" },
2656         [ACTION_HIBERNATE]    = { SPECIAL_HIBERNATE_TARGET,    "hibernate",    "replace-irreversibly" },
2657         [ACTION_HYBRID_SLEEP] = { SPECIAL_HYBRID_SLEEP_TARGET, "hybrid-sleep", "replace-irreversibly" },
2658 };
2659
2660 static enum action verb_to_action(const char *verb) {
2661         enum action i;
2662
2663         for (i = _ACTION_INVALID; i < _ACTION_MAX; i++)
2664                 if (streq_ptr(action_table[i].verb, verb))
2665                         return i;
2666
2667         return _ACTION_INVALID;
2668 }
2669
2670 static int start_unit(sd_bus *bus, char **args) {
2671         _cleanup_(bus_wait_for_jobs_freep) BusWaitForJobs *w = NULL;
2672         const char *method, *mode, *one_name, *suffix = NULL;
2673         _cleanup_strv_free_ char **names = NULL;
2674         char **name;
2675         int r = 0;
2676
2677         assert(bus);
2678
2679         ask_password_agent_open_if_enabled();
2680         polkit_agent_open_if_enabled();
2681
2682         if (arg_action == ACTION_SYSTEMCTL) {
2683                 enum action action;
2684                 method = verb_to_method(args[0]);
2685                 action = verb_to_action(args[0]);
2686
2687                 if (streq(args[0], "isolate")) {
2688                         mode = "isolate";
2689                         suffix = ".target";
2690                 } else
2691                         mode = action_table[action].mode ?: arg_job_mode;
2692
2693                 one_name = action_table[action].target;
2694         } else {
2695                 assert(arg_action < ELEMENTSOF(action_table));
2696                 assert(action_table[arg_action].target);
2697
2698                 method = "StartUnit";
2699
2700                 mode = action_table[arg_action].mode;
2701                 one_name = action_table[arg_action].target;
2702         }
2703
2704         if (one_name)
2705                 names = strv_new(one_name, NULL);
2706         else {
2707                 r = expand_names(bus, args + 1, suffix, &names);
2708                 if (r < 0)
2709                         log_error_errno(r, "Failed to expand names: %m");
2710         }
2711
2712         if (!arg_no_block) {
2713                 r = bus_wait_for_jobs_new(bus, &w);
2714                 if (r < 0)
2715                         return log_error_errno(r, "Could not watch jobs: %m");
2716         }
2717
2718         STRV_FOREACH(name, names) {
2719                 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2720                 int q;
2721
2722                 q = start_unit_one(bus, method, *name, mode, &error, w);
2723                 if (r >= 0 && q < 0)
2724                         r = translate_bus_error_to_exit_status(q, &error);
2725         }
2726
2727         if (!arg_no_block) {
2728                 int q;
2729
2730                 q = bus_wait_for_jobs(w, arg_quiet);
2731                 if (q < 0)
2732                         return q;
2733
2734                 /* When stopping units, warn if they can still be triggered by
2735                  * another active unit (socket, path, timer) */
2736                 if (!arg_quiet && streq(method, "StopUnit"))
2737                         STRV_FOREACH(name, names)
2738                                 check_triggering_units(bus, *name);
2739         }
2740
2741         return r;
2742 }
2743
2744 /* Ask systemd-logind, which might grant access to unprivileged users
2745  * through PolicyKit */
2746 static int reboot_with_logind(sd_bus *bus, enum action a) {
2747 #ifdef HAVE_LOGIND
2748         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2749         const char *method;
2750         int r;
2751
2752         if (!bus)
2753                 return -EIO;
2754
2755         polkit_agent_open_if_enabled();
2756
2757         switch (a) {
2758
2759         case ACTION_REBOOT:
2760                 method = "Reboot";
2761                 break;
2762
2763         case ACTION_POWEROFF:
2764                 method = "PowerOff";
2765                 break;
2766
2767         case ACTION_SUSPEND:
2768                 method = "Suspend";
2769                 break;
2770
2771         case ACTION_HIBERNATE:
2772                 method = "Hibernate";
2773                 break;
2774
2775         case ACTION_HYBRID_SLEEP:
2776                 method = "HybridSleep";
2777                 break;
2778
2779         default:
2780                 return -EINVAL;
2781         }
2782
2783         r = sd_bus_call_method(
2784                         bus,
2785                         "org.freedesktop.login1",
2786                         "/org/freedesktop/login1",
2787                         "org.freedesktop.login1.Manager",
2788                         method,
2789                         &error,
2790                         NULL,
2791                         "b", arg_ask_password);
2792         if (r < 0)
2793                 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
2794
2795         return r;
2796 #else
2797         return -ENOSYS;
2798 #endif
2799 }
2800
2801 static int check_inhibitors(sd_bus *bus, enum action a) {
2802 #ifdef HAVE_LOGIND
2803         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2804         _cleanup_strv_free_ char **sessions = NULL;
2805         const char *what, *who, *why, *mode;
2806         uint32_t uid, pid;
2807         unsigned c = 0;
2808         char **s;
2809         int r;
2810
2811         if (!bus)
2812                 return 0;
2813
2814         if (arg_ignore_inhibitors || arg_force > 0)
2815                 return 0;
2816
2817         if (arg_when > 0)
2818                 return 0;
2819
2820         if (geteuid() == 0)
2821                 return 0;
2822
2823         if (!on_tty())
2824                 return 0;
2825
2826         r = sd_bus_call_method(
2827                         bus,
2828                         "org.freedesktop.login1",
2829                         "/org/freedesktop/login1",
2830                         "org.freedesktop.login1.Manager",
2831                         "ListInhibitors",
2832                         NULL,
2833                         &reply,
2834                         NULL);
2835         if (r < 0)
2836                 /* If logind is not around, then there are no inhibitors... */
2837                 return 0;
2838
2839         r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssuu)");
2840         if (r < 0)
2841                 return bus_log_parse_error(r);
2842
2843         while ((r = sd_bus_message_read(reply, "(ssssuu)", &what, &who, &why, &mode, &uid, &pid)) > 0) {
2844                 _cleanup_free_ char *comm = NULL, *user = NULL;
2845                 _cleanup_strv_free_ char **sv = NULL;
2846
2847                 if (!streq(mode, "block"))
2848                         continue;
2849
2850                 sv = strv_split(what, ":");
2851                 if (!sv)
2852                         return log_oom();
2853
2854                 if ((pid_t) pid < 0)
2855                         return log_error_errno(ERANGE, "Bad PID %"PRIu32": %m", pid);
2856
2857                 if (!strv_contains(sv,
2858                                   a == ACTION_HALT ||
2859                                   a == ACTION_POWEROFF ||
2860                                   a == ACTION_REBOOT ||
2861                                   a == ACTION_KEXEC ? "shutdown" : "sleep"))
2862                         continue;
2863
2864                 get_process_comm(pid, &comm);
2865                 user = uid_to_name(uid);
2866
2867                 log_warning("Operation inhibited by \"%s\" (PID "PID_FMT" \"%s\", user %s), reason is \"%s\".",
2868                             who, (pid_t) pid, strna(comm), strna(user), why);
2869
2870                 c++;
2871         }
2872         if (r < 0)
2873                 return bus_log_parse_error(r);
2874
2875         r = sd_bus_message_exit_container(reply);
2876         if (r < 0)
2877                 return bus_log_parse_error(r);
2878
2879         /* Check for current sessions */
2880         sd_get_sessions(&sessions);
2881         STRV_FOREACH(s, sessions) {
2882                 _cleanup_free_ char *type = NULL, *tty = NULL, *seat = NULL, *user = NULL, *service = NULL, *class = NULL;
2883
2884                 if (sd_session_get_uid(*s, &uid) < 0 || uid == getuid())
2885                         continue;
2886
2887                 if (sd_session_get_class(*s, &class) < 0 || !streq(class, "user"))
2888                         continue;
2889
2890                 if (sd_session_get_type(*s, &type) < 0 || (!streq(type, "x11") && !streq(type, "tty")))
2891                         continue;
2892
2893                 sd_session_get_tty(*s, &tty);
2894                 sd_session_get_seat(*s, &seat);
2895                 sd_session_get_service(*s, &service);
2896                 user = uid_to_name(uid);
2897
2898                 log_warning("User %s is logged in on %s.", strna(user), isempty(tty) ? (isempty(seat) ? strna(service) : seat) : tty);
2899                 c++;
2900         }
2901
2902         if (c <= 0)
2903                 return 0;
2904
2905         log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
2906                   action_table[a].verb);
2907
2908         return -EPERM;
2909 #else
2910         return 0;
2911 #endif
2912 }
2913
2914 static int start_special(sd_bus *bus, char **args) {
2915         enum action a;
2916         int r;
2917
2918         assert(args);
2919
2920         a = verb_to_action(args[0]);
2921
2922         r = check_inhibitors(bus, a);
2923         if (r < 0)
2924                 return r;
2925
2926         if (arg_force >= 2 && geteuid() != 0) {
2927                 log_error("Must be root.");
2928                 return -EPERM;
2929         }
2930
2931         if (a == ACTION_REBOOT && args[1]) {
2932                 r = update_reboot_param_file(args[1]);
2933                 if (r < 0)
2934                         return r;
2935         }
2936
2937         if (arg_force >= 2 &&
2938             (a == ACTION_HALT ||
2939              a == ACTION_POWEROFF ||
2940              a == ACTION_REBOOT))
2941                 return halt_now(a);
2942
2943         if (arg_force >= 1 &&
2944             (a == ACTION_HALT ||
2945              a == ACTION_POWEROFF ||
2946              a == ACTION_REBOOT ||
2947              a == ACTION_KEXEC ||
2948              a == ACTION_EXIT))
2949                 return daemon_reload(bus, args);
2950
2951         /* first try logind, to allow authentication with polkit */
2952         if (geteuid() != 0 &&
2953             (a == ACTION_POWEROFF ||
2954              a == ACTION_REBOOT ||
2955              a == ACTION_SUSPEND ||
2956              a == ACTION_HIBERNATE ||
2957              a == ACTION_HYBRID_SLEEP)) {
2958                 r = reboot_with_logind(bus, a);
2959                 if (r >= 0 || IN_SET(r, -ENOTSUP, -EINPROGRESS))
2960                         return r;
2961         }
2962
2963         r = start_unit(bus, args);
2964         if (r == EXIT_SUCCESS)
2965                 warn_wall(a);
2966
2967         return r;
2968 }
2969
2970 static int check_unit_generic(sd_bus *bus, int code, const char *good_states, char **args) {
2971         _cleanup_strv_free_ char **names = NULL;
2972         char **name;
2973         int r;
2974
2975         assert(bus);
2976         assert(args);
2977
2978         r = expand_names(bus, args, NULL, &names);
2979         if (r < 0)
2980                 return log_error_errno(r, "Failed to expand names: %m");
2981
2982         STRV_FOREACH(name, names) {
2983                 int state;
2984
2985                 state = check_one_unit(bus, *name, good_states, arg_quiet);
2986                 if (state < 0)
2987                         return state;
2988                 if (state == 0)
2989                         r = code;
2990         }
2991
2992         return r;
2993 }
2994
2995 static int check_unit_active(sd_bus *bus, char **args) {
2996         /* According to LSB: 3, "program is not running" */
2997         return check_unit_generic(bus, 3, "active\0reloading\0", args + 1);
2998 }
2999
3000 static int check_unit_failed(sd_bus *bus, char **args) {
3001         return check_unit_generic(bus, 1, "failed\0", args + 1);
3002 }
3003
3004 static int kill_unit(sd_bus *bus, char **args) {
3005         _cleanup_strv_free_ char **names = NULL;
3006         char **name;
3007         int r, q;
3008
3009         assert(bus);
3010         assert(args);
3011
3012         polkit_agent_open_if_enabled();
3013
3014         if (!arg_kill_who)
3015                 arg_kill_who = "all";
3016
3017         r = expand_names(bus, args + 1, NULL, &names);
3018         if (r < 0)
3019                 log_error_errno(r, "Failed to expand names: %m");
3020
3021         STRV_FOREACH(name, names) {
3022                 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3023
3024                 q = sd_bus_call_method(
3025                                 bus,
3026                                 "org.freedesktop.systemd1",
3027                                 "/org/freedesktop/systemd1",
3028                                 "org.freedesktop.systemd1.Manager",
3029                                 "KillUnit",
3030                                 &error,
3031                                 NULL,
3032                                 "ssi", *names, arg_kill_who, arg_signal);
3033                 if (q < 0) {
3034                         log_error("Failed to kill unit %s: %s", *names, bus_error_message(&error, q));
3035                         if (r == 0)
3036                                 r = q;
3037                 }
3038         }
3039
3040         return r;
3041 }
3042
3043 typedef struct ExecStatusInfo {
3044         char *name;
3045
3046         char *path;
3047         char **argv;
3048
3049         bool ignore;
3050
3051         usec_t start_timestamp;
3052         usec_t exit_timestamp;
3053         pid_t pid;
3054         int code;
3055         int status;
3056
3057         LIST_FIELDS(struct ExecStatusInfo, exec);
3058 } ExecStatusInfo;
3059
3060 static void exec_status_info_free(ExecStatusInfo *i) {
3061         assert(i);
3062
3063         free(i->name);
3064         free(i->path);
3065         strv_free(i->argv);
3066         free(i);
3067 }
3068
3069 static int exec_status_info_deserialize(sd_bus_message *m, ExecStatusInfo *i) {
3070         uint64_t start_timestamp, exit_timestamp, start_timestamp_monotonic, exit_timestamp_monotonic;
3071         const char *path;
3072         uint32_t pid;
3073         int32_t code, status;
3074         int ignore, r;
3075
3076         assert(m);
3077         assert(i);
3078
3079         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_STRUCT, "sasbttttuii");
3080         if (r < 0)
3081                 return bus_log_parse_error(r);
3082         else if (r == 0)
3083                 return 0;
3084
3085         r = sd_bus_message_read(m, "s", &path);
3086         if (r < 0)
3087                 return bus_log_parse_error(r);
3088
3089         i->path = strdup(path);
3090         if (!i->path)
3091                 return log_oom();
3092
3093         r = sd_bus_message_read_strv(m, &i->argv);
3094         if (r < 0)
3095                 return bus_log_parse_error(r);
3096
3097         r = sd_bus_message_read(m,
3098                                 "bttttuii",
3099                                 &ignore,
3100                                 &start_timestamp, &start_timestamp_monotonic,
3101                                 &exit_timestamp, &exit_timestamp_monotonic,
3102                                 &pid,
3103                                 &code, &status);
3104         if (r < 0)
3105                 return bus_log_parse_error(r);
3106
3107         i->ignore = ignore;
3108         i->start_timestamp = (usec_t) start_timestamp;
3109         i->exit_timestamp = (usec_t) exit_timestamp;
3110         i->pid = (pid_t) pid;
3111         i->code = code;
3112         i->status = status;
3113
3114         r = sd_bus_message_exit_container(m);
3115         if (r < 0)
3116                 return bus_log_parse_error(r);
3117
3118         return 1;
3119 }
3120
3121 typedef struct UnitStatusInfo {
3122         const char *id;
3123         const char *load_state;
3124         const char *active_state;
3125         const char *sub_state;
3126         const char *unit_file_state;
3127         const char *unit_file_preset;
3128
3129         const char *description;
3130         const char *following;
3131
3132         char **documentation;
3133
3134         const char *fragment_path;
3135         const char *source_path;
3136         const char *control_group;
3137
3138         char **dropin_paths;
3139
3140         const char *load_error;
3141         const char *result;
3142
3143         usec_t inactive_exit_timestamp;
3144         usec_t inactive_exit_timestamp_monotonic;
3145         usec_t active_enter_timestamp;
3146         usec_t active_exit_timestamp;
3147         usec_t inactive_enter_timestamp;
3148
3149         bool need_daemon_reload;
3150
3151         /* Service */
3152         pid_t main_pid;
3153         pid_t control_pid;
3154         const char *status_text;
3155         const char *pid_file;
3156         bool running:1;
3157         int status_errno;
3158
3159         usec_t start_timestamp;
3160         usec_t exit_timestamp;
3161
3162         int exit_code, exit_status;
3163
3164         usec_t condition_timestamp;
3165         bool condition_result;
3166         bool failed_condition_trigger;
3167         bool failed_condition_negate;
3168         const char *failed_condition;
3169         const char *failed_condition_parameter;
3170
3171         usec_t assert_timestamp;
3172         bool assert_result;
3173         bool failed_assert_trigger;
3174         bool failed_assert_negate;
3175         const char *failed_assert;
3176         const char *failed_assert_parameter;
3177
3178         /* Socket */
3179         unsigned n_accepted;
3180         unsigned n_connections;
3181         bool accept;
3182
3183         /* Pairs of type, path */
3184         char **listen;
3185
3186         /* Device */
3187         const char *sysfs_path;
3188
3189         /* Mount, Automount */
3190         const char *where;
3191
3192         /* Swap */
3193         const char *what;
3194
3195         /* CGroup */
3196         uint64_t memory_current;
3197         uint64_t memory_limit;
3198         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 #if defined(HAVE_SYSV_COMPAT) && defined(HAVE_CHKCONFIG)
5042         unsigned f = 0;
5043         _cleanup_lookup_paths_free_ LookupPaths paths = {};
5044
5045         if (arg_scope != UNIT_FILE_SYSTEM)
5046                 return 0;
5047
5048         if (!streq(verb, "enable") &&
5049             !streq(verb, "disable") &&
5050             !streq(verb, "is-enabled"))
5051                 return 0;
5052
5053         /* Processes all SysV units, and reshuffles the array so that
5054          * afterwards only the native units remain */
5055
5056         r = lookup_paths_init(&paths, SYSTEMD_SYSTEM, false, arg_root, NULL, NULL, NULL);
5057         if (r < 0)
5058                 return r;
5059
5060         r = 0;
5061         while (args[f]) {
5062                 const char *name;
5063                 _cleanup_free_ char *p = NULL, *q = NULL, *l = NULL;
5064                 bool found_native = false, found_sysv;
5065                 unsigned c = 1;
5066                 const char *argv[6] = { "/sbin/chkconfig", NULL, NULL, NULL, NULL };
5067                 char **k;
5068                 int j;
5069                 pid_t pid;
5070                 siginfo_t status;
5071
5072                 name = args[f++];
5073
5074                 if (!endswith(name, ".service"))
5075                         continue;
5076
5077                 if (path_is_absolute(name))
5078                         continue;
5079
5080                 STRV_FOREACH(k, paths.unit_path) {
5081                         _cleanup_free_ char *path = NULL;
5082
5083                         path = path_join(arg_root, *k, name);
5084                         if (!path)
5085                                 return log_oom();
5086
5087                         found_native = access(path, F_OK) >= 0;
5088                         if (found_native)
5089                                 break;
5090                 }
5091
5092                 if (found_native)
5093                         continue;
5094
5095                 p = path_join(arg_root, SYSTEM_SYSVINIT_PATH, name);
5096                 if (!p)
5097                         return log_oom();
5098
5099                 p[strlen(p) - strlen(".service")] = 0;
5100                 found_sysv = access(p, F_OK) >= 0;
5101                 if (!found_sysv)
5102                         continue;
5103
5104                 log_info("%s is not a native service, redirecting to /sbin/chkconfig.", name);
5105
5106                 if (!isempty(arg_root))
5107                         argv[c++] = q = strappend("--root=", arg_root);
5108
5109                 argv[c++] = basename(p);
5110                 argv[c++] =
5111                         streq(verb, "enable") ? "on" :
5112                         streq(verb, "disable") ? "off" : "--level=5";
5113                 argv[c] = NULL;
5114
5115                 l = strv_join((char**)argv, " ");
5116                 if (!l)
5117                         return log_oom();
5118
5119                 log_info("Executing %s", l);
5120
5121                 pid = fork();
5122                 if (pid < 0)
5123                         return log_error_errno(errno, "Failed to fork: %m");
5124                 else if (pid == 0) {
5125                         /* Child */
5126
5127                         execv(argv[0], (char**) argv);
5128                         _exit(EXIT_FAILURE);
5129                 }
5130
5131                 j = wait_for_terminate(pid, &status);
5132                 if (j < 0) {
5133                         log_error_errno(r, "Failed to wait for child: %m");
5134                         return j;
5135                 }
5136
5137                 if (status.si_code == CLD_EXITED) {
5138                         if (streq(verb, "is-enabled")) {
5139                                 if (status.si_status == 0) {
5140                                         if (!arg_quiet)
5141                                                 puts("enabled");
5142                                         r = 1;
5143                                 } else {
5144                                         if (!arg_quiet)
5145                                                 puts("disabled");
5146                                 }
5147
5148                         } else if (status.si_status != 0)
5149                                 return -EINVAL;
5150                 } else
5151                         return -EPROTO;
5152
5153                 /* Remove this entry, so that we don't try enabling it as native unit */
5154                 assert(f > 0);
5155                 f--;
5156                 assert(args[f] == name);
5157                 strv_remove(args, name);
5158         }
5159
5160 #endif
5161         return r;
5162 }
5163
5164 static int mangle_names(char **original_names, char ***mangled_names) {
5165         char **i, **l, **name;
5166
5167         l = new(char*, strv_length(original_names) + 1);
5168         if (!l)
5169                 return log_oom();
5170
5171         i = l;
5172         STRV_FOREACH(name, original_names) {
5173
5174                 /* When enabling units qualified path names are OK,
5175                  * too, hence allow them explicitly. */
5176
5177                 if (is_path(*name))
5178                         *i = strdup(*name);
5179                 else
5180                         *i = unit_name_mangle(*name, MANGLE_NOGLOB);
5181
5182                 if (!*i) {
5183                         strv_free(l);
5184                         return log_oom();
5185                 }
5186
5187                 i++;
5188         }
5189
5190         *i = NULL;
5191         *mangled_names = l;
5192
5193         return 0;
5194 }
5195
5196 static int enable_unit(sd_bus *bus, char **args) {
5197         _cleanup_strv_free_ char **names = NULL;
5198         const char *verb = args[0];
5199         UnitFileChange *changes = NULL;
5200         unsigned n_changes = 0;
5201         int carries_install_info = -1;
5202         int r;
5203
5204         if (!args[1])
5205                 return 0;
5206
5207         r = mangle_names(args+1, &names);
5208         if (r < 0)
5209                 return r;
5210
5211         r = enable_sysv_units(verb, names);
5212         if (r < 0)
5213                 return r;
5214
5215         /* If the operation was fully executed by the SysV compat,
5216          * let's finish early */
5217         if (strv_isempty(names))
5218                 return 0;
5219
5220         if (!bus || avoid_bus()) {
5221                 if (streq(verb, "enable")) {
5222                         r = unit_file_enable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5223                         carries_install_info = r;
5224                 } else if (streq(verb, "disable"))
5225                         r = unit_file_disable(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
5226                 else if (streq(verb, "reenable")) {
5227                         r = unit_file_reenable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5228                         carries_install_info = r;
5229                 } else if (streq(verb, "link"))
5230                         r = unit_file_link(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5231                 else if (streq(verb, "preset")) {
5232                         r = unit_file_preset(arg_scope, arg_runtime, arg_root, names, arg_preset_mode, arg_force, &changes, &n_changes);
5233                         carries_install_info = r;
5234                 } else if (streq(verb, "mask"))
5235                         r = unit_file_mask(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5236                 else if (streq(verb, "unmask"))
5237                         r = unit_file_unmask(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
5238                 else
5239                         assert_not_reached("Unknown verb");
5240
5241                 if (r < 0) {
5242                         log_error_errno(r, "Operation failed: %m");
5243                         goto finish;
5244                 }
5245
5246                 if (!arg_quiet)
5247                         dump_unit_file_changes(changes, n_changes);
5248
5249                 r = 0;
5250         } else {
5251                 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
5252                 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5253                 int expect_carries_install_info = false;
5254                 bool send_force = true, send_preset_mode = false;
5255                 const char *method;
5256
5257                 polkit_agent_open_if_enabled();
5258
5259                 if (streq(verb, "enable")) {
5260                         method = "EnableUnitFiles";
5261                         expect_carries_install_info = true;
5262                 } else if (streq(verb, "disable")) {
5263                         method = "DisableUnitFiles";
5264                         send_force = false;
5265                 } else if (streq(verb, "reenable")) {
5266                         method = "ReenableUnitFiles";
5267                         expect_carries_install_info = true;
5268                 } else if (streq(verb, "link"))
5269                         method = "LinkUnitFiles";
5270                 else if (streq(verb, "preset")) {
5271
5272                         if (arg_preset_mode != UNIT_FILE_PRESET_FULL) {
5273                                 method = "PresetUnitFilesWithMode";
5274                                 send_preset_mode = true;
5275                         } else
5276                                 method = "PresetUnitFiles";
5277
5278                         expect_carries_install_info = true;
5279                 } else if (streq(verb, "mask"))
5280                         method = "MaskUnitFiles";
5281                 else if (streq(verb, "unmask")) {
5282                         method = "UnmaskUnitFiles";
5283                         send_force = false;
5284                 } else
5285                         assert_not_reached("Unknown verb");
5286
5287                 r = sd_bus_message_new_method_call(
5288                                 bus,
5289                                 &m,
5290                                 "org.freedesktop.systemd1",
5291                                 "/org/freedesktop/systemd1",
5292                                 "org.freedesktop.systemd1.Manager",
5293                                 method);
5294                 if (r < 0)
5295                         return bus_log_create_error(r);
5296
5297                 r = sd_bus_message_append_strv(m, names);
5298                 if (r < 0)
5299                         return bus_log_create_error(r);
5300
5301                 if (send_preset_mode) {
5302                         r = sd_bus_message_append(m, "s", unit_file_preset_mode_to_string(arg_preset_mode));
5303                         if (r < 0)
5304                                 return bus_log_create_error(r);
5305                 }
5306
5307                 r = sd_bus_message_append(m, "b", arg_runtime);
5308                 if (r < 0)
5309                         return bus_log_create_error(r);
5310
5311                 if (send_force) {
5312                         r = sd_bus_message_append(m, "b", arg_force);
5313                         if (r < 0)
5314                                 return bus_log_create_error(r);
5315                 }
5316
5317                 r = sd_bus_call(bus, m, 0, &error, &reply);
5318                 if (r < 0) {
5319                         log_error("Failed to execute operation: %s", bus_error_message(&error, r));
5320                         return r;
5321                 }
5322
5323                 if (expect_carries_install_info) {
5324                         r = sd_bus_message_read(reply, "b", &carries_install_info);
5325                         if (r < 0)
5326                                 return bus_log_parse_error(r);
5327                 }
5328
5329                 r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet);
5330                 if (r < 0)
5331                         return r;
5332
5333                 /* Try to reload if enabled */
5334                 if (!arg_no_reload)
5335                         r = daemon_reload(bus, args);
5336                 else
5337                         r = 0;
5338         }
5339
5340         if (carries_install_info == 0)
5341                 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
5342                             "using systemctl.\n"
5343                             "Possible reasons for having this kind of units are:\n"
5344                             "1) A unit may be statically enabled by being symlinked from another unit's\n"
5345                             "   .wants/ or .requires/ directory.\n"
5346                             "2) A unit's purpose may be to act as a helper for some other unit which has\n"
5347                             "   a requirement dependency on it.\n"
5348                             "3) A unit may be started when needed via activation (socket, path, timer,\n"
5349                             "   D-Bus, udev, scripted systemctl call, ...).\n");
5350
5351 finish:
5352         unit_file_changes_free(changes, n_changes);
5353
5354         return r;
5355 }
5356
5357 static int add_dependency(sd_bus *bus, char **args) {
5358         _cleanup_strv_free_ char **names = NULL;
5359         _cleanup_free_ char *target = NULL;
5360         const char *verb = args[0];
5361         UnitDependency dep;
5362         int r = 0;
5363
5364         if (!args[1])
5365                 return 0;
5366
5367         target = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".target");
5368         if (!target)
5369                 return log_oom();
5370
5371         r = mangle_names(args+2, &names);
5372         if (r < 0)
5373                 return r;
5374
5375         if (streq(verb, "add-wants"))
5376                 dep = UNIT_WANTS;
5377         else if (streq(verb, "add-requires"))
5378                 dep = UNIT_REQUIRES;
5379         else
5380                 assert_not_reached("Unknown verb");
5381
5382         if (!bus || avoid_bus()) {
5383                 UnitFileChange *changes = NULL;
5384                 unsigned n_changes = 0;
5385
5386                 r = unit_file_add_dependency(arg_scope, arg_runtime, arg_root, names, target, dep, arg_force, &changes, &n_changes);
5387
5388                 if (r < 0)
5389                         return log_error_errno(r, "Can't add dependency: %m");
5390
5391                 if (!arg_quiet)
5392                         dump_unit_file_changes(changes, n_changes);
5393
5394                 unit_file_changes_free(changes, n_changes);
5395
5396         } else {
5397                 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
5398                 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5399
5400                 polkit_agent_open_if_enabled();
5401
5402                 r = sd_bus_message_new_method_call(
5403                                 bus,
5404                                 &m,
5405                                 "org.freedesktop.systemd1",
5406                                 "/org/freedesktop/systemd1",
5407                                 "org.freedesktop.systemd1.Manager",
5408                                 "AddDependencyUnitFiles");
5409                 if (r < 0)
5410                         return bus_log_create_error(r);
5411
5412                 r = sd_bus_message_append_strv(m, names);
5413                 if (r < 0)
5414                         return bus_log_create_error(r);
5415
5416                 r = sd_bus_message_append(m, "ssbb", target, unit_dependency_to_string(dep), arg_runtime, arg_force);
5417                 if (r < 0)
5418                         return bus_log_create_error(r);
5419
5420                 r = sd_bus_call(bus, m, 0, &error, &reply);
5421                 if (r < 0) {
5422                         log_error("Failed to execute operation: %s", bus_error_message(&error, r));
5423                         return r;
5424                 }
5425
5426                 r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet);
5427                 if (r < 0)
5428                         return r;
5429
5430                 if (!arg_no_reload)
5431                         r = daemon_reload(bus, args);
5432                 else
5433                         r = 0;
5434         }
5435
5436         return r;
5437 }
5438
5439 static int preset_all(sd_bus *bus, char **args) {
5440         UnitFileChange *changes = NULL;
5441         unsigned n_changes = 0;
5442         int r;
5443
5444         if (!bus || avoid_bus()) {
5445
5446                 r = unit_file_preset_all(arg_scope, arg_runtime, arg_root, arg_preset_mode, arg_force, &changes, &n_changes);
5447                 if (r < 0) {
5448                         log_error_errno(r, "Operation failed: %m");
5449                         goto finish;
5450                 }
5451
5452                 if (!arg_quiet)
5453                         dump_unit_file_changes(changes, n_changes);
5454
5455                 r = 0;
5456
5457         } else {
5458                 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5459                 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
5460
5461                 polkit_agent_open_if_enabled();
5462
5463                 r = sd_bus_call_method(
5464                                 bus,
5465                                 "org.freedesktop.systemd1",
5466                                 "/org/freedesktop/systemd1",
5467                                 "org.freedesktop.systemd1.Manager",
5468                                 "PresetAllUnitFiles",
5469                                 &error,
5470                                 &reply,
5471                                 "sbb",
5472                                 unit_file_preset_mode_to_string(arg_preset_mode),
5473                                 arg_runtime,
5474                                 arg_force);
5475                 if (r < 0) {
5476                         log_error("Failed to execute operation: %s", bus_error_message(&error, r));
5477                         return r;
5478                 }
5479
5480                 r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet);
5481                 if (r < 0)
5482                         return r;
5483
5484                 if (!arg_no_reload)
5485                         r = daemon_reload(bus, args);
5486                 else
5487                         r = 0;
5488         }
5489
5490 finish:
5491         unit_file_changes_free(changes, n_changes);
5492
5493         return r;
5494 }
5495
5496 static int unit_is_enabled(sd_bus *bus, char **args) {
5497
5498         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5499         _cleanup_strv_free_ char **names = NULL;
5500         bool enabled;
5501         char **name;
5502         int r;
5503
5504         r = mangle_names(args+1, &names);
5505         if (r < 0)
5506                 return r;
5507
5508         r = enable_sysv_units(args[0], names);
5509         if (r < 0)
5510                 return r;
5511
5512         enabled = r > 0;
5513
5514         if (!bus || avoid_bus()) {
5515
5516                 STRV_FOREACH(name, names) {
5517                         UnitFileState state;
5518
5519                         state = unit_file_get_state(arg_scope, arg_root, *name);
5520                         if (state < 0)
5521                                 return log_error_errno(state, "Failed to get unit file state for %s: %m", *name);
5522
5523                         if (state == UNIT_FILE_ENABLED ||
5524                             state == UNIT_FILE_ENABLED_RUNTIME ||
5525                             state == UNIT_FILE_STATIC ||
5526                             state == UNIT_FILE_INDIRECT)
5527                                 enabled = true;
5528
5529                         if (!arg_quiet)
5530                                 puts(unit_file_state_to_string(state));
5531                 }
5532
5533         } else {
5534                 STRV_FOREACH(name, names) {
5535                         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
5536                         const char *s;
5537
5538                         r = sd_bus_call_method(
5539                                         bus,
5540                                         "org.freedesktop.systemd1",
5541                                         "/org/freedesktop/systemd1",
5542                                         "org.freedesktop.systemd1.Manager",
5543                                         "GetUnitFileState",
5544                                         &error,
5545                                         &reply,
5546                                         "s", *name);
5547                         if (r < 0) {
5548                                 log_error("Failed to get unit file state for %s: %s", *name, bus_error_message(&error, r));
5549                                 return r;
5550                         }
5551
5552                         r = sd_bus_message_read(reply, "s", &s);
5553                         if (r < 0)
5554                                 return bus_log_parse_error(r);
5555
5556                         if (STR_IN_SET(s, "enabled", "enabled-runtime", "static", "indirect"))
5557                                 enabled = true;
5558
5559                         if (!arg_quiet)
5560                                 puts(s);
5561                 }
5562         }
5563
5564         return !enabled;
5565 }
5566
5567 static int is_system_running(sd_bus *bus, char **args) {
5568         _cleanup_free_ char *state = NULL;
5569         int r;
5570
5571         r = sd_bus_get_property_string(
5572                         bus,
5573                         "org.freedesktop.systemd1",
5574                         "/org/freedesktop/systemd1",
5575                         "org.freedesktop.systemd1.Manager",
5576                         "SystemState",
5577                         NULL,
5578                         &state);
5579         if (r < 0) {
5580                 if (!arg_quiet)
5581                         puts("unknown");
5582                 return 0;
5583         }
5584
5585         if (!arg_quiet)
5586                 puts(state);
5587
5588         return streq(state, "running") ? EXIT_SUCCESS : EXIT_FAILURE;
5589 }
5590
5591 static int create_edit_temp_file(const char *new_path, const char *original_path, char **ret_tmp_fn) {
5592         char *t;
5593         int r;
5594
5595         assert(new_path);
5596         assert(original_path);
5597         assert(ret_tmp_fn);
5598
5599         r = tempfn_random(new_path, &t);
5600         if (r < 0)
5601                 return log_error_errno(r, "Failed to determine temporary filename for \"%s\": %m", new_path);
5602
5603         r = mkdir_parents(new_path, 0755);
5604         if (r < 0) {
5605                 log_error_errno(r, "Failed to create directories for \"%s\": %m", new_path);
5606                 free(t);
5607                 return r;
5608         }
5609
5610         r = copy_file(original_path, t, 0, 0644, 0);
5611         if (r == -ENOENT) {
5612                 r = touch(t);
5613                 if (r < 0) {
5614                         log_error_errno(r, "Failed to create temporary file \"%s\": %m", t);
5615                         free(t);
5616                         return r;
5617                 }
5618         } else if (r < 0) {
5619                 log_error_errno(r, "Failed to copy \"%s\" to \"%s\": %m", original_path, t);
5620                 free(t);
5621                 return r;
5622         }
5623
5624         *ret_tmp_fn = t;
5625
5626         return 0;
5627 }
5628
5629 static int get_file_to_edit(const char *name, const char *user_home, const char *user_runtime, char **ret_path) {
5630         _cleanup_free_ char *path = NULL, *path2 = NULL, *run = NULL;
5631
5632         switch (arg_scope) {
5633                 case UNIT_FILE_SYSTEM:
5634                         path = path_join(arg_root, SYSTEM_CONFIG_UNIT_PATH, name);
5635                         if (arg_runtime)
5636                                 run = path_join(arg_root, "/run/systemd/system/", name);
5637                         break;
5638                 case UNIT_FILE_GLOBAL:
5639                         path = path_join(arg_root, USER_CONFIG_UNIT_PATH, name);
5640                         if (arg_runtime)
5641                                 run = path_join(arg_root, "/run/systemd/user/", name);
5642                         break;
5643                 case UNIT_FILE_USER:
5644                         assert(user_home);
5645                         assert(user_runtime);
5646
5647                         path = path_join(arg_root, user_home, name);
5648                         if (arg_runtime) {
5649                                 path2 = path_join(arg_root, USER_CONFIG_UNIT_PATH, name);
5650                                 if (!path2)
5651                                         return log_oom();
5652                                 run = path_join(arg_root, user_runtime, name);
5653                         }
5654                         break;
5655                 default:
5656                         assert_not_reached("Invalid scope");
5657         }
5658         if (!path || (arg_runtime && !run))
5659                 return log_oom();
5660
5661         if (arg_runtime) {
5662                 if (access(path, F_OK) >= 0)
5663                         return log_error_errno(EEXIST, "Refusing to create \"%s\" because it would be overriden by \"%s\" anyway.",
5664                                                run, path);
5665                 if (path2 && access(path2, F_OK) >= 0)
5666                         return log_error_errno(EEXIST, "Refusing to create \"%s\" because it would be overriden by \"%s\" anyway.",
5667                                                run, path2);
5668                 *ret_path = run;
5669                 run = NULL;
5670         } else {
5671                 *ret_path = path;
5672                 path = NULL;
5673         }
5674
5675         return 0;
5676 }
5677
5678 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) {
5679         char *tmp_new_path, *ending;
5680         char *tmp_tmp_path;
5681         int r;
5682
5683         assert(unit_name);
5684         assert(ret_new_path);
5685         assert(ret_tmp_path);
5686
5687         ending = strjoina(unit_name, ".d/override.conf");
5688         r = get_file_to_edit(ending, user_home, user_runtime, &tmp_new_path);
5689         if (r < 0)
5690                 return r;
5691
5692         r = create_edit_temp_file(tmp_new_path, tmp_new_path, &tmp_tmp_path);
5693         if (r < 0) {
5694                 free(tmp_new_path);
5695                 return r;
5696         }
5697
5698         *ret_new_path = tmp_new_path;
5699         *ret_tmp_path = tmp_tmp_path;
5700
5701         return 0;
5702 }
5703
5704 static int unit_file_create_copy(
5705                 const char *unit_name,
5706                 const char *fragment_path,
5707                 const char *user_home,
5708                 const char *user_runtime,
5709                 char **ret_new_path,
5710                 char **ret_tmp_path) {
5711
5712         char *tmp_new_path;
5713         char *tmp_tmp_path;
5714         int r;
5715
5716         assert(fragment_path);
5717         assert(unit_name);
5718         assert(ret_new_path);
5719         assert(ret_tmp_path);
5720
5721         r = get_file_to_edit(unit_name, user_home, user_runtime, &tmp_new_path);
5722         if (r < 0)
5723                 return r;
5724
5725         if (!path_equal(fragment_path, tmp_new_path) && access(tmp_new_path, F_OK) == 0) {
5726                 char response;
5727
5728                 r = ask_char(&response, "yn", "\"%s\" already exists. Overwrite with \"%s\"? [(y)es, (n)o] ", tmp_new_path, fragment_path);
5729                 if (r < 0) {
5730                         free(tmp_new_path);
5731                         return r;
5732                 }
5733                 if (response != 'y') {
5734                         log_warning("%s ignored", unit_name);
5735                         free(tmp_new_path);
5736                         return -1;
5737                 }
5738         }
5739
5740         r = create_edit_temp_file(tmp_new_path, fragment_path, &tmp_tmp_path);
5741         if (r < 0) {
5742                 log_error_errno(r, "Failed to create temporary file for \"%s\": %m", tmp_new_path);
5743                 free(tmp_new_path);
5744                 return r;
5745         }
5746
5747         *ret_new_path = tmp_new_path;
5748         *ret_tmp_path = tmp_tmp_path;
5749
5750         return 0;
5751 }
5752
5753 static int run_editor(char **paths) {
5754         pid_t pid;
5755         int r;
5756
5757         assert(paths);
5758
5759         pid = fork();
5760         if (pid < 0) {
5761                 log_error_errno(errno, "Failed to fork: %m");
5762                 return -errno;
5763         }
5764
5765         if (pid == 0) {
5766                 const char **args;
5767                 char *editor;
5768                 char **tmp_path, **original_path, *p;
5769                 unsigned i = 1;
5770                 size_t argc;
5771
5772                 argc = strv_length(paths)/2 + 1;
5773                 args = newa(const char*, argc + 1);
5774
5775                 args[0] = NULL;
5776                 STRV_FOREACH_PAIR(original_path, tmp_path, paths) {
5777                         args[i] = *tmp_path;
5778                         i++;
5779                 }
5780                 args[argc] = NULL;
5781
5782                 /* SYSTEMD_EDITOR takes precedence over EDITOR which takes precedence over VISUAL
5783                  * If neither SYSTEMD_EDITOR nor EDITOR nor VISUAL are present,
5784                  * we try to execute well known editors
5785                  */
5786                 editor = getenv("SYSTEMD_EDITOR");
5787                 if (!editor)
5788                         editor = getenv("EDITOR");
5789                 if (!editor)
5790                         editor = getenv("VISUAL");
5791
5792                 if (!isempty(editor)) {
5793                         args[0] = editor;
5794                         execvp(editor, (char* const*) args);
5795                 }
5796
5797                 FOREACH_STRING(p, "nano", "vim", "vi") {
5798                         args[0] = p;
5799                         execvp(p, (char* const*) args);
5800                         /* We do not fail if the editor doesn't exist
5801                          * because we want to try each one of them before
5802                          * failing.
5803                          */
5804                         if (errno != ENOENT) {
5805                                 log_error("Failed to execute %s: %m", editor);
5806                                 _exit(EXIT_FAILURE);
5807                         }
5808                 }
5809
5810                 log_error("Cannot edit unit(s), no editor available. Please set either $SYSTEMD_EDITOR, $EDITOR or $VISUAL.");
5811                 _exit(EXIT_FAILURE);
5812         }
5813
5814         r = wait_for_terminate_and_warn("editor", pid, true);
5815         if (r < 0)
5816                 return log_error_errno(r, "Failed to wait for child: %m");
5817
5818         return r;
5819 }
5820
5821 static int find_paths_to_edit(sd_bus *bus, char **names, char ***paths) {
5822         _cleanup_free_ char *user_home = NULL;
5823         _cleanup_free_ char *user_runtime = NULL;
5824         _cleanup_lookup_paths_free_ LookupPaths lp = {};
5825         bool avoid_bus_cache;
5826         char **name;
5827         int r;
5828
5829         assert(names);
5830         assert(paths);
5831
5832         r = init_home_and_lookup_paths(&user_home, &user_runtime, &lp);
5833         if (r < 0)
5834                 return r;
5835
5836         avoid_bus_cache = !bus || avoid_bus();
5837
5838         STRV_FOREACH(name, names) {
5839                 _cleanup_free_ char *path = NULL;
5840                 char *new_path, *tmp_path;
5841
5842                 r = unit_find_paths(bus, *name, avoid_bus_cache, &lp, &path, NULL);
5843                 if (r < 0)
5844                         return r;
5845                 else if (r == 0)
5846                         return -ENOENT;
5847                 else if (!path) {
5848                         // FIXME: support units with path==NULL (no FragmentPath)
5849                         log_error("No fragment exists for %s.", *name);
5850                         return -ENOENT;
5851                 }
5852
5853                 if (arg_full)
5854                         r = unit_file_create_copy(*name, path, user_home, user_runtime, &new_path, &tmp_path);
5855                 else
5856                         r = unit_file_create_dropin(*name, user_home, user_runtime, &new_path, &tmp_path);
5857                 if (r < 0)
5858                         return r;
5859
5860                 r = strv_push_pair(paths, new_path, tmp_path);
5861                 if (r < 0)
5862                         return log_oom();
5863         }
5864
5865         return 0;
5866 }
5867
5868 static int edit(sd_bus *bus, char **args) {
5869         _cleanup_strv_free_ char **names = NULL;
5870         _cleanup_strv_free_ char **paths = NULL;
5871         char **original, **tmp;
5872         int r;
5873
5874         assert(args);
5875
5876         if (!on_tty()) {
5877                 log_error("Cannot edit units if not on a tty");
5878                 return -EINVAL;
5879         }
5880
5881         if (arg_transport != BUS_TRANSPORT_LOCAL) {
5882                 log_error("Cannot remotely edit units");
5883                 return -EINVAL;
5884         }
5885
5886         r = expand_names(bus, args + 1, NULL, &names);
5887         if (r < 0)
5888                 return log_error_errno(r, "Failed to expand names: %m");
5889
5890         r = find_paths_to_edit(bus, names, &paths);
5891         if (r < 0)
5892                 return r;
5893
5894         if (strv_isempty(paths))
5895                 return -ENOENT;
5896
5897         r = run_editor(paths);
5898         if (r < 0)
5899                 goto end;
5900
5901         STRV_FOREACH_PAIR(original, tmp, paths) {
5902                 /* If the temporary file is empty we ignore it.
5903                  * It's useful if the user wants to cancel its modification
5904                  */
5905                 if (null_or_empty_path(*tmp)) {
5906                         log_warning("Editing \"%s\" canceled: temporary file is empty", *original);
5907                         continue;
5908                 }
5909                 r = rename(*tmp, *original);
5910                 if (r < 0) {
5911                         r = log_error_errno(errno, "Failed to rename \"%s\" to \"%s\": %m", *tmp, *original);
5912                         goto end;
5913                 }
5914         }
5915
5916         if (!arg_no_reload && bus && !avoid_bus())
5917                 r = daemon_reload(bus, args);
5918
5919 end:
5920         STRV_FOREACH_PAIR(original, tmp, paths)
5921                 unlink_noerrno(*tmp);
5922
5923         return r;
5924 }
5925
5926 static void systemctl_help(void) {
5927
5928         pager_open_if_enabled();
5929
5930         printf("%s [OPTIONS...] {COMMAND} ...\n\n"
5931                "Query or send control commands to the systemd manager.\n\n"
5932                "  -h --help           Show this help\n"
5933                "     --version        Show package version\n"
5934                "     --system         Connect to system manager\n"
5935                "     --user           Connect to user service manager\n"
5936                "  -H --host=[USER@]HOST\n"
5937                "                      Operate on remote host\n"
5938                "  -M --machine=CONTAINER\n"
5939                "                      Operate on local container\n"
5940                "  -t --type=TYPE      List units of a particular type\n"
5941                "     --state=STATE    List units with particular LOAD or SUB or ACTIVE state\n"
5942                "  -p --property=NAME  Show only properties by this name\n"
5943                "  -a --all            Show all loaded units/properties, including dead/empty\n"
5944                "                      ones. To list all units installed on the system, use\n"
5945                "                      the 'list-unit-files' command instead.\n"
5946                "  -l --full           Don't ellipsize unit names on output\n"
5947                "  -r --recursive      Show unit list of host and local containers\n"
5948                "     --reverse        Show reverse dependencies with 'list-dependencies'\n"
5949                "     --job-mode=MODE  Specify how to deal with already queued jobs, when\n"
5950                "                      queueing a new job\n"
5951                "     --show-types     When showing sockets, explicitly show their type\n"
5952                "  -i --ignore-inhibitors\n"
5953                "                      When shutting down or sleeping, ignore inhibitors\n"
5954                "     --kill-who=WHO   Who to send signal to\n"
5955                "  -s --signal=SIGNAL  Which signal to send\n"
5956                "  -q --quiet          Suppress output\n"
5957                "     --no-block       Do not wait until operation finished\n"
5958                "     --no-wall        Don't send wall message before halt/power-off/reboot\n"
5959                "     --no-reload      Don't reload daemon after en-/dis-abling unit files\n"
5960                "     --no-legend      Do not print a legend (column headers and hints)\n"
5961                "     --no-pager       Do not pipe output into a pager\n"
5962                "     --no-ask-password\n"
5963                "                      Do not ask for system passwords\n"
5964                "     --global         Enable/disable unit files globally\n"
5965                "     --runtime        Enable unit files only temporarily until next reboot\n"
5966                "  -f --force          When enabling unit files, override existing symlinks\n"
5967                "                      When shutting down, execute action immediately\n"
5968                "     --preset-mode=   Apply only enable, only disable, or all presets\n"
5969                "     --root=PATH      Enable unit files in the specified root directory\n"
5970                "  -n --lines=INTEGER  Number of journal entries to show\n"
5971                "  -o --output=STRING  Change journal output mode (short, short-iso,\n"
5972                "                              short-precise, short-monotonic, verbose,\n"
5973                "                              export, json, json-pretty, json-sse, cat)\n"
5974                "     --plain          Print unit dependencies as a list instead of a tree\n\n"
5975                "Unit Commands:\n"
5976                "  list-units [PATTERN...]         List loaded units\n"
5977                "  list-sockets [PATTERN...]       List loaded sockets ordered by address\n"
5978                "  list-timers [PATTERN...]        List loaded timers ordered by next elapse\n"
5979                "  start NAME...                   Start (activate) one or more units\n"
5980                "  stop NAME...                    Stop (deactivate) one or more units\n"
5981                "  reload NAME...                  Reload one or more units\n"
5982                "  restart NAME...                 Start or restart one or more units\n"
5983                "  try-restart NAME...             Restart one or more units if active\n"
5984                "  reload-or-restart NAME...       Reload one or more units if possible,\n"
5985                "                                  otherwise start or restart\n"
5986                "  reload-or-try-restart NAME...   Reload one or more units if possible,\n"
5987                "                                  otherwise restart if active\n"
5988                "  isolate NAME                    Start one unit and stop all others\n"
5989                "  kill NAME...                    Send signal to processes of a unit\n"
5990                "  is-active PATTERN...            Check whether units are active\n"
5991                "  is-failed PATTERN...            Check whether units are failed\n"
5992                "  status [PATTERN...|PID...]      Show runtime status of one or more units\n"
5993                "  show [PATTERN...|JOB...]        Show properties of one or more\n"
5994                "                                  units/jobs or the manager\n"
5995                "  cat PATTERN...                  Show files and drop-ins of one or more units\n"
5996                "  set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
5997                "  help PATTERN...|PID...          Show manual for one or more units\n"
5998                "  reset-failed [PATTERN...]       Reset failed state for all, one, or more\n"
5999                "                                  units\n"
6000                "  list-dependencies [NAME]        Recursively show units which are required\n"
6001                "                                  or wanted by this unit or by which this\n"
6002                "                                  unit is required or wanted\n\n"
6003                "Unit File Commands:\n"
6004                "  list-unit-files [PATTERN...]    List installed unit files\n"
6005                "  enable NAME...                  Enable one or more unit files\n"
6006                "  disable NAME...                 Disable one or more unit files\n"
6007                "  reenable NAME...                Reenable one or more unit files\n"
6008                "  preset NAME...                  Enable/disable one or more unit files\n"
6009                "                                  based on preset configuration\n"
6010                "  preset-all                      Enable/disable all unit files based on\n"
6011                "                                  preset configuration\n"
6012                "  is-enabled NAME...              Check whether unit files are enabled\n"
6013                "  mask NAME...                    Mask one or more units\n"
6014                "  unmask NAME...                  Unmask one or more units\n"
6015                "  link PATH...                    Link one or more units files into\n"
6016                "                                  the search path\n"
6017                "  add-wants TARGET NAME...        Add 'Wants' dependency for the target\n"
6018                "                                  on specified one or more units\n"
6019                "  add-requires TARGET NAME...     Add 'Requires' dependency for the target\n"
6020                "                                  on specified one or more units\n"
6021                "  edit NAME...                    Edit one or more unit files\n"
6022                "  get-default                     Get the name of the default target\n"
6023                "  set-default NAME                Set the default target\n\n"
6024                "Machine Commands:\n"
6025                "  list-machines [PATTERN...]      List local containers and host\n\n"
6026                "Job Commands:\n"
6027                "  list-jobs [PATTERN...]          List jobs\n"
6028                "  cancel [JOB...]                 Cancel all, one, or more jobs\n\n"
6029                "Snapshot Commands:\n"
6030                "  snapshot [NAME]                 Create a snapshot\n"
6031                "  delete NAME...                  Remove one or more snapshots\n\n"
6032                "Environment Commands:\n"
6033                "  show-environment                Dump environment\n"
6034                "  set-environment NAME=VALUE...   Set one or more environment variables\n"
6035                "  unset-environment NAME...       Unset one or more environment variables\n"
6036                "  import-environment [NAME...]    Import all or some environment variables\n\n"
6037                "Manager Lifecycle Commands:\n"
6038                "  daemon-reload                   Reload systemd manager configuration\n"
6039                "  daemon-reexec                   Reexecute systemd manager\n\n"
6040                "System Commands:\n"
6041                "  is-system-running               Check whether system is fully running\n"
6042                "  default                         Enter system default mode\n"
6043                "  rescue                          Enter system rescue mode\n"
6044                "  emergency                       Enter system emergency mode\n"
6045                "  halt                            Shut down and halt the system\n"
6046                "  poweroff                        Shut down and power-off the system\n"
6047                "  reboot [ARG]                    Shut down and reboot the system\n"
6048                "  kexec                           Shut down and reboot the system with kexec\n"
6049                "  exit                            Request user instance exit\n"
6050                "  switch-root ROOT [INIT]         Change to a different root file system\n"
6051                "  suspend                         Suspend the system\n"
6052                "  hibernate                       Hibernate the system\n"
6053                "  hybrid-sleep                    Hibernate and suspend the system\n",
6054                program_invocation_short_name);
6055 }
6056
6057 static void halt_help(void) {
6058         printf("%s [OPTIONS...]%s\n\n"
6059                "%s the system.\n\n"
6060                "     --help      Show this help\n"
6061                "     --halt      Halt the machine\n"
6062                "  -p --poweroff  Switch off the machine\n"
6063                "     --reboot    Reboot the machine\n"
6064                "  -f --force     Force immediate halt/power-off/reboot\n"
6065                "  -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
6066                "  -d --no-wtmp   Don't write wtmp record\n"
6067                "     --no-wall   Don't send wall message before halt/power-off/reboot\n",
6068                program_invocation_short_name,
6069                arg_action == ACTION_REBOOT   ? " [ARG]" : "",
6070                arg_action == ACTION_REBOOT   ? "Reboot" :
6071                arg_action == ACTION_POWEROFF ? "Power off" :
6072                                                "Halt");
6073 }
6074
6075 static void shutdown_help(void) {
6076         printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
6077                "Shut down the system.\n\n"
6078                "     --help      Show this help\n"
6079                "  -H --halt      Halt the machine\n"
6080                "  -P --poweroff  Power-off the machine\n"
6081                "  -r --reboot    Reboot the machine\n"
6082                "  -h             Equivalent to --poweroff, overridden by --halt\n"
6083                "  -k             Don't halt/power-off/reboot, just send warnings\n"
6084                "     --no-wall   Don't send wall message before halt/power-off/reboot\n"
6085                "  -c             Cancel a pending shutdown\n",
6086                program_invocation_short_name);
6087 }
6088
6089 static void telinit_help(void) {
6090         printf("%s [OPTIONS...] {COMMAND}\n\n"
6091                "Send control commands to the init daemon.\n\n"
6092                "     --help      Show this help\n"
6093                "     --no-wall   Don't send wall message before halt/power-off/reboot\n\n"
6094                "Commands:\n"
6095                "  0              Power-off the machine\n"
6096                "  6              Reboot the machine\n"
6097                "  2, 3, 4, 5     Start runlevelX.target unit\n"
6098                "  1, s, S        Enter rescue mode\n"
6099                "  q, Q           Reload init daemon configuration\n"
6100                "  u, U           Reexecute init daemon\n",
6101                program_invocation_short_name);
6102 }
6103
6104 static void runlevel_help(void) {
6105         printf("%s [OPTIONS...]\n\n"
6106                "Prints the previous and current runlevel of the init system.\n\n"
6107                "     --help      Show this help\n",
6108                program_invocation_short_name);
6109 }
6110
6111 static void help_types(void) {
6112         int i;
6113         const char *t;
6114
6115         if (!arg_no_legend)
6116                 puts("Available unit types:");
6117         for (i = 0; i < _UNIT_TYPE_MAX; i++) {
6118                 t = unit_type_to_string(i);
6119                 if (t)
6120                         puts(t);
6121         }
6122 }
6123
6124 static int systemctl_parse_argv(int argc, char *argv[]) {
6125
6126         enum {
6127                 ARG_FAIL = 0x100,
6128                 ARG_REVERSE,
6129                 ARG_AFTER,
6130                 ARG_BEFORE,
6131                 ARG_SHOW_TYPES,
6132                 ARG_IRREVERSIBLE,
6133                 ARG_IGNORE_DEPENDENCIES,
6134                 ARG_VERSION,
6135                 ARG_USER,
6136                 ARG_SYSTEM,
6137                 ARG_GLOBAL,
6138                 ARG_NO_BLOCK,
6139                 ARG_NO_LEGEND,
6140                 ARG_NO_PAGER,
6141                 ARG_NO_WALL,
6142                 ARG_ROOT,
6143                 ARG_NO_RELOAD,
6144                 ARG_KILL_WHO,
6145                 ARG_NO_ASK_PASSWORD,
6146                 ARG_FAILED,
6147                 ARG_RUNTIME,
6148                 ARG_FORCE,
6149                 ARG_PLAIN,
6150                 ARG_STATE,
6151                 ARG_JOB_MODE,
6152                 ARG_PRESET_MODE,
6153         };
6154
6155         static const struct option options[] = {
6156                 { "help",                no_argument,       NULL, 'h'                     },
6157                 { "version",             no_argument,       NULL, ARG_VERSION             },
6158                 { "type",                required_argument, NULL, 't'                     },
6159                 { "property",            required_argument, NULL, 'p'                     },
6160                 { "all",                 no_argument,       NULL, 'a'                     },
6161                 { "reverse",             no_argument,       NULL, ARG_REVERSE             },
6162                 { "after",               no_argument,       NULL, ARG_AFTER               },
6163                 { "before",              no_argument,       NULL, ARG_BEFORE              },
6164                 { "show-types",          no_argument,       NULL, ARG_SHOW_TYPES          },
6165                 { "failed",              no_argument,       NULL, ARG_FAILED              }, /* compatibility only */
6166                 { "full",                no_argument,       NULL, 'l'                     },
6167                 { "job-mode",            required_argument, NULL, ARG_JOB_MODE            },
6168                 { "fail",                no_argument,       NULL, ARG_FAIL                }, /* compatibility only */
6169                 { "irreversible",        no_argument,       NULL, ARG_IRREVERSIBLE        }, /* compatibility only */
6170                 { "ignore-dependencies", no_argument,       NULL, ARG_IGNORE_DEPENDENCIES }, /* compatibility only */
6171                 { "ignore-inhibitors",   no_argument,       NULL, 'i'                     },
6172                 { "user",                no_argument,       NULL, ARG_USER                },
6173                 { "system",              no_argument,       NULL, ARG_SYSTEM              },
6174                 { "global",              no_argument,       NULL, ARG_GLOBAL              },
6175                 { "no-block",            no_argument,       NULL, ARG_NO_BLOCK            },
6176                 { "no-legend",           no_argument,       NULL, ARG_NO_LEGEND           },
6177                 { "no-pager",            no_argument,       NULL, ARG_NO_PAGER            },
6178                 { "no-wall",             no_argument,       NULL, ARG_NO_WALL             },
6179                 { "quiet",               no_argument,       NULL, 'q'                     },
6180                 { "root",                required_argument, NULL, ARG_ROOT                },
6181                 { "force",               no_argument,       NULL, ARG_FORCE               },
6182                 { "no-reload",           no_argument,       NULL, ARG_NO_RELOAD           },
6183                 { "kill-who",            required_argument, NULL, ARG_KILL_WHO            },
6184                 { "signal",              required_argument, NULL, 's'                     },
6185                 { "no-ask-password",     no_argument,       NULL, ARG_NO_ASK_PASSWORD     },
6186                 { "host",                required_argument, NULL, 'H'                     },
6187                 { "machine",             required_argument, NULL, 'M'                     },
6188                 { "runtime",             no_argument,       NULL, ARG_RUNTIME             },
6189                 { "lines",               required_argument, NULL, 'n'                     },
6190                 { "output",              required_argument, NULL, 'o'                     },
6191                 { "plain",               no_argument,       NULL, ARG_PLAIN               },
6192                 { "state",               required_argument, NULL, ARG_STATE               },
6193                 { "recursive",           no_argument,       NULL, 'r'                     },
6194                 { "preset-mode",         required_argument, NULL, ARG_PRESET_MODE         },
6195                 {}
6196         };
6197
6198         int c;
6199
6200         assert(argc >= 0);
6201         assert(argv);
6202
6203         while ((c = getopt_long(argc, argv, "ht:p:alqfs:H:M:n:o:ir", options, NULL)) >= 0)
6204
6205                 switch (c) {
6206
6207                 case 'h':
6208                         systemctl_help();
6209                         return 0;
6210
6211                 case ARG_VERSION:
6212                         puts(PACKAGE_STRING);
6213                         puts(SYSTEMD_FEATURES);
6214                         return 0;
6215
6216                 case 't': {
6217                         const char *word, *state;
6218                         size_t size;
6219
6220                         FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
6221                                 _cleanup_free_ char *type;
6222
6223                                 type = strndup(word, size);
6224                                 if (!type)
6225                                         return -ENOMEM;
6226
6227                                 if (streq(type, "help")) {
6228                                         help_types();
6229                                         return 0;
6230                                 }
6231
6232                                 if (unit_type_from_string(type) >= 0) {
6233                                         if (strv_push(&arg_types, type))
6234                                                 return log_oom();
6235                                         type = NULL;
6236                                         continue;
6237                                 }
6238
6239                                 /* It's much nicer to use --state= for
6240                                  * load states, but let's support this
6241                                  * in --types= too for compatibility
6242                                  * with old versions */
6243                                 if (unit_load_state_from_string(optarg) >= 0) {
6244                                         if (strv_push(&arg_states, type) < 0)
6245                                                 return log_oom();
6246                                         type = NULL;
6247                                         continue;
6248                                 }
6249
6250                                 log_error("Unknown unit type or load state '%s'.", type);
6251                                 log_info("Use -t help to see a list of allowed values.");
6252                                 return -EINVAL;
6253                         }
6254
6255                         break;
6256                 }
6257
6258                 case 'p': {
6259                         /* Make sure that if the empty property list
6260                            was specified, we won't show any properties. */
6261                         if (isempty(optarg) && !arg_properties) {
6262                                 arg_properties = new0(char*, 1);
6263                                 if (!arg_properties)
6264                                         return log_oom();
6265                         } else {
6266                                 const char *word, *state;
6267                                 size_t size;
6268
6269                                 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
6270                                         char *prop;
6271
6272                                         prop = strndup(word, size);
6273                                         if (!prop)
6274                                                 return log_oom();
6275
6276                                         if (strv_consume(&arg_properties, prop) < 0)
6277                                                 return log_oom();
6278                                 }
6279                         }
6280
6281                         /* If the user asked for a particular
6282                          * property, show it to him, even if it is
6283                          * empty. */
6284                         arg_all = true;
6285
6286                         break;
6287                 }
6288
6289                 case 'a':
6290                         arg_all = true;
6291                         break;
6292
6293                 case ARG_REVERSE:
6294                         arg_dependency = DEPENDENCY_REVERSE;
6295                         break;
6296
6297                 case ARG_AFTER:
6298                         arg_dependency = DEPENDENCY_AFTER;
6299                         break;
6300
6301                 case ARG_BEFORE:
6302                         arg_dependency = DEPENDENCY_BEFORE;
6303                         break;
6304
6305                 case ARG_SHOW_TYPES:
6306                         arg_show_types = true;
6307                         break;
6308
6309                 case ARG_JOB_MODE:
6310                         arg_job_mode = optarg;
6311                         break;
6312
6313                 case ARG_FAIL:
6314                         arg_job_mode = "fail";
6315                         break;
6316
6317                 case ARG_IRREVERSIBLE:
6318                         arg_job_mode = "replace-irreversibly";
6319                         break;
6320
6321                 case ARG_IGNORE_DEPENDENCIES:
6322                         arg_job_mode = "ignore-dependencies";
6323                         break;
6324
6325                 case ARG_USER:
6326                         arg_scope = UNIT_FILE_USER;
6327                         break;
6328
6329                 case ARG_SYSTEM:
6330                         arg_scope = UNIT_FILE_SYSTEM;
6331                         break;
6332
6333                 case ARG_GLOBAL:
6334                         arg_scope = UNIT_FILE_GLOBAL;
6335                         break;
6336
6337                 case ARG_NO_BLOCK:
6338                         arg_no_block = true;
6339                         break;
6340
6341                 case ARG_NO_LEGEND:
6342                         arg_no_legend = true;
6343                         break;
6344
6345                 case ARG_NO_PAGER:
6346                         arg_no_pager = true;
6347                         break;
6348
6349                 case ARG_NO_WALL:
6350                         arg_no_wall = true;
6351                         break;
6352
6353                 case ARG_ROOT:
6354                         arg_root = optarg;
6355                         break;
6356
6357                 case 'l':
6358                         arg_full = true;
6359                         break;
6360
6361                 case ARG_FAILED:
6362                         if (strv_extend(&arg_states, "failed") < 0)
6363                                 return log_oom();
6364
6365                         break;
6366
6367                 case 'q':
6368                         arg_quiet = true;
6369                         break;
6370
6371                 case ARG_FORCE:
6372                         arg_force ++;
6373                         break;
6374
6375                 case 'f':
6376                         arg_force ++;
6377                         break;
6378
6379                 case ARG_NO_RELOAD:
6380                         arg_no_reload = true;
6381                         break;
6382
6383                 case ARG_KILL_WHO:
6384                         arg_kill_who = optarg;
6385                         break;
6386
6387                 case 's':
6388                         if ((arg_signal = signal_from_string_try_harder(optarg)) < 0) {
6389                                 log_error("Failed to parse signal string %s.", optarg);
6390                                 return -EINVAL;
6391                         }
6392                         break;
6393
6394                 case ARG_NO_ASK_PASSWORD:
6395                         arg_ask_password = false;
6396                         break;
6397
6398                 case 'H':
6399                         arg_transport = BUS_TRANSPORT_REMOTE;
6400                         arg_host = optarg;
6401                         break;
6402
6403                 case 'M':
6404                         arg_transport = BUS_TRANSPORT_MACHINE;
6405                         arg_host = optarg;
6406                         break;
6407
6408                 case ARG_RUNTIME:
6409                         arg_runtime = true;
6410                         break;
6411
6412                 case 'n':
6413                         if (safe_atou(optarg, &arg_lines) < 0) {
6414                                 log_error("Failed to parse lines '%s'", optarg);
6415                                 return -EINVAL;
6416                         }
6417                         break;
6418
6419                 case 'o':
6420                         arg_output = output_mode_from_string(optarg);
6421                         if (arg_output < 0) {
6422                                 log_error("Unknown output '%s'.", optarg);
6423                                 return -EINVAL;
6424                         }
6425                         break;
6426
6427                 case 'i':
6428                         arg_ignore_inhibitors = true;
6429                         break;
6430
6431                 case ARG_PLAIN:
6432                         arg_plain = true;
6433                         break;
6434
6435                 case ARG_STATE: {
6436                         const char *word, *state;
6437                         size_t size;
6438
6439                         FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
6440                                 char *s;
6441
6442                                 s = strndup(word, size);
6443                                 if (!s)
6444                                         return log_oom();
6445
6446                                 if (strv_consume(&arg_states, s) < 0)
6447                                         return log_oom();
6448                         }
6449                         break;
6450                 }
6451
6452                 case 'r':
6453                         if (geteuid() != 0) {
6454                                 log_error("--recursive requires root privileges.");
6455                                 return -EPERM;
6456                         }
6457
6458                         arg_recursive = true;
6459                         break;
6460
6461                 case ARG_PRESET_MODE:
6462
6463                         arg_preset_mode = unit_file_preset_mode_from_string(optarg);
6464                         if (arg_preset_mode < 0) {
6465                                 log_error("Failed to parse preset mode: %s.", optarg);
6466                                 return -EINVAL;
6467                         }
6468
6469                         break;
6470
6471                 case '?':
6472                         return -EINVAL;
6473
6474                 default:
6475                         assert_not_reached("Unhandled option");
6476                 }
6477
6478         if (arg_transport != BUS_TRANSPORT_LOCAL && arg_scope != UNIT_FILE_SYSTEM) {
6479                 log_error("Cannot access user instance remotely.");
6480                 return -EINVAL;
6481         }
6482
6483         return 1;
6484 }
6485
6486 static int halt_parse_argv(int argc, char *argv[]) {
6487
6488         enum {
6489                 ARG_HELP = 0x100,
6490                 ARG_HALT,
6491                 ARG_REBOOT,
6492                 ARG_NO_WALL
6493         };
6494
6495         static const struct option options[] = {
6496                 { "help",      no_argument,       NULL, ARG_HELP    },
6497                 { "halt",      no_argument,       NULL, ARG_HALT    },
6498                 { "poweroff",  no_argument,       NULL, 'p'         },
6499                 { "reboot",    no_argument,       NULL, ARG_REBOOT  },
6500                 { "force",     no_argument,       NULL, 'f'         },
6501                 { "wtmp-only", no_argument,       NULL, 'w'         },
6502                 { "no-wtmp",   no_argument,       NULL, 'd'         },
6503                 { "no-wall",   no_argument,       NULL, ARG_NO_WALL },
6504                 {}
6505         };
6506
6507         int c, r, runlevel;
6508
6509         assert(argc >= 0);
6510         assert(argv);
6511
6512         if (utmp_get_runlevel(&runlevel, NULL) >= 0)
6513                 if (runlevel == '0' || runlevel == '6')
6514                         arg_force = 2;
6515
6516         while ((c = getopt_long(argc, argv, "pfwdnih", options, NULL)) >= 0)
6517                 switch (c) {
6518
6519                 case ARG_HELP:
6520                         halt_help();
6521                         return 0;
6522
6523                 case ARG_HALT:
6524                         arg_action = ACTION_HALT;
6525                         break;
6526
6527                 case 'p':
6528                         if (arg_action != ACTION_REBOOT)
6529                                 arg_action = ACTION_POWEROFF;
6530                         break;
6531
6532                 case ARG_REBOOT:
6533                         arg_action = ACTION_REBOOT;
6534                         break;
6535
6536                 case 'f':
6537                         arg_force = 2;
6538                         break;
6539
6540                 case 'w':
6541                         arg_dry = true;
6542                         break;
6543
6544                 case 'd':
6545                         arg_no_wtmp = true;
6546                         break;
6547
6548                 case ARG_NO_WALL:
6549                         arg_no_wall = true;
6550                         break;
6551
6552                 case 'i':
6553                 case 'h':
6554                 case 'n':
6555                         /* Compatibility nops */
6556                         break;
6557
6558                 case '?':
6559                         return -EINVAL;
6560
6561                 default:
6562                         assert_not_reached("Unhandled option");
6563                 }
6564
6565         if (arg_action == ACTION_REBOOT && (argc == optind || argc == optind + 1)) {
6566                 r = update_reboot_param_file(argc == optind + 1 ? argv[optind] : NULL);
6567                 if (r < 0)
6568                         return r;
6569         } else if (optind < argc) {
6570                 log_error("Too many arguments.");
6571                 return -EINVAL;
6572         }
6573
6574         return 1;
6575 }
6576
6577 static int parse_time_spec(const char *t, usec_t *_u) {
6578         assert(t);
6579         assert(_u);
6580
6581         if (streq(t, "now"))
6582                 *_u = 0;
6583         else if (!strchr(t, ':')) {
6584                 uint64_t u;
6585
6586                 if (safe_atou64(t, &u) < 0)
6587                         return -EINVAL;
6588
6589                 *_u = now(CLOCK_REALTIME) + USEC_PER_MINUTE * u;
6590         } else {
6591                 char *e = NULL;
6592                 long hour, minute;
6593                 struct tm tm = {};
6594                 time_t s;
6595                 usec_t n;
6596
6597                 errno = 0;
6598                 hour = strtol(t, &e, 10);
6599                 if (errno > 0 || *e != ':' || hour < 0 || hour > 23)
6600                         return -EINVAL;
6601
6602                 minute = strtol(e+1, &e, 10);
6603                 if (errno > 0 || *e != 0 || minute < 0 || minute > 59)
6604                         return -EINVAL;
6605
6606                 n = now(CLOCK_REALTIME);
6607                 s = (time_t) (n / USEC_PER_SEC);
6608
6609                 assert_se(localtime_r(&s, &tm));
6610
6611                 tm.tm_hour = (int) hour;
6612                 tm.tm_min = (int) minute;
6613                 tm.tm_sec = 0;
6614
6615                 assert_se(s = mktime(&tm));
6616
6617                 *_u = (usec_t) s * USEC_PER_SEC;
6618
6619                 while (*_u <= n)
6620                         *_u += USEC_PER_DAY;
6621         }
6622
6623         return 0;
6624 }
6625
6626 static int shutdown_parse_argv(int argc, char *argv[]) {
6627
6628         enum {
6629                 ARG_HELP = 0x100,
6630                 ARG_NO_WALL
6631         };
6632
6633         static const struct option options[] = {
6634                 { "help",      no_argument,       NULL, ARG_HELP    },
6635                 { "halt",      no_argument,       NULL, 'H'         },
6636                 { "poweroff",  no_argument,       NULL, 'P'         },
6637                 { "reboot",    no_argument,       NULL, 'r'         },
6638                 { "kexec",     no_argument,       NULL, 'K'         }, /* not documented extension */
6639                 { "no-wall",   no_argument,       NULL, ARG_NO_WALL },
6640                 {}
6641         };
6642
6643         int c, r;
6644
6645         assert(argc >= 0);
6646         assert(argv);
6647
6648         while ((c = getopt_long(argc, argv, "HPrhkKt:afFc", options, NULL)) >= 0)
6649                 switch (c) {
6650
6651                 case ARG_HELP:
6652                         shutdown_help();
6653                         return 0;
6654
6655                 case 'H':
6656                         arg_action = ACTION_HALT;
6657                         break;
6658
6659                 case 'P':
6660                         arg_action = ACTION_POWEROFF;
6661                         break;
6662
6663                 case 'r':
6664                         if (kexec_loaded())
6665                                 arg_action = ACTION_KEXEC;
6666                         else
6667                                 arg_action = ACTION_REBOOT;
6668                         break;
6669
6670                 case 'K':
6671                         arg_action = ACTION_KEXEC;
6672                         break;
6673
6674                 case 'h':
6675                         if (arg_action != ACTION_HALT)
6676                                 arg_action = ACTION_POWEROFF;
6677                         break;
6678
6679                 case 'k':
6680                         arg_dry = true;
6681                         break;
6682
6683                 case ARG_NO_WALL:
6684                         arg_no_wall = true;
6685                         break;
6686
6687                 case 't':
6688                 case 'a':
6689                 case 'f':
6690                 case 'F':
6691                         /* Compatibility nops */
6692                         break;
6693
6694                 case 'c':
6695                         arg_action = ACTION_CANCEL_SHUTDOWN;
6696                         break;
6697
6698                 case '?':
6699                         return -EINVAL;
6700
6701                 default:
6702                         assert_not_reached("Unhandled option");
6703                 }
6704
6705         if (argc > optind && arg_action != ACTION_CANCEL_SHUTDOWN) {
6706                 r = parse_time_spec(argv[optind], &arg_when);
6707                 if (r < 0) {
6708                         log_error("Failed to parse time specification: %s", argv[optind]);
6709                         return r;
6710                 }
6711         } else
6712                 arg_when = now(CLOCK_REALTIME) + USEC_PER_MINUTE;
6713
6714         if (argc > optind && arg_action == ACTION_CANCEL_SHUTDOWN)
6715                 /* No time argument for shutdown cancel */
6716                 arg_wall = argv + optind;
6717         else if (argc > optind + 1)
6718                 /* We skip the time argument */
6719                 arg_wall = argv + optind + 1;
6720
6721         optind = argc;
6722
6723         return 1;
6724 }
6725
6726 static int telinit_parse_argv(int argc, char *argv[]) {
6727
6728         enum {
6729                 ARG_HELP = 0x100,
6730                 ARG_NO_WALL
6731         };
6732
6733         static const struct option options[] = {
6734                 { "help",      no_argument,       NULL, ARG_HELP    },
6735                 { "no-wall",   no_argument,       NULL, ARG_NO_WALL },
6736                 {}
6737         };
6738
6739         static const struct {
6740                 char from;
6741                 enum action to;
6742         } table[] = {
6743                 { '0', ACTION_POWEROFF },
6744                 { '6', ACTION_REBOOT },
6745                 { '1', ACTION_RESCUE },
6746                 { '2', ACTION_RUNLEVEL2 },
6747                 { '3', ACTION_RUNLEVEL3 },
6748                 { '4', ACTION_RUNLEVEL4 },
6749                 { '5', ACTION_RUNLEVEL5 },
6750                 { 's', ACTION_RESCUE },
6751                 { 'S', ACTION_RESCUE },
6752                 { 'q', ACTION_RELOAD },
6753                 { 'Q', ACTION_RELOAD },
6754                 { 'u', ACTION_REEXEC },
6755                 { 'U', ACTION_REEXEC }
6756         };
6757
6758         unsigned i;
6759         int c;
6760
6761         assert(argc >= 0);
6762         assert(argv);
6763
6764         while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0)
6765                 switch (c) {
6766
6767                 case ARG_HELP:
6768                         telinit_help();
6769                         return 0;
6770
6771                 case ARG_NO_WALL:
6772                         arg_no_wall = true;
6773                         break;
6774
6775                 case '?':
6776                         return -EINVAL;
6777
6778                 default:
6779                         assert_not_reached("Unhandled option");
6780                 }
6781
6782         if (optind >= argc) {
6783                 log_error("%s: required argument missing.",
6784                           program_invocation_short_name);
6785                 return -EINVAL;
6786         }
6787
6788         if (optind + 1 < argc) {
6789                 log_error("Too many arguments.");
6790                 return -EINVAL;
6791         }
6792
6793         if (strlen(argv[optind]) != 1) {
6794                 log_error("Expected single character argument.");
6795                 return -EINVAL;
6796         }
6797
6798         for (i = 0; i < ELEMENTSOF(table); i++)
6799                 if (table[i].from == argv[optind][0])
6800                         break;
6801
6802         if (i >= ELEMENTSOF(table)) {
6803                 log_error("Unknown command '%s'.", argv[optind]);
6804                 return -EINVAL;
6805         }
6806
6807         arg_action = table[i].to;
6808
6809         optind ++;
6810
6811         return 1;
6812 }
6813
6814 static int runlevel_parse_argv(int argc, char *argv[]) {
6815
6816         enum {
6817                 ARG_HELP = 0x100,
6818         };
6819
6820         static const struct option options[] = {
6821                 { "help",      no_argument,       NULL, ARG_HELP    },
6822                 {}
6823         };
6824
6825         int c;
6826
6827         assert(argc >= 0);
6828         assert(argv);
6829
6830         while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0)
6831                 switch (c) {
6832
6833                 case ARG_HELP:
6834                         runlevel_help();
6835                         return 0;
6836
6837                 case '?':
6838                         return -EINVAL;
6839
6840                 default:
6841                         assert_not_reached("Unhandled option");
6842                 }
6843
6844         if (optind < argc) {
6845                 log_error("Too many arguments.");
6846                 return -EINVAL;
6847         }
6848
6849         return 1;
6850 }
6851
6852 static int parse_argv(int argc, char *argv[]) {
6853         assert(argc >= 0);
6854         assert(argv);
6855
6856         if (program_invocation_short_name) {
6857
6858                 if (strstr(program_invocation_short_name, "halt")) {
6859                         arg_action = ACTION_HALT;
6860                         return halt_parse_argv(argc, argv);
6861                 } else if (strstr(program_invocation_short_name, "poweroff")) {
6862                         arg_action = ACTION_POWEROFF;
6863                         return halt_parse_argv(argc, argv);
6864                 } else if (strstr(program_invocation_short_name, "reboot")) {
6865                         if (kexec_loaded())
6866                                 arg_action = ACTION_KEXEC;
6867                         else
6868                                 arg_action = ACTION_REBOOT;
6869                         return halt_parse_argv(argc, argv);
6870                 } else if (strstr(program_invocation_short_name, "shutdown")) {
6871                         arg_action = ACTION_POWEROFF;
6872                         return shutdown_parse_argv(argc, argv);
6873                 } else if (strstr(program_invocation_short_name, "init")) {
6874
6875                         if (sd_booted() > 0) {
6876                                 arg_action = _ACTION_INVALID;
6877                                 return telinit_parse_argv(argc, argv);
6878                         } else {
6879                                 /* Hmm, so some other init system is
6880                                  * running, we need to forward this
6881                                  * request to it. For now we simply
6882                                  * guess that it is Upstart. */
6883
6884                                 execv(TELINIT, argv);
6885
6886                                 log_error("Couldn't find an alternative telinit implementation to spawn.");
6887                                 return -EIO;
6888                         }
6889
6890                 } else if (strstr(program_invocation_short_name, "runlevel")) {
6891                         arg_action = ACTION_RUNLEVEL;
6892                         return runlevel_parse_argv(argc, argv);
6893                 }
6894         }
6895
6896         arg_action = ACTION_SYSTEMCTL;
6897         return systemctl_parse_argv(argc, argv);
6898 }
6899
6900 _pure_ static int action_to_runlevel(void) {
6901
6902         static const char table[_ACTION_MAX] = {
6903                 [ACTION_HALT] =      '0',
6904                 [ACTION_POWEROFF] =  '0',
6905                 [ACTION_REBOOT] =    '6',
6906                 [ACTION_RUNLEVEL2] = '2',
6907                 [ACTION_RUNLEVEL3] = '3',
6908                 [ACTION_RUNLEVEL4] = '4',
6909                 [ACTION_RUNLEVEL5] = '5',
6910                 [ACTION_RESCUE] =    '1'
6911         };
6912
6913         assert(arg_action < _ACTION_MAX);
6914
6915         return table[arg_action];
6916 }
6917
6918 static int talk_initctl(void) {
6919
6920         struct init_request request = {
6921                 .magic = INIT_MAGIC,
6922                 .sleeptime  = 0,
6923                 .cmd = INIT_CMD_RUNLVL
6924         };
6925
6926         _cleanup_close_ int fd = -1;
6927         char rl;
6928         int r;
6929
6930         rl = action_to_runlevel();
6931         if (!rl)
6932                 return 0;
6933
6934         request.runlevel = rl;
6935
6936         fd = open(INIT_FIFO, O_WRONLY|O_NDELAY|O_CLOEXEC|O_NOCTTY);
6937         if (fd < 0) {
6938                 if (errno == ENOENT)
6939                         return 0;
6940
6941                 log_error_errno(errno, "Failed to open "INIT_FIFO": %m");
6942                 return -errno;
6943         }
6944
6945         r = loop_write(fd, &request, sizeof(request), false);
6946         if (r < 0)
6947                 return log_error_errno(r, "Failed to write to "INIT_FIFO": %m");
6948
6949         return 1;
6950 }
6951
6952 static int systemctl_main(sd_bus *bus, int argc, char *argv[], int bus_error) {
6953
6954         static const struct {
6955                 const char* verb;
6956                 const enum {
6957                         MORE,
6958                         LESS,
6959                         EQUAL
6960                 } argc_cmp;
6961                 const int argc;
6962                 int (* const dispatch)(sd_bus *bus, char **args);
6963                 const enum {
6964                         NOBUS = 1,
6965                         FORCE,
6966                 } bus;
6967         } verbs[] = {
6968                 { "list-units",            MORE,  0, list_units        },
6969                 { "list-unit-files",       MORE,  1, list_unit_files,  NOBUS },
6970                 { "list-sockets",          MORE,  1, list_sockets      },
6971                 { "list-timers",           MORE,  1, list_timers       },
6972                 { "list-jobs",             MORE,  1, list_jobs         },
6973                 { "list-machines",         MORE,  1, list_machines     },
6974                 { "clear-jobs",            EQUAL, 1, daemon_reload     },
6975                 { "cancel",                MORE,  2, cancel_job        },
6976                 { "start",                 MORE,  2, start_unit        },
6977                 { "stop",                  MORE,  2, start_unit        },
6978                 { "condstop",              MORE,  2, start_unit        }, /* For compatibility with ALTLinux */
6979                 { "reload",                MORE,  2, start_unit        },
6980                 { "restart",               MORE,  2, start_unit        },
6981                 { "try-restart",           MORE,  2, start_unit        },
6982                 { "reload-or-restart",     MORE,  2, start_unit        },
6983                 { "reload-or-try-restart", MORE,  2, start_unit        },
6984                 { "force-reload",          MORE,  2, start_unit        }, /* For compatibility with SysV */
6985                 { "condreload",            MORE,  2, start_unit        }, /* For compatibility with ALTLinux */
6986                 { "condrestart",           MORE,  2, start_unit        }, /* For compatibility with RH */
6987                 { "isolate",               EQUAL, 2, start_unit        },
6988                 { "kill",                  MORE,  2, kill_unit         },
6989                 { "is-active",             MORE,  2, check_unit_active },
6990                 { "check",                 MORE,  2, check_unit_active },
6991                 { "is-failed",             MORE,  2, check_unit_failed },
6992                 { "show",                  MORE,  1, show              },
6993                 { "cat",                   MORE,  2, cat,              NOBUS },
6994                 { "status",                MORE,  1, show              },
6995                 { "help",                  MORE,  2, show              },
6996                 { "snapshot",              LESS,  2, snapshot          },
6997                 { "delete",                MORE,  2, delete_snapshot   },
6998                 { "daemon-reload",         EQUAL, 1, daemon_reload     },
6999                 { "daemon-reexec",         EQUAL, 1, daemon_reload     },
7000                 { "show-environment",      EQUAL, 1, show_environment  },
7001                 { "set-environment",       MORE,  2, set_environment   },
7002                 { "unset-environment",     MORE,  2, set_environment   },
7003                 { "import-environment",    MORE,  1, import_environment},
7004                 { "halt",                  EQUAL, 1, start_special,    FORCE },
7005                 { "poweroff",              EQUAL, 1, start_special,    FORCE },
7006                 { "reboot",                MORE,  1, start_special,    FORCE },
7007                 { "kexec",                 EQUAL, 1, start_special     },
7008                 { "suspend",               EQUAL, 1, start_special     },
7009                 { "hibernate",             EQUAL, 1, start_special     },
7010                 { "hybrid-sleep",          EQUAL, 1, start_special     },
7011                 { "default",               EQUAL, 1, start_special     },
7012                 { "rescue",                EQUAL, 1, start_special     },
7013                 { "emergency",             EQUAL, 1, start_special     },
7014                 { "exit",                  EQUAL, 1, start_special     },
7015                 { "reset-failed",          MORE,  1, reset_failed      },
7016                 { "enable",                MORE,  2, enable_unit,      NOBUS },
7017                 { "disable",               MORE,  2, enable_unit,      NOBUS },
7018                 { "is-enabled",            MORE,  2, unit_is_enabled,  NOBUS },
7019                 { "reenable",              MORE,  2, enable_unit,      NOBUS },
7020                 { "preset",                MORE,  2, enable_unit,      NOBUS },
7021                 { "preset-all",            EQUAL, 1, preset_all,       NOBUS },
7022                 { "mask",                  MORE,  2, enable_unit,      NOBUS },
7023                 { "unmask",                MORE,  2, enable_unit,      NOBUS },
7024                 { "link",                  MORE,  2, enable_unit,      NOBUS },
7025                 { "switch-root",           MORE,  2, switch_root       },
7026                 { "list-dependencies",     LESS,  2, list_dependencies },
7027                 { "set-default",           EQUAL, 2, set_default,      NOBUS },
7028                 { "get-default",           EQUAL, 1, get_default,      NOBUS },
7029                 { "set-property",          MORE,  3, set_property      },
7030                 { "is-system-running",     EQUAL, 1, is_system_running },
7031                 { "add-wants",             MORE,  3, add_dependency,   NOBUS },
7032                 { "add-requires",          MORE,  3, add_dependency,   NOBUS },
7033                 { "edit",                  MORE,  2, edit,             NOBUS },
7034                 {}
7035         }, *verb = verbs;
7036
7037         int left;
7038
7039         assert(argc >= 0);
7040         assert(argv);
7041
7042         left = argc - optind;
7043
7044         /* Special rule: no arguments (left == 0) means "list-units" */
7045         if (left > 0) {
7046                 if (streq(argv[optind], "help") && !argv[optind+1]) {
7047                         log_error("This command expects one or more "
7048                                   "unit names. Did you mean --help?");
7049                         return -EINVAL;
7050                 }
7051
7052                 for (; verb->verb; verb++)
7053                         if (streq(argv[optind], verb->verb))
7054                                 goto found;
7055
7056                 log_error("Unknown operation '%s'.", argv[optind]);
7057                 return -EINVAL;
7058         }
7059 found:
7060
7061         switch (verb->argc_cmp) {
7062
7063         case EQUAL:
7064                 if (left != verb->argc) {
7065                         log_error("Invalid number of arguments.");
7066                         return -EINVAL;
7067                 }
7068
7069                 break;
7070
7071         case MORE:
7072                 if (left < verb->argc) {
7073                         log_error("Too few arguments.");
7074                         return -EINVAL;
7075                 }
7076
7077                 break;
7078
7079         case LESS:
7080                 if (left > verb->argc) {
7081                         log_error("Too many arguments.");
7082                         return -EINVAL;
7083                 }
7084
7085                 break;
7086
7087         default:
7088                 assert_not_reached("Unknown comparison operator.");
7089         }
7090
7091         /* Require a bus connection for all operations but
7092          * enable/disable */
7093         if (verb->bus == NOBUS) {
7094                 if (!bus && !avoid_bus()) {
7095                         log_error_errno(bus_error, "Failed to get D-Bus connection: %m");
7096                         return -EIO;
7097                 }
7098
7099         } else {
7100                 if (running_in_chroot() > 0) {
7101                         log_info("Running in chroot, ignoring request.");
7102                         return 0;
7103                 }
7104
7105                 if ((verb->bus != FORCE || arg_force <= 0) && !bus) {
7106                         log_error_errno(bus_error, "Failed to get D-Bus connection: %m");
7107                         return -EIO;
7108                 }
7109         }
7110
7111         /* Increase max number of open files to 16K if we can, we
7112          * might needs this when browsing journal files, which might
7113          * be split up into many files. */
7114         setrlimit_closest(RLIMIT_NOFILE, &RLIMIT_MAKE_CONST(16384));
7115
7116         return verb->dispatch(bus, argv + optind);
7117 }
7118
7119 static int send_shutdownd(usec_t t, char mode, bool dry_run, bool warn, const char *message) {
7120
7121         struct sd_shutdown_command c = {
7122                 .usec = t,
7123                 .mode = mode,
7124                 .dry_run = dry_run,
7125                 .warn_wall = warn,
7126         };
7127
7128         union sockaddr_union sockaddr = {
7129                 .un.sun_family = AF_UNIX,
7130                 .un.sun_path = "/run/systemd/shutdownd",
7131         };
7132
7133         struct iovec iovec[2] = {{
7134                  .iov_base = (char*) &c,
7135                  .iov_len = offsetof(struct sd_shutdown_command, wall_message),
7136         }};
7137
7138         struct msghdr msghdr = {
7139                 .msg_name = &sockaddr,
7140                 .msg_namelen = offsetof(struct sockaddr_un, sun_path)
7141                                + strlen("/run/systemd/shutdownd"),
7142                 .msg_iov = iovec,
7143                 .msg_iovlen = 1,
7144         };
7145
7146         _cleanup_close_ int fd;
7147
7148         fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
7149         if (fd < 0)
7150                 return -errno;
7151
7152         if (!isempty(message)) {
7153                 iovec[1].iov_base = (char*) message;
7154                 iovec[1].iov_len = strlen(message);
7155                 msghdr.msg_iovlen++;
7156         }
7157
7158         if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) < 0)
7159                 return -errno;
7160
7161         return 0;
7162 }
7163
7164 static int reload_with_fallback(sd_bus *bus) {
7165
7166         if (bus) {
7167                 /* First, try systemd via D-Bus. */
7168                 if (daemon_reload(bus, NULL) >= 0)
7169                         return 0;
7170         }
7171
7172         /* Nothing else worked, so let's try signals */
7173         assert(arg_action == ACTION_RELOAD || arg_action == ACTION_REEXEC);
7174
7175         if (kill(1, arg_action == ACTION_RELOAD ? SIGHUP : SIGTERM) < 0)
7176                 return log_error_errno(errno, "kill() failed: %m");
7177
7178         return 0;
7179 }
7180
7181 static int start_with_fallback(sd_bus *bus) {
7182
7183         if (bus) {
7184                 /* First, try systemd via D-Bus. */
7185                 if (start_unit(bus, NULL) >= 0)
7186                         goto done;
7187         }
7188
7189         /* Nothing else worked, so let's try
7190          * /dev/initctl */
7191         if (talk_initctl() > 0)
7192                 goto done;
7193
7194         log_error("Failed to talk to init daemon.");
7195         return -EIO;
7196
7197 done:
7198         warn_wall(arg_action);
7199         return 0;
7200 }
7201
7202 static int halt_now(enum action a) {
7203
7204         /* The kernel will automaticall flush ATA disks and suchlike
7205          * on reboot(), but the file systems need to be synce'd
7206          * explicitly in advance. */
7207         sync();
7208
7209         /* Make sure C-A-D is handled by the kernel from this point
7210          * on... */
7211         reboot(RB_ENABLE_CAD);
7212
7213         switch (a) {
7214
7215         case ACTION_HALT:
7216                 log_info("Halting.");
7217                 reboot(RB_HALT_SYSTEM);
7218                 return -errno;
7219
7220         case ACTION_POWEROFF:
7221                 log_info("Powering off.");
7222                 reboot(RB_POWER_OFF);
7223                 return -errno;
7224
7225         case ACTION_REBOOT: {
7226                 _cleanup_free_ char *param = NULL;
7227
7228                 if (read_one_line_file(REBOOT_PARAM_FILE, &param) >= 0) {
7229                         log_info("Rebooting with argument '%s'.", param);
7230                         syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
7231                                 LINUX_REBOOT_CMD_RESTART2, param);
7232                 }
7233
7234                 log_info("Rebooting.");
7235                 reboot(RB_AUTOBOOT);
7236                 return -errno;
7237         }
7238
7239         default:
7240                 assert_not_reached("Unknown action.");
7241         }
7242 }
7243
7244 static int halt_main(sd_bus *bus) {
7245         int r;
7246
7247         r = check_inhibitors(bus, arg_action);
7248         if (r < 0)
7249                 return r;
7250
7251         if (geteuid() != 0) {
7252                 /* Try logind if we are a normal user and no special
7253                  * mode applies. Maybe PolicyKit allows us to shutdown
7254                  * the machine. */
7255
7256                 if (arg_when <= 0 &&
7257                     !arg_dry &&
7258                     arg_force <= 0 &&
7259                     (arg_action == ACTION_POWEROFF ||
7260                      arg_action == ACTION_REBOOT)) {
7261                         r = reboot_with_logind(bus, arg_action);
7262                         if (r >= 0)
7263                                 return r;
7264                 }
7265
7266                 log_error("Must be root.");
7267                 return -EPERM;
7268         }
7269
7270         if (arg_when > 0) {
7271                 _cleanup_free_ char *m;
7272
7273                 m = strv_join(arg_wall, " ");
7274                 if (!m)
7275                         return log_oom();
7276
7277                 r = send_shutdownd(arg_when,
7278                                    arg_action == ACTION_HALT     ? 'H' :
7279                                    arg_action == ACTION_POWEROFF ? 'P' :
7280                                    arg_action == ACTION_KEXEC    ? 'K' :
7281                                                                    'r',
7282                                    arg_dry,
7283                                    !arg_no_wall,
7284                                    m);
7285
7286                 if (r < 0)
7287                         log_warning_errno(r, "Failed to talk to shutdownd, proceeding with immediate shutdown: %m");
7288                 else {
7289                         char date[FORMAT_TIMESTAMP_MAX];
7290
7291                         log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.",
7292                                  format_timestamp(date, sizeof(date), arg_when));
7293                         return 0;
7294                 }
7295         }
7296
7297         if (!arg_dry && !arg_force)
7298                 return start_with_fallback(bus);
7299
7300         if (!arg_no_wtmp) {
7301                 if (sd_booted() > 0)
7302                         log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
7303                 else {
7304                         r = utmp_put_shutdown();
7305                         if (r < 0)
7306                                 log_warning_errno(r, "Failed to write utmp record: %m");
7307                 }
7308         }
7309
7310         if (arg_dry)
7311                 return 0;
7312
7313         r = halt_now(arg_action);
7314         log_error_errno(r, "Failed to reboot: %m");
7315
7316         return r;
7317 }
7318
7319 static int runlevel_main(void) {
7320         int r, runlevel, previous;
7321
7322         r = utmp_get_runlevel(&runlevel, &previous);
7323         if (r < 0) {
7324                 puts("unknown");
7325                 return r;
7326         }
7327
7328         printf("%c %c\n",
7329                previous <= 0 ? 'N' : previous,
7330                runlevel <= 0 ? 'N' : runlevel);
7331
7332         return 0;
7333 }
7334
7335 int main(int argc, char*argv[]) {
7336         _cleanup_bus_close_unref_ sd_bus *bus = NULL;
7337         int r;
7338
7339         setlocale(LC_ALL, "");
7340         log_parse_environment();
7341         log_open();
7342
7343         /* Explicitly not on_tty() to avoid setting cached value.
7344          * This becomes relevant for piping output which might be
7345          * ellipsized. */
7346         original_stdout_is_tty = isatty(STDOUT_FILENO);
7347
7348         r = parse_argv(argc, argv);
7349         if (r <= 0)
7350                 goto finish;
7351
7352         /* /sbin/runlevel doesn't need to communicate via D-Bus, so
7353          * let's shortcut this */
7354         if (arg_action == ACTION_RUNLEVEL) {
7355                 r = runlevel_main();
7356                 goto finish;
7357         }
7358
7359         if (running_in_chroot() > 0 && arg_action != ACTION_SYSTEMCTL) {
7360                 log_info("Running in chroot, ignoring request.");
7361                 r = 0;
7362                 goto finish;
7363         }
7364
7365         if (!avoid_bus())
7366                 r = bus_open_transport_systemd(arg_transport, arg_host, arg_scope != UNIT_FILE_SYSTEM, &bus);
7367
7368         if (bus)
7369                 sd_bus_set_allow_interactive_authorization(bus, arg_ask_password);
7370
7371         /* systemctl_main() will print an error message for the bus
7372          * connection, but only if it needs to */
7373
7374         switch (arg_action) {
7375
7376         case ACTION_SYSTEMCTL:
7377                 r = systemctl_main(bus, argc, argv, r);
7378                 break;
7379
7380         case ACTION_HALT:
7381         case ACTION_POWEROFF:
7382         case ACTION_REBOOT:
7383         case ACTION_KEXEC:
7384                 r = halt_main(bus);
7385                 break;
7386
7387         case ACTION_RUNLEVEL2:
7388         case ACTION_RUNLEVEL3:
7389         case ACTION_RUNLEVEL4:
7390         case ACTION_RUNLEVEL5:
7391         case ACTION_RESCUE:
7392         case ACTION_EMERGENCY:
7393         case ACTION_DEFAULT:
7394                 r = start_with_fallback(bus);
7395                 break;
7396
7397         case ACTION_RELOAD:
7398         case ACTION_REEXEC:
7399                 r = reload_with_fallback(bus);
7400                 break;
7401
7402         case ACTION_CANCEL_SHUTDOWN: {
7403                 _cleanup_free_ char *m = NULL;
7404
7405                 if (arg_wall) {
7406                         m = strv_join(arg_wall, " ");
7407                         if (!m) {
7408                                 r = log_oom();
7409                                 goto finish;
7410                         }
7411                 }
7412
7413                 r = send_shutdownd(arg_when, SD_SHUTDOWN_NONE, false, !arg_no_wall, m);
7414                 if (r < 0)
7415                         log_warning_errno(r, "Failed to talk to shutdownd, shutdown hasn't been cancelled: %m");
7416                 break;
7417         }
7418
7419         case ACTION_RUNLEVEL:
7420         case _ACTION_INVALID:
7421         default:
7422                 assert_not_reached("Unknown action");
7423         }
7424
7425 finish:
7426         pager_close();
7427         ask_password_agent_close();
7428         polkit_agent_close();
7429
7430         strv_free(arg_types);
7431         strv_free(arg_states);
7432         strv_free(arg_properties);
7433
7434         return r < 0 ? EXIT_FAILURE : r;
7435 }