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