]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/systemctl/systemctl.c
systemctl: also color filenames of drop-ins 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 char *u;
3682 int r;
3683
3684 r = sd_bus_call_method(
3685 bus,
3686 "org.freedesktop.systemd1",
3687 "/org/freedesktop/systemd1",
3688 "org.freedesktop.systemd1.Manager",
3689 "GetUnitByPID",
3690 &error,
3691 &reply,
3692 "u", pid);
3693 if (r < 0) {
3694 log_error("Failed to get unit for PID %lu: %s", (unsigned long) pid, bus_error_message(&error, r));
3695 return r;
3696 }
3697
3698 r = sd_bus_message_read(reply, "o", &u);
3699 if (r < 0)
3700 return bus_log_parse_error(r);
3701
3702 u = strdup(u);
3703 if (!u)
3704 return log_oom();
3705
3706 *unit = u;
3707 return 0;
3708 }
3709
3710 static int show_all(
3711 const char* verb,
3712 sd_bus *bus,
3713 bool show_properties,
3714 bool *new_line,
3715 bool *ellipsized) {
3716
3717 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3718 _cleanup_free_ UnitInfo *unit_infos = NULL;
3719 const UnitInfo *u;
3720 unsigned c;
3721 int r;
3722
3723 r = get_unit_list(bus, &reply, &unit_infos);
3724 if (r < 0)
3725 return r;
3726
3727 pager_open_if_enabled();
3728
3729 c = (unsigned) r;
3730
3731 qsort_safe(unit_infos, c, sizeof(UnitInfo), compare_unit_info);
3732
3733 for (u = unit_infos; u < unit_infos + c; u++) {
3734 _cleanup_free_ char *p = NULL;
3735
3736 if (!output_show_unit(u, NULL))
3737 continue;
3738
3739 p = unit_dbus_path_from_name(u->id);
3740 if (!p)
3741 return log_oom();
3742
3743 r = show_one(verb, bus, p, show_properties, new_line, ellipsized);
3744 if (r != 0)
3745 return r;
3746 }
3747
3748 return 0;
3749 }
3750
3751 static int cat(sd_bus *bus, char **args) {
3752 _cleanup_free_ char *unit = NULL, *n = NULL;
3753 int r = 0;
3754 char **name;
3755 bool first = true;
3756
3757 assert(bus);
3758 assert(args);
3759
3760 pager_open_if_enabled();
3761
3762 STRV_FOREACH(name, args+1) {
3763 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3764 _cleanup_strv_free_ char **dropin_paths = NULL;
3765 _cleanup_free_ char *fragment_path = NULL;
3766 char **path;
3767
3768 n = unit_name_mangle(*name);
3769 if (!n)
3770 return log_oom();
3771
3772 unit = unit_dbus_path_from_name(n);
3773 if (!unit)
3774 return log_oom();
3775
3776 if (need_daemon_reload(bus, n) > 0)
3777 log_warning("Unit file of %s changed on disk. Run 'systemctl%s daemon-reload'.",
3778 n, arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
3779
3780 r = sd_bus_get_property_string(
3781 bus,
3782 "org.freedesktop.systemd1",
3783 unit,
3784 "org.freedesktop.systemd1.Unit",
3785 "FragmentPath",
3786 &error,
3787 &fragment_path);
3788 if (r < 0) {
3789 log_warning("Failed to get FragmentPath: %s", bus_error_message(&error, r));
3790 continue;
3791 }
3792
3793 r = sd_bus_get_property_strv(
3794 bus,
3795 "org.freedesktop.systemd1",
3796 unit,
3797 "org.freedesktop.systemd1.Unit",
3798 "DropInPaths",
3799 &error,
3800 &dropin_paths);
3801 if (r < 0) {
3802 log_warning("Failed to get DropInPaths: %s", bus_error_message(&error, r));
3803 continue;
3804 }
3805
3806 if (first)
3807 first = false;
3808 else
3809 puts("");
3810
3811 if (!isempty(fragment_path)) {
3812 printf("%s# %s%s\n",
3813 ansi_highlight_blue(),
3814 fragment_path,
3815 ansi_highlight_off());
3816 fflush(stdout);
3817
3818 r = sendfile_full(STDOUT_FILENO, fragment_path);
3819 if (r < 0) {
3820 log_warning("Failed to cat %s: %s", fragment_path, strerror(-r));
3821 continue;
3822 }
3823 }
3824
3825 STRV_FOREACH(path, dropin_paths) {
3826 printf("%s%s# %s%s\n",
3827 isempty(fragment_path) && path == dropin_paths ? "" : "\n",
3828 ansi_highlight_blue(),
3829 *path,
3830 ansi_highlight_off());
3831 fflush(stdout);
3832
3833 r = sendfile_full(STDOUT_FILENO, *path);
3834 if (r < 0) {
3835 log_warning("Failed to cat %s: %s", *path, strerror(-r));
3836 continue;
3837 }
3838 }
3839 }
3840
3841 return r < 0 ? r : 0;
3842 }
3843
3844 static int show(sd_bus *bus, char **args) {
3845 int r, ret = 0;
3846 bool show_properties, show_status, new_line = false;
3847 char **name;
3848 bool ellipsized = false;
3849
3850 assert(bus);
3851 assert(args);
3852
3853 show_properties = streq(args[0], "show");
3854 show_status = streq(args[0], "status");
3855
3856 if (show_properties)
3857 pager_open_if_enabled();
3858
3859 /* If no argument is specified inspect the manager itself */
3860
3861 if (show_properties && strv_length(args) <= 1)
3862 return show_one(args[0], bus, "/org/freedesktop/systemd1", show_properties, &new_line, &ellipsized);
3863
3864 if (show_status && strv_length(args) <= 1)
3865 ret = show_all(args[0], bus, false, &new_line, &ellipsized);
3866 else
3867 STRV_FOREACH(name, args+1) {
3868 _cleanup_free_ char *unit = NULL;
3869 uint32_t id;
3870
3871 if (safe_atou32(*name, &id) < 0) {
3872 _cleanup_free_ char *n = NULL;
3873 /* Interpret as unit name */
3874
3875 n = unit_name_mangle(*name);
3876 if (!n)
3877 return log_oom();
3878
3879 unit = unit_dbus_path_from_name(n);
3880 if (!unit)
3881 return log_oom();
3882
3883 } else if (show_properties) {
3884 /* Interpret as job id */
3885 if (asprintf(&unit, "/org/freedesktop/systemd1/job/%u", id) < 0)
3886 return log_oom();
3887
3888 } else {
3889 /* Interpret as PID */
3890 r = get_unit_dbus_path_by_pid(bus, id, &unit);
3891 if (r < 0) {
3892 ret = r;
3893 continue;
3894 }
3895 }
3896
3897 show_one(args[0], bus, unit, show_properties, &new_line, &ellipsized);
3898 }
3899
3900 if (ellipsized && !arg_quiet)
3901 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
3902
3903 return ret;
3904 }
3905
3906 static int append_assignment(sd_bus_message *m, const char *assignment) {
3907 const char *eq;
3908 char *field;
3909 int r;
3910
3911 assert(m);
3912 assert(assignment);
3913
3914 eq = strchr(assignment, '=');
3915 if (!eq) {
3916 log_error("Not an assignment: %s", assignment);
3917 return -EINVAL;
3918 }
3919
3920 field = strndupa(assignment, eq - assignment);
3921 eq ++;
3922
3923 r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, field);
3924 if (r < 0)
3925 return bus_log_create_error(r);
3926
3927 if (streq(field, "CPUAccounting") ||
3928 streq(field, "MemoryAccounting") ||
3929 streq(field, "BlockIOAccounting")) {
3930
3931 r = parse_boolean(eq);
3932 if (r < 0) {
3933 log_error("Failed to parse boolean assignment %s.", assignment);
3934 return -EINVAL;
3935 }
3936
3937 r = sd_bus_message_append(m, "v", "b", r);
3938
3939 } else if (streq(field, "MemoryLimit")) {
3940 off_t bytes;
3941
3942 r = parse_bytes(eq, &bytes);
3943 if (r < 0) {
3944 log_error("Failed to parse bytes specification %s", assignment);
3945 return -EINVAL;
3946 }
3947
3948 r = sd_bus_message_append(m, "v", "t", (uint64_t) bytes);
3949
3950 } else if (streq(field, "CPUShares") || streq(field, "BlockIOWeight")) {
3951 uint64_t u;
3952
3953 r = safe_atou64(eq, &u);
3954 if (r < 0) {
3955 log_error("Failed to parse %s value %s.", field, eq);
3956 return -EINVAL;
3957 }
3958
3959 r = sd_bus_message_append(m, "v", "t", u);
3960
3961 } else if (streq(field, "DevicePolicy"))
3962 r = sd_bus_message_append(m, "v", "s", eq);
3963
3964 else if (streq(field, "DeviceAllow")) {
3965
3966 if (isempty(eq))
3967 r = sd_bus_message_append(m, "v", "a(ss)", 0);
3968 else {
3969 const char *path, *rwm;
3970 char *e;
3971
3972 e = strchr(eq, ' ');
3973 if (e) {
3974 path = strndupa(eq, e - eq);
3975 rwm = e+1;
3976 } else {
3977 path = eq;
3978 rwm = "";
3979 }
3980
3981 if (!path_startswith(path, "/dev")) {
3982 log_error("%s is not a device file in /dev.", path);
3983 return -EINVAL;
3984 }
3985
3986 r = sd_bus_message_append(m, "v", "a(ss)", 1, path, rwm);
3987 }
3988
3989 } else if (streq(field, "BlockIOReadBandwidth") || streq(field, "BlockIOWriteBandwidth")) {
3990
3991 if (isempty(eq))
3992 r = sd_bus_message_append(m, "v", "a(st)", 0);
3993 else {
3994 const char *path, *bandwidth;
3995 off_t bytes;
3996 char *e;
3997
3998 e = strchr(eq, ' ');
3999 if (e) {
4000 path = strndupa(eq, e - eq);
4001 bandwidth = e+1;
4002 } else {
4003 log_error("Failed to parse %s value %s.", field, eq);
4004 return -EINVAL;
4005 }
4006
4007 if (!path_startswith(path, "/dev")) {
4008 log_error("%s is not a device file in /dev.", path);
4009 return -EINVAL;
4010 }
4011
4012 r = parse_bytes(bandwidth, &bytes);
4013 if (r < 0) {
4014 log_error("Failed to parse byte value %s.", bandwidth);
4015 return -EINVAL;
4016 }
4017
4018 r = sd_bus_message_append(m, "v", "a(st)", 1, path, (uint64_t) bytes);
4019 }
4020
4021 } else if (streq(field, "BlockIODeviceWeight")) {
4022
4023 if (isempty(eq))
4024 r = sd_bus_message_append(m, "v", "a(st)", 0);
4025 else {
4026 const char *path, *weight;
4027 uint64_t u;
4028 char *e;
4029
4030 e = strchr(eq, ' ');
4031 if (e) {
4032 path = strndupa(eq, e - eq);
4033 weight = e+1;
4034 } else {
4035 log_error("Failed to parse %s value %s.", field, eq);
4036 return -EINVAL;
4037 }
4038
4039 if (!path_startswith(path, "/dev")) {
4040 log_error("%s is not a device file in /dev.", path);
4041 return -EINVAL;
4042 }
4043
4044 r = safe_atou64(weight, &u);
4045 if (r < 0) {
4046 log_error("Failed to parse %s value %s.", field, weight);
4047 return -EINVAL;
4048 }
4049 r = sd_bus_message_append(m, "v", "a(st)", path, u);
4050 }
4051
4052 } else {
4053 log_error("Unknown assignment %s.", assignment);
4054 return -EINVAL;
4055 }
4056
4057 if (r < 0)
4058 return bus_log_create_error(r);
4059
4060 return 0;
4061 }
4062
4063 static int set_property(sd_bus *bus, char **args) {
4064 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4065 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4066 _cleanup_free_ char *n = NULL;
4067 char **i;
4068 int r;
4069
4070 r = sd_bus_message_new_method_call(
4071 bus,
4072 "org.freedesktop.systemd1",
4073 "/org/freedesktop/systemd1",
4074 "org.freedesktop.systemd1.Manager",
4075 "SetUnitProperties",
4076 &m);
4077 if (r < 0)
4078 return bus_log_create_error(r);
4079
4080 n = unit_name_mangle(args[1]);
4081 if (!n)
4082 return log_oom();
4083
4084 r = sd_bus_message_append(m, "sb", n, arg_runtime);
4085 if (r < 0)
4086 return bus_log_create_error(r);
4087
4088 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, "(sv)");
4089 if (r < 0)
4090 return bus_log_create_error(r);
4091
4092 STRV_FOREACH(i, args + 2) {
4093 r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv");
4094 if (r < 0)
4095 return bus_log_create_error(r);
4096
4097 r = append_assignment(m, *i);
4098 if (r < 0)
4099 return r;
4100
4101 r = sd_bus_message_close_container(m);
4102 if (r < 0)
4103 return bus_log_create_error(r);
4104 }
4105
4106 r = sd_bus_message_close_container(m);
4107 if (r < 0)
4108 return bus_log_create_error(r);
4109
4110 r = sd_bus_call(bus, m, 0, &error, NULL);
4111 if (r < 0) {
4112 log_error("Failed to set unit properties on %s: %s", n, bus_error_message(&error, r));
4113 return r;
4114 }
4115
4116 return 0;
4117 }
4118
4119 static int snapshot(sd_bus *bus, char **args) {
4120 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4121 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4122 _cleanup_free_ char *n = NULL, *id = NULL;
4123 const char *path;
4124 int r;
4125
4126 if (strv_length(args) > 1)
4127 n = unit_name_mangle_with_suffix(args[1], ".snapshot");
4128 else
4129 n = strdup("");
4130 if (!n)
4131 return log_oom();
4132
4133 r = sd_bus_call_method(
4134 bus,
4135 "org.freedesktop.systemd1",
4136 "/org/freedesktop/systemd1",
4137 "org.freedesktop.systemd1.Manager",
4138 "CreateSnapshot",
4139 &error,
4140 &reply,
4141 "sb", n, false);
4142 if (r < 0) {
4143 log_error("Failed to create snapshot: %s", bus_error_message(&error, r));
4144 return r;
4145 }
4146
4147 r = sd_bus_message_read(reply, "o", &path);
4148 if (r < 0)
4149 return bus_log_parse_error(r);
4150
4151 r = sd_bus_get_property_string(
4152 bus,
4153 "org.freedesktop.systemd1",
4154 path,
4155 "org.freedesktop.systemd1.Unit",
4156 "Id",
4157 &error,
4158 &id);
4159 if (r < 0) {
4160 log_error("Failed to get ID of snapshot: %s", bus_error_message(&error, r));
4161 return r;
4162 }
4163
4164 if (!arg_quiet)
4165 puts(id);
4166
4167 return 0;
4168 }
4169
4170 static int delete_snapshot(sd_bus *bus, char **args) {
4171 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4172 char **name;
4173 int r;
4174
4175 assert(args);
4176
4177 STRV_FOREACH(name, args+1) {
4178 _cleanup_free_ char *n = NULL;
4179
4180 n = unit_name_mangle_with_suffix(*name, ".snapshot");
4181 if (!n)
4182 return log_oom();
4183
4184 r = sd_bus_call_method(
4185 bus,
4186 "org.freedesktop.systemd1",
4187 "/org/freedesktop/systemd1",
4188 "org.freedesktop.systemd1.Manager",
4189 "RemoveSnapshot",
4190 &error,
4191 NULL,
4192 "s", n);
4193 if (r < 0) {
4194 log_error("Failed to remove snapshot %s: %s", n, bus_error_message(&error, r));
4195 return r;
4196 }
4197 }
4198
4199 return 0;
4200 }
4201
4202 static int daemon_reload(sd_bus *bus, char **args) {
4203 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4204 const char *method;
4205 int r;
4206
4207 if (arg_action == ACTION_RELOAD)
4208 method = "Reload";
4209 else if (arg_action == ACTION_REEXEC)
4210 method = "Reexecute";
4211 else {
4212 assert(arg_action == ACTION_SYSTEMCTL);
4213
4214 method =
4215 streq(args[0], "clear-jobs") ||
4216 streq(args[0], "cancel") ? "ClearJobs" :
4217 streq(args[0], "daemon-reexec") ? "Reexecute" :
4218 streq(args[0], "reset-failed") ? "ResetFailed" :
4219 streq(args[0], "halt") ? "Halt" :
4220 streq(args[0], "poweroff") ? "PowerOff" :
4221 streq(args[0], "reboot") ? "Reboot" :
4222 streq(args[0], "kexec") ? "KExec" :
4223 streq(args[0], "exit") ? "Exit" :
4224 /* "daemon-reload" */ "Reload";
4225 }
4226
4227 r = sd_bus_call_method(
4228 bus,
4229 "org.freedesktop.systemd1",
4230 "/org/freedesktop/systemd1",
4231 "org.freedesktop.systemd1.Manager",
4232 method,
4233 &error,
4234 NULL,
4235 NULL);
4236
4237 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
4238 /* There's always a fallback possible for
4239 * legacy actions. */
4240 r = -EADDRNOTAVAIL;
4241 else if ((r == -ETIMEDOUT || r == -ECONNRESET) && streq(method, "Reexecute"))
4242 /* On reexecution, we expect a disconnect, not a
4243 * reply */
4244 r = 0;
4245 else if (r < 0)
4246 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
4247
4248 return r < 0 ? r : 0;
4249 }
4250
4251 static int reset_failed(sd_bus *bus, char **args) {
4252 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4253 char **name;
4254 int r;
4255
4256 if (strv_length(args) <= 1)
4257 return daemon_reload(bus, args);
4258
4259 STRV_FOREACH(name, args+1) {
4260 _cleanup_free_ char *n;
4261
4262 n = unit_name_mangle(*name);
4263 if (!n)
4264 return log_oom();
4265
4266 r = sd_bus_call_method(
4267 bus,
4268 "org.freedesktop.systemd1",
4269 "/org/freedesktop/systemd1",
4270 "org.freedesktop.systemd1.Manager",
4271 "ResetFailedUnit",
4272 &error,
4273 NULL,
4274 "s", n);
4275 if (r < 0) {
4276 log_error("Failed to reset failed state of unit %s: %s", n, bus_error_message(&error, r));
4277 return r;
4278 }
4279 }
4280
4281 return 0;
4282 }
4283
4284 static int show_environment(sd_bus *bus, char **args) {
4285 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4286 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4287 const char *text;
4288 int r;
4289
4290 pager_open_if_enabled();
4291
4292 r = sd_bus_get_property(
4293 bus,
4294 "org.freedesktop.systemd1",
4295 "/org/freedesktop/systemd1",
4296 "org.freedesktop.systemd1.Manager",
4297 "Environment",
4298 &error,
4299 &reply,
4300 "as");
4301 if (r < 0) {
4302 log_error("Failed to get environment: %s", bus_error_message(&error, r));
4303 return r;
4304 }
4305
4306 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "s");
4307 if (r < 0)
4308 return bus_log_parse_error(r);
4309
4310 while ((r = sd_bus_message_read_basic(reply, SD_BUS_TYPE_STRING, &text)) > 0)
4311 puts(text);
4312 if (r < 0)
4313 return bus_log_parse_error(r);
4314
4315 r = sd_bus_message_exit_container(reply);
4316 if (r < 0)
4317 return bus_log_parse_error(r);
4318
4319 return 0;
4320 }
4321
4322 static int switch_root(sd_bus *bus, char **args) {
4323 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4324 _cleanup_free_ char *init = NULL;
4325 const char *root;
4326 unsigned l;
4327 int r;
4328
4329 l = strv_length(args);
4330 if (l < 2 || l > 3) {
4331 log_error("Wrong number of arguments.");
4332 return -EINVAL;
4333 }
4334
4335 root = args[1];
4336
4337 if (l >= 3)
4338 init = strdup(args[2]);
4339 else {
4340 parse_env_file("/proc/cmdline", WHITESPACE,
4341 "init", &init,
4342 NULL);
4343
4344 if (!init)
4345 init = strdup("");
4346 }
4347
4348 if (!init)
4349 return log_oom();
4350
4351 log_debug("switching root - root: %s; init: %s", root, init);
4352
4353 r = sd_bus_call_method(
4354 bus,
4355 "org.freedesktop.systemd1",
4356 "/org/freedesktop/systemd1",
4357 "org.freedesktop.systemd1.Manager",
4358 "SwitchRoot",
4359 &error,
4360 NULL,
4361 "ss", root, init);
4362 if (r < 0) {
4363 log_error("Failed to switch root: %s", bus_error_message(&error, r));
4364 return r;
4365 }
4366
4367 return 0;
4368 }
4369
4370 static int set_environment(sd_bus *bus, char **args) {
4371 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4372 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4373 const char *method;
4374 int r;
4375
4376 assert(bus);
4377 assert(args);
4378
4379 method = streq(args[0], "set-environment")
4380 ? "SetEnvironment"
4381 : "UnsetEnvironment";
4382
4383 r = sd_bus_message_new_method_call(
4384 bus,
4385 "org.freedesktop.systemd1",
4386 "/org/freedesktop/systemd1",
4387 "org.freedesktop.systemd1.Manager",
4388 method,
4389 &m);
4390 if (r < 0)
4391 return bus_log_create_error(r);
4392
4393 r = sd_bus_message_append_strv(m, args + 1);
4394 if (r < 0)
4395 return bus_log_create_error(r);
4396
4397 r = sd_bus_call(bus, m, 0, &error, NULL);
4398 if (r < 0) {
4399 log_error("Failed to set environment: %s", bus_error_message(&error, r));
4400 return r;
4401 }
4402
4403 return 0;
4404 }
4405
4406 static int enable_sysv_units(const char *verb, char **args) {
4407 int r = 0;
4408
4409 #if defined(HAVE_SYSV_COMPAT) && defined(HAVE_CHKCONFIG)
4410 unsigned f = 1, t = 1;
4411 _cleanup_lookup_paths_free_ LookupPaths paths = {};
4412
4413 if (arg_scope != UNIT_FILE_SYSTEM)
4414 return 0;
4415
4416 if (!streq(verb, "enable") &&
4417 !streq(verb, "disable") &&
4418 !streq(verb, "is-enabled"))
4419 return 0;
4420
4421 /* Processes all SysV units, and reshuffles the array so that
4422 * afterwards only the native units remain */
4423
4424 r = lookup_paths_init(&paths, SYSTEMD_SYSTEM, false, NULL, NULL, NULL);
4425 if (r < 0)
4426 return r;
4427
4428 r = 0;
4429 for (f = 0; args[f]; f++) {
4430 const char *name;
4431 _cleanup_free_ char *p = NULL, *q = NULL;
4432 bool found_native = false, found_sysv;
4433 unsigned c = 1;
4434 const char *argv[6] = { "/sbin/chkconfig", NULL, NULL, NULL, NULL };
4435 char **k, *l;
4436 int j;
4437 pid_t pid;
4438 siginfo_t status;
4439
4440 name = args[f];
4441
4442 if (!endswith(name, ".service"))
4443 continue;
4444
4445 if (path_is_absolute(name))
4446 continue;
4447
4448 STRV_FOREACH(k, paths.unit_path) {
4449 if (!isempty(arg_root))
4450 asprintf(&p, "%s/%s/%s", arg_root, *k, name);
4451 else
4452 asprintf(&p, "%s/%s", *k, name);
4453
4454 if (!p) {
4455 r = log_oom();
4456 goto finish;
4457 }
4458
4459 found_native = access(p, F_OK) >= 0;
4460 free(p);
4461 p = NULL;
4462
4463 if (found_native)
4464 break;
4465 }
4466
4467 if (found_native)
4468 continue;
4469
4470 if (!isempty(arg_root))
4471 asprintf(&p, "%s/" SYSTEM_SYSVINIT_PATH "/%s", arg_root, name);
4472 else
4473 asprintf(&p, SYSTEM_SYSVINIT_PATH "/%s", name);
4474 if (!p) {
4475 r = log_oom();
4476 goto finish;
4477 }
4478
4479 p[strlen(p) - sizeof(".service") + 1] = 0;
4480 found_sysv = access(p, F_OK) >= 0;
4481
4482 if (!found_sysv)
4483 continue;
4484
4485 /* Mark this entry, so that we don't try enabling it as native unit */
4486 args[f] = (char*) "";
4487
4488 log_info("%s is not a native service, redirecting to /sbin/chkconfig.", name);
4489
4490 if (!isempty(arg_root))
4491 argv[c++] = q = strappend("--root=", arg_root);
4492
4493 argv[c++] = basename(p);
4494 argv[c++] =
4495 streq(verb, "enable") ? "on" :
4496 streq(verb, "disable") ? "off" : "--level=5";
4497 argv[c] = NULL;
4498
4499 l = strv_join((char**)argv, " ");
4500 if (!l) {
4501 r = log_oom();
4502 goto finish;
4503 }
4504
4505 log_info("Executing %s", l);
4506 free(l);
4507
4508 pid = fork();
4509 if (pid < 0) {
4510 log_error("Failed to fork: %m");
4511 r = -errno;
4512 goto finish;
4513 } else if (pid == 0) {
4514 /* Child */
4515
4516 execv(argv[0], (char**) argv);
4517 _exit(EXIT_FAILURE);
4518 }
4519
4520 j = wait_for_terminate(pid, &status);
4521 if (j < 0) {
4522 log_error("Failed to wait for child: %s", strerror(-r));
4523 r = j;
4524 goto finish;
4525 }
4526
4527 if (status.si_code == CLD_EXITED) {
4528 if (streq(verb, "is-enabled")) {
4529 if (status.si_status == 0) {
4530 if (!arg_quiet)
4531 puts("enabled");
4532 r = 1;
4533 } else {
4534 if (!arg_quiet)
4535 puts("disabled");
4536 }
4537
4538 } else if (status.si_status != 0) {
4539 r = -EINVAL;
4540 goto finish;
4541 }
4542 } else {
4543 r = -EPROTO;
4544 goto finish;
4545 }
4546 }
4547
4548 finish:
4549 /* Drop all SysV units */
4550 for (f = 0, t = 0; args[f]; f++) {
4551
4552 if (isempty(args[f]))
4553 continue;
4554
4555 args[t++] = args[f];
4556 }
4557
4558 args[t] = NULL;
4559
4560 #endif
4561 return r;
4562 }
4563
4564 static int mangle_names(char **original_names, char ***mangled_names) {
4565 char **i, **l, **name;
4566
4567 l = new(char*, strv_length(original_names) + 1);
4568 if (!l)
4569 return log_oom();
4570
4571 i = l;
4572 STRV_FOREACH(name, original_names) {
4573
4574 /* When enabling units qualified path names are OK,
4575 * too, hence allow them explicitly. */
4576
4577 if (is_path(*name))
4578 *i = strdup(*name);
4579 else
4580 *i = unit_name_mangle(*name);
4581
4582 if (!*i) {
4583 strv_free(l);
4584 return log_oom();
4585 }
4586
4587 i++;
4588 }
4589
4590 *i = NULL;
4591 *mangled_names = l;
4592
4593 return 0;
4594 }
4595
4596 static int enable_unit(sd_bus *bus, char **args) {
4597 _cleanup_strv_free_ char **mangled_names = NULL;
4598 const char *verb = args[0];
4599 UnitFileChange *changes = NULL;
4600 unsigned n_changes = 0;
4601 int carries_install_info = -1;
4602 int r;
4603
4604 if (!args[1])
4605 return 0;
4606
4607 r = mangle_names(args+1, &mangled_names);
4608 if (r < 0)
4609 return r;
4610
4611 r = enable_sysv_units(verb, mangled_names);
4612 if (r < 0)
4613 return r;
4614
4615 if (!bus || avoid_bus()) {
4616 if (streq(verb, "enable")) {
4617 r = unit_file_enable(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes);
4618 carries_install_info = r;
4619 } else if (streq(verb, "disable"))
4620 r = unit_file_disable(arg_scope, arg_runtime, arg_root, mangled_names, &changes, &n_changes);
4621 else if (streq(verb, "reenable")) {
4622 r = unit_file_reenable(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes);
4623 carries_install_info = r;
4624 } else if (streq(verb, "link"))
4625 r = unit_file_link(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes);
4626 else if (streq(verb, "preset")) {
4627 r = unit_file_preset(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes);
4628 carries_install_info = r;
4629 } else if (streq(verb, "mask"))
4630 r = unit_file_mask(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes);
4631 else if (streq(verb, "unmask"))
4632 r = unit_file_unmask(arg_scope, arg_runtime, arg_root, mangled_names, &changes, &n_changes);
4633 else
4634 assert_not_reached("Unknown verb");
4635
4636 if (r < 0) {
4637 log_error("Operation failed: %s", strerror(-r));
4638 goto finish;
4639 }
4640
4641 if (!arg_quiet)
4642 dump_unit_file_changes(changes, n_changes);
4643
4644 r = 0;
4645 } else {
4646 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
4647 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4648 int expect_carries_install_info = false;
4649 bool send_force = true;
4650 const char *method;
4651
4652 if (streq(verb, "enable")) {
4653 method = "EnableUnitFiles";
4654 expect_carries_install_info = true;
4655 } else if (streq(verb, "disable")) {
4656 method = "DisableUnitFiles";
4657 send_force = false;
4658 } else if (streq(verb, "reenable")) {
4659 method = "ReenableUnitFiles";
4660 expect_carries_install_info = true;
4661 } else if (streq(verb, "link"))
4662 method = "LinkUnitFiles";
4663 else if (streq(verb, "preset")) {
4664 method = "PresetUnitFiles";
4665 expect_carries_install_info = true;
4666 } else if (streq(verb, "mask"))
4667 method = "MaskUnitFiles";
4668 else if (streq(verb, "unmask")) {
4669 method = "UnmaskUnitFiles";
4670 send_force = false;
4671 } else
4672 assert_not_reached("Unknown verb");
4673
4674 r = sd_bus_message_new_method_call(
4675 bus,
4676 "org.freedesktop.systemd1",
4677 "/org/freedesktop/systemd1",
4678 "org.freedesktop.systemd1.Manager",
4679 method,
4680 &m);
4681 if (r < 0)
4682 return bus_log_create_error(r);
4683
4684 r = sd_bus_message_append_strv(m, mangled_names);
4685 if (r < 0)
4686 return bus_log_create_error(r);
4687
4688 r = sd_bus_message_append(m, "b", arg_runtime);
4689 if (r < 0)
4690 return bus_log_create_error(r);
4691
4692 if (send_force) {
4693 r = sd_bus_message_append(m, "b", arg_force);
4694 if (r < 0)
4695 return bus_log_create_error(r);
4696 }
4697
4698 r = sd_bus_call(bus, m, 0, &error, &reply);
4699 if (r < 0) {
4700 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
4701 return r;
4702 }
4703
4704 if (expect_carries_install_info) {
4705 r = sd_bus_message_read(reply, "b", &carries_install_info);
4706 if (r < 0)
4707 return bus_log_parse_error(r);
4708 }
4709
4710 r = deserialize_and_dump_unit_file_changes(reply);
4711 if (r < 0)
4712 return r;
4713
4714 /* Try to reload if enabeld */
4715 if (!arg_no_reload)
4716 r = daemon_reload(bus, args);
4717 else
4718 r = 0;
4719 }
4720
4721 if (carries_install_info == 0)
4722 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
4723 "using systemctl.\n"
4724 "Possible reasons for having this kind of units are:\n"
4725 "1) A unit may be statically enabled by being symlinked from another unit's\n"
4726 " .wants/ or .requires/ directory.\n"
4727 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
4728 " a requirement dependency on it.\n"
4729 "3) A unit may be started when needed via activation (socket, path, timer,\n"
4730 " D-Bus, udev, scripted systemctl call, ...).\n");
4731
4732 finish:
4733 unit_file_changes_free(changes, n_changes);
4734
4735 return r;
4736 }
4737
4738 static int unit_is_enabled(sd_bus *bus, char **args) {
4739
4740 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4741 _cleanup_strv_free_ char **mangled_names = NULL;
4742 bool enabled;
4743 char **name;
4744 int r;
4745
4746 r = mangle_names(args+1, &mangled_names);
4747 if (r < 0)
4748 return r;
4749
4750 r = enable_sysv_units(args[0], mangled_names);
4751 if (r < 0)
4752 return r;
4753
4754 enabled = r > 0;
4755
4756 if (!bus || avoid_bus()) {
4757
4758 STRV_FOREACH(name, mangled_names) {
4759 UnitFileState state;
4760
4761 state = unit_file_get_state(arg_scope, arg_root, *name);
4762 if (state < 0) {
4763 log_error("Failed to get unit file state for %s: %s", *name, strerror(-state));
4764 return state;
4765 }
4766
4767 if (state == UNIT_FILE_ENABLED ||
4768 state == UNIT_FILE_ENABLED_RUNTIME ||
4769 state == UNIT_FILE_STATIC)
4770 enabled = true;
4771
4772 if (!arg_quiet)
4773 puts(unit_file_state_to_string(state));
4774 }
4775
4776 } else {
4777 STRV_FOREACH(name, mangled_names) {
4778 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4779 const char *s;
4780
4781 r = sd_bus_call_method(
4782 bus,
4783 "org.freedesktop.systemd1",
4784 "/org/freedesktop/systemd1",
4785 "org.freedesktop.systemd1.Manager",
4786 "GetUnitFileState",
4787 &error,
4788 &reply,
4789 "s", *name);
4790 if (r < 0) {
4791 log_error("Failed to get unit file state for %s: %s", *name, bus_error_message(&error, r));
4792 return r;
4793 }
4794
4795 r = sd_bus_message_read(reply, "s", &s);
4796 if (r < 0)
4797 return bus_log_parse_error(r);
4798
4799 if (streq(s, "enabled") ||
4800 streq(s, "enabled-runtime") ||
4801 streq(s, "static"))
4802 enabled = true;
4803
4804 if (!arg_quiet)
4805 puts(s);
4806 }
4807 }
4808
4809 return !enabled;
4810 }
4811
4812 static int systemctl_help(void) {
4813
4814 pager_open_if_enabled();
4815
4816 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
4817 "Query or send control commands to the systemd manager.\n\n"
4818 " -h --help Show this help\n"
4819 " --version Show package version\n"
4820 " --system Connect to system manager\n"
4821 " --user Connect to user service manager\n"
4822 " -H --host=[USER@]HOST\n"
4823 " Operate on remote host\n"
4824 " -M --machine=CONTAINER\n"
4825 " Operate on local container\n"
4826 " -t --type=TYPE List only units of a particular type\n"
4827 " --state=STATE List only units with particular LOAD or SUB or ACTIVE state\n"
4828 " -p --property=NAME Show only properties by this name\n"
4829 " -a --all Show all loaded units/properties, including dead/empty\n"
4830 " ones. To list all units installed on the system, use\n"
4831 " the 'list-unit-files' command instead.\n"
4832 " -l --full Don't ellipsize unit names on output\n"
4833 " --reverse Show reverse dependencies with 'list-dependencies'\n"
4834 " --job-mode=MODE Specify how to deal with already queued jobs, when\n"
4835 " queueing a new job\n"
4836 " --show-types When showing sockets, explicitly show their type\n"
4837 " -i --ignore-inhibitors\n"
4838 " When shutting down or sleeping, ignore inhibitors\n"
4839 " --kill-who=WHO Who to send signal to\n"
4840 " -s --signal=SIGNAL Which signal to send\n"
4841 " -q --quiet Suppress output\n"
4842 " --no-block Do not wait until operation finished\n"
4843 " --no-wall Don't send wall message before halt/power-off/reboot\n"
4844 " --no-reload When enabling/disabling unit files, don't reload daemon\n"
4845 " configuration\n"
4846 " --no-legend Do not print a legend (column headers and hints)\n"
4847 " --no-pager Do not pipe output into a pager\n"
4848 " --no-ask-password\n"
4849 " Do not ask for system passwords\n"
4850 " --global Enable/disable unit files globally\n"
4851 " --runtime Enable unit files only temporarily until next reboot\n"
4852 " -f --force When enabling unit files, override existing symlinks\n"
4853 " When shutting down, execute action immediately\n"
4854 " --root=PATH Enable unit files in the specified root directory\n"
4855 " -n --lines=INTEGER Number of journal entries to show\n"
4856 " -o --output=STRING Change journal output mode (short, short-monotonic,\n"
4857 " verbose, export, json, json-pretty, json-sse, cat)\n"
4858 " --plain Print unit dependencies as a list instead of a tree\n\n"
4859 "Unit Commands:\n"
4860 " list-units [PATTERN...] List loaded units\n"
4861 " list-sockets [PATTERN...] List loaded sockets ordered by address\n"
4862 " list-timers [PATTERN...] List loaded timers ordered by next elapse\n"
4863 " start NAME... Start (activate) one or more units\n"
4864 " stop NAME... Stop (deactivate) one or more units\n"
4865 " reload NAME... Reload one or more units\n"
4866 " restart NAME... Start or restart one or more units\n"
4867 " try-restart NAME... Restart one or more units if active\n"
4868 " reload-or-restart NAME... Reload one or more units if possible,\n"
4869 " otherwise start or restart\n"
4870 " reload-or-try-restart NAME... Reload one or more units if possible,\n"
4871 " otherwise restart if active\n"
4872 " isolate NAME Start one unit and stop all others\n"
4873 " kill NAME... Send signal to processes of a unit\n"
4874 " is-active NAME... Check whether units are active\n"
4875 " is-failed NAME... Check whether units are failed\n"
4876 " status [NAME...|PID...] Show runtime status of one or more units\n"
4877 " show [NAME...|JOB...] Show properties of one or more\n"
4878 " units/jobs or the manager\n"
4879 " cat NAME... Show files and drop-ins of one or more units\n"
4880 " set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
4881 " help NAME...|PID... Show manual for one or more units\n"
4882 " reset-failed [NAME...] Reset failed state for all, one, or more\n"
4883 " units\n"
4884 " list-dependencies [NAME] Recursively show units which are required\n"
4885 " or wanted by this unit or by which this\n"
4886 " unit is required or wanted\n\n"
4887 "Unit File Commands:\n"
4888 " list-unit-files [PATTERN...] List installed unit files\n"
4889 " enable NAME... Enable one or more unit files\n"
4890 " disable NAME... Disable one or more unit files\n"
4891 " reenable NAME... Reenable one or more unit files\n"
4892 " preset NAME... Enable/disable one or more unit files\n"
4893 " based on preset configuration\n"
4894 " is-enabled NAME... Check whether unit files are enabled\n\n"
4895 " mask NAME... Mask one or more units\n"
4896 " unmask NAME... Unmask one or more units\n"
4897 " link PATH... Link one or more units files into\n"
4898 " the search path\n"
4899 " get-default Get the name of the default target\n"
4900 " set-default NAME Set the default target\n\n"
4901 "Job Commands:\n"
4902 " list-jobs [PATTERN...] List jobs\n"
4903 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
4904 "Snapshot Commands:\n"
4905 " snapshot [NAME] Create a snapshot\n"
4906 " delete NAME... Remove one or more snapshots\n\n"
4907 "Environment Commands:\n"
4908 " show-environment Dump environment\n"
4909 " set-environment NAME=VALUE... Set one or more environment variables\n"
4910 " unset-environment NAME... Unset one or more environment variables\n\n"
4911 "Manager Lifecycle Commands:\n"
4912 " daemon-reload Reload systemd manager configuration\n"
4913 " daemon-reexec Reexecute systemd manager\n\n"
4914 "System Commands:\n"
4915 " default Enter system default mode\n"
4916 " rescue Enter system rescue mode\n"
4917 " emergency Enter system emergency mode\n"
4918 " halt Shut down and halt the system\n"
4919 " poweroff Shut down and power-off the system\n"
4920 " reboot [ARG] Shut down and reboot the system\n"
4921 " kexec Shut down and reboot the system with kexec\n"
4922 " exit Request user instance exit\n"
4923 " switch-root ROOT [INIT] Change to a different root file system\n"
4924 " suspend Suspend the system\n"
4925 " hibernate Hibernate the system\n"
4926 " hybrid-sleep Hibernate and suspend the system\n",
4927 program_invocation_short_name);
4928
4929 return 0;
4930 }
4931
4932 static int halt_help(void) {
4933
4934 printf("%s [OPTIONS...]%s\n\n"
4935 "%s the system.\n\n"
4936 " --help Show this help\n"
4937 " --halt Halt the machine\n"
4938 " -p --poweroff Switch off the machine\n"
4939 " --reboot Reboot the machine\n"
4940 " -f --force Force immediate halt/power-off/reboot\n"
4941 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
4942 " -d --no-wtmp Don't write wtmp record\n"
4943 " --no-wall Don't send wall message before halt/power-off/reboot\n",
4944 program_invocation_short_name,
4945 arg_action == ACTION_REBOOT ? " [ARG]" : "",
4946 arg_action == ACTION_REBOOT ? "Reboot" :
4947 arg_action == ACTION_POWEROFF ? "Power off" :
4948 "Halt");
4949
4950 return 0;
4951 }
4952
4953 static int shutdown_help(void) {
4954
4955 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
4956 "Shut down the system.\n\n"
4957 " --help Show this help\n"
4958 " -H --halt Halt the machine\n"
4959 " -P --poweroff Power-off the machine\n"
4960 " -r --reboot Reboot the machine\n"
4961 " -h Equivalent to --poweroff, overridden by --halt\n"
4962 " -k Don't halt/power-off/reboot, just send warnings\n"
4963 " --no-wall Don't send wall message before halt/power-off/reboot\n"
4964 " -c Cancel a pending shutdown\n",
4965 program_invocation_short_name);
4966
4967 return 0;
4968 }
4969
4970 static int telinit_help(void) {
4971
4972 printf("%s [OPTIONS...] {COMMAND}\n\n"
4973 "Send control commands to the init daemon.\n\n"
4974 " --help Show this help\n"
4975 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
4976 "Commands:\n"
4977 " 0 Power-off the machine\n"
4978 " 6 Reboot the machine\n"
4979 " 2, 3, 4, 5 Start runlevelX.target unit\n"
4980 " 1, s, S Enter rescue mode\n"
4981 " q, Q Reload init daemon configuration\n"
4982 " u, U Reexecute init daemon\n",
4983 program_invocation_short_name);
4984
4985 return 0;
4986 }
4987
4988 static int runlevel_help(void) {
4989
4990 printf("%s [OPTIONS...]\n\n"
4991 "Prints the previous and current runlevel of the init system.\n\n"
4992 " --help Show this help\n",
4993 program_invocation_short_name);
4994
4995 return 0;
4996 }
4997
4998 static int help_types(void) {
4999 int i;
5000 const char *t;
5001
5002 puts("Available unit types:");
5003 for (i = 0; i < _UNIT_TYPE_MAX; i++) {
5004 t = unit_type_to_string(i);
5005 if (t)
5006 puts(t);
5007 }
5008
5009 return 0;
5010 }
5011
5012 static int systemctl_parse_argv(int argc, char *argv[]) {
5013
5014 enum {
5015 ARG_FAIL = 0x100,
5016 ARG_REVERSE,
5017 ARG_AFTER,
5018 ARG_BEFORE,
5019 ARG_SHOW_TYPES,
5020 ARG_IRREVERSIBLE,
5021 ARG_IGNORE_DEPENDENCIES,
5022 ARG_VERSION,
5023 ARG_USER,
5024 ARG_SYSTEM,
5025 ARG_GLOBAL,
5026 ARG_NO_BLOCK,
5027 ARG_NO_LEGEND,
5028 ARG_NO_PAGER,
5029 ARG_NO_WALL,
5030 ARG_ROOT,
5031 ARG_NO_RELOAD,
5032 ARG_KILL_WHO,
5033 ARG_NO_ASK_PASSWORD,
5034 ARG_FAILED,
5035 ARG_RUNTIME,
5036 ARG_FORCE,
5037 ARG_PLAIN,
5038 ARG_STATE,
5039 ARG_JOB_MODE
5040 };
5041
5042 static const struct option options[] = {
5043 { "help", no_argument, NULL, 'h' },
5044 { "version", no_argument, NULL, ARG_VERSION },
5045 { "type", required_argument, NULL, 't' },
5046 { "property", required_argument, NULL, 'p' },
5047 { "all", no_argument, NULL, 'a' },
5048 { "reverse", no_argument, NULL, ARG_REVERSE },
5049 { "after", no_argument, NULL, ARG_AFTER },
5050 { "before", no_argument, NULL, ARG_BEFORE },
5051 { "show-types", no_argument, NULL, ARG_SHOW_TYPES },
5052 { "failed", no_argument, NULL, ARG_FAILED }, /* compatibility only */
5053 { "full", no_argument, NULL, 'l' },
5054 { "job-mode", required_argument, NULL, ARG_JOB_MODE },
5055 { "fail", no_argument, NULL, ARG_FAIL }, /* compatibility only */
5056 { "irreversible", no_argument, NULL, ARG_IRREVERSIBLE }, /* compatibility only */
5057 { "ignore-dependencies", no_argument, NULL, ARG_IGNORE_DEPENDENCIES }, /* compatibility only */
5058 { "ignore-inhibitors", no_argument, NULL, 'i' },
5059 { "user", no_argument, NULL, ARG_USER },
5060 { "system", no_argument, NULL, ARG_SYSTEM },
5061 { "global", no_argument, NULL, ARG_GLOBAL },
5062 { "no-block", no_argument, NULL, ARG_NO_BLOCK },
5063 { "no-legend", no_argument, NULL, ARG_NO_LEGEND },
5064 { "no-pager", no_argument, NULL, ARG_NO_PAGER },
5065 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5066 { "quiet", no_argument, NULL, 'q' },
5067 { "root", required_argument, NULL, ARG_ROOT },
5068 { "force", no_argument, NULL, ARG_FORCE },
5069 { "no-reload", no_argument, NULL, ARG_NO_RELOAD },
5070 { "kill-who", required_argument, NULL, ARG_KILL_WHO },
5071 { "signal", required_argument, NULL, 's' },
5072 { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD },
5073 { "host", required_argument, NULL, 'H' },
5074 { "machine", required_argument, NULL, 'M' },
5075 { "runtime", no_argument, NULL, ARG_RUNTIME },
5076 { "lines", required_argument, NULL, 'n' },
5077 { "output", required_argument, NULL, 'o' },
5078 { "plain", no_argument, NULL, ARG_PLAIN },
5079 { "state", required_argument, NULL, ARG_STATE },
5080 {}
5081 };
5082
5083 int c;
5084
5085 assert(argc >= 0);
5086 assert(argv);
5087
5088 while ((c = getopt_long(argc, argv, "ht:p:alqfs:H:M:n:o:i", options, NULL)) >= 0) {
5089
5090 switch (c) {
5091
5092 case 'h':
5093 return systemctl_help();
5094
5095 case ARG_VERSION:
5096 puts(PACKAGE_STRING);
5097 puts(SYSTEMD_FEATURES);
5098 return 0;
5099
5100 case 't': {
5101 char *word, *state;
5102 size_t size;
5103
5104 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
5105 _cleanup_free_ char *type;
5106
5107 type = strndup(word, size);
5108 if (!type)
5109 return -ENOMEM;
5110
5111 if (streq(type, "help")) {
5112 help_types();
5113 return 0;
5114 }
5115
5116 if (unit_type_from_string(type) >= 0) {
5117 if (strv_push(&arg_types, type))
5118 return log_oom();
5119 type = NULL;
5120 continue;
5121 }
5122
5123 /* It's much nicer to use --state= for
5124 * load states, but let's support this
5125 * in --types= too for compatibility
5126 * with old versions */
5127 if (unit_load_state_from_string(optarg) >= 0) {
5128 if (strv_push(&arg_states, type) < 0)
5129 return log_oom();
5130 type = NULL;
5131 continue;
5132 }
5133
5134 log_error("Unknown unit type or load state '%s'.", type);
5135 log_info("Use -t help to see a list of allowed values.");
5136 return -EINVAL;
5137 }
5138
5139 break;
5140 }
5141
5142 case 'p': {
5143 /* Make sure that if the empty property list
5144 was specified, we won't show any properties. */
5145 if (isempty(optarg) && !arg_properties) {
5146 arg_properties = new0(char*, 1);
5147 if (!arg_properties)
5148 return log_oom();
5149 } else {
5150 char *word, *state;
5151 size_t size;
5152
5153 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
5154 char *prop;
5155
5156 prop = strndup(word, size);
5157 if (!prop)
5158 return log_oom();
5159
5160 if (strv_push(&arg_properties, prop) < 0) {
5161 free(prop);
5162 return log_oom();
5163 }
5164 }
5165 }
5166
5167 /* If the user asked for a particular
5168 * property, show it to him, even if it is
5169 * empty. */
5170 arg_all = true;
5171
5172 break;
5173 }
5174
5175 case 'a':
5176 arg_all = true;
5177 break;
5178
5179 case ARG_REVERSE:
5180 arg_dependency = DEPENDENCY_REVERSE;
5181 break;
5182
5183 case ARG_AFTER:
5184 arg_dependency = DEPENDENCY_AFTER;
5185 break;
5186
5187 case ARG_BEFORE:
5188 arg_dependency = DEPENDENCY_BEFORE;
5189 break;
5190
5191 case ARG_SHOW_TYPES:
5192 arg_show_types = true;
5193 break;
5194
5195 case ARG_JOB_MODE:
5196 arg_job_mode = optarg;
5197 break;
5198
5199 case ARG_FAIL:
5200 arg_job_mode = "fail";
5201 break;
5202
5203 case ARG_IRREVERSIBLE:
5204 arg_job_mode = "replace-irreversibly";
5205 break;
5206
5207 case ARG_IGNORE_DEPENDENCIES:
5208 arg_job_mode = "ignore-dependencies";
5209 break;
5210
5211 case ARG_USER:
5212 arg_scope = UNIT_FILE_USER;
5213 break;
5214
5215 case ARG_SYSTEM:
5216 arg_scope = UNIT_FILE_SYSTEM;
5217 break;
5218
5219 case ARG_GLOBAL:
5220 arg_scope = UNIT_FILE_GLOBAL;
5221 break;
5222
5223 case ARG_NO_BLOCK:
5224 arg_no_block = true;
5225 break;
5226
5227 case ARG_NO_LEGEND:
5228 arg_no_legend = true;
5229 break;
5230
5231 case ARG_NO_PAGER:
5232 arg_no_pager = true;
5233 break;
5234
5235 case ARG_NO_WALL:
5236 arg_no_wall = true;
5237 break;
5238
5239 case ARG_ROOT:
5240 arg_root = optarg;
5241 break;
5242
5243 case 'l':
5244 arg_full = true;
5245 break;
5246
5247 case ARG_FAILED:
5248 if (strv_extend(&arg_states, "failed") < 0)
5249 return log_oom();
5250
5251 break;
5252
5253 case 'q':
5254 arg_quiet = true;
5255 break;
5256
5257 case ARG_FORCE:
5258 arg_force ++;
5259 break;
5260
5261 case 'f':
5262 arg_force ++;
5263 break;
5264
5265 case ARG_NO_RELOAD:
5266 arg_no_reload = true;
5267 break;
5268
5269 case ARG_KILL_WHO:
5270 arg_kill_who = optarg;
5271 break;
5272
5273 case 's':
5274 if ((arg_signal = signal_from_string_try_harder(optarg)) < 0) {
5275 log_error("Failed to parse signal string %s.", optarg);
5276 return -EINVAL;
5277 }
5278 break;
5279
5280 case ARG_NO_ASK_PASSWORD:
5281 arg_ask_password = false;
5282 break;
5283
5284 case 'H':
5285 arg_transport = BUS_TRANSPORT_REMOTE;
5286 arg_host = optarg;
5287 break;
5288
5289 case 'M':
5290 arg_transport = BUS_TRANSPORT_CONTAINER;
5291 arg_host = optarg;
5292 break;
5293
5294 case ARG_RUNTIME:
5295 arg_runtime = true;
5296 break;
5297
5298 case 'n':
5299 if (safe_atou(optarg, &arg_lines) < 0) {
5300 log_error("Failed to parse lines '%s'", optarg);
5301 return -EINVAL;
5302 }
5303 break;
5304
5305 case 'o':
5306 arg_output = output_mode_from_string(optarg);
5307 if (arg_output < 0) {
5308 log_error("Unknown output '%s'.", optarg);
5309 return -EINVAL;
5310 }
5311 break;
5312
5313 case 'i':
5314 arg_ignore_inhibitors = true;
5315 break;
5316
5317 case ARG_PLAIN:
5318 arg_plain = true;
5319 break;
5320
5321 case ARG_STATE: {
5322 char *word, *state;
5323 size_t size;
5324
5325 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
5326 char *s;
5327
5328 s = strndup(word, size);
5329 if (!s)
5330 return log_oom();
5331
5332 if (strv_push(&arg_states, s) < 0) {
5333 free(s);
5334 return log_oom();
5335 }
5336 }
5337 break;
5338 }
5339
5340 case '?':
5341 return -EINVAL;
5342
5343 default:
5344 assert_not_reached("Unhandled option");
5345 }
5346 }
5347
5348 if (arg_transport != BUS_TRANSPORT_LOCAL && arg_scope != UNIT_FILE_SYSTEM) {
5349 log_error("Cannot access user instance remotely.");
5350 return -EINVAL;
5351 }
5352
5353 return 1;
5354 }
5355
5356 static int halt_parse_argv(int argc, char *argv[]) {
5357
5358 enum {
5359 ARG_HELP = 0x100,
5360 ARG_HALT,
5361 ARG_REBOOT,
5362 ARG_NO_WALL
5363 };
5364
5365 static const struct option options[] = {
5366 { "help", no_argument, NULL, ARG_HELP },
5367 { "halt", no_argument, NULL, ARG_HALT },
5368 { "poweroff", no_argument, NULL, 'p' },
5369 { "reboot", no_argument, NULL, ARG_REBOOT },
5370 { "force", no_argument, NULL, 'f' },
5371 { "wtmp-only", no_argument, NULL, 'w' },
5372 { "no-wtmp", no_argument, NULL, 'd' },
5373 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5374 {}
5375 };
5376
5377 int c, r, runlevel;
5378
5379 assert(argc >= 0);
5380 assert(argv);
5381
5382 if (utmp_get_runlevel(&runlevel, NULL) >= 0)
5383 if (runlevel == '0' || runlevel == '6')
5384 arg_force = 2;
5385
5386 while ((c = getopt_long(argc, argv, "pfwdnih", options, NULL)) >= 0) {
5387 switch (c) {
5388
5389 case ARG_HELP:
5390 return halt_help();
5391
5392 case ARG_HALT:
5393 arg_action = ACTION_HALT;
5394 break;
5395
5396 case 'p':
5397 if (arg_action != ACTION_REBOOT)
5398 arg_action = ACTION_POWEROFF;
5399 break;
5400
5401 case ARG_REBOOT:
5402 arg_action = ACTION_REBOOT;
5403 break;
5404
5405 case 'f':
5406 arg_force = 2;
5407 break;
5408
5409 case 'w':
5410 arg_dry = true;
5411 break;
5412
5413 case 'd':
5414 arg_no_wtmp = true;
5415 break;
5416
5417 case ARG_NO_WALL:
5418 arg_no_wall = true;
5419 break;
5420
5421 case 'i':
5422 case 'h':
5423 case 'n':
5424 /* Compatibility nops */
5425 break;
5426
5427 case '?':
5428 return -EINVAL;
5429
5430 default:
5431 assert_not_reached("Unhandled option");
5432 }
5433 }
5434
5435 if (arg_action == ACTION_REBOOT && argc == optind + 1) {
5436 r = write_string_file(REBOOT_PARAM_FILE, argv[optind]);
5437 if (r < 0) {
5438 log_error("Failed to write reboot param to "
5439 REBOOT_PARAM_FILE": %s", strerror(-r));
5440 return r;
5441 }
5442 } else if (optind < argc) {
5443 log_error("Too many arguments.");
5444 return -EINVAL;
5445 }
5446
5447 return 1;
5448 }
5449
5450 static int parse_time_spec(const char *t, usec_t *_u) {
5451 assert(t);
5452 assert(_u);
5453
5454 if (streq(t, "now"))
5455 *_u = 0;
5456 else if (!strchr(t, ':')) {
5457 uint64_t u;
5458
5459 if (safe_atou64(t, &u) < 0)
5460 return -EINVAL;
5461
5462 *_u = now(CLOCK_REALTIME) + USEC_PER_MINUTE * u;
5463 } else {
5464 char *e = NULL;
5465 long hour, minute;
5466 struct tm tm = {};
5467 time_t s;
5468 usec_t n;
5469
5470 errno = 0;
5471 hour = strtol(t, &e, 10);
5472 if (errno > 0 || *e != ':' || hour < 0 || hour > 23)
5473 return -EINVAL;
5474
5475 minute = strtol(e+1, &e, 10);
5476 if (errno > 0 || *e != 0 || minute < 0 || minute > 59)
5477 return -EINVAL;
5478
5479 n = now(CLOCK_REALTIME);
5480 s = (time_t) (n / USEC_PER_SEC);
5481
5482 assert_se(localtime_r(&s, &tm));
5483
5484 tm.tm_hour = (int) hour;
5485 tm.tm_min = (int) minute;
5486 tm.tm_sec = 0;
5487
5488 assert_se(s = mktime(&tm));
5489
5490 *_u = (usec_t) s * USEC_PER_SEC;
5491
5492 while (*_u <= n)
5493 *_u += USEC_PER_DAY;
5494 }
5495
5496 return 0;
5497 }
5498
5499 static int shutdown_parse_argv(int argc, char *argv[]) {
5500
5501 enum {
5502 ARG_HELP = 0x100,
5503 ARG_NO_WALL
5504 };
5505
5506 static const struct option options[] = {
5507 { "help", no_argument, NULL, ARG_HELP },
5508 { "halt", no_argument, NULL, 'H' },
5509 { "poweroff", no_argument, NULL, 'P' },
5510 { "reboot", no_argument, NULL, 'r' },
5511 { "kexec", no_argument, NULL, 'K' }, /* not documented extension */
5512 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5513 {}
5514 };
5515
5516 int c, r;
5517
5518 assert(argc >= 0);
5519 assert(argv);
5520
5521 while ((c = getopt_long(argc, argv, "HPrhkt:afFc", options, NULL)) >= 0) {
5522 switch (c) {
5523
5524 case ARG_HELP:
5525 return shutdown_help();
5526
5527 case 'H':
5528 arg_action = ACTION_HALT;
5529 break;
5530
5531 case 'P':
5532 arg_action = ACTION_POWEROFF;
5533 break;
5534
5535 case 'r':
5536 if (kexec_loaded())
5537 arg_action = ACTION_KEXEC;
5538 else
5539 arg_action = ACTION_REBOOT;
5540 break;
5541
5542 case 'K':
5543 arg_action = ACTION_KEXEC;
5544 break;
5545
5546 case 'h':
5547 if (arg_action != ACTION_HALT)
5548 arg_action = ACTION_POWEROFF;
5549 break;
5550
5551 case 'k':
5552 arg_dry = true;
5553 break;
5554
5555 case ARG_NO_WALL:
5556 arg_no_wall = true;
5557 break;
5558
5559 case 't':
5560 case 'a':
5561 /* Compatibility nops */
5562 break;
5563
5564 case 'c':
5565 arg_action = ACTION_CANCEL_SHUTDOWN;
5566 break;
5567
5568 case '?':
5569 return -EINVAL;
5570
5571 default:
5572 assert_not_reached("Unhandled option");
5573 }
5574 }
5575
5576 if (argc > optind && arg_action != ACTION_CANCEL_SHUTDOWN) {
5577 r = parse_time_spec(argv[optind], &arg_when);
5578 if (r < 0) {
5579 log_error("Failed to parse time specification: %s", argv[optind]);
5580 return r;
5581 }
5582 } else
5583 arg_when = now(CLOCK_REALTIME) + USEC_PER_MINUTE;
5584
5585 if (argc > optind && arg_action == ACTION_CANCEL_SHUTDOWN)
5586 /* No time argument for shutdown cancel */
5587 arg_wall = argv + optind;
5588 else if (argc > optind + 1)
5589 /* We skip the time argument */
5590 arg_wall = argv + optind + 1;
5591
5592 optind = argc;
5593
5594 return 1;
5595 }
5596
5597 static int telinit_parse_argv(int argc, char *argv[]) {
5598
5599 enum {
5600 ARG_HELP = 0x100,
5601 ARG_NO_WALL
5602 };
5603
5604 static const struct option options[] = {
5605 { "help", no_argument, NULL, ARG_HELP },
5606 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5607 {}
5608 };
5609
5610 static const struct {
5611 char from;
5612 enum action to;
5613 } table[] = {
5614 { '0', ACTION_POWEROFF },
5615 { '6', ACTION_REBOOT },
5616 { '1', ACTION_RESCUE },
5617 { '2', ACTION_RUNLEVEL2 },
5618 { '3', ACTION_RUNLEVEL3 },
5619 { '4', ACTION_RUNLEVEL4 },
5620 { '5', ACTION_RUNLEVEL5 },
5621 { 's', ACTION_RESCUE },
5622 { 'S', ACTION_RESCUE },
5623 { 'q', ACTION_RELOAD },
5624 { 'Q', ACTION_RELOAD },
5625 { 'u', ACTION_REEXEC },
5626 { 'U', ACTION_REEXEC }
5627 };
5628
5629 unsigned i;
5630 int c;
5631
5632 assert(argc >= 0);
5633 assert(argv);
5634
5635 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0) {
5636 switch (c) {
5637
5638 case ARG_HELP:
5639 return telinit_help();
5640
5641 case ARG_NO_WALL:
5642 arg_no_wall = true;
5643 break;
5644
5645 case '?':
5646 return -EINVAL;
5647
5648 default:
5649 assert_not_reached("Unhandled option");
5650 }
5651 }
5652
5653 if (optind >= argc) {
5654 telinit_help();
5655 return -EINVAL;
5656 }
5657
5658 if (optind + 1 < argc) {
5659 log_error("Too many arguments.");
5660 return -EINVAL;
5661 }
5662
5663 if (strlen(argv[optind]) != 1) {
5664 log_error("Expected single character argument.");
5665 return -EINVAL;
5666 }
5667
5668 for (i = 0; i < ELEMENTSOF(table); i++)
5669 if (table[i].from == argv[optind][0])
5670 break;
5671
5672 if (i >= ELEMENTSOF(table)) {
5673 log_error("Unknown command '%s'.", argv[optind]);
5674 return -EINVAL;
5675 }
5676
5677 arg_action = table[i].to;
5678
5679 optind ++;
5680
5681 return 1;
5682 }
5683
5684 static int runlevel_parse_argv(int argc, char *argv[]) {
5685
5686 enum {
5687 ARG_HELP = 0x100,
5688 };
5689
5690 static const struct option options[] = {
5691 { "help", no_argument, NULL, ARG_HELP },
5692 {}
5693 };
5694
5695 int c;
5696
5697 assert(argc >= 0);
5698 assert(argv);
5699
5700 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0) {
5701 switch (c) {
5702
5703 case ARG_HELP:
5704 return runlevel_help();
5705 return 0;
5706
5707 case '?':
5708 return -EINVAL;
5709
5710 default:
5711 assert_not_reached("Unhandled option");
5712 }
5713 }
5714
5715 if (optind < argc) {
5716 log_error("Too many arguments.");
5717 return -EINVAL;
5718 }
5719
5720 return 1;
5721 }
5722
5723 static int parse_argv(int argc, char *argv[]) {
5724 assert(argc >= 0);
5725 assert(argv);
5726
5727 if (program_invocation_short_name) {
5728
5729 if (strstr(program_invocation_short_name, "halt")) {
5730 arg_action = ACTION_HALT;
5731 return halt_parse_argv(argc, argv);
5732 } else if (strstr(program_invocation_short_name, "poweroff")) {
5733 arg_action = ACTION_POWEROFF;
5734 return halt_parse_argv(argc, argv);
5735 } else if (strstr(program_invocation_short_name, "reboot")) {
5736 if (kexec_loaded())
5737 arg_action = ACTION_KEXEC;
5738 else
5739 arg_action = ACTION_REBOOT;
5740 return halt_parse_argv(argc, argv);
5741 } else if (strstr(program_invocation_short_name, "shutdown")) {
5742 arg_action = ACTION_POWEROFF;
5743 return shutdown_parse_argv(argc, argv);
5744 } else if (strstr(program_invocation_short_name, "init")) {
5745
5746 if (sd_booted() > 0) {
5747 arg_action = _ACTION_INVALID;
5748 return telinit_parse_argv(argc, argv);
5749 } else {
5750 /* Hmm, so some other init system is
5751 * running, we need to forward this
5752 * request to it. For now we simply
5753 * guess that it is Upstart. */
5754
5755 execv(TELINIT, argv);
5756
5757 log_error("Couldn't find an alternative telinit implementation to spawn.");
5758 return -EIO;
5759 }
5760
5761 } else if (strstr(program_invocation_short_name, "runlevel")) {
5762 arg_action = ACTION_RUNLEVEL;
5763 return runlevel_parse_argv(argc, argv);
5764 }
5765 }
5766
5767 arg_action = ACTION_SYSTEMCTL;
5768 return systemctl_parse_argv(argc, argv);
5769 }
5770
5771 _pure_ static int action_to_runlevel(void) {
5772
5773 static const char table[_ACTION_MAX] = {
5774 [ACTION_HALT] = '0',
5775 [ACTION_POWEROFF] = '0',
5776 [ACTION_REBOOT] = '6',
5777 [ACTION_RUNLEVEL2] = '2',
5778 [ACTION_RUNLEVEL3] = '3',
5779 [ACTION_RUNLEVEL4] = '4',
5780 [ACTION_RUNLEVEL5] = '5',
5781 [ACTION_RESCUE] = '1'
5782 };
5783
5784 assert(arg_action < _ACTION_MAX);
5785
5786 return table[arg_action];
5787 }
5788
5789 static int talk_initctl(void) {
5790
5791 struct init_request request = {
5792 .magic = INIT_MAGIC,
5793 .sleeptime = 0,
5794 .cmd = INIT_CMD_RUNLVL
5795 };
5796
5797 _cleanup_close_ int fd = -1;
5798 char rl;
5799 int r;
5800
5801 rl = action_to_runlevel();
5802 if (!rl)
5803 return 0;
5804
5805 request.runlevel = rl;
5806
5807 fd = open(INIT_FIFO, O_WRONLY|O_NDELAY|O_CLOEXEC|O_NOCTTY);
5808 if (fd < 0) {
5809 if (errno == ENOENT)
5810 return 0;
5811
5812 log_error("Failed to open "INIT_FIFO": %m");
5813 return -errno;
5814 }
5815
5816 errno = 0;
5817 r = loop_write(fd, &request, sizeof(request), false) != sizeof(request);
5818 if (r) {
5819 log_error("Failed to write to "INIT_FIFO": %m");
5820 return errno > 0 ? -errno : -EIO;
5821 }
5822
5823 return 1;
5824 }
5825
5826 static int systemctl_main(sd_bus *bus, int argc, char *argv[], int bus_error) {
5827
5828 static const struct {
5829 const char* verb;
5830 const enum {
5831 MORE,
5832 LESS,
5833 EQUAL
5834 } argc_cmp;
5835 const int argc;
5836 int (* const dispatch)(sd_bus *bus, char **args);
5837 const enum {
5838 NOBUS = 1,
5839 FORCE,
5840 } bus;
5841 } verbs[] = {
5842 { "list-units", MORE, 0, list_units },
5843 { "list-unit-files", MORE, 1, list_unit_files, NOBUS },
5844 { "list-sockets", MORE, 1, list_sockets },
5845 { "list-timers", MORE, 1, list_timers },
5846 { "list-jobs", MORE, 1, list_jobs },
5847 { "clear-jobs", EQUAL, 1, daemon_reload },
5848 { "cancel", MORE, 2, cancel_job },
5849 { "start", MORE, 2, start_unit },
5850 { "stop", MORE, 2, start_unit },
5851 { "condstop", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
5852 { "reload", MORE, 2, start_unit },
5853 { "restart", MORE, 2, start_unit },
5854 { "try-restart", MORE, 2, start_unit },
5855 { "reload-or-restart", MORE, 2, start_unit },
5856 { "reload-or-try-restart", MORE, 2, start_unit },
5857 { "force-reload", MORE, 2, start_unit }, /* For compatibility with SysV */
5858 { "condreload", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
5859 { "condrestart", MORE, 2, start_unit }, /* For compatibility with RH */
5860 { "isolate", EQUAL, 2, start_unit },
5861 { "kill", MORE, 2, kill_unit },
5862 { "is-active", MORE, 2, check_unit_active },
5863 { "check", MORE, 2, check_unit_active },
5864 { "is-failed", MORE, 2, check_unit_failed },
5865 { "show", MORE, 1, show },
5866 { "cat", MORE, 2, cat },
5867 { "status", MORE, 1, show },
5868 { "help", MORE, 2, show },
5869 { "snapshot", LESS, 2, snapshot },
5870 { "delete", MORE, 2, delete_snapshot },
5871 { "daemon-reload", EQUAL, 1, daemon_reload },
5872 { "daemon-reexec", EQUAL, 1, daemon_reload },
5873 { "show-environment", EQUAL, 1, show_environment },
5874 { "set-environment", MORE, 2, set_environment },
5875 { "unset-environment", MORE, 2, set_environment },
5876 { "halt", EQUAL, 1, start_special, FORCE },
5877 { "poweroff", EQUAL, 1, start_special, FORCE },
5878 { "reboot", EQUAL, 1, start_special, FORCE },
5879 { "kexec", EQUAL, 1, start_special },
5880 { "suspend", EQUAL, 1, start_special },
5881 { "hibernate", EQUAL, 1, start_special },
5882 { "hybrid-sleep", EQUAL, 1, start_special },
5883 { "default", EQUAL, 1, start_special },
5884 { "rescue", EQUAL, 1, start_special },
5885 { "emergency", EQUAL, 1, start_special },
5886 { "exit", EQUAL, 1, start_special },
5887 { "reset-failed", MORE, 1, reset_failed },
5888 { "enable", MORE, 2, enable_unit, NOBUS },
5889 { "disable", MORE, 2, enable_unit, NOBUS },
5890 { "is-enabled", MORE, 2, unit_is_enabled, NOBUS },
5891 { "reenable", MORE, 2, enable_unit, NOBUS },
5892 { "preset", MORE, 2, enable_unit, NOBUS },
5893 { "mask", MORE, 2, enable_unit, NOBUS },
5894 { "unmask", MORE, 2, enable_unit, NOBUS },
5895 { "link", MORE, 2, enable_unit, NOBUS },
5896 { "switch-root", MORE, 2, switch_root },
5897 { "list-dependencies", LESS, 2, list_dependencies },
5898 { "set-default", EQUAL, 2, set_default, NOBUS },
5899 { "get-default", EQUAL, 1, get_default, NOBUS },
5900 { "set-property", MORE, 3, set_property },
5901 {}
5902 }, *verb = verbs;
5903
5904 int left;
5905
5906 assert(argc >= 0);
5907 assert(argv);
5908
5909 left = argc - optind;
5910
5911 /* Special rule: no arguments (left == 0) means "list-units" */
5912 if (left > 0) {
5913 if (streq(argv[optind], "help") && !argv[optind+1]) {
5914 log_error("This command expects one or more "
5915 "unit names. Did you mean --help?");
5916 return -EINVAL;
5917 }
5918
5919 for (; verb->verb; verb++)
5920 if (streq(argv[optind], verb->verb))
5921 goto found;
5922
5923 log_error("Unknown operation '%s'.", argv[optind]);
5924 return -EINVAL;
5925 }
5926 found:
5927
5928 switch (verb->argc_cmp) {
5929
5930 case EQUAL:
5931 if (left != verb->argc) {
5932 log_error("Invalid number of arguments.");
5933 return -EINVAL;
5934 }
5935
5936 break;
5937
5938 case MORE:
5939 if (left < verb->argc) {
5940 log_error("Too few arguments.");
5941 return -EINVAL;
5942 }
5943
5944 break;
5945
5946 case LESS:
5947 if (left > verb->argc) {
5948 log_error("Too many arguments.");
5949 return -EINVAL;
5950 }
5951
5952 break;
5953
5954 default:
5955 assert_not_reached("Unknown comparison operator.");
5956 }
5957
5958 /* Require a bus connection for all operations but
5959 * enable/disable */
5960 if (verb->bus == NOBUS) {
5961 if (!bus && !avoid_bus()) {
5962 log_error("Failed to get D-Bus connection: %s", strerror(-bus_error));
5963 return -EIO;
5964 }
5965
5966 } else {
5967 if (running_in_chroot() > 0) {
5968 log_info("Running in chroot, ignoring request.");
5969 return 0;
5970 }
5971
5972 if ((verb->bus != FORCE || arg_force <= 0) && !bus) {
5973 log_error("Failed to get D-Bus connection: %s", strerror(-bus_error));
5974 return -EIO;
5975 }
5976 }
5977
5978 return verb->dispatch(bus, argv + optind);
5979 }
5980
5981 static int send_shutdownd(usec_t t, char mode, bool dry_run, bool warn, const char *message) {
5982
5983 struct sd_shutdown_command c = {
5984 .usec = t,
5985 .mode = mode,
5986 .dry_run = dry_run,
5987 .warn_wall = warn,
5988 };
5989
5990 union sockaddr_union sockaddr = {
5991 .un.sun_family = AF_UNIX,
5992 .un.sun_path = "/run/systemd/shutdownd",
5993 };
5994
5995 struct iovec iovec[2] = {{
5996 .iov_base = (char*) &c,
5997 .iov_len = offsetof(struct sd_shutdown_command, wall_message),
5998 }};
5999
6000 struct msghdr msghdr = {
6001 .msg_name = &sockaddr,
6002 .msg_namelen = offsetof(struct sockaddr_un, sun_path)
6003 + sizeof("/run/systemd/shutdownd") - 1,
6004 .msg_iov = iovec,
6005 .msg_iovlen = 1,
6006 };
6007
6008 _cleanup_close_ int fd;
6009
6010 fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
6011 if (fd < 0)
6012 return -errno;
6013
6014 if (!isempty(message)) {
6015 iovec[1].iov_base = (char*) message;
6016 iovec[1].iov_len = strlen(message);
6017 msghdr.msg_iovlen++;
6018 }
6019
6020 if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) < 0)
6021 return -errno;
6022
6023 return 0;
6024 }
6025
6026 static int reload_with_fallback(sd_bus *bus) {
6027
6028 if (bus) {
6029 /* First, try systemd via D-Bus. */
6030 if (daemon_reload(bus, NULL) >= 0)
6031 return 0;
6032 }
6033
6034 /* Nothing else worked, so let's try signals */
6035 assert(arg_action == ACTION_RELOAD || arg_action == ACTION_REEXEC);
6036
6037 if (kill(1, arg_action == ACTION_RELOAD ? SIGHUP : SIGTERM) < 0) {
6038 log_error("kill() failed: %m");
6039 return -errno;
6040 }
6041
6042 return 0;
6043 }
6044
6045 static int start_with_fallback(sd_bus *bus) {
6046
6047 if (bus) {
6048 /* First, try systemd via D-Bus. */
6049 if (start_unit(bus, NULL) >= 0)
6050 goto done;
6051 }
6052
6053 /* Nothing else worked, so let's try
6054 * /dev/initctl */
6055 if (talk_initctl() > 0)
6056 goto done;
6057
6058 log_error("Failed to talk to init daemon.");
6059 return -EIO;
6060
6061 done:
6062 warn_wall(arg_action);
6063 return 0;
6064 }
6065
6066 static int halt_now(enum action a) {
6067
6068 /* Make sure C-A-D is handled by the kernel from this
6069 * point on... */
6070 reboot(RB_ENABLE_CAD);
6071
6072 switch (a) {
6073
6074 case ACTION_HALT:
6075 log_info("Halting.");
6076 reboot(RB_HALT_SYSTEM);
6077 return -errno;
6078
6079 case ACTION_POWEROFF:
6080 log_info("Powering off.");
6081 reboot(RB_POWER_OFF);
6082 return -errno;
6083
6084 case ACTION_REBOOT: {
6085 _cleanup_free_ char *param = NULL;
6086
6087 if (read_one_line_file(REBOOT_PARAM_FILE, &param) >= 0) {
6088 log_info("Rebooting with argument '%s'.", param);
6089 syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
6090 LINUX_REBOOT_CMD_RESTART2, param);
6091 }
6092
6093 log_info("Rebooting.");
6094 reboot(RB_AUTOBOOT);
6095 return -errno;
6096 }
6097
6098 default:
6099 assert_not_reached("Unknown action.");
6100 }
6101 }
6102
6103 static int halt_main(sd_bus *bus) {
6104 int r;
6105
6106 r = check_inhibitors(bus, arg_action);
6107 if (r < 0)
6108 return r;
6109
6110 if (geteuid() != 0) {
6111 /* Try logind if we are a normal user and no special
6112 * mode applies. Maybe PolicyKit allows us to shutdown
6113 * the machine. */
6114
6115 if (arg_when <= 0 &&
6116 !arg_dry &&
6117 arg_force <= 0 &&
6118 (arg_action == ACTION_POWEROFF ||
6119 arg_action == ACTION_REBOOT)) {
6120 r = reboot_with_logind(bus, arg_action);
6121 if (r >= 0)
6122 return r;
6123 }
6124
6125 log_error("Must be root.");
6126 return -EPERM;
6127 }
6128
6129 if (arg_when > 0) {
6130 _cleanup_free_ char *m;
6131
6132 m = strv_join(arg_wall, " ");
6133 if (!m)
6134 return log_oom();
6135
6136 r = send_shutdownd(arg_when,
6137 arg_action == ACTION_HALT ? 'H' :
6138 arg_action == ACTION_POWEROFF ? 'P' :
6139 arg_action == ACTION_KEXEC ? 'K' :
6140 'r',
6141 arg_dry,
6142 !arg_no_wall,
6143 m);
6144
6145 if (r < 0)
6146 log_warning("Failed to talk to shutdownd, proceeding with immediate shutdown: %s", strerror(-r));
6147 else {
6148 char date[FORMAT_TIMESTAMP_MAX];
6149
6150 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.",
6151 format_timestamp(date, sizeof(date), arg_when));
6152 return 0;
6153 }
6154 }
6155
6156 if (!arg_dry && !arg_force)
6157 return start_with_fallback(bus);
6158
6159 if (!arg_no_wtmp) {
6160 if (sd_booted() > 0)
6161 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
6162 else {
6163 r = utmp_put_shutdown();
6164 if (r < 0)
6165 log_warning("Failed to write utmp record: %s", strerror(-r));
6166 }
6167 }
6168
6169 if (arg_dry)
6170 return 0;
6171
6172 r = halt_now(arg_action);
6173 log_error("Failed to reboot: %s", strerror(-r));
6174
6175 return r;
6176 }
6177
6178 static int runlevel_main(void) {
6179 int r, runlevel, previous;
6180
6181 r = utmp_get_runlevel(&runlevel, &previous);
6182 if (r < 0) {
6183 puts("unknown");
6184 return r;
6185 }
6186
6187 printf("%c %c\n",
6188 previous <= 0 ? 'N' : previous,
6189 runlevel <= 0 ? 'N' : runlevel);
6190
6191 return 0;
6192 }
6193
6194 int main(int argc, char*argv[]) {
6195 _cleanup_bus_unref_ sd_bus *bus = NULL;
6196 int r;
6197
6198 setlocale(LC_ALL, "");
6199 log_parse_environment();
6200 log_open();
6201
6202 /* Explicitly not on_tty() to avoid setting cached value.
6203 * This becomes relevant for piping output which might be
6204 * ellipsized. */
6205 original_stdout_is_tty = isatty(STDOUT_FILENO);
6206
6207 r = parse_argv(argc, argv);
6208 if (r <= 0)
6209 goto finish;
6210
6211 /* /sbin/runlevel doesn't need to communicate via D-Bus, so
6212 * let's shortcut this */
6213 if (arg_action == ACTION_RUNLEVEL) {
6214 r = runlevel_main();
6215 goto finish;
6216 }
6217
6218 if (running_in_chroot() > 0 && arg_action != ACTION_SYSTEMCTL) {
6219 log_info("Running in chroot, ignoring request.");
6220 r = 0;
6221 goto finish;
6222 }
6223
6224 if (!avoid_bus())
6225 r = bus_open_transport_systemd(arg_transport, arg_host, arg_scope != UNIT_FILE_SYSTEM, &bus);
6226
6227 /* systemctl_main() will print an error message for the bus
6228 * connection, but only if it needs to */
6229
6230 switch (arg_action) {
6231
6232 case ACTION_SYSTEMCTL:
6233 r = systemctl_main(bus, argc, argv, r);
6234 break;
6235
6236 case ACTION_HALT:
6237 case ACTION_POWEROFF:
6238 case ACTION_REBOOT:
6239 case ACTION_KEXEC:
6240 r = halt_main(bus);
6241 break;
6242
6243 case ACTION_RUNLEVEL2:
6244 case ACTION_RUNLEVEL3:
6245 case ACTION_RUNLEVEL4:
6246 case ACTION_RUNLEVEL5:
6247 case ACTION_RESCUE:
6248 case ACTION_EMERGENCY:
6249 case ACTION_DEFAULT:
6250 r = start_with_fallback(bus);
6251 break;
6252
6253 case ACTION_RELOAD:
6254 case ACTION_REEXEC:
6255 r = reload_with_fallback(bus);
6256 break;
6257
6258 case ACTION_CANCEL_SHUTDOWN: {
6259 _cleanup_free_ char *m = NULL;
6260
6261 if (arg_wall) {
6262 m = strv_join(arg_wall, " ");
6263 if (!m) {
6264 r = log_oom();
6265 goto finish;
6266 }
6267 }
6268
6269 r = send_shutdownd(arg_when, SD_SHUTDOWN_NONE, false, !arg_no_wall, m);
6270 if (r < 0)
6271 log_warning("Failed to talk to shutdownd, shutdown hasn't been cancelled: %s", strerror(-r));
6272 break;
6273 }
6274
6275 case ACTION_RUNLEVEL:
6276 case _ACTION_INVALID:
6277 default:
6278 assert_not_reached("Unknown action");
6279 }
6280
6281 finish:
6282 pager_close();
6283 ask_password_agent_close();
6284 polkit_agent_close();
6285
6286 strv_free(arg_types);
6287 strv_free(arg_states);
6288 strv_free(arg_properties);
6289
6290 return r < 0 ? EXIT_FAILURE : r;
6291 }