xref: /PHP-7.1/Zend/zend_ini.c (revision ccd4716e)
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@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