libgmime: Build with --disable-crypto
[termux-packages] / packages / glib / glib-gtimezone.c.patch
... / ...
CommitLineData
1Patch submitted at https://bugzilla.gnome.org/show_bug.cgi?id=771304
2
3diff -u -r ../glib-2.54.2/glib/gtimezone.c ./glib/gtimezone.c
4--- ../glib-2.54.2/glib/gtimezone.c 2017-07-14 01:03:39.000000000 +0200
5+++ ./glib/gtimezone.c 2017-12-09 02:03:46.797229494 +0100
6@@ -43,6 +43,13 @@
7 #include <windows.h>
8 #endif
9
10+#ifdef __ANDROID__
11+#include <arpa/inet.h>
12+#include <fcntl.h>
13+#include <sys/system_properties.h>
14+#include <unistd.h>
15+#endif
16+
17 /**
18 * SECTION:timezone
19 * @title: GTimeZone
20@@ -392,7 +399,105 @@
21 gtz->transitions = NULL;
22 }
23
24-#ifdef G_OS_UNIX
25+#ifdef __ANDROID__
26+/* Android does not have /etc/localtime but uses a system property for the
27+ the current timezone. There are no files under /usr/share/zoneinfo,
28+ instead a single /system/usr/share/zoneinfo/tzdata which are all zoneinfo
29+ files compiled together with the following tool:
30+ https://android.googlesource.com/platform/external/icu/+/master/tools/ZoneCompactor.java */
31+static GBytes*
32+zone_info_android (const gchar *identifier)
33+{
34+ struct tzdata_header
35+ {
36+ char version[12];
37+ uint32_t index_offset;
38+ uint32_t data_offset;
39+ uint32_t zonetab_offset;
40+ } __attribute__((packed)) header;
41+
42+ struct tzdata_index_entry
43+ {
44+ char name[40];
45+ uint32_t offset;
46+ uint32_t length;
47+ uint32_t unused;
48+ } __attribute__((packed)) entry;
49+
50+ char sys_timezone[PROP_VALUE_MAX];
51+
52+ if (identifier == NULL)
53+ {
54+ if (__system_property_get("persist.sys.timezone", sys_timezone) < 1)
55+ {
56+ g_warning("__system_property_get(\"persist.sys.timezone\") failed\n");
57+ return NULL;
58+ }
59+ identifier = sys_timezone;
60+ }
61+
62+ int tzdata_fd = open("/system/usr/share/zoneinfo/tzdata", O_RDONLY);
63+ if (tzdata_fd < 0)
64+ {
65+ g_warning("Failed opening tzdata");
66+ return NULL;
67+ }
68+
69+ if (read(tzdata_fd, &header, sizeof(header)) < (ssize_t) sizeof(header))
70+ {
71+ g_warning("Failed reading tzdata header");
72+ goto error;
73+ }
74+
75+ header.index_offset = htonl(header.index_offset);
76+ header.data_offset = htonl(header.data_offset);
77+
78+ uint32_t current_offset = header.index_offset;
79+ while (current_offset < header.data_offset)
80+ {
81+ if (read(tzdata_fd, &entry, sizeof(entry)) < (ssize_t) sizeof(entry))
82+ {
83+ g_warning("Failed reading tzdata index entry");
84+ goto error;
85+ }
86+
87+ if (strcmp(entry.name, identifier) == 0)
88+ {
89+ entry.offset = htonl(entry.offset);
90+ entry.length = htonl(entry.length);
91+ if (entry.length == 0)
92+ {
93+ g_warning("Invalid tzdata entry with length zero");
94+ goto error;
95+ }
96+
97+ if (lseek(tzdata_fd, header.data_offset + entry.offset, SEEK_SET) == -1)
98+ {
99+ g_warning("Failed seeking to tzdata entry");
100+ goto error;
101+ }
102+
103+ guint8* data = g_malloc(entry.length);
104+ if (read(tzdata_fd, data, entry.length) < entry.length)
105+ {
106+ g_warning("Failed reading tzdata entry");
107+ g_free(data);
108+ goto error;
109+ }
110+
111+ close(tzdata_fd);
112+ return g_bytes_new_take(data, entry.length);
113+ }
114+ }
115+
116+error:
117+ close(tzdata_fd);
118+
119+ return NULL;
120+}
121+
122+#elif defined(G_OS_UNIX)
123+
124 static GBytes*
125 zone_info_unix (const gchar *identifier)
126 {
127@@ -436,6 +541,10 @@
128 return zoneinfo;
129 }
130
131+#endif
132+
133+#ifdef G_OS_UNIX
134+
135 static void
136 init_zone_from_iana_info (GTimeZone *gtz, GBytes *zoneinfo)
137 {
138@@ -1387,7 +1496,11 @@
139 if (tz->t_info == NULL)
140 {
141 #ifdef G_OS_UNIX
142+# ifdef __ANDROID__
143+ GBytes *zoneinfo = zone_info_android (identifier);
144+# else
145 GBytes *zoneinfo = zone_info_unix (identifier);
146+# endif
147 if (!zoneinfo)
148 zone_for_constant_offset (tz, "UTC");
149 else