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