1 /*
2 +----------------------------------------------------------------------+
3 | Zend Engine |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 1998-2018 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@php.net> |
16 +----------------------------------------------------------------------+
17 */
18
19 #include "zend.h"
20 #include "zend_sort.h"
21 #include "zend_API.h"
22 #include "zend_ini.h"
23 #include "zend_alloc.h"
24 #include "zend_operators.h"
25 #include "zend_strtod.h"
26
27 static HashTable *registered_zend_ini_directives;
28
29 #define NO_VALUE_PLAINTEXT "no value"
30 #define NO_VALUE_HTML "<i>no value</i>"
31
32 /*
33 * hash_apply functions
34 */
zend_remove_ini_entries(zval * el,void * arg)35 static int zend_remove_ini_entries(zval *el, void *arg) /* {{{ */
36 {
37 zend_ini_entry *ini_entry = (zend_ini_entry *)Z_PTR_P(el);
38 int module_number = *(int *)arg;
39 if (ini_entry->module_number == module_number) {
40 return 1;
41 } else {
42 return 0;
43 }
44 }
45 /* }}} */
46
zend_restore_ini_entry_cb(zend_ini_entry * ini_entry,int stage)47 static int zend_restore_ini_entry_cb(zend_ini_entry *ini_entry, int stage) /* {{{ */
48 {
49 int result = FAILURE;
50
51 if (ini_entry->modified) {
52 if (ini_entry->on_modify) {
53 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 result = ini_entry->on_modify(ini_entry, ini_entry->orig_value, ini_entry->mh_arg1, ini_entry->mh_arg2, ini_entry->mh_arg3, stage);
58 } zend_end_try();
59 }
60 if (stage == ZEND_INI_STAGE_RUNTIME && result == FAILURE) {
61 /* runtime failure is OK */
62 return 1;
63 }
64 if (ini_entry->value != ini_entry->orig_value) {
65 zend_string_release(ini_entry->value);
66 }
67 ini_entry->value = ini_entry->orig_value;
68 ini_entry->modifiable = ini_entry->orig_modifiable;
69 ini_entry->modified = 0;
70 ini_entry->orig_value = NULL;
71 ini_entry->orig_modifiable = 0;
72 }
73 return 0;
74 }
75 /* }}} */
76
zend_restore_ini_entry_wrapper(zval * el)77 static int zend_restore_ini_entry_wrapper(zval *el) /* {{{ */
78 {
79 zend_ini_entry *ini_entry = (zend_ini_entry *)Z_PTR_P(el);
80 zend_restore_ini_entry_cb(ini_entry, ZEND_INI_STAGE_DEACTIVATE);
81 return 1;
82 }
83 /* }}} */
84
free_ini_entry(zval * zv)85 static void free_ini_entry(zval *zv) /* {{{ */
86 {
87 zend_ini_entry *entry = (zend_ini_entry*)Z_PTR_P(zv);
88
89 zend_string_release_ex(entry->name, 1);
90 if (entry->value) {
91 zend_string_release(entry->value);
92 }
93 if (entry->orig_value) {
94 zend_string_release_ex(entry->orig_value, 1);
95 }
96 free(entry);
97 }
98 /* }}} */
99
100 /*
101 * Startup / shutdown
102 */
zend_ini_startup(void)103 ZEND_API int zend_ini_startup(void) /* {{{ */
104 {
105 registered_zend_ini_directives = (HashTable *) malloc(sizeof(HashTable));
106
107 EG(ini_directives) = registered_zend_ini_directives;
108 EG(modified_ini_directives) = NULL;
109 EG(error_reporting_ini_entry) = NULL;
110 zend_hash_init_ex(registered_zend_ini_directives, 128, NULL, free_ini_entry, 1, 0);
111 return SUCCESS;
112 }
113 /* }}} */
114
zend_ini_shutdown(void)115 ZEND_API int zend_ini_shutdown(void) /* {{{ */
116 {
117 zend_ini_dtor(EG(ini_directives));
118 return SUCCESS;
119 }
120 /* }}} */
121
zend_ini_dtor(HashTable * ini_directives)122 ZEND_API void zend_ini_dtor(HashTable *ini_directives) /* {{{ */
123 {
124 zend_hash_destroy(ini_directives);
125 free(ini_directives);
126 }
127 /* }}} */
128
zend_ini_global_shutdown(void)129 ZEND_API int zend_ini_global_shutdown(void) /* {{{ */
130 {
131 zend_hash_destroy(registered_zend_ini_directives);
132 free(registered_zend_ini_directives);
133 return SUCCESS;
134 }
135 /* }}} */
136
zend_ini_deactivate(void)137 ZEND_API int zend_ini_deactivate(void) /* {{{ */
138 {
139 if (EG(modified_ini_directives)) {
140 zend_hash_apply(EG(modified_ini_directives), zend_restore_ini_entry_wrapper);
141 zend_hash_destroy(EG(modified_ini_directives));
142 FREE_HASHTABLE(EG(modified_ini_directives));
143 EG(modified_ini_directives) = NULL;
144 }
145 return SUCCESS;
146 }
147 /* }}} */
148
149 #ifdef ZTS
copy_ini_entry(zval * zv)150 static void copy_ini_entry(zval *zv) /* {{{ */
151 {
152 zend_ini_entry *old_entry = (zend_ini_entry*)Z_PTR_P(zv);
153 zend_ini_entry *new_entry = pemalloc(sizeof(zend_ini_entry), 1);
154
155 Z_PTR_P(zv) = new_entry;
156 memcpy(new_entry, old_entry, sizeof(zend_ini_entry));
157 if (old_entry->name) {
158 new_entry->name = zend_string_dup(old_entry->name, 1);
159 }
160 if (old_entry->value) {
161 new_entry->value = zend_string_dup(old_entry->value, 1);
162 }
163 if (old_entry->orig_value) {
164 new_entry->orig_value = zend_string_dup(old_entry->orig_value, 1);
165 }
166 }
167 /* }}} */
168
zend_copy_ini_directives(void)169 ZEND_API int zend_copy_ini_directives(void) /* {{{ */
170 {
171 EG(modified_ini_directives) = NULL;
172 EG(error_reporting_ini_entry) = NULL;
173 EG(ini_directives) = (HashTable *) malloc(sizeof(HashTable));
174 zend_hash_init_ex(EG(ini_directives), registered_zend_ini_directives->nNumOfElements, NULL, free_ini_entry, 1, 0);
175 zend_hash_copy(EG(ini_directives), registered_zend_ini_directives, copy_ini_entry);
176 return SUCCESS;
177 }
178 /* }}} */
179 #endif
180
ini_key_compare(const void * a,const void * b)181 static int ini_key_compare(const void *a, const void *b) /* {{{ */
182 {
183 const Bucket *f;
184 const Bucket *s;
185
186 f = (const Bucket *) a;
187 s = (const Bucket *) b;
188
189 if (!f->key && !s->key) { /* both numeric */
190 if (f->h > s->h) {
191 return -1;
192 } else if (f->h < s->h) {
193 return 1;
194 }
195 return 0;
196 } else if (!f->key) { /* f is numeric, s is not */
197 return -1;
198 } else if (!s->key) { /* s is numeric, f is not */
199 return 1;
200 } else { /* both strings */
201 return zend_binary_strcasecmp(ZSTR_VAL(f->key), ZSTR_LEN(f->key), ZSTR_VAL(s->key), ZSTR_LEN(s->key));
202 }
203 }
204 /* }}} */
205
zend_ini_sort_entries(void)206 ZEND_API void zend_ini_sort_entries(void) /* {{{ */
207 {
208 zend_hash_sort(EG(ini_directives), ini_key_compare, 0);
209 }
210 /* }}} */
211
212 /*
213 * Registration / unregistration
214 */
zend_register_ini_entries(const zend_ini_entry_def * ini_entry,int module_number)215 ZEND_API int zend_register_ini_entries(const zend_ini_entry_def *ini_entry, int module_number) /* {{{ */
216 {
217 zend_ini_entry *p;
218 zval *default_value;
219 HashTable *directives = registered_zend_ini_directives;
220
221 #ifdef ZTS
222 /* if we are called during the request, eg: from dl(),
223 * then we should not touch the global directives table,
224 * and should update the per-(request|thread) version instead.
225 * This solves two problems: one is that ini entries for dl()'d
226 * extensions will now work, and the second is that updating the
227 * global hash here from dl() is not mutex protected and can
228 * lead to death.
229 */
230 if (directives != EG(ini_directives)) {
231 directives = EG(ini_directives);
232 }
233 #endif
234
235 while (ini_entry->name) {
236 p = pemalloc(sizeof(zend_ini_entry), 1);
237 p->name = zend_string_init_interned(ini_entry->name, ini_entry->name_length, 1);
238 p->on_modify = ini_entry->on_modify;
239 p->mh_arg1 = ini_entry->mh_arg1;
240 p->mh_arg2 = ini_entry->mh_arg2;
241 p->mh_arg3 = ini_entry->mh_arg3;
242 p->value = NULL;
243 p->orig_value = NULL;
244 p->displayer = ini_entry->displayer;
245 p->modifiable = ini_entry->modifiable;
246
247 p->orig_modifiable = 0;
248 p->modified = 0;
249 p->module_number = module_number;
250
251 if (zend_hash_add_ptr(directives, p->name, (void*)p) == NULL) {
252 if (p->name) {
253 zend_string_release_ex(p->name, 1);
254 }
255 zend_unregister_ini_entries(module_number);
256 return FAILURE;
257 }
258 if (((default_value = zend_get_configuration_directive(p->name)) != NULL) &&
259 (!p->on_modify || p->on_modify(p, Z_STR_P(default_value), p->mh_arg1, p->mh_arg2, p->mh_arg3, ZEND_INI_STAGE_STARTUP) == SUCCESS)) {
260
261 p->value = zend_new_interned_string(zend_string_copy(Z_STR_P(default_value)));
262 } else {
263 p->value = ini_entry->value ?
264 zend_string_init_interned(ini_entry->value, ini_entry->value_length, 1) : NULL;
265
266 if (p->on_modify) {
267 p->on_modify(p, p->value, p->mh_arg1, p->mh_arg2, p->mh_arg3, ZEND_INI_STAGE_STARTUP);
268 }
269 }
270 ini_entry++;
271 }
272 return SUCCESS;
273 }
274 /* }}} */
275
zend_unregister_ini_entries(int module_number)276 ZEND_API void zend_unregister_ini_entries(int module_number) /* {{{ */
277 {
278 zend_hash_apply_with_argument(registered_zend_ini_directives, zend_remove_ini_entries, (void *) &module_number);
279 }
280 /* }}} */
281
282 #ifdef ZTS
zend_ini_refresh_cache(zval * el,void * arg)283 static int zend_ini_refresh_cache(zval *el, void *arg) /* {{{ */
284 {
285 zend_ini_entry *p = (zend_ini_entry *)Z_PTR_P(el);
286 int stage = (int)(zend_intptr_t)arg;
287
288 if (p->on_modify) {
289 p->on_modify(p, p->value, p->mh_arg1, p->mh_arg2, p->mh_arg3, stage);
290 }
291 return 0;
292 }
293 /* }}} */
294
zend_ini_refresh_caches(int stage)295 ZEND_API void zend_ini_refresh_caches(int stage) /* {{{ */
296 {
297 zend_hash_apply_with_argument(EG(ini_directives), zend_ini_refresh_cache, (void *)(zend_intptr_t) stage);
298 }
299 /* }}} */
300 #endif
301
zend_alter_ini_entry(zend_string * name,zend_string * new_value,int modify_type,int stage)302 ZEND_API int zend_alter_ini_entry(zend_string *name, zend_string *new_value, int modify_type, int stage) /* {{{ */
303 {
304
305 return zend_alter_ini_entry_ex(name, new_value, modify_type, stage, 0);
306 }
307 /* }}} */
308
zend_alter_ini_entry_chars(zend_string * name,const char * value,size_t value_length,int modify_type,int stage)309 ZEND_API int zend_alter_ini_entry_chars(zend_string *name, const char *value, size_t value_length, int modify_type, int stage) /* {{{ */
310 {
311 int ret;
312 zend_string *new_value;
313
314 new_value = zend_string_init(value, value_length, !(stage & ZEND_INI_STAGE_IN_REQUEST));
315 ret = zend_alter_ini_entry_ex(name, new_value, modify_type, stage, 0);
316 zend_string_release(new_value);
317 return ret;
318 }
319 /* }}} */
320
zend_alter_ini_entry_chars_ex(zend_string * name,const char * value,size_t value_length,int modify_type,int stage,int force_change)321 ZEND_API int zend_alter_ini_entry_chars_ex(zend_string *name, const char *value, size_t value_length, int modify_type, int stage, int force_change) /* {{{ */
322 {
323 int ret;
324 zend_string *new_value;
325
326 new_value = zend_string_init(value, value_length, !(stage & ZEND_INI_STAGE_IN_REQUEST));
327 ret = zend_alter_ini_entry_ex(name, new_value, modify_type, stage, force_change);
328 zend_string_release(new_value);
329 return ret;
330 }
331 /* }}} */
332
zend_alter_ini_entry_ex(zend_string * name,zend_string * new_value,int modify_type,int stage,int force_change)333 ZEND_API int zend_alter_ini_entry_ex(zend_string *name, zend_string *new_value, int modify_type, int stage, int force_change) /* {{{ */
334 {
335 zend_ini_entry *ini_entry;
336 zend_string *duplicate;
337 uint8_t modifiable;
338 zend_bool modified;
339
340 if ((ini_entry = zend_hash_find_ptr(EG(ini_directives), name)) == NULL) {
341 return FAILURE;
342 }
343
344 modifiable = ini_entry->modifiable;
345 modified = ini_entry->modified;
346
347 if (stage == ZEND_INI_STAGE_ACTIVATE && modify_type == ZEND_INI_SYSTEM) {
348 ini_entry->modifiable = ZEND_INI_SYSTEM;
349 }
350
351 if (!force_change) {
352 if (!(ini_entry->modifiable & modify_type)) {
353 return FAILURE;
354 }
355 }
356
357 if (!EG(modified_ini_directives)) {
358 ALLOC_HASHTABLE(EG(modified_ini_directives));
359 zend_hash_init(EG(modified_ini_directives), 8, NULL, NULL, 0);
360 }
361 if (!modified) {
362 ini_entry->orig_value = ini_entry->value;
363 ini_entry->orig_modifiable = modifiable;
364 ini_entry->modified = 1;
365 zend_hash_add_ptr(EG(modified_ini_directives), ini_entry->name, ini_entry);
366 }
367
368 duplicate = zend_string_copy(new_value);
369
370 if (!ini_entry->on_modify
371 || ini_entry->on_modify(ini_entry, duplicate, ini_entry->mh_arg1, ini_entry->mh_arg2, ini_entry->mh_arg3, stage) == SUCCESS) {
372 if (modified && ini_entry->orig_value != ini_entry->value) { /* we already changed the value, free the changed value */
373 zend_string_release(ini_entry->value);
374 }
375 ini_entry->value = duplicate;
376 } else {
377 zend_string_release(duplicate);
378 return FAILURE;
379 }
380
381 return SUCCESS;
382 }
383 /* }}} */
384
zend_restore_ini_entry(zend_string * name,int stage)385 ZEND_API int zend_restore_ini_entry(zend_string *name, int stage) /* {{{ */
386 {
387 zend_ini_entry *ini_entry;
388
389 if ((ini_entry = zend_hash_find_ptr(EG(ini_directives), name)) == NULL ||
390 (stage == ZEND_INI_STAGE_RUNTIME && (ini_entry->modifiable & ZEND_INI_USER) == 0)) {
391 return FAILURE;
392 }
393
394 if (EG(modified_ini_directives)) {
395 if (zend_restore_ini_entry_cb(ini_entry, stage) == 0) {
396 zend_hash_del(EG(modified_ini_directives), name);
397 } else {
398 return FAILURE;
399 }
400 }
401
402 return SUCCESS;
403 }
404 /* }}} */
405
zend_ini_register_displayer(char * name,uint32_t name_length,void (* displayer)(zend_ini_entry * ini_entry,int type))406 ZEND_API int zend_ini_register_displayer(char *name, uint32_t name_length, void (*displayer)(zend_ini_entry *ini_entry, int type)) /* {{{ */
407 {
408 zend_ini_entry *ini_entry;
409
410 ini_entry = zend_hash_str_find_ptr(registered_zend_ini_directives, name, name_length);
411 if (ini_entry == NULL) {
412 return FAILURE;
413 }
414
415 ini_entry->displayer = displayer;
416 return SUCCESS;
417 }
418 /* }}} */
419
420 /*
421 * Data retrieval
422 */
423
zend_ini_long(char * name,size_t name_length,int orig)424 ZEND_API zend_long zend_ini_long(char *name, size_t name_length, int orig) /* {{{ */
425 {
426 zend_ini_entry *ini_entry;
427
428 ini_entry = zend_hash_str_find_ptr(EG(ini_directives), name, name_length);
429 if (ini_entry) {
430 if (orig && ini_entry->modified) {
431 return (ini_entry->orig_value ? ZEND_STRTOL(ZSTR_VAL(ini_entry->orig_value), NULL, 0) : 0);
432 } else {
433 return (ini_entry->value ? ZEND_STRTOL(ZSTR_VAL(ini_entry->value), NULL, 0) : 0);
434 }
435 }
436
437 return 0;
438 }
439 /* }}} */
440
zend_ini_double(char * name,size_t name_length,int orig)441 ZEND_API double zend_ini_double(char *name, size_t name_length, int orig) /* {{{ */
442 {
443 zend_ini_entry *ini_entry;
444
445 ini_entry = zend_hash_str_find_ptr(EG(ini_directives), name, name_length);
446 if (ini_entry) {
447 if (orig && ini_entry->modified) {
448 return (double) (ini_entry->orig_value ? zend_strtod(ZSTR_VAL(ini_entry->orig_value), NULL) : 0.0);
449 } else {
450 return (double) (ini_entry->value ? zend_strtod(ZSTR_VAL(ini_entry->value), NULL) : 0.0);
451 }
452 }
453
454 return 0.0;
455 }
456 /* }}} */
457
zend_ini_string_ex(char * name,size_t name_length,int orig,zend_bool * exists)458 ZEND_API char *zend_ini_string_ex(char *name, size_t name_length, int orig, zend_bool *exists) /* {{{ */
459 {
460 zend_ini_entry *ini_entry;
461
462 ini_entry = zend_hash_str_find_ptr(EG(ini_directives), name, name_length);
463 if (ini_entry) {
464 if (exists) {
465 *exists = 1;
466 }
467
468 if (orig && ini_entry->modified) {
469 return ini_entry->orig_value ? ZSTR_VAL(ini_entry->orig_value) : NULL;
470 } else {
471 return ini_entry->value ? ZSTR_VAL(ini_entry->value) : NULL;
472 }
473 } else {
474 if (exists) {
475 *exists = 0;
476 }
477 return NULL;
478 }
479 }
480 /* }}} */
481
zend_ini_string(char * name,size_t name_length,int orig)482 ZEND_API char *zend_ini_string(char *name, size_t name_length, int orig) /* {{{ */
483 {
484 zend_bool exists = 1;
485 char *return_value;
486
487 return_value = zend_ini_string_ex(name, name_length, orig, &exists);
488 if (!exists) {
489 return NULL;
490 } else if (!return_value) {
491 return_value = "";
492 }
493 return return_value;
494 }
495 /* }}} */
496
zend_ini_get_value(zend_string * name)497 ZEND_API zend_string *zend_ini_get_value(zend_string *name) /* {{{ */
498 {
499 zend_ini_entry *ini_entry;
500
501 ini_entry = zend_hash_find_ptr(EG(ini_directives), name);
502 if (ini_entry) {
503 return ini_entry->value ? ini_entry->value : ZSTR_EMPTY_ALLOC();
504 } else {
505 return NULL;
506 }
507 }
508 /* }}} */
509
zend_ini_parse_bool(zend_string * str)510 ZEND_API zend_bool zend_ini_parse_bool(zend_string *str)
511 {
512 if ((ZSTR_LEN(str) == 4 && strcasecmp(ZSTR_VAL(str), "true") == 0)
513 || (ZSTR_LEN(str) == 3 && strcasecmp(ZSTR_VAL(str), "yes") == 0)
514 || (ZSTR_LEN(str) == 2 && strcasecmp(ZSTR_VAL(str), "on") == 0)) {
515 return 1;
516 } else {
517 return atoi(ZSTR_VAL(str)) != 0;
518 }
519 }
520
521 #if TONY_20070307
zend_ini_displayer_cb(zend_ini_entry * ini_entry,int type)522 static void zend_ini_displayer_cb(zend_ini_entry *ini_entry, int type) /* {{{ */
523 {
524 if (ini_entry->displayer) {
525 ini_entry->displayer(ini_entry, type);
526 } else {
527 char *display_string;
528 uint32_t display_string_length;
529
530 if (type == ZEND_INI_DISPLAY_ORIG && ini_entry->modified) {
531 if (ini_entry->orig_value) {
532 display_string = ini_entry->orig_value;
533 display_string_length = ini_entry->orig_value_length;
534 } else {
535 if (zend_uv.html_errors) {
536 display_string = NO_VALUE_HTML;
537 display_string_length = sizeof(NO_VALUE_HTML) - 1;
538 } else {
539 display_string = NO_VALUE_PLAINTEXT;
540 display_string_length = sizeof(NO_VALUE_PLAINTEXT) - 1;
541 }
542 }
543 } else if (ini_entry->value && ini_entry->value[0]) {
544 display_string = ini_entry->value;
545 display_string_length = ini_entry->value_length;
546 } else {
547 if (zend_uv.html_errors) {
548 display_string = NO_VALUE_HTML;
549 display_string_length = sizeof(NO_VALUE_HTML) - 1;
550 } else {
551 display_string = NO_VALUE_PLAINTEXT;
552 display_string_length = sizeof(NO_VALUE_PLAINTEXT) - 1;
553 }
554 }
555 ZEND_WRITE(display_string, display_string_length);
556 }
557 }
558 /* }}} */
559 #endif
560
ZEND_INI_DISP(zend_ini_boolean_displayer_cb)561 ZEND_INI_DISP(zend_ini_boolean_displayer_cb) /* {{{ */
562 {
563 int value;
564 zend_string *tmp_value;
565
566 if (type == ZEND_INI_DISPLAY_ORIG && ini_entry->modified) {
567 tmp_value = (ini_entry->orig_value ? ini_entry->orig_value : NULL );
568 } else if (ini_entry->value) {
569 tmp_value = ini_entry->value;
570 } else {
571 tmp_value = NULL;
572 }
573
574 if (tmp_value) {
575 value = zend_ini_parse_bool(tmp_value);
576 } else {
577 value = 0;
578 }
579
580 if (value) {
581 ZEND_PUTS("On");
582 } else {
583 ZEND_PUTS("Off");
584 }
585 }
586 /* }}} */
587
ZEND_INI_DISP(zend_ini_color_displayer_cb)588 ZEND_INI_DISP(zend_ini_color_displayer_cb) /* {{{ */
589 {
590 char *value;
591
592 if (type == ZEND_INI_DISPLAY_ORIG && ini_entry->modified) {
593 value = ZSTR_VAL(ini_entry->orig_value);
594 } else if (ini_entry->value) {
595 value = ZSTR_VAL(ini_entry->value);
596 } else {
597 value = NULL;
598 }
599 if (value) {
600 if (zend_uv.html_errors) {
601 zend_printf("<font style=\"color: %s\">%s</font>", value, value);
602 } else {
603 ZEND_PUTS(value);
604 }
605 } else {
606 if (zend_uv.html_errors) {
607 ZEND_PUTS(NO_VALUE_HTML);
608 } else {
609 ZEND_PUTS(NO_VALUE_PLAINTEXT);
610 }
611 }
612 }
613 /* }}} */
614
ZEND_INI_DISP(display_link_numbers)615 ZEND_INI_DISP(display_link_numbers) /* {{{ */
616 {
617 char *value;
618
619 if (type == ZEND_INI_DISPLAY_ORIG && ini_entry->modified) {
620 value = ZSTR_VAL(ini_entry->orig_value);
621 } else if (ini_entry->value) {
622 value = ZSTR_VAL(ini_entry->value);
623 } else {
624 value = NULL;
625 }
626
627 if (value) {
628 if (atoi(value) == -1) {
629 ZEND_PUTS("Unlimited");
630 } else {
631 zend_printf("%s", value);
632 }
633 }
634 }
635 /* }}} */
636
637 /* Standard message handlers */
ZEND_INI_MH(OnUpdateBool)638 ZEND_API ZEND_INI_MH(OnUpdateBool) /* {{{ */
639 {
640 zend_bool *p;
641 #ifndef ZTS
642 char *base = (char *) mh_arg2;
643 #else
644 char *base;
645
646 base = (char *) ts_resource(*((int *) mh_arg2));
647 #endif
648
649 p = (zend_bool *) (base+(size_t) mh_arg1);
650
651 *p = zend_ini_parse_bool(new_value);
652 return SUCCESS;
653 }
654 /* }}} */
655
ZEND_INI_MH(OnUpdateLong)656 ZEND_API ZEND_INI_MH(OnUpdateLong) /* {{{ */
657 {
658 zend_long *p;
659 #ifndef ZTS
660 char *base = (char *) mh_arg2;
661 #else
662 char *base;
663
664 base = (char *) ts_resource(*((int *) mh_arg2));
665 #endif
666
667 p = (zend_long *) (base+(size_t) mh_arg1);
668
669 *p = zend_atol(ZSTR_VAL(new_value), ZSTR_LEN(new_value));
670 return SUCCESS;
671 }
672 /* }}} */
673
ZEND_INI_MH(OnUpdateLongGEZero)674 ZEND_API ZEND_INI_MH(OnUpdateLongGEZero) /* {{{ */
675 {
676 zend_long *p, tmp;
677 #ifndef ZTS
678 char *base = (char *) mh_arg2;
679 #else
680 char *base;
681
682 base = (char *) ts_resource(*((int *) mh_arg2));
683 #endif
684
685 tmp = zend_atol(ZSTR_VAL(new_value), ZSTR_LEN(new_value));
686 if (tmp < 0) {
687 return FAILURE;
688 }
689
690 p = (zend_long *) (base+(size_t) mh_arg1);
691 *p = tmp;
692
693 return SUCCESS;
694 }
695 /* }}} */
696
ZEND_INI_MH(OnUpdateReal)697 ZEND_API ZEND_INI_MH(OnUpdateReal) /* {{{ */
698 {
699 double *p;
700 #ifndef ZTS
701 char *base = (char *) mh_arg2;
702 #else
703 char *base;
704
705 base = (char *) ts_resource(*((int *) mh_arg2));
706 #endif
707
708 p = (double *) (base+(size_t) mh_arg1);
709
710 *p = zend_strtod(ZSTR_VAL(new_value), NULL);
711 return SUCCESS;
712 }
713 /* }}} */
714
ZEND_INI_MH(OnUpdateString)715 ZEND_API ZEND_INI_MH(OnUpdateString) /* {{{ */
716 {
717 char **p;
718 #ifndef ZTS
719 char *base = (char *) mh_arg2;
720 #else
721 char *base;
722
723 base = (char *) ts_resource(*((int *) mh_arg2));
724 #endif
725
726 p = (char **) (base+(size_t) mh_arg1);
727
728 *p = new_value ? ZSTR_VAL(new_value) : NULL;
729 return SUCCESS;
730 }
731 /* }}} */
732
ZEND_INI_MH(OnUpdateStringUnempty)733 ZEND_API ZEND_INI_MH(OnUpdateStringUnempty) /* {{{ */
734 {
735 char **p;
736 #ifndef ZTS
737 char *base = (char *) mh_arg2;
738 #else
739 char *base;
740
741 base = (char *) ts_resource(*((int *) mh_arg2));
742 #endif
743
744 if (new_value && !ZSTR_VAL(new_value)[0]) {
745 return FAILURE;
746 }
747
748 p = (char **) (base+(size_t) mh_arg1);
749
750 *p = new_value ? ZSTR_VAL(new_value) : NULL;
751 return SUCCESS;
752 }
753 /* }}} */
754
755 /*
756 * Local variables:
757 * tab-width: 4
758 * c-basic-offset: 4
759 * indent-tabs-mode: t
760 * End:
761 * vim600: sw=4 ts=4 fdm=marker
762 * vim<600: sw=4 ts=4
763 */
764