1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2 
3 #include <errno.h>
4 #include <getopt.h>
5 #include <stdio.h>
6 #include <stdlib.h>
7 
8 #include "sd-bus.h"
9 
10 #include "alloc-util.h"
11 #include "bus-error.h"
12 #include "log.h"
13 #include "main-func.h"
14 #include "pretty-print.h"
15 #include "terminal-util.h"
16 #include "util.h"
17 
help(void)18 static int help(void) {
19         _cleanup_free_ char *link = NULL;
20         int r;
21 
22         r = terminal_urlify_man("systemd-boot-check-no-failures.service", "8", &link);
23         if (r < 0)
24                 return log_oom();
25 
26         printf("%s [OPTIONS...]\n"
27                "\n%sVerify system operational state.%s\n\n"
28                "  -h --help          Show this help\n"
29                "     --version       Print version\n"
30                "\nSee the %s for details.\n",
31                program_invocation_short_name,
32                ansi_highlight(),
33                ansi_normal(),
34                link);
35 
36         return 0;
37 }
38 
parse_argv(int argc,char * argv[])39 static int parse_argv(int argc, char *argv[]) {
40         enum {
41                 ARG_PATH = 0x100,
42                 ARG_VERSION,
43         };
44 
45         static const struct option options[] = {
46                 { "help",         no_argument,       NULL, 'h'              },
47                 { "version",      no_argument,       NULL, ARG_VERSION      },
48                 {}
49         };
50 
51         int c;
52 
53         assert(argc >= 0);
54         assert(argv);
55 
56         while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0)
57                 switch (c) {
58 
59                 case 'h':
60                         help();
61                         return 0;
62 
63                 case ARG_VERSION:
64                         return version();
65 
66                 case '?':
67                         return -EINVAL;
68 
69                 default:
70                         assert_not_reached();
71                 }
72 
73         return 1;
74 }
75 
run(int argc,char * argv[])76 static int run(int argc, char *argv[]) {
77         _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
78         _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
79         uint32_t n;
80         int r;
81 
82         log_parse_environment();
83         log_open();
84 
85         r = parse_argv(argc, argv);
86         if (r <= 0)
87                 return r;
88 
89         r = sd_bus_open_system(&bus);
90         if (r < 0)
91                 return log_error_errno(r, "Failed to connect to system bus: %m");
92 
93         r = sd_bus_get_property_trivial(
94                         bus,
95                         "org.freedesktop.systemd1",
96                         "/org/freedesktop/systemd1",
97                         "org.freedesktop.systemd1.Manager",
98                         "NFailedUnits",
99                         &error,
100                         'u',
101                         &n);
102         if (r < 0)
103                 return log_error_errno(r, "Failed to get failed units counter: %s", bus_error_message(&error, r));
104 
105         if (n > 0)
106                 log_notice("Health check: %" PRIu32 " units have failed.", n);
107         else
108                 log_info("Health check: no failed units.");
109 
110         return n > 0;
111 }
112 
113 DEFINE_MAIN_FUNCTION_WITH_POSITIVE_FAILURE(run);
114