1 : /*
2 : +----------------------------------------------------------------------+
3 : | Zend Engine |
4 : +----------------------------------------------------------------------+
5 : | Copyright (c) 1998-2009 Zend Technologies Ltd. (http://www.zend.com) |
6 : +----------------------------------------------------------------------+
7 : | This source file is subject to version 2.00 of the Zend license, |
8 : | that is bundled with this package in the file LICENSE, and is |
9 : | available through the world-wide-web at the following url: |
10 : | http://www.zend.com/license/2_00.txt. |
11 : | If you did not receive a copy of the Zend license and are unable to |
12 : | obtain it through the world-wide-web, please send a note to |
13 : | license@zend.com so we can mail you a copy immediately. |
14 : +----------------------------------------------------------------------+
15 : | Author: Zeev Suraski <zeev@zend.com> |
16 : +----------------------------------------------------------------------+
17 : */
18 :
19 : /* $Id: zend_ini.c 284254 2009-07-17 11:49:50Z jani $ */
20 :
21 : #include "zend.h"
22 : #include "zend_qsort.h"
23 : #include "zend_API.h"
24 : #include "zend_ini.h"
25 : #include "zend_alloc.h"
26 : #include "zend_operators.h"
27 : #include "zend_strtod.h"
28 :
29 : static HashTable *registered_zend_ini_directives;
30 :
31 : #define NO_VALUE_PLAINTEXT "no value"
32 : #define NO_VALUE_HTML "<i>no value</i>"
33 :
34 : /*
35 : * hash_apply functions
36 : */
37 : static int zend_remove_ini_entries(zend_ini_entry *ini_entry, int *module_number TSRMLS_DC) /* {{{ */
38 65809234 : {
39 65809234 : if (ini_entry->module_number == *module_number) {
40 3665961 : return 1;
41 : } else {
42 62143273 : return 0;
43 : }
44 : }
45 : /* }}} */
46 :
47 : static int zend_restore_ini_entry_cb(zend_ini_entry *ini_entry, int stage TSRMLS_DC) /* {{{ */
48 3478 : {
49 3478 : int result = FAILURE;
50 :
51 3478 : if (ini_entry->modified) {
52 3477 : if (ini_entry->on_modify) {
53 3477 : zend_try {
54 : /* even if on_modify bails out, we have to continue on with restoring,
55 : since there can be allocated variables that would be freed on MM shutdown
56 : and would lead to memory corruption later ini entry is modified again */
57 3477 : result = ini_entry->on_modify(ini_entry, ini_entry->orig_value, ini_entry->orig_value_length, ini_entry->mh_arg1, ini_entry->mh_arg2, ini_entry->mh_arg3, stage TSRMLS_CC);
58 3477 : } zend_end_try();
59 : }
60 3477 : if (stage == ZEND_INI_STAGE_RUNTIME && result == FAILURE) {
61 : /* runtime failure is OK */
62 0 : return 1;
63 : }
64 3477 : if (ini_entry->value != ini_entry->orig_value) {
65 3466 : efree(ini_entry->value);
66 : }
67 3477 : ini_entry->value = ini_entry->orig_value;
68 3477 : ini_entry->value_length = ini_entry->orig_value_length;
69 3477 : ini_entry->modifiable = ini_entry->orig_modifiable;
70 3477 : ini_entry->modified = 0;
71 3477 : ini_entry->orig_value = NULL;
72 3477 : ini_entry->orig_value_length = 0;
73 3477 : ini_entry->orig_modifiable = 0;
74 : }
75 3478 : return 0;
76 : }
77 : /* }}} */
78 :
79 : static int zend_restore_ini_entry_wrapper(zend_ini_entry **ini_entry TSRMLS_DC) /* {{{ */
80 3455 : {
81 3455 : zend_restore_ini_entry_cb(*ini_entry, ZEND_INI_STAGE_DEACTIVATE TSRMLS_CC);
82 3455 : return 1;
83 : }
84 : /* }}} */
85 :
86 : /*
87 : * Startup / shutdown
88 : */
89 : ZEND_API int zend_ini_startup(TSRMLS_D) /* {{{ */
90 17007 : {
91 17007 : registered_zend_ini_directives = (HashTable *) malloc(sizeof(HashTable));
92 :
93 17007 : EG(ini_directives) = registered_zend_ini_directives;
94 17007 : EG(modified_ini_directives) = NULL;
95 17007 : if (zend_hash_init_ex(registered_zend_ini_directives, 100, NULL, NULL, 1, 0) == FAILURE) {
96 0 : return FAILURE;
97 : }
98 17007 : return SUCCESS;
99 : }
100 : /* }}} */
101 :
102 : ZEND_API int zend_ini_shutdown(TSRMLS_D) /* {{{ */
103 17039 : {
104 17039 : zend_hash_destroy(EG(ini_directives));
105 17039 : free(EG(ini_directives));
106 17039 : return SUCCESS;
107 : }
108 : /* }}} */
109 :
110 : ZEND_API int zend_ini_global_shutdown(TSRMLS_D) /* {{{ */
111 0 : {
112 0 : zend_hash_destroy(registered_zend_ini_directives);
113 0 : free(registered_zend_ini_directives);
114 0 : return SUCCESS;
115 : }
116 : /* }}} */
117 :
118 : ZEND_API int zend_ini_deactivate(TSRMLS_D) /* {{{ */
119 17039 : {
120 17039 : if (EG(modified_ini_directives)) {
121 3002 : zend_hash_apply(EG(modified_ini_directives), (apply_func_t) zend_restore_ini_entry_wrapper TSRMLS_CC);
122 3002 : zend_hash_destroy(EG(modified_ini_directives));
123 3002 : FREE_HASHTABLE(EG(modified_ini_directives));
124 3002 : EG(modified_ini_directives) = NULL;
125 : }
126 17039 : return SUCCESS;
127 : }
128 : /* }}} */
129 :
130 : #ifdef ZTS
131 : ZEND_API int zend_copy_ini_directives(TSRMLS_D) /* {{{ */
132 : {
133 : zend_ini_entry ini_entry;
134 :
135 : EG(modified_ini_directives) = NULL;
136 : EG(ini_directives) = (HashTable *) malloc(sizeof(HashTable));
137 : if (zend_hash_init_ex(EG(ini_directives), registered_zend_ini_directives->nNumOfElements, NULL, NULL, 1, 0) == FAILURE) {
138 : return FAILURE;
139 : }
140 : zend_hash_copy(EG(ini_directives), registered_zend_ini_directives, NULL, &ini_entry, sizeof(zend_ini_entry));
141 : return SUCCESS;
142 : }
143 : /* }}} */
144 : #endif
145 :
146 : static int ini_key_compare(const void *a, const void *b TSRMLS_DC) /* {{{ */
147 97659 : {
148 : Bucket *f;
149 : Bucket *s;
150 :
151 97659 : f = *((Bucket **) a);
152 97659 : s = *((Bucket **) b);
153 :
154 97659 : if (f->nKeyLength == 0 && s->nKeyLength == 0) { /* both numeric */
155 0 : return ZEND_NORMALIZE_BOOL(f->nKeyLength - s->nKeyLength);
156 97659 : } else if (f->nKeyLength == 0) { /* f is numeric, s is not */
157 0 : return -1;
158 97659 : } else if (s->nKeyLength == 0) { /* s is numeric, f is not */
159 0 : return 1;
160 : } else { /* both strings */
161 : /* FIXME: unicode hash */
162 97659 : return zend_binary_strcasecmp(f->key.arKey.s, f->nKeyLength, s->key.arKey.s, s->nKeyLength);
163 : }
164 : }
165 : /* }}} */
166 :
167 : ZEND_API void zend_ini_sort_entries(TSRMLS_D) /* {{{ */
168 56 : {
169 56 : zend_hash_sort(EG(ini_directives), zend_qsort, ini_key_compare, 0 TSRMLS_CC);
170 56 : }
171 : /* }}} */
172 :
173 : /*
174 : * Registration / unregistration
175 : */
176 : ZEND_API int zend_register_ini_entries(const zend_ini_entry *ini_entry, int module_number TSRMLS_DC) /* {{{ */
177 493528 : {
178 493528 : const zend_ini_entry *p = ini_entry;
179 : zend_ini_entry *hashed_ini_entry;
180 : zval default_value;
181 493528 : HashTable *directives = registered_zend_ini_directives;
182 493528 : zend_bool config_directive_success = 0;
183 :
184 : #ifdef ZTS
185 : /* if we are called during the request, eg: from dl(),
186 : * then we should not touch the global directives table,
187 : * and should update the per-(request|thread) version instead.
188 : * This solves two problems: one is that ini entries for dl()'d
189 : * extensions will now work, and the second is that updating the
190 : * global hash here from dl() is not mutex protected and can
191 : * lead to death.
192 : */
193 : if (directives != EG(ini_directives)) {
194 : directives = EG(ini_directives);
195 : }
196 : #endif
197 :
198 4697182 : while (p->name) {
199 3710126 : config_directive_success = 0;
200 3710126 : if (zend_hash_add(directives, p->name, p->name_length, (void*)p, sizeof(zend_ini_entry), (void **) &hashed_ini_entry) == FAILURE) {
201 0 : zend_unregister_ini_entries(module_number TSRMLS_CC);
202 0 : return FAILURE;
203 : }
204 3710126 : hashed_ini_entry->module_number = module_number;
205 3710126 : if ((zend_get_configuration_directive(p->name, p->name_length, &default_value)) == SUCCESS) {
206 576845 : if (!hashed_ini_entry->on_modify
207 : || hashed_ini_entry->on_modify(hashed_ini_entry, Z_STRVAL(default_value), Z_STRLEN(default_value), hashed_ini_entry->mh_arg1, hashed_ini_entry->mh_arg2, hashed_ini_entry->mh_arg3, ZEND_INI_STAGE_STARTUP TSRMLS_CC) == SUCCESS) {
208 576841 : hashed_ini_entry->value = Z_STRVAL(default_value);
209 576841 : hashed_ini_entry->value_length = Z_STRLEN(default_value);
210 576841 : config_directive_success = 1;
211 : }
212 : }
213 :
214 3710126 : if (!config_directive_success && hashed_ini_entry->on_modify) {
215 2844104 : hashed_ini_entry->on_modify(hashed_ini_entry, hashed_ini_entry->value, hashed_ini_entry->value_length, hashed_ini_entry->mh_arg1, hashed_ini_entry->mh_arg2, hashed_ini_entry->mh_arg3, ZEND_INI_STAGE_STARTUP TSRMLS_CC);
216 : }
217 3710126 : p++;
218 : }
219 493528 : return SUCCESS;
220 : }
221 : /* }}} */
222 :
223 : ZEND_API void zend_unregister_ini_entries(int module_number TSRMLS_DC) /* {{{ */
224 443336 : {
225 443336 : zend_hash_apply_with_argument(registered_zend_ini_directives, (apply_func_arg_t) zend_remove_ini_entries, (void *) &module_number TSRMLS_CC);
226 443336 : }
227 : /* }}} */
228 :
229 : #ifdef ZTS
230 : static int zend_ini_refresh_cache(zend_ini_entry *p, int stage TSRMLS_DC) /* {{{ */
231 : {
232 : if (p->on_modify) {
233 : p->on_modify(p, p->value, p->value_length, p->mh_arg1, p->mh_arg2, p->mh_arg3, stage TSRMLS_CC);
234 : }
235 : return 0;
236 : }
237 : /* }}} */
238 :
239 : ZEND_API void zend_ini_refresh_caches(int stage TSRMLS_DC) /* {{{ */
240 : {
241 : zend_hash_apply_with_argument(EG(ini_directives), (apply_func_arg_t) zend_ini_refresh_cache, (void *)(zend_uintptr_t) stage TSRMLS_CC);
242 : }
243 : /* }}} */
244 : #endif
245 :
246 : ZEND_API int zend_alter_ini_entry(char *name, uint name_length, char *new_value, uint new_value_length, int modify_type, int stage) /* {{{ */
247 2411 : {
248 : TSRMLS_FETCH();
249 :
250 2411 : return zend_alter_ini_entry_ex(name, name_length, new_value, new_value_length, modify_type, stage, 0 TSRMLS_CC);
251 : }
252 : /* }}} */
253 :
254 : ZEND_API int zend_alter_ini_entry_ex(char *name, uint name_length, char *new_value, uint new_value_length, int modify_type, int stage, int force_change TSRMLS_DC) /* {{{ */
255 2302743 : {
256 : zend_ini_entry *ini_entry;
257 : char *duplicate;
258 : zend_bool modifiable;
259 : zend_bool modified;
260 :
261 2302743 : if (zend_hash_find(EG(ini_directives), name, name_length, (void **) &ini_entry) == FAILURE) {
262 22 : return FAILURE;
263 : }
264 :
265 2302721 : modifiable = ini_entry->modifiable;
266 2302721 : modified = ini_entry->modified;
267 :
268 2302721 : if (stage == ZEND_INI_STAGE_ACTIVATE && modify_type == ZEND_INI_SYSTEM) {
269 0 : ini_entry->modifiable = ZEND_INI_SYSTEM;
270 : }
271 :
272 2302721 : if (!force_change) {
273 2965 : if (!(ini_entry->modifiable & modify_type)) {
274 1 : return FAILURE;
275 : }
276 : }
277 :
278 2302720 : if (!EG(modified_ini_directives)) {
279 3001 : ALLOC_HASHTABLE(EG(modified_ini_directives));
280 3001 : zend_hash_init(EG(modified_ini_directives), 8, NULL, NULL, 0);
281 : }
282 2302720 : if (!modified) {
283 3476 : ini_entry->orig_value = ini_entry->value;
284 3476 : ini_entry->orig_value_length = ini_entry->value_length;
285 3476 : ini_entry->orig_modifiable = modifiable;
286 3476 : ini_entry->modified = 1;
287 3476 : zend_hash_add(EG(modified_ini_directives), name, name_length, &ini_entry, sizeof(zend_ini_entry*), NULL);
288 : }
289 :
290 2302720 : duplicate = estrndup(new_value, new_value_length);
291 :
292 2302720 : if (!ini_entry->on_modify
293 : || ini_entry->on_modify(ini_entry, duplicate, new_value_length, ini_entry->mh_arg1, ini_entry->mh_arg2, ini_entry->mh_arg3, stage TSRMLS_CC) == SUCCESS) {
294 2302702 : if (modified && ini_entry->orig_value != ini_entry->value) { /* we already changed the value, free the changed value */
295 2299237 : efree(ini_entry->value);
296 : }
297 2302702 : ini_entry->value = duplicate;
298 2302702 : ini_entry->value_length = new_value_length;
299 : } else {
300 18 : efree(duplicate);
301 18 : return FAILURE;
302 : }
303 :
304 2302702 : return SUCCESS;
305 : }
306 : /* }}} */
307 :
308 : ZEND_API int zend_restore_ini_entry(char *name, uint name_length, int stage) /* {{{ */
309 24 : {
310 : zend_ini_entry *ini_entry;
311 : TSRMLS_FETCH();
312 :
313 24 : if (zend_hash_find(EG(ini_directives), name, name_length, (void **) &ini_entry) == FAILURE ||
314 : (stage == ZEND_INI_STAGE_RUNTIME && (ini_entry->modifiable & ZEND_INI_USER) == 0)) {
315 0 : return FAILURE;
316 : }
317 :
318 24 : if (EG(modified_ini_directives)) {
319 23 : if (zend_restore_ini_entry_cb(ini_entry, stage TSRMLS_CC) == 0) {
320 23 : zend_hash_del(EG(modified_ini_directives), name, name_length);
321 : } else {
322 0 : return FAILURE;
323 : }
324 : }
325 :
326 24 : return SUCCESS;
327 : }
328 : /* }}} */
329 :
330 : ZEND_API int zend_ini_register_displayer(char *name, uint name_length, void (*displayer)(zend_ini_entry *ini_entry, int type)) /* {{{ */
331 0 : {
332 : zend_ini_entry *ini_entry;
333 :
334 0 : if (zend_hash_find(registered_zend_ini_directives, name, name_length, (void **) &ini_entry) == FAILURE) {
335 0 : return FAILURE;
336 : }
337 :
338 0 : ini_entry->displayer = displayer;
339 0 : return SUCCESS;
340 : }
341 : /* }}} */
342 :
343 : /*
344 : * Data retrieval
345 : */
346 :
347 : ZEND_API long zend_ini_long(char *name, uint name_length, int orig) /* {{{ */
348 462 : {
349 : zend_ini_entry *ini_entry;
350 : TSRMLS_FETCH();
351 :
352 462 : if (zend_hash_find(EG(ini_directives), name, name_length, (void **) &ini_entry) == SUCCESS) {
353 462 : if (orig && ini_entry->modified) {
354 0 : return (ini_entry->orig_value ? strtol(ini_entry->orig_value, NULL, 0) : 0);
355 : } else {
356 462 : return (ini_entry->value ? strtol(ini_entry->value, NULL, 0) : 0);
357 : }
358 : }
359 :
360 0 : return 0;
361 : }
362 : /* }}} */
363 :
364 : ZEND_API double zend_ini_double(char *name, uint name_length, int orig) /* {{{ */
365 48 : {
366 : zend_ini_entry *ini_entry;
367 : TSRMLS_FETCH();
368 :
369 48 : if (zend_hash_find(EG(ini_directives), name, name_length, (void **) &ini_entry) == SUCCESS) {
370 48 : if (orig && ini_entry->modified) {
371 0 : return (double) (ini_entry->orig_value ? zend_strtod(ini_entry->orig_value, NULL) : 0.0);
372 : } else {
373 48 : return (double) (ini_entry->value ? zend_strtod(ini_entry->value, NULL) : 0.0);
374 : }
375 : }
376 :
377 0 : return 0.0;
378 : }
379 : /* }}} */
380 :
381 : ZEND_API char *zend_ini_string_ex(char *name, uint name_length, int orig, zend_bool *exists) /* {{{ */
382 156697 : {
383 : zend_ini_entry *ini_entry;
384 : TSRMLS_FETCH();
385 :
386 156697 : if (zend_hash_find(EG(ini_directives), name, name_length, (void **) &ini_entry) == SUCCESS) {
387 156673 : if (exists) {
388 34917 : *exists = 1;
389 : }
390 :
391 156673 : if (orig && ini_entry->modified) {
392 0 : return ini_entry->orig_value;
393 : } else {
394 156673 : return ini_entry->value;
395 : }
396 : } else {
397 24 : if (exists) {
398 24 : *exists = 0;
399 : }
400 24 : return NULL;
401 : }
402 : }
403 : /* }}} */
404 :
405 : ZEND_API char *zend_ini_string(char *name, uint name_length, int orig) /* {{{ */
406 34941 : {
407 34941 : zend_bool exists = 1;
408 : char *return_value;
409 :
410 34941 : return_value = zend_ini_string_ex(name, name_length, orig, &exists);
411 34941 : if (!exists) {
412 24 : return NULL;
413 34917 : } else if (!return_value) {
414 17128 : return_value = "";
415 : }
416 34917 : return return_value;
417 : }
418 : /* }}} */
419 :
420 : #if TONY_20070307
421 : static void zend_ini_displayer_cb(zend_ini_entry *ini_entry, int type) /* {{{ */
422 : {
423 : if (ini_entry->displayer) {
424 : ini_entry->displayer(ini_entry, type);
425 : } else {
426 : char *display_string;
427 : uint display_string_length;
428 :
429 : if (type == ZEND_INI_DISPLAY_ORIG && ini_entry->modified) {
430 : if (ini_entry->orig_value) {
431 : display_string = ini_entry->orig_value;
432 : display_string_length = ini_entry->orig_value_length;
433 : } else {
434 : if (zend_uv.html_errors) {
435 : display_string = NO_VALUE_HTML;
436 : display_string_length = sizeof(NO_VALUE_HTML) - 1;
437 : } else {
438 : display_string = NO_VALUE_PLAINTEXT;
439 : display_string_length = sizeof(NO_VALUE_PLAINTEXT) - 1;
440 : }
441 : }
442 : } else if (ini_entry->value && ini_entry->value[0]) {
443 : display_string = ini_entry->value;
444 : display_string_length = ini_entry->value_length;
445 : } else {
446 : if (zend_uv.html_errors) {
447 : display_string = NO_VALUE_HTML;
448 : display_string_length = sizeof(NO_VALUE_HTML) - 1;
449 : } else {
450 : display_string = NO_VALUE_PLAINTEXT;
451 : display_string_length = sizeof(NO_VALUE_PLAINTEXT) - 1;
452 : }
453 : }
454 : ZEND_WRITE(display_string, display_string_length);
455 : }
456 : }
457 : /* }}} */
458 : #endif
459 :
460 : ZEND_INI_DISP(zend_ini_boolean_displayer_cb) /* {{{ */
461 4214 : {
462 : int value, tmp_value_len;
463 : char *tmp_value;
464 :
465 4214 : if (type == ZEND_INI_DISPLAY_ORIG && ini_entry->modified) {
466 0 : tmp_value = (ini_entry->orig_value ? ini_entry->orig_value : NULL );
467 0 : tmp_value_len = ini_entry->orig_value_length;
468 4214 : } else if (ini_entry->value) {
469 4214 : tmp_value = ini_entry->value;
470 4214 : tmp_value_len = ini_entry->value_length;
471 : } else {
472 0 : tmp_value = NULL;
473 0 : tmp_value_len = 0;
474 : }
475 :
476 4214 : if (tmp_value) {
477 4214 : if (tmp_value_len == 4 && strcasecmp(tmp_value, "true") == 0) {
478 0 : value = 1;
479 4214 : } else if (tmp_value_len == 3 && strcasecmp(tmp_value, "yes") == 0) {
480 0 : value = 1;
481 4214 : } else if (tmp_value_len == 2 && strcasecmp(tmp_value, "on") == 0) {
482 0 : value = 1;
483 : } else {
484 4214 : value = atoi(tmp_value);
485 : }
486 : } else {
487 0 : value = 0;
488 : }
489 :
490 4214 : if (value) {
491 1884 : ZEND_PUTS("On");
492 : } else {
493 2330 : ZEND_PUTS("Off");
494 : }
495 4214 : }
496 : /* }}} */
497 :
498 : ZEND_INI_DISP(zend_ini_color_displayer_cb) /* {{{ */
499 430 : {
500 : char *value;
501 :
502 430 : if (type == ZEND_INI_DISPLAY_ORIG && ini_entry->modified) {
503 0 : value = ini_entry->orig_value;
504 430 : } else if (ini_entry->value) {
505 430 : value = ini_entry->value;
506 : } else {
507 0 : value = NULL;
508 : }
509 430 : if (value) {
510 430 : if (zend_uv.html_errors) {
511 430 : zend_printf("<font style=\"color: %s\">%s</font>", value, value);
512 : } else {
513 0 : ZEND_PUTS(value);
514 : }
515 : } else {
516 0 : if (zend_uv.html_errors) {
517 0 : ZEND_PUTS(NO_VALUE_HTML);
518 : } else {
519 0 : ZEND_PUTS(NO_VALUE_PLAINTEXT);
520 : }
521 : }
522 430 : }
523 : /* }}} */
524 :
525 : ZEND_INI_DISP(display_link_numbers) /* {{{ */
526 688 : {
527 : char *value;
528 :
529 688 : if (type == ZEND_INI_DISPLAY_ORIG && ini_entry->modified) {
530 0 : value = ini_entry->orig_value;
531 688 : } else if (ini_entry->value) {
532 688 : value = ini_entry->value;
533 : } else {
534 0 : value = NULL;
535 : }
536 :
537 688 : if (value) {
538 688 : if (atoi(value) == -1) {
539 602 : ZEND_PUTS("Unlimited");
540 : } else {
541 86 : zend_printf("%s", value);
542 : }
543 : }
544 688 : }
545 : /* }}} */
546 :
547 : /* Standard message handlers */
548 : ZEND_API ZEND_INI_MH(OnUpdateBool) /* {{{ */
549 700241 : {
550 : zend_bool *p;
551 : #ifndef ZTS
552 700241 : char *base = (char *) mh_arg2;
553 : #else
554 : char *base;
555 :
556 : base = (char *) ts_resource(*((int *) mh_arg2));
557 : #endif
558 :
559 700241 : p = (zend_bool *) (base+(size_t) mh_arg1);
560 :
561 700241 : if (new_value_length == 2 && strcasecmp("on", new_value) == 0) {
562 0 : *p = (zend_bool) 1;
563 : }
564 700241 : else if (new_value_length == 3 && strcasecmp("yes", new_value) == 0) {
565 0 : *p = (zend_bool) 1;
566 : }
567 700241 : else if (new_value_length == 4 && strcasecmp("true", new_value) == 0) {
568 0 : *p = (zend_bool) 1;
569 : }
570 : else {
571 700241 : *p = (zend_bool) atoi(new_value);
572 : }
573 700241 : return SUCCESS;
574 : }
575 : /* }}} */
576 :
577 : ZEND_API ZEND_INI_MH(OnUpdateLong) /* {{{ */
578 969638 : {
579 : long *p;
580 : #ifndef ZTS
581 969638 : char *base = (char *) mh_arg2;
582 : #else
583 : char *base;
584 :
585 : base = (char *) ts_resource(*((int *) mh_arg2));
586 : #endif
587 :
588 969638 : p = (long *) (base+(size_t) mh_arg1);
589 :
590 969638 : *p = zend_atol(new_value, new_value_length);
591 969638 : return SUCCESS;
592 : }
593 : /* }}} */
594 :
595 : ZEND_API ZEND_INI_MH(OnUpdateLongGEZero) /* {{{ */
596 51021 : {
597 : long *p, tmp;
598 : #ifndef ZTS
599 51021 : char *base = (char *) mh_arg2;
600 : #else
601 : char *base;
602 :
603 : base = (char *) ts_resource(*((int *) mh_arg2));
604 : #endif
605 :
606 51021 : tmp = zend_atol(new_value, new_value_length);
607 51021 : if (tmp < 0) {
608 0 : return FAILURE;
609 : }
610 :
611 51021 : p = (long *) (base+(size_t) mh_arg1);
612 51021 : *p = tmp;
613 :
614 51021 : return SUCCESS;
615 : }
616 : /* }}} */
617 :
618 : ZEND_API ZEND_INI_MH(OnUpdateReal) /* {{{ */
619 17007 : {
620 : double *p;
621 : #ifndef ZTS
622 17007 : char *base = (char *) mh_arg2;
623 : #else
624 : char *base;
625 :
626 : base = (char *) ts_resource(*((int *) mh_arg2));
627 : #endif
628 :
629 17007 : p = (double *) (base+(size_t) mh_arg1);
630 :
631 17007 : *p = zend_strtod(new_value, NULL);
632 17007 : return SUCCESS;
633 : }
634 : /* }}} */
635 :
636 : ZEND_API ZEND_INI_MH(OnUpdateString) /* {{{ */
637 817226 : {
638 : char **p;
639 : #ifndef ZTS
640 817226 : char *base = (char *) mh_arg2;
641 : #else
642 : char *base;
643 :
644 : base = (char *) ts_resource(*((int *) mh_arg2));
645 : #endif
646 :
647 817226 : p = (char **) (base+(size_t) mh_arg1);
648 :
649 817226 : *p = new_value;
650 817226 : return SUCCESS;
651 : }
652 : /* }}} */
653 :
654 : ZEND_API ZEND_INI_MH(OnUpdateStringUnempty) /* {{{ */
655 187223 : {
656 : char **p;
657 : #ifndef ZTS
658 187223 : char *base = (char *) mh_arg2;
659 : #else
660 : char *base;
661 :
662 : base = (char *) ts_resource(*((int *) mh_arg2));
663 : #endif
664 :
665 187223 : if (new_value && !new_value[0]) {
666 11 : return FAILURE;
667 : }
668 :
669 187212 : p = (char **) (base+(size_t) mh_arg1);
670 :
671 187212 : *p = new_value;
672 187212 : return SUCCESS;
673 : }
674 : /* }}} */
675 :
676 : ZEND_API ZEND_INI_MH(OnUpdateUTF8String) /* {{{ */
677 51023 : {
678 : UChar **up;
679 51023 : UChar *ustr = NULL;
680 : int32_t ustr_len, capacity;
681 51023 : UErrorCode status = U_ZERO_ERROR;
682 : #ifndef ZTS
683 51023 : char *base = (char *) mh_arg2;
684 : #else
685 : char *base;
686 :
687 : base = (char *) ts_resource(*((int *) mh_arg2));
688 : #endif
689 : /* Convert only if unicode semantics is on. Otherwise, same as OnUpdateString */
690 : /* estimate capacity */
691 51023 : capacity = (new_value_length > 2) ? ((new_value_length >> 1) + (new_value_length >> 3) + 2) : new_value_length;
692 :
693 : while (1) {
694 85038 : ustr = peurealloc(ustr, capacity+1, 1);
695 85038 : u_strFromUTF8(ustr, capacity+1, &ustr_len, new_value, new_value_length, &status);
696 85038 : if (status == U_BUFFER_OVERFLOW_ERROR || status == U_STRING_NOT_TERMINATED_WARNING) {
697 34015 : capacity = ustr_len;
698 34015 : status = U_ZERO_ERROR;
699 : } else {
700 : break;
701 : }
702 34015 : }
703 :
704 51023 : if (U_FAILURE(status)) {
705 0 : zend_error(E_WARNING, "Could not convert UTF-8 INI value to Unicode");
706 0 : efree(ustr);
707 0 : return FAILURE;
708 : }
709 :
710 51023 : up = (UChar **) (base+(size_t) mh_arg1);
711 51023 : *up = ustr;
712 :
713 51023 : return SUCCESS;
714 : }
715 : /* }}} */
716 :
717 : /*
718 : * Local variables:
719 : * tab-width: 4
720 : * c-basic-offset: 4
721 : * indent-tabs-mode: t
722 : * End:
723 : */
|