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