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