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