This source file includes following definitions.
- zend_remove_ini_entries
- zend_restore_ini_entry_cb
- zend_restore_ini_entry_wrapper
- zend_ini_startup
- zend_ini_shutdown
- zend_ini_global_shutdown
- zend_ini_deactivate
- zend_copy_ini_directives
- ini_key_compare
- zend_ini_sort_entries
- zend_register_ini_entries
- zend_unregister_ini_entries
- zend_ini_refresh_cache
- zend_ini_refresh_caches
- zend_alter_ini_entry
- zend_alter_ini_entry_ex
- zend_restore_ini_entry
- zend_ini_register_displayer
- zend_ini_long
- zend_ini_double
- zend_ini_string_ex
- zend_ini_string
- zend_ini_displayer_cb
- ZEND_INI_DISP
- ZEND_INI_DISP
- ZEND_INI_DISP
- ZEND_INI_MH
- ZEND_INI_MH
- ZEND_INI_MH
- ZEND_INI_MH
- ZEND_INI_MH
- ZEND_INI_MH
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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
36
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
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
55
56
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
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
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
88
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
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
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
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
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
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) {
157 return ZEND_NORMALIZE_BOOL(f->nKeyLength - s->nKeyLength);
158 } else if (f->nKeyLength == 0) {
159 return -1;
160 } else if (s->nKeyLength == 0) {
161 return 1;
162 } else {
163 return zend_binary_strcasecmp(f->arKey, f->nKeyLength, s->arKey, s->nKeyLength);
164 }
165 }
166
167
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
176
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
187
188
189
190
191
192
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
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
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
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
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
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) {
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
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
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
346
347
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
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
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
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
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
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
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
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
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
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
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
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
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
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
679
680
681
682
683