mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-01-26 22:16:16 +01:00
parent
62a88d9f38
commit
8cc71d35d0
107
glib/gtimezone.c
107
glib/gtimezone.c
@ -440,6 +440,88 @@ zone_for_constant_offset (GTimeZone *gtz, const gchar *name)
|
||||
}
|
||||
|
||||
#ifdef G_OS_UNIX
|
||||
|
||||
#if defined(__sun) && defined(__SVR4)
|
||||
/*
|
||||
* only used by Illumos distros or Solaris < 11: parse the /etc/default/init
|
||||
* text file looking for TZ= followed by the timezone, possibly quoted
|
||||
*
|
||||
*/
|
||||
static gchar *
|
||||
zone_identifier_illumos (void)
|
||||
{
|
||||
gchar *resolved_identifier = NULL;
|
||||
gchar *contents = NULL;
|
||||
const gchar *line_start = NULL;
|
||||
gsize tz_len = 0;
|
||||
|
||||
if (!g_file_get_contents ("/etc/default/init", &contents, NULL, NULL) )
|
||||
return NULL;
|
||||
|
||||
/* is TZ= the first/only line in the file? */
|
||||
if (strncmp (contents, "TZ=", 3) == 0)
|
||||
{
|
||||
/* found TZ= on the first line, skip over the TZ= */
|
||||
line_start = contents + 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* find a newline followed by TZ= */
|
||||
line_start = strstr (contents, "\nTZ=");
|
||||
if (line_start != NULL)
|
||||
line_start = line_start + 4; /* skip past the \nTZ= */
|
||||
}
|
||||
|
||||
/*
|
||||
* line_start is NULL if we didn't find TZ= at the start of any line,
|
||||
* otherwise it points to what is after the '=' (possibly '\0')
|
||||
*/
|
||||
if (line_start == NULL || *line_start == '\0')
|
||||
return NULL;
|
||||
|
||||
/* skip past a possible opening " or ' */
|
||||
if (*line_start == '"' || *line_start == '\'')
|
||||
line_start++;
|
||||
|
||||
/*
|
||||
* loop over the next few characters, building up the length of
|
||||
* the timezone identifier, ending with end of string, newline or
|
||||
* a " or ' character
|
||||
*/
|
||||
while (*(line_start + tz_len) != '\0' &&
|
||||
*(line_start + tz_len) != '\n' &&
|
||||
*(line_start + tz_len) != '"' &&
|
||||
*(line_start + tz_len) != '\'')
|
||||
tz_len++;
|
||||
|
||||
if (tz_len > 0)
|
||||
{
|
||||
/* found it */
|
||||
resolved_identifier = g_strndup (line_start, tz_len);
|
||||
g_strchomp (resolved_identifier);
|
||||
g_free (contents);
|
||||
return g_steal_pointer (&resolved_identifier);
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
#endif /* defined(__sun) && defined(__SRVR) */
|
||||
|
||||
/*
|
||||
* returns the path to the top of the Olson zoneinfo timezone hierarchy.
|
||||
*/
|
||||
static const gchar *
|
||||
zone_info_base_dir (void)
|
||||
{
|
||||
if (g_file_test ("/usr/share/zoneinfo", G_FILE_TEST_IS_DIR))
|
||||
return "/usr/share/zoneinfo"; /* Most distros */
|
||||
else if (g_file_test ("/usr/share/lib/zoneinfo", G_FILE_TEST_IS_DIR))
|
||||
return "/usr/share/lib/zoneinfo"; /* Illumos distros */
|
||||
|
||||
/* need a better fallback case */
|
||||
return "/usr/share/zoneinfo";
|
||||
}
|
||||
|
||||
static gchar *
|
||||
zone_identifier_unix (void)
|
||||
{
|
||||
@ -458,17 +540,26 @@ zone_identifier_unix (void)
|
||||
G_FILE_ERROR_INVAL);
|
||||
g_clear_error (&read_link_err);
|
||||
|
||||
/* Fallback to the content of /var/db/zoneinfo or /etc/timezone
|
||||
* if /etc/localtime is not a symlink. /var/db/zoneinfo is
|
||||
* where 'tzsetup' program on FreeBSD and DragonflyBSD stores
|
||||
* the timezone chosen by the user. /etc/timezone is where user
|
||||
* choice is expressed on Gentoo OpenRC and others. */
|
||||
/* if /etc/localtime is not a symlink, try:
|
||||
* - /var/db/zoneinfo : 'tzsetup' program on FreeBSD and
|
||||
* DragonflyBSD stores the timezone chosen by the user there.
|
||||
* - /etc/timezone : Gentoo, OpenRC, and others store
|
||||
* the user choice there.
|
||||
* - call zone_identifier_illumos iff __sun and __SVR4 are defined,
|
||||
* as a last-ditch effort to parse the TZ= setting from within
|
||||
* /etc/default/init
|
||||
*/
|
||||
if (not_a_symlink && (g_file_get_contents ("/var/db/zoneinfo",
|
||||
&resolved_identifier,
|
||||
NULL, NULL) ||
|
||||
g_file_get_contents ("/etc/timezone",
|
||||
&resolved_identifier,
|
||||
NULL, NULL)))
|
||||
NULL, NULL)
|
||||
#if defined(__sun) && defined(__SVR4)
|
||||
||
|
||||
(resolved_identifier = zone_identifier_illumos ())
|
||||
#endif
|
||||
))
|
||||
g_strchomp (resolved_identifier);
|
||||
else
|
||||
{
|
||||
@ -487,7 +578,7 @@ zone_identifier_unix (void)
|
||||
|
||||
tzdir = g_getenv ("TZDIR");
|
||||
if (tzdir == NULL)
|
||||
tzdir = "/usr/share/zoneinfo";
|
||||
tzdir = zone_info_base_dir ();
|
||||
|
||||
/* Strip the prefix and slashes if possible. */
|
||||
if (g_str_has_prefix (resolved_identifier, tzdir))
|
||||
@ -520,7 +611,7 @@ zone_info_unix (const gchar *identifier,
|
||||
|
||||
tzdir = g_getenv ("TZDIR");
|
||||
if (tzdir == NULL)
|
||||
tzdir = "/usr/share/zoneinfo";
|
||||
tzdir = zone_info_base_dir ();
|
||||
|
||||
/* identifier can be a relative or absolute path name;
|
||||
if relative, it is interpreted starting from /usr/share/zoneinfo
|
||||
|
Loading…
Reference in New Issue
Block a user