| /* SPDX-License-Identifier: LGPL-2.1-or-later */ |
| |
| #include <stdlib.h> |
| |
| #include "analyze-condition.h" |
| #include "condition.h" |
| #include "conf-parser.h" |
| #include "load-fragment.h" |
| #include "service.h" |
| |
| static int parse_condition(Unit *u, const char *line) { |
| assert(u); |
| assert(line); |
| |
| for (ConditionType t = 0; t < _CONDITION_TYPE_MAX; t++) { |
| ConfigParserCallback callback; |
| Condition **target; |
| const char *p, *name; |
| |
| name = condition_type_to_string(t); |
| p = startswith(line, name); |
| if (p) |
| target = &u->conditions; |
| else { |
| name = assert_type_to_string(t); |
| p = startswith(line, name); |
| if (!p) |
| continue; |
| |
| target = &u->asserts; |
| } |
| |
| p += strspn(p, WHITESPACE); |
| |
| if (*p != '=') |
| continue; |
| p++; |
| |
| p += strspn(p, WHITESPACE); |
| |
| if (condition_takes_path(t)) |
| callback = config_parse_unit_condition_path; |
| else |
| callback = config_parse_unit_condition_string; |
| |
| return callback(NULL, "(cmdline)", 0, NULL, 0, name, t, p, target, u); |
| } |
| |
| return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Cannot parse \"%s\".", line); |
| } |
| |
| _printf_(7, 8) |
| static int log_helper(void *userdata, int level, int error, const char *file, int line, const char *func, const char *format, ...) { |
| Unit *u = userdata; |
| va_list ap; |
| int r; |
| |
| assert(u); |
| |
| /* "upgrade" debug messages */ |
| level = MIN(LOG_INFO, level); |
| |
| va_start(ap, format); |
| r = log_object_internalv(level, error, file, line, func, |
| NULL, |
| u->id, |
| NULL, |
| NULL, |
| format, ap); |
| va_end(ap); |
| |
| return r; |
| } |
| |
| int verify_conditions(char **lines, UnitFileScope scope) { |
| _cleanup_(manager_freep) Manager *m = NULL; |
| Unit *u; |
| char **line; |
| int r, q = 1; |
| |
| r = manager_new(scope, MANAGER_TEST_RUN_MINIMAL, &m); |
| if (r < 0) |
| return log_error_errno(r, "Failed to initialize manager: %m"); |
| |
| log_debug("Starting manager..."); |
| r = manager_startup(m, NULL, NULL); |
| if (r < 0) |
| return r; |
| |
| r = unit_new_for_name(m, sizeof(Service), "test.service", &u); |
| if (r < 0) |
| return log_error_errno(r, "Failed to create test.service: %m"); |
| |
| STRV_FOREACH(line, lines) { |
| r = parse_condition(u, *line); |
| if (r < 0) |
| return r; |
| } |
| |
| r = condition_test_list(u->asserts, environ, assert_type_to_string, log_helper, u); |
| if (u->asserts) |
| log_notice("Asserts %s.", r > 0 ? "succeeded" : "failed"); |
| |
| q = condition_test_list(u->conditions, environ, condition_type_to_string, log_helper, u); |
| if (u->conditions) |
| log_notice("Conditions %s.", q > 0 ? "succeeded" : "failed"); |
| |
| return r > 0 && q > 0 ? 0 : -EIO; |
| } |