libgmime: Build with --disable-crypto
[termux-packages] / packages / glib / glib-gtimezone.c.patch
1 Patch submitted at https://bugzilla.gnome.org/show_bug.cgi?id=771304
2
3 diff -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