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