[systemd-devel] [PATCH] timedated: gather timezone from /etc/localtime sym target

Shawn Landen shawnlandden at gmail.com
Wed Aug 8 12:29:42 PDT 2012


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.

v2 - Add ZONEINFO_PATH
   - Restructured the patch so its very straight forward to remove
support for the old methods. (some log_warning()s should then be converted
to log_error() too)
---
 src/timedate/timedated.c |   34 ++++++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/src/timedate/timedated.c b/src/timedate/timedated.c
index 09fd808..01d01b6 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"
@@ -74,6 +75,10 @@
         BUS_GENERIC_INTERFACES_LIST             \
         "org.freedesktop.timedate1\0"
 
+#ifndef ZONEINFO_PATH
+#  define ZONEINFO_PATH "/usr/share/zoneinfo/"
+#endif
+
 const char timedate_interface[] _introspect_("timedate1") = INTERFACE;
 
 typedef struct TZ {
@@ -174,9 +179,37 @@ 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 %s", ZONEINFO_PATH);
+        } 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, ZONEINFO_PATH)) {
+                        log_warning("/etc/localtime should be an absolute symlink to a timezone data file in %s", ZONEINFO_PATH);
+                } else {
+                        tz.zone = strdup(t + strlen(ZONEINFO_PATH));
+                        if (!tz.zone) {
+                                free(t);
+                                return log_oom();
+                        }
+
+                        free(t);
+                        goto have_timeone;
+                }
+
+                free(t);
+        }
+
         r = read_one_line_file("/etc/timezone", &tz.zone);
         if (r < 0) {
                 if (r != -ENOENT)
@@ -192,6 +225,7 @@ static int read_data(void) {
 #endif
         }
 
+have_timezone:
         if (isempty(tz.zone)) {
                 free(tz.zone);
                 tz.zone = NULL;
-- 
1.7.10.4



More information about the systemd-devel mailing list