chiark / gitweb /
67bc42660e6f9ed2ea26d8cc9260a13ae65bb121
[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], MANGLE_NOGLOB);
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], MANGLE_NOGLOB, ".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, MANGLE_NOGLOB);
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, MANGLE_NOGLOB);
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, MANGLE_GLOB, suffix);
2115                 else
2116                         t = unit_name_mangle(*name, MANGLE_GLOB);
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_strv_free_ char **names = NULL;
2490         char **name;
2491         int r = code;
2492
2493         assert(bus);
2494         assert(args);
2495
2496         r = expand_names(bus, args, NULL, &names);
2497         if (r < 0)
2498                 log_error("Failed to expand names: %s", strerror(-r));
2499
2500         STRV_FOREACH(name, names) {
2501                 int state;
2502
2503                 state = check_one_unit(bus, *name, good_states, arg_quiet);
2504                 if (state < 0)
2505                         return state;
2506                 if (state > 0)
2507                         r = 0;
2508         }
2509
2510         return r;
2511 }
2512
2513 static int check_unit_active(sd_bus *bus, char **args) {
2514         /* According to LSB: 3, "program is not running" */
2515         return check_unit_generic(bus, 3, "active\0reloading\0", args + 1);
2516 }
2517
2518 static int check_unit_failed(sd_bus *bus, char **args) {
2519         return check_unit_generic(bus, 1, "failed\0", args + 1);
2520 }
2521
2522 static int kill_unit(sd_bus *bus, char **args) {
2523         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2524         _cleanup_strv_free_ char **names = NULL;
2525         char **name;
2526         int r, q;
2527
2528         assert(bus);
2529         assert(args);
2530
2531         if (!arg_kill_who)
2532                 arg_kill_who = "all";
2533
2534         r = expand_names(bus, args + 1, NULL, &names);
2535         if (r < 0)
2536                 log_error("Failed to expand names: %s", strerror(-r));
2537
2538         STRV_FOREACH(name, names) {
2539                 q = sd_bus_call_method(
2540                                 bus,
2541                                 "org.freedesktop.systemd1",
2542                                 "/org/freedesktop/systemd1",
2543                                 "org.freedesktop.systemd1.Manager",
2544                                 "KillUnit",
2545                                 &error,
2546                                 NULL,
2547                                 "ssi", *names, arg_kill_who, arg_signal);
2548                 if (q < 0) {
2549                         log_error("Failed to kill unit %s: %s",
2550                                   *names, bus_error_message(&error, r));
2551                         if (r == 0)
2552                                 r = q;
2553                 }
2554         }
2555
2556         return r;
2557 }
2558
2559 typedef struct ExecStatusInfo {
2560         char *name;
2561
2562         char *path;
2563         char **argv;
2564
2565         bool ignore;
2566
2567         usec_t start_timestamp;
2568         usec_t exit_timestamp;
2569         pid_t pid;
2570         int code;
2571         int status;
2572
2573         LIST_FIELDS(struct ExecStatusInfo, exec);
2574 } ExecStatusInfo;
2575
2576 static void exec_status_info_free(ExecStatusInfo *i) {
2577         assert(i);
2578
2579         free(i->name);
2580         free(i->path);
2581         strv_free(i->argv);
2582         free(i);
2583 }
2584
2585 static int exec_status_info_deserialize(sd_bus_message *m, ExecStatusInfo *i) {
2586         uint64_t start_timestamp, exit_timestamp, start_timestamp_monotonic, exit_timestamp_monotonic;
2587         const char *path;
2588         uint32_t pid;
2589         int32_t code, status;
2590         int ignore, r;
2591
2592         assert(m);
2593         assert(i);
2594
2595         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_STRUCT, "sasbttttuii");
2596         if (r < 0)
2597                 return bus_log_parse_error(r);
2598         else if (r == 0)
2599                 return 0;
2600
2601         r = sd_bus_message_read(m, "s", &path);
2602         if (r < 0)
2603                 return bus_log_parse_error(r);
2604
2605         i->path = strdup(path);
2606         if (!i->path)
2607                 return log_oom();
2608
2609         r = sd_bus_message_read_strv(m, &i->argv);
2610         if (r < 0)
2611                 return bus_log_parse_error(r);
2612
2613         r = sd_bus_message_read(m,
2614                                 "bttttuii",
2615                                 &ignore,
2616                                 &start_timestamp, &start_timestamp_monotonic,
2617                                 &exit_timestamp, &exit_timestamp_monotonic,
2618                                 &pid,
2619                                 &code, &status);
2620         if (r < 0)
2621                 return bus_log_parse_error(r);
2622
2623         i->ignore = ignore;
2624         i->start_timestamp = (usec_t) start_timestamp;
2625         i->exit_timestamp = (usec_t) exit_timestamp;
2626         i->pid = (pid_t) pid;
2627         i->code = code;
2628         i->status = status;
2629
2630         r = sd_bus_message_exit_container(m);
2631         if (r < 0)
2632                 return bus_log_parse_error(r);
2633
2634         return 1;
2635 }
2636
2637 typedef struct UnitStatusInfo {
2638         const char *id;
2639         const char *load_state;
2640         const char *active_state;
2641         const char *sub_state;
2642         const char *unit_file_state;
2643
2644         const char *description;
2645         const char *following;
2646
2647         char **documentation;
2648
2649         const char *fragment_path;
2650         const char *source_path;
2651         const char *control_group;
2652
2653         char **dropin_paths;
2654
2655         const char *load_error;
2656         const char *result;
2657
2658         usec_t inactive_exit_timestamp;
2659         usec_t inactive_exit_timestamp_monotonic;
2660         usec_t active_enter_timestamp;
2661         usec_t active_exit_timestamp;
2662         usec_t inactive_enter_timestamp;
2663
2664         bool need_daemon_reload;
2665
2666         /* Service */
2667         pid_t main_pid;
2668         pid_t control_pid;
2669         const char *status_text;
2670         const char *pid_file;
2671         bool running:1;
2672
2673         usec_t start_timestamp;
2674         usec_t exit_timestamp;
2675
2676         int exit_code, exit_status;
2677
2678         usec_t condition_timestamp;
2679         bool condition_result;
2680         bool failed_condition_trigger;
2681         bool failed_condition_negate;
2682         const char *failed_condition;
2683         const char *failed_condition_param;
2684
2685         /* Socket */
2686         unsigned n_accepted;
2687         unsigned n_connections;
2688         bool accept;
2689
2690         /* Pairs of type, path */
2691         char **listen;
2692
2693         /* Device */
2694         const char *sysfs_path;
2695
2696         /* Mount, Automount */
2697         const char *where;
2698
2699         /* Swap */
2700         const char *what;
2701
2702         LIST_HEAD(ExecStatusInfo, exec);
2703 } UnitStatusInfo;
2704
2705 static void print_status_info(
2706                 UnitStatusInfo *i,
2707                 bool *ellipsized) {
2708
2709         ExecStatusInfo *p;
2710         const char *on, *off, *ss;
2711         usec_t timestamp;
2712         char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
2713         char since2[FORMAT_TIMESTAMP_MAX], *s2;
2714         const char *path;
2715         int flags =
2716                 arg_all * OUTPUT_SHOW_ALL |
2717                 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
2718                 on_tty() * OUTPUT_COLOR |
2719                 !arg_quiet * OUTPUT_WARN_CUTOFF |
2720                 arg_full * OUTPUT_FULL_WIDTH;
2721         char **t, **t2;
2722
2723         assert(i);
2724
2725         /* This shows pretty information about a unit. See
2726          * print_property() for a low-level property printer */
2727
2728         printf("%s", strna(i->id));
2729
2730         if (i->description && !streq_ptr(i->id, i->description))
2731                 printf(" - %s", i->description);
2732
2733         printf("\n");
2734
2735         if (i->following)
2736                 printf("   Follow: unit currently follows state of %s\n", i->following);
2737
2738         if (streq_ptr(i->load_state, "error")) {
2739                 on = ansi_highlight_red();
2740                 off = ansi_highlight_off();
2741         } else
2742                 on = off = "";
2743
2744         path = i->source_path ? i->source_path : i->fragment_path;
2745
2746         if (i->load_error)
2747                 printf("   Loaded: %s%s%s (Reason: %s)\n",
2748                        on, strna(i->load_state), off, i->load_error);
2749         else if (path && i->unit_file_state)
2750                 printf("   Loaded: %s%s%s (%s; %s)\n",
2751                        on, strna(i->load_state), off, path, i->unit_file_state);
2752         else if (path)
2753                 printf("   Loaded: %s%s%s (%s)\n",
2754                        on, strna(i->load_state), off, path);
2755         else
2756                 printf("   Loaded: %s%s%s\n",
2757                        on, strna(i->load_state), off);
2758
2759         if (!strv_isempty(i->dropin_paths)) {
2760                 _cleanup_free_ char *dir = NULL;
2761                 bool last = false;
2762                 char ** dropin;
2763
2764                 STRV_FOREACH(dropin, i->dropin_paths) {
2765                         if (! dir || last) {
2766                                 printf(dir ? "        " : "  Drop-In: ");
2767
2768                                 free(dir);
2769                                 dir = NULL;
2770
2771                                 if (path_get_parent(*dropin, &dir) < 0) {
2772                                         log_oom();
2773                                         return;
2774                                 }
2775
2776                                 printf("%s\n           %s", dir,
2777                                        draw_special_char(DRAW_TREE_RIGHT));
2778                         }
2779
2780                         last = ! (*(dropin + 1) && startswith(*(dropin + 1), dir));
2781
2782                         printf("%s%s", basename(*dropin), last ? "\n" : ", ");
2783                 }
2784         }
2785
2786         ss = streq_ptr(i->active_state, i->sub_state) ? NULL : i->sub_state;
2787
2788         if (streq_ptr(i->active_state, "failed")) {
2789                 on = ansi_highlight_red();
2790                 off = ansi_highlight_off();
2791         } else if (streq_ptr(i->active_state, "active") || streq_ptr(i->active_state, "reloading")) {
2792                 on = ansi_highlight_green();
2793                 off = ansi_highlight_off();
2794         } else
2795                 on = off = "";
2796
2797         if (ss)
2798                 printf("   Active: %s%s (%s)%s",
2799                        on, strna(i->active_state), ss, off);
2800         else
2801                 printf("   Active: %s%s%s",
2802                        on, strna(i->active_state), off);
2803
2804         if (!isempty(i->result) && !streq(i->result, "success"))
2805                 printf(" (Result: %s)", i->result);
2806
2807         timestamp = (streq_ptr(i->active_state, "active")      ||
2808                      streq_ptr(i->active_state, "reloading"))   ? i->active_enter_timestamp :
2809                     (streq_ptr(i->active_state, "inactive")    ||
2810                      streq_ptr(i->active_state, "failed"))      ? i->inactive_enter_timestamp :
2811                     streq_ptr(i->active_state, "activating")    ? i->inactive_exit_timestamp :
2812                                                                   i->active_exit_timestamp;
2813
2814         s1 = format_timestamp_relative(since1, sizeof(since1), timestamp);
2815         s2 = format_timestamp(since2, sizeof(since2), timestamp);
2816
2817         if (s1)
2818                 printf(" since %s; %s\n", s2, s1);
2819         else if (s2)
2820                 printf(" since %s\n", s2);
2821         else
2822                 printf("\n");
2823
2824         if (!i->condition_result && i->condition_timestamp > 0) {
2825                 s1 = format_timestamp_relative(since1, sizeof(since1), i->condition_timestamp);
2826                 s2 = format_timestamp(since2, sizeof(since2), i->condition_timestamp);
2827
2828                 printf("           start condition failed at %s%s%s\n",
2829                        s2, s1 ? "; " : "", s1 ? s1 : "");
2830                 if (i->failed_condition_trigger)
2831                         printf("           none of the trigger conditions were met\n");
2832                 else if (i->failed_condition)
2833                         printf("           %s=%s%s was not met\n",
2834                                i->failed_condition,
2835                                i->failed_condition_negate ? "!" : "",
2836                                i->failed_condition_param);
2837         }
2838
2839         if (i->sysfs_path)
2840                 printf("   Device: %s\n", i->sysfs_path);
2841         if (i->where)
2842                 printf("    Where: %s\n", i->where);
2843         if (i->what)
2844                 printf("     What: %s\n", i->what);
2845
2846         STRV_FOREACH(t, i->documentation)
2847                 printf(" %*s %s\n", 9, t == i->documentation ? "Docs:" : "", *t);
2848
2849         STRV_FOREACH_PAIR(t, t2, i->listen)
2850                 printf(" %*s %s (%s)\n", 9, t == i->listen ? "Listen:" : "", *t2, *t);
2851
2852         if (i->accept)
2853                 printf(" Accepted: %u; Connected: %u\n", i->n_accepted, i->n_connections);
2854
2855         LIST_FOREACH(exec, p, i->exec) {
2856                 _cleanup_free_ char *argv = NULL;
2857                 bool good;
2858
2859                 /* Only show exited processes here */
2860                 if (p->code == 0)
2861                         continue;
2862
2863                 argv = strv_join(p->argv, " ");
2864                 printf("  Process: %u %s=%s ", p->pid, p->name, strna(argv));
2865
2866                 good = is_clean_exit_lsb(p->code, p->status, NULL);
2867                 if (!good) {
2868                         on = ansi_highlight_red();
2869                         off = ansi_highlight_off();
2870                 } else
2871                         on = off = "";
2872
2873                 printf("%s(code=%s, ", on, sigchld_code_to_string(p->code));
2874
2875                 if (p->code == CLD_EXITED) {
2876                         const char *c;
2877
2878                         printf("status=%i", p->status);
2879
2880                         c = exit_status_to_string(p->status, EXIT_STATUS_SYSTEMD);
2881                         if (c)
2882                                 printf("/%s", c);
2883
2884                 } else
2885                         printf("signal=%s", signal_to_string(p->status));
2886
2887                 printf(")%s\n", off);
2888
2889                 if (i->main_pid == p->pid &&
2890                     i->start_timestamp == p->start_timestamp &&
2891                     i->exit_timestamp == p->start_timestamp)
2892                         /* Let's not show this twice */
2893                         i->main_pid = 0;
2894
2895                 if (p->pid == i->control_pid)
2896                         i->control_pid = 0;
2897         }
2898
2899         if (i->main_pid > 0 || i->control_pid > 0) {
2900                 if (i->main_pid > 0) {
2901                         printf(" Main PID: %u", (unsigned) i->main_pid);
2902
2903                         if (i->running) {
2904                                 _cleanup_free_ char *comm = NULL;
2905                                 get_process_comm(i->main_pid, &comm);
2906                                 if (comm)
2907                                         printf(" (%s)", comm);
2908                         } else if (i->exit_code > 0) {
2909                                 printf(" (code=%s, ", sigchld_code_to_string(i->exit_code));
2910
2911                                 if (i->exit_code == CLD_EXITED) {
2912                                         const char *c;
2913
2914                                         printf("status=%i", i->exit_status);
2915
2916                                         c = exit_status_to_string(i->exit_status, EXIT_STATUS_SYSTEMD);
2917                                         if (c)
2918                                                 printf("/%s", c);
2919
2920                                 } else
2921                                         printf("signal=%s", signal_to_string(i->exit_status));
2922                                 printf(")");
2923                         }
2924
2925                         if (i->control_pid > 0)
2926                                 printf(";");
2927                 }
2928
2929                 if (i->control_pid > 0) {
2930                         _cleanup_free_ char *c = NULL;
2931
2932                         printf(" %8s: %u", i->main_pid ? "" : " Control", (unsigned) i->control_pid);
2933
2934                         get_process_comm(i->control_pid, &c);
2935                         if (c)
2936                                 printf(" (%s)", c);
2937                 }
2938
2939                 printf("\n");
2940         }
2941
2942         if (i->status_text)
2943                 printf("   Status: \"%s\"\n", i->status_text);
2944
2945         if (i->control_group &&
2946             (i->main_pid > 0 || i->control_pid > 0 || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, i->control_group, false) == 0)) {
2947                 unsigned c;
2948
2949                 printf("   CGroup: %s\n", i->control_group);
2950
2951                 if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_CONTAINER) {
2952                         unsigned k = 0;
2953                         pid_t extra[2];
2954                         char prefix[] = "           ";
2955
2956                         c = columns();
2957                         if (c > sizeof(prefix) - 1)
2958                                 c -= sizeof(prefix) - 1;
2959                         else
2960                                 c = 0;
2961
2962                         if (i->main_pid > 0)
2963                                 extra[k++] = i->main_pid;
2964
2965                         if (i->control_pid > 0)
2966                                 extra[k++] = i->control_pid;
2967
2968                         show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, i->control_group, prefix,
2969                                                       c, false, extra, k, flags);
2970                 }
2971         }
2972
2973         if (i->id && arg_transport == BUS_TRANSPORT_LOCAL) {
2974                 printf("\n");
2975                 show_journal_by_unit(stdout,
2976                                      i->id,
2977                                      arg_output,
2978                                      0,
2979                                      i->inactive_exit_timestamp_monotonic,
2980                                      arg_lines,
2981                                      getuid(),
2982                                      flags,
2983                                      arg_scope == UNIT_FILE_SYSTEM,
2984                                      ellipsized);
2985         }
2986
2987         if (i->need_daemon_reload)
2988                 printf("\n%sWarning:%s Unit file changed on disk, 'systemctl %sdaemon-reload' recommended.\n",
2989                        ansi_highlight_red(),
2990                        ansi_highlight_off(),
2991                        arg_scope == UNIT_FILE_SYSTEM ? "" : "--user ");
2992 }
2993
2994 static void show_unit_help(UnitStatusInfo *i) {
2995         char **p;
2996
2997         assert(i);
2998
2999         if (!i->documentation) {
3000                 log_info("Documentation for %s not known.", i->id);
3001                 return;
3002         }
3003
3004         STRV_FOREACH(p, i->documentation) {
3005
3006                 if (startswith(*p, "man:")) {
3007                         const char *args[4] = { "man", NULL, NULL, NULL };
3008                         _cleanup_free_ char *page = NULL, *section = NULL;
3009                         char *e = NULL;
3010                         pid_t pid;
3011                         size_t k;
3012
3013                         k = strlen(*p);
3014
3015                         if ((*p)[k-1] == ')')
3016                                 e = strrchr(*p, '(');
3017
3018                         if (e) {
3019                                 page = strndup((*p) + 4, e - *p - 4);
3020                                 section = strndup(e + 1, *p + k - e - 2);
3021                                 if (!page || !section) {
3022                                         log_oom();
3023                                         return;
3024                                 }
3025
3026                                 args[1] = section;
3027                                 args[2] = page;
3028                         } else
3029                                 args[1] = *p + 4;
3030
3031                         pid = fork();
3032                         if (pid < 0) {
3033                                 log_error("Failed to fork: %m");
3034                                 continue;
3035                         }
3036
3037                         if (pid == 0) {
3038                                 /* Child */
3039                                 execvp(args[0], (char**) args);
3040                                 log_error("Failed to execute man: %m");
3041                                 _exit(EXIT_FAILURE);
3042                         }
3043
3044                         wait_for_terminate(pid, NULL);
3045                 } else
3046                         log_info("Can't show: %s", *p);
3047         }
3048 }
3049
3050 static int status_property(const char *name, sd_bus_message *m, UnitStatusInfo *i, const char *contents) {
3051         int r;
3052
3053         assert(name);
3054         assert(m);
3055         assert(i);
3056
3057         switch (contents[0]) {
3058
3059         case SD_BUS_TYPE_STRING: {
3060                 const char *s;
3061
3062                 r = sd_bus_message_read(m, "s", &s);
3063                 if (r < 0)
3064                         return bus_log_parse_error(r);
3065
3066                 if (!isempty(s)) {
3067                         if (streq(name, "Id"))
3068                                 i->id = s;
3069                         else if (streq(name, "LoadState"))
3070                                 i->load_state = s;
3071                         else if (streq(name, "ActiveState"))
3072                                 i->active_state = s;
3073                         else if (streq(name, "SubState"))
3074                                 i->sub_state = s;
3075                         else if (streq(name, "Description"))
3076                                 i->description = s;
3077                         else if (streq(name, "FragmentPath"))
3078                                 i->fragment_path = s;
3079                         else if (streq(name, "SourcePath"))
3080                                 i->source_path = s;
3081 #ifndef NOLEGACY
3082                         else if (streq(name, "DefaultControlGroup")) {
3083                                 const char *e;
3084                                 e = startswith(s, SYSTEMD_CGROUP_CONTROLLER ":");
3085                                 if (e)
3086                                         i->control_group = e;
3087                         }
3088 #endif
3089                         else if (streq(name, "ControlGroup"))
3090                                 i->control_group = s;
3091                         else if (streq(name, "StatusText"))
3092                                 i->status_text = s;
3093                         else if (streq(name, "PIDFile"))
3094                                 i->pid_file = s;
3095                         else if (streq(name, "SysFSPath"))
3096                                 i->sysfs_path = s;
3097                         else if (streq(name, "Where"))
3098                                 i->where = s;
3099                         else if (streq(name, "What"))
3100                                 i->what = s;
3101                         else if (streq(name, "Following"))
3102                                 i->following = s;
3103                         else if (streq(name, "UnitFileState"))
3104                                 i->unit_file_state = s;
3105                         else if (streq(name, "Result"))
3106                                 i->result = s;
3107                 }
3108
3109                 break;
3110         }
3111
3112         case SD_BUS_TYPE_BOOLEAN: {
3113                 int b;
3114
3115                 r = sd_bus_message_read(m, "b", &b);
3116                 if (r < 0)
3117                         return bus_log_parse_error(r);
3118
3119                 if (streq(name, "Accept"))
3120                         i->accept = b;
3121                 else if (streq(name, "NeedDaemonReload"))
3122                         i->need_daemon_reload = b;
3123                 else if (streq(name, "ConditionResult"))
3124                         i->condition_result = b;
3125
3126                 break;
3127         }
3128
3129         case SD_BUS_TYPE_UINT32: {
3130                 uint32_t u;
3131
3132                 r = sd_bus_message_read(m, "u", &u);
3133                 if (r < 0)
3134                         return bus_log_parse_error(r);
3135
3136                 if (streq(name, "MainPID")) {
3137                         if (u > 0) {
3138                                 i->main_pid = (pid_t) u;
3139                                 i->running = true;
3140                         }
3141                 } else if (streq(name, "ControlPID"))
3142                         i->control_pid = (pid_t) u;
3143                 else if (streq(name, "ExecMainPID")) {
3144                         if (u > 0)
3145                                 i->main_pid = (pid_t) u;
3146                 } else if (streq(name, "NAccepted"))
3147                         i->n_accepted = u;
3148                 else if (streq(name, "NConnections"))
3149                         i->n_connections = u;
3150
3151                 break;
3152         }
3153
3154         case SD_BUS_TYPE_INT32: {
3155                 int32_t j;
3156
3157                 r = sd_bus_message_read(m, "i", &j);
3158                 if (r < 0)
3159                         return bus_log_parse_error(r);
3160
3161                 if (streq(name, "ExecMainCode"))
3162                         i->exit_code = (int) j;
3163                 else if (streq(name, "ExecMainStatus"))
3164                         i->exit_status = (int) j;
3165
3166                 break;
3167         }
3168
3169         case SD_BUS_TYPE_UINT64: {
3170                 uint64_t u;
3171
3172                 r = sd_bus_message_read(m, "t", &u);
3173                 if (r < 0)
3174                         return bus_log_parse_error(r);
3175
3176                 if (streq(name, "ExecMainStartTimestamp"))
3177                         i->start_timestamp = (usec_t) u;
3178                 else if (streq(name, "ExecMainExitTimestamp"))
3179                         i->exit_timestamp = (usec_t) u;
3180                 else if (streq(name, "ActiveEnterTimestamp"))
3181                         i->active_enter_timestamp = (usec_t) u;
3182                 else if (streq(name, "InactiveEnterTimestamp"))
3183                         i->inactive_enter_timestamp = (usec_t) u;
3184                 else if (streq(name, "InactiveExitTimestamp"))
3185                         i->inactive_exit_timestamp = (usec_t) u;
3186                 else if (streq(name, "InactiveExitTimestampMonotonic"))
3187                         i->inactive_exit_timestamp_monotonic = (usec_t) u;
3188                 else if (streq(name, "ActiveExitTimestamp"))
3189                         i->active_exit_timestamp = (usec_t) u;
3190                 else if (streq(name, "ConditionTimestamp"))
3191                         i->condition_timestamp = (usec_t) u;
3192
3193                 break;
3194         }
3195
3196         case SD_BUS_TYPE_ARRAY:
3197
3198                 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3199                         _cleanup_free_ ExecStatusInfo *info = NULL;
3200
3201                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3202                         if (r < 0)
3203                                 return bus_log_parse_error(r);
3204
3205                         info = new0(ExecStatusInfo, 1);
3206                         if (!info)
3207                                 return log_oom();
3208
3209                         while ((r = exec_status_info_deserialize(m, info)) > 0) {
3210
3211                                 info->name = strdup(name);
3212                                 if (!info->name)
3213                                         log_oom();
3214
3215                                 LIST_PREPEND(exec, i->exec, info);
3216
3217                                 info = new0(ExecStatusInfo, 1);
3218                                 if (!info)
3219                                         log_oom();
3220                         }
3221
3222                         if (r < 0)
3223                                 return bus_log_parse_error(r);
3224
3225                         r = sd_bus_message_exit_container(m);
3226                         if (r < 0)
3227                                 return bus_log_parse_error(r);
3228
3229                         return 0;
3230
3231                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3232                         const char *type, *path;
3233
3234                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3235                         if (r < 0)
3236                                 return bus_log_parse_error(r);
3237
3238                         while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0) {
3239
3240                                 r = strv_extend(&i->listen, type);
3241                                 if (r < 0)
3242                                         return r;
3243
3244                                 r = strv_extend(&i->listen, path);
3245                                 if (r < 0)
3246                                         return r;
3247                         }
3248                         if (r < 0)
3249                                 return bus_log_parse_error(r);
3250
3251                         r = sd_bus_message_exit_container(m);
3252                         if (r < 0)
3253                                 return bus_log_parse_error(r);
3254
3255                         return 0;
3256
3257                 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "DropInPaths")) {
3258
3259                         r = sd_bus_message_read_strv(m, &i->dropin_paths);
3260                         if (r < 0)
3261                                 return bus_log_parse_error(r);
3262
3263                 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Documentation")) {
3264
3265                         r = sd_bus_message_read_strv(m, &i->documentation);
3266                         if (r < 0)
3267                                 return bus_log_parse_error(r);
3268
3269                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Conditions")) {
3270                         const char *cond, *param;
3271                         int trigger, negate;
3272                         int32_t state;
3273
3274                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
3275                         if (r < 0)
3276                                 return bus_log_parse_error(r);
3277
3278                         while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, &param, &state)) > 0) {
3279                                 log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
3280                                 if (state < 0 && (!trigger || !i->failed_condition)) {
3281                                         i->failed_condition = cond;
3282                                         i->failed_condition_trigger = trigger;
3283                                         i->failed_condition_negate = negate;
3284                                         i->failed_condition_param = param;
3285                                 }
3286                         }
3287                         if (r < 0)
3288                                 return bus_log_parse_error(r);
3289
3290                         r = sd_bus_message_exit_container(m);
3291                         if (r < 0)
3292                                 return bus_log_parse_error(r);
3293
3294                 } else
3295                         goto skip;
3296
3297                 break;
3298
3299         case SD_BUS_TYPE_STRUCT_BEGIN:
3300
3301                 if (streq(name, "LoadError")) {
3302                         const char *n, *message;
3303
3304                         r = sd_bus_message_read(m, "(ss)", &n, &message);
3305                         if (r < 0)
3306                                 return bus_log_parse_error(r);
3307
3308                         if (!isempty(message))
3309                                 i->load_error = message;
3310                 } else
3311                         goto skip;
3312
3313                 break;
3314
3315         default:
3316                 goto skip;
3317         }
3318
3319         return 0;
3320
3321 skip:
3322         r = sd_bus_message_skip(m, contents);
3323         if (r < 0)
3324                 return bus_log_parse_error(r);
3325
3326         return 0;
3327 }
3328
3329 static int print_property(const char *name, sd_bus_message *m, const char *contents) {
3330         int r;
3331
3332         assert(name);
3333         assert(m);
3334
3335         /* This is a low-level property printer, see
3336          * print_status_info() for the nicer output */
3337
3338         if (arg_properties && !strv_find(arg_properties, name)) {
3339                 /* skip what we didn't read */
3340                 r = sd_bus_message_skip(m, contents);
3341                 return r;
3342         }
3343
3344         switch (contents[0]) {
3345
3346         case SD_BUS_TYPE_STRUCT_BEGIN:
3347
3348                 if (contents[1] == SD_BUS_TYPE_UINT32 && streq(name, "Job")) {
3349                         uint32_t u;
3350
3351                         r = sd_bus_message_read(m, "(uo)", &u, NULL);
3352                         if (r < 0)
3353                                 return bus_log_parse_error(r);
3354
3355                         if (u > 0)
3356                                 printf("%s=%u\n", name, (unsigned) u);
3357                         else if (arg_all)
3358                                 printf("%s=\n", name);
3359
3360                         return 0;
3361
3362                 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Unit")) {
3363                         const char *s;
3364
3365                         r = sd_bus_message_read(m, "(so)", &s, NULL);
3366                         if (r < 0)
3367                                 return bus_log_parse_error(r);
3368
3369                         if (arg_all || !isempty(s))
3370                                 printf("%s=%s\n", name, s);
3371
3372                         return 0;
3373
3374                 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "LoadError")) {
3375                         const char *a = NULL, *b = NULL;
3376
3377                         r = sd_bus_message_read(m, "(ss)", &a, &b);
3378                         if (r < 0)
3379                                 return bus_log_parse_error(r);
3380
3381                         if (arg_all || !isempty(a) || !isempty(b))
3382                                 printf("%s=%s \"%s\"\n", name, strempty(a), strempty(b));
3383
3384                         return 0;
3385                 }
3386
3387                 break;
3388
3389         case SD_BUS_TYPE_ARRAY:
3390
3391                 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "EnvironmentFiles")) {
3392                         const char *path;
3393                         int ignore;
3394
3395                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sb)");
3396                         if (r < 0)
3397                                 return bus_log_parse_error(r);
3398
3399                         while ((r = sd_bus_message_read(m, "(sb)", &path, &ignore)) > 0)
3400                                 printf("EnvironmentFile=%s (ignore_errors=%s)\n", path, yes_no(ignore));
3401
3402                         if (r < 0)
3403                                 return bus_log_parse_error(r);
3404
3405                         r = sd_bus_message_exit_container(m);
3406                         if (r < 0)
3407                                 return bus_log_parse_error(r);
3408
3409                         return 0;
3410
3411                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Paths")) {
3412                         const char *type, *path;
3413
3414                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3415                         if (r < 0)
3416                                 return bus_log_parse_error(r);
3417
3418                         while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
3419                                 printf("%s=%s\n", type, path);
3420                         if (r < 0)
3421                                 return bus_log_parse_error(r);
3422
3423                         r = sd_bus_message_exit_container(m);
3424                         if (r < 0)
3425                                 return bus_log_parse_error(r);
3426
3427                         return 0;
3428
3429                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3430                         const char *type, *path;
3431
3432                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3433                         if (r < 0)
3434                                 return bus_log_parse_error(r);
3435
3436                         while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
3437                                 printf("Listen%s=%s\n", type, path);
3438                         if (r < 0)
3439                                 return bus_log_parse_error(r);
3440
3441                         r = sd_bus_message_exit_container(m);
3442                         if (r < 0)
3443                                 return bus_log_parse_error(r);
3444
3445                         return 0;
3446
3447                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Timers")) {
3448                         const char *base;
3449                         uint64_t value, next_elapse;
3450
3451                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(stt)");
3452                         if (r < 0)
3453                                 return bus_log_parse_error(r);
3454
3455                         while ((r = sd_bus_message_read(m, "(stt)", &base, &value, &next_elapse)) > 0) {
3456                                 char timespan1[FORMAT_TIMESPAN_MAX], timespan2[FORMAT_TIMESPAN_MAX];
3457
3458                                 printf("%s={ value=%s ; next_elapse=%s }\n",
3459                                        base,
3460                                        format_timespan(timespan1, sizeof(timespan1), value, 0),
3461                                        format_timespan(timespan2, sizeof(timespan2), next_elapse, 0));
3462                         }
3463                         if (r < 0)
3464                                 return bus_log_parse_error(r);
3465
3466                         r = sd_bus_message_exit_container(m);
3467                         if (r < 0)
3468                                 return bus_log_parse_error(r);
3469
3470                         return 0;
3471
3472                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3473                         ExecStatusInfo info = {};
3474
3475                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3476                         if (r < 0)
3477                                 return bus_log_parse_error(r);
3478
3479                         while ((r = exec_status_info_deserialize(m, &info)) > 0) {
3480                                 char timestamp1[FORMAT_TIMESTAMP_MAX], timestamp2[FORMAT_TIMESTAMP_MAX];
3481                                 _cleanup_free_ char *tt;
3482
3483                                 tt = strv_join(info.argv, " ");
3484
3485                                 printf("%s={ path=%s ; argv[]=%s ; ignore_errors=%s ; start_time=[%s] ; stop_time=[%s] ; pid=%u ; code=%s ; status=%i%s%s }\n",
3486                                        name,
3487                                        strna(info.path),
3488                                        strna(tt),
3489                                        yes_no(info.ignore),
3490                                        strna(format_timestamp(timestamp1, sizeof(timestamp1), info.start_timestamp)),
3491                                        strna(format_timestamp(timestamp2, sizeof(timestamp2), info.exit_timestamp)),
3492                                        (unsigned) info. pid,
3493                                        sigchld_code_to_string(info.code),
3494                                        info.status,
3495                                        info.code == CLD_EXITED ? "" : "/",
3496                                        strempty(info.code == CLD_EXITED ? NULL : signal_to_string(info.status)));
3497
3498                                 free(info.path);
3499                                 strv_free(info.argv);
3500                                 zero(info);
3501                         }
3502
3503                         r = sd_bus_message_exit_container(m);
3504                         if (r < 0)
3505                                 return bus_log_parse_error(r);
3506
3507                         return 0;
3508
3509                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "DeviceAllow")) {
3510                         const char *path, *rwm;
3511
3512                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3513                         if (r < 0)
3514                                 return bus_log_parse_error(r);
3515
3516                         while ((r = sd_bus_message_read(m, "(ss)", &path, &rwm)) > 0)
3517                                 printf("%s=%s %s\n", name, strna(path), strna(rwm));
3518                         if (r < 0)
3519                                 return bus_log_parse_error(r);
3520
3521                         r = sd_bus_message_exit_container(m);
3522                         if (r < 0)
3523                                 return bus_log_parse_error(r);
3524
3525                         return 0;
3526
3527                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "BlockIODeviceWeight")) {
3528                         const char *path;
3529                         uint64_t weight;
3530
3531                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
3532                         if (r < 0)
3533                                 return bus_log_parse_error(r);
3534
3535                         while ((r = sd_bus_message_read(m, "(st)", &path, &weight)) > 0)
3536                                 printf("%s=%s %" PRIu64 "\n", name, strna(path), weight);
3537                         if (r < 0)
3538                                 return bus_log_parse_error(r);
3539
3540                         r = sd_bus_message_exit_container(m);
3541                         if (r < 0)
3542                                 return bus_log_parse_error(r);
3543
3544                         return 0;
3545
3546                 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && (streq(name, "BlockIOReadBandwidth") || streq(name, "BlockIOWriteBandwidth"))) {
3547                         const char *path;