+int config_parse_personality(
+ 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 long *personality = data, p;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(personality);
+
+ p = personality_from_string(rvalue);
+ if (p == 0xffffffffUL) {
+ log_syntax(unit, LOG_ERR, filename, line, EINVAL,
+ "Failed to parse personality, ignoring: %s", rvalue);
+ return 0;
+ }
+
+ *personality = p;
+ return 0;
+}
+
+int config_parse_runtime_directory(
+ 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***rt = data;
+ const char *word, *state;
+ size_t l;
+ int r;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ if (isempty(rvalue)) {
+ /* Empty assignment resets the list */
+ strv_free(*rt);
+ *rt = NULL;
+ return 0;
+ }
+
+ FOREACH_WORD_QUOTED(word, l, rvalue, state) {
+ _cleanup_free_ char *n;
+
+ n = strndup(word, l);
+ if (!n)
+ return log_oom();
+
+ if (!filename_is_safe(n)) {
+ log_syntax(unit, LOG_ERR, filename, line, EINVAL,
+ "Runtime directory is not valid, ignoring assignment: %s", rvalue);
+ continue;
+ }
+
+ r = strv_push(rt, n);
+ if (r < 0)
+ return log_oom();
+
+ n = NULL;
+ }
+ if (!isempty(state))
+ log_syntax(unit, LOG_ERR, filename, line, EINVAL,
+ "Trailing garbage, ignoring.");
+
+ return 0;
+}
+
+int config_parse_set_status(
+ 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) {
+
+ size_t l;
+ const char *word, *state;
+ int r;
+ ExitStatusSet *status_set = data;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ /* Empty assignment resets the list */
+ if (isempty(rvalue)) {
+ exit_status_set_free(status_set);
+ return 0;
+ }
+
+ FOREACH_WORD(word, l, rvalue, state) {
+ _cleanup_free_ char *temp;
+ int val;
+
+ temp = strndup(word, l);
+ if (!temp)
+ return log_oom();
+
+ r = safe_atoi(temp, &val);
+ if (r < 0) {
+ val = signal_from_string_try_harder(temp);
+
+ if (val <= 0) {
+ log_syntax(unit, LOG_ERR, filename, line, -val,
+ "Failed to parse value, ignoring: %s", word);
+ return 0;
+ }
+ } else {
+ if (val < 0 || val > 255) {
+ log_syntax(unit, LOG_ERR, filename, line, ERANGE,
+ "Value %d is outside range 0-255, ignoring", val);
+ continue;
+ }
+ }
+
+ r = set_ensure_allocated(&status_set->status, NULL);
+ if (r < 0)
+ return log_oom();
+
+ r = set_put(status_set->status, INT_TO_PTR(val));
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, -r,
+ "Unable to store: %s", word);
+ return r;
+ }
+ }
+ if (!isempty(state))
+ log_syntax(unit, LOG_ERR, filename, line, EINVAL,
+ "Trailing garbage, ignoring.");
+
+ return 0;
+}
+
+int config_parse_namespace_path_strv(
+ 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*** sv = data;
+ const char *word, *state;
+ size_t l;
+ int r;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ if (isempty(rvalue)) {
+ /* Empty assignment resets the list */
+ strv_free(*sv);
+ *sv = NULL;
+ return 0;
+ }
+
+ FOREACH_WORD_QUOTED(word, l, rvalue, state) {
+ _cleanup_free_ char *n;
+ int offset;
+
+ n = strndup(word, l);
+ if (!n)
+ return log_oom();
+
+ if (!utf8_is_valid(n)) {
+ log_invalid_utf8(unit, LOG_ERR, filename, line, EINVAL, rvalue);
+ continue;
+ }
+
+ offset = n[0] == '-';
+ if (!path_is_absolute(n + offset)) {
+ log_syntax(unit, LOG_ERR, filename, line, EINVAL,
+ "Not an absolute path, ignoring: %s", rvalue);
+ continue;
+ }
+
+ path_kill_slashes(n);
+
+ r = strv_push(sv, n);
+ if (r < 0)
+ return log_oom();
+
+ n = NULL;
+ }
+ if (!isempty(state))
+ log_syntax(unit, LOG_ERR, filename, line, EINVAL,
+ "Trailing garbage, ignoring.");
+
+ return 0;
+}
+
+int config_parse_no_new_privileges(
+ 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) {
+
+ ExecContext *c = data;
+ int k;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ k = parse_boolean(rvalue);
+ if (k < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, -k,
+ "Failed to parse boolean value, ignoring: %s", rvalue);
+ return 0;
+ }
+
+ c->no_new_privileges = !!k;
+ c->no_new_privileges_set = true;
+
+ return 0;
+}
+
+int config_parse_protect_home(
+ 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) {
+
+ ExecContext *c = data;
+ int k;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ /* Our enum shall be a superset of booleans, hence first try
+ * to parse as as boolean, and then as enum */
+
+ k = parse_boolean(rvalue);
+ if (k > 0)
+ c->protect_home = PROTECT_HOME_YES;
+ else if (k == 0)
+ c->protect_home = PROTECT_HOME_NO;
+ else {
+ ProtectHome h;
+
+ h = protect_home_from_string(rvalue);
+ if (h < 0){
+ log_syntax(unit, LOG_ERR, filename, line, -h,
+ "Failed to parse protect home value, ignoring: %s", rvalue);
+ return 0;
+ }
+
+ c->protect_home = h;
+ }
+
+ return 0;
+}
+
+int config_parse_protect_system(
+ 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) {
+
+ ExecContext *c = data;
+ int k;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ /* Our enum shall be a superset of booleans, hence first try
+ * to parse as as boolean, and then as enum */
+
+ k = parse_boolean(rvalue);
+ if (k > 0)
+ c->protect_system = PROTECT_SYSTEM_YES;
+ else if (k == 0)
+ c->protect_system = PROTECT_SYSTEM_NO;
+ else {
+ ProtectSystem s;
+
+ s = protect_system_from_string(rvalue);
+ if (s < 0){
+ log_syntax(unit, LOG_ERR, filename, line, -s,
+ "Failed to parse protect system value, ignoring: %s", rvalue);
+ return 0;
+ }
+
+ c->protect_system = s;
+ }
+
+ return 0;
+}
+