chiark / gitweb /
loginctl: show the 10 most recent log user/session log lines in "loginctl user-status...
[elogind.git] / src / systemctl / systemctl.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright 2010 Lennart Poettering
7   Copyright 2013 Marc-Antoine Perennou
8
9   systemd is free software; you can redistribute it and/or modify it
10   under the terms of the GNU Lesser General Public License as published by
11   the Free Software Foundation; either version 2.1 of the License, or
12   (at your option) any later version.
13
14   systemd is distributed in the hope that it will be useful, but
15   WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17   Lesser General Public License for more details.
18
19   You should have received a copy of the GNU Lesser General Public License
20   along with systemd; If not, see <http://www.gnu.org/licenses/>.
21 ***/
22
23 #include <sys/reboot.h>
24 #include <linux/reboot.h>
25 #include <sys/syscall.h>
26 #include <stdio.h>
27 #include <getopt.h>
28 #include <locale.h>
29 #include <stdbool.h>
30 #include <string.h>
31 #include <errno.h>
32 #include <sys/ioctl.h>
33 #include <termios.h>
34 #include <unistd.h>
35 #include <fcntl.h>
36 #include <sys/socket.h>
37 #include <sys/stat.h>
38 #include <stddef.h>
39 #include <sys/prctl.h>
40 #include <fnmatch.h>
41
42 #include "sd-daemon.h"
43 #include "sd-shutdown.h"
44 #include "sd-login.h"
45 #include "sd-bus.h"
46 #include "log.h"
47 #include "util.h"
48 #include "macro.h"
49 #include "set.h"
50 #include "utmp-wtmp.h"
51 #include "special.h"
52 #include "initreq.h"
53 #include "path-util.h"
54 #include "strv.h"
55 #include "cgroup-show.h"
56 #include "cgroup-util.h"
57 #include "list.h"
58 #include "path-lookup.h"
59 #include "conf-parser.h"
60 #include "exit-status.h"
61 #include "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 "copy.h"
71 #include "env-util.h"
72 #include "bus-util.h"
73 #include "bus-message.h"
74 #include "bus-error.h"
75 #include "bus-common-errors.h"
76 #include "mkdir.h"
77 #include "dropin.h"
78
79 static char **arg_types = NULL;
80 static char **arg_states = NULL;
81 static char **arg_properties = NULL;
82 static bool arg_all = false;
83 static enum dependency {
84         DEPENDENCY_FORWARD,
85         DEPENDENCY_REVERSE,
86         DEPENDENCY_AFTER,
87         DEPENDENCY_BEFORE,
88         _DEPENDENCY_MAX
89 } arg_dependency = DEPENDENCY_FORWARD;
90 static const char *arg_job_mode = "replace";
91 static UnitFileScope arg_scope = UNIT_FILE_SYSTEM;
92 static bool arg_no_block = false;
93 static bool arg_no_legend = false;
94 static bool arg_no_pager = false;
95 static bool arg_no_wtmp = false;
96 static bool arg_no_wall = false;
97 static bool arg_no_reload = false;
98 static bool arg_show_types = false;
99 static bool arg_ignore_inhibitors = false;
100 static bool arg_dry = false;
101 static bool arg_quiet = false;
102 static bool arg_full = false;
103 static bool arg_recursive = false;
104 static int arg_force = 0;
105 static bool arg_ask_password = true;
106 static bool arg_runtime = false;
107 static UnitFilePresetMode arg_preset_mode = UNIT_FILE_PRESET_FULL;
108 static char **arg_wall = NULL;
109 static const char *arg_kill_who = NULL;
110 static int arg_signal = SIGTERM;
111 static const char *arg_root = NULL;
112 static usec_t arg_when = 0;
113 static enum action {
114         _ACTION_INVALID,
115         ACTION_SYSTEMCTL,
116         ACTION_HALT,
117         ACTION_POWEROFF,
118         ACTION_REBOOT,
119         ACTION_KEXEC,
120         ACTION_EXIT,
121         ACTION_SUSPEND,
122         ACTION_HIBERNATE,
123         ACTION_HYBRID_SLEEP,
124         ACTION_RUNLEVEL2,
125         ACTION_RUNLEVEL3,
126         ACTION_RUNLEVEL4,
127         ACTION_RUNLEVEL5,
128         ACTION_RESCUE,
129         ACTION_EMERGENCY,
130         ACTION_DEFAULT,
131         ACTION_RELOAD,
132         ACTION_REEXEC,
133         ACTION_RUNLEVEL,
134         ACTION_CANCEL_SHUTDOWN,
135         _ACTION_MAX
136 } arg_action = ACTION_SYSTEMCTL;
137 static BusTransport arg_transport = BUS_TRANSPORT_LOCAL;
138 static char *arg_host = NULL;
139 static unsigned arg_lines = 10;
140 static OutputMode arg_output = OUTPUT_SHORT;
141 static bool arg_plain = false;
142
143 static bool original_stdout_is_tty;
144
145 static int daemon_reload(sd_bus *bus, char **args);
146 static int halt_now(enum action a);
147 static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet);
148
149 static char** strv_skip_first(char **strv) {
150         if (strv_length(strv) > 0)
151                 return strv + 1;
152         return NULL;
153 }
154
155 static void pager_open_if_enabled(void) {
156
157         if (arg_no_pager)
158                 return;
159
160         pager_open(false);
161 }
162
163 static void ask_password_agent_open_if_enabled(void) {
164
165         /* Open the password agent as a child process if necessary */
166
167         if (!arg_ask_password)
168                 return;
169
170         if (arg_scope != UNIT_FILE_SYSTEM)
171                 return;
172
173         if (arg_transport != BUS_TRANSPORT_LOCAL)
174                 return;
175
176         ask_password_agent_open();
177 }
178
179 #ifdef HAVE_LOGIND
180 static void polkit_agent_open_if_enabled(void) {
181
182         /* Open the polkit agent as a child process if necessary */
183
184         if (!arg_ask_password)
185                 return;
186
187         if (arg_scope != UNIT_FILE_SYSTEM)
188                 return;
189
190         if (arg_transport != BUS_TRANSPORT_LOCAL)
191                 return;
192
193         polkit_agent_open();
194 }
195 #endif
196
197 static OutputFlags get_output_flags(void) {
198         return
199                 arg_all * OUTPUT_SHOW_ALL |
200                 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
201                 on_tty() * OUTPUT_COLOR |
202                 !arg_quiet * OUTPUT_WARN_CUTOFF |
203                 arg_full * OUTPUT_FULL_WIDTH;
204 }
205
206 static int translate_bus_error_to_exit_status(int r, const sd_bus_error *error) {
207         assert(error);
208
209         if (!sd_bus_error_is_set(error))
210                 return r;
211
212         if (sd_bus_error_has_name(error, SD_BUS_ERROR_ACCESS_DENIED) ||
213             sd_bus_error_has_name(error, BUS_ERROR_ONLY_BY_DEPENDENCY) ||
214             sd_bus_error_has_name(error, BUS_ERROR_NO_ISOLATION) ||
215             sd_bus_error_has_name(error, BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE))
216                 return EXIT_NOPERMISSION;
217
218         if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT))
219                 return EXIT_NOTINSTALLED;
220
221         if (sd_bus_error_has_name(error, BUS_ERROR_JOB_TYPE_NOT_APPLICABLE) ||
222             sd_bus_error_has_name(error, SD_BUS_ERROR_NOT_SUPPORTED))
223                 return EXIT_NOTIMPLEMENTED;
224
225         if (sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED))
226                 return EXIT_NOTCONFIGURED;
227
228         if (r != 0)
229                 return r;
230
231         return EXIT_FAILURE;
232 }
233
234 static void warn_wall(enum action a) {
235         static const char *table[_ACTION_MAX] = {
236                 [ACTION_HALT]            = "The system is going down for system halt NOW!",
237                 [ACTION_REBOOT]          = "The system is going down for reboot NOW!",
238                 [ACTION_POWEROFF]        = "The system is going down for power-off NOW!",
239                 [ACTION_KEXEC]           = "The system is going down for kexec reboot NOW!",
240                 [ACTION_RESCUE]          = "The system is going down to rescue mode NOW!",
241                 [ACTION_EMERGENCY]       = "The system is going down to emergency mode NOW!",
242                 [ACTION_CANCEL_SHUTDOWN] = "The system shutdown has been cancelled NOW!"
243         };
244
245         if (arg_no_wall)
246                 return;
247
248         if (arg_wall) {
249                 _cleanup_free_ char *p;
250
251                 p = strv_join(arg_wall, " ");
252                 if (!p) {
253                         log_oom();
254                         return;
255                 }
256
257                 if (*p) {
258                         utmp_wall(p, NULL, NULL);
259                         return;
260                 }
261         }
262
263         if (!table[a])
264                 return;
265
266         utmp_wall(table[a], NULL, NULL);
267 }
268
269 static bool avoid_bus(void) {
270
271         if (running_in_chroot() > 0)
272                 return true;
273
274         if (sd_booted() <= 0)
275                 return true;
276
277         if (!isempty(arg_root))
278                 return true;
279
280         if (arg_scope == UNIT_FILE_GLOBAL)
281                 return true;
282
283         return false;
284 }
285
286 static int compare_unit_info(const void *a, const void *b) {
287         const UnitInfo *u = a, *v = b;
288         const char *d1, *d2;
289         int r;
290
291         /* First, order by machine */
292         if (!u->machine && v->machine)
293                 return -1;
294         if (u->machine && !v->machine)
295                 return 1;
296         if (u->machine && v->machine) {
297                 r = strcasecmp(u->machine, v->machine);
298                 if (r != 0)
299                         return r;
300         }
301
302         /* Second, order by unit type */
303         d1 = strrchr(u->id, '.');
304         d2 = strrchr(v->id, '.');
305         if (d1 && d2) {
306                 r = strcasecmp(d1, d2);
307                 if (r != 0)
308                         return r;
309         }
310
311         /* Third, order by name */
312         return strcasecmp(u->id, v->id);
313 }
314
315 static bool output_show_unit(const UnitInfo *u, char **patterns) {
316         if (!strv_isempty(patterns)) {
317                 char **pattern;
318
319                 STRV_FOREACH(pattern, patterns)
320                         if (fnmatch(*pattern, u->id, FNM_NOESCAPE) == 0)
321                                 goto next;
322                 return false;
323         }
324
325 next:
326         if (arg_types) {
327                 const char *dot;
328
329                 dot = strrchr(u->id, '.');
330                 if (!dot)
331                         return false;
332
333                 if (!strv_find(arg_types, dot+1))
334                         return false;
335         }
336
337         if (arg_all)
338                 return true;
339
340         if (u->job_id > 0)
341                 return true;
342
343         if (streq(u->active_state, "inactive") || u->following[0])
344                 return false;
345
346         return true;
347 }
348
349 static int output_units_list(const UnitInfo *unit_infos, unsigned c) {
350         unsigned circle_len = 0, id_len, max_id_len, load_len, active_len, sub_len, job_len, desc_len;
351         const UnitInfo *u;
352         unsigned n_shown = 0;
353         int job_count = 0;
354
355         max_id_len = strlen("UNIT");
356         load_len = strlen("LOAD");
357         active_len = strlen("ACTIVE");
358         sub_len = strlen("SUB");
359         job_len = strlen("JOB");
360         desc_len = 0;
361
362         for (u = unit_infos; u < unit_infos + c; u++) {
363                 max_id_len = MAX(max_id_len, strlen(u->id) + (u->machine ? strlen(u->machine)+1 : 0));
364                 load_len = MAX(load_len, strlen(u->load_state));
365                 active_len = MAX(active_len, strlen(u->active_state));
366                 sub_len = MAX(sub_len, strlen(u->sub_state));
367
368                 if (u->job_id != 0) {
369                         job_len = MAX(job_len, strlen(u->job_type));
370                         job_count++;
371                 }
372
373                 if (!arg_no_legend &&
374                     (streq(u->active_state, "failed") ||
375                      STR_IN_SET(u->load_state, "error", "not-found", "masked")))
376                         circle_len = 2;
377         }
378
379         if (!arg_full && original_stdout_is_tty) {
380                 unsigned basic_len;
381
382                 id_len = MIN(max_id_len, 25u);
383                 basic_len = circle_len + 5 + id_len + 5 + active_len + sub_len;
384
385                 if (job_count)
386                         basic_len += job_len + 1;
387
388                 if (basic_len < (unsigned) columns()) {
389                         unsigned extra_len, incr;
390                         extra_len = columns() - basic_len;
391
392                         /* Either UNIT already got 25, or is fully satisfied.
393                          * Grant up to 25 to DESC now. */
394                         incr = MIN(extra_len, 25u);
395                         desc_len += incr;
396                         extra_len -= incr;
397
398                         /* split the remaining space between UNIT and DESC,
399                          * but do not give UNIT more than it needs. */
400                         if (extra_len > 0) {
401                                 incr = MIN(extra_len / 2, max_id_len - id_len);
402                                 id_len += incr;
403                                 desc_len += extra_len - incr;
404                         }
405                 }
406         } else
407                 id_len = max_id_len;
408
409         for (u = unit_infos; u < unit_infos + c; u++) {
410                 _cleanup_free_ char *e = NULL, *j = NULL;
411                 const char *on_loaded = "", *off_loaded = "";
412                 const char *on_active = "", *off_active = "";
413                 const char *on_circle = "", *off_circle = "";
414                 const char *id;
415                 bool circle = false;
416
417                 if (!n_shown && !arg_no_legend) {
418
419                         if (circle_len > 0)
420                                 fputs("  ", stdout);
421
422                         printf("%-*s %-*s %-*s %-*s ",
423                                id_len, "UNIT",
424                                load_len, "LOAD",
425                                active_len, "ACTIVE",
426                                sub_len, "SUB");
427
428                         if (job_count)
429                                 printf("%-*s ", job_len, "JOB");
430
431                         if (!arg_full && arg_no_pager)
432                                 printf("%.*s\n", desc_len, "DESCRIPTION");
433                         else
434                                 printf("%s\n", "DESCRIPTION");
435                 }
436
437                 n_shown++;
438
439                 if (STR_IN_SET(u->load_state, "error", "not-found", "masked")) {
440                         on_loaded = ansi_highlight_red();
441                         on_circle = ansi_highlight_yellow();
442                         off_loaded = off_circle = ansi_highlight_off();
443                         circle = true;
444                 }
445
446                 if (streq(u->active_state, "failed")) {
447                         on_circle = on_active = ansi_highlight_red();
448                         off_circle = off_active = ansi_highlight_off();
449                         circle = true;
450                 }
451
452                 if (u->machine) {
453                         j = strjoin(u->machine, ":", u->id, NULL);
454                         if (!j)
455                                 return log_oom();
456
457                         id = j;
458                 } else
459                         id = u->id;
460
461                 if (arg_full) {
462                         e = ellipsize(id, id_len, 33);
463                         if (!e)
464                                 return log_oom();
465
466                         id = e;
467                 }
468
469                 if (circle_len > 0)
470                         printf("%s%s%s ", on_circle, circle ? draw_special_char(DRAW_BLACK_CIRCLE) : " ", off_circle);
471
472                 printf("%s%-*s%s %s%-*s%s %s%-*s %-*s%s %-*s",
473                        on_active, id_len, id, off_active,
474                        on_loaded, load_len, u->load_state, off_loaded,
475                        on_active, active_len, u->active_state,
476                        sub_len, u->sub_state, off_active,
477                        job_count ? job_len + 1 : 0, u->job_id ? u->job_type : "");
478
479                 if (desc_len > 0)
480                         printf("%.*s\n", desc_len, u->description);
481                 else
482                         printf("%s\n", u->description);
483         }
484
485         if (!arg_no_legend) {
486                 const char *on, *off;
487
488                 if (n_shown) {
489                         puts("\n"
490                              "LOAD   = Reflects whether the unit definition was properly loaded.\n"
491                              "ACTIVE = The high-level unit activation state, i.e. generalization of SUB.\n"
492                              "SUB    = The low-level unit activation state, values depend on unit type.");
493                         puts(job_count ? "JOB    = Pending job for the unit.\n" : "");
494                         on = ansi_highlight();
495                         off = ansi_highlight_off();
496                 } else {
497                         on = ansi_highlight_red();
498                         off = ansi_highlight_off();
499                 }
500
501                 if (arg_all)
502                         printf("%s%u loaded units listed.%s\n"
503                                "To show all installed unit files use 'systemctl list-unit-files'.\n",
504                                on, n_shown, off);
505                 else
506                         printf("%s%u loaded units listed.%s Pass --all to see loaded but inactive units, too.\n"
507                                "To show all installed unit files use 'systemctl list-unit-files'.\n",
508                                on, n_shown, off);
509         }
510
511         return 0;
512 }
513
514 static int get_unit_list(
515                 sd_bus *bus,
516                 const char *machine,
517                 char **patterns,
518                 UnitInfo **unit_infos,
519                 int c,
520                 sd_bus_message **_reply) {
521
522         _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
523         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
524         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
525         size_t size = c;
526         int r;
527         UnitInfo u;
528
529         assert(bus);
530         assert(unit_infos);
531         assert(_reply);
532
533         r = sd_bus_message_new_method_call(
534                         bus,
535                         &m,
536                         "org.freedesktop.systemd1",
537                         "/org/freedesktop/systemd1",
538                         "org.freedesktop.systemd1.Manager",
539                         "ListUnitsFiltered");
540
541         if (r < 0)
542                 return bus_log_create_error(r);
543
544         r = sd_bus_message_append_strv(m, arg_states);
545         if (r < 0)
546                 return bus_log_create_error(r);
547
548         r = sd_bus_call(bus, m, 0, &error, &reply);
549         if (r < 0) {
550                 log_error("Failed to list units: %s", bus_error_message(&error, r));
551                 return r;
552         }
553
554         r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssssouso)");
555         if (r < 0)
556                 return bus_log_parse_error(r);
557
558         while ((r = bus_parse_unit_info(reply, &u)) > 0) {
559                 u.machine = machine;
560
561                 if (!output_show_unit(&u, patterns))
562                         continue;
563
564                 if (!GREEDY_REALLOC(*unit_infos, size, c+1))
565                         return log_oom();
566
567                 (*unit_infos)[c++] = u;
568         }
569         if (r < 0)
570                 return bus_log_parse_error(r);
571
572         r = sd_bus_message_exit_container(reply);
573         if (r < 0)
574                 return bus_log_parse_error(r);
575
576         *_reply = reply;
577         reply = NULL;
578
579         return c;
580 }
581
582 static void message_set_freep(Set **set) {
583         sd_bus_message *m;
584
585         while ((m = set_steal_first(*set)))
586                 sd_bus_message_unref(m);
587
588         set_free(*set);
589 }
590
591 static int get_unit_list_recursive(
592                 sd_bus *bus,
593                 char **patterns,
594                 UnitInfo **_unit_infos,
595                 Set **_replies,
596                 char ***_machines) {
597
598         _cleanup_free_ UnitInfo *unit_infos = NULL;
599         _cleanup_(message_set_freep) Set *replies;
600         sd_bus_message *reply;
601         int c, r;
602
603         assert(bus);
604         assert(_replies);
605         assert(_unit_infos);
606         assert(_machines);
607
608         replies = set_new(NULL);
609         if (!replies)
610                 return log_oom();
611
612         c = get_unit_list(bus, NULL, patterns, &unit_infos, 0, &reply);
613         if (c < 0)
614                 return c;
615
616         r = set_put(replies, reply);
617         if (r < 0) {
618                 sd_bus_message_unref(reply);
619                 return r;
620         }
621
622         if (arg_recursive) {
623                 _cleanup_strv_free_ char **machines = NULL;
624                 char **i;
625
626                 r = sd_get_machine_names(&machines);
627                 if (r < 0)
628                         return r;
629
630                 STRV_FOREACH(i, machines) {
631                         _cleanup_bus_close_unref_ sd_bus *container = NULL;
632                         int k;
633
634                         r = sd_bus_open_system_machine(&container, *i);
635                         if (r < 0) {
636                                 log_error_errno(r, "Failed to connect to container %s: %m", *i);
637                                 continue;
638                         }
639
640                         k = get_unit_list(container, *i, patterns, &unit_infos, c, &reply);
641                         if (k < 0)
642                                 return k;
643
644                         c = k;
645
646                         r = set_put(replies, reply);
647                         if (r < 0) {
648                                 sd_bus_message_unref(reply);
649                                 return r;
650                         }
651                 }
652
653                 *_machines = machines;
654                 machines = NULL;
655         } else
656                 *_machines = NULL;
657
658         *_unit_infos = unit_infos;
659         unit_infos = NULL;
660
661         *_replies = replies;
662         replies = NULL;
663
664         return c;
665 }
666
667 static int list_units(sd_bus *bus, char **args) {
668         _cleanup_free_ UnitInfo *unit_infos = NULL;
669         _cleanup_(message_set_freep) Set *replies = NULL;
670         _cleanup_strv_free_ char **machines = NULL;
671         int r;
672
673         pager_open_if_enabled();
674
675         r = get_unit_list_recursive(bus, strv_skip_first(args), &unit_infos, &replies, &machines);
676         if (r < 0)
677                 return r;
678
679         qsort_safe(unit_infos, r, sizeof(UnitInfo), compare_unit_info);
680         return output_units_list(unit_infos, r);
681 }
682
683 static int get_triggered_units(
684                 sd_bus *bus,
685                 const char* path,
686                 char*** ret) {
687
688         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
689         int r;
690
691         r = sd_bus_get_property_strv(
692                         bus,
693                         "org.freedesktop.systemd1",
694                         path,
695                         "org.freedesktop.systemd1.Unit",
696                         "Triggers",
697                         &error,
698                         ret);
699
700         if (r < 0)
701                 log_error("Failed to determine triggers: %s", bus_error_message(&error, r));
702
703         return 0;
704 }
705
706 static int get_listening(
707                 sd_bus *bus,
708                 const char* unit_path,
709                 char*** listening) {
710
711         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
712         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
713         const char *type, *path;
714         int r, n = 0;
715
716         r = sd_bus_get_property(
717                         bus,
718                         "org.freedesktop.systemd1",
719                         unit_path,
720                         "org.freedesktop.systemd1.Socket",
721                         "Listen",
722                         &error,
723                         &reply,
724                         "a(ss)");
725         if (r < 0) {
726                 log_error("Failed to get list of listening sockets: %s", bus_error_message(&error, r));
727                 return r;
728         }
729
730         r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ss)");
731         if (r < 0)
732                 return bus_log_parse_error(r);
733
734         while ((r = sd_bus_message_read(reply, "(ss)", &type, &path)) > 0) {
735
736                 r = strv_extend(listening, type);
737                 if (r < 0)
738                         return log_oom();
739
740                 r = strv_extend(listening, path);
741                 if (r < 0)
742                         return log_oom();
743
744                 n++;
745         }
746         if (r < 0)
747                 return bus_log_parse_error(r);
748
749         r = sd_bus_message_exit_container(reply);
750         if (r < 0)
751                 return bus_log_parse_error(r);
752
753         return n;
754 }
755
756 struct socket_info {
757         const char *machine;
758         const char* id;
759
760         char* type;
761         char* path;
762
763         /* Note: triggered is a list here, although it almost certainly
764          * will always be one unit. Nevertheless, dbus API allows for multiple
765          * values, so let's follow that. */
766         char** triggered;
767
768         /* The strv above is shared. free is set only in the first one. */
769         bool own_triggered;
770 };
771
772 static int socket_info_compare(const struct socket_info *a, const struct socket_info *b) {
773         int o;
774
775         assert(a);
776         assert(b);
777
778         if (!a->machine && b->machine)
779                 return -1;
780         if (a->machine && !b->machine)
781                 return 1;
782         if (a->machine && b->machine) {
783                 o = strcasecmp(a->machine, b->machine);
784                 if (o != 0)
785                         return o;
786         }
787
788         o = strcmp(a->path, b->path);
789         if (o == 0)
790                 o = strcmp(a->type, b->type);
791
792         return o;
793 }
794
795 static int output_sockets_list(struct socket_info *socket_infos, unsigned cs) {
796         struct socket_info *s;
797         unsigned pathlen = strlen("LISTEN"),
798                 typelen = strlen("TYPE") * arg_show_types,
799                 socklen = strlen("UNIT"),
800                 servlen = strlen("ACTIVATES");
801         const char *on, *off;
802
803         for (s = socket_infos; s < socket_infos + cs; s++) {
804                 unsigned tmp = 0;
805                 char **a;
806
807                 socklen = MAX(socklen, strlen(s->id));
808                 if (arg_show_types)
809                         typelen = MAX(typelen, strlen(s->type));
810                 pathlen = MAX(pathlen, strlen(s->path) + (s->machine ? strlen(s->machine)+1 : 0));
811
812                 STRV_FOREACH(a, s->triggered)
813                         tmp += strlen(*a) + 2*(a != s->triggered);
814                 servlen = MAX(servlen, tmp);
815         }
816
817         if (cs) {
818                 if (!arg_no_legend)
819                         printf("%-*s %-*.*s%-*s %s\n",
820                                pathlen, "LISTEN",
821                                typelen + arg_show_types, typelen + arg_show_types, "TYPE ",
822                                socklen, "UNIT",
823                                "ACTIVATES");
824
825                 for (s = socket_infos; s < socket_infos + cs; s++) {
826                         _cleanup_free_ char *j = NULL;
827                         const char *path;
828                         char **a;
829
830                         if (s->machine) {
831                                 j = strjoin(s->machine, ":", s->path, NULL);
832                                 if (!j)
833                                         return log_oom();
834                                 path = j;
835                         } else
836                                 path = s->path;
837
838                         if (arg_show_types)
839                                 printf("%-*s %-*s %-*s",
840                                        pathlen, path, typelen, s->type, socklen, s->id);
841                         else
842                                 printf("%-*s %-*s",
843                                        pathlen, path, socklen, s->id);
844                         STRV_FOREACH(a, s->triggered)
845                                 printf("%s %s",
846                                        a == s->triggered ? "" : ",", *a);
847                         printf("\n");
848                 }
849
850                 on = ansi_highlight();
851                 off = ansi_highlight_off();
852                 if (!arg_no_legend)
853                         printf("\n");
854         } else {
855                 on = ansi_highlight_red();
856                 off = ansi_highlight_off();
857         }
858
859         if (!arg_no_legend) {
860                 printf("%s%u sockets listed.%s\n", on, cs, off);
861                 if (!arg_all)
862                         printf("Pass --all to see loaded but inactive sockets, too.\n");
863         }
864
865         return 0;
866 }
867
868 static int list_sockets(sd_bus *bus, char **args) {
869         _cleanup_(message_set_freep) Set *replies = NULL;
870         _cleanup_strv_free_ char **machines = NULL;
871         _cleanup_free_ UnitInfo *unit_infos = NULL;
872         _cleanup_free_ struct socket_info *socket_infos = NULL;
873         const UnitInfo *u;
874         struct socket_info *s;
875         unsigned cs = 0;
876         size_t size = 0;
877         int r = 0, n;
878
879         pager_open_if_enabled();
880
881         n = get_unit_list_recursive(bus, strv_skip_first(args), &unit_infos, &replies, &machines);
882         if (n < 0)
883                 return n;
884
885         for (u = unit_infos; u < unit_infos + n; u++) {
886                 _cleanup_strv_free_ char **listening = NULL, **triggered = NULL;
887                 int i, c;
888
889                 if (!endswith(u->id, ".socket"))
890                         continue;
891
892                 r = get_triggered_units(bus, u->unit_path, &triggered);
893                 if (r < 0)
894                         goto cleanup;
895
896                 c = get_listening(bus, u->unit_path, &listening);
897                 if (c < 0) {
898                         r = c;
899                         goto cleanup;
900                 }
901
902                 if (!GREEDY_REALLOC(socket_infos, size, cs + c)) {
903                         r = log_oom();
904                         goto cleanup;
905                 }
906
907                 for (i = 0; i < c; i++)
908                         socket_infos[cs + i] = (struct socket_info) {
909                                 .machine = u->machine,
910                                 .id = u->id,
911                                 .type = listening[i*2],
912                                 .path = listening[i*2 + 1],
913                                 .triggered = triggered,
914                                 .own_triggered = i==0,
915                         };
916
917                 /* from this point on we will cleanup those socket_infos */
918                 cs += c;
919                 free(listening);
920                 listening = triggered = NULL; /* avoid cleanup */
921         }
922
923         qsort_safe(socket_infos, cs, sizeof(struct socket_info),
924                    (__compar_fn_t) socket_info_compare);
925
926         output_sockets_list(socket_infos, cs);
927
928  cleanup:
929         assert(cs == 0 || socket_infos);
930         for (s = socket_infos; s < socket_infos + cs; s++) {
931                 free(s->type);
932                 free(s->path);
933                 if (s->own_triggered)
934                         strv_free(s->triggered);
935         }
936
937         return r;
938 }
939
940 static int get_next_elapse(
941                 sd_bus *bus,
942                 const char *path,
943                 dual_timestamp *next) {
944
945         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
946         dual_timestamp t;
947         int r;
948
949         assert(bus);
950         assert(path);
951         assert(next);
952
953         r = sd_bus_get_property_trivial(
954                         bus,
955                         "org.freedesktop.systemd1",
956                         path,
957                         "org.freedesktop.systemd1.Timer",
958                         "NextElapseUSecMonotonic",
959                         &error,
960                         't',
961                         &t.monotonic);
962         if (r < 0) {
963                 log_error("Failed to get next elapsation time: %s", bus_error_message(&error, r));
964                 return r;
965         }
966
967         r = sd_bus_get_property_trivial(
968                         bus,
969                         "org.freedesktop.systemd1",
970                         path,
971                         "org.freedesktop.systemd1.Timer",
972                         "NextElapseUSecRealtime",
973                         &error,
974                         't',
975                         &t.realtime);
976         if (r < 0) {
977                 log_error("Failed to get next elapsation time: %s", bus_error_message(&error, r));
978                 return r;
979         }
980
981         *next = t;
982         return 0;
983 }
984
985 static int get_last_trigger(
986                 sd_bus *bus,
987                 const char *path,
988                 usec_t *last) {
989
990         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
991         int r;
992
993         assert(bus);
994         assert(path);
995         assert(last);
996
997         r = sd_bus_get_property_trivial(
998                         bus,
999                         "org.freedesktop.systemd1",
1000                         path,
1001                         "org.freedesktop.systemd1.Timer",
1002                         "LastTriggerUSec",
1003                         &error,
1004                         't',
1005                         last);
1006         if (r < 0) {
1007                 log_error("Failed to get last trigger time: %s", bus_error_message(&error, r));
1008                 return r;
1009         }
1010
1011         return 0;
1012 }
1013
1014 struct timer_info {
1015         const char* machine;
1016         const char* id;
1017         usec_t next_elapse;
1018         usec_t last_trigger;
1019         char** triggered;
1020 };
1021
1022 static int timer_info_compare(const struct timer_info *a, const struct timer_info *b) {
1023         int o;
1024
1025         assert(a);
1026         assert(b);
1027
1028         if (!a->machine && b->machine)
1029                 return -1;
1030         if (a->machine && !b->machine)
1031                 return 1;
1032         if (a->machine && b->machine) {
1033                 o = strcasecmp(a->machine, b->machine);
1034                 if (o != 0)
1035                         return o;
1036         }
1037
1038         if (a->next_elapse < b->next_elapse)
1039                 return -1;
1040         if (a->next_elapse > b->next_elapse)
1041                 return 1;
1042
1043         return strcmp(a->id, b->id);
1044 }
1045
1046 static int output_timers_list(struct timer_info *timer_infos, unsigned n) {
1047         struct timer_info *t;
1048         unsigned
1049                 nextlen = strlen("NEXT"),
1050                 leftlen = strlen("LEFT"),
1051                 lastlen = strlen("LAST"),
1052                 passedlen = strlen("PASSED"),
1053                 unitlen = strlen("UNIT"),
1054                 activatelen = strlen("ACTIVATES");
1055
1056         const char *on, *off;
1057
1058         assert(timer_infos || n == 0);
1059
1060         for (t = timer_infos; t < timer_infos + n; t++) {
1061                 unsigned ul = 0;
1062                 char **a;
1063
1064                 if (t->next_elapse > 0) {
1065                         char tstamp[FORMAT_TIMESTAMP_MAX] = "", trel[FORMAT_TIMESTAMP_RELATIVE_MAX] = "";
1066
1067                         format_timestamp(tstamp, sizeof(tstamp), t->next_elapse);
1068                         nextlen = MAX(nextlen, strlen(tstamp) + 1);
1069
1070                         format_timestamp_relative(trel, sizeof(trel), t->next_elapse);
1071                         leftlen = MAX(leftlen, strlen(trel));
1072                 }
1073
1074                 if (t->last_trigger > 0) {
1075                         char tstamp[FORMAT_TIMESTAMP_MAX] = "", trel[FORMAT_TIMESTAMP_RELATIVE_MAX] = "";
1076
1077                         format_timestamp(tstamp, sizeof(tstamp), t->last_trigger);
1078                         lastlen = MAX(lastlen, strlen(tstamp) + 1);
1079
1080                         format_timestamp_relative(trel, sizeof(trel), t->last_trigger);
1081                         passedlen = MAX(passedlen, strlen(trel));
1082                 }
1083
1084                 unitlen = MAX(unitlen, strlen(t->id) + (t->machine ? strlen(t->machine)+1 : 0));
1085
1086                 STRV_FOREACH(a, t->triggered)
1087                         ul += strlen(*a) + 2*(a != t->triggered);
1088
1089                 activatelen = MAX(activatelen, ul);
1090         }
1091
1092         if (n > 0) {
1093                 if (!arg_no_legend)
1094                         printf("%-*s %-*s %-*s %-*s %-*s %s\n",
1095                                nextlen,   "NEXT",
1096                                leftlen,   "LEFT",
1097                                lastlen,   "LAST",
1098                                passedlen, "PASSED",
1099                                unitlen,   "UNIT",
1100                                           "ACTIVATES");
1101
1102                 for (t = timer_infos; t < timer_infos + n; t++) {
1103                         _cleanup_free_ char *j = NULL;
1104                         const char *unit;
1105                         char tstamp1[FORMAT_TIMESTAMP_MAX] = "n/a", trel1[FORMAT_TIMESTAMP_RELATIVE_MAX] = "n/a";
1106                         char tstamp2[FORMAT_TIMESTAMP_MAX] = "n/a", trel2[FORMAT_TIMESTAMP_RELATIVE_MAX] = "n/a";
1107                         char **a;
1108
1109                         format_timestamp(tstamp1, sizeof(tstamp1), t->next_elapse);
1110                         format_timestamp_relative(trel1, sizeof(trel1), t->next_elapse);
1111
1112                         format_timestamp(tstamp2, sizeof(tstamp2), t->last_trigger);
1113                         format_timestamp_relative(trel2, sizeof(trel2), t->last_trigger);
1114
1115                         if (t->machine) {
1116                                 j = strjoin(t->machine, ":", t->id, NULL);
1117                                 if (!j)
1118                                         return log_oom();
1119                                 unit = j;
1120                         } else
1121                                 unit = t->id;
1122
1123                         printf("%-*s %-*s %-*s %-*s %-*s",
1124                                nextlen, tstamp1, leftlen, trel1, lastlen, tstamp2, passedlen, trel2, unitlen, unit);
1125
1126                         STRV_FOREACH(a, t->triggered)
1127                                 printf("%s %s",
1128                                        a == t->triggered ? "" : ",", *a);
1129                         printf("\n");
1130                 }
1131
1132                 on = ansi_highlight();
1133                 off = ansi_highlight_off();
1134                 if (!arg_no_legend)
1135                         printf("\n");
1136         } else {
1137                 on = ansi_highlight_red();
1138                 off = ansi_highlight_off();
1139         }
1140
1141         if (!arg_no_legend) {
1142                 printf("%s%u timers listed.%s\n", on, n, off);
1143                 if (!arg_all)
1144                         printf("Pass --all to see loaded but inactive timers, too.\n");
1145         }
1146
1147         return 0;
1148 }
1149
1150 static usec_t calc_next_elapse(dual_timestamp *nw, dual_timestamp *next) {
1151         usec_t next_elapse;
1152
1153         assert(nw);
1154         assert(next);
1155
1156         if (next->monotonic != USEC_INFINITY && next->monotonic > 0) {
1157                 usec_t converted;
1158
1159                 if (next->monotonic > nw->monotonic)
1160                         converted = nw->realtime + (next->monotonic - nw->monotonic);
1161                 else
1162                         converted = nw->realtime - (nw->monotonic - next->monotonic);
1163
1164                 if (next->realtime != USEC_INFINITY && next->realtime > 0)
1165                         next_elapse = MIN(converted, next->realtime);
1166                 else
1167                         next_elapse = converted;
1168
1169         } else
1170                 next_elapse = next->realtime;
1171
1172         return next_elapse;
1173 }
1174
1175 static int list_timers(sd_bus *bus, char **args) {
1176         _cleanup_(message_set_freep) Set *replies = NULL;
1177         _cleanup_strv_free_ char **machines = NULL;
1178         _cleanup_free_ struct timer_info *timer_infos = NULL;
1179         _cleanup_free_ UnitInfo *unit_infos = NULL;
1180         struct timer_info *t;
1181         const UnitInfo *u;
1182         size_t size = 0;
1183         int n, c = 0;
1184         dual_timestamp nw;
1185         int r = 0;
1186
1187         pager_open_if_enabled();
1188
1189         n = get_unit_list_recursive(bus, strv_skip_first(args), &unit_infos, &replies, &machines);
1190         if (n < 0)
1191                 return n;
1192
1193         dual_timestamp_get(&nw);
1194
1195         for (u = unit_infos; u < unit_infos + n; u++) {
1196                 _cleanup_strv_free_ char **triggered = NULL;
1197                 dual_timestamp next = {};
1198                 usec_t m, last = 0;
1199
1200                 if (!endswith(u->id, ".timer"))
1201                         continue;
1202
1203                 r = get_triggered_units(bus, u->unit_path, &triggered);
1204                 if (r < 0)
1205                         goto cleanup;
1206
1207                 r = get_next_elapse(bus, u->unit_path, &next);
1208                 if (r < 0)
1209                         goto cleanup;
1210
1211                 get_last_trigger(bus, u->unit_path, &last);
1212
1213                 if (!GREEDY_REALLOC(timer_infos, size, c+1)) {
1214                         r = log_oom();
1215                         goto cleanup;
1216                 }
1217
1218                 m = calc_next_elapse(&nw, &next);
1219
1220                 timer_infos[c++] = (struct timer_info) {
1221                         .machine = u->machine,
1222                         .id = u->id,
1223                         .next_elapse = m,
1224                         .last_trigger = last,
1225                         .triggered = triggered,
1226                 };
1227
1228                 triggered = NULL; /* avoid cleanup */
1229         }
1230
1231         qsort_safe(timer_infos, c, sizeof(struct timer_info),
1232                    (__compar_fn_t) timer_info_compare);
1233
1234         output_timers_list(timer_infos, c);
1235
1236  cleanup:
1237         for (t = timer_infos; t < timer_infos + c; t++)
1238                 strv_free(t->triggered);
1239
1240         return r;
1241 }
1242
1243 static int compare_unit_file_list(const void *a, const void *b) {
1244         const char *d1, *d2;
1245         const UnitFileList *u = a, *v = b;
1246
1247         d1 = strrchr(u->path, '.');
1248         d2 = strrchr(v->path, '.');
1249
1250         if (d1 && d2) {
1251                 int r;
1252
1253                 r = strcasecmp(d1, d2);
1254                 if (r != 0)
1255                         return r;
1256         }
1257
1258         return strcasecmp(basename(u->path), basename(v->path));
1259 }
1260
1261 static bool output_show_unit_file(const UnitFileList *u, char **patterns) {
1262         if (!strv_isempty(patterns)) {
1263                 char **pattern;
1264
1265                 STRV_FOREACH(pattern, patterns)
1266                         if (fnmatch(*pattern, basename(u->path), FNM_NOESCAPE) == 0)
1267                                 goto next;
1268                 return false;
1269         }
1270
1271 next:
1272         if (!strv_isempty(arg_types)) {
1273                 const char *dot;
1274
1275                 dot = strrchr(u->path, '.');
1276                 if (!dot)
1277                         return false;
1278
1279                 if (!strv_find(arg_types, dot+1))
1280                         return false;
1281         }
1282
1283         if (!strv_isempty(arg_states)) {
1284                 if (!strv_find(arg_states, unit_file_state_to_string(u->state)))
1285                         return false;
1286         }
1287
1288         return true;
1289 }
1290
1291 static void output_unit_file_list(const UnitFileList *units, unsigned c) {
1292         unsigned max_id_len, id_cols, state_cols;
1293         const UnitFileList *u;
1294
1295         max_id_len = strlen("UNIT FILE");
1296         state_cols = strlen("STATE");
1297
1298         for (u = units; u < units + c; u++) {
1299                 max_id_len = MAX(max_id_len, strlen(basename(u->path)));
1300                 state_cols = MAX(state_cols, strlen(unit_file_state_to_string(u->state)));
1301         }
1302
1303         if (!arg_full) {
1304                 unsigned basic_cols;
1305
1306                 id_cols = MIN(max_id_len, 25u);
1307                 basic_cols = 1 + id_cols + state_cols;
1308                 if (basic_cols < (unsigned) columns())
1309                         id_cols += MIN(columns() - basic_cols, max_id_len - id_cols);
1310         } else
1311                 id_cols = max_id_len;
1312
1313         if (!arg_no_legend)
1314                 printf("%-*s %-*s\n",
1315                        id_cols, "UNIT FILE",
1316                        state_cols, "STATE");
1317
1318         for (u = units; u < units + c; u++) {
1319                 _cleanup_free_ char *e = NULL;
1320                 const char *on, *off;
1321                 const char *id;
1322
1323                 if (u->state == UNIT_FILE_MASKED ||
1324                     u->state == UNIT_FILE_MASKED_RUNTIME ||
1325                     u->state == UNIT_FILE_DISABLED ||
1326                     u->state == UNIT_FILE_INVALID) {
1327                         on  = ansi_highlight_red();
1328                         off = ansi_highlight_off();
1329                 } else if (u->state == UNIT_FILE_ENABLED) {
1330                         on  = ansi_highlight_green();
1331                         off = ansi_highlight_off();
1332                 } else
1333                         on = off = "";
1334
1335                 id = basename(u->path);
1336
1337                 e = arg_full ? NULL : ellipsize(id, id_cols, 33);
1338
1339                 printf("%-*s %s%-*s%s\n",
1340                        id_cols, e ? e : id,
1341                        on, state_cols, unit_file_state_to_string(u->state), off);
1342         }
1343
1344         if (!arg_no_legend)
1345                 printf("\n%u unit files listed.\n", c);
1346 }
1347
1348 static int list_unit_files(sd_bus *bus, char **args) {
1349         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1350         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1351         _cleanup_free_ UnitFileList *units = NULL;
1352         UnitFileList *unit;
1353         size_t size = 0;
1354         unsigned c = 0;
1355         const char *state;
1356         char *path;
1357         int r;
1358
1359         pager_open_if_enabled();
1360
1361         if (avoid_bus()) {
1362                 Hashmap *h;
1363                 UnitFileList *u;
1364                 Iterator i;
1365                 unsigned n_units;
1366
1367                 h = hashmap_new(&string_hash_ops);
1368                 if (!h)
1369                         return log_oom();
1370
1371                 r = unit_file_get_list(arg_scope, arg_root, h);
1372                 if (r < 0) {
1373                         unit_file_list_free(h);
1374                         log_error_errno(r, "Failed to get unit file list: %m");
1375                         return r;
1376                 }
1377
1378                 n_units = hashmap_size(h);
1379
1380                 units = new(UnitFileList, n_units);
1381                 if (!units && n_units > 0) {
1382                         unit_file_list_free(h);
1383                         return log_oom();
1384                 }
1385
1386                 HASHMAP_FOREACH(u, h, i) {
1387                         if (!output_show_unit_file(u, strv_skip_first(args)))
1388                                 continue;
1389
1390                         units[c++] = *u;
1391                         free(u);
1392                 }
1393
1394                 assert(c <= n_units);
1395                 hashmap_free(h);
1396         } else {
1397                 r = sd_bus_call_method(
1398                                 bus,
1399                                 "org.freedesktop.systemd1",
1400                                 "/org/freedesktop/systemd1",
1401                                 "org.freedesktop.systemd1.Manager",
1402                                 "ListUnitFiles",
1403                                 &error,
1404                                 &reply,
1405                                 NULL);
1406                 if (r < 0) {
1407                         log_error("Failed to list unit files: %s", bus_error_message(&error, r));
1408                         return r;
1409                 }
1410
1411                 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ss)");
1412                 if (r < 0)
1413                         return bus_log_parse_error(r);
1414
1415                 while ((r = sd_bus_message_read(reply, "(ss)", &path, &state)) > 0) {
1416
1417                         if (!GREEDY_REALLOC(units, size, c + 1))
1418                                 return log_oom();
1419
1420                         units[c] = (struct UnitFileList) {
1421                                 path,
1422                                 unit_file_state_from_string(state)
1423                         };
1424
1425                         if (output_show_unit_file(&units[c], strv_skip_first(args)))
1426                                 c ++;
1427
1428                 }
1429                 if (r < 0)
1430                         return bus_log_parse_error(r);
1431
1432                 r = sd_bus_message_exit_container(reply);
1433                 if (r < 0)
1434                         return bus_log_parse_error(r);
1435         }
1436
1437         qsort_safe(units, c, sizeof(UnitFileList), compare_unit_file_list);
1438         output_unit_file_list(units, c);
1439
1440         if (avoid_bus()) {
1441                 for (unit = units; unit < units + c; unit++)
1442                         free(unit->path);
1443         }
1444
1445         return 0;
1446 }
1447
1448 static int list_dependencies_print(const char *name, int level, unsigned int branches, bool last) {
1449         _cleanup_free_ char *n = NULL;
1450         size_t max_len = MAX(columns(),20u);
1451         size_t len = 0;
1452         int i;
1453
1454         if (!arg_plain) {
1455
1456                 for (i = level - 1; i >= 0; i--) {
1457                         len += 2;
1458                         if (len > max_len - 3 && !arg_full) {
1459                                 printf("%s...\n",max_len % 2 ? "" : " ");
1460                                 return 0;
1461                         }
1462                         printf("%s", draw_special_char(branches & (1 << i) ? DRAW_TREE_VERTICAL : DRAW_TREE_SPACE));
1463                 }
1464                 len += 2;
1465
1466                 if (len > max_len - 3 && !arg_full) {
1467                         printf("%s...\n",max_len % 2 ? "" : " ");
1468                         return 0;
1469                 }
1470
1471                 printf("%s", draw_special_char(last ? DRAW_TREE_RIGHT : DRAW_TREE_BRANCH));
1472         }
1473
1474         if (arg_full){
1475                 printf("%s\n", name);
1476                 return 0;
1477         }
1478
1479         n = ellipsize(name, max_len-len, 100);
1480         if (!n)
1481                 return log_oom();
1482
1483         printf("%s\n", n);
1484         return 0;
1485 }
1486
1487 static int list_dependencies_get_dependencies(sd_bus *bus, const char *name, char ***deps) {
1488
1489         static const char *dependencies[_DEPENDENCY_MAX] = {
1490                 [DEPENDENCY_FORWARD] = "Requires\0"
1491                                        "RequiresOverridable\0"
1492                                        "Requisite\0"
1493                                        "RequisiteOverridable\0"
1494                                        "Wants\0"
1495                                        "BindsTo\0",
1496                 [DEPENDENCY_REVERSE] = "RequiredBy\0"
1497                                        "RequiredByOverridable\0"
1498                                        "WantedBy\0"
1499                                        "PartOf\0"
1500                                        "BoundBy\0",
1501                 [DEPENDENCY_AFTER]   = "After\0",
1502                 [DEPENDENCY_BEFORE]  = "Before\0",
1503         };
1504
1505         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1506         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1507         _cleanup_strv_free_ char **ret = NULL;
1508         _cleanup_free_ char *path = NULL;
1509         int r;
1510
1511         assert(bus);
1512         assert(name);
1513         assert(deps);
1514         assert_cc(ELEMENTSOF(dependencies) == _DEPENDENCY_MAX);
1515
1516         path = unit_dbus_path_from_name(name);
1517         if (!path)
1518                 return log_oom();
1519
1520         r = sd_bus_call_method(
1521                         bus,
1522                         "org.freedesktop.systemd1",
1523                         path,
1524                         "org.freedesktop.DBus.Properties",
1525                         "GetAll",
1526                         &error,
1527                         &reply,
1528                         "s", "org.freedesktop.systemd1.Unit");
1529         if (r < 0) {
1530                 log_error("Failed to get properties of %s: %s", name, bus_error_message(&error, r));
1531                 return r;
1532         }
1533
1534         r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
1535         if (r < 0)
1536                 return bus_log_parse_error(r);
1537
1538         while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
1539                 const char *prop;
1540
1541                 r = sd_bus_message_read(reply, "s", &prop);
1542                 if (r < 0)
1543                         return bus_log_parse_error(r);
1544
1545                 if (!nulstr_contains(dependencies[arg_dependency], prop)) {
1546                         r = sd_bus_message_skip(reply, "v");
1547                         if (r < 0)
1548                                 return bus_log_parse_error(r);
1549                 } else {
1550
1551                         r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, "as");
1552                         if (r < 0)
1553                                 return bus_log_parse_error(r);
1554
1555                         r = bus_message_read_strv_extend(reply, &ret);
1556                         if (r < 0)
1557                                 return bus_log_parse_error(r);
1558
1559                         r = sd_bus_message_exit_container(reply);
1560                         if (r < 0)
1561                                 return bus_log_parse_error(r);
1562                 }
1563
1564                 r = sd_bus_message_exit_container(reply);
1565                 if (r < 0)
1566                         return bus_log_parse_error(r);
1567
1568         }
1569         if (r < 0)
1570                 return bus_log_parse_error(r);
1571
1572         r = sd_bus_message_exit_container(reply);
1573         if (r < 0)
1574                 return bus_log_parse_error(r);
1575
1576         *deps = ret;
1577         ret = NULL;
1578
1579         return 0;
1580 }
1581
1582 static int list_dependencies_compare(const void *_a, const void *_b) {
1583         const char **a = (const char**) _a, **b = (const char**) _b;
1584
1585         if (unit_name_to_type(*a) == UNIT_TARGET && unit_name_to_type(*b) != UNIT_TARGET)
1586                 return 1;
1587         if (unit_name_to_type(*a) != UNIT_TARGET && unit_name_to_type(*b) == UNIT_TARGET)
1588                 return -1;
1589
1590         return strcasecmp(*a, *b);
1591 }
1592
1593 static int list_dependencies_one(
1594                 sd_bus *bus,
1595                 const char *name,
1596                 int level,
1597                 char ***units,
1598                 unsigned int branches) {
1599
1600         _cleanup_strv_free_ char **deps = NULL;
1601         char **c;
1602         int r = 0;
1603
1604         assert(bus);
1605         assert(name);
1606         assert(units);
1607
1608         r = strv_extend(units, name);
1609         if (r < 0)
1610                 return log_oom();
1611
1612         r = list_dependencies_get_dependencies(bus, name, &deps);
1613         if (r < 0)
1614                 return r;
1615
1616         qsort_safe(deps, strv_length(deps), sizeof (char*), list_dependencies_compare);
1617
1618         STRV_FOREACH(c, deps) {
1619                 int state;
1620
1621                 if (strv_contains(*units, *c)) {
1622                         if (!arg_plain) {
1623                                 r = list_dependencies_print("...", level + 1, (branches << 1) | (c[1] == NULL ? 0 : 1), 1);
1624                                 if (r < 0)
1625                                         return r;
1626                         }
1627                         continue;
1628                 }
1629
1630                 state = check_one_unit(bus, *c, "activating\0active\0reloading\0", true);
1631                 if (state > 0)
1632                         printf("%s%s%s ", ansi_highlight_green(), draw_special_char(DRAW_BLACK_CIRCLE), ansi_highlight_off());
1633                 else
1634                         printf("%s%s%s ", ansi_highlight_red(), draw_special_char(DRAW_BLACK_CIRCLE), ansi_highlight_off());
1635
1636                 r = list_dependencies_print(*c, level, branches, c[1] == NULL);
1637                 if (r < 0)
1638                         return r;
1639
1640                 if (arg_all || unit_name_to_type(*c) == UNIT_TARGET) {
1641                        r = list_dependencies_one(bus, *c, level + 1, units, (branches << 1) | (c[1] == NULL ? 0 : 1));
1642                        if (r < 0)
1643                                return r;
1644                 }
1645         }
1646
1647         if (!arg_plain)
1648                 strv_remove(*units, name);
1649
1650         return 0;
1651 }
1652
1653 static int list_dependencies(sd_bus *bus, char **args) {
1654         _cleanup_strv_free_ char **units = NULL;
1655         _cleanup_free_ char *unit = NULL;
1656         const char *u;
1657
1658         assert(bus);
1659
1660         if (args[1]) {
1661                 unit = unit_name_mangle(args[1], MANGLE_NOGLOB);
1662                 if (!unit)
1663                         return log_oom();
1664                 u = unit;
1665         } else
1666                 u = SPECIAL_DEFAULT_TARGET;
1667
1668         pager_open_if_enabled();
1669
1670         puts(u);
1671
1672         return list_dependencies_one(bus, u, 0, &units, 0);
1673 }
1674
1675 struct machine_info {
1676         bool is_host;
1677         char *name;
1678         char *state;
1679         char *control_group;
1680         uint32_t n_failed_units;
1681         uint32_t n_jobs;
1682         usec_t timestamp;
1683 };
1684
1685 static const struct bus_properties_map machine_info_property_map[] = {
1686         { "SystemState",        "s", NULL, offsetof(struct machine_info, state)          },
1687         { "NJobs",              "u", NULL, offsetof(struct machine_info, n_jobs)         },
1688         { "NFailedUnits",       "u", NULL, offsetof(struct machine_info, n_failed_units) },
1689         { "ControlGroup",       "s", NULL, offsetof(struct machine_info, control_group)  },
1690         { "UserspaceTimestamp", "t", NULL, offsetof(struct machine_info, timestamp)      },
1691         {}
1692 };
1693
1694 static void free_machines_list(struct machine_info *machine_infos, int n) {
1695         int i;
1696
1697         if (!machine_infos)
1698                 return;
1699
1700         for (i = 0; i < n; i++) {
1701                 free(machine_infos[i].name);
1702                 free(machine_infos[i].state);
1703                 free(machine_infos[i].control_group);
1704         }
1705
1706         free(machine_infos);
1707 }
1708
1709 static int compare_machine_info(const void *a, const void *b) {
1710         const struct machine_info *u = a, *v = b;
1711
1712         if (u->is_host != v->is_host)
1713                 return u->is_host > v->is_host ? -1 : 1;
1714
1715         return strcasecmp(u->name, v->name);
1716 }
1717
1718 static int get_machine_properties(sd_bus *bus, struct machine_info *mi) {
1719         _cleanup_bus_close_unref_ sd_bus *container = NULL;
1720         int r;
1721
1722         assert(mi);
1723
1724         if (!bus) {
1725                 r = sd_bus_open_system_machine(&container, mi->name);
1726                 if (r < 0)
1727                         return r;
1728
1729                 bus = container;
1730         }
1731
1732         r = bus_map_all_properties(bus, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map, mi);
1733         if (r < 0)
1734                 return r;
1735
1736         return 0;
1737 }
1738
1739 static bool output_show_machine(const char *name, char **patterns) {
1740         char **i;
1741
1742         assert(name);
1743
1744         if (strv_isempty(patterns))
1745                 return true;
1746
1747         STRV_FOREACH(i, patterns)
1748                 if (fnmatch(*i, name, FNM_NOESCAPE) == 0)
1749                         return true;
1750
1751         return false;
1752 }
1753
1754 static int get_machine_list(
1755                 sd_bus *bus,
1756                 struct machine_info **_machine_infos,
1757                 char **patterns) {
1758
1759         struct machine_info *machine_infos = NULL;
1760         _cleanup_strv_free_ char **m = NULL;
1761         _cleanup_free_ char *hn = NULL;
1762         size_t sz = 0;
1763         char **i;
1764         int c = 0;
1765
1766         hn = gethostname_malloc();
1767         if (!hn)
1768                 return log_oom();
1769
1770         if (output_show_machine(hn, patterns)) {
1771                 if (!GREEDY_REALLOC0(machine_infos, sz, c+1))
1772                         return log_oom();
1773
1774                 machine_infos[c].is_host = true;
1775                 machine_infos[c].name = hn;
1776                 hn = NULL;
1777
1778                 get_machine_properties(bus, &machine_infos[c]);
1779                 c++;
1780         }
1781
1782         sd_get_machine_names(&m);
1783         STRV_FOREACH(i, m) {
1784                 _cleanup_free_ char *class = NULL;
1785
1786                 if (!output_show_machine(*i, patterns))
1787                         continue;
1788
1789                 sd_machine_get_class(*i, &class);
1790                 if (!streq_ptr(class, "container"))
1791                         continue;
1792
1793                 if (!GREEDY_REALLOC0(machine_infos, sz, c+1)) {
1794                         free_machines_list(machine_infos, c);
1795                         return log_oom();
1796                 }
1797
1798                 machine_infos[c].is_host = false;
1799                 machine_infos[c].name = strdup(*i);
1800                 if (!machine_infos[c].name) {
1801                         free_machines_list(machine_infos, c);
1802                         return log_oom();
1803                 }
1804
1805                 get_machine_properties(NULL, &machine_infos[c]);
1806                 c++;
1807         }
1808
1809         *_machine_infos = machine_infos;
1810         return c;
1811 }
1812
1813 static void output_machines_list(struct machine_info *machine_infos, unsigned n) {
1814         struct machine_info *m;
1815         unsigned
1816                 circle_len = 0,
1817                 namelen = sizeof("NAME") - 1,
1818                 statelen = sizeof("STATE") - 1,
1819                 failedlen = sizeof("FAILED") - 1,
1820                 jobslen = sizeof("JOBS") - 1;
1821
1822         assert(machine_infos || n == 0);
1823
1824         for (m = machine_infos; m < machine_infos + n; m++) {
1825                 namelen = MAX(namelen, strlen(m->name) + (m->is_host ? sizeof(" (host)") - 1 : 0));
1826                 statelen = MAX(statelen, m->state ? strlen(m->state) : 0);
1827                 failedlen = MAX(failedlen, DECIMAL_STR_WIDTH(m->n_failed_units));
1828                 jobslen = MAX(jobslen, DECIMAL_STR_WIDTH(m->n_jobs));
1829
1830                 if (!arg_no_legend && !streq_ptr(m->state, "running"))
1831                         circle_len = 2;
1832         }
1833
1834         if (!arg_no_legend) {
1835                 if (circle_len > 0)
1836                         fputs("  ", stdout);
1837
1838                 printf("%-*s %-*s %-*s %-*s\n",
1839                          namelen, "NAME",
1840                         statelen, "STATE",
1841                        failedlen, "FAILED",
1842                          jobslen, "JOBS");
1843         }
1844
1845         for (m = machine_infos; m < machine_infos + n; m++) {
1846                 const char *on_state = "", *off_state = "";
1847                 const char *on_failed = "", *off_failed = "";
1848                 bool circle = false;
1849
1850                 if (streq_ptr(m->state, "degraded")) {
1851                         on_state = ansi_highlight_red();
1852                         off_state = ansi_highlight_off();
1853                         circle = true;
1854                 } else if (!streq_ptr(m->state, "running")) {
1855                         on_state = ansi_highlight_yellow();
1856                         off_state = ansi_highlight_off();
1857                         circle = true;
1858                 }
1859
1860                 if (m->n_failed_units > 0) {
1861                         on_failed = ansi_highlight_red();
1862                         off_failed = ansi_highlight_off();
1863                 } else
1864                         on_failed = off_failed = "";
1865
1866                 if (circle_len > 0)
1867                         printf("%s%s%s ", on_state, circle ? draw_special_char(DRAW_BLACK_CIRCLE) : " ", off_state);
1868
1869                 if (m->is_host)
1870                         printf("%-*s (host) %s%-*s%s %s%*u%s %*u\n",
1871                                (int) (namelen - (sizeof(" (host)")-1)), strna(m->name),
1872                                on_state, statelen, strna(m->state), off_state,
1873                                on_failed, failedlen, m->n_failed_units, off_failed,
1874                                jobslen, m->n_jobs);
1875                 else
1876                         printf("%-*s %s%-*s%s %s%*u%s %*u\n",
1877                                namelen, strna(m->name),
1878                                on_state, statelen, strna(m->state), off_state,
1879                                on_failed, failedlen, m->n_failed_units, off_failed,
1880                                jobslen, m->n_jobs);
1881         }
1882
1883         if (!arg_no_legend)
1884                 printf("\n%u machines listed.\n", n);
1885 }
1886
1887 static int list_machines(sd_bus *bus, char **args) {
1888         struct machine_info *machine_infos = NULL;
1889         int r;
1890
1891         assert(bus);
1892
1893         if (geteuid() != 0) {
1894                 log_error("Must be root.");
1895                 return -EPERM;
1896         }
1897
1898         pager_open_if_enabled();
1899
1900         r = get_machine_list(bus, &machine_infos, strv_skip_first(args));
1901         if (r < 0)
1902                 return r;
1903
1904         qsort_safe(machine_infos, r, sizeof(struct machine_info), compare_machine_info);
1905         output_machines_list(machine_infos, r);
1906         free_machines_list(machine_infos, r);
1907
1908         return 0;
1909 }
1910
1911 static int get_default(sd_bus *bus, char **args) {
1912         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1913         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1914         _cleanup_free_ char *_path = NULL;
1915         const char *path;
1916         int r;
1917
1918         if (!bus || avoid_bus()) {
1919                 r = unit_file_get_default(arg_scope, arg_root, &_path);
1920                 if (r < 0)
1921                         return log_error_errno(r, "Failed to get default target: %m");
1922                 path = _path;
1923
1924         } else {
1925                 r = sd_bus_call_method(
1926                                 bus,
1927                                 "org.freedesktop.systemd1",
1928                                 "/org/freedesktop/systemd1",
1929                                 "org.freedesktop.systemd1.Manager",
1930                                 "GetDefaultTarget",
1931                                 &error,
1932                                 &reply,
1933                                 NULL);
1934                 if (r < 0) {
1935                         log_error("Failed to get default target: %s", bus_error_message(&error, -r));
1936                         return r;
1937                 }
1938
1939                 r = sd_bus_message_read(reply, "s", &path);
1940                 if (r < 0)
1941                         return bus_log_parse_error(r);
1942         }
1943
1944         if (path)
1945                 printf("%s\n", path);
1946
1947         return 0;
1948 }
1949
1950 static void dump_unit_file_changes(const UnitFileChange *changes, unsigned n_changes) {
1951         unsigned i;
1952
1953         assert(changes || n_changes == 0);
1954
1955         for (i = 0; i < n_changes; i++) {
1956                 if (changes[i].type == UNIT_FILE_SYMLINK)
1957                         log_info("Created symlink from %s to %s.", changes[i].path, changes[i].source);
1958                 else
1959                         log_info("Removed symlink %s.", changes[i].path);
1960         }
1961 }
1962
1963 static int set_default(sd_bus *bus, char **args) {
1964         _cleanup_free_ char *unit = NULL;
1965         UnitFileChange *changes = NULL;
1966         unsigned n_changes = 0;
1967         int r;
1968
1969         unit = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".target");
1970         if (!unit)
1971                 return log_oom();
1972
1973         if (!bus || avoid_bus()) {
1974                 r = unit_file_set_default(arg_scope, arg_root, unit, true, &changes, &n_changes);
1975                 if (r < 0)
1976                         return log_error_errno(r, "Failed to set default target: %m");
1977
1978                 if (!arg_quiet)
1979                         dump_unit_file_changes(changes, n_changes);
1980
1981                 r = 0;
1982         } else {
1983                 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
1984                 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1985
1986                 r = sd_bus_message_new_method_call(
1987                                 bus,
1988                                 &m,
1989                                 "org.freedesktop.systemd1",
1990                                 "/org/freedesktop/systemd1",
1991                                 "org.freedesktop.systemd1.Manager",
1992                                 "SetDefaultTarget");
1993                 if (r < 0)
1994                         return bus_log_create_error(r);
1995
1996                 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
1997                 if (r < 0)
1998                         return bus_log_create_error(r);
1999
2000                 r = sd_bus_message_append(m, "sb", unit, 1);
2001                 if (r < 0)
2002                         return bus_log_create_error(r);
2003
2004                 r = sd_bus_call(bus, m, 0, &error, &reply);
2005                 if (r < 0) {
2006                         log_error("Failed to set default target: %s", bus_error_message(&error, -r));
2007                         return r;
2008                 }
2009
2010                 r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet);
2011                 if (r < 0)
2012                         return r;
2013
2014                 /* Try to reload if enabled */
2015                 if (!arg_no_reload)
2016                         r = daemon_reload(bus, args);
2017                 else
2018                         r = 0;
2019         }
2020
2021         unit_file_changes_free(changes, n_changes);
2022
2023         return r;
2024 }
2025
2026 struct job_info {
2027         uint32_t id;
2028         const char *name, *type, *state;
2029 };
2030
2031 static void output_jobs_list(const struct job_info* jobs, unsigned n, bool skipped) {
2032         unsigned id_len, unit_len, type_len, state_len;
2033         const struct job_info *j;
2034         const char *on, *off;
2035         bool shorten = false;
2036
2037         assert(n == 0 || jobs);
2038
2039         if (n == 0) {
2040                 on = ansi_highlight_green();
2041                 off = ansi_highlight_off();
2042
2043                 printf("%sNo jobs %s.%s\n", on, skipped ? "listed" : "running", off);
2044                 return;
2045         }
2046
2047         pager_open_if_enabled();
2048
2049         id_len = strlen("JOB");
2050         unit_len = strlen("UNIT");
2051         type_len = strlen("TYPE");
2052         state_len = strlen("STATE");
2053
2054         for (j = jobs; j < jobs + n; j++) {
2055                 uint32_t id = j->id;
2056                 assert(j->name && j->type && j->state);
2057
2058                 id_len = MAX(id_len, DECIMAL_STR_WIDTH(id));
2059                 unit_len = MAX(unit_len, strlen(j->name));
2060                 type_len = MAX(type_len, strlen(j->type));
2061                 state_len = MAX(state_len, strlen(j->state));
2062         }
2063
2064         if (!arg_full && id_len + 1 + unit_len + type_len + 1 + state_len > columns()) {
2065                 unit_len = MAX(33u, columns() - id_len - type_len - state_len - 3);
2066                 shorten = true;
2067         }
2068
2069         if (!arg_no_legend)
2070                 printf("%*s %-*s %-*s %-*s\n",
2071                        id_len, "JOB",
2072                        unit_len, "UNIT",
2073                        type_len, "TYPE",
2074                        state_len, "STATE");
2075
2076         for (j = jobs; j < jobs + n; j++) {
2077                 _cleanup_free_ char *e = NULL;
2078
2079                 if (streq(j->state, "running")) {
2080                         on = ansi_highlight();
2081                         off = ansi_highlight_off();
2082                 } else
2083                         on = off = "";
2084
2085                 e = shorten ? ellipsize(j->name, unit_len, 33) : NULL;
2086                 printf("%*u %s%-*s%s %-*s %s%-*s%s\n",
2087                        id_len, j->id,
2088                        on, unit_len, e ? e : j->name, off,
2089                        type_len, j->type,
2090                        on, state_len, j->state, off);
2091         }
2092
2093         if (!arg_no_legend) {
2094                 on = ansi_highlight();
2095                 off = ansi_highlight_off();
2096
2097                 printf("\n%s%u jobs listed%s.\n", on, n, off);
2098         }
2099 }
2100
2101 static bool output_show_job(struct job_info *job, char **patterns) {
2102         char **pattern;
2103
2104         assert(job);
2105
2106         if (strv_isempty(patterns))
2107                 return true;
2108
2109         STRV_FOREACH(pattern, patterns)
2110                 if (fnmatch(*pattern, job->name, FNM_NOESCAPE) == 0)
2111                         return true;
2112         return false;
2113 }
2114
2115 static int list_jobs(sd_bus *bus, char **args) {
2116         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2117         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2118         const char *name, *type, *state, *job_path, *unit_path;
2119         _cleanup_free_ struct job_info *jobs = NULL;
2120         size_t size = 0;
2121         unsigned c = 0;
2122         uint32_t id;
2123         int r;
2124         bool skipped = false;
2125
2126         r = sd_bus_call_method(
2127                         bus,
2128                         "org.freedesktop.systemd1",
2129                         "/org/freedesktop/systemd1",
2130                         "org.freedesktop.systemd1.Manager",
2131                         "ListJobs",
2132                         &error,
2133                         &reply,
2134                         NULL);
2135         if (r < 0) {
2136                 log_error("Failed to list jobs: %s", bus_error_message(&error, r));
2137                 return r;
2138         }
2139
2140         r = sd_bus_message_enter_container(reply, 'a', "(usssoo)");
2141         if (r < 0)
2142                 return bus_log_parse_error(r);
2143
2144         while ((r = sd_bus_message_read(reply, "(usssoo)", &id, &name, &type, &state, &job_path, &unit_path)) > 0) {
2145                 struct job_info job = { id, name, type, state };
2146
2147                 if (!output_show_job(&job, strv_skip_first(args))) {
2148                         skipped = true;
2149                         continue;
2150                 }
2151
2152                 if (!GREEDY_REALLOC(jobs, size, c + 1))
2153                         return log_oom();
2154
2155                 jobs[c++] = job;
2156         }
2157         if (r < 0)
2158                 return bus_log_parse_error(r);
2159
2160         r = sd_bus_message_exit_container(reply);
2161         if (r < 0)
2162                 return bus_log_parse_error(r);
2163
2164         output_jobs_list(jobs, c, skipped);
2165         return r;
2166 }
2167
2168 static int cancel_job(sd_bus *bus, char **args) {
2169         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2170         char **name;
2171         int r = 0;
2172
2173         assert(args);
2174
2175         if (strv_length(args) <= 1)
2176                 return daemon_reload(bus, args);
2177
2178         STRV_FOREACH(name, args+1) {
2179                 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
2180                 uint32_t id;
2181                 int q;
2182
2183                 q = safe_atou32(*name, &id);
2184                 if (q < 0)
2185                         return log_error_errno(q, "Failed to parse job id \"%s\": %m", *name);
2186
2187                 q = sd_bus_message_new_method_call(
2188                                 bus,
2189                                 &m,
2190                                 "org.freedesktop.systemd1",
2191                                 "/org/freedesktop/systemd1",
2192                                 "org.freedesktop.systemd1.Manager",
2193                                 "CancelJob");
2194                 if (q < 0)
2195                         return bus_log_create_error(q);
2196
2197                 q = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
2198                 if (q < 0)
2199                         return bus_log_create_error(1);
2200
2201                 q = sd_bus_message_append(m, "u", id);
2202                 if (q < 0)
2203                         return bus_log_create_error(q);
2204
2205                 q = sd_bus_call(bus, m, 0, &error, NULL);
2206                 if (q < 0) {
2207                         log_error("Failed to cancel job %"PRIu32": %s", id, bus_error_message(&error, q));
2208                         if (r == 0)
2209                                 r = q;
2210                 }
2211         }
2212
2213         return r;
2214 }
2215
2216 static int need_daemon_reload(sd_bus *bus, const char *unit) {
2217         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2218         const char *path;
2219         int b, r;
2220
2221         /* We ignore all errors here, since this is used to show a
2222          * warning only */
2223
2224         /* We don't use unit_dbus_path_from_name() directly since we
2225          * don't want to load the unit if it isn't loaded. */
2226
2227         r = sd_bus_call_method(
2228                         bus,
2229                         "org.freedesktop.systemd1",
2230                         "/org/freedesktop/systemd1",
2231                         "org.freedesktop.systemd1.Manager",
2232                         "GetUnit",
2233                         NULL,
2234                         &reply,
2235                         "s", unit);
2236         if (r < 0)
2237                 return r;
2238
2239         r = sd_bus_message_read(reply, "o", &path);
2240         if (r < 0)
2241                 return r;
2242
2243         r = sd_bus_get_property_trivial(
2244                         bus,
2245                         "org.freedesktop.systemd1",
2246                         path,
2247                         "org.freedesktop.systemd1.Unit",
2248                         "NeedDaemonReload",
2249                         NULL,
2250                         'b', &b);
2251         if (r < 0)
2252                 return r;
2253
2254         return b;
2255 }
2256
2257 static void warn_unit_file_changed(const char *name) {
2258         log_warning("%sWarning:%s %s changed on disk. Run 'systemctl%s daemon-reload' to reload units.",
2259                     ansi_highlight_red(),
2260                     ansi_highlight_off(),
2261                     name,
2262                     arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
2263 }
2264
2265 static int unit_file_find_path(LookupPaths *lp, const char *unit_name, char **unit_path) {
2266         char **p;
2267
2268         assert(lp);
2269         assert(unit_name);
2270         assert(unit_path);
2271
2272         STRV_FOREACH(p, lp->unit_path) {
2273                 _cleanup_free_ char *path;
2274
2275                 path = path_join(arg_root, *p, unit_name);
2276                 if (!path)
2277                         return log_oom();
2278
2279                 if (access(path, F_OK) == 0) {
2280                         *unit_path = path;
2281                         path = NULL;
2282                         return 1;
2283                 }
2284         }
2285
2286         return 0;
2287 }
2288
2289 static int unit_find_paths(sd_bus *bus,
2290                            const char *unit_name,
2291                            bool avoid_bus_cache,
2292                            LookupPaths *lp,
2293                            char **fragment_path,
2294                            char ***dropin_paths) {
2295         int r;
2296
2297         /**
2298          * Finds where the unit is defined on disk. Returns 0 if the unit
2299          * is not found. Returns 1 if it is found, and sets
2300          * - the path to the unit in *path, if it exists on disk,
2301          * - and a strv of existing drop-ins in *dropins,
2302          *   if the arg is not NULL and any dropins were found.
2303          */
2304
2305         assert(unit_name);
2306         assert(fragment_path);
2307         assert(lp);
2308
2309         if (!avoid_bus_cache && !unit_name_is_template(unit_name)) {
2310                 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2311                 _cleanup_free_ char *unit = NULL;
2312                 _cleanup_free_ char *path = NULL;
2313                 _cleanup_strv_free_ char **dropins = NULL;
2314
2315                 unit = unit_dbus_path_from_name(unit_name);
2316                 if (!unit)
2317                         return log_oom();
2318
2319                 if (need_daemon_reload(bus, unit_name) > 0)
2320                         warn_unit_file_changed(unit_name);
2321
2322                 r = sd_bus_get_property_string(
2323                                 bus,
2324                                 "org.freedesktop.systemd1",
2325                                 unit,
2326                                 "org.freedesktop.systemd1.Unit",
2327                                 "FragmentPath",
2328                                 &error,
2329                                 &path);
2330                 if (r < 0)
2331                         return log_error_errno(r, "Failed to get FragmentPath: %s", bus_error_message(&error, r));
2332
2333                 r = sd_bus_get_property_strv(
2334                                 bus,
2335                                 "org.freedesktop.systemd1",
2336                                 unit,
2337                                 "org.freedesktop.systemd1.Unit",
2338                                 "DropInPaths",
2339                                 &error,
2340                                 &dropins);
2341                 if (r < 0)
2342                         return log_error_errno(r, "Failed to get DropInPaths: %s", bus_error_message(&error, r));
2343
2344                 r = 0;
2345                 if (!isempty(path)) {
2346                         *fragment_path = path;
2347                         path = NULL;
2348                         r = 1;
2349                 }
2350
2351                 if (dropin_paths && !strv_isempty(dropins)) {
2352                         *dropin_paths = dropins;
2353                         dropins = NULL;
2354                         r = 1;
2355                 }
2356         } else {
2357                 _cleanup_set_free_ Set *names;
2358
2359                 names = set_new(NULL);
2360                 if (!names)
2361                         return -ENOMEM;
2362
2363                 r = set_put(names, unit_name);
2364                 if (r < 0)
2365                         return r;
2366
2367                 r = unit_file_find_path(lp, unit_name, fragment_path);
2368                 if (r < 0)
2369                         return r;
2370
2371                 if (r == 0) {
2372                         _cleanup_free_ char *template;
2373
2374                         template = unit_name_template(unit_name);
2375                         if (!template)
2376                                 return log_oom();
2377
2378                         if (!streq(template, unit_name)) {
2379                                 r = unit_file_find_path(lp, template, fragment_path);
2380                                 if (r < 0)
2381                                         return r;
2382                         }
2383                 }
2384
2385                 if (dropin_paths)
2386                         r = unit_file_find_dropin_paths(lp->unit_path, NULL, names, dropin_paths);
2387         }
2388
2389         return r;
2390 }
2391
2392 static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet) {
2393         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2394         _cleanup_free_ char *n = NULL, *state = NULL;
2395         const char *path;
2396         int r;
2397
2398         assert(name);
2399
2400         n = unit_name_mangle(name, MANGLE_NOGLOB);
2401         if (!n)
2402                 return log_oom();
2403
2404         /* We don't use unit_dbus_path_from_name() directly since we
2405          * don't want to load the unit if it isn't loaded. */
2406
2407         r = sd_bus_call_method(
2408                         bus,
2409                         "org.freedesktop.systemd1",
2410                         "/org/freedesktop/systemd1",
2411                         "org.freedesktop.systemd1.Manager",
2412                         "GetUnit",
2413                         NULL,
2414                         &reply,
2415                         "s", n);
2416         if (r < 0) {
2417                 if (!quiet)
2418                         puts("unknown");
2419                 return 0;
2420         }
2421
2422         r = sd_bus_message_read(reply, "o", &path);
2423         if (r < 0)
2424                 return bus_log_parse_error(r);
2425
2426         r = sd_bus_get_property_string(
2427                         bus,
2428                         "org.freedesktop.systemd1",
2429                         path,
2430                         "org.freedesktop.systemd1.Unit",
2431                         "ActiveState",
2432                         NULL,
2433                         &state);
2434         if (r < 0) {
2435                 if (!quiet)
2436                         puts("unknown");
2437                 return 0;
2438         }
2439
2440         if (!quiet)
2441                 puts(state);
2442
2443         return nulstr_contains(good_states, state);
2444 }
2445
2446 static int check_triggering_units(
2447                 sd_bus *bus,
2448                 const char *name) {
2449
2450         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2451         _cleanup_free_ char *path = NULL, *n = NULL, *state = NULL;
2452         _cleanup_strv_free_ char **triggered_by = NULL;
2453         bool print_warning_label = true;
2454         char **i;
2455         int r;
2456
2457         n = unit_name_mangle(name, MANGLE_NOGLOB);
2458         if (!n)
2459                 return log_oom();
2460
2461         path = unit_dbus_path_from_name(n);
2462         if (!path)
2463                 return log_oom();
2464
2465         r = sd_bus_get_property_string(
2466                         bus,
2467                         "org.freedesktop.systemd1",
2468                         path,
2469                         "org.freedesktop.systemd1.Unit",
2470                         "LoadState",
2471                         &error,
2472                         &state);
2473         if (r < 0) {
2474                 log_error("Failed to get load state of %s: %s", n, bus_error_message(&error, r));
2475                 return r;
2476         }
2477
2478         if (streq(state, "masked"))
2479                 return 0;
2480
2481         r = sd_bus_get_property_strv(
2482                         bus,
2483                         "org.freedesktop.systemd1",
2484                         path,
2485                         "org.freedesktop.systemd1.Unit",
2486                         "TriggeredBy",
2487                         &error,
2488                         &triggered_by);
2489         if (r < 0) {
2490                 log_error("Failed to get triggered by array of %s: %s", n, bus_error_message(&error, r));
2491                 return r;
2492         }
2493
2494         STRV_FOREACH(i, triggered_by) {
2495                 r = check_one_unit(bus, *i, "active\0reloading\0", true);
2496                 if (r < 0)
2497                         return log_error_errno(r, "Failed to check unit: %m");
2498
2499                 if (r == 0)
2500                         continue;
2501
2502                 if (print_warning_label) {
2503                         log_warning("Warning: Stopping %s, but it can still be activated by:", n);
2504                         print_warning_label = false;
2505                 }
2506
2507                 log_warning("  %s", *i);
2508         }
2509
2510         return 0;
2511 }
2512
2513 static const struct {
2514         const char *verb;
2515         const char *method;
2516 } unit_actions[] = {
2517         { "start",                 "StartUnit" },
2518         { "stop",                  "StopUnit" },
2519         { "condstop",              "StopUnit" },
2520         { "reload",                "ReloadUnit" },
2521         { "restart",               "RestartUnit" },
2522         { "try-restart",           "TryRestartUnit" },
2523         { "condrestart",           "TryRestartUnit" },
2524         { "reload-or-restart",     "ReloadOrRestartUnit" },
2525         { "reload-or-try-restart", "ReloadOrTryRestartUnit" },
2526         { "condreload",            "ReloadOrTryRestartUnit" },
2527         { "force-reload",          "ReloadOrTryRestartUnit" }
2528 };
2529
2530 static const char *verb_to_method(const char *verb) {
2531        uint i;
2532
2533        for (i = 0; i < ELEMENTSOF(unit_actions); i++)
2534                 if (streq_ptr(unit_actions[i].verb, verb))
2535                         return unit_actions[i].method;
2536
2537        return "StartUnit";
2538 }
2539
2540 static const char *method_to_verb(const char *method) {
2541        uint i;
2542
2543        for (i = 0; i < ELEMENTSOF(unit_actions); i++)
2544                 if (streq_ptr(unit_actions[i].method, method))
2545                         return unit_actions[i].verb;
2546
2547        return "n/a";
2548 }
2549
2550 static int start_unit_one(
2551                 sd_bus *bus,
2552                 const char *method,
2553                 const char *name,
2554                 const char *mode,
2555                 sd_bus_error *error,
2556                 BusWaitForJobs *w) {
2557
2558         _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
2559         const char *path;
2560         int r;
2561
2562         assert(method);
2563         assert(name);
2564         assert(mode);
2565         assert(error);
2566
2567         log_debug("Calling manager for %s on %s, %s", method, name, mode);
2568
2569         r = sd_bus_message_new_method_call(
2570                         bus,
2571                         &m,
2572                         "org.freedesktop.systemd1",
2573                         "/org/freedesktop/systemd1",
2574                         "org.freedesktop.systemd1.Manager",
2575                         method);
2576         if (r < 0)
2577                 return bus_log_create_error(r);
2578
2579         r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
2580         if (r < 0)
2581                 return bus_log_create_error(r);
2582
2583         r = sd_bus_message_append(m, "ss", name, mode);
2584         if (r < 0)
2585                 return bus_log_create_error(r);
2586
2587         r = sd_bus_call(bus, m, 0, error, &reply);
2588         if (r < 0) {
2589                 const char *verb;
2590
2591                 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
2592                         /* There's always a fallback possible for
2593                          * legacy actions. */
2594                         return -EADDRNOTAVAIL;
2595
2596                 verb = method_to_verb(method);
2597
2598                 log_error("Failed to %s %s: %s", verb, name, bus_error_message(error, r));
2599                 return r;
2600         }
2601
2602         r = sd_bus_message_read(reply, "o", &path);
2603         if (r < 0)
2604                 return bus_log_parse_error(r);
2605
2606         if (need_daemon_reload(bus, name) > 0)
2607                 warn_unit_file_changed(name);
2608
2609         if (w) {
2610                 log_debug("Adding %s to the set", path);
2611                 r = bus_wait_for_jobs_add(w, path);
2612                 if (r < 0)
2613                         return log_oom();
2614         }
2615
2616         return 0;
2617 }
2618
2619 static int expand_names(sd_bus *bus, char **names, const char* suffix, char ***ret) {
2620
2621         _cleanup_strv_free_ char **mangled = NULL, **globs = NULL;
2622         char **name;
2623         int r = 0, i;
2624
2625         STRV_FOREACH(name, names) {
2626                 char *t;
2627
2628                 if (suffix)
2629                         t = unit_name_mangle_with_suffix(*name, MANGLE_GLOB, suffix);
2630                 else
2631                         t = unit_name_mangle(*name, MANGLE_GLOB);
2632                 if (!t)
2633                         return log_oom();
2634
2635                 if (string_is_glob(t))
2636                         r = strv_consume(&globs, t);
2637                 else
2638                         r = strv_consume(&mangled, t);
2639                 if (r < 0)
2640                         return log_oom();
2641         }
2642
2643         /* Query the manager only if any of the names are a glob, since
2644          * this is fairly expensive */
2645         if (!strv_isempty(globs)) {
2646                 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2647                 _cleanup_free_ UnitInfo *unit_infos = NULL;
2648
2649                 if (!bus)
2650                         return log_error_errno(ENOTSUP, "Unit name globbing without bus is not implemented.");
2651
2652                 r = get_unit_list(bus, NULL, globs, &unit_infos, 0, &reply);
2653                 if (r < 0)
2654                         return r;
2655
2656                 for (i = 0; i < r; i++)
2657                         if (strv_extend(&mangled, unit_infos[i].id) < 0)
2658                                 return log_oom();
2659         }
2660
2661         *ret = mangled;
2662         mangled = NULL; /* do not free */
2663
2664         return 0;
2665 }
2666
2667 static const struct {
2668         const char *target;
2669         const char *verb;
2670         const char *mode;
2671 } action_table[_ACTION_MAX] = {
2672         [ACTION_HALT]         = { SPECIAL_HALT_TARGET,         "halt",         "replace-irreversibly" },
2673         [ACTION_POWEROFF]     = { SPECIAL_POWEROFF_TARGET,     "poweroff",     "replace-irreversibly" },
2674         [ACTION_REBOOT]       = { SPECIAL_REBOOT_TARGET,       "reboot",       "replace-irreversibly" },
2675         [ACTION_KEXEC]        = { SPECIAL_KEXEC_TARGET,        "kexec",        "replace-irreversibly" },
2676         [ACTION_RUNLEVEL2]    = { SPECIAL_RUNLEVEL2_TARGET,    NULL,           "isolate" },
2677         [ACTION_RUNLEVEL3]    = { SPECIAL_RUNLEVEL3_TARGET,    NULL,           "isolate" },
2678         [ACTION_RUNLEVEL4]    = { SPECIAL_RUNLEVEL4_TARGET,    NULL,           "isolate" },
2679         [ACTION_RUNLEVEL5]    = { SPECIAL_RUNLEVEL5_TARGET,    NULL,           "isolate" },
2680         [ACTION_RESCUE]       = { SPECIAL_RESCUE_TARGET,       "rescue",       "isolate" },
2681         [ACTION_EMERGENCY]    = { SPECIAL_EMERGENCY_TARGET,    "emergency",    "isolate" },
2682         [ACTION_DEFAULT]      = { SPECIAL_DEFAULT_TARGET,      "default",      "isolate" },
2683         [ACTION_EXIT]         = { SPECIAL_EXIT_TARGET,         "exit",         "replace-irreversibly" },
2684         [ACTION_SUSPEND]      = { SPECIAL_SUSPEND_TARGET,      "suspend",      "replace-irreversibly" },
2685         [ACTION_HIBERNATE]    = { SPECIAL_HIBERNATE_TARGET,    "hibernate",    "replace-irreversibly" },
2686         [ACTION_HYBRID_SLEEP] = { SPECIAL_HYBRID_SLEEP_TARGET, "hybrid-sleep", "replace-irreversibly" },
2687 };
2688
2689 static enum action verb_to_action(const char *verb) {
2690         enum action i;
2691
2692         for (i = _ACTION_INVALID; i < _ACTION_MAX; i++)
2693                 if (streq_ptr(action_table[i].verb, verb))
2694                         return i;
2695
2696         return _ACTION_INVALID;
2697 }
2698
2699 static int start_unit(sd_bus *bus, char **args) {
2700         _cleanup_(bus_wait_for_jobs_freep) BusWaitForJobs *w = NULL;
2701         const char *method, *mode, *one_name, *suffix = NULL;
2702         _cleanup_strv_free_ char **names = NULL;
2703         char **name;
2704         int r = 0;
2705
2706         assert(bus);
2707
2708         ask_password_agent_open_if_enabled();
2709
2710         if (arg_action == ACTION_SYSTEMCTL) {
2711                 enum action action;
2712                 method = verb_to_method(args[0]);
2713                 action = verb_to_action(args[0]);
2714
2715                 if (streq(args[0], "isolate")) {
2716                         mode = "isolate";
2717                         suffix = ".target";
2718                 } else
2719                         mode = action_table[action].mode ?: arg_job_mode;
2720
2721                 one_name = action_table[action].target;
2722         } else {
2723                 assert(arg_action < ELEMENTSOF(action_table));
2724                 assert(action_table[arg_action].target);
2725
2726                 method = "StartUnit";
2727
2728                 mode = action_table[arg_action].mode;
2729                 one_name = action_table[arg_action].target;
2730         }
2731
2732         if (one_name)
2733                 names = strv_new(one_name, NULL);
2734         else {
2735                 r = expand_names(bus, args + 1, suffix, &names);
2736                 if (r < 0)
2737                         log_error_errno(r, "Failed to expand names: %m");
2738         }
2739
2740         if (!arg_no_block) {
2741                 r = bus_wait_for_jobs_new(bus, &w);
2742                 if (r < 0)
2743                         return log_error_errno(r, "Could not watch jobs: %m");
2744         }
2745
2746         STRV_FOREACH(name, names) {
2747                 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2748                 int q;
2749
2750                 q = start_unit_one(bus, method, *name, mode, &error, w);
2751                 if (r >= 0 && q < 0)
2752                         r = translate_bus_error_to_exit_status(q, &error);
2753         }
2754
2755         if (!arg_no_block) {
2756                 int q;
2757
2758                 q = bus_wait_for_jobs(w, arg_quiet);
2759                 if (q < 0)
2760                         return q;
2761
2762                 /* When stopping units, warn if they can still be triggered by
2763                  * another active unit (socket, path, timer) */
2764                 if (!arg_quiet && streq(method, "StopUnit"))
2765                         STRV_FOREACH(name, names)
2766                                 check_triggering_units(bus, *name);
2767         }
2768
2769         return r;
2770 }
2771
2772 /* Ask systemd-logind, which might grant access to unprivileged users
2773  * through PolicyKit */
2774 static int reboot_with_logind(sd_bus *bus, enum action a) {
2775 #ifdef HAVE_LOGIND
2776         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2777         const char *method;
2778         int r;
2779
2780         if (!bus)
2781                 return -EIO;
2782
2783         polkit_agent_open_if_enabled();
2784
2785         switch (a) {
2786
2787         case ACTION_REBOOT:
2788                 method = "Reboot";
2789                 break;
2790
2791         case ACTION_POWEROFF:
2792                 method = "PowerOff";
2793                 break;
2794
2795         case ACTION_SUSPEND:
2796                 method = "Suspend";
2797                 break;
2798
2799         case ACTION_HIBERNATE:
2800                 method = "Hibernate";
2801                 break;
2802
2803         case ACTION_HYBRID_SLEEP:
2804                 method = "HybridSleep";
2805                 break;
2806
2807         default:
2808                 return -EINVAL;
2809         }
2810
2811         r = sd_bus_call_method(
2812                         bus,
2813                         "org.freedesktop.login1",
2814                         "/org/freedesktop/login1",
2815                         "org.freedesktop.login1.Manager",
2816                         method,
2817                         &error,
2818                         NULL,
2819                         "b", arg_ask_password);
2820         if (r < 0)
2821                 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
2822
2823         return r;
2824 #else
2825         return -ENOSYS;
2826 #endif
2827 }
2828
2829 static int check_inhibitors(sd_bus *bus, enum action a) {
2830 #ifdef HAVE_LOGIND
2831         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2832         _cleanup_strv_free_ char **sessions = NULL;
2833         const char *what, *who, *why, *mode;
2834         uint32_t uid, pid;
2835         unsigned c = 0;
2836         char **s;
2837         int r;
2838
2839         if (!bus)
2840                 return 0;
2841
2842         if (arg_ignore_inhibitors || arg_force > 0)
2843                 return 0;
2844
2845         if (arg_when > 0)
2846                 return 0;
2847
2848         if (geteuid() == 0)
2849                 return 0;
2850
2851         if (!on_tty())
2852                 return 0;
2853
2854         r = sd_bus_call_method(
2855                         bus,
2856                         "org.freedesktop.login1",
2857                         "/org/freedesktop/login1",
2858                         "org.freedesktop.login1.Manager",
2859                         "ListInhibitors",
2860                         NULL,
2861                         &reply,
2862                         NULL);
2863         if (r < 0)
2864                 /* If logind is not around, then there are no inhibitors... */
2865                 return 0;
2866
2867         r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssuu)");
2868         if (r < 0)
2869                 return bus_log_parse_error(r);
2870
2871         while ((r = sd_bus_message_read(reply, "(ssssuu)", &what, &who, &why, &mode, &uid, &pid)) > 0) {
2872                 _cleanup_free_ char *comm = NULL, *user = NULL;
2873                 _cleanup_strv_free_ char **sv = NULL;
2874
2875                 if (!streq(mode, "block"))
2876                         continue;
2877
2878                 sv = strv_split(what, ":");
2879                 if (!sv)
2880                         return log_oom();
2881
2882                 if (!strv_contains(sv,
2883                                   a == ACTION_HALT ||
2884                                   a == ACTION_POWEROFF ||
2885                                   a == ACTION_REBOOT ||
2886                                   a == ACTION_KEXEC ? "shutdown" : "sleep"))
2887                         continue;
2888
2889                 get_process_comm(pid, &comm);
2890                 user = uid_to_name(uid);
2891
2892                 log_warning("Operation inhibited by \"%s\" (PID "PID_FMT" \"%s\", user %s), reason is \"%s\".",
2893                             who, pid, strna(comm), strna(user), why);
2894
2895                 c++;
2896         }
2897         if (r < 0)
2898                 return bus_log_parse_error(r);
2899
2900         r = sd_bus_message_exit_container(reply);
2901         if (r < 0)
2902                 return bus_log_parse_error(r);
2903
2904         /* Check for current sessions */
2905         sd_get_sessions(&sessions);
2906         STRV_FOREACH(s, sessions) {
2907                 _cleanup_free_ char *type = NULL, *tty = NULL, *seat = NULL, *user = NULL, *service = NULL, *class = NULL;
2908
2909                 if (sd_session_get_uid(*s, &uid) < 0 || uid == getuid())
2910                         continue;
2911
2912                 if (sd_session_get_class(*s, &class) < 0 || !streq(class, "user"))
2913                         continue;
2914
2915                 if (sd_session_get_type(*s, &type) < 0 || (!streq(type, "x11") && !streq(type, "tty")))
2916                         continue;
2917
2918                 sd_session_get_tty(*s, &tty);
2919                 sd_session_get_seat(*s, &seat);
2920                 sd_session_get_service(*s, &service);
2921                 user = uid_to_name(uid);
2922
2923                 log_warning("User %s is logged in on %s.", strna(user), isempty(tty) ? (isempty(seat) ? strna(service) : seat) : tty);
2924                 c++;
2925         }
2926
2927         if (c <= 0)
2928                 return 0;
2929
2930         log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
2931                   action_table[a].verb);
2932
2933         return -EPERM;
2934 #else
2935         return 0;
2936 #endif
2937 }
2938
2939 static int start_special(sd_bus *bus, char **args) {
2940         enum action a;
2941         int r;
2942
2943         assert(args);
2944
2945         a = verb_to_action(args[0]);
2946
2947         r = check_inhibitors(bus, a);
2948         if (r < 0)
2949                 return r;
2950
2951         if (arg_force >= 2 && geteuid() != 0) {
2952                 log_error("Must be root.");
2953                 return -EPERM;
2954         }
2955
2956         if (arg_force >= 2 &&
2957             (a == ACTION_HALT ||
2958              a == ACTION_POWEROFF ||
2959              a == ACTION_REBOOT))
2960                 return halt_now(a);
2961
2962         if (arg_force >= 1 &&
2963             (a == ACTION_HALT ||
2964              a == ACTION_POWEROFF ||
2965              a == ACTION_REBOOT ||
2966              a == ACTION_KEXEC ||
2967              a == ACTION_EXIT))
2968                 return daemon_reload(bus, args);
2969
2970         /* first try logind, to allow authentication with polkit */
2971         if (geteuid() != 0 &&
2972             (a == ACTION_POWEROFF ||
2973              a == ACTION_REBOOT ||
2974              a == ACTION_SUSPEND ||
2975              a == ACTION_HIBERNATE ||
2976              a == ACTION_HYBRID_SLEEP)) {
2977                 r = reboot_with_logind(bus, a);
2978                 if (r >= 0 || IN_SET(r, -ENOTSUP, -EINPROGRESS))
2979                         return r;
2980         }
2981
2982         r = start_unit(bus, args);
2983         if (r == EXIT_SUCCESS)
2984                 warn_wall(a);
2985
2986         return r;
2987 }
2988
2989 static int check_unit_generic(sd_bus *bus, int code, const char *good_states, char **args) {
2990         _cleanup_strv_free_ char **names = NULL;
2991         char **name;
2992         int r;
2993
2994         assert(bus);
2995         assert(args);
2996
2997         r = expand_names(bus, args, NULL, &names);
2998         if (r < 0)
2999                 return log_error_errno(r, "Failed to expand names: %m");
3000
3001         STRV_FOREACH(name, names) {
3002                 int state;
3003
3004                 state = check_one_unit(bus, *name, good_states, arg_quiet);
3005                 if (state < 0)
3006                         return state;
3007                 if (state == 0)
3008                         r = code;
3009         }
3010
3011         return r;
3012 }
3013
3014 static int check_unit_active(sd_bus *bus, char **args) {
3015         /* According to LSB: 3, "program is not running" */
3016         return check_unit_generic(bus, 3, "active\0reloading\0", args + 1);
3017 }
3018
3019 static int check_unit_failed(sd_bus *bus, char **args) {
3020         return check_unit_generic(bus, 1, "failed\0", args + 1);
3021 }
3022
3023 static int kill_unit(sd_bus *bus, char **args) {
3024         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3025         _cleanup_strv_free_ char **names = NULL;
3026         char **name;
3027         int r, q;
3028
3029         assert(bus);
3030         assert(args);
3031
3032         if (!arg_kill_who)
3033                 arg_kill_who = "all";
3034
3035         r = expand_names(bus, args + 1, NULL, &names);
3036         if (r < 0)
3037                 log_error_errno(r, "Failed to expand names: %m");
3038
3039         STRV_FOREACH(name, names) {
3040                 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
3041
3042                 q = sd_bus_message_new_method_call(
3043                                 bus,
3044                                 &m,
3045                                 "org.freedesktop.systemd1",
3046                                 "/org/freedesktop/systemd1",
3047                                 "org.freedesktop.systemd1.Manager",
3048                                 "KillUnit");
3049                 if (q < 0)
3050                         return bus_log_create_error(q);
3051
3052                 q = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
3053                 if (q < 0)
3054                         return bus_log_create_error(q);
3055
3056                 q = sd_bus_message_append(m, "ssi", *names, arg_kill_who, arg_signal);
3057                 if (q < 0)
3058                         return bus_log_create_error(q);
3059
3060                 q = sd_bus_call(bus, m, 0, &error, NULL);
3061                 if (q < 0) {
3062                         log_error("Failed to kill unit %s: %s", *names, bus_error_message(&error, q));
3063                         if (r == 0)
3064                                 r = q;
3065                 }
3066         }
3067
3068         return r;
3069 }
3070
3071 typedef struct ExecStatusInfo {
3072         char *name;
3073
3074         char *path;
3075         char **argv;
3076
3077         bool ignore;
3078
3079         usec_t start_timestamp;
3080         usec_t exit_timestamp;
3081         pid_t pid;
3082         int code;
3083         int status;
3084
3085         LIST_FIELDS(struct ExecStatusInfo, exec);
3086 } ExecStatusInfo;
3087
3088 static void exec_status_info_free(ExecStatusInfo *i) {
3089         assert(i);
3090
3091         free(i->name);
3092         free(i->path);
3093         strv_free(i->argv);
3094         free(i);
3095 }
3096
3097 static int exec_status_info_deserialize(sd_bus_message *m, ExecStatusInfo *i) {
3098         uint64_t start_timestamp, exit_timestamp, start_timestamp_monotonic, exit_timestamp_monotonic;
3099         const char *path;
3100         uint32_t pid;
3101         int32_t code, status;
3102         int ignore, r;
3103
3104         assert(m);
3105         assert(i);
3106
3107         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_STRUCT, "sasbttttuii");
3108         if (r < 0)
3109                 return bus_log_parse_error(r);
3110         else if (r == 0)
3111                 return 0;
3112
3113         r = sd_bus_message_read(m, "s", &path);
3114         if (r < 0)
3115                 return bus_log_parse_error(r);
3116
3117         i->path = strdup(path);
3118         if (!i->path)
3119                 return log_oom();
3120
3121         r = sd_bus_message_read_strv(m, &i->argv);
3122         if (r < 0)
3123                 return bus_log_parse_error(r);
3124
3125         r = sd_bus_message_read(m,
3126                                 "bttttuii",
3127                                 &ignore,
3128                                 &start_timestamp, &start_timestamp_monotonic,
3129                                 &exit_timestamp, &exit_timestamp_monotonic,
3130                                 &pid,
3131                                 &code, &status);
3132         if (r < 0)
3133                 return bus_log_parse_error(r);
3134
3135         i->ignore = ignore;
3136         i->start_timestamp = (usec_t) start_timestamp;
3137         i->exit_timestamp = (usec_t) exit_timestamp;
3138         i->pid = (pid_t) pid;
3139         i->code = code;
3140         i->status = status;
3141
3142         r = sd_bus_message_exit_container(m);
3143         if (r < 0)
3144                 return bus_log_parse_error(r);
3145
3146         return 1;
3147 }
3148
3149 typedef struct UnitStatusInfo {
3150         const char *id;
3151         const char *load_state;
3152         const char *active_state;
3153         const char *sub_state;
3154         const char *unit_file_state;
3155         const char *unit_file_preset;
3156
3157         const char *description;
3158         const char *following;
3159
3160         char **documentation;
3161