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