]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/systemctl/systemctl.c
systemctl: make "systemctl is-system-running" return "offline" if we are not booted...
[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 <errno.h>
24 #include <fcntl.h>
25 #include <getopt.h>
26 #include <linux/reboot.h>
27 #include <locale.h>
28 #include <stdbool.h>
29 #include <stddef.h>
30 #include <stdio.h>
31 #include <string.h>
32 #include <sys/reboot.h>
33 #include <sys/socket.h>
34 #include <unistd.h>
35
36 #include "sd-bus.h"
37 #include "sd-daemon.h"
38 #include "sd-login.h"
39
40 #include "bus-common-errors.h"
41 #include "bus-error.h"
42 #include "bus-message.h"
43 #include "bus-util.h"
44 #include "cgroup-show.h"
45 #include "cgroup-util.h"
46 #include "copy.h"
47 #include "dropin.h"
48 #include "efivars.h"
49 #include "env-util.h"
50 #include "exit-status.h"
51 #include "fileio.h"
52 #include "formats-util.h"
53 #include "hostname-util.h"
54 #include "initreq.h"
55 #include "install.h"
56 #include "list.h"
57 #include "log.h"
58 #include "logs-show.h"
59 #include "macro.h"
60 #include "mkdir.h"
61 #include "pager.h"
62 #include "path-lookup.h"
63 #include "path-util.h"
64 #include "process-util.h"
65 #include "set.h"
66 #include "signal-util.h"
67 #include "socket-util.h"
68 #include "spawn-ask-password-agent.h"
69 #include "spawn-polkit-agent.h"
70 #include "special.h"
71 #include "strv.h"
72 #include "terminal-util.h"
73 #include "unit-name.h"
74 #include "util.h"
75 #include "utmp-wtmp.h"
76
77 static char **arg_types = NULL;
78 static char **arg_states = NULL;
79 static char **arg_properties = NULL;
80 static bool arg_all = false;
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 bool arg_recursive = false;
102 static int arg_force = 0;
103 static bool arg_ask_password = false;
104 static bool arg_runtime = false;
105 static UnitFilePresetMode arg_preset_mode = UNIT_FILE_PRESET_FULL;
106 static char **arg_wall = NULL;
107 static const char *arg_kill_who = NULL;
108 static int arg_signal = SIGTERM;
109 static const char *arg_root = NULL;
110 static usec_t arg_when = 0;
111 static enum action {
112 _ACTION_INVALID,
113 ACTION_SYSTEMCTL,
114 ACTION_HALT,
115 ACTION_POWEROFF,
116 ACTION_REBOOT,
117 ACTION_KEXEC,
118 ACTION_EXIT,
119 ACTION_SUSPEND,
120 ACTION_HIBERNATE,
121 ACTION_HYBRID_SLEEP,
122 ACTION_RUNLEVEL2,
123 ACTION_RUNLEVEL3,
124 ACTION_RUNLEVEL4,
125 ACTION_RUNLEVEL5,
126 ACTION_RESCUE,
127 ACTION_EMERGENCY,
128 ACTION_DEFAULT,
129 ACTION_RELOAD,
130 ACTION_REEXEC,
131 ACTION_RUNLEVEL,
132 ACTION_CANCEL_SHUTDOWN,
133 _ACTION_MAX
134 } arg_action = ACTION_SYSTEMCTL;
135 static BusTransport arg_transport = BUS_TRANSPORT_LOCAL;
136 static char *arg_host = NULL;
137 static unsigned arg_lines = 10;
138 static OutputMode arg_output = OUTPUT_SHORT;
139 static bool arg_plain = false;
140 static bool arg_firmware_setup = false;
141 static bool arg_now = false;
142
143 static bool original_stdout_is_tty;
144
145 static int daemon_reload(sd_bus *bus, char **args);
146 static int halt_now(enum action a);
147 static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet);
148
149 static char** strv_skip_first(char **strv) {
150 if (strv_length(strv) > 0)
151 return strv + 1;
152 return NULL;
153 }
154
155 static void pager_open_if_enabled(void) {
156
157 if (arg_no_pager)
158 return;
159
160 pager_open(false);
161 }
162
163 static void ask_password_agent_open_if_enabled(void) {
164
165 /* Open the password agent as a child process if necessary */
166
167 if (!arg_ask_password)
168 return;
169
170 if (arg_scope != UNIT_FILE_SYSTEM)
171 return;
172
173 if (arg_transport != BUS_TRANSPORT_LOCAL)
174 return;
175
176 ask_password_agent_open();
177 }
178
179 static void polkit_agent_open_if_enabled(void) {
180
181 /* Open the polkit agent as a child process if necessary */
182
183 if (!arg_ask_password)
184 return;
185
186 if (arg_scope != UNIT_FILE_SYSTEM)
187 return;
188
189 if (arg_transport != BUS_TRANSPORT_LOCAL)
190 return;
191
192 polkit_agent_open();
193 }
194
195 static OutputFlags get_output_flags(void) {
196 return
197 arg_all * OUTPUT_SHOW_ALL |
198 arg_full * OUTPUT_FULL_WIDTH |
199 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
200 on_tty() * OUTPUT_COLOR |
201 !arg_quiet * OUTPUT_WARN_CUTOFF;
202 }
203
204 static int translate_bus_error_to_exit_status(int r, const sd_bus_error *error) {
205 assert(error);
206
207 if (!sd_bus_error_is_set(error))
208 return r;
209
210 if (sd_bus_error_has_name(error, SD_BUS_ERROR_ACCESS_DENIED) ||
211 sd_bus_error_has_name(error, BUS_ERROR_ONLY_BY_DEPENDENCY) ||
212 sd_bus_error_has_name(error, BUS_ERROR_NO_ISOLATION) ||
213 sd_bus_error_has_name(error, BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE))
214 return EXIT_NOPERMISSION;
215
216 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT))
217 return EXIT_NOTINSTALLED;
218
219 if (sd_bus_error_has_name(error, BUS_ERROR_JOB_TYPE_NOT_APPLICABLE) ||
220 sd_bus_error_has_name(error, SD_BUS_ERROR_NOT_SUPPORTED))
221 return EXIT_NOTIMPLEMENTED;
222
223 if (sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED))
224 return EXIT_NOTCONFIGURED;
225
226 if (r != 0)
227 return r;
228
229 return EXIT_FAILURE;
230 }
231
232 static void warn_wall(enum action a) {
233 static const char *table[_ACTION_MAX] = {
234 [ACTION_HALT] = "The system is going down for system halt NOW!",
235 [ACTION_REBOOT] = "The system is going down for reboot NOW!",
236 [ACTION_POWEROFF] = "The system is going down for power-off NOW!",
237 [ACTION_KEXEC] = "The system is going down for kexec reboot NOW!",
238 [ACTION_RESCUE] = "The system is going down to rescue mode NOW!",
239 [ACTION_EMERGENCY] = "The system is going down to emergency mode NOW!",
240 [ACTION_CANCEL_SHUTDOWN] = "The system shutdown has been cancelled NOW!"
241 };
242
243 if (arg_no_wall)
244 return;
245
246 if (arg_wall) {
247 _cleanup_free_ char *p;
248
249 p = strv_join(arg_wall, " ");
250 if (!p) {
251 log_oom();
252 return;
253 }
254
255 if (*p) {
256 utmp_wall(p, NULL, NULL, NULL, NULL);
257 return;
258 }
259 }
260
261 if (!table[a])
262 return;
263
264 utmp_wall(table[a], NULL, NULL, NULL, NULL);
265 }
266
267 static bool avoid_bus(void) {
268
269 if (running_in_chroot() > 0)
270 return true;
271
272 if (sd_booted() <= 0)
273 return true;
274
275 if (!isempty(arg_root))
276 return true;
277
278 if (arg_scope == UNIT_FILE_GLOBAL)
279 return true;
280
281 return false;
282 }
283
284 static int compare_unit_info(const void *a, const void *b) {
285 const UnitInfo *u = a, *v = b;
286 const char *d1, *d2;
287 int r;
288
289 /* First, order by machine */
290 if (!u->machine && v->machine)
291 return -1;
292 if (u->machine && !v->machine)
293 return 1;
294 if (u->machine && v->machine) {
295 r = strcasecmp(u->machine, v->machine);
296 if (r != 0)
297 return r;
298 }
299
300 /* Second, order by unit type */
301 d1 = strrchr(u->id, '.');
302 d2 = strrchr(v->id, '.');
303 if (d1 && d2) {
304 r = strcasecmp(d1, d2);
305 if (r != 0)
306 return r;
307 }
308
309 /* Third, order by name */
310 return strcasecmp(u->id, v->id);
311 }
312
313 static bool output_show_unit(const UnitInfo *u, char **patterns) {
314 if (!strv_fnmatch_or_empty(patterns, u->id, FNM_NOESCAPE))
315 return false;
316
317 if (arg_types) {
318 const char *dot;
319
320 dot = strrchr(u->id, '.');
321 if (!dot)
322 return false;
323
324 if (!strv_find(arg_types, dot+1))
325 return false;
326 }
327
328 if (arg_all)
329 return true;
330
331 if (u->job_id > 0)
332 return true;
333
334 if (streq(u->active_state, "inactive") || u->following[0])
335 return false;
336
337 return true;
338 }
339
340 static int output_units_list(const UnitInfo *unit_infos, unsigned c) {
341 unsigned circle_len = 0, id_len, max_id_len, load_len, active_len, sub_len, job_len, desc_len;
342 const UnitInfo *u;
343 unsigned n_shown = 0;
344 int job_count = 0;
345
346 max_id_len = strlen("UNIT");
347 load_len = strlen("LOAD");
348 active_len = strlen("ACTIVE");
349 sub_len = strlen("SUB");
350 job_len = strlen("JOB");
351 desc_len = 0;
352
353 for (u = unit_infos; u < unit_infos + c; u++) {
354 max_id_len = MAX(max_id_len, strlen(u->id) + (u->machine ? strlen(u->machine)+1 : 0));
355 load_len = MAX(load_len, strlen(u->load_state));
356 active_len = MAX(active_len, strlen(u->active_state));
357 sub_len = MAX(sub_len, strlen(u->sub_state));
358
359 if (u->job_id != 0) {
360 job_len = MAX(job_len, strlen(u->job_type));
361 job_count++;
362 }
363
364 if (!arg_no_legend &&
365 (streq(u->active_state, "failed") ||
366 STR_IN_SET(u->load_state, "error", "not-found", "masked")))
367 circle_len = 2;
368 }
369
370 if (!arg_full && original_stdout_is_tty) {
371 unsigned basic_len;
372
373 id_len = MIN(max_id_len, 25u);
374 basic_len = circle_len + 5 + id_len + 5 + active_len + sub_len;
375
376 if (job_count)
377 basic_len += job_len + 1;
378
379 if (basic_len < (unsigned) columns()) {
380 unsigned extra_len, incr;
381 extra_len = columns() - basic_len;
382
383 /* Either UNIT already got 25, or is fully satisfied.
384 * Grant up to 25 to DESC now. */
385 incr = MIN(extra_len, 25u);
386 desc_len += incr;
387 extra_len -= incr;
388
389 /* split the remaining space between UNIT and DESC,
390 * but do not give UNIT more than it needs. */
391 if (extra_len > 0) {
392 incr = MIN(extra_len / 2, max_id_len - id_len);
393 id_len += incr;
394 desc_len += extra_len - incr;
395 }
396 }
397 } else
398 id_len = max_id_len;
399
400 for (u = unit_infos; u < unit_infos + c; u++) {
401 _cleanup_free_ char *e = NULL, *j = NULL;
402 const char *on_loaded = "", *off_loaded = "";
403 const char *on_active = "", *off_active = "";
404 const char *on_circle = "", *off_circle = "";
405 const char *id;
406 bool circle = false;
407
408 if (!n_shown && !arg_no_legend) {
409
410 if (circle_len > 0)
411 fputs(" ", stdout);
412
413 printf("%-*s %-*s %-*s %-*s ",
414 id_len, "UNIT",
415 load_len, "LOAD",
416 active_len, "ACTIVE",
417 sub_len, "SUB");
418
419 if (job_count)
420 printf("%-*s ", job_len, "JOB");
421
422 if (!arg_full && arg_no_pager)
423 printf("%.*s\n", desc_len, "DESCRIPTION");
424 else
425 printf("%s\n", "DESCRIPTION");
426 }
427
428 n_shown++;
429
430 if (STR_IN_SET(u->load_state, "error", "not-found", "masked") && !arg_plain) {
431 on_loaded = ansi_highlight_red();
432 on_circle = ansi_highlight_yellow();
433 off_loaded = off_circle = ansi_normal();
434 circle = true;
435 } else if (streq(u->active_state, "failed") && !arg_plain) {
436 on_circle = on_active = ansi_highlight_red();
437 off_circle = off_active = ansi_normal();
438 circle = true;
439 }
440
441 if (u->machine) {
442 j = strjoin(u->machine, ":", u->id, NULL);
443 if (!j)
444 return log_oom();
445
446 id = j;
447 } else
448 id = u->id;
449
450 if (arg_full) {
451 e = ellipsize(id, id_len, 33);
452 if (!e)
453 return log_oom();
454
455 id = e;
456 }
457
458 if (circle_len > 0)
459 printf("%s%s%s ", on_circle, circle ? draw_special_char(DRAW_BLACK_CIRCLE) : " ", off_circle);
460
461 printf("%s%-*s%s %s%-*s%s %s%-*s %-*s%s %-*s",
462 on_active, id_len, id, off_active,
463 on_loaded, load_len, u->load_state, off_loaded,
464 on_active, active_len, u->active_state,
465 sub_len, u->sub_state, off_active,
466 job_count ? job_len + 1 : 0, u->job_id ? u->job_type : "");
467
468 if (desc_len > 0)
469 printf("%.*s\n", desc_len, u->description);
470 else
471 printf("%s\n", u->description);
472 }
473
474 if (!arg_no_legend) {
475 const char *on, *off;
476
477 if (n_shown) {
478 puts("\n"
479 "LOAD = Reflects whether the unit definition was properly loaded.\n"
480 "ACTIVE = The high-level unit activation state, i.e. generalization of SUB.\n"
481 "SUB = The low-level unit activation state, values depend on unit type.");
482 puts(job_count ? "JOB = Pending job for the unit.\n" : "");
483 on = ansi_highlight();
484 off = ansi_normal();
485 } else {
486 on = ansi_highlight_red();
487 off = ansi_normal();
488 }
489
490 if (arg_all)
491 printf("%s%u loaded units listed.%s\n"
492 "To show all installed unit files use 'systemctl list-unit-files'.\n",
493 on, n_shown, off);
494 else
495 printf("%s%u loaded units listed.%s Pass --all to see loaded but inactive units, too.\n"
496 "To show all installed unit files use 'systemctl list-unit-files'.\n",
497 on, n_shown, off);
498 }
499
500 return 0;
501 }
502
503 static int get_unit_list(
504 sd_bus *bus,
505 const char *machine,
506 char **patterns,
507 UnitInfo **unit_infos,
508 int c,
509 sd_bus_message **_reply) {
510
511 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
512 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
513 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
514 size_t size = c;
515 int r;
516 UnitInfo u;
517
518 assert(bus);
519 assert(unit_infos);
520 assert(_reply);
521
522 r = sd_bus_message_new_method_call(
523 bus,
524 &m,
525 "org.freedesktop.systemd1",
526 "/org/freedesktop/systemd1",
527 "org.freedesktop.systemd1.Manager",
528 "ListUnitsFiltered");
529
530 if (r < 0)
531 return bus_log_create_error(r);
532
533 r = sd_bus_message_append_strv(m, arg_states);
534 if (r < 0)
535 return bus_log_create_error(r);
536
537 r = sd_bus_call(bus, m, 0, &error, &reply);
538 if (r < 0)
539 return log_error_errno(r, "Failed to list units: %s", bus_error_message(&error, r));
540
541 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssssouso)");
542 if (r < 0)
543 return bus_log_parse_error(r);
544
545 while ((r = bus_parse_unit_info(reply, &u)) > 0) {
546 u.machine = machine;
547
548 if (!output_show_unit(&u, patterns))
549 continue;
550
551 if (!GREEDY_REALLOC(*unit_infos, size, c+1))
552 return log_oom();
553
554 (*unit_infos)[c++] = u;
555 }
556 if (r < 0)
557 return bus_log_parse_error(r);
558
559 r = sd_bus_message_exit_container(reply);
560 if (r < 0)
561 return bus_log_parse_error(r);
562
563 *_reply = reply;
564 reply = NULL;
565
566 return c;
567 }
568
569 static void message_set_freep(Set **set) {
570 sd_bus_message *m;
571
572 while ((m = set_steal_first(*set)))
573 sd_bus_message_unref(m);
574
575 set_free(*set);
576 }
577
578 static int get_unit_list_recursive(
579 sd_bus *bus,
580 char **patterns,
581 UnitInfo **_unit_infos,
582 Set **_replies,
583 char ***_machines) {
584
585 _cleanup_free_ UnitInfo *unit_infos = NULL;
586 _cleanup_(message_set_freep) Set *replies;
587 sd_bus_message *reply;
588 int c, r;
589
590 assert(bus);
591 assert(_replies);
592 assert(_unit_infos);
593 assert(_machines);
594
595 replies = set_new(NULL);
596 if (!replies)
597 return log_oom();
598
599 c = get_unit_list(bus, NULL, patterns, &unit_infos, 0, &reply);
600 if (c < 0)
601 return c;
602
603 r = set_put(replies, reply);
604 if (r < 0) {
605 sd_bus_message_unref(reply);
606 return log_oom();
607 }
608
609 if (arg_recursive) {
610 _cleanup_strv_free_ char **machines = NULL;
611 char **i;
612
613 r = sd_get_machine_names(&machines);
614 if (r < 0)
615 return log_error_errno(r, "Failed to get machine names: %m");
616
617 STRV_FOREACH(i, machines) {
618 _cleanup_bus_flush_close_unref_ sd_bus *container = NULL;
619 int k;
620
621 r = sd_bus_open_system_machine(&container, *i);
622 if (r < 0) {
623 log_warning_errno(r, "Failed to connect to container %s, ignoring: %m", *i);
624 continue;
625 }
626
627 k = get_unit_list(container, *i, patterns, &unit_infos, c, &reply);
628 if (k < 0)
629 return k;
630
631 c = k;
632
633 r = set_put(replies, reply);
634 if (r < 0) {
635 sd_bus_message_unref(reply);
636 return log_oom();
637 }
638 }
639
640 *_machines = machines;
641 machines = NULL;
642 } else
643 *_machines = NULL;
644
645 *_unit_infos = unit_infos;
646 unit_infos = NULL;
647
648 *_replies = replies;
649 replies = NULL;
650
651 return c;
652 }
653
654 static int list_units(sd_bus *bus, char **args) {
655 _cleanup_free_ UnitInfo *unit_infos = NULL;
656 _cleanup_(message_set_freep) Set *replies = NULL;
657 _cleanup_strv_free_ char **machines = NULL;
658 int r;
659
660 pager_open_if_enabled();
661
662 r = get_unit_list_recursive(bus, strv_skip_first(args), &unit_infos, &replies, &machines);
663 if (r < 0)
664 return r;
665
666 qsort_safe(unit_infos, r, sizeof(UnitInfo), compare_unit_info);
667 return output_units_list(unit_infos, r);
668 }
669
670 static int get_triggered_units(
671 sd_bus *bus,
672 const char* path,
673 char*** ret) {
674
675 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
676 int r;
677
678 r = sd_bus_get_property_strv(
679 bus,
680 "org.freedesktop.systemd1",
681 path,
682 "org.freedesktop.systemd1.Unit",
683 "Triggers",
684 &error,
685 ret);
686
687 if (r < 0)
688 log_error("Failed to determine triggers: %s", bus_error_message(&error, r));
689
690 return 0;
691 }
692
693 static int get_listening(
694 sd_bus *bus,
695 const char* unit_path,
696 char*** listening) {
697
698 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
699 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
700 const char *type, *path;
701 int r, n = 0;
702
703 r = sd_bus_get_property(
704 bus,
705 "org.freedesktop.systemd1",
706 unit_path,
707 "org.freedesktop.systemd1.Socket",
708 "Listen",
709 &error,
710 &reply,
711 "a(ss)");
712 if (r < 0) {
713 log_error("Failed to get list of listening sockets: %s", bus_error_message(&error, r));
714 return r;
715 }
716
717 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ss)");
718 if (r < 0)
719 return bus_log_parse_error(r);
720
721 while ((r = sd_bus_message_read(reply, "(ss)", &type, &path)) > 0) {
722
723 r = strv_extend(listening, type);
724 if (r < 0)
725 return log_oom();
726
727 r = strv_extend(listening, path);
728 if (r < 0)
729 return log_oom();
730
731 n++;
732 }
733 if (r < 0)
734 return bus_log_parse_error(r);
735
736 r = sd_bus_message_exit_container(reply);
737 if (r < 0)
738 return bus_log_parse_error(r);
739
740 return n;
741 }
742
743 struct socket_info {
744 const char *machine;
745 const char* id;
746
747 char* type;
748 char* path;
749
750 /* Note: triggered is a list here, although it almost certainly
751 * will always be one unit. Nevertheless, dbus API allows for multiple
752 * values, so let's follow that. */
753 char** triggered;
754
755 /* The strv above is shared. free is set only in the first one. */
756 bool own_triggered;
757 };
758
759 static int socket_info_compare(const struct socket_info *a, const struct socket_info *b) {
760 int o;
761
762 assert(a);
763 assert(b);
764
765 if (!a->machine && b->machine)
766 return -1;
767 if (a->machine && !b->machine)
768 return 1;
769 if (a->machine && b->machine) {
770 o = strcasecmp(a->machine, b->machine);
771 if (o != 0)
772 return o;
773 }
774
775 o = strcmp(a->path, b->path);
776 if (o == 0)
777 o = strcmp(a->type, b->type);
778
779 return o;
780 }
781
782 static int output_sockets_list(struct socket_info *socket_infos, unsigned cs) {
783 struct socket_info *s;
784 unsigned pathlen = strlen("LISTEN"),
785 typelen = strlen("TYPE") * arg_show_types,
786 socklen = strlen("UNIT"),
787 servlen = strlen("ACTIVATES");
788 const char *on, *off;
789
790 for (s = socket_infos; s < socket_infos + cs; s++) {
791 unsigned tmp = 0;
792 char **a;
793
794 socklen = MAX(socklen, strlen(s->id));
795 if (arg_show_types)
796 typelen = MAX(typelen, strlen(s->type));
797 pathlen = MAX(pathlen, strlen(s->path) + (s->machine ? strlen(s->machine)+1 : 0));
798
799 STRV_FOREACH(a, s->triggered)
800 tmp += strlen(*a) + 2*(a != s->triggered);
801 servlen = MAX(servlen, tmp);
802 }
803
804 if (cs) {
805 if (!arg_no_legend)
806 printf("%-*s %-*.*s%-*s %s\n",
807 pathlen, "LISTEN",
808 typelen + arg_show_types, typelen + arg_show_types, "TYPE ",
809 socklen, "UNIT",
810 "ACTIVATES");
811
812 for (s = socket_infos; s < socket_infos + cs; s++) {
813 _cleanup_free_ char *j = NULL;
814 const char *path;
815 char **a;
816
817 if (s->machine) {
818 j = strjoin(s->machine, ":", s->path, NULL);
819 if (!j)
820 return log_oom();
821 path = j;
822 } else
823 path = s->path;
824
825 if (arg_show_types)
826 printf("%-*s %-*s %-*s",
827 pathlen, path, typelen, s->type, socklen, s->id);
828 else
829 printf("%-*s %-*s",
830 pathlen, path, socklen, s->id);
831 STRV_FOREACH(a, s->triggered)
832 printf("%s %s",
833 a == s->triggered ? "" : ",", *a);
834 printf("\n");
835 }
836
837 on = ansi_highlight();
838 off = ansi_normal();
839 if (!arg_no_legend)
840 printf("\n");
841 } else {
842 on = ansi_highlight_red();
843 off = ansi_normal();
844 }
845
846 if (!arg_no_legend) {
847 printf("%s%u sockets listed.%s\n", on, cs, off);
848 if (!arg_all)
849 printf("Pass --all to see loaded but inactive sockets, too.\n");
850 }
851
852 return 0;
853 }
854
855 static int list_sockets(sd_bus *bus, char **args) {
856 _cleanup_(message_set_freep) Set *replies = NULL;
857 _cleanup_strv_free_ char **machines = NULL;
858 _cleanup_free_ UnitInfo *unit_infos = NULL;
859 _cleanup_free_ struct socket_info *socket_infos = NULL;
860 const UnitInfo *u;
861 struct socket_info *s;
862 unsigned cs = 0;
863 size_t size = 0;
864 int r = 0, n;
865
866 pager_open_if_enabled();
867
868 n = get_unit_list_recursive(bus, strv_skip_first(args), &unit_infos, &replies, &machines);
869 if (n < 0)
870 return n;
871
872 for (u = unit_infos; u < unit_infos + n; u++) {
873 _cleanup_strv_free_ char **listening = NULL, **triggered = NULL;
874 int i, c;
875
876 if (!endswith(u->id, ".socket"))
877 continue;
878
879 r = get_triggered_units(bus, u->unit_path, &triggered);
880 if (r < 0)
881 goto cleanup;
882
883 c = get_listening(bus, u->unit_path, &listening);
884 if (c < 0) {
885 r = c;
886 goto cleanup;
887 }
888
889 if (!GREEDY_REALLOC(socket_infos, size, cs + c)) {
890 r = log_oom();
891 goto cleanup;
892 }
893
894 for (i = 0; i < c; i++)
895 socket_infos[cs + i] = (struct socket_info) {
896 .machine = u->machine,
897 .id = u->id,
898 .type = listening[i*2],
899 .path = listening[i*2 + 1],
900 .triggered = triggered,
901 .own_triggered = i==0,
902 };
903
904 /* from this point on we will cleanup those socket_infos */
905 cs += c;
906 free(listening);
907 listening = triggered = NULL; /* avoid cleanup */
908 }
909
910 qsort_safe(socket_infos, cs, sizeof(struct socket_info),
911 (__compar_fn_t) socket_info_compare);
912
913 output_sockets_list(socket_infos, cs);
914
915 cleanup:
916 assert(cs == 0 || socket_infos);
917 for (s = socket_infos; s < socket_infos + cs; s++) {
918 free(s->type);
919 free(s->path);
920 if (s->own_triggered)
921 strv_free(s->triggered);
922 }
923
924 return r;
925 }
926
927 static int get_next_elapse(
928 sd_bus *bus,
929 const char *path,
930 dual_timestamp *next) {
931
932 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
933 dual_timestamp t;
934 int r;
935
936 assert(bus);
937 assert(path);
938 assert(next);
939
940 r = sd_bus_get_property_trivial(
941 bus,
942 "org.freedesktop.systemd1",
943 path,
944 "org.freedesktop.systemd1.Timer",
945 "NextElapseUSecMonotonic",
946 &error,
947 't',
948 &t.monotonic);
949 if (r < 0) {
950 log_error("Failed to get next elapsation time: %s", bus_error_message(&error, r));
951 return r;
952 }
953
954 r = sd_bus_get_property_trivial(
955 bus,
956 "org.freedesktop.systemd1",
957 path,
958 "org.freedesktop.systemd1.Timer",
959 "NextElapseUSecRealtime",
960 &error,
961 't',
962 &t.realtime);
963 if (r < 0) {
964 log_error("Failed to get next elapsation time: %s", bus_error_message(&error, r));
965 return r;
966 }
967
968 *next = t;
969 return 0;
970 }
971
972 static int get_last_trigger(
973 sd_bus *bus,
974 const char *path,
975 usec_t *last) {
976
977 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
978 int r;
979
980 assert(bus);
981 assert(path);
982 assert(last);
983
984 r = sd_bus_get_property_trivial(
985 bus,
986 "org.freedesktop.systemd1",
987 path,
988 "org.freedesktop.systemd1.Timer",
989 "LastTriggerUSec",
990 &error,
991 't',
992 last);
993 if (r < 0) {
994 log_error("Failed to get last trigger time: %s", bus_error_message(&error, r));
995 return r;
996 }
997
998 return 0;
999 }
1000
1001 struct timer_info {
1002 const char* machine;
1003 const char* id;
1004 usec_t next_elapse;
1005 usec_t last_trigger;
1006 char** triggered;
1007 };
1008
1009 static int timer_info_compare(const struct timer_info *a, const struct timer_info *b) {
1010 int o;
1011
1012 assert(a);
1013 assert(b);
1014
1015 if (!a->machine && b->machine)
1016 return -1;
1017 if (a->machine && !b->machine)
1018 return 1;
1019 if (a->machine && b->machine) {
1020 o = strcasecmp(a->machine, b->machine);
1021 if (o != 0)
1022 return o;
1023 }
1024
1025 if (a->next_elapse < b->next_elapse)
1026 return -1;
1027 if (a->next_elapse > b->next_elapse)
1028 return 1;
1029
1030 return strcmp(a->id, b->id);
1031 }
1032
1033 static int output_timers_list(struct timer_info *timer_infos, unsigned n) {
1034 struct timer_info *t;
1035 unsigned
1036 nextlen = strlen("NEXT"),
1037 leftlen = strlen("LEFT"),
1038 lastlen = strlen("LAST"),
1039 passedlen = strlen("PASSED"),
1040 unitlen = strlen("UNIT"),
1041 activatelen = strlen("ACTIVATES");
1042
1043 const char *on, *off;
1044
1045 assert(timer_infos || n == 0);
1046
1047 for (t = timer_infos; t < timer_infos + n; t++) {
1048 unsigned ul = 0;
1049 char **a;
1050
1051 if (t->next_elapse > 0) {
1052 char tstamp[FORMAT_TIMESTAMP_MAX] = "", trel[FORMAT_TIMESTAMP_RELATIVE_MAX] = "";
1053
1054 format_timestamp(tstamp, sizeof(tstamp), t->next_elapse);
1055 nextlen = MAX(nextlen, strlen(tstamp) + 1);
1056
1057 format_timestamp_relative(trel, sizeof(trel), t->next_elapse);
1058 leftlen = MAX(leftlen, strlen(trel));
1059 }
1060
1061 if (t->last_trigger > 0) {
1062 char tstamp[FORMAT_TIMESTAMP_MAX] = "", trel[FORMAT_TIMESTAMP_RELATIVE_MAX] = "";
1063
1064 format_timestamp(tstamp, sizeof(tstamp), t->last_trigger);
1065 lastlen = MAX(lastlen, strlen(tstamp) + 1);
1066
1067 format_timestamp_relative(trel, sizeof(trel), t->last_trigger);
1068 passedlen = MAX(passedlen, strlen(trel));
1069 }
1070
1071 unitlen = MAX(unitlen, strlen(t->id) + (t->machine ? strlen(t->machine)+1 : 0));
1072
1073 STRV_FOREACH(a, t->triggered)
1074 ul += strlen(*a) + 2*(a != t->triggered);
1075
1076 activatelen = MAX(activatelen, ul);
1077 }
1078
1079 if (n > 0) {
1080 if (!arg_no_legend)
1081 printf("%-*s %-*s %-*s %-*s %-*s %s\n",
1082 nextlen, "NEXT",
1083 leftlen, "LEFT",
1084 lastlen, "LAST",
1085 passedlen, "PASSED",
1086 unitlen, "UNIT",
1087 "ACTIVATES");
1088
1089 for (t = timer_infos; t < timer_infos + n; t++) {
1090 _cleanup_free_ char *j = NULL;
1091 const char *unit;
1092 char tstamp1[FORMAT_TIMESTAMP_MAX] = "n/a", trel1[FORMAT_TIMESTAMP_RELATIVE_MAX] = "n/a";
1093 char tstamp2[FORMAT_TIMESTAMP_MAX] = "n/a", trel2[FORMAT_TIMESTAMP_RELATIVE_MAX] = "n/a";
1094 char **a;
1095
1096 format_timestamp(tstamp1, sizeof(tstamp1), t->next_elapse);
1097 format_timestamp_relative(trel1, sizeof(trel1), t->next_elapse);
1098
1099 format_timestamp(tstamp2, sizeof(tstamp2), t->last_trigger);
1100 format_timestamp_relative(trel2, sizeof(trel2), t->last_trigger);
1101
1102 if (t->machine) {
1103 j = strjoin(t->machine, ":", t->id, NULL);
1104 if (!j)
1105 return log_oom();
1106 unit = j;
1107 } else
1108 unit = t->id;
1109
1110 printf("%-*s %-*s %-*s %-*s %-*s",
1111 nextlen, tstamp1, leftlen, trel1, lastlen, tstamp2, passedlen, trel2, unitlen, unit);
1112
1113 STRV_FOREACH(a, t->triggered)
1114 printf("%s %s",
1115 a == t->triggered ? "" : ",", *a);
1116 printf("\n");
1117 }
1118
1119 on = ansi_highlight();
1120 off = ansi_normal();
1121 if (!arg_no_legend)
1122 printf("\n");
1123 } else {
1124 on = ansi_highlight_red();
1125 off = ansi_normal();
1126 }
1127
1128 if (!arg_no_legend) {
1129 printf("%s%u timers listed.%s\n", on, n, off);
1130 if (!arg_all)
1131 printf("Pass --all to see loaded but inactive timers, too.\n");
1132 }
1133
1134 return 0;
1135 }
1136
1137 static usec_t calc_next_elapse(dual_timestamp *nw, dual_timestamp *next) {
1138 usec_t next_elapse;
1139
1140 assert(nw);
1141 assert(next);
1142
1143 if (next->monotonic != USEC_INFINITY && next->monotonic > 0) {
1144 usec_t converted;
1145
1146 if (next->monotonic > nw->monotonic)
1147 converted = nw->realtime + (next->monotonic - nw->monotonic);
1148 else
1149 converted = nw->realtime - (nw->monotonic - next->monotonic);
1150
1151 if (next->realtime != USEC_INFINITY && next->realtime > 0)
1152 next_elapse = MIN(converted, next->realtime);
1153 else
1154 next_elapse = converted;
1155
1156 } else
1157 next_elapse = next->realtime;
1158
1159 return next_elapse;
1160 }
1161
1162 static int list_timers(sd_bus *bus, char **args) {
1163 _cleanup_(message_set_freep) Set *replies = NULL;
1164 _cleanup_strv_free_ char **machines = NULL;
1165 _cleanup_free_ struct timer_info *timer_infos = NULL;
1166 _cleanup_free_ UnitInfo *unit_infos = NULL;
1167 struct timer_info *t;
1168 const UnitInfo *u;
1169 size_t size = 0;
1170 int n, c = 0;
1171 dual_timestamp nw;
1172 int r = 0;
1173
1174 pager_open_if_enabled();
1175
1176 n = get_unit_list_recursive(bus, strv_skip_first(args), &unit_infos, &replies, &machines);
1177 if (n < 0)
1178 return n;
1179
1180 dual_timestamp_get(&nw);
1181
1182 for (u = unit_infos; u < unit_infos + n; u++) {
1183 _cleanup_strv_free_ char **triggered = NULL;
1184 dual_timestamp next = DUAL_TIMESTAMP_NULL;
1185 usec_t m, last = 0;
1186
1187 if (!endswith(u->id, ".timer"))
1188 continue;
1189
1190 r = get_triggered_units(bus, u->unit_path, &triggered);
1191 if (r < 0)
1192 goto cleanup;
1193
1194 r = get_next_elapse(bus, u->unit_path, &next);
1195 if (r < 0)
1196 goto cleanup;
1197
1198 get_last_trigger(bus, u->unit_path, &last);
1199
1200 if (!GREEDY_REALLOC(timer_infos, size, c+1)) {
1201 r = log_oom();
1202 goto cleanup;
1203 }
1204
1205 m = calc_next_elapse(&nw, &next);
1206
1207 timer_infos[c++] = (struct timer_info) {
1208 .machine = u->machine,
1209 .id = u->id,
1210 .next_elapse = m,
1211 .last_trigger = last,
1212 .triggered = triggered,
1213 };
1214
1215 triggered = NULL; /* avoid cleanup */
1216 }
1217
1218 qsort_safe(timer_infos, c, sizeof(struct timer_info),
1219 (__compar_fn_t) timer_info_compare);
1220
1221 output_timers_list(timer_infos, c);
1222
1223 cleanup:
1224 for (t = timer_infos; t < timer_infos + c; t++)
1225 strv_free(t->triggered);
1226
1227 return r;
1228 }
1229
1230 static int compare_unit_file_list(const void *a, const void *b) {
1231 const char *d1, *d2;
1232 const UnitFileList *u = a, *v = b;
1233
1234 d1 = strrchr(u->path, '.');
1235 d2 = strrchr(v->path, '.');
1236
1237 if (d1 && d2) {
1238 int r;
1239
1240 r = strcasecmp(d1, d2);
1241 if (r != 0)
1242 return r;
1243 }
1244
1245 return strcasecmp(basename(u->path), basename(v->path));
1246 }
1247
1248 static bool output_show_unit_file(const UnitFileList *u, char **patterns) {
1249 if (!strv_fnmatch_or_empty(patterns, basename(u->path), FNM_NOESCAPE))
1250 return false;
1251
1252 if (!strv_isempty(arg_types)) {
1253 const char *dot;
1254
1255 dot = strrchr(u->path, '.');
1256 if (!dot)
1257 return false;
1258
1259 if (!strv_find(arg_types, dot+1))
1260 return false;
1261 }
1262
1263 if (!strv_isempty(arg_states) &&
1264 !strv_find(arg_states, unit_file_state_to_string(u->state)))
1265 return false;
1266
1267 return true;
1268 }
1269
1270 static void output_unit_file_list(const UnitFileList *units, unsigned c) {
1271 unsigned max_id_len, id_cols, state_cols;
1272 const UnitFileList *u;
1273
1274 max_id_len = strlen("UNIT FILE");
1275 state_cols = strlen("STATE");
1276
1277 for (u = units; u < units + c; u++) {
1278 max_id_len = MAX(max_id_len, strlen(basename(u->path)));
1279 state_cols = MAX(state_cols, strlen(unit_file_state_to_string(u->state)));
1280 }
1281
1282 if (!arg_full) {
1283 unsigned basic_cols;
1284
1285 id_cols = MIN(max_id_len, 25u);
1286 basic_cols = 1 + id_cols + state_cols;
1287 if (basic_cols < (unsigned) columns())
1288 id_cols += MIN(columns() - basic_cols, max_id_len - id_cols);
1289 } else
1290 id_cols = max_id_len;
1291
1292 if (!arg_no_legend)
1293 printf("%-*s %-*s\n",
1294 id_cols, "UNIT FILE",
1295 state_cols, "STATE");
1296
1297 for (u = units; u < units + c; u++) {
1298 _cleanup_free_ char *e = NULL;
1299 const char *on, *off;
1300 const char *id;
1301
1302 if (IN_SET(u->state,
1303 UNIT_FILE_MASKED,
1304 UNIT_FILE_MASKED_RUNTIME,
1305 UNIT_FILE_DISABLED,
1306 UNIT_FILE_INVALID)) {
1307 on = ansi_highlight_red();
1308 off = ansi_normal();
1309 } else if (u->state == UNIT_FILE_ENABLED) {
1310 on = ansi_highlight_green();
1311 off = ansi_normal();
1312 } else
1313 on = off = "";
1314
1315 id = basename(u->path);
1316
1317 e = arg_full ? NULL : ellipsize(id, id_cols, 33);
1318
1319 printf("%-*s %s%-*s%s\n",
1320 id_cols, e ? e : id,
1321 on, state_cols, unit_file_state_to_string(u->state), off);
1322 }
1323
1324 if (!arg_no_legend)
1325 printf("\n%u unit files listed.\n", c);
1326 }
1327
1328 static int list_unit_files(sd_bus *bus, char **args) {
1329 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1330 _cleanup_free_ UnitFileList *units = NULL;
1331 UnitFileList *unit;
1332 size_t size = 0;
1333 unsigned c = 0;
1334 const char *state;
1335 char *path;
1336 int r;
1337
1338 pager_open_if_enabled();
1339
1340 if (avoid_bus()) {
1341 Hashmap *h;
1342 UnitFileList *u;
1343 Iterator i;
1344 unsigned n_units;
1345
1346 h = hashmap_new(&string_hash_ops);
1347 if (!h)
1348 return log_oom();
1349
1350 r = unit_file_get_list(arg_scope, arg_root, h);
1351 if (r < 0) {
1352 unit_file_list_free(h);
1353 log_error_errno(r, "Failed to get unit file list: %m");
1354 return r;
1355 }
1356
1357 n_units = hashmap_size(h);
1358
1359 units = new(UnitFileList, n_units);
1360 if (!units && n_units > 0) {
1361 unit_file_list_free(h);
1362 return log_oom();
1363 }
1364
1365 HASHMAP_FOREACH(u, h, i) {
1366 if (!output_show_unit_file(u, strv_skip_first(args)))
1367 continue;
1368
1369 units[c++] = *u;
1370 free(u);
1371 }
1372
1373 assert(c <= n_units);
1374 hashmap_free(h);
1375 } else {
1376 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1377
1378 r = sd_bus_call_method(
1379 bus,
1380 "org.freedesktop.systemd1",
1381 "/org/freedesktop/systemd1",
1382 "org.freedesktop.systemd1.Manager",
1383 "ListUnitFiles",
1384 &error,
1385 &reply,
1386 NULL);
1387 if (r < 0) {
1388 log_error("Failed to list unit files: %s", bus_error_message(&error, r));
1389 return r;
1390 }
1391
1392 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ss)");
1393 if (r < 0)
1394 return bus_log_parse_error(r);
1395
1396 while ((r = sd_bus_message_read(reply, "(ss)", &path, &state)) > 0) {
1397
1398 if (!GREEDY_REALLOC(units, size, c + 1))
1399 return log_oom();
1400
1401 units[c] = (struct UnitFileList) {
1402 path,
1403 unit_file_state_from_string(state)
1404 };
1405
1406 if (output_show_unit_file(&units[c], strv_skip_first(args)))
1407 c ++;
1408
1409 }
1410 if (r < 0)
1411 return bus_log_parse_error(r);
1412
1413 r = sd_bus_message_exit_container(reply);
1414 if (r < 0)
1415 return bus_log_parse_error(r);
1416 }
1417
1418 qsort_safe(units, c, sizeof(UnitFileList), compare_unit_file_list);
1419 output_unit_file_list(units, c);
1420
1421 if (avoid_bus()) {
1422 for (unit = units; unit < units + c; unit++)
1423 free(unit->path);
1424 }
1425
1426 return 0;
1427 }
1428
1429 static int list_dependencies_print(const char *name, int level, unsigned int branches, bool last) {
1430 _cleanup_free_ char *n = NULL;
1431 size_t max_len = MAX(columns(),20u);
1432 size_t len = 0;
1433 int i;
1434
1435 if (!arg_plain) {
1436
1437 for (i = level - 1; i >= 0; i--) {
1438 len += 2;
1439 if (len > max_len - 3 && !arg_full) {
1440 printf("%s...\n",max_len % 2 ? "" : " ");
1441 return 0;
1442 }
1443 printf("%s", draw_special_char(branches & (1 << i) ? DRAW_TREE_VERTICAL : DRAW_TREE_SPACE));
1444 }
1445 len += 2;
1446
1447 if (len > max_len - 3 && !arg_full) {
1448 printf("%s...\n",max_len % 2 ? "" : " ");
1449 return 0;
1450 }
1451
1452 printf("%s", draw_special_char(last ? DRAW_TREE_RIGHT : DRAW_TREE_BRANCH));
1453 }
1454
1455 if (arg_full){
1456 printf("%s\n", name);
1457 return 0;
1458 }
1459
1460 n = ellipsize(name, max_len-len, 100);
1461 if (!n)
1462 return log_oom();
1463
1464 printf("%s\n", n);
1465 return 0;
1466 }
1467
1468 static int list_dependencies_get_dependencies(sd_bus *bus, const char *name, char ***deps) {
1469
1470 static const char *dependencies[_DEPENDENCY_MAX] = {
1471 [DEPENDENCY_FORWARD] = "Requires\0"
1472 "RequiresOverridable\0"
1473 "Requisite\0"
1474 "RequisiteOverridable\0"
1475 "Wants\0"
1476 "ConsistsOf\0"
1477 "BindsTo\0",
1478 [DEPENDENCY_REVERSE] = "RequiredBy\0"
1479 "RequiredByOverridable\0"
1480 "RequisiteOf\0"
1481 "RequisiteOfOverridable\0"
1482 "WantedBy\0"
1483 "PartOf\0"
1484 "BoundBy\0",
1485 [DEPENDENCY_AFTER] = "After\0",
1486 [DEPENDENCY_BEFORE] = "Before\0",
1487 };
1488
1489 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1490 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1491 _cleanup_strv_free_ char **ret = NULL;
1492 _cleanup_free_ char *path = NULL;
1493 int r;
1494
1495 assert(bus);
1496 assert(name);
1497 assert(deps);
1498 assert_cc(ELEMENTSOF(dependencies) == _DEPENDENCY_MAX);
1499
1500 path = unit_dbus_path_from_name(name);
1501 if (!path)
1502 return log_oom();
1503
1504 r = sd_bus_call_method(
1505 bus,
1506 "org.freedesktop.systemd1",
1507 path,
1508 "org.freedesktop.DBus.Properties",
1509 "GetAll",
1510 &error,
1511 &reply,
1512 "s", "org.freedesktop.systemd1.Unit");
1513 if (r < 0) {
1514 log_error("Failed to get properties of %s: %s", name, bus_error_message(&error, r));
1515 return r;
1516 }
1517
1518 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
1519 if (r < 0)
1520 return bus_log_parse_error(r);
1521
1522 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
1523 const char *prop;
1524
1525 r = sd_bus_message_read(reply, "s", &prop);
1526 if (r < 0)
1527 return bus_log_parse_error(r);
1528
1529 if (!nulstr_contains(dependencies[arg_dependency], prop)) {
1530 r = sd_bus_message_skip(reply, "v");
1531 if (r < 0)
1532 return bus_log_parse_error(r);
1533 } else {
1534
1535 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, "as");
1536 if (r < 0)
1537 return bus_log_parse_error(r);
1538
1539 r = bus_message_read_strv_extend(reply, &ret);
1540 if (r < 0)
1541 return bus_log_parse_error(r);
1542
1543 r = sd_bus_message_exit_container(reply);
1544 if (r < 0)
1545 return bus_log_parse_error(r);
1546 }
1547
1548 r = sd_bus_message_exit_container(reply);
1549 if (r < 0)
1550 return bus_log_parse_error(r);
1551
1552 }
1553 if (r < 0)
1554 return bus_log_parse_error(r);
1555
1556 r = sd_bus_message_exit_container(reply);
1557 if (r < 0)
1558 return bus_log_parse_error(r);
1559
1560 *deps = ret;
1561 ret = NULL;
1562
1563 return 0;
1564 }
1565
1566 static int list_dependencies_compare(const void *_a, const void *_b) {
1567 const char **a = (const char**) _a, **b = (const char**) _b;
1568
1569 if (unit_name_to_type(*a) == UNIT_TARGET && unit_name_to_type(*b) != UNIT_TARGET)
1570 return 1;
1571 if (unit_name_to_type(*a) != UNIT_TARGET && unit_name_to_type(*b) == UNIT_TARGET)
1572 return -1;
1573
1574 return strcasecmp(*a, *b);
1575 }
1576
1577 static int list_dependencies_one(
1578 sd_bus *bus,
1579 const char *name,
1580 int level,
1581 char ***units,
1582 unsigned int branches) {
1583
1584 _cleanup_strv_free_ char **deps = NULL;
1585 char **c;
1586 int r = 0;
1587
1588 assert(bus);
1589 assert(name);
1590 assert(units);
1591
1592 r = strv_extend(units, name);
1593 if (r < 0)
1594 return log_oom();
1595
1596 r = list_dependencies_get_dependencies(bus, name, &deps);
1597 if (r < 0)
1598 return r;
1599
1600 qsort_safe(deps, strv_length(deps), sizeof (char*), list_dependencies_compare);
1601
1602 STRV_FOREACH(c, deps) {
1603 if (strv_contains(*units, *c)) {
1604 if (!arg_plain) {
1605 r = list_dependencies_print("...", level + 1, (branches << 1) | (c[1] == NULL ? 0 : 1), 1);
1606 if (r < 0)
1607 return r;
1608 }
1609 continue;
1610 }
1611
1612 if (arg_plain)
1613 printf(" ");
1614 else {
1615 int state;
1616 const char *on;
1617
1618 state = check_one_unit(bus, *c, "activating\0active\0reloading\0", true);
1619 on = state > 0 ? ansi_highlight_green() : ansi_highlight_red();
1620 printf("%s%s%s ", on, draw_special_char(DRAW_BLACK_CIRCLE), ansi_normal());
1621 }
1622
1623 r = list_dependencies_print(*c, level, branches, c[1] == NULL);
1624 if (r < 0)
1625 return r;
1626
1627 if (arg_all || unit_name_to_type(*c) == UNIT_TARGET) {
1628 r = list_dependencies_one(bus, *c, level + 1, units, (branches << 1) | (c[1] == NULL ? 0 : 1));
1629 if (r < 0)
1630 return r;
1631 }
1632 }
1633
1634 if (!arg_plain)
1635 strv_remove(*units, name);
1636
1637 return 0;
1638 }
1639
1640 static int list_dependencies(sd_bus *bus, char **args) {
1641 _cleanup_strv_free_ char **units = NULL;
1642 _cleanup_free_ char *unit = NULL;
1643 const char *u;
1644 int r;
1645
1646 assert(bus);
1647
1648 if (args[1]) {
1649 r = unit_name_mangle(args[1], UNIT_NAME_NOGLOB, &unit);
1650 if (r < 0)
1651 return log_error_errno(r, "Failed to mangle unit name: %m");
1652
1653 u = unit;
1654 } else
1655 u = SPECIAL_DEFAULT_TARGET;
1656
1657 pager_open_if_enabled();
1658
1659 puts(u);
1660
1661 return list_dependencies_one(bus, u, 0, &units, 0);
1662 }
1663
1664 struct machine_info {
1665 bool is_host;
1666 char *name;
1667 char *state;
1668 char *control_group;
1669 uint32_t n_failed_units;
1670 uint32_t n_jobs;
1671 usec_t timestamp;
1672 };
1673
1674 static const struct bus_properties_map machine_info_property_map[] = {
1675 { "SystemState", "s", NULL, offsetof(struct machine_info, state) },
1676 { "NJobs", "u", NULL, offsetof(struct machine_info, n_jobs) },
1677 { "NFailedUnits", "u", NULL, offsetof(struct machine_info, n_failed_units) },
1678 { "ControlGroup", "s", NULL, offsetof(struct machine_info, control_group) },
1679 { "UserspaceTimestamp", "t", NULL, offsetof(struct machine_info, timestamp) },
1680 {}
1681 };
1682
1683 static void machine_info_clear(struct machine_info *info) {
1684 if (info) {
1685 free(info->name);
1686 free(info->state);
1687 free(info->control_group);
1688 zero(*info);
1689 }
1690 }
1691
1692 static void free_machines_list(struct machine_info *machine_infos, int n) {
1693 int i;
1694
1695 if (!machine_infos)
1696 return;
1697
1698 for (i = 0; i < n; i++)
1699 machine_info_clear(&machine_infos[i]);
1700
1701 free(machine_infos);
1702 }
1703
1704 static int compare_machine_info(const void *a, const void *b) {
1705 const struct machine_info *u = a, *v = b;
1706
1707 if (u->is_host != v->is_host)
1708 return u->is_host > v->is_host ? -1 : 1;
1709
1710 return strcasecmp(u->name, v->name);
1711 }
1712
1713 static int get_machine_properties(sd_bus *bus, struct machine_info *mi) {
1714 _cleanup_bus_flush_close_unref_ sd_bus *container = NULL;
1715 int r;
1716
1717 assert(mi);
1718
1719 if (!bus) {
1720 r = sd_bus_open_system_machine(&container, mi->name);
1721 if (r < 0)
1722 return r;
1723
1724 bus = container;
1725 }
1726
1727 r = bus_map_all_properties(bus, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map, mi);
1728 if (r < 0)
1729 return r;
1730
1731 return 0;
1732 }
1733
1734 static bool output_show_machine(const char *name, char **patterns) {
1735 return strv_fnmatch_or_empty(patterns, name, FNM_NOESCAPE);
1736 }
1737
1738 static int get_machine_list(
1739 sd_bus *bus,
1740 struct machine_info **_machine_infos,
1741 char **patterns) {
1742
1743 struct machine_info *machine_infos = NULL;
1744 _cleanup_strv_free_ char **m = NULL;
1745 _cleanup_free_ char *hn = NULL;
1746 size_t sz = 0;
1747 char **i;
1748 int c = 0, r;
1749
1750 hn = gethostname_malloc();
1751 if (!hn)
1752 return log_oom();
1753
1754 if (output_show_machine(hn, patterns)) {
1755 if (!GREEDY_REALLOC0(machine_infos, sz, c+1))
1756 return log_oom();
1757
1758 machine_infos[c].is_host = true;
1759 machine_infos[c].name = hn;
1760 hn = NULL;
1761
1762 get_machine_properties(bus, &machine_infos[c]);
1763 c++;
1764 }
1765
1766 r = sd_get_machine_names(&m);
1767 if (r < 0)
1768 return log_error_errno(r, "Failed to get machine list: %m");
1769
1770 STRV_FOREACH(i, m) {
1771 _cleanup_free_ char *class = NULL;
1772
1773 if (!output_show_machine(*i, patterns))
1774 continue;
1775
1776 sd_machine_get_class(*i, &class);
1777 if (!streq_ptr(class, "container"))
1778 continue;
1779
1780 if (!GREEDY_REALLOC0(machine_infos, sz, c+1)) {
1781 free_machines_list(machine_infos, c);
1782 return log_oom();
1783 }
1784
1785 machine_infos[c].is_host = false;
1786 machine_infos[c].name = strdup(*i);
1787 if (!machine_infos[c].name) {
1788 free_machines_list(machine_infos, c);
1789 return log_oom();
1790 }
1791
1792 get_machine_properties(NULL, &machine_infos[c]);
1793 c++;
1794 }
1795
1796 *_machine_infos = machine_infos;
1797 return c;
1798 }
1799
1800 static void output_machines_list(struct machine_info *machine_infos, unsigned n) {
1801 struct machine_info *m;
1802 unsigned
1803 circle_len = 0,
1804 namelen = sizeof("NAME") - 1,
1805 statelen = sizeof("STATE") - 1,
1806 failedlen = sizeof("FAILED") - 1,
1807 jobslen = sizeof("JOBS") - 1;
1808
1809 assert(machine_infos || n == 0);
1810
1811 for (m = machine_infos; m < machine_infos + n; m++) {
1812 namelen = MAX(namelen, strlen(m->name) + (m->is_host ? sizeof(" (host)") - 1 : 0));
1813 statelen = MAX(statelen, m->state ? strlen(m->state) : 0);
1814 failedlen = MAX(failedlen, DECIMAL_STR_WIDTH(m->n_failed_units));
1815 jobslen = MAX(jobslen, DECIMAL_STR_WIDTH(m->n_jobs));
1816
1817 if (!arg_plain && !streq_ptr(m->state, "running"))
1818 circle_len = 2;
1819 }
1820
1821 if (!arg_no_legend) {
1822 if (circle_len > 0)
1823 fputs(" ", stdout);
1824
1825 printf("%-*s %-*s %-*s %-*s\n",
1826 namelen, "NAME",
1827 statelen, "STATE",
1828 failedlen, "FAILED",
1829 jobslen, "JOBS");
1830 }
1831
1832 for (m = machine_infos; m < machine_infos + n; m++) {
1833 const char *on_state = "", *off_state = "";
1834 const char *on_failed = "", *off_failed = "";
1835 bool circle = false;
1836
1837 if (streq_ptr(m->state, "degraded")) {
1838 on_state = ansi_highlight_red();
1839 off_state = ansi_normal();
1840 circle = true;
1841 } else if (!streq_ptr(m->state, "running")) {
1842 on_state = ansi_highlight_yellow();
1843 off_state = ansi_normal();
1844 circle = true;
1845 }
1846
1847 if (m->n_failed_units > 0) {
1848 on_failed = ansi_highlight_red();
1849 off_failed = ansi_normal();
1850 } else
1851 on_failed = off_failed = "";
1852
1853 if (circle_len > 0)
1854 printf("%s%s%s ", on_state, circle ? draw_special_char(DRAW_BLACK_CIRCLE) : " ", off_state);
1855
1856 if (m->is_host)
1857 printf("%-*s (host) %s%-*s%s %s%*u%s %*u\n",
1858 (int) (namelen - (sizeof(" (host)")-1)), strna(m->name),
1859 on_state, statelen, strna(m->state), off_state,
1860 on_failed, failedlen, m->n_failed_units, off_failed,
1861 jobslen, m->n_jobs);
1862 else
1863 printf("%-*s %s%-*s%s %s%*u%s %*u\n",
1864 namelen, strna(m->name),
1865 on_state, statelen, strna(m->state), off_state,
1866 on_failed, failedlen, m->n_failed_units, off_failed,
1867 jobslen, m->n_jobs);
1868 }
1869
1870 if (!arg_no_legend)
1871 printf("\n%u machines listed.\n", n);
1872 }
1873
1874 static int list_machines(sd_bus *bus, char **args) {
1875 struct machine_info *machine_infos = NULL;
1876 int r;
1877
1878 assert(bus);
1879
1880 if (geteuid() != 0) {
1881 log_error("Must be root.");
1882 return -EPERM;
1883 }
1884
1885 pager_open_if_enabled();
1886
1887 r = get_machine_list(bus, &machine_infos, strv_skip_first(args));
1888 if (r < 0)
1889 return r;
1890
1891 qsort_safe(machine_infos, r, sizeof(struct machine_info), compare_machine_info);
1892 output_machines_list(machine_infos, r);
1893 free_machines_list(machine_infos, r);
1894
1895 return 0;
1896 }
1897
1898 static int get_default(sd_bus *bus, char **args) {
1899 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1900 _cleanup_free_ char *_path = NULL;
1901 const char *path;
1902 int r;
1903
1904 if (!bus || avoid_bus()) {
1905 r = unit_file_get_default(arg_scope, arg_root, &_path);
1906 if (r < 0)
1907 return log_error_errno(r, "Failed to get default target: %m");
1908 path = _path;
1909
1910 } else {
1911 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1912
1913 r = sd_bus_call_method(
1914 bus,
1915 "org.freedesktop.systemd1",
1916 "/org/freedesktop/systemd1",
1917 "org.freedesktop.systemd1.Manager",
1918 "GetDefaultTarget",
1919 &error,
1920 &reply,
1921 NULL);
1922 if (r < 0) {
1923 log_error("Failed to get default target: %s", bus_error_message(&error, -r));
1924 return r;
1925 }
1926
1927 r = sd_bus_message_read(reply, "s", &path);
1928 if (r < 0)
1929 return bus_log_parse_error(r);
1930 }
1931
1932 if (path)
1933 printf("%s\n", path);
1934
1935 return 0;
1936 }
1937
1938 static void dump_unit_file_changes(const UnitFileChange *changes, unsigned n_changes) {
1939 unsigned i;
1940
1941 assert(changes || n_changes == 0);
1942
1943 for (i = 0; i < n_changes; i++) {
1944 if (changes[i].type == UNIT_FILE_SYMLINK)
1945 log_info("Created symlink from %s to %s.", changes[i].path, changes[i].source);
1946 else
1947 log_info("Removed symlink %s.", changes[i].path);
1948 }
1949 }
1950
1951 static int set_default(sd_bus *bus, char **args) {
1952 _cleanup_free_ char *unit = NULL;
1953 UnitFileChange *changes = NULL;
1954 unsigned n_changes = 0;
1955 int r;
1956
1957 r = unit_name_mangle_with_suffix(args[1], UNIT_NAME_NOGLOB, ".target", &unit);
1958 if (r < 0)
1959 return log_error_errno(r, "Failed to mangle unit name: %m");
1960
1961 if (!bus || avoid_bus()) {
1962 r = unit_file_set_default(arg_scope, arg_root, unit, true, &changes, &n_changes);
1963 if (r < 0)
1964 return log_error_errno(r, "Failed to set default target: %m");
1965
1966 if (!arg_quiet)
1967 dump_unit_file_changes(changes, n_changes);
1968
1969 r = 0;
1970 } else {
1971 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1972 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1973
1974 polkit_agent_open_if_enabled();
1975
1976 r = sd_bus_call_method(
1977 bus,
1978 "org.freedesktop.systemd1",
1979 "/org/freedesktop/systemd1",
1980 "org.freedesktop.systemd1.Manager",
1981 "SetDefaultTarget",
1982 &error,
1983 &reply,
1984 "sb", unit, 1);
1985 if (r < 0) {
1986 log_error("Failed to set default target: %s", bus_error_message(&error, -r));
1987 return r;
1988 }
1989
1990 r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet, NULL, NULL);
1991 if (r < 0)
1992 return r;
1993
1994 /* Try to reload if enabled */
1995 if (!arg_no_reload)
1996 r = daemon_reload(bus, args);
1997 else
1998 r = 0;
1999 }
2000
2001 unit_file_changes_free(changes, n_changes);
2002
2003 return r;
2004 }
2005
2006 struct job_info {
2007 uint32_t id;
2008 const char *name, *type, *state;
2009 };
2010
2011 static void output_jobs_list(const struct job_info* jobs, unsigned n, bool skipped) {
2012 unsigned id_len, unit_len, type_len, state_len;
2013 const struct job_info *j;
2014 const char *on, *off;
2015 bool shorten = false;
2016
2017 assert(n == 0 || jobs);
2018
2019 if (n == 0) {
2020 if (!arg_no_legend) {
2021 on = ansi_highlight_green();
2022 off = ansi_normal();
2023
2024 printf("%sNo jobs %s.%s\n", on, skipped ? "listed" : "running", off);
2025 }
2026 return;
2027 }
2028
2029 pager_open_if_enabled();
2030
2031 id_len = strlen("JOB");
2032 unit_len = strlen("UNIT");
2033 type_len = strlen("TYPE");
2034 state_len = strlen("STATE");
2035
2036 for (j = jobs; j < jobs + n; j++) {
2037 uint32_t id = j->id;
2038 assert(j->name && j->type && j->state);
2039
2040 id_len = MAX(id_len, DECIMAL_STR_WIDTH(id));
2041 unit_len = MAX(unit_len, strlen(j->name));
2042 type_len = MAX(type_len, strlen(j->type));
2043 state_len = MAX(state_len, strlen(j->state));
2044 }
2045
2046 if (!arg_full && id_len + 1 + unit_len + type_len + 1 + state_len > columns()) {
2047 unit_len = MAX(33u, columns() - id_len - type_len - state_len - 3);
2048 shorten = true;
2049 }
2050
2051 if (!arg_no_legend)
2052 printf("%*s %-*s %-*s %-*s\n",
2053 id_len, "JOB",
2054 unit_len, "UNIT",
2055 type_len, "TYPE",
2056 state_len, "STATE");
2057
2058 for (j = jobs; j < jobs + n; j++) {
2059 _cleanup_free_ char *e = NULL;
2060
2061 if (streq(j->state, "running")) {
2062 on = ansi_highlight();
2063 off = ansi_normal();
2064 } else
2065 on = off = "";
2066
2067 e = shorten ? ellipsize(j->name, unit_len, 33) : NULL;
2068 printf("%*u %s%-*s%s %-*s %s%-*s%s\n",
2069 id_len, j->id,
2070 on, unit_len, e ? e : j->name, off,
2071 type_len, j->type,
2072 on, state_len, j->state, off);
2073 }
2074
2075 if (!arg_no_legend) {
2076 on = ansi_highlight();
2077 off = ansi_normal();
2078
2079 printf("\n%s%u jobs listed%s.\n", on, n, off);
2080 }
2081 }
2082
2083 static bool output_show_job(struct job_info *job, char **patterns) {
2084 return strv_fnmatch_or_empty(patterns, job->name, FNM_NOESCAPE);
2085 }
2086
2087 static int list_jobs(sd_bus *bus, char **args) {
2088 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2089 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2090 const char *name, *type, *state, *job_path, *unit_path;
2091 _cleanup_free_ struct job_info *jobs = NULL;
2092 size_t size = 0;
2093 unsigned c = 0;
2094 uint32_t id;
2095 int r;
2096 bool skipped = false;
2097
2098 r = sd_bus_call_method(
2099 bus,
2100 "org.freedesktop.systemd1",
2101 "/org/freedesktop/systemd1",
2102 "org.freedesktop.systemd1.Manager",
2103 "ListJobs",
2104 &error,
2105 &reply,
2106 NULL);
2107 if (r < 0) {
2108 log_error("Failed to list jobs: %s", bus_error_message(&error, r));
2109 return r;
2110 }
2111
2112 r = sd_bus_message_enter_container(reply, 'a', "(usssoo)");
2113 if (r < 0)
2114 return bus_log_parse_error(r);
2115
2116 while ((r = sd_bus_message_read(reply, "(usssoo)", &id, &name, &type, &state, &job_path, &unit_path)) > 0) {
2117 struct job_info job = { id, name, type, state };
2118
2119 if (!output_show_job(&job, strv_skip_first(args))) {
2120 skipped = true;
2121 continue;
2122 }
2123
2124 if (!GREEDY_REALLOC(jobs, size, c + 1))
2125 return log_oom();
2126
2127 jobs[c++] = job;
2128 }
2129 if (r < 0)
2130 return bus_log_parse_error(r);
2131
2132 r = sd_bus_message_exit_container(reply);
2133 if (r < 0)
2134 return bus_log_parse_error(r);
2135
2136 output_jobs_list(jobs, c, skipped);
2137 return r;
2138 }
2139
2140 static int cancel_job(sd_bus *bus, char **args) {
2141 char **name;
2142 int r = 0;
2143
2144 assert(args);
2145
2146 if (strv_length(args) <= 1)
2147 return daemon_reload(bus, args);
2148
2149 polkit_agent_open_if_enabled();
2150
2151 STRV_FOREACH(name, args+1) {
2152 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2153 uint32_t id;
2154 int q;
2155
2156 q = safe_atou32(*name, &id);
2157 if (q < 0)
2158 return log_error_errno(q, "Failed to parse job id \"%s\": %m", *name);
2159
2160 q = sd_bus_call_method(
2161 bus,
2162 "org.freedesktop.systemd1",
2163 "/org/freedesktop/systemd1",
2164 "org.freedesktop.systemd1.Manager",
2165 "CancelJob",
2166 &error,
2167 NULL,
2168 "u", id);
2169 if (q < 0) {
2170 log_error("Failed to cancel job %"PRIu32": %s", id, bus_error_message(&error, q));
2171 if (r == 0)
2172 r = q;
2173 }
2174 }
2175
2176 return r;
2177 }
2178
2179 static int need_daemon_reload(sd_bus *bus, const char *unit) {
2180 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2181 const char *path;
2182 int b, r;
2183
2184 /* We ignore all errors here, since this is used to show a
2185 * warning only */
2186
2187 /* We don't use unit_dbus_path_from_name() directly since we
2188 * don't want to load the unit if it isn't loaded. */
2189
2190 r = sd_bus_call_method(
2191 bus,
2192 "org.freedesktop.systemd1",
2193 "/org/freedesktop/systemd1",
2194 "org.freedesktop.systemd1.Manager",
2195 "GetUnit",
2196 NULL,
2197 &reply,
2198 "s", unit);
2199 if (r < 0)
2200 return r;
2201
2202 r = sd_bus_message_read(reply, "o", &path);
2203 if (r < 0)
2204 return r;
2205
2206 r = sd_bus_get_property_trivial(
2207 bus,
2208 "org.freedesktop.systemd1",
2209 path,
2210 "org.freedesktop.systemd1.Unit",
2211 "NeedDaemonReload",
2212 NULL,
2213 'b', &b);
2214 if (r < 0)
2215 return r;
2216
2217 return b;
2218 }
2219
2220 static void warn_unit_file_changed(const char *name) {
2221 log_warning("%sWarning:%s %s changed on disk. Run 'systemctl%s daemon-reload' to reload units.",
2222 ansi_highlight_red(),
2223 ansi_normal(),
2224 name,
2225 arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
2226 }
2227
2228 static int unit_file_find_path(LookupPaths *lp, const char *unit_name, char **unit_path) {
2229 char **p;
2230
2231 assert(lp);
2232 assert(unit_name);
2233 assert(unit_path);
2234
2235 STRV_FOREACH(p, lp->unit_path) {
2236 _cleanup_free_ char *path;
2237
2238 path = path_join(arg_root, *p, unit_name);
2239 if (!path)
2240 return log_oom();
2241
2242 if (access(path, F_OK) == 0) {
2243 *unit_path = path;
2244 path = NULL;
2245 return 1;
2246 }
2247 }
2248
2249 return 0;
2250 }
2251
2252 static int unit_find_paths(
2253 sd_bus *bus,
2254 const char *unit_name,
2255 bool avoid_bus_cache,
2256 LookupPaths *lp,
2257 char **fragment_path,
2258 char ***dropin_paths) {
2259
2260 _cleanup_free_ char *path = NULL;
2261 _cleanup_strv_free_ char **dropins = NULL;
2262 int r;
2263
2264 /**
2265 * Finds where the unit is defined on disk. Returns 0 if the unit
2266 * is not found. Returns 1 if it is found, and sets
2267 * - the path to the unit in *path, if it exists on disk,
2268 * - and a strv of existing drop-ins in *dropins,
2269 * if the arg is not NULL and any dropins were found.
2270 */
2271
2272 assert(unit_name);
2273 assert(fragment_path);
2274 assert(lp);
2275
2276 if (!avoid_bus_cache && !unit_name_is_valid(unit_name, UNIT_NAME_TEMPLATE)) {
2277 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2278 _cleanup_bus_message_unref_ sd_bus_message *unit_load_error = NULL;
2279 _cleanup_free_ char *unit = NULL;
2280 char *unit_load_error_name, *unit_load_error_message;
2281
2282 unit = unit_dbus_path_from_name(unit_name);
2283 if (!unit)
2284 return log_oom();
2285
2286 if (need_daemon_reload(bus, unit_name) > 0)
2287 warn_unit_file_changed(unit_name);
2288
2289 r = sd_bus_get_property(
2290 bus,
2291 "org.freedesktop.systemd1",
2292 unit,
2293 "org.freedesktop.systemd1.Unit",
2294 "LoadError",
2295 &error,
2296 &unit_load_error,
2297 "(ss)");
2298 if (r < 0)
2299 return log_error_errno(r, "Failed to get LoadError: %s", bus_error_message(&error, r));
2300
2301 r = sd_bus_message_read(
2302 unit_load_error,
2303 "(ss)",
2304 &unit_load_error_name,
2305 &unit_load_error_message);
2306 if (r < 0)
2307 return bus_log_parse_error(r);
2308
2309 if (!isempty(unit_load_error_name)) {
2310 log_error("Unit %s is not loaded: %s", unit_name, unit_load_error_message);
2311 return 0;
2312 }
2313
2314 r = sd_bus_get_property_string(
2315 bus,
2316 "org.freedesktop.systemd1",
2317 unit,
2318 "org.freedesktop.systemd1.Unit",
2319 "FragmentPath",
2320 &error,
2321 &path);
2322 if (r < 0)
2323 return log_error_errno(r, "Failed to get FragmentPath: %s", bus_error_message(&error, r));
2324
2325 if (dropin_paths) {
2326 r = sd_bus_get_property_strv(
2327 bus,
2328 "org.freedesktop.systemd1",
2329 unit,
2330 "org.freedesktop.systemd1.Unit",
2331 "DropInPaths",
2332 &error,
2333 &dropins);
2334 if (r < 0)
2335 return log_error_errno(r, "Failed to get DropInPaths: %s", bus_error_message(&error, r));
2336 }
2337 } else {
2338 _cleanup_set_free_ Set *names;
2339
2340 names = set_new(NULL);
2341 if (!names)
2342 return log_oom();
2343
2344 r = set_put(names, unit_name);
2345 if (r < 0)
2346 return log_error_errno(r, "Failed to add unit name: %m");
2347
2348 r = unit_file_find_path(lp, unit_name, &path);
2349 if (r < 0)
2350 return r;
2351
2352 if (r == 0) {
2353 _cleanup_free_ char *template = NULL;
2354
2355 r = unit_name_template(unit_name, &template);
2356 if (r < 0 && r != -EINVAL)
2357 return log_error_errno(r, "Failed to determine template name: %m");
2358 if (r >= 0) {
2359 r = unit_file_find_path(lp, template, &path);
2360 if (r < 0)
2361 return r;
2362 }
2363 }
2364
2365 if (dropin_paths) {
2366 r = unit_file_find_dropin_paths(lp->unit_path, NULL, names, &dropins);
2367 if (r < 0)
2368 return r;
2369 }
2370 }
2371
2372 r = 0;
2373
2374 if (!isempty(path)) {
2375 *fragment_path = path;
2376 path = NULL;
2377 r = 1;
2378 }
2379
2380 if (dropin_paths && !strv_isempty(dropins)) {
2381 *dropin_paths = dropins;
2382 dropins = NULL;
2383 r = 1;
2384 }
2385
2386 if (r == 0)
2387 log_error("No files found for %s.", unit_name);
2388
2389 return r;
2390 }
2391
2392 static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet) {
2393 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2394 _cleanup_free_ char *n = NULL, *state = NULL;
2395 const char *path;
2396 int r;
2397
2398 assert(name);
2399
2400 r = unit_name_mangle(name, UNIT_NAME_NOGLOB, &n);
2401 if (r < 0)
2402 return log_error_errno(r, "Failed to mangle unit name: %m");
2403
2404 /* We don't use unit_dbus_path_from_name() directly since we
2405 * don't want to load the unit if it isn't loaded. */
2406
2407 r = sd_bus_call_method(
2408 bus,
2409 "org.freedesktop.systemd1",
2410 "/org/freedesktop/systemd1",
2411 "org.freedesktop.systemd1.Manager",
2412 "GetUnit",
2413 NULL,
2414 &reply,
2415 "s", n);
2416 if (r < 0) {
2417 if (!quiet)
2418 puts("unknown");
2419 return 0;
2420 }
2421
2422 r = sd_bus_message_read(reply, "o", &path);
2423 if (r < 0)
2424 return bus_log_parse_error(r);
2425
2426 r = sd_bus_get_property_string(
2427 bus,
2428 "org.freedesktop.systemd1",
2429 path,
2430 "org.freedesktop.systemd1.Unit",
2431 "ActiveState",
2432 NULL,
2433 &state);
2434 if (r < 0) {
2435 if (!quiet)
2436 puts("unknown");
2437 return 0;
2438 }
2439
2440 if (!quiet)
2441 puts(state);
2442
2443 return nulstr_contains(good_states, state);
2444 }
2445
2446 static int check_triggering_units(
2447 sd_bus *bus,
2448 const char *name) {
2449
2450 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2451 _cleanup_free_ char *path = NULL, *n = NULL, *state = NULL;
2452 _cleanup_strv_free_ char **triggered_by = NULL;
2453 bool print_warning_label = true;
2454 char **i;
2455 int r;
2456
2457 r = unit_name_mangle(name, UNIT_NAME_NOGLOB, &n);
2458 if (r < 0)
2459 return log_error_errno(r, "Failed to mangle unit name: %m");
2460
2461 path = unit_dbus_path_from_name(n);
2462 if (!path)
2463 return log_oom();
2464
2465 r = sd_bus_get_property_string(
2466 bus,
2467 "org.freedesktop.systemd1",
2468 path,
2469 "org.freedesktop.systemd1.Unit",
2470 "LoadState",
2471 &error,
2472 &state);
2473 if (r < 0) {
2474 log_error("Failed to get load state of %s: %s", n, bus_error_message(&error, r));
2475 return r;
2476 }
2477
2478 if (streq(state, "masked"))
2479 return 0;
2480
2481 r = sd_bus_get_property_strv(
2482 bus,
2483 "org.freedesktop.systemd1",
2484 path,
2485 "org.freedesktop.systemd1.Unit",
2486 "TriggeredBy",
2487 &error,
2488 &triggered_by);
2489 if (r < 0) {
2490 log_error("Failed to get triggered by array of %s: %s", n, bus_error_message(&error, r));
2491 return r;
2492 }
2493
2494 STRV_FOREACH(i, triggered_by) {
2495 r = check_one_unit(bus, *i, "active\0reloading\0", true);
2496 if (r < 0)
2497 return log_error_errno(r, "Failed to check unit: %m");
2498
2499 if (r == 0)
2500 continue;
2501
2502 if (print_warning_label) {
2503 log_warning("Warning: Stopping %s, but it can still be activated by:", n);
2504 print_warning_label = false;
2505 }
2506
2507 log_warning(" %s", *i);
2508 }
2509
2510 return 0;
2511 }
2512
2513 static const struct {
2514 const char *verb;
2515 const char *method;
2516 } unit_actions[] = {
2517 { "start", "StartUnit" },
2518 { "stop", "StopUnit" },
2519 { "condstop", "StopUnit" },
2520 { "reload", "ReloadUnit" },
2521 { "restart", "RestartUnit" },
2522 { "try-restart", "TryRestartUnit" },
2523 { "condrestart", "TryRestartUnit" },
2524 { "reload-or-restart", "ReloadOrRestartUnit" },
2525 { "reload-or-try-restart", "ReloadOrTryRestartUnit" },
2526 { "condreload", "ReloadOrTryRestartUnit" },
2527 { "force-reload", "ReloadOrTryRestartUnit" }
2528 };
2529
2530 static const char *verb_to_method(const char *verb) {
2531 uint i;
2532
2533 for (i = 0; i < ELEMENTSOF(unit_actions); i++)
2534 if (streq_ptr(unit_actions[i].verb, verb))
2535 return unit_actions[i].method;
2536
2537 return "StartUnit";
2538 }
2539
2540 static const char *method_to_verb(const char *method) {
2541 uint i;
2542
2543 for (i = 0; i < ELEMENTSOF(unit_actions); i++)
2544 if (streq_ptr(unit_actions[i].method, method))
2545 return unit_actions[i].verb;
2546
2547 return "n/a";
2548 }
2549
2550 static int start_unit_one(
2551 sd_bus *bus,
2552 const char *method,
2553 const char *name,
2554 const char *mode,
2555 sd_bus_error *error,
2556 BusWaitForJobs *w) {
2557
2558 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2559 const char *path;
2560 int r;
2561
2562 assert(method);
2563 assert(name);
2564 assert(mode);
2565 assert(error);
2566
2567 log_debug("Calling manager for %s on %s, %s", method, name, mode);
2568
2569 r = sd_bus_call_method(
2570 bus,
2571 "org.freedesktop.systemd1",
2572 "/org/freedesktop/systemd1",
2573 "org.freedesktop.systemd1.Manager",
2574 method,
2575 error,
2576 &reply,
2577 "ss", name, mode);
2578 if (r < 0) {
2579 const char *verb;
2580
2581 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
2582 /* There's always a fallback possible for
2583 * legacy actions. */
2584 return -EADDRNOTAVAIL;
2585
2586 verb = method_to_verb(method);
2587
2588 log_error("Failed to %s %s: %s", verb, name, bus_error_message(error, r));
2589 return r;
2590 }
2591
2592 r = sd_bus_message_read(reply, "o", &path);
2593 if (r < 0)
2594 return bus_log_parse_error(r);
2595
2596 if (need_daemon_reload(bus, name) > 0)
2597 warn_unit_file_changed(name);
2598
2599 if (w) {
2600 log_debug("Adding %s to the set", path);
2601 r = bus_wait_for_jobs_add(w, path);
2602 if (r < 0)
2603 return log_oom();
2604 }
2605
2606 return 0;
2607 }
2608
2609 static int expand_names(sd_bus *bus, char **names, const char* suffix, char ***ret) {
2610
2611 _cleanup_strv_free_ char **mangled = NULL, **globs = NULL;
2612 char **name;
2613 int r, i;
2614
2615 STRV_FOREACH(name, names) {
2616 char *t;
2617
2618 if (suffix)
2619 r = unit_name_mangle_with_suffix(*name, UNIT_NAME_GLOB, suffix, &t);
2620 else
2621 r = unit_name_mangle(*name, UNIT_NAME_GLOB, &t);
2622 if (r < 0)
2623 return log_error_errno(r, "Failed to mangle name: %m");
2624
2625 if (string_is_glob(t))
2626 r = strv_consume(&globs, t);
2627 else
2628 r = strv_consume(&mangled, t);
2629 if (r < 0)
2630 return log_oom();
2631 }
2632
2633 /* Query the manager only if any of the names are a glob, since
2634 * this is fairly expensive */
2635 if (!strv_isempty(globs)) {
2636 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2637 _cleanup_free_ UnitInfo *unit_infos = NULL;
2638
2639 if (!bus)
2640 return log_error_errno(EOPNOTSUPP, "Unit name globbing without bus is not implemented.");
2641
2642 r = get_unit_list(bus, NULL, globs, &unit_infos, 0, &reply);
2643 if (r < 0)
2644 return r;
2645
2646 for (i = 0; i < r; i++)
2647 if (strv_extend(&mangled, unit_infos[i].id) < 0)
2648 return log_oom();
2649 }
2650
2651 *ret = mangled;
2652 mangled = NULL; /* do not free */
2653
2654 return 0;
2655 }
2656
2657 static const struct {
2658 const char *target;
2659 const char *verb;
2660 const char *mode;
2661 } action_table[_ACTION_MAX] = {
2662 [ACTION_HALT] = { SPECIAL_HALT_TARGET, "halt", "replace-irreversibly" },
2663 [ACTION_POWEROFF] = { SPECIAL_POWEROFF_TARGET, "poweroff", "replace-irreversibly" },
2664 [ACTION_REBOOT] = { SPECIAL_REBOOT_TARGET, "reboot", "replace-irreversibly" },
2665 [ACTION_KEXEC] = { SPECIAL_KEXEC_TARGET, "kexec", "replace-irreversibly" },
2666 [ACTION_RUNLEVEL2] = { SPECIAL_MULTI_USER_TARGET, NULL, "isolate" },
2667 [ACTION_RUNLEVEL3] = { SPECIAL_MULTI_USER_TARGET, NULL, "isolate" },
2668 [ACTION_RUNLEVEL4] = { SPECIAL_MULTI_USER_TARGET, NULL, "isolate" },
2669 [ACTION_RUNLEVEL5] = { SPECIAL_GRAPHICAL_TARGET, NULL, "isolate" },
2670 [ACTION_RESCUE] = { SPECIAL_RESCUE_TARGET, "rescue", "isolate" },
2671 [ACTION_EMERGENCY] = { SPECIAL_EMERGENCY_TARGET, "emergency", "isolate" },
2672 [ACTION_DEFAULT] = { SPECIAL_DEFAULT_TARGET, "default", "isolate" },
2673 [ACTION_EXIT] = { SPECIAL_EXIT_TARGET, "exit", "replace-irreversibly" },
2674 [ACTION_SUSPEND] = { SPECIAL_SUSPEND_TARGET, "suspend", "replace-irreversibly" },
2675 [ACTION_HIBERNATE] = { SPECIAL_HIBERNATE_TARGET, "hibernate", "replace-irreversibly" },
2676 [ACTION_HYBRID_SLEEP] = { SPECIAL_HYBRID_SLEEP_TARGET, "hybrid-sleep", "replace-irreversibly" },
2677 };
2678
2679 static enum action verb_to_action(const char *verb) {
2680 enum action i;
2681
2682 for (i = _ACTION_INVALID; i < _ACTION_MAX; i++)
2683 if (streq_ptr(action_table[i].verb, verb))
2684 return i;
2685
2686 return _ACTION_INVALID;
2687 }
2688
2689 static int start_unit(sd_bus *bus, char **args) {
2690 _cleanup_(bus_wait_for_jobs_freep) BusWaitForJobs *w = NULL;
2691 const char *method, *mode, *one_name, *suffix = NULL;
2692 _cleanup_strv_free_ char **names = NULL;
2693 char **name;
2694 int r = 0;
2695
2696 assert(bus);
2697
2698 ask_password_agent_open_if_enabled();
2699 polkit_agent_open_if_enabled();
2700
2701 if (arg_action == ACTION_SYSTEMCTL) {
2702 enum action action;
2703 method = verb_to_method(args[0]);
2704 action = verb_to_action(args[0]);
2705
2706 if (streq(args[0], "isolate")) {
2707 mode = "isolate";
2708 suffix = ".target";
2709 } else
2710 mode = action_table[action].mode ?: arg_job_mode;
2711
2712 one_name = action_table[action].target;
2713 } else {
2714 assert(arg_action < ELEMENTSOF(action_table));
2715 assert(action_table[arg_action].target);
2716
2717 method = "StartUnit";
2718
2719 mode = action_table[arg_action].mode;
2720 one_name = action_table[arg_action].target;
2721 }
2722
2723 if (one_name)
2724 names = strv_new(one_name, NULL);
2725 else {
2726 r = expand_names(bus, args + 1, suffix, &names);
2727 if (r < 0)
2728 log_error_errno(r, "Failed to expand names: %m");
2729 }
2730
2731 if (!arg_no_block) {
2732 r = bus_wait_for_jobs_new(bus, &w);
2733 if (r < 0)
2734 return log_error_errno(r, "Could not watch jobs: %m");
2735 }
2736
2737 STRV_FOREACH(name, names) {
2738 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2739 int q;
2740
2741 q = start_unit_one(bus, method, *name, mode, &error, w);
2742 if (r >= 0 && q < 0)
2743 r = translate_bus_error_to_exit_status(q, &error);
2744 }
2745
2746 if (!arg_no_block) {
2747 int q;
2748
2749 q = bus_wait_for_jobs(w, arg_quiet);
2750 if (q < 0)
2751 return q;
2752
2753 /* When stopping units, warn if they can still be triggered by
2754 * another active unit (socket, path, timer) */
2755 if (!arg_quiet && streq(method, "StopUnit"))
2756 STRV_FOREACH(name, names)
2757 check_triggering_units(bus, *name);
2758 }
2759
2760 return r;
2761 }
2762
2763 /* Ask systemd-logind, which might grant access to unprivileged users
2764 * through PolicyKit */
2765 static int reboot_with_logind(sd_bus *bus, enum action a) {
2766 #ifdef HAVE_LOGIND
2767 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2768 const char *method, *description;
2769 int r;
2770
2771 if (!bus)
2772 return -EIO;
2773
2774 polkit_agent_open_if_enabled();
2775
2776 switch (a) {
2777
2778 case ACTION_REBOOT:
2779 method = "Reboot";
2780 description = "reboot system";
2781 break;
2782
2783 case ACTION_POWEROFF:
2784 method = "PowerOff";
2785 description = "power off system";
2786 break;
2787
2788 case ACTION_SUSPEND:
2789 method = "Suspend";
2790 description = "suspend system";
2791 break;
2792
2793 case ACTION_HIBERNATE:
2794 method = "Hibernate";
2795 description = "hibernate system";
2796 break;
2797
2798 case ACTION_HYBRID_SLEEP:
2799 method = "HybridSleep";
2800 description = "put system into hybrid sleep";
2801 break;
2802
2803 default:
2804 return -EINVAL;
2805 }
2806
2807 if (!strv_isempty(arg_wall)) {
2808 _cleanup_free_ char *m;
2809
2810 m = strv_join(arg_wall, " ");
2811 if (!m)
2812 return log_oom();
2813
2814 r = sd_bus_call_method(
2815 bus,
2816 "org.freedesktop.login1",
2817 "/org/freedesktop/login1",
2818 "org.freedesktop.login1.Manager",
2819 "SetWallMessage",
2820 &error,
2821 NULL,
2822 "sb",
2823 m,
2824 !arg_no_wall);
2825
2826 if (r < 0) {
2827 log_warning_errno(r, "Failed to set wall message, ignoring: %s",
2828 bus_error_message(&error, r));
2829 sd_bus_error_free(&error);
2830 }
2831 }
2832
2833
2834 r = sd_bus_call_method(
2835 bus,
2836 "org.freedesktop.login1",
2837 "/org/freedesktop/login1",
2838 "org.freedesktop.login1.Manager",
2839 method,
2840 &error,
2841 NULL,
2842 "b", arg_ask_password);
2843 if (r < 0)
2844 log_error("Failed to %s via logind: %s", description, bus_error_message(&error, r));
2845
2846 return r;
2847 #else
2848 return -ENOSYS;
2849 #endif
2850 }
2851
2852 static int check_inhibitors(sd_bus *bus, enum action a) {
2853 #ifdef HAVE_LOGIND
2854 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2855 _cleanup_strv_free_ char **sessions = NULL;
2856 const char *what, *who, *why, *mode;
2857 uint32_t uid, pid;
2858 unsigned c = 0;
2859 char **s;
2860 int r;
2861
2862 if (!bus)
2863 return 0;
2864
2865 if (arg_ignore_inhibitors || arg_force > 0)
2866 return 0;
2867
2868 if (arg_when > 0)
2869 return 0;
2870
2871 if (geteuid() == 0)
2872 return 0;
2873
2874 if (!on_tty())
2875 return 0;
2876
2877 r = sd_bus_call_method(
2878 bus,
2879 "org.freedesktop.login1",
2880 "/org/freedesktop/login1",
2881 "org.freedesktop.login1.Manager",
2882 "ListInhibitors",
2883 NULL,
2884 &reply,
2885 NULL);
2886 if (r < 0)
2887 /* If logind is not around, then there are no inhibitors... */
2888 return 0;
2889
2890 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssuu)");
2891 if (r < 0)
2892 return bus_log_parse_error(r);
2893
2894 while ((r = sd_bus_message_read(reply, "(ssssuu)", &what, &who, &why, &mode, &uid, &pid)) > 0) {
2895 _cleanup_free_ char *comm = NULL, *user = NULL;
2896 _cleanup_strv_free_ char **sv = NULL;
2897
2898 if (!streq(mode, "block"))
2899 continue;
2900
2901 sv = strv_split(what, ":");
2902 if (!sv)
2903 return log_oom();
2904
2905 if ((pid_t) pid < 0)
2906 return log_error_errno(ERANGE, "Bad PID %"PRIu32": %m", pid);
2907
2908 if (!strv_contains(sv,
2909 IN_SET(a,
2910 ACTION_HALT,
2911 ACTION_POWEROFF,
2912 ACTION_REBOOT,
2913 ACTION_KEXEC) ? "shutdown" : "sleep"))
2914 continue;
2915
2916 get_process_comm(pid, &comm);
2917 user = uid_to_name(uid);
2918
2919 log_warning("Operation inhibited by \"%s\" (PID "PID_FMT" \"%s\", user %s), reason is \"%s\".",
2920 who, (pid_t) pid, strna(comm), strna(user), why);
2921
2922 c++;
2923 }
2924 if (r < 0)
2925 return bus_log_parse_error(r);
2926
2927 r = sd_bus_message_exit_container(reply);
2928 if (r < 0)
2929 return bus_log_parse_error(r);
2930
2931 /* Check for current sessions */
2932 sd_get_sessions(&sessions);
2933 STRV_FOREACH(s, sessions) {
2934 _cleanup_free_ char *type = NULL, *tty = NULL, *seat = NULL, *user = NULL, *service = NULL, *class = NULL;
2935
2936 if (sd_session_get_uid(*s, &uid) < 0 || uid == getuid())
2937 continue;
2938
2939 if (sd_session_get_class(*s, &class) < 0 || !streq(class, "user"))
2940 continue;
2941
2942 if (sd_session_get_type(*s, &type) < 0 || (!streq(type, "x11") && !streq(type, "tty")))
2943 continue;
2944
2945 sd_session_get_tty(*s, &tty);
2946 sd_session_get_seat(*s, &seat);
2947 sd_session_get_service(*s, &service);
2948 user = uid_to_name(uid);
2949
2950 log_warning("User %s is logged in on %s.", strna(user), isempty(tty) ? (isempty(seat) ? strna(service) : seat) : tty);
2951 c++;
2952 }
2953
2954 if (c <= 0)
2955 return 0;
2956
2957 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
2958 action_table[a].verb);
2959
2960 return -EPERM;
2961 #else
2962 return 0;
2963 #endif
2964 }
2965
2966 static int prepare_firmware_setup(sd_bus *bus) {
2967 #ifdef HAVE_LOGIND
2968 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2969 #endif
2970 int r;
2971
2972 if (!arg_firmware_setup)
2973 return 0;
2974
2975 if (arg_transport == BUS_TRANSPORT_LOCAL) {
2976
2977 r = efi_set_reboot_to_firmware(true);
2978 if (r < 0)
2979 log_debug_errno(r, "Cannot indicate to EFI to boot into setup mode, will retry via logind: %m");
2980 else
2981 return r;
2982 }
2983
2984 #ifdef HAVE_LOGIND
2985 r = sd_bus_call_method(
2986 bus,
2987 "org.freedesktop.login1",
2988 "/org/freedesktop/login1",
2989 "org.freedesktop.login1.Manager",
2990 "SetRebootToFirmwareSetup",
2991 &error,
2992 NULL,
2993 "b", true);
2994 if (r < 0) {
2995 log_error("Cannot indicate to EFI to boot into setup mode: %s", bus_error_message(&error, r));
2996 return r;
2997 }
2998
2999 return 0;
3000 #else
3001 log_error("Cannot remotely indicate to EFI to boot into setup mode.");
3002 return -EINVAL;
3003 #endif
3004 }
3005
3006 static int start_special(sd_bus *bus, char **args) {
3007 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3008 enum action a;
3009 int r;
3010
3011 assert(args);
3012
3013 a = verb_to_action(args[0]);
3014
3015 r = check_inhibitors(bus, a);
3016 if (r < 0)
3017 return r;
3018
3019 if (arg_force >= 2 && geteuid() != 0) {
3020 log_error("Must be root.");
3021 return -EPERM;
3022 }
3023
3024 r = prepare_firmware_setup(bus);
3025 if (r < 0)
3026 return r;
3027
3028 if (a == ACTION_REBOOT && args[1]) {
3029 r = update_reboot_param_file(args[1]);
3030 if (r < 0)
3031 return r;
3032 } else if (a == ACTION_EXIT && strv_length(args) > 1) {
3033 /* If the exit code is not given on the command line, don't
3034 * reset it to zero: just keep it as it might have been set
3035 * previously. */
3036 uint8_t code = 0;
3037
3038 r = safe_atou8(args[1], &code);
3039 if (r < 0) {
3040 log_error("Invalid exit code.");
3041 return -EINVAL;
3042 }
3043
3044 r = sd_bus_call_method(
3045 bus,
3046 "org.freedesktop.systemd1",
3047 "/org/freedesktop/systemd1",
3048 "org.freedesktop.systemd1.Manager",
3049 "SetExitCode",
3050 &error,
3051 NULL,
3052 "y", code);
3053 if (r < 0) {
3054 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
3055 return r;
3056 }
3057 }
3058
3059 if (arg_force >= 2 &&
3060 IN_SET(a,
3061 ACTION_HALT,
3062 ACTION_POWEROFF,
3063 ACTION_REBOOT))
3064 return halt_now(a);
3065
3066 if (arg_force >= 1 &&
3067 IN_SET(a,
3068 ACTION_HALT,
3069 ACTION_POWEROFF,
3070 ACTION_REBOOT,
3071 ACTION_KEXEC,
3072 ACTION_EXIT))
3073 return daemon_reload(bus, args);
3074
3075 /* first try logind, to allow authentication with polkit */
3076 if (geteuid() != 0 &&
3077 IN_SET(a,
3078 ACTION_POWEROFF,
3079 ACTION_REBOOT,
3080 ACTION_SUSPEND,
3081 ACTION_HIBERNATE,
3082 ACTION_HYBRID_SLEEP)) {
3083 r = reboot_with_logind(bus, a);
3084 if (r >= 0)
3085 return r;
3086 if (IN_SET(r, -EOPNOTSUPP, -EINPROGRESS))
3087 /* requested operation is not supported or already in progress */
3088 return r;
3089 /* on all other errors, try low-level operation */
3090 }
3091
3092 r = start_unit(bus, args);
3093 if (r == EXIT_SUCCESS)
3094 warn_wall(a);
3095
3096 return r;
3097 }
3098
3099 static int check_unit_generic(sd_bus *bus, int code, const char *good_states, char **args) {
3100 _cleanup_strv_free_ char **names = NULL;
3101 char **name;
3102 int r;
3103
3104 assert(bus);
3105 assert(args);
3106
3107 r = expand_names(bus, args, NULL, &names);
3108 if (r < 0)
3109 return log_error_errno(r, "Failed to expand names: %m");
3110
3111 STRV_FOREACH(name, names) {
3112 int state;
3113
3114 state = check_one_unit(bus, *name, good_states, arg_quiet);
3115 if (state < 0)
3116 return state;
3117 if (state == 0)
3118 r = code;
3119 }
3120
3121 return r;
3122 }
3123
3124 static int check_unit_active(sd_bus *bus, char **args) {
3125 /* According to LSB: 3, "program is not running" */
3126 return check_unit_generic(bus, 3, "active\0reloading\0", args + 1);
3127 }
3128
3129 static int check_unit_failed(sd_bus *bus, char **args) {
3130 return check_unit_generic(bus, 1, "failed\0", args + 1);
3131 }
3132
3133 static int kill_unit(sd_bus *bus, char **args) {
3134 _cleanup_strv_free_ char **names = NULL;
3135 char *kill_who = NULL, **name;
3136 int r, q;
3137
3138 assert(bus);
3139 assert(args);
3140
3141 polkit_agent_open_if_enabled();
3142
3143 if (!arg_kill_who)
3144 arg_kill_who = "all";
3145
3146 /* --fail was specified */
3147 if (streq(arg_job_mode, "fail"))
3148 kill_who = strjoina(arg_kill_who, "-fail", NULL);
3149
3150 r = expand_names(bus, args + 1, NULL, &names);
3151 if (r < 0)
3152 log_error_errno(r, "Failed to expand names: %m");
3153
3154 STRV_FOREACH(name, names) {
3155 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3156
3157 q = sd_bus_call_method(
3158 bus,
3159 "org.freedesktop.systemd1",
3160 "/org/freedesktop/systemd1",
3161 "org.freedesktop.systemd1.Manager",
3162 "KillUnit",
3163 &error,
3164 NULL,
3165 "ssi", *names, kill_who ? kill_who : arg_kill_who, arg_signal);
3166 if (q < 0) {
3167 log_error("Failed to kill unit %s: %s", *names, bus_error_message(&error, q));
3168 if (r == 0)
3169 r = q;
3170 }
3171 }
3172
3173 return r;
3174 }
3175
3176 typedef struct ExecStatusInfo {
3177 char *name;
3178
3179 char *path;
3180 char **argv;
3181
3182 bool ignore;
3183
3184 usec_t start_timestamp;
3185 usec_t exit_timestamp;
3186 pid_t pid;
3187 int code;
3188 int status;
3189
3190 LIST_FIELDS(struct ExecStatusInfo, exec);
3191 } ExecStatusInfo;
3192
3193 static void exec_status_info_free(ExecStatusInfo *i) {
3194 assert(i);
3195
3196 free(i->name);
3197 free(i->path);
3198 strv_free(i->argv);
3199 free(i);
3200 }
3201
3202 static int exec_status_info_deserialize(sd_bus_message *m, ExecStatusInfo *i) {
3203 uint64_t start_timestamp, exit_timestamp, start_timestamp_monotonic, exit_timestamp_monotonic;
3204 const char *path;
3205 uint32_t pid;
3206 int32_t code, status;
3207 int ignore, r;
3208
3209 assert(m);
3210 assert(i);
3211
3212 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_STRUCT, "sasbttttuii");
3213 if (r < 0)
3214 return bus_log_parse_error(r);
3215 else if (r == 0)
3216 return 0;
3217
3218 r = sd_bus_message_read(m, "s", &path);
3219 if (r < 0)
3220 return bus_log_parse_error(r);
3221
3222 i->path = strdup(path);
3223 if (!i->path)
3224 return log_oom();
3225
3226 r = sd_bus_message_read_strv(m, &i->argv);
3227 if (r < 0)
3228 return bus_log_parse_error(r);
3229
3230 r = sd_bus_message_read(m,
3231 "bttttuii",
3232 &ignore,
3233 &start_timestamp, &start_timestamp_monotonic,
3234 &exit_timestamp, &exit_timestamp_monotonic,
3235 &pid,
3236 &code, &status);
3237 if (r < 0)
3238 return bus_log_parse_error(r);
3239
3240 i->ignore = ignore;
3241 i->start_timestamp = (usec_t) start_timestamp;
3242 i->exit_timestamp = (usec_t) exit_timestamp;
3243 i->pid = (pid_t) pid;
3244 i->code = code;
3245 i->status = status;
3246
3247 r = sd_bus_message_exit_container(m);
3248 if (r < 0)
3249 return bus_log_parse_error(r);
3250
3251 return 1;
3252 }
3253
3254 typedef struct UnitStatusInfo {
3255 const char *id;
3256 const char *load_state;
3257 const char *active_state;
3258 const char *sub_state;
3259 const char *unit_file_state;
3260 const char *unit_file_preset;
3261
3262 const char *description;
3263 const char *following;
3264
3265 char **documentation;
3266
3267 const char *fragment_path;
3268 const char *source_path;
3269 const char *control_group;
3270
3271 char **dropin_paths;
3272
3273 const char *load_error;
3274 const char *result;
3275
3276 usec_t inactive_exit_timestamp;
3277 usec_t inactive_exit_timestamp_monotonic;
3278 usec_t active_enter_timestamp;
3279 usec_t active_exit_timestamp;
3280 usec_t inactive_enter_timestamp;
3281
3282 bool need_daemon_reload;
3283
3284 /* Service */
3285 pid_t main_pid;
3286 pid_t control_pid;
3287 const char *status_text;
3288 const char *pid_file;
3289 bool running:1;
3290 int status_errno;
3291
3292 usec_t start_timestamp;
3293 usec_t exit_timestamp;
3294
3295 int exit_code, exit_status;
3296
3297 usec_t condition_timestamp;
3298 bool condition_result;
3299 bool failed_condition_trigger;
3300 bool failed_condition_negate;
3301 const char *failed_condition;
3302 const char *failed_condition_parameter;
3303
3304 usec_t assert_timestamp;
3305 bool assert_result;
3306 bool failed_assert_trigger;
3307 bool failed_assert_negate;
3308 const char *failed_assert;
3309 const char *failed_assert_parameter;
3310
3311 /* Socket */
3312 unsigned n_accepted;
3313 unsigned n_connections;
3314 bool accept;
3315
3316 /* Pairs of type, path */
3317 char **listen;
3318
3319 /* Device */
3320 const char *sysfs_path;
3321
3322 /* Mount, Automount */
3323 const char *where;
3324
3325 /* Swap */
3326 const char *what;
3327
3328 /* CGroup */
3329 uint64_t memory_current;
3330 uint64_t memory_limit;
3331 uint64_t cpu_usage_nsec;
3332 uint64_t tasks_current;
3333 uint64_t tasks_max;
3334
3335 LIST_HEAD(ExecStatusInfo, exec);
3336 } UnitStatusInfo;
3337
3338 static void print_status_info(
3339 UnitStatusInfo *i,
3340 bool *ellipsized) {
3341
3342 ExecStatusInfo *p;
3343 const char *active_on, *active_off, *on, *off, *ss;
3344 usec_t timestamp;
3345 char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
3346 char since2[FORMAT_TIMESTAMP_MAX], *s2;
3347 const char *path;
3348 char **t, **t2;
3349
3350 assert(i);
3351
3352 /* This shows pretty information about a unit. See
3353 * print_property() for a low-level property printer */
3354
3355 if (streq_ptr(i->active_state, "failed")) {
3356 active_on = ansi_highlight_red();
3357 active_off = ansi_normal();
3358 } else if (streq_ptr(i->active_state, "active") || streq_ptr(i->active_state, "reloading")) {
3359 active_on = ansi_highlight_green();
3360 active_off = ansi_normal();
3361 } else
3362 active_on = active_off = "";
3363
3364 printf("%s%s%s %s", active_on, draw_special_char(DRAW_BLACK_CIRCLE), active_off, strna(i->id));
3365
3366 if (i->description && !streq_ptr(i->id, i->description))
3367 printf(" - %s", i->description);
3368
3369 printf("\n");
3370
3371 if (i->following)
3372 printf(" Follow: unit currently follows state of %s\n", i->following);
3373
3374 if (streq_ptr(i->load_state, "error")) {
3375 on = ansi_highlight_red();
3376 off = ansi_normal();
3377 } else
3378 on = off = "";
3379
3380 path = i->source_path ? i->source_path : i->fragment_path;
3381
3382 if (i->load_error)
3383 printf(" Loaded: %s%s%s (Reason: %s)\n",
3384 on, strna(i->load_state), off, i->load_error);
3385 else if (path && !isempty(i->unit_file_state) && !isempty(i->unit_file_preset))
3386 printf(" Loaded: %s%s%s (%s; %s; vendor preset: %s)\n",
3387 on, strna(i->load_state), off, path, i->unit_file_state, i->unit_file_preset);
3388 else if (path && !isempty(i->unit_file_state))
3389 printf(" Loaded: %s%s%s (%s; %s)\n",
3390 on, strna(i->load_state), off, path, i->unit_file_state);
3391 else if (path)
3392 printf(" Loaded: %s%s%s (%s)\n",
3393 on, strna(i->load_state), off, path);
3394 else
3395 printf(" Loaded: %s%s%s\n",
3396 on, strna(i->load_state), off);
3397
3398 if (!strv_isempty(i->dropin_paths)) {
3399 _cleanup_free_ char *dir = NULL;
3400 bool last = false;
3401 char ** dropin;
3402
3403 STRV_FOREACH(dropin, i->dropin_paths) {
3404 if (! dir || last) {
3405 printf(dir ? " " : " Drop-In: ");
3406
3407 dir = mfree(dir);
3408
3409 if (path_get_parent(*dropin, &dir) < 0) {
3410 log_oom();
3411 return;
3412 }
3413
3414 printf("%s\n %s", dir,
3415 draw_special_char(DRAW_TREE_RIGHT));
3416 }
3417
3418 last = ! (*(dropin + 1) && startswith(*(dropin + 1), dir));
3419
3420 printf("%s%s", basename(*dropin), last ? "\n" : ", ");
3421 }
3422 }
3423
3424 ss = streq_ptr(i->active_state, i->sub_state) ? NULL : i->sub_state;
3425 if (ss)
3426 printf(" Active: %s%s (%s)%s",
3427 active_on, strna(i->active_state), ss, active_off);
3428 else
3429 printf(" Active: %s%s%s",
3430 active_on, strna(i->active_state), active_off);
3431
3432 if (!isempty(i->result) && !streq(i->result, "success"))
3433 printf(" (Result: %s)", i->result);
3434
3435 timestamp = (streq_ptr(i->active_state, "active") ||
3436 streq_ptr(i->active_state, "reloading")) ? i->active_enter_timestamp :
3437 (streq_ptr(i->active_state, "inactive") ||
3438 streq_ptr(i->active_state, "failed")) ? i->inactive_enter_timestamp :
3439 streq_ptr(i->active_state, "activating") ? i->inactive_exit_timestamp :
3440 i->active_exit_timestamp;
3441
3442 s1 = format_timestamp_relative(since1, sizeof(since1), timestamp);
3443 s2 = format_timestamp(since2, sizeof(since2), timestamp);
3444
3445 if (s1)
3446 printf(" since %s; %s\n", s2, s1);
3447 else if (s2)
3448 printf(" since %s\n", s2);
3449 else
3450 printf("\n");
3451
3452 if (!i->condition_result && i->condition_timestamp > 0) {
3453 s1 = format_timestamp_relative(since1, sizeof(since1), i->condition_timestamp);
3454 s2 = format_timestamp(since2, sizeof(since2), i->condition_timestamp);
3455
3456 printf("Condition: start %scondition failed%s at %s%s%s\n",
3457 ansi_highlight_yellow(), ansi_normal(),
3458 s2, s1 ? "; " : "", s1 ? s1 : "");
3459 if (i->failed_condition_trigger)
3460 printf(" none of the trigger conditions were met\n");
3461 else if (i->failed_condition)
3462 printf(" %s=%s%s was not met\n",
3463 i->failed_condition,
3464 i->failed_condition_negate ? "!" : "",
3465 i->failed_condition_parameter);
3466 }
3467
3468 if (!i->assert_result && i->assert_timestamp > 0) {
3469 s1 = format_timestamp_relative(since1, sizeof(since1), i->assert_timestamp);
3470 s2 = format_timestamp(since2, sizeof(since2), i->assert_timestamp);
3471
3472 printf(" Assert: start %sassertion failed%s at %s%s%s\n",
3473 ansi_highlight_red(), ansi_normal(),
3474 s2, s1 ? "; " : "", s1 ? s1 : "");
3475 if (i->failed_assert_trigger)
3476 printf(" none of the trigger assertions were met\n");
3477 else if (i->failed_assert)
3478 printf(" %s=%s%s was not met\n",
3479 i->failed_assert,
3480 i->failed_assert_negate ? "!" : "",
3481 i->failed_assert_parameter);
3482 }
3483
3484 if (i->sysfs_path)
3485 printf(" Device: %s\n", i->sysfs_path);
3486 if (i->where)
3487 printf(" Where: %s\n", i->where);
3488 if (i->what)
3489 printf(" What: %s\n", i->what);
3490
3491 STRV_FOREACH(t, i->documentation)
3492 printf(" %*s %s\n", 9, t == i->documentation ? "Docs:" : "", *t);
3493
3494 STRV_FOREACH_PAIR(t, t2, i->listen)
3495 printf(" %*s %s (%s)\n", 9, t == i->listen ? "Listen:" : "", *t2, *t);
3496
3497 if (i->accept)
3498 printf(" Accepted: %u; Connected: %u\n", i->n_accepted, i->n_connections);
3499
3500 LIST_FOREACH(exec, p, i->exec) {
3501 _cleanup_free_ char *argv = NULL;
3502 bool good;
3503
3504 /* Only show exited processes here */
3505 if (p->code == 0)
3506 continue;
3507
3508 argv = strv_join(p->argv, " ");
3509 printf(" Process: "PID_FMT" %s=%s ", p->pid, p->name, strna(argv));
3510
3511 good = is_clean_exit_lsb(p->code, p->status, NULL);
3512 if (!good) {
3513 on = ansi_highlight_red();
3514 off = ansi_normal();
3515 } else
3516 on = off = "";
3517
3518 printf("%s(code=%s, ", on, sigchld_code_to_string(p->code));
3519
3520 if (p->code == CLD_EXITED) {
3521 const char *c;
3522
3523 printf("status=%i", p->status);
3524
3525 c = exit_status_to_string(p->status, EXIT_STATUS_SYSTEMD);
3526 if (c)
3527 printf("/%s", c);
3528
3529 } else
3530 printf("signal=%s", signal_to_string(p->status));
3531
3532 printf(")%s\n", off);
3533
3534 if (i->main_pid == p->pid &&
3535 i->start_timestamp == p->start_timestamp &&
3536 i->exit_timestamp == p->start_timestamp)
3537 /* Let's not show this twice */
3538 i->main_pid = 0;
3539
3540 if (p->pid == i->control_pid)
3541 i->control_pid = 0;
3542 }
3543
3544 if (i->main_pid > 0 || i->control_pid > 0) {
3545 if (i->main_pid > 0) {
3546 printf(" Main PID: "PID_FMT, i->main_pid);
3547
3548 if (i->running) {
3549 _cleanup_free_ char *comm = NULL;
3550 get_process_comm(i->main_pid, &comm);
3551 if (comm)
3552 printf(" (%s)", comm);
3553 } else if (i->exit_code > 0) {
3554 printf(" (code=%s, ", sigchld_code_to_string(i->exit_code));
3555
3556 if (i->exit_code == CLD_EXITED) {
3557 const char *c;
3558
3559 printf("status=%i", i->exit_status);
3560
3561 c = exit_status_to_string(i->exit_status, EXIT_STATUS_SYSTEMD);
3562 if (c)
3563 printf("/%s", c);
3564
3565 } else
3566 printf("signal=%s", signal_to_string(i->exit_status));
3567 printf(")");
3568 }
3569
3570 if (i->control_pid > 0)
3571 printf(";");
3572 }
3573
3574 if (i->control_pid > 0) {
3575 _cleanup_free_ char *c = NULL;
3576
3577 printf(" %8s: "PID_FMT, i->main_pid ? "" : " Control", i->control_pid);
3578
3579 get_process_comm(i->control_pid, &c);
3580 if (c)
3581 printf(" (%s)", c);
3582 }
3583
3584 printf("\n");
3585 }
3586
3587 if (i->status_text)
3588 printf(" Status: \"%s\"\n", i->status_text);
3589 if (i->status_errno > 0)
3590 printf(" Error: %i (%s)\n", i->status_errno, strerror(i->status_errno));
3591
3592 if (i->tasks_current != (uint64_t) -1) {
3593 printf(" Tasks: %" PRIu64, i->tasks_current);
3594
3595 if (i->tasks_max != (uint64_t) -1)
3596 printf(" (limit: %" PRIi64 ")\n", i->tasks_max);
3597 else
3598 printf("\n");
3599 }
3600
3601 if (i->memory_current != (uint64_t) -1) {
3602 char buf[FORMAT_BYTES_MAX];
3603
3604 printf(" Memory: %s", format_bytes(buf, sizeof(buf), i->memory_current));
3605
3606 if (i->memory_limit != (uint64_t) -1)
3607 printf(" (limit: %s)\n", format_bytes(buf, sizeof(buf), i->memory_limit));
3608 else
3609 printf("\n");
3610 }
3611
3612 if (i->cpu_usage_nsec != (uint64_t) -1) {
3613 char buf[FORMAT_TIMESPAN_MAX];
3614 printf(" CPU: %s\n", format_timespan(buf, sizeof(buf), i->cpu_usage_nsec / NSEC_PER_USEC, USEC_PER_MSEC));
3615 }
3616
3617 if (i->control_group &&
3618 (i->main_pid > 0 || i->control_pid > 0 ||
3619 (!IN_SET(arg_transport, BUS_TRANSPORT_LOCAL, BUS_TRANSPORT_MACHINE) || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, i->control_group) == 0))) {
3620 unsigned c;
3621
3622 printf(" CGroup: %s\n", i->control_group);
3623
3624 if (IN_SET(arg_transport,
3625 BUS_TRANSPORT_LOCAL,
3626 BUS_TRANSPORT_MACHINE)) {
3627 unsigned k = 0;
3628 pid_t extra[2];
3629 static const char prefix[] = " ";
3630
3631 c = columns();
3632 if (c > sizeof(prefix) - 1)
3633 c -= sizeof(prefix) - 1;
3634 else
3635 c = 0;
3636
3637 if (i->main_pid > 0)
3638 extra[k++] = i->main_pid;
3639
3640 if (i->control_pid > 0)
3641 extra[k++] = i->control_pid;
3642
3643 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, i->control_group, prefix, c, false, extra, k, get_output_flags());
3644 }
3645 }
3646
3647 if (i->id && arg_transport == BUS_TRANSPORT_LOCAL)
3648 show_journal_by_unit(
3649 stdout,
3650 i->id,
3651 arg_output,
3652 0,
3653 i->inactive_exit_timestamp_monotonic,
3654 arg_lines,
3655 getuid(),
3656 get_output_flags() | OUTPUT_BEGIN_NEWLINE,
3657 SD_JOURNAL_LOCAL_ONLY,
3658 arg_scope == UNIT_FILE_SYSTEM,
3659 ellipsized);
3660
3661 if (i->need_daemon_reload)
3662 warn_unit_file_changed(i->id);
3663 }
3664
3665 static void show_unit_help(UnitStatusInfo *i) {
3666 char **p;
3667
3668 assert(i);
3669
3670 if (!i->documentation) {
3671 log_info("Documentation for %s not known.", i->id);
3672 return;
3673 }
3674
3675 STRV_FOREACH(p, i->documentation)
3676 if (startswith(*p, "man:"))
3677 show_man_page(*p + 4, false);
3678 else
3679 log_info("Can't show: %s", *p);
3680 }
3681
3682 static int status_property(const char *name, sd_bus_message *m, UnitStatusInfo *i, const char *contents) {
3683 int r;
3684
3685 assert(name);
3686 assert(m);
3687 assert(i);
3688
3689 switch (contents[0]) {
3690
3691 case SD_BUS_TYPE_STRING: {
3692 const char *s;
3693
3694 r = sd_bus_message_read(m, "s", &s);
3695 if (r < 0)
3696 return bus_log_parse_error(r);
3697
3698 if (!isempty(s)) {
3699 if (streq(name, "Id"))
3700 i->id = s;
3701 else if (streq(name, "LoadState"))
3702 i->load_state = s;
3703 else if (streq(name, "ActiveState"))
3704 i->active_state = s;
3705 else if (streq(name, "SubState"))
3706 i->sub_state = s;
3707 else if (streq(name, "Description"))
3708 i->description = s;
3709 else if (streq(name, "FragmentPath"))
3710 i->fragment_path = s;
3711 else if (streq(name, "SourcePath"))
3712 i->source_path = s;
3713 #ifndef NOLEGACY
3714 else if (streq(name, "DefaultControlGroup")) {
3715 const char *e;
3716 e = startswith(s, SYSTEMD_CGROUP_CONTROLLER ":");
3717 if (e)
3718 i->control_group = e;
3719 }
3720 #endif
3721 else if (streq(name, "ControlGroup"))
3722 i->control_group = s;
3723 else if (streq(name, "StatusText"))
3724 i->status_text = s;
3725 else if (streq(name, "PIDFile"))
3726 i->pid_file = s;
3727 else if (streq(name, "SysFSPath"))
3728 i->sysfs_path = s;
3729 else if (streq(name, "Where"))
3730 i->where = s;
3731 else if (streq(name, "What"))
3732 i->what = s;
3733 else if (streq(name, "Following"))
3734 i->following = s;
3735 else if (streq(name, "UnitFileState"))
3736 i->unit_file_state = s;
3737 else if (streq(name, "UnitFilePreset"))
3738 i->unit_file_preset = s;
3739 else if (streq(name, "Result"))
3740 i->result = s;
3741 }
3742
3743 break;
3744 }
3745
3746 case SD_BUS_TYPE_BOOLEAN: {
3747 int b;
3748
3749 r = sd_bus_message_read(m, "b", &b);
3750 if (r < 0)
3751 return bus_log_parse_error(r);
3752
3753 if (streq(name, "Accept"))
3754 i->accept = b;
3755 else if (streq(name, "NeedDaemonReload"))
3756 i->need_daemon_reload = b;
3757 else if (streq(name, "ConditionResult"))
3758 i->condition_result = b;
3759 else if (streq(name, "AssertResult"))
3760 i->assert_result = b;
3761
3762 break;
3763 }
3764
3765 case SD_BUS_TYPE_UINT32: {
3766 uint32_t u;
3767
3768 r = sd_bus_message_read(m, "u", &u);
3769 if (r < 0)
3770 return bus_log_parse_error(r);
3771
3772 if (streq(name, "MainPID")) {
3773 if (u > 0) {
3774 i->main_pid = (pid_t) u;
3775 i->running = true;
3776 }
3777 } else if (streq(name, "ControlPID"))
3778 i->control_pid = (pid_t) u;
3779 else if (streq(name, "ExecMainPID")) {
3780 if (u > 0)
3781 i->main_pid = (pid_t) u;
3782 } else if (streq(name, "NAccepted"))
3783 i->n_accepted = u;
3784 else if (streq(name, "NConnections"))
3785 i->n_connections = u;
3786
3787 break;
3788 }
3789
3790 case SD_BUS_TYPE_INT32: {
3791 int32_t j;
3792
3793 r = sd_bus_message_read(m, "i", &j);
3794 if (r < 0)
3795 return bus_log_parse_error(r);
3796
3797 if (streq(name, "ExecMainCode"))
3798 i->exit_code = (int) j;
3799 else if (streq(name, "ExecMainStatus"))
3800 i->exit_status = (int) j;
3801 else if (streq(name, "StatusErrno"))
3802 i->status_errno = (int) j;
3803
3804 break;
3805 }
3806
3807 case SD_BUS_TYPE_UINT64: {
3808 uint64_t u;
3809
3810 r = sd_bus_message_read(m, "t", &u);
3811 if (r < 0)
3812 return bus_log_parse_error(r);
3813
3814 if (streq(name, "ExecMainStartTimestamp"))
3815 i->start_timestamp = (usec_t) u;
3816 else if (streq(name, "ExecMainExitTimestamp"))
3817 i->exit_timestamp = (usec_t) u;
3818 else if (streq(name, "ActiveEnterTimestamp"))
3819 i->active_enter_timestamp = (usec_t) u;
3820 else if (streq(name, "InactiveEnterTimestamp"))
3821 i->inactive_enter_timestamp = (usec_t) u;
3822 else if (streq(name, "InactiveExitTimestamp"))
3823 i->inactive_exit_timestamp = (usec_t) u;
3824 else if (streq(name, "InactiveExitTimestampMonotonic"))
3825 i->inactive_exit_timestamp_monotonic = (usec_t) u;
3826 else if (streq(name, "ActiveExitTimestamp"))
3827 i->active_exit_timestamp = (usec_t) u;
3828 else if (streq(name, "ConditionTimestamp"))
3829 i->condition_timestamp = (usec_t) u;
3830 else if (streq(name, "AssertTimestamp"))
3831 i->assert_timestamp = (usec_t) u;
3832 else if (streq(name, "MemoryCurrent"))
3833 i->memory_current = u;
3834 else if (streq(name, "MemoryLimit"))
3835 i->memory_limit = u;
3836 else if (streq(name, "TasksCurrent"))
3837 i->tasks_current = u;
3838 else if (streq(name, "TasksMax"))
3839 i->tasks_max = u;
3840 else if (streq(name, "CPUUsageNSec"))
3841 i->cpu_usage_nsec = u;
3842
3843 break;
3844 }
3845
3846 case SD_BUS_TYPE_ARRAY:
3847
3848 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3849 _cleanup_free_ ExecStatusInfo *info = NULL;
3850
3851 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3852 if (r < 0)
3853 return bus_log_parse_error(r);
3854
3855 info = new0(ExecStatusInfo, 1);
3856 if (!info)
3857 return log_oom();
3858
3859 while ((r = exec_status_info_deserialize(m, info)) > 0) {
3860
3861 info->name = strdup(name);
3862 if (!info->name)
3863 log_oom();
3864
3865 LIST_PREPEND(exec, i->exec, info);
3866
3867 info = new0(ExecStatusInfo, 1);
3868 if (!info)
3869 log_oom();
3870 }
3871
3872 if (r < 0)
3873 return bus_log_parse_error(r);
3874
3875 r = sd_bus_message_exit_container(m);
3876 if (r < 0)
3877 return bus_log_parse_error(r);
3878
3879 return 0;
3880
3881 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3882 const char *type, *path;
3883
3884 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3885 if (r < 0)
3886 return bus_log_parse_error(r);
3887
3888 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0) {
3889
3890 r = strv_extend(&i->listen, type);
3891 if (r < 0)
3892 return r;
3893
3894 r = strv_extend(&i->listen, path);
3895 if (r < 0)
3896 return r;
3897 }
3898 if (r < 0)
3899 return bus_log_parse_error(r);
3900
3901 r = sd_bus_message_exit_container(m);
3902 if (r < 0)
3903 return bus_log_parse_error(r);
3904
3905 return 0;
3906
3907 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "DropInPaths")) {
3908
3909 r = sd_bus_message_read_strv(m, &i->dropin_paths);
3910 if (r < 0)
3911 return bus_log_parse_error(r);
3912
3913 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Documentation")) {
3914
3915 r = sd_bus_message_read_strv(m, &i->documentation);
3916 if (r < 0)
3917 return bus_log_parse_error(r);
3918
3919 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Conditions")) {
3920 const char *cond, *param;
3921 int trigger, negate;
3922 int32_t state;
3923
3924 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
3925 if (r < 0)
3926 return bus_log_parse_error(r);
3927
3928 while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, &param, &state)) > 0) {
3929 log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
3930 if (state < 0 && (!trigger || !i->failed_condition)) {
3931 i->failed_condition = cond;
3932 i->failed_condition_trigger = trigger;
3933 i->failed_condition_negate = negate;
3934 i->failed_condition_parameter = param;
3935 }
3936 }
3937 if (r < 0)
3938 return bus_log_parse_error(r);
3939
3940 r = sd_bus_message_exit_container(m);
3941 if (r < 0)
3942 return bus_log_parse_error(r);
3943
3944 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Asserts")) {
3945 const char *cond, *param;
3946 int trigger, negate;
3947 int32_t state;
3948
3949 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
3950 if (r < 0)
3951 return bus_log_parse_error(r);
3952
3953 while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, &param, &state)) > 0) {
3954 log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
3955 if (state < 0 && (!trigger || !i->failed_assert)) {
3956 i->failed_assert = cond;
3957 i->failed_assert_trigger = trigger;
3958 i->failed_assert_negate = negate;
3959 i->failed_assert_parameter = param;
3960 }
3961 }
3962 if (r < 0)
3963 return bus_log_parse_error(r);
3964
3965 r = sd_bus_message_exit_container(m);
3966 if (r < 0)
3967 return bus_log_parse_error(r);
3968
3969 } else
3970 goto skip;
3971
3972 break;
3973
3974 case SD_BUS_TYPE_STRUCT_BEGIN:
3975
3976 if (streq(name, "LoadError")) {
3977 const char *n, *message;
3978
3979 r = sd_bus_message_read(m, "(ss)", &n, &message);
3980 if (r < 0)
3981 return bus_log_parse_error(r);
3982
3983 if (!isempty(message))
3984 i->load_error = message;
3985 } else
3986 goto skip;
3987
3988 break;
3989
3990 default:
3991 goto skip;
3992 }
3993
3994 return 0;
3995
3996 skip:
3997 r = sd_bus_message_skip(m, contents);
3998 if (r < 0)
3999 return bus_log_parse_error(r);
4000
4001 return 0;
4002 }
4003
4004 static int print_property(const char *name, sd_bus_message *m, const char *contents) {
4005 int r;
4006
4007 assert(name);
4008 assert(m);
4009
4010 /* This is a low-level property printer, see
4011 * print_status_info() for the nicer output */
4012
4013 if (arg_properties && !strv_find(arg_properties, name)) {
4014 /* skip what we didn't read */
4015 r = sd_bus_message_skip(m, contents);
4016 return r;
4017 }
4018
4019 switch (contents[0]) {
4020
4021 case SD_BUS_TYPE_STRUCT_BEGIN:
4022
4023 if (contents[1] == SD_BUS_TYPE_UINT32 && streq(name, "Job")) {
4024 uint32_t u;
4025
4026 r = sd_bus_message_read(m, "(uo)", &u, NULL);
4027 if (r < 0)
4028 return bus_log_parse_error(r);
4029
4030 if (u > 0)
4031 printf("%s=%"PRIu32"\n", name, u);
4032 else if (arg_all)
4033 printf("%s=\n", name);
4034
4035 return 0;
4036
4037 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Unit")) {
4038 const char *s;
4039
4040 r = sd_bus_message_read(m, "(so)", &s, NULL);
4041 if (r < 0)
4042 return bus_log_parse_error(r);
4043
4044 if (arg_all || !isempty(s))
4045 printf("%s=%s\n", name, s);
4046
4047 return 0;
4048
4049 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "LoadError")) {
4050 const char *a = NULL, *b = NULL;
4051
4052 r = sd_bus_message_read(m, "(ss)", &a, &b);
4053 if (r < 0)
4054 return bus_log_parse_error(r);
4055
4056 if (arg_all || !isempty(a) || !isempty(b))
4057 printf("%s=%s \"%s\"\n", name, strempty(a), strempty(b));
4058
4059 return 0;
4060 } else if (streq_ptr(name, "SystemCallFilter")) {
4061 _cleanup_strv_free_ char **l = NULL;
4062 int whitelist;
4063
4064 r = sd_bus_message_enter_container(m, 'r', "bas");
4065 if (r < 0)
4066 return bus_log_parse_error(r);
4067
4068 r = sd_bus_message_read(m, "b", &whitelist);
4069 if (r < 0)
4070 return bus_log_parse_error(r);
4071
4072 r = sd_bus_message_read_strv(m, &l);
4073 if (r < 0)
4074 return bus_log_parse_error(r);
4075
4076 r = sd_bus_message_exit_container(m);
4077 if (r < 0)
4078 return bus_log_parse_error(r);
4079
4080 if (arg_all || whitelist || !strv_isempty(l)) {
4081 bool first = true;
4082 char **i;
4083
4084 fputs(name, stdout);
4085 fputc('=', stdout);
4086
4087 if (!whitelist)
4088 fputc('~', stdout);
4089
4090 STRV_FOREACH(i, l) {
4091 if (first)
4092 first = false;
4093 else
4094 fputc(' ', stdout);
4095
4096 fputs(*i, stdout);
4097 }
4098 fputc('\n', stdout);
4099 }
4100
4101 return 0;
4102 }
4103
4104 break;
4105
4106 case SD_BUS_TYPE_ARRAY:
4107
4108 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "EnvironmentFiles")) {
4109 const char *path;
4110 int ignore;
4111
4112 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sb)");
4113 if (r < 0)
4114 return bus_log_parse_error(r);
4115
4116 while ((r = sd_bus_message_read(m, "(sb)", &path, &ignore)) > 0)
4117 printf("EnvironmentFile=%s (ignore_errors=%s)\n", path, yes_no(ignore));
4118
4119 if (r < 0)
4120 return bus_log_parse_error(r);
4121
4122 r = sd_bus_message_exit_container(m);
4123 if (r < 0)
4124 return bus_log_parse_error(r);
4125
4126 return 0;
4127
4128 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Paths")) {
4129 const char *type, *path;
4130
4131 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
4132 if (r < 0)
4133 return bus_log_parse_error(r);
4134
4135 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
4136 printf("%s=%s\n", type, path);
4137 if (r < 0)
4138 return bus_log_parse_error(r);
4139
4140 r = sd_bus_message_exit_container(m);
4141 if (r < 0)
4142 return bus_log_parse_error(r);
4143
4144 return 0;
4145
4146 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
4147 const char *type, *path;
4148
4149 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
4150 if (r < 0)
4151 return bus_log_parse_error(r);
4152
4153 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
4154 printf("Listen%s=%s\n", type, path);
4155 if (r < 0)
4156 return bus_log_parse_error(r);
4157
4158 r = sd_bus_message_exit_container(m);
4159 if (r < 0)
4160 return bus_log_parse_error(r);
4161
4162 return 0;
4163
4164 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Timers")) {
4165 const char *base;
4166 uint64_t value, next_elapse;
4167
4168 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(stt)");
4169 if (r < 0)
4170 return bus_log_parse_error(r);
4171
4172 while ((r = sd_bus_message_read(m, "(stt)", &base, &value, &next_elapse)) > 0) {
4173 char timespan1[FORMAT_TIMESPAN_MAX], timespan2[FORMAT_TIMESPAN_MAX];
4174
4175 printf("%s={ value=%s ; next_elapse=%s }\n",
4176 base,
4177 format_timespan(timespan1, sizeof(timespan1), value, 0),
4178 format_timespan(timespan2, sizeof(timespan2), next_elapse, 0));
4179 }
4180 if (r < 0)
4181 return bus_log_parse_error(r);
4182
4183 r = sd_bus_message_exit_container(m);
4184 if (r < 0)
4185 return bus_log_parse_error(r);
4186
4187 return 0;
4188
4189 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
4190 ExecStatusInfo info = {};
4191
4192 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
4193 if (r < 0)
4194 return bus_log_parse_error(r);
4195
4196 while ((r = exec_status_info_deserialize(m, &info)) > 0) {
4197 char timestamp1[FORMAT_TIMESTAMP_MAX], timestamp2[FORMAT_TIMESTAMP_MAX];
4198 _cleanup_free_ char *tt;
4199
4200 tt = strv_join(info.argv, " ");
4201
4202 printf("%s={ path=%s ; argv[]=%s ; ignore_errors=%s ; start_time=[%s] ; stop_time=[%s] ; pid="PID_FMT" ; code=%s ; status=%i%s%s }\n",
4203 name,
4204 strna(info.path),
4205 strna(tt),
4206 yes_no(info.ignore),
4207 strna(format_timestamp(timestamp1, sizeof(timestamp1), info.start_timestamp)),
4208 strna(format_timestamp(timestamp2, sizeof(timestamp2), info.exit_timestamp)),
4209 info.pid,
4210 sigchld_code_to_string(info.code),
4211 info.status,
4212 info.code == CLD_EXITED ? "" : "/",
4213 strempty(info.code == CLD_EXITED ? NULL : signal_to_string(info.status)));
4214
4215 free(info.path);
4216 strv_free(info.argv);
4217 zero(info);
4218 }
4219
4220 r = sd_bus_message_exit_container(m);
4221 if (r < 0)
4222 return bus_log_parse_error(r);
4223
4224 return 0;
4225
4226 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "DeviceAllow")) {
4227 const char *path, *rwm;
4228
4229 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
4230 if (r < 0)
4231 return bus_log_parse_error(r);
4232
4233 while ((r = sd_bus_message_read(m, "(ss)", &path, &rwm)) > 0)
4234 printf("%s=%s %s\n", name, strna(path), strna(rwm));
4235 if (r < 0)
4236 return bus_log_parse_error(r);
4237
4238 r = sd_bus_message_exit_container(m);
4239 if (r < 0)
4240 return bus_log_parse_error(r);
4241
4242 return 0;
4243
4244 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "BlockIODeviceWeight")) {
4245 const char *path;
4246 uint64_t weight;
4247
4248 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
4249 if (r < 0)
4250 return bus_log_parse_error(r);
4251
4252 while ((r = sd_bus_message_read(m, "(st)", &path, &weight)) > 0)
4253 printf("%s=%s %" PRIu64 "\n", name, strna(path), weight);
4254 if (r < 0)
4255 return bus_log_parse_error(r);
4256
4257 r = sd_bus_message_exit_container(m);
4258 if (r < 0)
4259 return bus_log_parse_error(r);
4260
4261 return 0;
4262
4263 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && (streq(name, "BlockIOReadBandwidth") || streq(name, "BlockIOWriteBandwidth"))) {
4264 const char *path;
4265 uint64_t bandwidth;
4266
4267 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
4268 if (r < 0)
4269 return bus_log_parse_error(r);
4270
4271 while ((r = sd_bus_message_read(m, "(st)", &path, &bandwidth)) > 0)
4272 printf("%s=%s %" PRIu64 "\n", name, strna(path), bandwidth);
4273 if (r < 0)
4274 return bus_log_parse_error(r);
4275
4276 r = sd_bus_message_exit_container(m);
4277 if (r < 0)
4278 return bus_log_parse_error(r);
4279
4280 return 0;
4281 }
4282
4283 break;
4284 }
4285
4286 r = bus_print_property(name, m, arg_all);
4287 if (r < 0)
4288 return bus_log_parse_error(r);
4289
4290 if (r == 0) {
4291 r = sd_bus_message_skip(m, contents);
4292 if (r < 0)
4293 return bus_log_parse_error(r);
4294
4295 if (arg_all)
4296 printf("%s=[unprintable]\n", name);
4297 }
4298
4299 return 0;
4300 }
4301
4302 static int show_one(
4303 const char *verb,
4304 sd_bus *bus,
4305 const char *path,
4306 bool show_properties,
4307 bool *new_line,
4308 bool *ellipsized) {
4309
4310 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4311 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4312 UnitStatusInfo info = {
4313 .memory_current = (uint64_t) -1,
4314 .memory_limit = (uint64_t) -1,
4315 .cpu_usage_nsec = (uint64_t) -1,
4316 .tasks_current = (uint64_t) -1,
4317 .tasks_max = (uint64_t) -1,
4318 };
4319 ExecStatusInfo *p;
4320 int r;
4321
4322 assert(path);
4323 assert(new_line);
4324
4325 log_debug("Showing one %s", path);
4326
4327 r = sd_bus_call_method(
4328 bus,
4329 "org.freedesktop.systemd1",
4330 path,
4331 "org.freedesktop.DBus.Properties",
4332 "GetAll",
4333 &error,
4334 &reply,
4335 "s", "");
4336 if (r < 0)
4337 return log_error_errno(r, "Failed to get properties: %s", bus_error_message(&error, r));
4338
4339 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
4340 if (r < 0)
4341 return bus_log_parse_error(r);
4342
4343 if (*new_line)
4344 printf("\n");
4345
4346 *new_line = true;
4347
4348 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
4349 const char *name, *contents;
4350
4351 r = sd_bus_message_read(reply, "s", &name);
4352 if (r < 0)
4353 return bus_log_parse_error(r);
4354
4355 r = sd_bus_message_peek_type(reply, NULL, &contents);
4356 if (r < 0)
4357 return bus_log_parse_error(r);
4358
4359 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, contents);
4360 if (r < 0)
4361 return bus_log_parse_error(r);
4362
4363 if (show_properties)
4364 r = print_property(name, reply, contents);
4365 else
4366 r = status_property(name, reply, &info, contents);
4367 if (r < 0)
4368 return r;
4369
4370 r = sd_bus_message_exit_container(reply);
4371 if (r < 0)
4372 return bus_log_parse_error(r);
4373
4374 r = sd_bus_message_exit_container(reply);
4375 if (r < 0)
4376 return bus_log_parse_error(r);
4377 }
4378 if (r < 0)
4379 return bus_log_parse_error(r);
4380
4381 r = sd_bus_message_exit_container(reply);
4382 if (r < 0)
4383 return bus_log_parse_error(r);
4384
4385 r = 0;
4386
4387 if (!show_properties) {
4388 if (streq(verb, "help"))
4389 show_unit_help(&info);
4390 else
4391 print_status_info(&info, ellipsized);
4392 }
4393
4394 strv_free(info.documentation);
4395 strv_free(info.dropin_paths);
4396 strv_free(info.listen);
4397
4398 if (!streq_ptr(info.active_state, "active") &&
4399 !streq_ptr(info.active_state, "reloading") &&
4400 streq(verb, "status")) {
4401 /* According to LSB: "program not running" */
4402 /* 0: program is running or service is OK
4403 * 1: program is dead and /run PID file exists
4404 * 2: program is dead and /run/lock lock file exists
4405 * 3: program is not running
4406 * 4: program or service status is unknown
4407 */
4408 if (info.pid_file && access(info.pid_file, F_OK) == 0)
4409 r = 1;
4410 else
4411 r = 3;
4412 }
4413
4414 while ((p = info.exec)) {
4415 LIST_REMOVE(exec, info.exec, p);
4416 exec_status_info_free(p);
4417 }
4418
4419 return r;
4420 }
4421
4422 static int get_unit_dbus_path_by_pid(
4423 sd_bus *bus,
4424 uint32_t pid,
4425 char **unit) {
4426
4427 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4428 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4429 char *u;
4430 int r;
4431
4432 r = sd_bus_call_method(
4433 bus,
4434 "org.freedesktop.systemd1",
4435 "/org/freedesktop/systemd1",
4436 "org.freedesktop.systemd1.Manager",
4437 "GetUnitByPID",
4438 &error,
4439 &reply,
4440 "u", pid);
4441 if (r < 0) {
4442 log_error("Failed to get unit for PID %"PRIu32": %s", pid, bus_error_message(&error, r));
4443 return r;
4444 }
4445
4446 r = sd_bus_message_read(reply, "o", &u);
4447 if (r < 0)
4448 return bus_log_parse_error(r);
4449
4450 u = strdup(u);
4451 if (!u)
4452 return log_oom();
4453
4454 *unit = u;
4455 return 0;
4456 }
4457
4458 static int show_all(
4459 const char* verb,
4460 sd_bus *bus,
4461 bool show_properties,
4462 bool *new_line,
4463 bool *ellipsized) {
4464
4465 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4466 _cleanup_free_ UnitInfo *unit_infos = NULL;
4467 const UnitInfo *u;
4468 unsigned c;
4469 int r, ret = 0;
4470
4471 r = get_unit_list(bus, NULL, NULL, &unit_infos, 0, &reply);
4472 if (r < 0)
4473 return r;
4474
4475 pager_open_if_enabled();
4476
4477 c = (unsigned) r;
4478
4479 qsort_safe(unit_infos, c, sizeof(UnitInfo), compare_unit_info);
4480
4481 for (u = unit_infos; u < unit_infos + c; u++) {
4482 _cleanup_free_ char *p = NULL;
4483
4484 p = unit_dbus_path_from_name(u->id);
4485 if (!p)
4486 return log_oom();
4487
4488 r = show_one(verb, bus, p, show_properties, new_line, ellipsized);
4489 if (r < 0)
4490 return r;
4491 else if (r > 0 && ret == 0)
4492 ret = r;
4493 }
4494
4495 return ret;
4496 }
4497
4498 static int show_system_status(sd_bus *bus) {
4499 char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], since2[FORMAT_TIMESTAMP_MAX];
4500 _cleanup_free_ char *hn = NULL;
4501 _cleanup_(machine_info_clear) struct machine_info mi = {};
4502 const char *on, *off;
4503 int r;
4504
4505 hn = gethostname_malloc();
4506 if (!hn)
4507 return log_oom();
4508
4509 r = bus_map_all_properties(bus, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map, &mi);
4510 if (r < 0)
4511 return log_error_errno(r, "Failed to read server status: %m");
4512
4513 if (streq_ptr(mi.state, "degraded")) {
4514 on = ansi_highlight_red();
4515 off = ansi_normal();
4516 } else if (!streq_ptr(mi.state, "running")) {
4517 on = ansi_highlight_yellow();
4518 off = ansi_normal();
4519 } else
4520 on = off = "";
4521
4522 printf("%s%s%s %s\n", on, draw_special_char(DRAW_BLACK_CIRCLE), off, arg_host ? arg_host : hn);
4523
4524 printf(" State: %s%s%s\n",
4525 on, strna(mi.state), off);
4526
4527 printf(" Jobs: %u queued\n", mi.n_jobs);
4528 printf(" Failed: %u units\n", mi.n_failed_units);
4529
4530 printf(" Since: %s; %s\n",
4531 format_timestamp(since2, sizeof(since2), mi.timestamp),
4532 format_timestamp_relative(since1, sizeof(since1), mi.timestamp));
4533
4534 printf(" CGroup: %s\n", mi.control_group ?: "/");
4535 if (IN_SET(arg_transport,
4536 BUS_TRANSPORT_LOCAL,
4537 BUS_TRANSPORT_MACHINE)) {
4538 static const char prefix[] = " ";
4539 unsigned c;
4540
4541 c = columns();
4542 if (c > sizeof(prefix) - 1)
4543 c -= sizeof(prefix) - 1;
4544 else
4545 c = 0;
4546
4547 show_cgroup(SYSTEMD_CGROUP_CONTROLLER, strempty(mi.control_group), prefix, c, false, get_output_flags());
4548 }
4549
4550 return 0;
4551 }
4552
4553 static int show(sd_bus *bus, char **args) {
4554 bool show_properties, show_status, new_line = false;
4555 bool ellipsized = false;
4556 int r, ret = 0;
4557
4558 assert(bus);
4559 assert(args);
4560
4561 show_properties = streq(args[0], "show");
4562 show_status = streq(args[0], "status");
4563
4564 if (show_properties)
4565 pager_open_if_enabled();
4566
4567 if (show_status)
4568 /* Increase max number of open files to 16K if we can, we
4569 * might needs this when browsing journal files, which might
4570 * be split up into many files. */
4571 setrlimit_closest(RLIMIT_NOFILE, &RLIMIT_MAKE_CONST(16384));
4572
4573 /* If no argument is specified inspect the manager itself */
4574
4575 if (show_properties && strv_length(args) <= 1)
4576 return show_one(args[0], bus, "/org/freedesktop/systemd1", show_properties, &new_line, &ellipsized);
4577
4578 if (show_status && strv_length(args) <= 1) {
4579
4580 pager_open_if_enabled();
4581 show_system_status(bus);
4582 new_line = true;
4583
4584 if (arg_all)
4585 ret = show_all(args[0], bus, false, &new_line, &ellipsized);
4586 } else {
4587 _cleanup_free_ char **patterns = NULL;
4588 char **name;
4589
4590 STRV_FOREACH(name, args + 1) {
4591 _cleanup_free_ char *unit = NULL;
4592 uint32_t id;
4593
4594 if (safe_atou32(*name, &id) < 0) {
4595 if (strv_push(&patterns, *name) < 0)
4596 return log_oom();
4597
4598 continue;
4599 } else if (show_properties) {
4600 /* Interpret as job id */
4601 if (asprintf(&unit, "/org/freedesktop/systemd1/job/%u", id) < 0)
4602 return log_oom();
4603
4604 } else {
4605 /* Interpret as PID */
4606 r = get_unit_dbus_path_by_pid(bus, id, &unit);
4607 if (r < 0) {
4608 ret = r;
4609 continue;
4610 }
4611 }
4612
4613 r = show_one(args[0], bus, unit, show_properties,
4614 &new_line, &ellipsized);
4615 if (r < 0)
4616 return r;
4617 else if (r > 0 && ret == 0)
4618 ret = r;
4619 }
4620
4621 if (!strv_isempty(patterns)) {
4622 _cleanup_strv_free_ char **names = NULL;
4623
4624 r = expand_names(bus, patterns, NULL, &names);
4625 if (r < 0)
4626 log_error_errno(r, "Failed to expand names: %m");
4627
4628 STRV_FOREACH(name, names) {
4629 _cleanup_free_ char *unit;
4630
4631 unit = unit_dbus_path_from_name(*name);
4632 if (!unit)
4633 return log_oom();
4634
4635 r = show_one(args[0], bus, unit, show_properties,
4636 &new_line, &ellipsized);
4637 if (r < 0)
4638 return r;
4639 else if (r > 0 && ret == 0)
4640 ret = r;
4641 }
4642 }
4643 }
4644
4645 if (ellipsized && !arg_quiet)
4646 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
4647
4648 return ret;
4649 }
4650
4651 static int init_home_and_lookup_paths(char **user_home, char **user_runtime, LookupPaths *lp) {
4652 int r;
4653
4654 assert(user_home);
4655 assert(user_runtime);
4656 assert(lp);
4657
4658 if (arg_scope == UNIT_FILE_USER) {
4659 r = user_config_home(user_home);
4660 if (r < 0)
4661 return log_error_errno(r, "Failed to query XDG_CONFIG_HOME: %m");
4662 else if (r == 0)
4663 return log_error_errno(ENOTDIR, "Cannot find units: $XDG_CONFIG_HOME and $HOME are not set.");
4664
4665 r = user_runtime_dir(user_runtime);
4666 if (r < 0)
4667 return log_error_errno(r, "Failed to query XDG_CONFIG_HOME: %m");
4668 else if (r == 0)
4669 return log_error_errno(ENOTDIR, "Cannot find units: $XDG_RUNTIME_DIR is not set.");
4670 }
4671
4672 r = lookup_paths_init_from_scope(lp, arg_scope, arg_root);
4673 if (r < 0)
4674 return log_error_errno(r, "Failed to query unit lookup paths: %m");
4675
4676 return 0;
4677 }
4678
4679 static int cat_file(const char *filename, bool newline) {
4680 _cleanup_close_ int fd;
4681
4682 fd = open(filename, O_RDONLY|O_CLOEXEC|O_NOCTTY);
4683 if (fd < 0)
4684 return -errno;
4685
4686 printf("%s%s# %s%s\n",
4687 newline ? "\n" : "",
4688 ansi_highlight_blue(),
4689 filename,
4690 ansi_normal());
4691 fflush(stdout);
4692
4693 return copy_bytes(fd, STDOUT_FILENO, (uint64_t) -1, false);
4694 }
4695
4696 static int cat(sd_bus *bus, char **args) {
4697 _cleanup_free_ char *user_home = NULL;
4698 _cleanup_free_ char *user_runtime = NULL;
4699 _cleanup_lookup_paths_free_ LookupPaths lp = {};
4700 _cleanup_strv_free_ char **names = NULL;
4701 char **name;
4702 bool first = true, avoid_bus_cache;
4703 int r;
4704
4705 assert(args);
4706
4707 if (arg_transport != BUS_TRANSPORT_LOCAL) {
4708 log_error("Cannot remotely cat units");
4709 return -EINVAL;
4710 }
4711
4712 r = init_home_and_lookup_paths(&user_home, &user_runtime, &lp);
4713 if (r < 0)
4714 return r;
4715
4716 r = expand_names(bus, args + 1, NULL, &names);
4717 if (r < 0)
4718 return log_error_errno(r, "Failed to expand names: %m");
4719
4720 avoid_bus_cache = !bus || avoid_bus();
4721
4722 pager_open_if_enabled();
4723
4724 STRV_FOREACH(name, names) {
4725 _cleanup_free_ char *fragment_path = NULL;
4726 _cleanup_strv_free_ char **dropin_paths = NULL;
4727 char **path;
4728
4729 r = unit_find_paths(bus, *name, avoid_bus_cache, &lp, &fragment_path, &dropin_paths);
4730 if (r < 0)
4731 return r;
4732 else if (r == 0)
4733 return -ENOENT;
4734
4735 if (first)
4736 first = false;
4737 else
4738 puts("");
4739
4740 if (fragment_path) {
4741 r = cat_file(fragment_path, false);
4742 if (r < 0)
4743 return log_warning_errno(r, "Failed to cat %s: %m", fragment_path);
4744 }
4745
4746 STRV_FOREACH(path, dropin_paths) {
4747 r = cat_file(*path, path == dropin_paths);
4748 if (r < 0)
4749 return log_warning_errno(r, "Failed to cat %s: %m", *path);
4750 }
4751 }
4752
4753 return 0;
4754 }
4755
4756 static int set_property(sd_bus *bus, char **args) {
4757 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4758 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4759 _cleanup_free_ char *n = NULL;
4760 char **i;
4761 int r;
4762
4763 polkit_agent_open_if_enabled();
4764
4765 r = sd_bus_message_new_method_call(
4766 bus,
4767 &m,
4768 "org.freedesktop.systemd1",
4769 "/org/freedesktop/systemd1",
4770 "org.freedesktop.systemd1.Manager",
4771 "SetUnitProperties");
4772 if (r < 0)
4773 return bus_log_create_error(r);
4774
4775 r = unit_name_mangle(args[1], UNIT_NAME_NOGLOB, &n);
4776 if (r < 0)
4777 return log_error_errno(r, "Failed to mangle unit name: %m");
4778
4779 r = sd_bus_message_append(m, "sb", n, arg_runtime);
4780 if (r < 0)
4781 return bus_log_create_error(r);
4782
4783 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, "(sv)");
4784 if (r < 0)
4785 return bus_log_create_error(r);
4786
4787 STRV_FOREACH(i, args + 2) {
4788 r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv");
4789 if (r < 0)
4790 return bus_log_create_error(r);
4791
4792 r = bus_append_unit_property_assignment(m, *i);
4793 if (r < 0)
4794 return r;
4795
4796 r = sd_bus_message_close_container(m);
4797 if (r < 0)
4798 return bus_log_create_error(r);
4799 }
4800
4801 r = sd_bus_message_close_container(m);
4802 if (r < 0)
4803 return bus_log_create_error(r);
4804
4805 r = sd_bus_call(bus, m, 0, &error, NULL);
4806 if (r < 0) {
4807 log_error("Failed to set unit properties on %s: %s", n, bus_error_message(&error, r));
4808 return r;
4809 }
4810
4811 return 0;
4812 }
4813
4814 static int snapshot(sd_bus *bus, char **args) {
4815 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4816 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4817 _cleanup_free_ char *n = NULL, *id = NULL;
4818 const char *path;
4819 int r;
4820
4821 polkit_agent_open_if_enabled();
4822
4823 if (strv_length(args) > 1) {
4824 r = unit_name_mangle_with_suffix(args[1], UNIT_NAME_NOGLOB, ".snapshot", &n);
4825 if (r < 0)
4826 return log_error_errno(r, "Failed to generate unit name: %m");
4827 } else {
4828 n = strdup("");
4829 if (!n)
4830 return log_oom();
4831 }
4832
4833 r = sd_bus_call_method(
4834 bus,
4835 "org.freedesktop.systemd1",
4836 "/org/freedesktop/systemd1",
4837 "org.freedesktop.systemd1.Manager",
4838 "CreateSnapshot",
4839 &error,
4840 &reply,
4841 "sb", n, false);
4842 if (r < 0) {
4843 log_error("Failed to create snapshot: %s", bus_error_message(&error, r));
4844 return r;
4845 }
4846
4847 r = sd_bus_message_read(reply, "o", &path);
4848 if (r < 0)
4849 return bus_log_parse_error(r);
4850
4851 r = sd_bus_get_property_string(
4852 bus,
4853 "org.freedesktop.systemd1",
4854 path,
4855 "org.freedesktop.systemd1.Unit",
4856 "Id",
4857 &error,
4858 &id);
4859 if (r < 0) {
4860 log_error("Failed to get ID of snapshot: %s", bus_error_message(&error, r));
4861 return r;
4862 }
4863
4864 if (!arg_quiet)
4865 puts(id);
4866
4867 return 0;
4868 }
4869
4870 static int delete_snapshot(sd_bus *bus, char **args) {
4871 _cleanup_strv_free_ char **names = NULL;
4872 char **name;
4873 int r;
4874
4875 assert(args);
4876
4877 polkit_agent_open_if_enabled();
4878
4879 r = expand_names(bus, args + 1, ".snapshot", &names);
4880 if (r < 0)
4881 log_error_errno(r, "Failed to expand names: %m");
4882
4883 STRV_FOREACH(name, names) {
4884 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4885 int q;
4886
4887 q = sd_bus_call_method(
4888 bus,
4889 "org.freedesktop.systemd1",
4890 "/org/freedesktop/systemd1",
4891 "org.freedesktop.systemd1.Manager",
4892 "RemoveSnapshot",
4893 &error,
4894 NULL,
4895 "s", *name);
4896 if (q < 0) {
4897 log_error("Failed to remove snapshot %s: %s", *name, bus_error_message(&error, q));
4898 if (r == 0)
4899 r = q;
4900 }
4901 }
4902
4903 return r;
4904 }
4905
4906 static int daemon_reload(sd_bus *bus, char **args) {
4907 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4908 const char *method;
4909 int r;
4910
4911 polkit_agent_open_if_enabled();
4912
4913 if (arg_action == ACTION_RELOAD)
4914 method = "Reload";
4915 else if (arg_action == ACTION_REEXEC)
4916 method = "Reexecute";
4917 else {
4918 assert(arg_action == ACTION_SYSTEMCTL);
4919
4920 method =
4921 streq(args[0], "clear-jobs") ||
4922 streq(args[0], "cancel") ? "ClearJobs" :
4923 streq(args[0], "daemon-reexec") ? "Reexecute" :
4924 streq(args[0], "reset-failed") ? "ResetFailed" :
4925 streq(args[0], "halt") ? "Halt" :
4926 streq(args[0], "poweroff") ? "PowerOff" :
4927 streq(args[0], "reboot") ? "Reboot" :
4928 streq(args[0], "kexec") ? "KExec" :
4929 streq(args[0], "exit") ? "Exit" :
4930 /* "daemon-reload" */ "Reload";
4931 }
4932
4933 r = sd_bus_call_method(
4934 bus,
4935 "org.freedesktop.systemd1",
4936 "/org/freedesktop/systemd1",
4937 "org.freedesktop.systemd1.Manager",
4938 method,
4939 &error,
4940 NULL,
4941 NULL);
4942 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
4943 /* There's always a fallback possible for
4944 * legacy actions. */
4945 r = -EADDRNOTAVAIL;
4946 else if ((r == -ETIMEDOUT || r == -ECONNRESET) && streq(method, "Reexecute"))
4947 /* On reexecution, we expect a disconnect, not a
4948 * reply */
4949 r = 0;
4950 else if (r < 0)
4951 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
4952
4953 return r < 0 ? r : 0;
4954 }
4955
4956 static int reset_failed(sd_bus *bus, char **args) {
4957 _cleanup_strv_free_ char **names = NULL;
4958 char **name;
4959 int r, q;
4960
4961 if (strv_length(args) <= 1)
4962 return daemon_reload(bus, args);
4963
4964 polkit_agent_open_if_enabled();
4965
4966 r = expand_names(bus, args + 1, NULL, &names);
4967 if (r < 0)
4968 log_error_errno(r, "Failed to expand names: %m");
4969
4970 STRV_FOREACH(name, names) {
4971 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4972
4973 q = sd_bus_call_method(
4974 bus,
4975 "org.freedesktop.systemd1",
4976 "/org/freedesktop/systemd1",
4977 "org.freedesktop.systemd1.Manager",
4978 "ResetFailedUnit",
4979 &error,
4980 NULL,
4981 "s", *name);
4982 if (q < 0) {
4983 log_error("Failed to reset failed state of unit %s: %s", *name, bus_error_message(&error, q));
4984 if (r == 0)
4985 r = q;
4986 }
4987 }
4988
4989 return r;
4990 }
4991
4992 static int show_environment(sd_bus *bus, char **args) {
4993 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4994 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4995 const char *text;
4996 int r;
4997
4998 pager_open_if_enabled();
4999
5000 r = sd_bus_get_property(
5001 bus,
5002 "org.freedesktop.systemd1",
5003 "/org/freedesktop/systemd1",
5004 "org.freedesktop.systemd1.Manager",
5005 "Environment",
5006 &error,
5007 &reply,
5008 "as");
5009 if (r < 0) {
5010 log_error("Failed to get environment: %s", bus_error_message(&error, r));
5011 return r;
5012 }
5013
5014 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "s");
5015 if (r < 0)
5016 return bus_log_parse_error(r);
5017
5018 while ((r = sd_bus_message_read_basic(reply, SD_BUS_TYPE_STRING, &text)) > 0)
5019 puts(text);
5020 if (r < 0)
5021 return bus_log_parse_error(r);
5022
5023 r = sd_bus_message_exit_container(reply);
5024 if (r < 0)
5025 return bus_log_parse_error(r);
5026
5027 return 0;
5028 }
5029
5030 static int switch_root(sd_bus *bus, char **args) {
5031 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5032 _cleanup_free_ char *cmdline_init = NULL;
5033 const char *root, *init;
5034 unsigned l;
5035 int r;
5036
5037 l = strv_length(args);
5038 if (l < 2 || l > 3) {
5039 log_error("Wrong number of arguments.");
5040 return -EINVAL;
5041 }
5042
5043 root = args[1];
5044
5045 if (l >= 3)
5046 init = args[2];
5047 else {
5048 r = parse_env_file("/proc/cmdline", WHITESPACE,
5049 "init", &cmdline_init,
5050 NULL);
5051 if (r < 0)
5052 log_debug_errno(r, "Failed to parse /proc/cmdline: %m");
5053
5054 init = cmdline_init;
5055 }
5056
5057 if (isempty(init))
5058 init = NULL;
5059
5060 if (init) {
5061 const char *root_systemd_path = NULL, *root_init_path = NULL;
5062
5063 root_systemd_path = strjoina(root, "/" SYSTEMD_BINARY_PATH);
5064 root_init_path = strjoina(root, "/", init);
5065
5066 /* If the passed init is actually the same as the
5067 * systemd binary, then let's suppress it. */
5068 if (files_same(root_init_path, root_systemd_path) > 0)
5069 init = NULL;
5070 }
5071
5072 log_debug("Switching root - root: %s; init: %s", root, strna(init));
5073
5074 r = sd_bus_call_method(
5075 bus,
5076 "org.freedesktop.systemd1",
5077 "/org/freedesktop/systemd1",
5078 "org.freedesktop.systemd1.Manager",
5079 "SwitchRoot",
5080 &error,
5081 NULL,
5082 "ss", root, init);
5083 if (r < 0) {
5084 log_error("Failed to switch root: %s", bus_error_message(&error, r));
5085 return r;
5086 }
5087
5088 return 0;
5089 }
5090
5091 static int set_environment(sd_bus *bus, char **args) {
5092 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5093 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
5094 const char *method;
5095 int r;
5096
5097 assert(bus);
5098 assert(args);
5099
5100 polkit_agent_open_if_enabled();
5101
5102 method = streq(args[0], "set-environment")
5103 ? "SetEnvironment"
5104 : "UnsetEnvironment";
5105
5106 r = sd_bus_message_new_method_call(
5107 bus,
5108 &m,
5109 "org.freedesktop.systemd1",
5110 "/org/freedesktop/systemd1",
5111 "org.freedesktop.systemd1.Manager",
5112 method);
5113 if (r < 0)
5114 return bus_log_create_error(r);
5115
5116 r = sd_bus_message_append_strv(m, args + 1);
5117 if (r < 0)
5118 return bus_log_create_error(r);
5119
5120 r = sd_bus_call(bus, m, 0, &error, NULL);
5121 if (r < 0) {
5122 log_error("Failed to set environment: %s", bus_error_message(&error, r));
5123 return r;
5124 }
5125
5126 return 0;
5127 }
5128
5129 static int import_environment(sd_bus *bus, char **args) {
5130 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5131 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
5132 int r;
5133
5134 assert(bus);
5135 assert(args);
5136
5137 polkit_agent_open_if_enabled();
5138
5139 r = sd_bus_message_new_method_call(
5140 bus,
5141 &m,
5142 "org.freedesktop.systemd1",
5143 "/org/freedesktop/systemd1",
5144 "org.freedesktop.systemd1.Manager",
5145 "SetEnvironment");
5146 if (r < 0)
5147 return bus_log_create_error(r);
5148
5149 if (strv_isempty(args + 1))
5150 r = sd_bus_message_append_strv(m, environ);
5151 else {
5152 char **a, **b;
5153
5154 r = sd_bus_message_open_container(m, 'a', "s");
5155 if (r < 0)
5156 return bus_log_create_error(r);
5157
5158 STRV_FOREACH(a, args + 1) {
5159
5160 if (!env_name_is_valid(*a)) {
5161 log_error("Not a valid environment variable name: %s", *a);
5162 return -EINVAL;
5163 }
5164
5165 STRV_FOREACH(b, environ) {
5166 const char *eq;
5167
5168 eq = startswith(*b, *a);
5169 if (eq && *eq == '=') {
5170
5171 r = sd_bus_message_append(m, "s", *b);
5172 if (r < 0)
5173 return bus_log_create_error(r);
5174
5175 break;
5176 }
5177 }
5178 }
5179
5180 r = sd_bus_message_close_container(m);
5181 }
5182 if (r < 0)
5183 return bus_log_create_error(r);
5184
5185 r = sd_bus_call(bus, m, 0, &error, NULL);
5186 if (r < 0) {
5187 log_error("Failed to import environment: %s", bus_error_message(&error, r));
5188 return r;
5189 }
5190
5191 return 0;
5192 }
5193
5194 static int enable_sysv_units(const char *verb, char **args) {
5195 int r = 0;
5196
5197 #if defined(HAVE_SYSV_COMPAT)
5198 unsigned f = 0;
5199 _cleanup_lookup_paths_free_ LookupPaths paths = {};
5200
5201 if (arg_scope != UNIT_FILE_SYSTEM)
5202 return 0;
5203
5204 if (!STR_IN_SET(verb,
5205 "enable",
5206 "disable",
5207 "is-enabled"))
5208 return 0;
5209
5210 /* Processes all SysV units, and reshuffles the array so that
5211 * afterwards only the native units remain */
5212
5213 r = lookup_paths_init(&paths, MANAGER_SYSTEM, false, arg_root, NULL, NULL, NULL);
5214 if (r < 0)
5215 return r;
5216
5217 r = 0;
5218 while (args[f]) {
5219 const char *name;
5220 _cleanup_free_ char *p = NULL, *q = NULL, *l = NULL;
5221 bool found_native = false, found_sysv;
5222 unsigned c = 1;
5223 const char *argv[6] = { ROOTLIBEXECDIR "/systemd-sysv-install", NULL, NULL, NULL, NULL };
5224 char **k;
5225 int j;
5226 pid_t pid;
5227 siginfo_t status;
5228
5229 name = args[f++];
5230
5231 if (!endswith(name, ".service"))
5232 continue;
5233
5234 if (path_is_absolute(name))
5235 continue;
5236
5237 STRV_FOREACH(k, paths.unit_path) {
5238 _cleanup_free_ char *path = NULL;
5239
5240 path = path_join(arg_root, *k, name);
5241 if (!path)
5242 return log_oom();
5243
5244 found_native = access(path, F_OK) >= 0;
5245 if (found_native)
5246 break;
5247 }
5248
5249 /* If we have both a native unit and a SysV script,
5250 * enable/disable them both (below); for is-enabled, prefer the
5251 * native unit */
5252 if (found_native && streq(verb, "is-enabled"))
5253 continue;
5254
5255 p = path_join(arg_root, SYSTEM_SYSVINIT_PATH, name);
5256 if (!p)
5257 return log_oom();
5258
5259 p[strlen(p) - strlen(".service")] = 0;
5260 found_sysv = access(p, F_OK) >= 0;
5261 if (!found_sysv)
5262 continue;
5263
5264 if (found_native)
5265 log_info("Synchronizing state of %s with SysV init with %s...", name, argv[0]);
5266 else
5267 log_info("%s is not a native service, redirecting to systemd-sysv-install", name);
5268
5269 if (!isempty(arg_root))
5270 argv[c++] = q = strappend("--root=", arg_root);
5271
5272 argv[c++] = verb;
5273 argv[c++] = basename(p);
5274 argv[c] = NULL;
5275
5276 l = strv_join((char**)argv, " ");
5277 if (!l)
5278 return log_oom();
5279
5280 log_info("Executing %s", l);
5281
5282 pid = fork();
5283 if (pid < 0)
5284 return log_error_errno(errno, "Failed to fork: %m");
5285 else if (pid == 0) {
5286 /* Child */
5287
5288 (void) reset_all_signal_handlers();
5289 (void) reset_signal_mask();
5290
5291 execv(argv[0], (char**) argv);
5292 log_error("Failed to execute %s: %m", argv[0]);
5293 _exit(EXIT_FAILURE);
5294 }
5295
5296 j = wait_for_terminate(pid, &status);
5297 if (j < 0) {
5298 log_error_errno(r, "Failed to wait for child: %m");
5299 return j;
5300 }
5301
5302 if (status.si_code == CLD_EXITED) {
5303 if (streq(verb, "is-enabled")) {
5304 if (status.si_status == 0) {
5305 if (!arg_quiet)
5306 puts("enabled");
5307 r = 1;
5308 } else {
5309 if (!arg_quiet)
5310 puts("disabled");
5311 }
5312
5313 } else if (status.si_status != 0)
5314 return -EINVAL;
5315 } else
5316 return -EPROTO;
5317
5318 if (found_native)
5319 continue;
5320
5321 /* Remove this entry, so that we don't try enabling it as native unit */
5322 assert(f > 0);
5323 f--;
5324 assert(args[f] == name);
5325 strv_remove(args, name);
5326 }
5327
5328 #endif
5329 return r;
5330 }
5331
5332 static int mangle_names(char **original_names, char ***mangled_names) {
5333 char **i, **l, **name;
5334 int r;
5335
5336 l = i = new(char*, strv_length(original_names) + 1);
5337 if (!l)
5338 return log_oom();
5339
5340 STRV_FOREACH(name, original_names) {
5341
5342 /* When enabling units qualified path names are OK,
5343 * too, hence allow them explicitly. */
5344
5345 if (is_path(*name)) {
5346 *i = strdup(*name);
5347 if (!*i) {
5348 strv_free(l);
5349 return log_oom();
5350 }
5351 } else {
5352 r = unit_name_mangle(*name, UNIT_NAME_NOGLOB, i);
5353 if (r < 0) {
5354 strv_free(l);
5355 return log_error_errno(r, "Failed to mangle unit name: %m");
5356 }
5357 }
5358
5359 i++;
5360 }
5361
5362 *i = NULL;
5363 *mangled_names = l;
5364
5365 return 0;
5366 }
5367
5368 static int enable_unit(sd_bus *bus, char **args) {
5369 _cleanup_strv_free_ char **names = NULL;
5370 const char *verb = args[0];
5371 UnitFileChange *changes = NULL;
5372 unsigned n_changes = 0;
5373 int carries_install_info = -1;
5374 int r;
5375
5376 if (!args[1])
5377 return 0;
5378
5379 r = mangle_names(args+1, &names);
5380 if (r < 0)
5381 return r;
5382
5383 r = enable_sysv_units(verb, names);
5384 if (r < 0)
5385 return r;
5386
5387 /* If the operation was fully executed by the SysV compat,
5388 * let's finish early */
5389 if (strv_isempty(names))
5390 return 0;
5391
5392 if (!bus || avoid_bus()) {
5393 if (streq(verb, "enable")) {
5394 r = unit_file_enable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5395 carries_install_info = r;
5396 } else if (streq(verb, "disable"))
5397 r = unit_file_disable(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
5398 else if (streq(verb, "reenable")) {
5399 r = unit_file_reenable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5400 carries_install_info = r;
5401 } else if (streq(verb, "link"))
5402 r = unit_file_link(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5403 else if (streq(verb, "preset")) {
5404 r = unit_file_preset(arg_scope, arg_runtime, arg_root, names, arg_preset_mode, arg_force, &changes, &n_changes);
5405 carries_install_info = r;
5406 } else if (streq(verb, "mask"))
5407 r = unit_file_mask(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5408 else if (streq(verb, "unmask"))
5409 r = unit_file_unmask(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
5410 else
5411 assert_not_reached("Unknown verb");
5412
5413 if (r < 0) {
5414 log_error_errno(r, "Operation failed: %m");
5415 goto finish;
5416 }
5417
5418 if (!arg_quiet)
5419 dump_unit_file_changes(changes, n_changes);
5420
5421 r = 0;
5422 } else {
5423 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
5424 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5425 int expect_carries_install_info = false;
5426 bool send_force = true, send_preset_mode = false;
5427 const char *method;
5428
5429 polkit_agent_open_if_enabled();
5430
5431 if (streq(verb, "enable")) {
5432 method = "EnableUnitFiles";
5433 expect_carries_install_info = true;
5434 } else if (streq(verb, "disable")) {
5435 method = "DisableUnitFiles";
5436 send_force = false;
5437 } else if (streq(verb, "reenable")) {
5438 method = "ReenableUnitFiles";
5439 expect_carries_install_info = true;
5440 } else if (streq(verb, "link"))
5441 method = "LinkUnitFiles";
5442 else if (streq(verb, "preset")) {
5443
5444 if (arg_preset_mode != UNIT_FILE_PRESET_FULL) {
5445 method = "PresetUnitFilesWithMode";
5446 send_preset_mode = true;
5447 } else
5448 method = "PresetUnitFiles";
5449
5450 expect_carries_install_info = true;
5451 } else if (streq(verb, "mask"))
5452 method = "MaskUnitFiles";
5453 else if (streq(verb, "unmask")) {
5454 method = "UnmaskUnitFiles";
5455 send_force = false;
5456 } else
5457 assert_not_reached("Unknown verb");
5458
5459 r = sd_bus_message_new_method_call(
5460 bus,
5461 &m,
5462 "org.freedesktop.systemd1",
5463 "/org/freedesktop/systemd1",
5464 "org.freedesktop.systemd1.Manager",
5465 method);
5466 if (r < 0)
5467 return bus_log_create_error(r);
5468
5469 r = sd_bus_message_append_strv(m, names);
5470 if (r < 0)
5471 return bus_log_create_error(r);
5472
5473 if (send_preset_mode) {
5474 r = sd_bus_message_append(m, "s", unit_file_preset_mode_to_string(arg_preset_mode));
5475 if (r < 0)
5476 return bus_log_create_error(r);
5477 }
5478
5479 r = sd_bus_message_append(m, "b", arg_runtime);
5480 if (r < 0)
5481 return bus_log_create_error(r);
5482
5483 if (send_force) {
5484 r = sd_bus_message_append(m, "b", arg_force);
5485 if (r < 0)
5486 return bus_log_create_error(r);
5487 }
5488
5489 r = sd_bus_call(bus, m, 0, &error, &reply);
5490 if (r < 0) {
5491 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
5492 return r;
5493 }
5494
5495 if (expect_carries_install_info) {
5496 r = sd_bus_message_read(reply, "b", &carries_install_info);
5497 if (r < 0)
5498 return bus_log_parse_error(r);
5499 }
5500
5501 r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet, &changes, &n_changes);
5502 if (r < 0)
5503 return r;
5504
5505 /* Try to reload if enabled */
5506 if (!arg_no_reload)
5507 r = daemon_reload(bus, args);
5508 else
5509 r = 0;
5510 }
5511
5512 if (carries_install_info == 0)
5513 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
5514 "using systemctl.\n"
5515 "Possible reasons for having this kind of units are:\n"
5516 "1) A unit may be statically enabled by being symlinked from another unit's\n"
5517 " .wants/ or .requires/ directory.\n"
5518 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
5519 " a requirement dependency on it.\n"
5520 "3) A unit may be started when needed via activation (socket, path, timer,\n"
5521 " D-Bus, udev, scripted systemctl call, ...).\n");
5522
5523 if (arg_now && n_changes > 0 && STR_IN_SET(args[0], "enable", "disable", "mask")) {
5524 char *new_args[n_changes + 2];
5525 unsigned i;
5526
5527 new_args[0] = streq(args[0], "enable") ? (char *)"start" : (char *)"stop";
5528 for (i = 0; i < n_changes; i++)
5529 new_args[i + 1] = basename(changes[i].path);
5530 new_args[i + 1] = NULL;
5531
5532 r = start_unit(bus, new_args);
5533 }
5534
5535 finish:
5536 unit_file_changes_free(changes, n_changes);
5537
5538 return r;
5539 }
5540
5541 static int add_dependency(sd_bus *bus, char **args) {
5542 _cleanup_strv_free_ char **names = NULL;
5543 _cleanup_free_ char *target = NULL;
5544 const char *verb = args[0];
5545 UnitDependency dep;
5546 int r = 0;
5547
5548 if (!args[1])
5549 return 0;
5550
5551 r = unit_name_mangle_with_suffix(args[1], UNIT_NAME_NOGLOB, ".target", &target);
5552 if (r < 0)
5553 return log_error_errno(r, "Failed to mangle unit name: %m");
5554
5555 r = mangle_names(args+2, &names);
5556 if (r < 0)
5557 return r;
5558
5559 if (streq(verb, "add-wants"))
5560 dep = UNIT_WANTS;
5561 else if (streq(verb, "add-requires"))
5562 dep = UNIT_REQUIRES;
5563 else
5564 assert_not_reached("Unknown verb");
5565
5566 if (!bus || avoid_bus()) {
5567 UnitFileChange *changes = NULL;
5568 unsigned n_changes = 0;
5569
5570 r = unit_file_add_dependency(arg_scope, arg_runtime, arg_root, names, target, dep, arg_force, &changes, &n_changes);
5571
5572 if (r < 0)
5573 return log_error_errno(r, "Can't add dependency: %m");
5574
5575 if (!arg_quiet)
5576 dump_unit_file_changes(changes, n_changes);
5577
5578 unit_file_changes_free(changes, n_changes);
5579
5580 } else {
5581 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
5582 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5583
5584 polkit_agent_open_if_enabled();
5585
5586 r = sd_bus_message_new_method_call(
5587 bus,
5588 &m,
5589 "org.freedesktop.systemd1",
5590 "/org/freedesktop/systemd1",
5591 "org.freedesktop.systemd1.Manager",
5592 "AddDependencyUnitFiles");
5593 if (r < 0)
5594 return bus_log_create_error(r);
5595
5596 r = sd_bus_message_append_strv(m, names);
5597 if (r < 0)
5598 return bus_log_create_error(r);
5599
5600 r = sd_bus_message_append(m, "ssbb", target, unit_dependency_to_string(dep), arg_runtime, arg_force);
5601 if (r < 0)
5602 return bus_log_create_error(r);
5603
5604 r = sd_bus_call(bus, m, 0, &error, &reply);
5605 if (r < 0) {
5606 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
5607 return r;
5608 }
5609
5610 r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet, NULL, NULL);
5611 if (r < 0)
5612 return r;
5613
5614 if (!arg_no_reload)
5615 r = daemon_reload(bus, args);
5616 else
5617 r = 0;
5618 }
5619
5620 return r;
5621 }
5622
5623 static int preset_all(sd_bus *bus, char **args) {
5624 UnitFileChange *changes = NULL;
5625 unsigned n_changes = 0;
5626 int r;
5627
5628 if (!bus || avoid_bus()) {
5629
5630 r = unit_file_preset_all(arg_scope, arg_runtime, arg_root, arg_preset_mode, arg_force, &changes, &n_changes);
5631 if (r < 0) {
5632 log_error_errno(r, "Operation failed: %m");
5633 goto finish;
5634 }
5635
5636 if (!arg_quiet)
5637 dump_unit_file_changes(changes, n_changes);
5638
5639 r = 0;
5640
5641 } else {
5642 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5643 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
5644
5645 polkit_agent_open_if_enabled();
5646
5647 r = sd_bus_call_method(
5648 bus,
5649 "org.freedesktop.systemd1",
5650 "/org/freedesktop/systemd1",
5651 "org.freedesktop.systemd1.Manager",
5652 "PresetAllUnitFiles",
5653 &error,
5654 &reply,
5655 "sbb",
5656 unit_file_preset_mode_to_string(arg_preset_mode),
5657 arg_runtime,
5658 arg_force);
5659 if (r < 0) {
5660 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
5661 return r;
5662 }
5663
5664 r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet, NULL, NULL);
5665 if (r < 0)
5666 return r;
5667
5668 if (!arg_no_reload)
5669 r = daemon_reload(bus, args);
5670 else
5671 r = 0;
5672 }
5673
5674 finish:
5675 unit_file_changes_free(changes, n_changes);
5676
5677 return r;
5678 }
5679
5680 static int unit_is_enabled(sd_bus *bus, char **args) {
5681
5682 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5683 _cleanup_strv_free_ char **names = NULL;
5684 bool enabled;
5685 char **name;
5686 int r;
5687
5688 r = mangle_names(args+1, &names);
5689 if (r < 0)
5690 return r;
5691
5692 r = enable_sysv_units(args[0], names);
5693 if (r < 0)
5694 return r;
5695
5696 enabled = r > 0;
5697
5698 if (!bus || avoid_bus()) {
5699
5700 STRV_FOREACH(name, names) {
5701 UnitFileState state;
5702
5703 state = unit_file_get_state(arg_scope, arg_root, *name);
5704 if (state < 0)
5705 return log_error_errno(state, "Failed to get unit file state for %s: %m", *name);
5706
5707 if (IN_SET(state,
5708 UNIT_FILE_ENABLED,
5709 UNIT_FILE_ENABLED_RUNTIME,
5710 UNIT_FILE_STATIC,
5711 UNIT_FILE_INDIRECT))
5712 enabled = true;
5713
5714 if (!arg_quiet)
5715 puts(unit_file_state_to_string(state));
5716 }
5717
5718 } else {
5719 STRV_FOREACH(name, names) {
5720 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
5721 const char *s;
5722
5723 r = sd_bus_call_method(
5724 bus,
5725 "org.freedesktop.systemd1",
5726 "/org/freedesktop/systemd1",
5727 "org.freedesktop.systemd1.Manager",
5728 "GetUnitFileState",
5729 &error,
5730 &reply,
5731 "s", *name);
5732 if (r < 0) {
5733 log_error("Failed to get unit file state for %s: %s", *name, bus_error_message(&error, r));
5734 return r;
5735 }
5736
5737 r = sd_bus_message_read(reply, "s", &s);
5738 if (r < 0)
5739 return bus_log_parse_error(r);
5740
5741 if (STR_IN_SET(s, "enabled", "enabled-runtime", "static", "indirect"))
5742 enabled = true;
5743
5744 if (!arg_quiet)
5745 puts(s);
5746 }
5747 }
5748
5749 return !enabled;
5750 }
5751
5752 static int is_system_running(sd_bus *bus, char **args) {
5753 _cleanup_free_ char *state = NULL;
5754 int r;
5755
5756 if (arg_transport == BUS_TRANSPORT_LOCAL && !sd_booted()) {
5757 if (!arg_quiet)
5758 puts("offline");
5759 return EXIT_FAILURE;
5760 }
5761
5762 r = sd_bus_get_property_string(
5763 bus,
5764 "org.freedesktop.systemd1",
5765 "/org/freedesktop/systemd1",
5766 "org.freedesktop.systemd1.Manager",
5767 "SystemState",
5768 NULL,
5769 &state);
5770 if (r < 0) {
5771 if (!arg_quiet)
5772 puts("unknown");
5773 return 0;
5774 }
5775
5776 if (!arg_quiet)
5777 puts(state);
5778
5779 return streq(state, "running") ? EXIT_SUCCESS : EXIT_FAILURE;
5780 }
5781
5782 static int create_edit_temp_file(const char *new_path, const char *original_path, char **ret_tmp_fn) {
5783 char *t;
5784 int r;
5785
5786 assert(new_path);
5787 assert(original_path);
5788 assert(ret_tmp_fn);
5789
5790 r = tempfn_random(new_path, NULL, &t);
5791 if (r < 0)
5792 return log_error_errno(r, "Failed to determine temporary filename for \"%s\": %m", new_path);
5793
5794 r = mkdir_parents(new_path, 0755);
5795 if (r < 0) {
5796 log_error_errno(r, "Failed to create directories for \"%s\": %m", new_path);
5797 free(t);
5798 return r;
5799 }
5800
5801 r = copy_file(original_path, t, 0, 0644, 0);
5802 if (r == -ENOENT) {
5803 r = touch(t);
5804 if (r < 0) {
5805 log_error_errno(r, "Failed to create temporary file \"%s\": %m", t);
5806 free(t);
5807 return r;
5808 }
5809 } else if (r < 0) {
5810 log_error_errno(r, "Failed to copy \"%s\" to \"%s\": %m", original_path, t);
5811 free(t);
5812 return r;
5813 }
5814
5815 *ret_tmp_fn = t;
5816
5817 return 0;
5818 }
5819
5820 static int get_file_to_edit(const char *name, const char *user_home, const char *user_runtime, char **ret_path) {
5821 _cleanup_free_ char *path = NULL, *path2 = NULL, *run = NULL;
5822
5823 switch (arg_scope) {
5824 case UNIT_FILE_SYSTEM:
5825 path = path_join(arg_root, SYSTEM_CONFIG_UNIT_PATH, name);
5826 if (arg_runtime)
5827 run = path_join(arg_root, "/run/systemd/system/", name);
5828 break;
5829 case UNIT_FILE_GLOBAL:
5830 path = path_join(arg_root, USER_CONFIG_UNIT_PATH, name);
5831 if (arg_runtime)
5832 run = path_join(arg_root, "/run/systemd/user/", name);
5833 break;
5834 case UNIT_FILE_USER:
5835 assert(user_home);
5836 assert(user_runtime);
5837
5838 path = path_join(arg_root, user_home, name);
5839 if (arg_runtime) {
5840 path2 = path_join(arg_root, USER_CONFIG_UNIT_PATH, name);
5841 if (!path2)
5842 return log_oom();
5843 run = path_join(arg_root, user_runtime, name);
5844 }
5845 break;
5846 default:
5847 assert_not_reached("Invalid scope");
5848 }
5849 if (!path || (arg_runtime && !run))
5850 return log_oom();
5851
5852 if (arg_runtime) {
5853 if (access(path, F_OK) >= 0)
5854 return log_error_errno(EEXIST, "Refusing to create \"%s\" because it would be overridden by \"%s\" anyway.",
5855 run, path);
5856 if (path2 && access(path2, F_OK) >= 0)
5857 return log_error_errno(EEXIST, "Refusing to create \"%s\" because it would be overridden by \"%s\" anyway.",
5858 run, path2);
5859 *ret_path = run;
5860 run = NULL;
5861 } else {
5862 *ret_path = path;
5863 path = NULL;
5864 }
5865
5866 return 0;
5867 }
5868
5869 static int unit_file_create_dropin(const char *unit_name, const char *user_home, const char *user_runtime, char **ret_new_path, char **ret_tmp_path) {
5870 char *tmp_new_path, *ending;
5871 char *tmp_tmp_path;
5872 int r;
5873
5874 assert(unit_name);
5875 assert(ret_new_path);
5876 assert(ret_tmp_path);
5877
5878 ending = strjoina(unit_name, ".d/override.conf");
5879 r = get_file_to_edit(ending, user_home, user_runtime, &tmp_new_path);
5880 if (r < 0)
5881 return r;
5882
5883 r = create_edit_temp_file(tmp_new_path, tmp_new_path, &tmp_tmp_path);
5884 if (r < 0) {
5885 free(tmp_new_path);
5886 return r;
5887 }
5888
5889 *ret_new_path = tmp_new_path;
5890 *ret_tmp_path = tmp_tmp_path;
5891
5892 return 0;
5893 }
5894
5895 static int unit_file_create_copy(
5896 const char *unit_name,
5897 const char *fragment_path,
5898 const char *user_home,
5899 const char *user_runtime,
5900 char **ret_new_path,
5901 char **ret_tmp_path) {
5902
5903 char *tmp_new_path;
5904 char *tmp_tmp_path;
5905 int r;
5906
5907 assert(fragment_path);
5908 assert(unit_name);
5909 assert(ret_new_path);
5910 assert(ret_tmp_path);
5911
5912 r = get_file_to_edit(unit_name, user_home, user_runtime, &tmp_new_path);
5913 if (r < 0)
5914 return r;
5915
5916 if (!path_equal(fragment_path, tmp_new_path) && access(tmp_new_path, F_OK) == 0) {
5917 char response;
5918
5919 r = ask_char(&response, "yn", "\"%s\" already exists. Overwrite with \"%s\"? [(y)es, (n)o] ", tmp_new_path, fragment_path);
5920 if (r < 0) {
5921 free(tmp_new_path);
5922 return r;
5923 }
5924 if (response != 'y') {
5925 log_warning("%s ignored", unit_name);
5926 free(tmp_new_path);
5927 return -1;
5928 }
5929 }
5930
5931 r = create_edit_temp_file(tmp_new_path, fragment_path, &tmp_tmp_path);
5932 if (r < 0) {
5933 log_error_errno(r, "Failed to create temporary file for \"%s\": %m", tmp_new_path);
5934 free(tmp_new_path);
5935 return r;
5936 }
5937
5938 *ret_new_path = tmp_new_path;
5939 *ret_tmp_path = tmp_tmp_path;
5940
5941 return 0;
5942 }
5943
5944 static int run_editor(char **paths) {
5945 pid_t pid;
5946 int r;
5947
5948 assert(paths);
5949
5950 pid = fork();
5951 if (pid < 0) {
5952 log_error_errno(errno, "Failed to fork: %m");
5953 return -errno;
5954 }
5955
5956 if (pid == 0) {
5957 const char **args;
5958 char *editor, **editor_args = NULL;
5959 char **tmp_path, **original_path, *p;
5960 unsigned n_editor_args = 0, i = 1;
5961 size_t argc;
5962
5963 (void) reset_all_signal_handlers();
5964 (void) reset_signal_mask();
5965
5966 argc = strv_length(paths)/2 + 1;
5967
5968 /* SYSTEMD_EDITOR takes precedence over EDITOR which takes precedence over VISUAL
5969 * If neither SYSTEMD_EDITOR nor EDITOR nor VISUAL are present,
5970 * we try to execute well known editors
5971 */
5972 editor = getenv("SYSTEMD_EDITOR");
5973 if (!editor)
5974 editor = getenv("EDITOR");
5975 if (!editor)
5976 editor = getenv("VISUAL");
5977
5978 if (!isempty(editor)) {
5979 editor_args = strv_split(editor, WHITESPACE);
5980 if (!editor_args) {
5981 (void) log_oom();
5982 _exit(EXIT_FAILURE);
5983 }
5984 n_editor_args = strv_length(editor_args);
5985 argc += n_editor_args - 1;
5986 }
5987 args = newa(const char*, argc + 1);
5988
5989 if (n_editor_args > 0) {
5990 args[0] = editor_args[0];
5991 for (; i < n_editor_args; i++)
5992 args[i] = editor_args[i];
5993 }
5994
5995 STRV_FOREACH_PAIR(original_path, tmp_path, paths) {
5996 args[i] = *tmp_path;
5997 i++;
5998 }
5999 args[i] = NULL;
6000
6001 if (n_editor_args > 0)
6002 execvp(args[0], (char* const*) args);
6003
6004 FOREACH_STRING(p, "editor", "nano", "vim", "vi") {
6005 args[0] = p;
6006 execvp(p, (char* const*) args);
6007 /* We do not fail if the editor doesn't exist
6008 * because we want to try each one of them before
6009 * failing.
6010 */
6011 if (errno != ENOENT) {
6012 log_error("Failed to execute %s: %m", editor);
6013 _exit(EXIT_FAILURE);
6014 }
6015 }
6016
6017 log_error("Cannot edit unit(s), no editor available. Please set either $SYSTEMD_EDITOR, $EDITOR or $VISUAL.");
6018 _exit(EXIT_FAILURE);
6019 }
6020
6021 r = wait_for_terminate_and_warn("editor", pid, true);
6022 if (r < 0)
6023 return log_error_errno(r, "Failed to wait for child: %m");
6024
6025 return r;
6026 }
6027
6028 static int find_paths_to_edit(sd_bus *bus, char **names, char ***paths) {
6029 _cleanup_free_ char *user_home = NULL;
6030 _cleanup_free_ char *user_runtime = NULL;
6031 _cleanup_lookup_paths_free_ LookupPaths lp = {};
6032 bool avoid_bus_cache;
6033 char **name;
6034 int r;
6035
6036 assert(names);
6037 assert(paths);
6038
6039 r = init_home_and_lookup_paths(&user_home, &user_runtime, &lp);
6040 if (r < 0)
6041 return r;
6042
6043 avoid_bus_cache = !bus || avoid_bus();
6044
6045 STRV_FOREACH(name, names) {
6046 _cleanup_free_ char *path = NULL;
6047 char *new_path, *tmp_path;
6048
6049 r = unit_find_paths(bus, *name, avoid_bus_cache, &lp, &path, NULL);
6050 if (r < 0)
6051 return r;
6052 else if (r == 0)
6053 return -ENOENT;
6054 else if (!path) {
6055 // FIXME: support units with path==NULL (no FragmentPath)
6056 log_error("No fragment exists for %s.", *name);
6057 return -ENOENT;
6058 }
6059
6060 if (arg_full)
6061 r = unit_file_create_copy(*name, path, user_home, user_runtime, &new_path, &tmp_path);
6062 else
6063 r = unit_file_create_dropin(*name, user_home, user_runtime, &new_path, &tmp_path);
6064 if (r < 0)
6065 return r;
6066
6067 r = strv_push_pair(paths, new_path, tmp_path);
6068 if (r < 0)
6069 return log_oom();
6070 }
6071
6072 return 0;
6073 }
6074
6075 static int edit(sd_bus *bus, char **args) {
6076 _cleanup_strv_free_ char **names = NULL;
6077 _cleanup_strv_free_ char **paths = NULL;
6078 char **original, **tmp;
6079 int r;
6080
6081 assert(args);
6082
6083 if (!on_tty()) {
6084 log_error("Cannot edit units if not on a tty");
6085 return -EINVAL;
6086 }
6087
6088 if (arg_transport != BUS_TRANSPORT_LOCAL) {
6089 log_error("Cannot remotely edit units");
6090 return -EINVAL;
6091 }
6092
6093 r = expand_names(bus, args + 1, NULL, &names);
6094 if (r < 0)
6095 return log_error_errno(r, "Failed to expand names: %m");
6096
6097 r = find_paths_to_edit(bus, names, &paths);
6098 if (r < 0)
6099 return r;
6100
6101 if (strv_isempty(paths))
6102 return -ENOENT;
6103
6104 r = run_editor(paths);
6105 if (r < 0)
6106 goto end;
6107
6108 STRV_FOREACH_PAIR(original, tmp, paths) {
6109 /* If the temporary file is empty we ignore it.
6110 * It's useful if the user wants to cancel its modification
6111 */
6112 if (null_or_empty_path(*tmp)) {
6113 log_warning("Editing \"%s\" canceled: temporary file is empty", *original);
6114 continue;
6115 }
6116 r = rename(*tmp, *original);
6117 if (r < 0) {
6118 r = log_error_errno(errno, "Failed to rename \"%s\" to \"%s\": %m", *tmp, *original);
6119 goto end;
6120 }
6121 }
6122
6123 if (!arg_no_reload && bus && !avoid_bus())
6124 r = daemon_reload(bus, args);
6125
6126 end:
6127 STRV_FOREACH_PAIR(original, tmp, paths)
6128 unlink_noerrno(*tmp);
6129
6130 return r;
6131 }
6132
6133 static void systemctl_help(void) {
6134
6135 pager_open_if_enabled();
6136
6137 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
6138 "Query or send control commands to the systemd manager.\n\n"
6139 " -h --help Show this help\n"
6140 " --version Show package version\n"
6141 " --system Connect to system manager\n"
6142 " --user Connect to user service manager\n"
6143 " -H --host=[USER@]HOST\n"
6144 " Operate on remote host\n"
6145 " -M --machine=CONTAINER\n"
6146 " Operate on local container\n"
6147 " -t --type=TYPE List units of a particular type\n"
6148 " --state=STATE List units with particular LOAD or SUB or ACTIVE state\n"
6149 " -p --property=NAME Show only properties by this name\n"
6150 " -a --all Show all loaded units/properties, including dead/empty\n"
6151 " ones. To list all units installed on the system, use\n"
6152 " the 'list-unit-files' command instead.\n"
6153 " -l --full Don't ellipsize unit names on output\n"
6154 " -r --recursive Show unit list of host and local containers\n"
6155 " --reverse Show reverse dependencies with 'list-dependencies'\n"
6156 " --job-mode=MODE Specify how to deal with already queued jobs, when\n"
6157 " queueing a new job\n"
6158 " --show-types When showing sockets, explicitly show their type\n"
6159 " -i --ignore-inhibitors\n"
6160 " When shutting down or sleeping, ignore inhibitors\n"
6161 " --kill-who=WHO Who to send signal to\n"
6162 " -s --signal=SIGNAL Which signal to send\n"
6163 " --now Start or stop unit in addition to enabling or disabling it\n"
6164 " -q --quiet Suppress output\n"
6165 " --no-block Do not wait until operation finished\n"
6166 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6167 " --no-reload Don't reload daemon after en-/dis-abling unit files\n"
6168 " --no-legend Do not print a legend (column headers and hints)\n"
6169 " --no-pager Do not pipe output into a pager\n"
6170 " --no-ask-password\n"
6171 " Do not ask for system passwords\n"
6172 " --global Enable/disable unit files globally\n"
6173 " --runtime Enable unit files only temporarily until next reboot\n"
6174 " -f --force When enabling unit files, override existing symlinks\n"
6175 " When shutting down, execute action immediately\n"
6176 " --preset-mode= Apply only enable, only disable, or all presets\n"
6177 " --root=PATH Enable unit files in the specified root directory\n"
6178 " -n --lines=INTEGER Number of journal entries to show\n"
6179 " -o --output=STRING Change journal output mode (short, short-iso,\n"
6180 " short-precise, short-monotonic, verbose,\n"
6181 " export, json, json-pretty, json-sse, cat)\n"
6182 " --firmware-setup Tell the firmware to show the setup menu on next boot\n"
6183 " --plain Print unit dependencies as a list instead of a tree\n\n"
6184 "Unit Commands:\n"
6185 " list-units [PATTERN...] List loaded units\n"
6186 " list-sockets [PATTERN...] List loaded sockets ordered by address\n"
6187 " list-timers [PATTERN...] List loaded timers ordered by next elapse\n"
6188 " start NAME... Start (activate) one or more units\n"
6189 " stop NAME... Stop (deactivate) one or more units\n"
6190 " reload NAME... Reload one or more units\n"
6191 " restart NAME... Start or restart one or more units\n"
6192 " try-restart NAME... Restart one or more units if active\n"
6193 " reload-or-restart NAME... Reload one or more units if possible,\n"
6194 " otherwise start or restart\n"
6195 " reload-or-try-restart NAME... Reload one or more units if possible,\n"
6196 " otherwise restart if active\n"
6197 " isolate NAME Start one unit and stop all others\n"
6198 " kill NAME... Send signal to processes of a unit\n"
6199 " is-active PATTERN... Check whether units are active\n"
6200 " is-failed PATTERN... Check whether units are failed\n"
6201 " status [PATTERN...|PID...] Show runtime status of one or more units\n"
6202 " show [PATTERN...|JOB...] Show properties of one or more\n"
6203 " units/jobs or the manager\n"
6204 " cat PATTERN... Show files and drop-ins of one or more units\n"
6205 " set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
6206 " help PATTERN...|PID... Show manual for one or more units\n"
6207 " reset-failed [PATTERN...] Reset failed state for all, one, or more\n"
6208 " units\n"
6209 " list-dependencies [NAME] Recursively show units which are required\n"
6210 " or wanted by this unit or by which this\n"
6211 " unit is required or wanted\n\n"
6212 "Unit File Commands:\n"
6213 " list-unit-files [PATTERN...] List installed unit files\n"
6214 " enable NAME... Enable one or more unit files\n"
6215 " disable NAME... Disable one or more unit files\n"
6216 " reenable NAME... Reenable one or more unit files\n"
6217 " preset NAME... Enable/disable one or more unit files\n"
6218 " based on preset configuration\n"
6219 " preset-all Enable/disable all unit files based on\n"
6220 " preset configuration\n"
6221 " is-enabled NAME... Check whether unit files are enabled\n"
6222 " mask NAME... Mask one or more units\n"
6223 " unmask NAME... Unmask one or more units\n"
6224 " link PATH... Link one or more units files into\n"
6225 " the search path\n"
6226 " add-wants TARGET NAME... Add 'Wants' dependency for the target\n"
6227 " on specified one or more units\n"
6228 " add-requires TARGET NAME... Add 'Requires' dependency for the target\n"
6229 " on specified one or more units\n"
6230 " edit NAME... Edit one or more unit files\n"
6231 " get-default Get the name of the default target\n"
6232 " set-default NAME Set the default target\n\n"
6233 "Machine Commands:\n"
6234 " list-machines [PATTERN...] List local containers and host\n\n"
6235 "Job Commands:\n"
6236 " list-jobs [PATTERN...] List jobs\n"
6237 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
6238 "Snapshot Commands:\n"
6239 " snapshot [NAME] Create a snapshot\n"
6240 " delete NAME... Remove one or more snapshots\n\n"
6241 "Environment Commands:\n"
6242 " show-environment Dump environment\n"
6243 " set-environment NAME=VALUE... Set one or more environment variables\n"
6244 " unset-environment NAME... Unset one or more environment variables\n"
6245 " import-environment [NAME...] Import all or some environment variables\n\n"
6246 "Manager Lifecycle Commands:\n"
6247 " daemon-reload Reload systemd manager configuration\n"
6248 " daemon-reexec Reexecute systemd manager\n\n"
6249 "System Commands:\n"
6250 " is-system-running Check whether system is fully running\n"
6251 " default Enter system default mode\n"
6252 " rescue Enter system rescue mode\n"
6253 " emergency Enter system emergency mode\n"
6254 " halt Shut down and halt the system\n"
6255 " poweroff Shut down and power-off the system\n"
6256 " reboot [ARG] Shut down and reboot the system\n"
6257 " kexec Shut down and reboot the system with kexec\n"
6258 " exit [EXIT_CODE] Request user instance or container exit\n"
6259 " switch-root ROOT [INIT] Change to a different root file system\n"
6260 " suspend Suspend the system\n"
6261 " hibernate Hibernate the system\n"
6262 " hybrid-sleep Hibernate and suspend the system\n",
6263 program_invocation_short_name);
6264 }
6265
6266 static void halt_help(void) {
6267 printf("%s [OPTIONS...]%s\n\n"
6268 "%s the system.\n\n"
6269 " --help Show this help\n"
6270 " --halt Halt the machine\n"
6271 " -p --poweroff Switch off the machine\n"
6272 " --reboot Reboot the machine\n"
6273 " -f --force Force immediate halt/power-off/reboot\n"
6274 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
6275 " -d --no-wtmp Don't write wtmp record\n"
6276 " --no-wall Don't send wall message before halt/power-off/reboot\n",
6277 program_invocation_short_name,
6278 arg_action == ACTION_REBOOT ? " [ARG]" : "",
6279 arg_action == ACTION_REBOOT ? "Reboot" :
6280 arg_action == ACTION_POWEROFF ? "Power off" :
6281 "Halt");
6282 }
6283
6284 static void shutdown_help(void) {
6285 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
6286 "Shut down the system.\n\n"
6287 " --help Show this help\n"
6288 " -H --halt Halt the machine\n"
6289 " -P --poweroff Power-off the machine\n"
6290 " -r --reboot Reboot the machine\n"
6291 " -h Equivalent to --poweroff, overridden by --halt\n"
6292 " -k Don't halt/power-off/reboot, just send warnings\n"
6293 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6294 " -c Cancel a pending shutdown\n",
6295 program_invocation_short_name);
6296 }
6297
6298 static void telinit_help(void) {
6299 printf("%s [OPTIONS...] {COMMAND}\n\n"
6300 "Send control commands to the init daemon.\n\n"
6301 " --help Show this help\n"
6302 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
6303 "Commands:\n"
6304 " 0 Power-off the machine\n"
6305 " 6 Reboot the machine\n"
6306 " 2, 3, 4, 5 Start runlevelX.target unit\n"
6307 " 1, s, S Enter rescue mode\n"
6308 " q, Q Reload init daemon configuration\n"
6309 " u, U Reexecute init daemon\n",
6310 program_invocation_short_name);
6311 }
6312
6313 static void runlevel_help(void) {
6314 printf("%s [OPTIONS...]\n\n"
6315 "Prints the previous and current runlevel of the init system.\n\n"
6316 " --help Show this help\n",
6317 program_invocation_short_name);
6318 }
6319
6320 static void help_types(void) {
6321 int i;
6322 const char *t;
6323
6324 if (!arg_no_legend)
6325 puts("Available unit types:");
6326 for (i = 0; i < _UNIT_TYPE_MAX; i++) {
6327 t = unit_type_to_string(i);
6328 if (t)
6329 puts(t);
6330 }
6331 }
6332
6333 static int systemctl_parse_argv(int argc, char *argv[]) {
6334
6335 enum {
6336 ARG_FAIL = 0x100,
6337 ARG_REVERSE,
6338 ARG_AFTER,
6339 ARG_BEFORE,
6340 ARG_SHOW_TYPES,
6341 ARG_IRREVERSIBLE,
6342 ARG_IGNORE_DEPENDENCIES,
6343 ARG_VERSION,
6344 ARG_USER,
6345 ARG_SYSTEM,
6346 ARG_GLOBAL,
6347 ARG_NO_BLOCK,
6348 ARG_NO_LEGEND,
6349 ARG_NO_PAGER,
6350 ARG_NO_WALL,
6351 ARG_ROOT,
6352 ARG_NO_RELOAD,
6353 ARG_KILL_WHO,
6354 ARG_NO_ASK_PASSWORD,
6355 ARG_FAILED,
6356 ARG_RUNTIME,
6357 ARG_FORCE,
6358 ARG_PLAIN,
6359 ARG_STATE,
6360 ARG_JOB_MODE,
6361 ARG_PRESET_MODE,
6362 ARG_FIRMWARE_SETUP,
6363 ARG_NOW,
6364 ARG_MESSAGE,
6365 };
6366
6367 static const struct option options[] = {
6368 { "help", no_argument, NULL, 'h' },
6369 { "version", no_argument, NULL, ARG_VERSION },
6370 { "type", required_argument, NULL, 't' },
6371 { "property", required_argument, NULL, 'p' },
6372 { "all", no_argument, NULL, 'a' },
6373 { "reverse", no_argument, NULL, ARG_REVERSE },
6374 { "after", no_argument, NULL, ARG_AFTER },
6375 { "before", no_argument, NULL, ARG_BEFORE },
6376 { "show-types", no_argument, NULL, ARG_SHOW_TYPES },
6377 { "failed", no_argument, NULL, ARG_FAILED }, /* compatibility only */
6378 { "full", no_argument, NULL, 'l' },
6379 { "job-mode", required_argument, NULL, ARG_JOB_MODE },
6380 { "fail", no_argument, NULL, ARG_FAIL }, /* compatibility only */
6381 { "irreversible", no_argument, NULL, ARG_IRREVERSIBLE }, /* compatibility only */
6382 { "ignore-dependencies", no_argument, NULL, ARG_IGNORE_DEPENDENCIES }, /* compatibility only */
6383 { "ignore-inhibitors", no_argument, NULL, 'i' },
6384 { "user", no_argument, NULL, ARG_USER },
6385 { "system", no_argument, NULL, ARG_SYSTEM },
6386 { "global", no_argument, NULL, ARG_GLOBAL },
6387 { "no-block", no_argument, NULL, ARG_NO_BLOCK },
6388 { "no-legend", no_argument, NULL, ARG_NO_LEGEND },
6389 { "no-pager", no_argument, NULL, ARG_NO_PAGER },
6390 { "no-wall", no_argument, NULL, ARG_NO_WALL },
6391 { "quiet", no_argument, NULL, 'q' },
6392 { "root", required_argument, NULL, ARG_ROOT },
6393 { "force", no_argument, NULL, ARG_FORCE },
6394 { "no-reload", no_argument, NULL, ARG_NO_RELOAD },
6395 { "kill-who", required_argument, NULL, ARG_KILL_WHO },
6396 { "signal", required_argument, NULL, 's' },
6397 { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD },
6398 { "host", required_argument, NULL, 'H' },
6399 { "machine", required_argument, NULL, 'M' },
6400 { "runtime", no_argument, NULL, ARG_RUNTIME },
6401 { "lines", required_argument, NULL, 'n' },
6402 { "output", required_argument, NULL, 'o' },
6403 { "plain", no_argument, NULL, ARG_PLAIN },
6404 { "state", required_argument, NULL, ARG_STATE },
6405 { "recursive", no_argument, NULL, 'r' },
6406 { "preset-mode", required_argument, NULL, ARG_PRESET_MODE },
6407 { "firmware-setup", no_argument, NULL, ARG_FIRMWARE_SETUP },
6408 { "now", no_argument, NULL, ARG_NOW },
6409 { "message", required_argument, NULL, ARG_MESSAGE },
6410 {}
6411 };
6412
6413 int c;
6414
6415 assert(argc >= 0);
6416 assert(argv);
6417
6418 /* we default to allowing interactive authorization only in systemctl (not in the legacy commands) */
6419 arg_ask_password = true;
6420
6421 while ((c = getopt_long(argc, argv, "ht:p:alqfs:H:M:n:o:ir", options, NULL)) >= 0)
6422
6423 switch (c) {
6424
6425 case 'h':
6426 systemctl_help();
6427 return 0;
6428
6429 case ARG_VERSION:
6430 return version();
6431
6432 case 't': {
6433 const char *word, *state;
6434 size_t size;
6435
6436 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
6437 _cleanup_free_ char *type;
6438
6439 type = strndup(word, size);
6440 if (!type)
6441 return -ENOMEM;
6442
6443 if (streq(type, "help")) {
6444 help_types();
6445 return 0;
6446 }
6447
6448 if (unit_type_from_string(type) >= 0) {
6449 if (strv_push(&arg_types, type))
6450 return log_oom();
6451 type = NULL;
6452 continue;
6453 }
6454
6455 /* It's much nicer to use --state= for
6456 * load states, but let's support this
6457 * in --types= too for compatibility
6458 * with old versions */
6459 if (unit_load_state_from_string(optarg) >= 0) {
6460 if (strv_push(&arg_states, type) < 0)
6461 return log_oom();
6462 type = NULL;
6463 continue;
6464 }
6465
6466 log_error("Unknown unit type or load state '%s'.", type);
6467 log_info("Use -t help to see a list of allowed values.");
6468 return -EINVAL;
6469 }
6470
6471 break;
6472 }
6473
6474 case 'p': {
6475 /* Make sure that if the empty property list
6476 was specified, we won't show any properties. */
6477 if (isempty(optarg) && !arg_properties) {
6478 arg_properties = new0(char*, 1);
6479 if (!arg_properties)
6480 return log_oom();
6481 } else {
6482 const char *word, *state;
6483 size_t size;
6484
6485 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
6486 char *prop;
6487
6488 prop = strndup(word, size);
6489 if (!prop)
6490 return log_oom();
6491
6492 if (strv_consume(&arg_properties, prop) < 0)
6493 return log_oom();
6494 }
6495 }
6496
6497 /* If the user asked for a particular
6498 * property, show it to him, even if it is
6499 * empty. */
6500 arg_all = true;
6501
6502 break;
6503 }
6504
6505 case 'a':
6506 arg_all = true;
6507 break;
6508
6509 case ARG_REVERSE:
6510 arg_dependency = DEPENDENCY_REVERSE;
6511 break;
6512
6513 case ARG_AFTER:
6514 arg_dependency = DEPENDENCY_AFTER;
6515 break;
6516
6517 case ARG_BEFORE:
6518 arg_dependency = DEPENDENCY_BEFORE;
6519 break;
6520
6521 case ARG_SHOW_TYPES:
6522 arg_show_types = true;
6523 break;
6524
6525 case ARG_JOB_MODE:
6526 arg_job_mode = optarg;
6527 break;
6528
6529 case ARG_FAIL:
6530 arg_job_mode = "fail";
6531 break;
6532
6533 case ARG_IRREVERSIBLE:
6534 arg_job_mode = "replace-irreversibly";
6535 break;
6536
6537 case ARG_IGNORE_DEPENDENCIES:
6538 arg_job_mode = "ignore-dependencies";
6539 break;
6540
6541 case ARG_USER:
6542 arg_scope = UNIT_FILE_USER;
6543 break;
6544
6545 case ARG_SYSTEM:
6546 arg_scope = UNIT_FILE_SYSTEM;
6547 break;
6548
6549 case ARG_GLOBAL:
6550 arg_scope = UNIT_FILE_GLOBAL;
6551 break;
6552
6553 case ARG_NO_BLOCK:
6554 arg_no_block = true;
6555 break;
6556
6557 case ARG_NO_LEGEND:
6558 arg_no_legend = true;
6559 break;
6560
6561 case ARG_NO_PAGER:
6562 arg_no_pager = true;
6563 break;
6564
6565 case ARG_NO_WALL:
6566 arg_no_wall = true;
6567 break;
6568
6569 case ARG_ROOT:
6570 arg_root = optarg;
6571 break;
6572
6573 case 'l':
6574 arg_full = true;
6575 break;
6576
6577 case ARG_FAILED:
6578 if (strv_extend(&arg_states, "failed") < 0)
6579 return log_oom();
6580
6581 break;
6582
6583 case 'q':
6584 arg_quiet = true;
6585 break;
6586
6587 case ARG_FORCE:
6588 arg_force ++;
6589 break;
6590
6591 case 'f':
6592 arg_force ++;
6593 break;
6594
6595 case ARG_NO_RELOAD:
6596 arg_no_reload = true;
6597 break;
6598
6599 case ARG_KILL_WHO:
6600 arg_kill_who = optarg;
6601 break;
6602
6603 case 's':
6604 if ((arg_signal = signal_from_string_try_harder(optarg)) < 0) {
6605 log_error("Failed to parse signal string %s.", optarg);
6606 return -EINVAL;
6607 }
6608 break;
6609
6610 case ARG_NO_ASK_PASSWORD:
6611 arg_ask_password = false;
6612 break;
6613
6614 case 'H':
6615 arg_transport = BUS_TRANSPORT_REMOTE;
6616 arg_host = optarg;
6617 break;
6618
6619 case 'M':
6620 arg_transport = BUS_TRANSPORT_MACHINE;
6621 arg_host = optarg;
6622 break;
6623
6624 case ARG_RUNTIME:
6625 arg_runtime = true;
6626 break;
6627
6628 case 'n':
6629 if (safe_atou(optarg, &arg_lines) < 0) {
6630 log_error("Failed to parse lines '%s'", optarg);
6631 return -EINVAL;
6632 }
6633 break;
6634
6635 case 'o':
6636 arg_output = output_mode_from_string(optarg);
6637 if (arg_output < 0) {
6638 log_error("Unknown output '%s'.", optarg);
6639 return -EINVAL;
6640 }
6641 break;
6642
6643 case 'i':
6644 arg_ignore_inhibitors = true;
6645 break;
6646
6647 case ARG_PLAIN:
6648 arg_plain = true;
6649 break;
6650
6651 case ARG_FIRMWARE_SETUP:
6652 arg_firmware_setup = true;
6653 break;
6654
6655 case ARG_STATE: {
6656 const char *word, *state;
6657 size_t size;
6658
6659 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
6660 char *s;
6661
6662 s = strndup(word, size);
6663 if (!s)
6664 return log_oom();
6665
6666 if (strv_consume(&arg_states, s) < 0)
6667 return log_oom();
6668 }
6669 break;
6670 }
6671
6672 case 'r':
6673 if (geteuid() != 0) {
6674 log_error("--recursive requires root privileges.");
6675 return -EPERM;
6676 }
6677
6678 arg_recursive = true;
6679 break;
6680
6681 case ARG_PRESET_MODE:
6682
6683 arg_preset_mode = unit_file_preset_mode_from_string(optarg);
6684 if (arg_preset_mode < 0) {
6685 log_error("Failed to parse preset mode: %s.", optarg);
6686 return -EINVAL;
6687 }
6688
6689 break;
6690
6691 case ARG_NOW:
6692 arg_now = true;
6693 break;
6694
6695 case ARG_MESSAGE:
6696 if (strv_extend(&arg_wall, optarg) < 0)
6697 return log_oom();
6698 break;
6699
6700 case '?':
6701 return -EINVAL;
6702
6703 default:
6704 assert_not_reached("Unhandled option");
6705 }
6706
6707 if (arg_transport != BUS_TRANSPORT_LOCAL && arg_scope != UNIT_FILE_SYSTEM) {
6708 log_error("Cannot access user instance remotely.");
6709 return -EINVAL;
6710 }
6711
6712 return 1;
6713 }
6714
6715 static int halt_parse_argv(int argc, char *argv[]) {
6716
6717 enum {
6718 ARG_HELP = 0x100,
6719 ARG_HALT,
6720 ARG_REBOOT,
6721 ARG_NO_WALL
6722 };
6723
6724 static const struct option options[] = {
6725 { "help", no_argument, NULL, ARG_HELP },
6726 { "halt", no_argument, NULL, ARG_HALT },
6727 { "poweroff", no_argument, NULL, 'p' },
6728 { "reboot", no_argument, NULL, ARG_REBOOT },
6729 { "force", no_argument, NULL, 'f' },
6730 { "wtmp-only", no_argument, NULL, 'w' },
6731 { "no-wtmp", no_argument, NULL, 'd' },
6732 { "no-wall", no_argument, NULL, ARG_NO_WALL },
6733 {}
6734 };
6735
6736 int c, r, runlevel;
6737
6738 assert(argc >= 0);
6739 assert(argv);
6740
6741 if (utmp_get_runlevel(&runlevel, NULL) >= 0)
6742 if (runlevel == '0' || runlevel == '6')
6743 arg_force = 2;
6744
6745 while ((c = getopt_long(argc, argv, "pfwdnih", options, NULL)) >= 0)
6746 switch (c) {
6747
6748 case ARG_HELP:
6749 halt_help();
6750 return 0;
6751
6752 case ARG_HALT:
6753 arg_action = ACTION_HALT;
6754 break;
6755
6756 case 'p':
6757 if (arg_action != ACTION_REBOOT)
6758 arg_action = ACTION_POWEROFF;
6759 break;
6760
6761 case ARG_REBOOT:
6762 arg_action = ACTION_REBOOT;
6763 break;
6764
6765 case 'f':
6766 arg_force = 2;
6767 break;
6768
6769 case 'w':
6770 arg_dry = true;
6771 break;
6772
6773 case 'd':
6774 arg_no_wtmp = true;
6775 break;
6776
6777 case ARG_NO_WALL:
6778 arg_no_wall = true;
6779 break;
6780
6781 case 'i':
6782 case 'h':
6783 case 'n':
6784 /* Compatibility nops */
6785 break;
6786
6787 case '?':
6788 return -EINVAL;
6789
6790 default:
6791 assert_not_reached("Unhandled option");
6792 }
6793
6794 if (arg_action == ACTION_REBOOT && (argc == optind || argc == optind + 1)) {
6795 r = update_reboot_param_file(argc == optind + 1 ? argv[optind] : NULL);
6796 if (r < 0)
6797 return r;
6798 } else if (optind < argc) {
6799 log_error("Too many arguments.");
6800 return -EINVAL;
6801 }
6802
6803 return 1;
6804 }
6805
6806 static int parse_time_spec(const char *t, usec_t *_u) {
6807 assert(t);
6808 assert(_u);
6809
6810 if (streq(t, "now"))
6811 *_u = 0;
6812 else if (!strchr(t, ':')) {
6813 uint64_t u;
6814
6815 if (safe_atou64(t, &u) < 0)
6816 return -EINVAL;
6817
6818 *_u = now(CLOCK_REALTIME) + USEC_PER_MINUTE * u;
6819 } else {
6820 char *e = NULL;
6821 long hour, minute;
6822 struct tm tm = {};
6823 time_t s;
6824 usec_t n;
6825
6826 errno = 0;
6827 hour = strtol(t, &e, 10);
6828 if (errno > 0 || *e != ':' || hour < 0 || hour > 23)
6829 return -EINVAL;
6830
6831 minute = strtol(e+1, &e, 10);
6832 if (errno > 0 || *e != 0 || minute < 0 || minute > 59)
6833 return -EINVAL;
6834
6835 n = now(CLOCK_REALTIME);
6836 s = (time_t) (n / USEC_PER_SEC);
6837
6838 assert_se(localtime_r(&s, &tm));
6839
6840 tm.tm_hour = (int) hour;
6841 tm.tm_min = (int) minute;
6842 tm.tm_sec = 0;
6843
6844 assert_se(s = mktime(&tm));
6845
6846 *_u = (usec_t) s * USEC_PER_SEC;
6847
6848 while (*_u <= n)
6849 *_u += USEC_PER_DAY;
6850 }
6851
6852 return 0;
6853 }
6854
6855 static int shutdown_parse_argv(int argc, char *argv[]) {
6856
6857 enum {
6858 ARG_HELP = 0x100,
6859 ARG_NO_WALL
6860 };
6861
6862 static const struct option options[] = {
6863 { "help", no_argument, NULL, ARG_HELP },
6864 { "halt", no_argument, NULL, 'H' },
6865 { "poweroff", no_argument, NULL, 'P' },
6866 { "reboot", no_argument, NULL, 'r' },
6867 { "kexec", no_argument, NULL, 'K' }, /* not documented extension */
6868 { "no-wall", no_argument, NULL, ARG_NO_WALL },
6869 {}
6870 };
6871
6872 int c, r;
6873
6874 assert(argc >= 0);
6875 assert(argv);
6876
6877 while ((c = getopt_long(argc, argv, "HPrhkKt:afFc", options, NULL)) >= 0)
6878 switch (c) {
6879
6880 case ARG_HELP:
6881 shutdown_help();
6882 return 0;
6883
6884 case 'H':
6885 arg_action = ACTION_HALT;
6886 break;
6887
6888 case 'P':
6889 arg_action = ACTION_POWEROFF;
6890 break;
6891
6892 case 'r':
6893 if (kexec_loaded())
6894 arg_action = ACTION_KEXEC;
6895 else
6896 arg_action = ACTION_REBOOT;
6897 break;
6898
6899 case 'K':
6900 arg_action = ACTION_KEXEC;
6901 break;
6902
6903 case 'h':
6904 if (arg_action != ACTION_HALT)
6905 arg_action = ACTION_POWEROFF;
6906 break;
6907
6908 case 'k':
6909 arg_dry = true;
6910 break;
6911
6912 case ARG_NO_WALL:
6913 arg_no_wall = true;
6914 break;
6915
6916 case 't':
6917 case 'a':
6918 case 'f':
6919 case 'F':
6920 /* Compatibility nops */
6921 break;
6922
6923 case 'c':
6924 arg_action = ACTION_CANCEL_SHUTDOWN;
6925 break;
6926
6927 case '?':
6928 return -EINVAL;
6929
6930 default:
6931 assert_not_reached("Unhandled option");
6932 }
6933
6934 if (argc > optind && arg_action != ACTION_CANCEL_SHUTDOWN) {
6935 r = parse_time_spec(argv[optind], &arg_when);
6936 if (r < 0) {
6937 log_error("Failed to parse time specification: %s", argv[optind]);
6938 return r;
6939 }
6940 } else
6941 arg_when = now(CLOCK_REALTIME) + USEC_PER_MINUTE;
6942
6943 if (argc > optind && arg_action == ACTION_CANCEL_SHUTDOWN)
6944 /* No time argument for shutdown cancel */
6945 arg_wall = argv + optind;
6946 else if (argc > optind + 1)
6947 /* We skip the time argument */
6948 arg_wall = argv + optind + 1;
6949
6950 optind = argc;
6951
6952 return 1;
6953 }
6954
6955 static int telinit_parse_argv(int argc, char *argv[]) {
6956
6957 enum {
6958 ARG_HELP = 0x100,
6959 ARG_NO_WALL
6960 };
6961
6962 static const struct option options[] = {
6963 { "help", no_argument, NULL, ARG_HELP },
6964 { "no-wall", no_argument, NULL, ARG_NO_WALL },
6965 {}
6966 };
6967
6968 static const struct {
6969 char from;
6970 enum action to;
6971 } table[] = {
6972 { '0', ACTION_POWEROFF },
6973 { '6', ACTION_REBOOT },
6974 { '1', ACTION_RESCUE },
6975 { '2', ACTION_RUNLEVEL2 },
6976 { '3', ACTION_RUNLEVEL3 },
6977 { '4', ACTION_RUNLEVEL4 },
6978 { '5', ACTION_RUNLEVEL5 },
6979 { 's', ACTION_RESCUE },
6980 { 'S', ACTION_RESCUE },
6981 { 'q', ACTION_RELOAD },
6982 { 'Q', ACTION_RELOAD },
6983 { 'u', ACTION_REEXEC },
6984 { 'U', ACTION_REEXEC }
6985 };
6986
6987 unsigned i;
6988 int c;
6989
6990 assert(argc >= 0);
6991 assert(argv);
6992
6993 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0)
6994 switch (c) {
6995
6996 case ARG_HELP:
6997 telinit_help();
6998 return 0;
6999
7000 case ARG_NO_WALL:
7001 arg_no_wall = true;
7002 break;
7003
7004 case '?':
7005 return -EINVAL;
7006
7007 default:
7008 assert_not_reached("Unhandled option");
7009 }
7010
7011 if (optind >= argc) {
7012 log_error("%s: required argument missing.",
7013 program_invocation_short_name);
7014 return -EINVAL;
7015 }
7016
7017 if (optind + 1 < argc) {
7018 log_error("Too many arguments.");
7019 return -EINVAL;
7020 }
7021
7022 if (strlen(argv[optind]) != 1) {
7023 log_error("Expected single character argument.");
7024 return -EINVAL;
7025 }
7026
7027 for (i = 0; i < ELEMENTSOF(table); i++)
7028 if (table[i].from == argv[optind][0])
7029 break;
7030
7031 if (i >= ELEMENTSOF(table)) {
7032 log_error("Unknown command '%s'.", argv[optind]);
7033 return -EINVAL;
7034 }
7035
7036 arg_action = table[i].to;
7037
7038 optind ++;
7039
7040 return 1;
7041 }
7042
7043 static int runlevel_parse_argv(int argc, char *argv[]) {
7044
7045 enum {
7046 ARG_HELP = 0x100,
7047 };
7048
7049 static const struct option options[] = {
7050 { "help", no_argument, NULL, ARG_HELP },
7051 {}
7052 };
7053
7054 int c;
7055
7056 assert(argc >= 0);
7057 assert(argv);
7058
7059 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0)
7060 switch (c) {
7061
7062 case ARG_HELP:
7063 runlevel_help();
7064 return 0;
7065
7066 case '?':
7067 return -EINVAL;
7068
7069 default:
7070 assert_not_reached("Unhandled option");
7071 }
7072
7073 if (optind < argc) {
7074 log_error("Too many arguments.");
7075 return -EINVAL;
7076 }
7077
7078 return 1;
7079 }
7080
7081 static int parse_argv(int argc, char *argv[]) {
7082 assert(argc >= 0);
7083 assert(argv);
7084
7085 if (program_invocation_short_name) {
7086
7087 if (strstr(program_invocation_short_name, "halt")) {
7088 arg_action = ACTION_HALT;
7089 return halt_parse_argv(argc, argv);
7090 } else if (strstr(program_invocation_short_name, "poweroff")) {
7091 arg_action = ACTION_POWEROFF;
7092 return halt_parse_argv(argc, argv);
7093 } else if (strstr(program_invocation_short_name, "reboot")) {
7094 if (kexec_loaded())
7095 arg_action = ACTION_KEXEC;
7096 else
7097 arg_action = ACTION_REBOOT;
7098 return halt_parse_argv(argc, argv);
7099 } else if (strstr(program_invocation_short_name, "shutdown")) {
7100 arg_action = ACTION_POWEROFF;
7101 return shutdown_parse_argv(argc, argv);
7102 } else if (strstr(program_invocation_short_name, "init")) {
7103
7104 if (sd_booted() > 0) {
7105 arg_action = _ACTION_INVALID;
7106 return telinit_parse_argv(argc, argv);
7107 } else {
7108 /* Hmm, so some other init system is
7109 * running, we need to forward this
7110 * request to it. For now we simply
7111 * guess that it is Upstart. */
7112
7113 execv(TELINIT, argv);
7114
7115 log_error("Couldn't find an alternative telinit implementation to spawn.");
7116 return -EIO;
7117 }
7118
7119 } else if (strstr(program_invocation_short_name, "runlevel")) {
7120 arg_action = ACTION_RUNLEVEL;
7121 return runlevel_parse_argv(argc, argv);
7122 }
7123 }
7124
7125 arg_action = ACTION_SYSTEMCTL;
7126 return systemctl_parse_argv(argc, argv);
7127 }
7128
7129 _pure_ static int action_to_runlevel(void) {
7130
7131 static const char table[_ACTION_MAX] = {
7132 [ACTION_HALT] = '0',
7133 [ACTION_POWEROFF] = '0',
7134 [ACTION_REBOOT] = '6',
7135 [ACTION_RUNLEVEL2] = '2',
7136 [ACTION_RUNLEVEL3] = '3',
7137 [ACTION_RUNLEVEL4] = '4',
7138 [ACTION_RUNLEVEL5] = '5',
7139 [ACTION_RESCUE] = '1'
7140 };
7141
7142 assert(arg_action < _ACTION_MAX);
7143
7144 return table[arg_action];
7145 }
7146
7147 static int talk_initctl(void) {
7148
7149 struct init_request request = {
7150 .magic = INIT_MAGIC,
7151 .sleeptime = 0,
7152 .cmd = INIT_CMD_RUNLVL
7153 };
7154
7155 _cleanup_close_ int fd = -1;
7156 char rl;
7157 int r;
7158
7159 rl = action_to_runlevel();
7160 if (!rl)
7161 return 0;
7162
7163 request.runlevel = rl;
7164
7165 fd = open(INIT_FIFO, O_WRONLY|O_NDELAY|O_CLOEXEC|O_NOCTTY);
7166 if (fd < 0) {
7167 if (errno == ENOENT)
7168 return 0;
7169
7170 log_error_errno(errno, "Failed to open "INIT_FIFO": %m");
7171 return -errno;
7172 }
7173
7174 r = loop_write(fd, &request, sizeof(request), false);
7175 if (r < 0)
7176 return log_error_errno(r, "Failed to write to "INIT_FIFO": %m");
7177
7178 return 1;
7179 }
7180
7181 static int systemctl_main(sd_bus *bus, int argc, char *argv[], int bus_error) {
7182
7183 static const struct {
7184 const char* verb;
7185 const enum {
7186 MORE,
7187 LESS,
7188 EQUAL
7189 } argc_cmp;
7190 const int argc;
7191 int (* const dispatch)(sd_bus *bus, char **args);
7192 const enum {
7193 NOBUS = 1,
7194 FORCE,
7195 } bus;
7196 } verbs[] = {
7197 { "list-units", MORE, 0, list_units },
7198 { "list-unit-files", MORE, 1, list_unit_files, NOBUS },
7199 { "list-sockets", MORE, 1, list_sockets },
7200 { "list-timers", MORE, 1, list_timers },
7201 { "list-jobs", MORE, 1, list_jobs },
7202 { "list-machines", MORE, 1, list_machines },
7203 { "clear-jobs", EQUAL, 1, daemon_reload },
7204 { "cancel", MORE, 2, cancel_job },
7205 { "start", MORE, 2, start_unit },
7206 { "stop", MORE, 2, start_unit },
7207 { "condstop", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
7208 { "reload", MORE, 2, start_unit },
7209 { "restart", MORE, 2, start_unit },
7210 { "try-restart", MORE, 2, start_unit },
7211 { "reload-or-restart", MORE, 2, start_unit },
7212 { "reload-or-try-restart", MORE, 2, start_unit },
7213 { "force-reload", MORE, 2, start_unit }, /* For compatibility with SysV */
7214 { "condreload", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
7215 { "condrestart", MORE, 2, start_unit }, /* For compatibility with RH */
7216 { "isolate", EQUAL, 2, start_unit },
7217 { "kill", MORE, 2, kill_unit },
7218 { "is-active", MORE, 2, check_unit_active },
7219 { "check", MORE, 2, check_unit_active },
7220 { "is-failed", MORE, 2, check_unit_failed },
7221 { "show", MORE, 1, show },
7222 { "cat", MORE, 2, cat, NOBUS },
7223 { "status", MORE, 1, show },
7224 { "help", MORE, 2, show },
7225 { "snapshot", LESS, 2, snapshot },
7226 { "delete", MORE, 2, delete_snapshot },
7227 { "daemon-reload", EQUAL, 1, daemon_reload },
7228 { "daemon-reexec", EQUAL, 1, daemon_reload },
7229 { "show-environment", EQUAL, 1, show_environment },
7230 { "set-environment", MORE, 2, set_environment },
7231 { "unset-environment", MORE, 2, set_environment },
7232 { "import-environment", MORE, 1, import_environment},
7233 { "halt", EQUAL, 1, start_special, FORCE },
7234 { "poweroff", EQUAL, 1, start_special, FORCE },
7235 { "reboot", MORE, 1, start_special, FORCE },
7236 { "kexec", EQUAL, 1, start_special },
7237 { "suspend", EQUAL, 1, start_special },
7238 { "hibernate", EQUAL, 1, start_special },
7239 { "hybrid-sleep", EQUAL, 1, start_special },
7240 { "default", EQUAL, 1, start_special },
7241 { "rescue", EQUAL, 1, start_special },
7242 { "emergency", EQUAL, 1, start_special },
7243 { "exit", LESS, 2, start_special },
7244 { "reset-failed", MORE, 1, reset_failed },
7245 { "enable", MORE, 2, enable_unit, NOBUS },
7246 { "disable", MORE, 2, enable_unit, NOBUS },
7247 { "is-enabled", MORE, 2, unit_is_enabled, NOBUS },
7248 { "reenable", MORE, 2, enable_unit, NOBUS },
7249 { "preset", MORE, 2, enable_unit, NOBUS },
7250 { "preset-all", EQUAL, 1, preset_all, NOBUS },
7251 { "mask", MORE, 2, enable_unit, NOBUS },
7252 { "unmask", MORE, 2, enable_unit, NOBUS },
7253 { "link", MORE, 2, enable_unit, NOBUS },
7254 { "switch-root", MORE, 2, switch_root },
7255 { "list-dependencies", LESS, 2, list_dependencies },
7256 { "set-default", EQUAL, 2, set_default, NOBUS },
7257 { "get-default", EQUAL, 1, get_default, NOBUS },
7258 { "set-property", MORE, 3, set_property },
7259 { "is-system-running", EQUAL, 1, is_system_running },
7260 { "add-wants", MORE, 3, add_dependency, NOBUS },
7261 { "add-requires", MORE, 3, add_dependency, NOBUS },
7262 { "edit", MORE, 2, edit, NOBUS },
7263 {}
7264 }, *verb = verbs;
7265
7266 int left;
7267
7268 assert(argc >= 0);
7269 assert(argv);
7270
7271 left = argc - optind;
7272
7273 /* Special rule: no arguments (left == 0) means "list-units" */
7274 if (left > 0) {
7275 if (streq(argv[optind], "help") && !argv[optind+1]) {
7276 log_error("This command expects one or more "
7277 "unit names. Did you mean --help?");
7278 return -EINVAL;
7279 }
7280
7281 for (; verb->verb; verb++)
7282 if (streq(argv[optind], verb->verb))
7283 goto found;
7284
7285 log_error("Unknown operation '%s'.", argv[optind]);
7286 return -EINVAL;
7287 }
7288 found:
7289
7290 switch (verb->argc_cmp) {
7291
7292 case EQUAL:
7293 if (left != verb->argc) {
7294 log_error("Invalid number of arguments.");
7295 return -EINVAL;
7296 }
7297
7298 break;
7299
7300 case MORE:
7301 if (left < verb->argc) {
7302 log_error("Too few arguments.");
7303 return -EINVAL;
7304 }
7305
7306 break;
7307
7308 case LESS:
7309 if (left > verb->argc) {
7310 log_error("Too many arguments.");
7311 return -EINVAL;
7312 }
7313
7314 break;
7315
7316 default:
7317 assert_not_reached("Unknown comparison operator.");
7318 }
7319
7320 /* Require a bus connection for all operations but
7321 * enable/disable */
7322 if (verb->bus == NOBUS) {
7323 if (!bus && !avoid_bus()) {
7324 log_error_errno(bus_error, "Failed to get D-Bus connection: %m");
7325 return -EIO;
7326 }
7327
7328 } else {
7329 if (running_in_chroot() > 0) {
7330 log_info("Running in chroot, ignoring request.");
7331 return 0;
7332 }
7333
7334 if ((verb->bus != FORCE || arg_force <= 0) && !bus) {
7335 log_error_errno(bus_error, "Failed to get D-Bus connection: %m");
7336 return -EIO;
7337 }
7338 }
7339
7340 return verb->dispatch(bus, argv + optind);
7341 }
7342
7343 static int reload_with_fallback(sd_bus *bus) {
7344
7345 if (bus) {
7346 /* First, try systemd via D-Bus. */
7347 if (daemon_reload(bus, NULL) >= 0)
7348 return 0;
7349 }
7350
7351 /* Nothing else worked, so let's try signals */
7352 assert(arg_action == ACTION_RELOAD || arg_action == ACTION_REEXEC);
7353
7354 if (kill(1, arg_action == ACTION_RELOAD ? SIGHUP : SIGTERM) < 0)
7355 return log_error_errno(errno, "kill() failed: %m");
7356
7357 return 0;
7358 }
7359
7360 static int start_with_fallback(sd_bus *bus) {
7361
7362 if (bus) {
7363 /* First, try systemd via D-Bus. */
7364 if (start_unit(bus, NULL) >= 0)
7365 goto done;
7366 }
7367
7368 /* Nothing else worked, so let's try
7369 * /dev/initctl */
7370 if (talk_initctl() > 0)
7371 goto done;
7372
7373 log_error("Failed to talk to init daemon.");
7374 return -EIO;
7375
7376 done:
7377 warn_wall(arg_action);
7378 return 0;
7379 }
7380
7381 static int halt_now(enum action a) {
7382
7383 /* The kernel will automaticall flush ATA disks and suchlike
7384 * on reboot(), but the file systems need to be synce'd
7385 * explicitly in advance. */
7386 sync();
7387
7388 /* Make sure C-A-D is handled by the kernel from this point
7389 * on... */
7390 reboot(RB_ENABLE_CAD);
7391
7392 switch (a) {
7393
7394 case ACTION_HALT:
7395 log_info("Halting.");
7396 reboot(RB_HALT_SYSTEM);
7397 return -errno;
7398
7399 case ACTION_POWEROFF:
7400 log_info("Powering off.");
7401 reboot(RB_POWER_OFF);
7402 return -errno;
7403
7404 case ACTION_KEXEC:
7405 case ACTION_REBOOT: {
7406 _cleanup_free_ char *param = NULL;
7407
7408 if (read_one_line_file(REBOOT_PARAM_FILE, &param) >= 0) {
7409 log_info("Rebooting with argument '%s'.", param);
7410 syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
7411 LINUX_REBOOT_CMD_RESTART2, param);
7412 }
7413
7414 log_info("Rebooting.");
7415 reboot(RB_AUTOBOOT);
7416 return -errno;
7417 }
7418
7419 default:
7420 assert_not_reached("Unknown action.");
7421 }
7422 }
7423
7424 static int halt_main(sd_bus *bus) {
7425 int r;
7426
7427 r = check_inhibitors(bus, arg_action);
7428 if (r < 0)
7429 return r;
7430
7431 if (geteuid() != 0) {
7432 if (arg_when > 0 ||
7433 arg_dry ||
7434 arg_force > 0) {
7435 log_error("Must be root.");
7436 return -EPERM;
7437 }
7438
7439 /* Try logind if we are a normal user and no special
7440 * mode applies. Maybe PolicyKit allows us to shutdown
7441 * the machine. */
7442 if (IN_SET(arg_action,
7443 ACTION_POWEROFF,
7444 ACTION_REBOOT)) {
7445 r = reboot_with_logind(bus, arg_action);
7446 if (r >= 0)
7447 return r;
7448 if (IN_SET(r, -EOPNOTSUPP, -EINPROGRESS))
7449 /* requested operation is not supported or already in progress */
7450 return r;
7451 /* on all other errors, try low-level operation */
7452 }
7453 }
7454
7455 if (arg_when > 0) {
7456 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
7457 _cleanup_bus_flush_close_unref_ sd_bus *b = NULL;
7458 _cleanup_free_ char *m = NULL;
7459 const char *action;
7460
7461 assert(geteuid() == 0);
7462
7463 if (avoid_bus()) {
7464 log_error("Unable to perform operation without bus connection.");
7465 return -ENOSYS;
7466 }
7467
7468 r = sd_bus_open_system(&b);
7469 if (r < 0)
7470 return log_error_errno(r, "Unable to open system bus: %m");
7471
7472 m = strv_join(arg_wall, " ");
7473 if (!m)
7474 return log_oom();
7475
7476 r = sd_bus_call_method(
7477 b,
7478 "org.freedesktop.login1",
7479 "/org/freedesktop/login1",
7480 "org.freedesktop.login1.Manager",
7481 "SetWallMessage",
7482 &error,
7483 NULL,
7484 "sb",
7485 m,
7486 !arg_no_wall);
7487
7488 if (r < 0) {
7489 log_warning_errno(r, "Failed to set wall message, ignoring: %s",
7490 bus_error_message(&error, r));
7491 sd_bus_error_free(&error);
7492 }
7493
7494 switch (arg_action) {
7495 case ACTION_HALT:
7496 action = "halt";
7497 break;
7498 case ACTION_POWEROFF:
7499 action = "poweroff";
7500 break;
7501 case ACTION_KEXEC:
7502 action = "kexec";
7503 break;
7504 default:
7505 action = "reboot";
7506 break;
7507 }
7508
7509 if (arg_dry)
7510 action = strjoina("dry-", action);
7511
7512 r = sd_bus_call_method(
7513 b,
7514 "org.freedesktop.login1",
7515 "/org/freedesktop/login1",
7516 "org.freedesktop.login1.Manager",
7517 "ScheduleShutdown",
7518 &error,
7519 NULL,
7520 "st",
7521 action,
7522 arg_when);
7523 if (r < 0)
7524 log_warning_errno(r, "Failed to call ScheduleShutdown in logind, proceeding with immediate shutdown: %s",
7525 bus_error_message(&error, r));
7526 else {
7527 char date[FORMAT_TIMESTAMP_MAX];
7528
7529 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.",
7530 format_timestamp(date, sizeof(date), arg_when));
7531 return 0;
7532 }
7533 }
7534
7535 if (!arg_dry && !arg_force)
7536 return start_with_fallback(bus);
7537
7538 assert(geteuid() == 0);
7539
7540 if (!arg_no_wtmp) {
7541 if (sd_booted() > 0)
7542 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
7543 else {
7544 r = utmp_put_shutdown();
7545 if (r < 0)
7546 log_warning_errno(r, "Failed to write utmp record: %m");
7547 }
7548 }
7549
7550 if (arg_dry)
7551 return 0;
7552
7553 r = halt_now(arg_action);
7554 log_error_errno(r, "Failed to reboot: %m");
7555
7556 return r;
7557 }
7558
7559 static int runlevel_main(void) {
7560 int r, runlevel, previous;
7561
7562 r = utmp_get_runlevel(&runlevel, &previous);
7563 if (r < 0) {
7564 puts("unknown");
7565 return r;
7566 }
7567
7568 printf("%c %c\n",
7569 previous <= 0 ? 'N' : previous,
7570 runlevel <= 0 ? 'N' : runlevel);
7571
7572 return 0;
7573 }
7574
7575 int main(int argc, char*argv[]) {
7576 _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL;
7577 int r;
7578
7579 setlocale(LC_ALL, "");
7580 log_parse_environment();
7581 log_open();
7582
7583 /* Explicitly not on_tty() to avoid setting cached value.
7584 * This becomes relevant for piping output which might be
7585 * ellipsized. */
7586 original_stdout_is_tty = isatty(STDOUT_FILENO);
7587
7588 r = parse_argv(argc, argv);
7589 if (r <= 0)
7590 goto finish;
7591
7592 /* /sbin/runlevel doesn't need to communicate via D-Bus, so
7593 * let's shortcut this */
7594 if (arg_action == ACTION_RUNLEVEL) {
7595 r = runlevel_main();
7596 goto finish;
7597 }
7598
7599 if (running_in_chroot() > 0 && arg_action != ACTION_SYSTEMCTL) {
7600 log_info("Running in chroot, ignoring request.");
7601 r = 0;
7602 goto finish;
7603 }
7604
7605 if (!avoid_bus())
7606 r = bus_open_transport_systemd(arg_transport, arg_host, arg_scope != UNIT_FILE_SYSTEM, &bus);
7607
7608 if (bus)
7609 sd_bus_set_allow_interactive_authorization(bus, arg_ask_password);
7610
7611 /* systemctl_main() will print an error message for the bus
7612 * connection, but only if it needs to */
7613
7614 switch (arg_action) {
7615
7616 case ACTION_SYSTEMCTL:
7617 r = systemctl_main(bus, argc, argv, r);
7618 break;
7619
7620 case ACTION_HALT:
7621 case ACTION_POWEROFF:
7622 case ACTION_REBOOT:
7623 case ACTION_KEXEC:
7624 r = halt_main(bus);
7625 break;
7626
7627 case ACTION_RUNLEVEL2:
7628 case ACTION_RUNLEVEL3:
7629 case ACTION_RUNLEVEL4:
7630 case ACTION_RUNLEVEL5:
7631 case ACTION_RESCUE:
7632 case ACTION_EMERGENCY:
7633 case ACTION_DEFAULT:
7634 r = start_with_fallback(bus);
7635 break;
7636
7637 case ACTION_RELOAD:
7638 case ACTION_REEXEC:
7639 r = reload_with_fallback(bus);
7640 break;
7641
7642 case ACTION_CANCEL_SHUTDOWN: {
7643 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
7644 _cleanup_bus_flush_close_unref_ sd_bus *b = NULL;
7645 _cleanup_free_ char *m = NULL;
7646
7647 if (avoid_bus()) {
7648 log_error("Unable to perform operation without bus connection.");
7649 return -ENOSYS;
7650 }
7651
7652 r = sd_bus_open_system(&b);
7653 if (r < 0)
7654 return log_error_errno(r, "Unable to open system bus: %m");
7655
7656 if (arg_wall) {
7657 m = strv_join(arg_wall, " ");
7658 if (!m) {
7659 r = log_oom();
7660 goto finish;
7661 }
7662 }
7663
7664 r = sd_bus_call_method(
7665 b,
7666 "org.freedesktop.login1",
7667 "/org/freedesktop/login1",
7668 "org.freedesktop.login1.Manager",
7669 "SetWallMessage",
7670 &error,
7671 NULL,
7672 "sb",
7673 m,
7674 !arg_no_wall);
7675
7676 if (r < 0) {
7677 log_warning_errno(r, "Failed to set wall message, ignoring: %s",
7678 bus_error_message(&error, r));
7679 sd_bus_error_free(&error);
7680 }
7681
7682 r = sd_bus_call_method(
7683 b,
7684 "org.freedesktop.login1",
7685 "/org/freedesktop/login1",
7686 "org.freedesktop.login1.Manager",
7687 "CancelScheduledShutdown",
7688 &error,
7689 NULL, NULL);
7690 if (r < 0)
7691 log_warning_errno(r, "Failed to talk to logind, shutdown hasn't been cancelled: %s",
7692 bus_error_message(&error, r));
7693 break;
7694 }
7695
7696 case ACTION_RUNLEVEL:
7697 case _ACTION_INVALID:
7698 default:
7699 assert_not_reached("Unknown action");
7700 }
7701
7702 finish:
7703 pager_close();
7704 ask_password_agent_close();
7705 polkit_agent_close();
7706
7707 strv_free(arg_types);
7708 strv_free(arg_states);
7709 strv_free(arg_properties);
7710
7711 sd_bus_default_flush_close();
7712
7713 return r < 0 ? EXIT_FAILURE : r;
7714 }