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