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