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