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