time-util: add new get_timezone() call to get local timezone

Let's move the timedated-specific code to time-util.h and make it
generic.
This commit is contained in:
Lennart Poettering 2015-08-26 19:14:51 +02:00
parent a00458421d
commit 5c904ba5a5
3 changed files with 42 additions and 26 deletions

View file

@ -26,6 +26,7 @@
#include "util.h"
#include "time-util.h"
#include "path-util.h"
#include "strv.h"
usec_t now(clockid_t clock_id) {
@ -971,7 +972,10 @@ bool timezone_is_valid(const char *name) {
const char *p, *t;
struct stat st;
if (!name || *name == 0 || *name == '/')
if (isempty(name))
return false;
if (name[0] == '/')
return false;
for (p = name; *p; p++) {
@ -1021,3 +1025,30 @@ clockid_t clock_boottime_or_monotonic(void) {
return clock;
}
int get_timezone(char **timezone) {
_cleanup_free_ char *t = NULL;
const char *e;
char *z;
int r;
r = readlink_malloc("/etc/localtime", &t);
if (r < 0)
return r; /* returns EINVAL if not a symlink */
e = path_startswith(t, "/usr/share/zoneinfo/");
if (!e)
e = path_startswith(t, "../usr/share/zoneinfo/");
if (!e)
return -EINVAL;
if (!timezone_is_valid(e))
return -EINVAL;
z = strdup(e);
if (!z)
return -ENOMEM;
*timezone = z;
return 0;
}

View file

@ -110,3 +110,5 @@ bool timezone_is_valid(const char *name);
clockid_t clock_boottime_or_monotonic(void);
#define xstrftime(buf, fmt, tm) assert_se(strftime(buf, ELEMENTSOF(buf), fmt, tm) > 0)
int get_timezone(char **timezone);

View file

@ -68,32 +68,15 @@ static int context_read_data(Context *c) {
assert(c);
r = readlink_malloc("/etc/localtime", &t);
if (r < 0) {
if (r == -EINVAL)
log_warning("/etc/localtime should be a symbolic link to a time zone data file in /usr/share/zoneinfo/.");
else
log_warning_errno(r, "Failed to get target of /etc/localtime: %m");
} else {
const char *e;
r = get_timezone(&t);
if (r == -EINVAL)
log_warning_errno(r, "/etc/localtime should be a symbolic link to a time zone data file in /usr/share/zoneinfo/.");
else if (r < 0)
log_warning_errno(r, "Failed to get target of /etc/localtime: %m");
e = path_startswith(t, "/usr/share/zoneinfo/");
if (!e)
e = path_startswith(t, "../usr/share/zoneinfo/");
if (!e)
log_warning("/etc/localtime should be a symbolic link to a time zone data file in /usr/share/zoneinfo/.");
else {
c->zone = strdup(e);
if (!c->zone)
return log_oom();
}
}
if (isempty(c->zone)) {
free(c->zone);
c->zone = NULL;
}
free(c->zone);
c->zone = t;
t = NULL;
c->local_rtc = clock_is_localtime() > 0;