1 /*
2 +----------------------------------------------------------------------+
3 | Zend Engine |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 1998-2014 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