diff options
author | Lennart Poettering <lennart@poettering.net> | 2020-04-30 18:32:44 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2020-05-07 17:24:22 +0200 |
commit | a00a78b84e2ab352b3144bfae8bc578d172303be (patch) | |
tree | f45bdab5db60c30378615ec603b82c7d9c088541 /src/locale/localed.c | |
parent | test: add test case for locale_is_installed() (diff) | |
download | systemd-a00a78b84e2ab352b3144bfae8bc578d172303be.tar.xz systemd-a00a78b84e2ab352b3144bfae8bc578d172303be.zip |
tree-wide: port various bits over to locale_is_installed()
Diffstat (limited to 'src/locale/localed.c')
-rw-r--r-- | src/locale/localed.c | 87 |
1 files changed, 53 insertions, 34 deletions
diff --git a/src/locale/localed.c b/src/locale/localed.c index acdf79fa6b..a6aa3bae8c 100644 --- a/src/locale/localed.c +++ b/src/locale/localed.c @@ -258,18 +258,57 @@ static int property_get_xkb( return -EINVAL; } +static int process_locale_list_item( + const char *assignment, + char *new_locale[static _VARIABLE_LC_MAX], + sd_bus_error *error) { + + assert(assignment); + assert(new_locale); + + for (LocaleVariable p = 0; p < _VARIABLE_LC_MAX; p++) { + const char *name, *e; + + assert_se(name = locale_variable_to_string(p)); + + e = startswith(assignment, name); + if (!e) + continue; + + if (*e != '=') + continue; + + e++; + + if (!locale_is_valid(e)) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Locale %s is not valid, refusing.", e); + if (locale_is_installed(e) <= 0) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Locale %s not installed, refusing.", e); + if (new_locale[p]) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Locale variable %s set twice, refusing.", name); + + new_locale[p] = strdup(e); + if (!new_locale[p]) + return -ENOMEM; + + return 0; + } + + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Locale assignment %s not valid, refusing.", assignment); +} + static int method_set_locale(sd_bus_message *m, void *userdata, sd_bus_error *error) { _cleanup_(locale_variables_freep) char *new_locale[_VARIABLE_LC_MAX] = {}; _cleanup_strv_free_ char **settings = NULL, **l = NULL; Context *c = userdata; bool modified = false; - int interactive, p, r; + int interactive, r; char **i; assert(m); assert(c); - r = bus_message_read_strv_extend(m, &l); + r = sd_bus_message_read_strv(m, &l); if (r < 0) return r; @@ -278,11 +317,13 @@ static int method_set_locale(sd_bus_message *m, void *userdata, sd_bus_error *er return r; /* If single locale without variable name is provided, then we assume it is LANG=. */ - if (strv_length(l) == 1 && !strchr(*l, '=')) { - if (!locale_is_valid(*l)) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid Locale data."); + if (strv_length(l) == 1 && !strchr(l[0], '=')) { + if (!locale_is_valid(l[0])) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid locale specification: %s", l[0]); + if (locale_is_installed(l[0]) <= 0) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified locale is not installed: %s", l[0]); - new_locale[VARIABLE_LANG] = strdup(*l); + new_locale[VARIABLE_LANG] = strdup(l[0]); if (!new_locale[VARIABLE_LANG]) return -ENOMEM; @@ -291,31 +332,9 @@ static int method_set_locale(sd_bus_message *m, void *userdata, sd_bus_error *er /* Check whether a variable is valid */ STRV_FOREACH(i, l) { - bool valid = false; - - for (p = 0; p < _VARIABLE_LC_MAX; p++) { - size_t k; - const char *name; - - name = locale_variable_to_string(p); - assert(name); - - k = strlen(name); - if (startswith(*i, name) && - (*i)[k] == '=' && - locale_is_valid((*i) + k + 1)) { - valid = true; - - new_locale[p] = strdup((*i) + k + 1); - if (!new_locale[p]) - return -ENOMEM; - - break; - } - } - - if (!valid) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid Locale data."); + r = process_locale_list_item(*i, new_locale, error); + if (r < 0) + return r; } /* If LANG was specified, but not LANGUAGE, check if we should @@ -338,7 +357,7 @@ static int method_set_locale(sd_bus_message *m, void *userdata, sd_bus_error *er } /* Merge with the current settings */ - for (p = 0; p < _VARIABLE_LC_MAX; p++) + for (LocaleVariable p = 0; p < _VARIABLE_LC_MAX; p++) if (!isempty(c->locale[p]) && isempty(new_locale[p])) { new_locale[p] = strdup(c->locale[p]); if (!new_locale[p]) @@ -347,7 +366,7 @@ static int method_set_locale(sd_bus_message *m, void *userdata, sd_bus_error *er locale_simplify(new_locale); - for (p = 0; p < _VARIABLE_LC_MAX; p++) + for (LocaleVariable p = 0; p < _VARIABLE_LC_MAX; p++) if (!streq_ptr(c->locale[p], new_locale[p])) { modified = true; break; @@ -372,7 +391,7 @@ static int method_set_locale(sd_bus_message *m, void *userdata, sd_bus_error *er if (r == 0) return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */ - for (p = 0; p < _VARIABLE_LC_MAX; p++) + for (LocaleVariable p = 0; p < _VARIABLE_LC_MAX; p++) free_and_replace(c->locale[p], new_locale[p]); r = locale_write_data(c, &settings); |