]>
Commit | Line | Data |
---|---|---|
db9ecf05 | 1 | /* SPDX-License-Identifier: LGPL-2.1-or-later */ |
edfea9fe ZJS |
2 | |
3 | #include <stdlib.h> | |
4 | ||
5 | #include "analyze-condition.h" | |
6 | #include "condition.h" | |
7 | #include "conf-parser.h" | |
8 | #include "load-fragment.h" | |
9 | #include "service.h" | |
10 | ||
edfea9fe | 11 | static int parse_condition(Unit *u, const char *line) { |
625a1640 LP |
12 | assert(u); |
13 | assert(line); | |
14 | ||
15 | for (ConditionType t = 0; t < _CONDITION_TYPE_MAX; t++) { | |
16 | ConfigParserCallback callback; | |
17 | Condition **target; | |
18 | const char *p, *name; | |
19 | ||
20 | name = condition_type_to_string(t); | |
21 | p = startswith(line, name); | |
22 | if (p) | |
23 | target = &u->conditions; | |
24 | else { | |
25 | name = assert_type_to_string(t); | |
26 | p = startswith(line, name); | |
27 | if (!p) | |
28 | continue; | |
29 | ||
30 | target = &u->asserts; | |
31 | } | |
08ef6886 | 32 | |
edfea9fe | 33 | p += strspn(p, WHITESPACE); |
08ef6886 | 34 | |
edfea9fe | 35 | if (*p != '=') |
08ef6886 LP |
36 | continue; |
37 | p++; | |
edfea9fe | 38 | |
08ef6886 | 39 | p += strspn(p, WHITESPACE); |
edfea9fe | 40 | |
476cfe62 | 41 | if (condition_takes_path(t)) |
625a1640 LP |
42 | callback = config_parse_unit_condition_path; |
43 | else | |
44 | callback = config_parse_unit_condition_string; | |
45 | ||
46 | return callback(NULL, "(cmdline)", 0, NULL, 0, name, t, p, target, u); | |
edfea9fe ZJS |
47 | } |
48 | ||
49 | return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Cannot parse \"%s\".", line); | |
50 | } | |
51 | ||
52 | _printf_(7, 8) | |
53 | static int log_helper(void *userdata, int level, int error, const char *file, int line, const char *func, const char *format, ...) { | |
54 | Unit *u = userdata; | |
55 | va_list ap; | |
56 | int r; | |
57 | ||
58 | assert(u); | |
59 | ||
60 | /* "upgrade" debug messages */ | |
61 | level = MIN(LOG_INFO, level); | |
62 | ||
63 | va_start(ap, format); | |
64 | r = log_object_internalv(level, error, file, line, func, | |
65 | NULL, | |
66 | u->id, | |
67 | NULL, | |
68 | NULL, | |
69 | format, ap); | |
70 | va_end(ap); | |
71 | ||
72 | return r; | |
73 | } | |
74 | ||
75 | int verify_conditions(char **lines, UnitFileScope scope) { | |
76 | _cleanup_(manager_freep) Manager *m = NULL; | |
77 | Unit *u; | |
78 | char **line; | |
79 | int r, q = 1; | |
80 | ||
81 | r = manager_new(scope, MANAGER_TEST_RUN_MINIMAL, &m); | |
82 | if (r < 0) | |
83 | return log_error_errno(r, "Failed to initialize manager: %m"); | |
84 | ||
85 | log_debug("Starting manager..."); | |
2a7cf953 | 86 | r = manager_startup(m, /* serialization= */ NULL, /* fds= */ NULL, /* root= */ NULL); |
edfea9fe ZJS |
87 | if (r < 0) |
88 | return r; | |
89 | ||
90 | r = unit_new_for_name(m, sizeof(Service), "test.service", &u); | |
91 | if (r < 0) | |
92 | return log_error_errno(r, "Failed to create test.service: %m"); | |
93 | ||
94 | STRV_FOREACH(line, lines) { | |
95 | r = parse_condition(u, *line); | |
96 | if (r < 0) | |
97 | return r; | |
98 | } | |
99 | ||
a0b191b7 | 100 | r = condition_test_list(u->asserts, environ, assert_type_to_string, log_helper, u); |
edfea9fe ZJS |
101 | if (u->asserts) |
102 | log_notice("Asserts %s.", r > 0 ? "succeeded" : "failed"); | |
103 | ||
a0b191b7 | 104 | q = condition_test_list(u->conditions, environ, condition_type_to_string, log_helper, u); |
edfea9fe ZJS |
105 | if (u->conditions) |
106 | log_notice("Conditions %s.", q > 0 ? "succeeded" : "failed"); | |
107 | ||
108 | return r > 0 && q > 0 ? 0 : -EIO; | |
109 | } |