]> git.pld-linux.org Git - packages/php.git/blame - php-systzdata.patch
- make it possible to coinstall phpXY-pdo-pgsql
[packages/php.git] / php-systzdata.patch
CommitLineData
e07925ee 1
2Add support for use of the system timezone database, rather
3than embedding a copy. Discussed upstream but was not desired.
4
5History:
e07925ee 6r3: fix a crash if /usr/share/zoneinfo doesn't exist (Raphael Geissert)
7r2: add filesystem trawl to set up name alias index
8r1: initial revision
9
e7819c98
ER
10--- php-5.2.5/ext/date/lib/timelib.m4.systzdata
11+++ php-5.2.5/ext/date/lib/timelib.m4
12@@ -78,3 +78,17 @@ stdlib.h
13
14 dnl Check for strtoll, atoll
15 AC_CHECK_FUNCS(strtoll atoll strftime)
16+
17+PHP_ARG_WITH(system-tzdata, for use of system timezone data,
18+[ --with-system-tzdata[=DIR] to specify use of system timezone data],
19+no, no)
20+
21+if test "$PHP_SYSTEM_TZDATA" != "no"; then
22+ AC_DEFINE(HAVE_SYSTEM_TZDATA, 1, [Define if system timezone data is used])
23+
24+ if test "$PHP_SYSTEM_TZDATA" != "yes"; then
25+ AC_DEFINE_UNQUOTED(HAVE_SYSTEM_TZDATA_PREFIX, "$PHP_SYSTEM_TZDATA",
26+ [Define for location of system timezone data])
27+ fi
28+fi
29+
30--- php-5.2.5/ext/date/lib/parse_tz.c.systzdata
31+++ php-5.2.5/ext/date/lib/parse_tz.c
e07925ee 32@@ -20,6 +20,16 @@
33
34 #include "timelib.h"
35
36+#ifdef HAVE_SYSTEM_TZDATA
37+#include <sys/mman.h>
38+#include <sys/stat.h>
39+#include <limits.h>
40+#include <fcntl.h>
41+#include <unistd.h>
42+
43+#include "php_scandir.h"
44+#endif
45+
46 #include <stdio.h>
47
48 #ifdef HAVE_LOCALE_H
e7819c98 49@@ -31,7 +41,10 @@
e07925ee 50 #else
51 #include <strings.h>
52 #endif
53+
54+#ifndef HAVE_SYSTEM_TZDATA
55 #include "timezonedb.h"
56+#endif
e07925ee 57
58 #if (defined(__APPLE__) || defined(__APPLE_CC__)) && (defined(__BIG_ENDIAN__) || defined(__LITTLE_ENDIAN__))
59 # if defined(__LITTLE_ENDIAN__)
e7819c98 60@@ -206,6 +219,195 @@ void timelib_dump_tzinfo(timelib_tzinfo
e07925ee 61 }
62 }
63
e07925ee 64+#ifdef HAVE_SYSTEM_TZDATA
65+
66+#ifdef HAVE_SYSTEM_TZDATA_PREFIX
67+#define ZONEINFO_PREFIX HAVE_SYSTEM_TZDATA_PREFIX
68+#else
69+#define ZONEINFO_PREFIX "/usr/share/zoneinfo"
70+#endif
71+
e07925ee 72+static const timelib_tzdb *timezonedb_system = NULL;
73+
e07925ee 74+/* Filter out some non-tzdata files and the posix/right databases, if
75+ * present. */
76+static int index_filter(const struct dirent *ent)
77+{
78+ return strcmp(ent->d_name, ".") != 0
79+ && strcmp(ent->d_name, "..") != 0
80+ && strcmp(ent->d_name, "posix") != 0
81+ && strcmp(ent->d_name, "posixrules") != 0
82+ && strcmp(ent->d_name, "right") != 0
83+ && strstr(ent->d_name, ".tab") == NULL;
84+}
85+
e07925ee 86+/* Create the zone identifier index by trawling the filesystem. */
87+static void create_zone_index(timelib_tzdb *db)
88+{
89+ size_t dirstack_size, dirstack_top;
90+ size_t index_size, index_next;
91+ timelib_tzdb_index_entry *db_index;
92+ char **dirstack;
93+
94+ /* LIFO stack to hold directory entries to scan; each slot is a
95+ * directory name relative to the zoneinfo prefix. */
96+ dirstack_size = 32;
97+ dirstack = malloc(dirstack_size * sizeof *dirstack);
98+ dirstack_top = 1;
99+ dirstack[0] = strdup("");
100+
101+ /* Index array. */
102+ index_size = 64;
103+ db_index = malloc(index_size * sizeof *db_index);
104+ index_next = 0;
105+
106+ do {
107+ struct dirent **ents;
108+ char name[PATH_MAX], *top;
109+ int count;
110+
111+ /* Pop the top stack entry, and iterate through its contents. */
112+ top = dirstack[--dirstack_top];
113+ snprintf(name, sizeof name, ZONEINFO_PREFIX "/%s", top);
114+
115+ count = php_scandir(name, &ents, index_filter, php_alphasort);
116+
117+ while (count > 0) {
118+ struct stat st;
119+ const char *leaf = ents[count - 1]->d_name;
120+
121+ snprintf(name, sizeof name, ZONEINFO_PREFIX "/%s/%s",
122+ top, leaf);
123+
124+ if (strlen(name) && stat(name, &st) == 0) {
125+ /* Name, relative to the zoneinfo prefix. */
126+ const char *root = top;
127+
128+ if (root[0] == '/') root++;
129+
130+ snprintf(name, sizeof name, "%s%s%s", root,
131+ *root ? "/": "", leaf);
132+
133+ if (S_ISDIR(st.st_mode)) {
134+ if (dirstack_top == dirstack_size) {
135+ dirstack_size *= 2;
136+ dirstack = realloc(dirstack,
137+ dirstack_size * sizeof *dirstack);
138+ }
139+ dirstack[dirstack_top++] = strdup(name);
140+ }
141+ else {
142+ if (index_next == index_size) {
143+ index_size *= 2;
144+ db_index = realloc(db_index,
145+ index_size * sizeof *db_index);
146+ }
147+
e7819c98
ER
148+ db_index[index_next].id = strdup(name);
149+ db_index[index_next++].pos = 0;
e07925ee 150+ }
151+ }
152+
153+ free(ents[--count]);
154+ }
155+
156+ if (count != -1) free(ents);
157+ free(top);
158+ } while (dirstack_top);
159+
e07925ee 160+ db->index = db_index;
161+ db->index_size = index_next;
162+
163+ free(dirstack);
164+}
165+
e07925ee 166+/* Return the mmap()ed tzfile if found, else NULL. On success, the
167+ * length of the mapped data is placed in *length. */
168+static char *map_tzfile(const char *timezone, size_t *length)
169+{
170+ char fname[PATH_MAX];
171+ struct stat st;
172+ char *p;
173+ int fd;
174+
e7819c98 175+ if (strstr(timezone, "..") != NULL) {
e07925ee 176+ return NULL;
177+ }
178+
179+ snprintf(fname, sizeof fname, ZONEINFO_PREFIX "/%s", timezone);
180+
181+ fd = open(fname, O_RDONLY);
182+ if (fd == -1) {
183+ return NULL;
e7819c98 184+ } else if (fstat(fd, &st) != 0 || st.st_size < 21) {
e07925ee 185+ close(fd);
186+ return NULL;
187+ }
188+
189+ *length = st.st_size;
190+ p = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
191+ close(fd);
192+
193+ return p != MAP_FAILED ? p : NULL;
194+}
195+
e7819c98 196+const timelib_tzdb *timelib_builtin_db(void)
e07925ee 197+{
e07925ee 198+ if (timezonedb_system == NULL) {
199+ timelib_tzdb *tmp = malloc(sizeof *tmp);
200+
201+ tmp->version = "0.system";
202+ tmp->data = NULL;
203+ create_zone_index(tmp);
e07925ee 204+ timezonedb_system = tmp;
205+ }
e07925ee 206+
207+ return timezonedb_system;
e7819c98
ER
208+}
209+
210+const timelib_tzdb_index_entry *timelib_timezone_builtin_identifiers_list(int *count)
211+{
e07925ee 212+ *count = timezonedb_system->index_size;
213+ return timezonedb_system->index;
e7819c98 214+}
e07925ee 215+
e7819c98
ER
216+int timelib_timezone_id_is_valid(char *timezone, const timelib_tzdb *tzdb)
217+{
218+ char fname[PATH_MAX];
e07925ee 219+
e7819c98 220+ if (strstr(timezone, "..") != NULL) {
e07925ee 221+ return 0;
e7819c98
ER
222+ }
223+
224+ snprintf(fname, sizeof fname, ZONEINFO_PREFIX "/%s", timezone);
e07925ee 225+
e7819c98
ER
226+ return access(fname, R_OK) == 0 ? 1 : 0;
227+}
e07925ee 228+
e7819c98
ER
229+timelib_tzinfo *timelib_parse_tzfile(char *timezone, const timelib_tzdb *tzdb)
230+{
231+ char *tzf, *orig;
232+ timelib_tzinfo *tmp;
233+ size_t len;
e07925ee 234+
e7819c98
ER
235+ orig = map_tzfile(timezone, &len);
236+ if (orig == NULL) {
237+ return NULL;
238+ }
e07925ee 239+
e7819c98 240+ tmp = timelib_tzinfo_ctor(timezone);
e07925ee 241+
e7819c98
ER
242+ tzf = orig + 20;
243+ read_header(&tzf, tmp);
244+ read_transistions(&tzf, tmp);
245+ read_types(&tzf, tmp);
e07925ee 246+
e7819c98
ER
247+ munmap(orig, len);
248+
249+ return tmp;
250+}
251+#else /* !HAVE_SYSTEM_TZDATA */
e07925ee 252+
e7819c98
ER
253 static int seek_to_tz_position(const unsigned char **tzf, char *timezone, const timelib_tzdb *tzdb)
254 {
255 int left = 0, right = tzdb->index_size - 1;
256@@ -279,6 +481,7 @@ timelib_tzinfo *timelib_parse_tzfile(cha
257
258 return tmp;
259 }
260+#endif
261
262 static ttinfo* fetch_timezone_offset(timelib_tzinfo *tz, timelib_sll ts, timelib_sll *transition_time)
263 {
This page took 0.051076 seconds and 4 git commands to generate.