From 7568345034f2890af745747783c5abfbf6eccf0f Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 7 Jul 2014 11:49:48 +0200 Subject: shared: make timezone and locale enumeration and validation generic This way we can reuse it other code thatn just localectl/localed + timedatectl/timedated. --- src/timedate/timedatectl.c | 60 ++++------------------------------------------ src/timedate/timedated.c | 53 ++-------------------------------------- 2 files changed, 7 insertions(+), 106 deletions(-) (limited to 'src/timedate') diff --git a/src/timedate/timedatectl.c b/src/timedate/timedatectl.c index a8769e4180..203b5be6dd 100644 --- a/src/timedate/timedatectl.c +++ b/src/timedate/timedatectl.c @@ -355,69 +355,19 @@ static int set_ntp(sd_bus *bus, char **args, unsigned n) { } static int list_timezones(sd_bus *bus, char **args, unsigned n) { - _cleanup_fclose_ FILE *f = NULL; _cleanup_strv_free_ char **zones = NULL; - size_t n_zones = 0; + int r; assert(args); assert(n == 1); - f = fopen("/usr/share/zoneinfo/zone.tab", "re"); - if (!f) { - log_error("Failed to open time zone database: %m"); - return -errno; - } - - for (;;) { - char l[LINE_MAX], *p, **z, *w; - size_t k; - - if (!fgets(l, sizeof(l), f)) { - if (feof(f)) - break; - - log_error("Failed to read time zone database: %m"); - return -errno; - } - - p = strstrip(l); - - if (isempty(p) || *p == '#') - continue; - - /* Skip over country code */ - p += strcspn(p, WHITESPACE); - p += strspn(p, WHITESPACE); - - /* Skip over coordinates */ - p += strcspn(p, WHITESPACE); - p += strspn(p, WHITESPACE); - - /* Found timezone name */ - k = strcspn(p, WHITESPACE); - if (k <= 0) - continue; - - w = strndup(p, k); - if (!w) - return log_oom(); - - z = realloc(zones, sizeof(char*) * (n_zones + 2)); - if (!z) { - free(w); - return log_oom(); - } - - zones = z; - zones[n_zones++] = w; + r = get_timezones(&zones); + if (r < 0) { + log_error("Failed to read list of time zones: %s", strerror(-r)); + return r; } - if (zones) - zones[n_zones] = NULL; - pager_open_if_enabled(); - - strv_sort(zones); strv_print(zones); return 0; diff --git a/src/timedate/timedated.c b/src/timedate/timedated.c index 204031fe77..5d3b8c41e6 100644 --- a/src/timedate/timedated.c +++ b/src/timedate/timedated.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "sd-id128.h" #include "sd-messages.h" @@ -58,54 +59,6 @@ static void context_free(Context *c, sd_bus *bus) { bus_verify_polkit_async_registry_free(bus, c->polkit_registry); } -static bool valid_timezone(const char *name) { - const char *p; - char *t; - bool slash = false; - int r; - struct stat st; - - assert(name); - - if (*name == '/' || *name == 0) - return false; - - for (p = name; *p; p++) { - if (!(*p >= '0' && *p <= '9') && - !(*p >= 'a' && *p <= 'z') && - !(*p >= 'A' && *p <= 'Z') && - !(*p == '-' || *p == '_' || *p == '+' || *p == '/')) - return false; - - if (*p == '/') { - - if (slash) - return false; - - slash = true; - } else - slash = false; - } - - if (slash) - return false; - - t = strappend("/usr/share/zoneinfo/", name); - if (!t) - return false; - - r = stat(t, &st); - free(t); - - if (r < 0) - return false; - - if (!S_ISREG(st.st_mode)) - return false; - - return true; -} - static int context_read_data(Context *c) { _cleanup_free_ char *t = NULL; int r; @@ -502,7 +455,7 @@ static int method_set_timezone(sd_bus *bus, sd_bus_message *m, void *userdata, s if (r < 0) return r; - if (!valid_timezone(z)) + if (!timezone_is_valid(z)) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid time zone '%s'", z); if (streq_ptr(z, c->zone)) @@ -737,8 +690,6 @@ static int method_set_ntp(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus return sd_bus_reply_method_return(m, NULL); } -#include - static const sd_bus_vtable timedate_vtable[] = { SD_BUS_VTABLE_START(0), SD_BUS_PROPERTY("Timezone", "s", NULL, offsetof(Context, zone), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), -- cgit v1.2.3-54-g00ecf