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