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