/* SPDX-License-Identifier: LGPL-2.1+ */
-/***
- This file is part of systemd.
-
- Copyright 2010 Lennart Poettering
-***/
#include <errno.h>
#include <limits.h>
#include "fs-util.h"
#include "log.h"
#include "macro.h"
+#include "missing.h"
#include "parse-util.h"
#include "path-util.h"
#include "process-util.h"
+#include "rlimit-util.h"
#include "signal-util.h"
#include "socket-util.h"
#include "string-util.h"
#include "syslog-util.h"
#include "time-util.h"
#include "utf8.h"
-#include "rlimit-util.h"
int config_item_table_lookup(
const void *table,
assert(ltype);
assert(data);
- if (!section)
- p = lookup(lvalue, strlen(lvalue));
- else {
- char *key;
-
- key = strjoin(section, ".", lvalue);
- if (!key)
- return -ENOMEM;
+ if (section) {
+ const char *key;
+ key = strjoina(section, ".", lvalue);
p = lookup(key, strlen(key));
- free(key);
- }
-
+ } else
+ p = lookup(lvalue, strlen(lvalue));
if (!p)
return 0;
r = lookup(table, section, lvalue, &func, <ype, &data, userdata);
if (r < 0)
return r;
-
if (r > 0) {
if (func)
return func(unit, filename, line, section, section_line,
/* Warn about unknown non-extension fields. */
if (!(flags & CONFIG_PARSE_RELAXED) && !startswith(lvalue, "X-"))
- log_syntax(unit, LOG_WARNING, filename, line, 0, "Unknown lvalue '%s' in section '%s'", lvalue, section);
+ log_syntax(unit, LOG_WARNING, filename, line, 0, "Unknown lvalue '%s' in section '%s', ignoring", lvalue, section);
return 0;
}
if (!*l)
return 0;
- if (strchr(COMMENTS "\n", *l))
+ if (*l == '\n')
return 0;
include = first_word(l, ".include");
return config_parse(unit, fn, NULL, sections, lookup, table, flags, userdata);
}
+ if (!utf8_is_valid(l))
+ return log_syntax_invalid_utf8(unit, LOG_WARNING, filename, line, l);
+
if (*l == '[') {
size_t k;
char *n;
*section_line = 0;
*section_ignored = true;
} else {
- free(*section);
- *section = n;
+ free_and_replace(*section, n);
*section_line = line;
*section_ignored = false;
}
/* Only log on request, except for ENOENT,
* since we return 0 to the caller. */
if ((flags & CONFIG_PARSE_WARN) || errno == ENOENT)
- log_full(errno == ENOENT ? LOG_DEBUG : LOG_ERR,
- "Failed to open configuration file '%s': %m", filename);
+ log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_ERR, errno,
+ "Failed to open configuration file '%s': %m", filename);
return errno == ENOENT ? 0 : -errno;
}
}
return r;
}
+ if (strchr(COMMENTS, *skip_leading_chars(buf, WHITESPACE)))
+ continue;
+
l = buf;
if (!(flags & CONFIG_PARSE_REFUSE_BOM)) {
char *q;
if (flags & CONFIG_PARSE_WARN)
log_warning_errno(r, "%s:%u: Failed to parse file: %m", filename, line);
return r;
-
}
continuation = mfree(continuation);
if (flags & CONFIG_PARSE_WARN)
log_warning_errno(r, "%s:%u: Failed to parse file: %m", filename, line);
return r;
-
}
}
}
#define DEFINE_PARSER(type, vartype, conv_func) \
- int config_parse_##type( \
- const char *unit, \
- const char *filename, \
- unsigned line, \
- const char *section, \
- unsigned section_line, \
- const char *lvalue, \
- int ltype, \
- const char *rvalue, \
- void *data, \
- void *userdata) { \
- \
- vartype *i = data; \
- int r; \
- \
- assert(filename); \
- assert(lvalue); \
- assert(rvalue); \
- assert(data); \
- \
- r = conv_func(rvalue, i); \
- if (r < 0) \
- log_syntax(unit, LOG_ERR, filename, line, r, \
- "Failed to parse %s value, ignoring: %s", \
- #type, rvalue); \
- \
- return 0; \
- }
+ DEFINE_CONFIG_PARSE_PTR(config_parse_##type, conv_func, vartype, "Failed to parse " #type " value")
DEFINE_PARSER(int, int, safe_atoi);
DEFINE_PARSER(long, long, safe_atoli);
DEFINE_PARSER(double, double, safe_atod);
DEFINE_PARSER(nsec, nsec_t, parse_nsec);
DEFINE_PARSER(sec, usec_t, parse_sec);
+DEFINE_PARSER(sec_def_infinity, usec_t, parse_sec_def_infinity);
DEFINE_PARSER(mode, mode_t, parse_mode);
int config_parse_iec_size(const char* unit,
assert(data);
r = parse_size(rvalue, 1024, &v);
- if (r < 0 || (uint64_t) (size_t) v != v) {
- log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse size value, ignoring: %s", rvalue);
+ if (r >= 0 && (uint64_t) (size_t) v != v)
+ r = -ERANGE;
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse size value '%s', ignoring: %m", rvalue);
return 0;
}
assert(data);
r = parse_size(rvalue, 1000, &v);
- if (r < 0 || (uint64_t) (size_t) v != v) {
- log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse size value, ignoring: %s", rvalue);
+ if (r >= 0 && (uint64_t) (size_t) v != v)
+ r = -ERANGE;
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse size value '%s', ignoring: %m", rvalue);
return 0;
}
return fatal ? -ENOEXEC : 0;
}
- *b = !!k;
+ *b = k;
return 0;
}
assert(rvalue);
assert(data);
- if (!utf8_is_valid(rvalue)) {
- log_syntax_invalid_utf8(unit, LOG_ERR, filename, line, rvalue);
- return 0;
- }
-
if (free_and_strdup(s, empty_to_null(rvalue)) < 0)
return log_oom();
void *data,
void *userdata) {
- char **s = data, *n;
+ _cleanup_free_ char *n = NULL;
bool fatal = ltype;
+ char **s = data;
+ int r;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(data);
- if (isempty(rvalue)) {
- n = NULL;
+ if (isempty(rvalue))
goto finalize;
- }
-
- if (!utf8_is_valid(rvalue)) {
- log_syntax_invalid_utf8(unit, LOG_ERR, filename, line, rvalue);
- return fatal ? -ENOEXEC : 0;
- }
-
- if (!path_is_absolute(rvalue)) {
- log_syntax(unit, LOG_ERR, filename, line, 0,
- "Not an absolute path%s: %s",
- fatal ? "" : ", ignoring", rvalue);
- return fatal ? -ENOEXEC : 0;
- }
n = strdup(rvalue);
if (!n)
return log_oom();
- path_kill_slashes(n);
+ r = path_simplify_and_warn(n, PATH_CHECK_ABSOLUTE | (fatal ? PATH_CHECK_FATAL : 0), unit, filename, line, lvalue);
+ if (r < 0)
+ return fatal ? -ENOEXEC : 0;
finalize:
- free(*s);
- *s = n;
-
- return 0;
+ return free_and_replace(*s, n);
}
int config_parse_strv(
break;
}
- if (!utf8_is_valid(word)) {
- log_syntax_invalid_utf8(unit, LOG_ERR, filename, line, word);
- free(word);
- continue;
- }
-
r = strv_consume(sv, word);
if (r < 0)
return log_oom();
const char *rvalue,
void *data,
void *userdata) {
+
Disabled reason = ltype;
switch(reason) {
+
case DISABLED_CONFIGURATION:
log_syntax(unit, LOG_DEBUG, filename, line, 0,
"Support for option %s= has been disabled at compile time and it is ignored", lvalue);
break;
+
case DISABLED_LEGACY:
log_syntax(unit, LOG_INFO, filename, line, 0,
"Support for option %s= has been removed and it is ignored", lvalue);
break;
+
case DISABLED_EXPERIMENTAL:
log_syntax(unit, LOG_INFO, filename, line, 0,
"Support for option %s= has not yet been enabled and it is ignored", lvalue);
break;
- };
+ }
return 0;
}
return 0;
}
-int config_parse_join_controllers(
- const char *unit,
- const char *filename,
- unsigned line,
- const char *section,
- unsigned section_line,
- const char *lvalue,
- int ltype,
- const char *rvalue,
- void *data,
- void *userdata) {
-
- char ****ret = data;
- const char *whole_rvalue = rvalue;
- unsigned n = 0;
- _cleanup_(strv_free_freep) char ***controllers = NULL;
-
- assert(filename);
- assert(lvalue);
- assert(rvalue);
- assert(ret);
-
- for (;;) {
- _cleanup_free_ char *word = NULL;
- char **l;
- int r;
-
- r = extract_first_word(&rvalue, &word, NULL, EXTRACT_QUOTES);
- if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, r, "Invalid value for %s: %s", lvalue, whole_rvalue);
- return r;
- }
- if (r == 0)
- break;
-
- l = strv_split(word, ",");
- if (!l)
- return log_oom();
- strv_uniq(l);
-
- if (strv_length(l) <= 1) {
- strv_free(l);
- continue;
- }
-
- if (!controllers) {
- controllers = new(char**, 2);
- if (!controllers) {
- strv_free(l);
- return log_oom();
- }
-
- controllers[0] = l;
- controllers[1] = NULL;
-
- n = 1;
- } else {
- char ***a;
- char ***t;
-
- t = new0(char**, n+2);
- if (!t) {
- strv_free(l);
- return log_oom();
- }
-
- n = 0;
-
- for (a = controllers; *a; a++)
- if (strv_overlap(*a, l)) {
- if (strv_extend_strv(&l, *a, false) < 0) {
- strv_free(l);
- strv_free_free(t);
- return log_oom();
- }
-
- } else {
- char **c;
-
- c = strv_copy(*a);
- if (!c) {
- strv_free(l);
- strv_free_free(t);
- return log_oom();
- }
-
- t[n++] = c;
- }
-
- t[n++] = strv_uniq(l);
-
- strv_free_free(controllers);
- controllers = t;
- }
- }
- if (!isempty(rvalue))
- log_syntax(unit, LOG_ERR, filename, line, 0, "Trailing garbage, ignoring.");
-
- /* As a special case, return a single empty strv, to override the default */
- if (!controllers) {
- controllers = new(char**, 2);
- if (!controllers)
- return log_oom();
- controllers[0] = strv_new(NULL, NULL);
- if (!controllers[0])
- return log_oom();
- controllers[1] = NULL;
- }
-
- strv_free_free(*ret);
- *ret = TAKE_PTR(controllers);
-
- return 0;
-}
-
int config_parse_mtu(
const char *unit,
const char *filename,
return 0;
}
+
+int config_parse_permille(const char* unit,
+ const char *filename,
+ unsigned line,
+ const char *section,
+ unsigned section_line,
+ const char *lvalue,
+ int ltype,
+ const char *rvalue,
+ void *data,
+ void *userdata) {
+
+ unsigned *permille = data;
+ int r;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(permille);
+
+ r = parse_permille(rvalue);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r,
+ "Failed to parse permille value, ignoring: %s", rvalue);
+ return 0;
+ }
+
+ *permille = (unsigned) r;
+
+ return 0;
+}