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