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