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