]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/analyze/analyze-condition.c
strv: make iterator in STRV_FOREACH() declaread in the loop
[thirdparty/systemd.git] / src / analyze / analyze-condition.c
CommitLineData
db9ecf05 1/* SPDX-License-Identifier: LGPL-2.1-or-later */
edfea9fe
ZJS
2
3#include <stdlib.h>
4
e82116e5 5#include "analyze.h"
edfea9fe 6#include "analyze-condition.h"
f2562398 7#include "analyze-verify-util.h"
edfea9fe
ZJS
8#include "condition.h"
9#include "conf-parser.h"
10#include "load-fragment.h"
11#include "service.h"
12
edfea9fe 13static int parse_condition(Unit *u, const char *line) {
625a1640
LP
14 assert(u);
15 assert(line);
16
17 for (ConditionType t = 0; t < _CONDITION_TYPE_MAX; t++) {
18 ConfigParserCallback callback;
19 Condition **target;
20 const char *p, *name;
21
22 name = condition_type_to_string(t);
23 p = startswith(line, name);
24 if (p)
25 target = &u->conditions;
26 else {
27 name = assert_type_to_string(t);
28 p = startswith(line, name);
29 if (!p)
30 continue;
31
32 target = &u->asserts;
33 }
08ef6886 34
edfea9fe 35 p += strspn(p, WHITESPACE);
08ef6886 36
edfea9fe 37 if (*p != '=')
08ef6886
LP
38 continue;
39 p++;
edfea9fe 40
08ef6886 41 p += strspn(p, WHITESPACE);
edfea9fe 42
476cfe62 43 if (condition_takes_path(t))
625a1640
LP
44 callback = config_parse_unit_condition_path;
45 else
46 callback = config_parse_unit_condition_string;
47
48 return callback(NULL, "(cmdline)", 0, NULL, 0, name, t, p, target, u);
edfea9fe
ZJS
49 }
50
51 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Cannot parse \"%s\".", line);
52}
53
54_printf_(7, 8)
55static int log_helper(void *userdata, int level, int error, const char *file, int line, const char *func, const char *format, ...) {
56 Unit *u = userdata;
57 va_list ap;
58 int r;
59
60 assert(u);
61
62 /* "upgrade" debug messages */
63 level = MIN(LOG_INFO, level);
64
65 va_start(ap, format);
66 r = log_object_internalv(level, error, file, line, func,
67 NULL,
68 u->id,
69 NULL,
70 NULL,
71 format, ap);
72 va_end(ap);
73
74 return r;
75}
76
e82116e5 77static int verify_conditions(char **lines, UnitFileScope scope, const char *unit, const char *root) {
edfea9fe
ZJS
78 _cleanup_(manager_freep) Manager *m = NULL;
79 Unit *u;
edfea9fe
ZJS
80 int r, q = 1;
81
8de7929d
DDM
82 if (unit) {
83 _cleanup_strv_free_ char **filenames = NULL;
84 _cleanup_free_ char *var = NULL;
85
86 filenames = strv_new(unit);
87 if (!filenames)
88 return log_oom();
89
90 r = verify_generate_path(&var, filenames);
91 if (r < 0)
92 return log_error_errno(r, "Failed to generate unit load path: %m");
93
94 assert_se(set_unit_path(var) >= 0);
95 }
96
edfea9fe
ZJS
97 r = manager_new(scope, MANAGER_TEST_RUN_MINIMAL, &m);
98 if (r < 0)
99 return log_error_errno(r, "Failed to initialize manager: %m");
100
101 log_debug("Starting manager...");
8de7929d 102 r = manager_startup(m, /* serialization= */ NULL, /* fds= */ NULL, root);
edfea9fe
ZJS
103 if (r < 0)
104 return r;
105
8de7929d
DDM
106 if (unit) {
107 _cleanup_free_ char *prepared = NULL;
edfea9fe 108
8de7929d
DDM
109 r = verify_prepare_filename(unit, &prepared);
110 if (r < 0)
111 return log_error_errno(r, "Failed to prepare filename %s: %m", unit);
112
113 r = manager_load_startable_unit_or_warn(m, NULL, prepared, &u);
edfea9fe
ZJS
114 if (r < 0)
115 return r;
8de7929d 116 } else {
8de7929d
DDM
117 r = unit_new_for_name(m, sizeof(Service), "test.service", &u);
118 if (r < 0)
119 return log_error_errno(r, "Failed to create test.service: %m");
120
121 STRV_FOREACH(line, lines) {
122 r = parse_condition(u, *line);
123 if (r < 0)
124 return r;
125 }
edfea9fe
ZJS
126 }
127
a0b191b7 128 r = condition_test_list(u->asserts, environ, assert_type_to_string, log_helper, u);
edfea9fe
ZJS
129 if (u->asserts)
130 log_notice("Asserts %s.", r > 0 ? "succeeded" : "failed");
131
a0b191b7 132 q = condition_test_list(u->conditions, environ, condition_type_to_string, log_helper, u);
edfea9fe
ZJS
133 if (u->conditions)
134 log_notice("Conditions %s.", q > 0 ? "succeeded" : "failed");
135
136 return r > 0 && q > 0 ? 0 : -EIO;
137}
e82116e5 138
ef38bedb 139int verb_condition(int argc, char *argv[], void *userdata) {
e82116e5
LP
140 return verify_conditions(strv_skip(argv, 1), arg_scope, arg_unit, arg_root);
141}