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