[glib] gtimezone: Fallback to /var/db/zoneinfo on FreeBSD



commit 50677e933616ac107f26d2d133d46561e26d7e36
Author: Ting-Wei Lan <lantw src gnome org>
Date:   Sun Apr 29 01:47:15 2018 +0800

    gtimezone: Fallback to /var/db/zoneinfo on FreeBSD
    
    The timezone setup utility of FreeBSD, tzsetup, which is run during the
    installation, creates /etc/localtime by copying the chosen timezone file
    from /usr/share/zoneinfo. Although it can correctly deal with the case
    where /etc/localtime is a symlink, it is not the default and there is no
    user interface to change the default copying behaviour.
    
    Fortunately, tzsetup has been modified to write the name of the chosen
    timezone to /var/db/zoneinfo in 2009, so we can know the name of the
    current timezone by reading it. DragonflyBSD also seems to do the same
    thing in its tzsetup.
    
    https://svnweb.freebsd.org/changeset/base/198267
    https://bugzilla.gnome.org/show_bug.cgi?id=795165

 glib/gtimezone.c | 38 ++++++++++++++++++++++++++++----------
 1 file changed, 28 insertions(+), 10 deletions(-)
---
diff --git a/glib/gtimezone.c b/glib/gtimezone.c
index 69464cd00..896c117bc 100644
--- a/glib/gtimezone.c
+++ b/glib/gtimezone.c
@@ -434,23 +434,41 @@ zone_info_unix (const gchar  *identifier,
     {
       gsize prefix_len = 0;
       gchar *canonical_path = NULL;
+      GError *read_link_err = NULL;
 
       filename = g_strdup ("/etc/localtime");
 
       /* Resolve the actual timezone pointed to by /etc/localtime. */
-      resolved_identifier = g_file_read_link (filename, NULL);
+      resolved_identifier = g_file_read_link (filename, &read_link_err);
       if (resolved_identifier == NULL)
         {
-          /* Error */
-          if (out_identifier != NULL)
-            *out_identifier = NULL;
-          return NULL;
+          gboolean not_a_symlink = g_error_matches (read_link_err,
+                                                    G_FILE_ERROR,
+                                                    G_FILE_ERROR_INVAL);
+          g_clear_error (&read_link_err);
+
+          /* Fallback to the content of /var/db/zoneinfo if /etc/localtime is
+           * not a symlink. This is where 'tzsetup' program on FreeBSD and
+           * DragonflyBSD stores the timezone chosen by the user. */
+          if (not_a_symlink && g_file_get_contents ("/var/db/zoneinfo",
+                                                    &resolved_identifier,
+                                                    NULL, NULL))
+            g_strchomp (resolved_identifier);
+          else
+            {
+              /* Error */
+              if (out_identifier != NULL)
+                *out_identifier = NULL;
+              return NULL;
+            }
+        }
+      else
+        {
+          /* Resolve relative path */
+          canonical_path = g_canonicalize_filename (resolved_identifier, "/etc");
+          g_free (resolved_identifier);
+          resolved_identifier = g_steal_pointer (&canonical_path);
         }
-
-      /* Resolve relative path */
-      canonical_path = g_canonicalize_filename (resolved_identifier, "/etc");
-      g_free (resolved_identifier);
-      resolved_identifier = g_steal_pointer (&canonical_path);
 
       /* Strip the prefix and slashes if possible. */
       if (g_str_has_prefix (resolved_identifier, tzdir))


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]