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