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