time-util: add new get_timezone() call to get local timezone
authorLennart Poettering <lennart@poettering.net>
Wed, 26 Aug 2015 17:14:51 +0000 (19:14 +0200)
committerLennart Poettering <lennart@poettering.net>
Wed, 26 Aug 2015 18:36:42 +0000 (20:36 +0200)
Let's move the timedated-specific code to time-util.h and make it
generic.

src/basic/time-util.c
src/basic/time-util.h
src/timedate/timedated.c

index e278196..3d8d5d7 100644 (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;
+}
index 2aba042..03a47f3 100644 (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);
index 21d6ee4..42ae70f 100644 (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;