libgmime: Build with --disable-crypto
[termux-packages] / packages / glib / glib-gtimezone.c.patch
CommitLineData
69fd9a5c
FF
1Patch submitted at https://bugzilla.gnome.org/show_bug.cgi?id=771304
2
dcaafa88
FF
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
c780e809 6@@ -43,6 +43,13 @@
8aef3a59
FF
7 #include <windows.h>
8 #endif
9
10+#ifdef __ANDROID__
c780e809 11+#include <arpa/inet.h>
8aef3a59
FF
12+#include <fcntl.h>
13+#include <sys/system_properties.h>
c780e809 14+#include <unistd.h>
8aef3a59
FF
15+#endif
16+
17 /**
18 * SECTION:timezone
19 * @title: GTimeZone
dcaafa88
FF
20@@ -392,7 +399,105 @@
21 gtz->transitions = NULL;
22 }
23
24-#ifdef G_OS_UNIX
8aef3a59 25+#ifdef __ANDROID__
dcaafa88
FF
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;
8aef3a59
FF
40+ } __attribute__((packed)) header;
41+
dcaafa88
FF
42+ struct tzdata_index_entry
43+ {
44+ char name[40];
45+ uint32_t offset;
46+ uint32_t length;
47+ uint32_t unused;
8aef3a59
FF
48+ } __attribute__((packed)) entry;
49+
69fd9a5c 50+ char sys_timezone[PROP_VALUE_MAX];
dcaafa88
FF
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;
8aef3a59 60+ }
dcaafa88
FF
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;
8aef3a59 67+ }
8aef3a59 68+
dcaafa88
FF
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+ {
8aef3a59
FF
83+ g_warning("Failed reading tzdata index entry");
84+ goto error;
85+ }
dcaafa88
FF
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);
8aef3a59 113+ }
8aef3a59 114+ }
dcaafa88 115+
8aef3a59 116+error:
dcaafa88
FF
117+ close(tzdata_fd);
118+
8aef3a59 119+ return NULL;
dcaafa88
FF
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 @@
8aef3a59 128 return zoneinfo;
8aef3a59
FF
129 }
130
dcaafa88
FF
131+#endif
132+
133+#ifdef G_OS_UNIX
134+
8aef3a59 135 static void
dcaafa88
FF
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