keep other method for now, consider dropping later. Supporting relative links here could be problematic as timezones in /usr/share/zoneinfo are often themselves symlinks (and symlinks to symlinks), so this implamentation only only support absolute links. --- src/timedate/timedated.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+)
diff --git a/src/timedate/timedated.c b/src/timedate/timedated.c index 09fd808..456e409 100644 --- a/src/timedate/timedated.c +++ b/src/timedate/timedated.c @@ -24,6 +24,7 @@ #include <errno.h> #include <string.h> #include <unistd.h> +#include <sys/stat.h> #include "util.h" #include "strv.h" @@ -174,9 +175,35 @@ static void verify_timezone(void) { static int read_data(void) { int r; + struct stat st; free_data(); + r = lstat("/etc/localtime", &st); + if (r < 0) { + log_warning("lstat() of %s failed: %m", "/etc/localtime"); + } else if (!S_ISLNK(st.st_mode)) { + log_warning("/etc/localtime should be an absolute symlink to a timezone data file in /usr/share/zoneinfo/"); + } else { + char *t; + + r = readlink_malloc("/etc/localtime", &t); + if (r < 0) { + log_warning("Failed to get target of %s: %m", "/etc/localtime"); + } else if (!startswith(t, "/usr/share/zoneinfo/")) { + log_warning("/etc/localtime should be an absolute symlink to a timezone data file in /usr/share/zoneinfo/"); + } else { + tz.zone = strdup(t + strlen("/usr/share/zoneinfo/")); + free(t); + if (!tz.zone) + return log_oom(); + + goto have_timezone; + } + + free(t); + } + r = read_one_line_file("/etc/timezone", &tz.zone); if (r < 0) { if (r != -ENOENT) @@ -192,6 +219,7 @@ static int read_data(void) { #endif } +have_timezone: if (isempty(tz.zone)) { free(tz.zone); tz.zone = NULL; -- 1.7.10.4 _______________________________________________ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel