]> git.pld-linux.org Git - packages/php.git/blob - php-systzdata.patch
use /usr/sbin/php-fpm as other branches
[packages/php.git] / php-systzdata.patch
1
2 Add support for use of the system timezone database, rather
3 than embedding a copy.  Discussed upstream but was not desired.
4
5 History:
6 r3: fix a crash if /usr/share/zoneinfo doesn't exist (Raphael Geissert)
7 r2: add filesystem trawl to set up name alias index
8 r1: initial revision
9
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
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
49 @@ -31,7 +41,10 @@
50  #else
51  #include <strings.h>
52  #endif
53 +
54 +#ifndef HAVE_SYSTEM_TZDATA
55  #include "timezonedb.h"
56 +#endif
57  
58  #if (defined(__APPLE__) || defined(__APPLE_CC__)) && (defined(__BIG_ENDIAN__) || defined(__LITTLE_ENDIAN__))
59  # if defined(__LITTLE_ENDIAN__)
60 @@ -206,6 +219,195 @@ void timelib_dump_tzinfo(timelib_tzinfo 
61         }
62  }
63  
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 +
72 +static const timelib_tzdb *timezonedb_system = NULL;
73 +
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 +
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 +
148 +                                       db_index[index_next].id = strdup(name);
149 +                                       db_index[index_next++].pos = 0;
150 +                               }
151 +                       }
152 +
153 +                       free(ents[--count]);
154 +               }
155 +               
156 +               if (count != -1) free(ents);
157 +               free(top);
158 +       } while (dirstack_top);
159 +
160 +       db->index = db_index;
161 +       db->index_size = index_next;
162 +
163 +       free(dirstack);
164 +}
165 +
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 +       
175 +       if (strstr(timezone, "..") != NULL) {
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;
184 +       } else if (fstat(fd, &st) != 0 || st.st_size < 21) {
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 +
196 +const timelib_tzdb *timelib_builtin_db(void)
197 +{
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);
204 +               timezonedb_system = tmp;
205 +       }
206 +                       
207 +       return timezonedb_system;
208 +}
209 +
210 +const timelib_tzdb_index_entry *timelib_timezone_builtin_identifiers_list(int *count)
211 +{
212 +       *count = timezonedb_system->index_size;
213 +       return timezonedb_system->index;
214 +}
215 +
216 +int timelib_timezone_id_is_valid(char *timezone, const timelib_tzdb *tzdb)
217 +{
218 +       char fname[PATH_MAX];
219 +
220 +       if (strstr(timezone, "..") != NULL) {
221 +               return 0;
222 +       }
223 +       
224 +       snprintf(fname, sizeof fname, ZONEINFO_PREFIX "/%s", timezone);
225 +
226 +       return access(fname, R_OK) == 0 ? 1 : 0;
227 +}
228 +
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;
234 +
235 +       orig = map_tzfile(timezone, &len);
236 +       if (orig == NULL) {
237 +               return NULL;
238 +       }
239 +
240 +       tmp = timelib_tzinfo_ctor(timezone);
241 +
242 +       tzf = orig + 20;
243 +       read_header(&tzf, tmp);
244 +       read_transistions(&tzf, tmp);
245 +       read_types(&tzf, tmp);
246 +
247 +       munmap(orig, len);
248 +
249 +       return tmp;
250 +}
251 +#else /* !HAVE_SYSTEM_TZDATA */
252 +
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.061549 seconds and 3 git commands to generate.