You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

628 lines
17 KiB

27 years ago
25 years ago
27 years ago
24 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
24 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
24 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
  1. /*
  2. +----------------------------------------------------------------------+
  3. | PHP Version 4 |
  4. +----------------------------------------------------------------------+
  5. | Copyright (c) 1997-2003 The PHP Group |
  6. +----------------------------------------------------------------------+
  7. | This source file is subject to version 3.0 of the PHP 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.php.net/license/3_0.txt. |
  11. | If you did not receive a copy of the PHP license and are unable to |
  12. | obtain it through the world-wide-web, please send a note to |
  13. | license@php.net so we can mail you a copy immediately. |
  14. +----------------------------------------------------------------------+
  15. | Author: Zeev Suraski <zeev@zend.com> |
  16. +----------------------------------------------------------------------+
  17. */
  18. /* $Id$ */
  19. /* Check CWD for php.ini */
  20. #define INI_CHECK_CWD
  21. #include "php.h"
  22. #include "ext/standard/info.h"
  23. #include "zend_ini.h"
  24. #include "php_ini.h"
  25. #include "ext/standard/dl.h"
  26. #include "zend_extensions.h"
  27. #include "zend_highlight.h"
  28. #include "SAPI.h"
  29. #include "php_main.h"
  30. #include "php_scandir.h"
  31. #ifdef PHP_WIN32
  32. #include "win32/php_registry.h"
  33. #endif
  34. #if HAVE_SCANDIR && HAVE_ALPHASORT && HAVE_DIRENT_H
  35. #include <dirent.h>
  36. #endif
  37. #ifndef S_ISREG
  38. #define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
  39. #endif
  40. typedef struct _php_extension_lists {
  41. zend_llist engine;
  42. zend_llist functions;
  43. } php_extension_lists;
  44. /* True globals */
  45. static HashTable configuration_hash;
  46. PHPAPI char *php_ini_opened_path=NULL;
  47. static php_extension_lists extension_lists;
  48. PHPAPI char *php_ini_scanned_files=NULL;
  49. /* {{{ php_ini_displayer_cb
  50. */
  51. static void php_ini_displayer_cb(zend_ini_entry *ini_entry, int type)
  52. {
  53. if (ini_entry->displayer) {
  54. ini_entry->displayer(ini_entry, type);
  55. } else {
  56. char *display_string;
  57. uint display_string_length, esc_html=0;
  58. TSRMLS_FETCH();
  59. if (type == ZEND_INI_DISPLAY_ORIG && ini_entry->modified) {
  60. if (ini_entry->orig_value && ini_entry->orig_value[0]) {
  61. display_string = ini_entry->orig_value;
  62. display_string_length = ini_entry->orig_value_length;
  63. esc_html = !sapi_module.phpinfo_as_text;
  64. } else {
  65. if (!sapi_module.phpinfo_as_text) {
  66. display_string = "<i>no value</i>";
  67. display_string_length = sizeof("<i>no value</i>") - 1;
  68. } else {
  69. display_string = "no value";
  70. display_string_length = sizeof("no value") - 1;
  71. }
  72. }
  73. } else if (ini_entry->value && ini_entry->value[0]) {
  74. display_string = ini_entry->value;
  75. display_string_length = ini_entry->value_length;
  76. esc_html = !sapi_module.phpinfo_as_text;
  77. } else {
  78. if (!sapi_module.phpinfo_as_text) {
  79. display_string = "<i>no value</i>";
  80. display_string_length = sizeof("<i>no value</i>") - 1;
  81. } else {
  82. display_string = "no value";
  83. display_string_length = sizeof("no value") - 1;
  84. }
  85. }
  86. if (esc_html) {
  87. php_html_puts(display_string, display_string_length TSRMLS_CC);
  88. } else {
  89. PHPWRITE(display_string, display_string_length);
  90. }
  91. }
  92. }
  93. /* }}} */
  94. /* {{{ php_ini_displayer
  95. */
  96. static int php_ini_displayer(zend_ini_entry *ini_entry, int module_number TSRMLS_DC)
  97. {
  98. if (ini_entry->module_number != module_number) {
  99. return 0;
  100. }
  101. if (!sapi_module.phpinfo_as_text) {
  102. PUTS("<tr>");
  103. PUTS("<td class=\"e\">");
  104. PHPWRITE(ini_entry->name, ini_entry->name_length - 1);
  105. PUTS("</td><td class=\"v\">");
  106. php_ini_displayer_cb(ini_entry, ZEND_INI_DISPLAY_ACTIVE);
  107. PUTS("</td><td class=\"v\">");
  108. php_ini_displayer_cb(ini_entry, ZEND_INI_DISPLAY_ORIG);
  109. PUTS("</td></tr>\n");
  110. } else {
  111. PHPWRITE(ini_entry->name, ini_entry->name_length - 1);
  112. PUTS(" => ");
  113. php_ini_displayer_cb(ini_entry, ZEND_INI_DISPLAY_ACTIVE);
  114. PUTS(" => ");
  115. php_ini_displayer_cb(ini_entry, ZEND_INI_DISPLAY_ORIG);
  116. PUTS("\n");
  117. }
  118. return 0;
  119. }
  120. /* }}} */
  121. /* {{{ display_ini_entries
  122. */
  123. PHPAPI void display_ini_entries(zend_module_entry *module)
  124. {
  125. int module_number;
  126. TSRMLS_FETCH();
  127. if (module) {
  128. module_number = module->module_number;
  129. } else {
  130. module_number = 0;
  131. }
  132. php_info_print_table_start();
  133. php_info_print_table_header(3, "Directive", "Local Value", "Master Value");
  134. zend_hash_apply_with_argument(EG(ini_directives), (apply_func_arg_t) php_ini_displayer, (void *) (long) module_number TSRMLS_CC);
  135. php_info_print_table_end();
  136. }
  137. /* }}} */
  138. /* php.ini support */
  139. #ifdef ZTS
  140. # if (ZEND_DEBUG)
  141. # define ZEND_EXTENSION_TOKEN "zend_extension_debug_ts"
  142. # else
  143. # define ZEND_EXTENSION_TOKEN "zend_extension_ts"
  144. # endif
  145. #else
  146. # if (ZEND_DEBUG)
  147. # define ZEND_EXTENSION_TOKEN "zend_extension_debug"
  148. # else
  149. # define ZEND_EXTENSION_TOKEN "zend_extension"
  150. # endif
  151. #endif
  152. /* {{{ pvalue_config_destructor
  153. */
  154. static void pvalue_config_destructor(zval *pvalue)
  155. {
  156. if (Z_TYPE_P(pvalue) == IS_STRING && Z_STRVAL_P(pvalue) != empty_string) {
  157. free(Z_STRVAL_P(pvalue));
  158. }
  159. }
  160. /* }}} */
  161. /* {{{ php_config_ini_parser_cb
  162. */
  163. static void php_config_ini_parser_cb(zval *arg1, zval *arg2, int callback_type, void *arg)
  164. {
  165. switch (callback_type) {
  166. case ZEND_INI_PARSER_ENTRY: {
  167. zval *entry;
  168. if (!arg2) {
  169. break;
  170. }
  171. if (!strcasecmp(Z_STRVAL_P(arg1), "extension")) { /* load function module */
  172. zval copy;
  173. copy = *arg2;
  174. zval_copy_ctor(&copy);
  175. copy.refcount = 0;
  176. zend_llist_add_element(&extension_lists.functions, &copy);
  177. } else if (!strcasecmp(Z_STRVAL_P(arg1), ZEND_EXTENSION_TOKEN)) { /* load Zend extension */
  178. char *extension_name = estrndup(Z_STRVAL_P(arg2), Z_STRLEN_P(arg2));
  179. zend_llist_add_element(&extension_lists.engine, &extension_name);
  180. } else {
  181. zend_hash_update(&configuration_hash, Z_STRVAL_P(arg1), Z_STRLEN_P(arg1) + 1, arg2, sizeof(zval), (void **) &entry);
  182. Z_STRVAL_P(entry) = zend_strndup(Z_STRVAL_P(entry), Z_STRLEN_P(entry));
  183. }
  184. }
  185. break;
  186. case ZEND_INI_PARSER_POP_ENTRY: {
  187. zval *hash;
  188. zval **find_hash;
  189. zval *element;
  190. if (!arg2) {
  191. /* bare string - nothing to do */
  192. break;
  193. }
  194. if (zend_hash_find(&configuration_hash, Z_STRVAL_P(arg1), Z_STRLEN_P(arg1) + 1, (void **) &find_hash) == FAILURE) {
  195. ALLOC_ZVAL(hash);
  196. array_init(hash);
  197. zend_hash_update(&configuration_hash, Z_STRVAL_P(arg1), Z_STRLEN_P(arg1) + 1, &hash, sizeof(zval *), NULL);
  198. } else {
  199. hash = *find_hash;
  200. }
  201. ALLOC_ZVAL(element);
  202. *element = *arg2;
  203. zval_copy_ctor(element);
  204. INIT_PZVAL(element);
  205. add_next_index_zval(hash, element);
  206. }
  207. break;
  208. case ZEND_INI_PARSER_SECTION:
  209. break;
  210. }
  211. }
  212. /* }}} */
  213. /* {{{ php_load_function_extension_cb
  214. */
  215. static void php_load_function_extension_cb(void *arg TSRMLS_DC)
  216. {
  217. zval *extension = (zval *) arg;
  218. zval zval;
  219. php_dl(extension, MODULE_PERSISTENT, &zval TSRMLS_CC);
  220. }
  221. /* }}} */
  222. /* {{{ php_load_zend_extension_cb
  223. */
  224. static void php_load_zend_extension_cb(void *arg TSRMLS_DC)
  225. {
  226. zend_load_extension(*((char **) arg));
  227. }
  228. /* }}} */
  229. /* {{{ php_init_config
  230. */
  231. int php_init_config()
  232. {
  233. char *env_location, *php_ini_search_path;
  234. char *binary_location;
  235. int safe_mode_state;
  236. char *open_basedir;
  237. int free_ini_search_path=0;
  238. zend_file_handle fh;
  239. struct stat sb;
  240. char ini_file[MAXPATHLEN];
  241. char *p;
  242. zend_llist scanned_ini_list;
  243. int l, total_l=0;
  244. zend_llist_element *element;
  245. TSRMLS_FETCH();
  246. if (zend_hash_init(&configuration_hash, 0, NULL, (dtor_func_t) pvalue_config_destructor, 1) == FAILURE) {
  247. return FAILURE;
  248. }
  249. if (sapi_module.ini_defaults) {
  250. sapi_module.ini_defaults(&configuration_hash);
  251. }
  252. zend_llist_init(&extension_lists.engine, sizeof(char *), (llist_dtor_func_t) free_estring, 1);
  253. zend_llist_init(&extension_lists.functions, sizeof(zval), (llist_dtor_func_t) ZVAL_DESTRUCTOR, 1);
  254. zend_llist_init(&scanned_ini_list, sizeof(char *), (llist_dtor_func_t) free_estring, 1);
  255. safe_mode_state = PG(safe_mode);
  256. open_basedir = PG(open_basedir);
  257. env_location = getenv("PHPRC");
  258. if (!env_location) {
  259. env_location = "";
  260. }
  261. if (sapi_module.php_ini_path_override) {
  262. php_ini_search_path = sapi_module.php_ini_path_override;
  263. free_ini_search_path = 0;
  264. } else {
  265. char *default_location;
  266. static const char paths_separator[] = { ZEND_PATHS_SEPARATOR, 0 };
  267. #ifdef PHP_WIN32
  268. char *reg_location;
  269. #endif
  270. php_ini_search_path = (char *) emalloc(MAXPATHLEN * 4 + strlen(env_location) + 3 + 1);
  271. free_ini_search_path = 1;
  272. php_ini_search_path[0] = 0;
  273. #ifdef PHP_WIN32
  274. /* Add registry location */
  275. reg_location = GetIniPathFromRegistry();
  276. if(reg_location != NULL) {
  277. if (*php_ini_search_path) {
  278. strcat(php_ini_search_path, paths_separator);
  279. }
  280. strcat(php_ini_search_path, reg_location);
  281. efree(reg_location);
  282. }
  283. #endif
  284. /*
  285. * Prepare search path
  286. */
  287. /* Add environment location */
  288. if (env_location[0]) {
  289. if (*php_ini_search_path) {
  290. strcat(php_ini_search_path, paths_separator);
  291. }
  292. strcat(php_ini_search_path, env_location);
  293. }
  294. /* Add cwd */
  295. #ifdef INI_CHECK_CWD
  296. if (strcmp(sapi_module.name, "cli") != 0) {
  297. if (*php_ini_search_path) {
  298. strcat(php_ini_search_path, paths_separator);
  299. }
  300. strcat(php_ini_search_path, ".");
  301. }
  302. #endif
  303. /* Add binary directory */
  304. #ifdef PHP_WIN32
  305. binary_location = (char *) emalloc(MAXPATHLEN);
  306. if (GetModuleFileName(0, binary_location, MAXPATHLEN) == 0) {
  307. efree(binary_location);
  308. binary_location = NULL;
  309. }
  310. #else
  311. if (sapi_module.executable_location) {
  312. binary_location = estrdup(sapi_module.executable_location);
  313. } else {
  314. binary_location = NULL;
  315. }
  316. #endif
  317. if (binary_location) {
  318. char *separator_location = strrchr(binary_location, DEFAULT_SLASH);
  319. if (separator_location) {
  320. *(separator_location+1) = 0;
  321. }
  322. if (*php_ini_search_path) {
  323. strcat(php_ini_search_path, paths_separator);
  324. }
  325. strcat(php_ini_search_path, binary_location);
  326. efree(binary_location);
  327. }
  328. /* Add default location */
  329. #ifdef PHP_WIN32
  330. default_location = (char *) emalloc(MAXPATHLEN + 1);
  331. if (0 < GetWindowsDirectory(default_location, MAXPATHLEN)) {
  332. if (*php_ini_search_path) {
  333. strcat(php_ini_search_path, paths_separator);
  334. }
  335. strcat(php_ini_search_path, default_location);
  336. }
  337. efree(default_location);
  338. {
  339. /* For people running under terminal services, GetWindowsDirectory will
  340. * return their personal Windows directory, so lets add the system
  341. * windows directory too */
  342. typedef UINT (WINAPI *get_system_windows_directory_func)(char *buffer, UINT size);
  343. static get_system_windows_directory_func get_system_windows_directory = NULL;
  344. HMODULE kern;
  345. if (get_system_windows_directory == NULL) {
  346. kern = LoadLibrary("kernel32.dll");
  347. if (kern) {
  348. get_system_windows_directory = (get_system_windows_directory_func)GetProcAddress(kern, "GetSystemWindowsDirectoryA");
  349. }
  350. }
  351. if (get_system_windows_directory != NULL) {
  352. default_location = (char *) emalloc(MAXPATHLEN + 1);
  353. if (0 < get_system_windows_directory(default_location, MAXPATHLEN)) {
  354. if (*php_ini_search_path) {
  355. strcat(php_ini_search_path, paths_separator);
  356. }
  357. strcat(php_ini_search_path, default_location);
  358. }
  359. efree(default_location);
  360. }
  361. }
  362. #else
  363. default_location = PHP_CONFIG_FILE_PATH;
  364. if (*php_ini_search_path) {
  365. strcat(php_ini_search_path, paths_separator);
  366. }
  367. strcat(php_ini_search_path, default_location);
  368. #endif
  369. }
  370. PG(safe_mode) = 0;
  371. PG(open_basedir) = NULL;
  372. memset(&fh, 0, sizeof(fh));
  373. /* Check if php_ini_path_override is a file */
  374. if (!sapi_module.php_ini_ignore) {
  375. if (sapi_module.php_ini_path_override && sapi_module.php_ini_path_override[0]) {
  376. struct stat statbuf;
  377. if (!VCWD_STAT(sapi_module.php_ini_path_override, &statbuf)) {
  378. if (!((statbuf.st_mode & S_IFMT) == S_IFDIR)) {
  379. fh.handle.fp = VCWD_FOPEN(sapi_module.php_ini_path_override, "r");
  380. fh.filename = sapi_module.php_ini_path_override;
  381. }
  382. }
  383. }
  384. /* Search php-%sapi-module-name%.ini file in search path */
  385. if (!fh.handle.fp) {
  386. const char *fmt = "php-%s.ini";
  387. char *ini_fname = emalloc(strlen(fmt) + strlen(sapi_module.name));
  388. sprintf(ini_fname, fmt, sapi_module.name);
  389. fh.handle.fp = php_fopen_with_path(ini_fname, "r", php_ini_search_path, &php_ini_opened_path TSRMLS_CC);
  390. efree(ini_fname);
  391. if (fh.handle.fp) {
  392. fh.filename = php_ini_opened_path;
  393. }
  394. }
  395. /* Search php.ini file in search path */
  396. if (!fh.handle.fp) {
  397. fh.handle.fp = php_fopen_with_path("php.ini", "r", php_ini_search_path, &php_ini_opened_path TSRMLS_CC);
  398. if (fh.handle.fp) {
  399. fh.filename = php_ini_opened_path;
  400. }
  401. }
  402. }
  403. if (free_ini_search_path) {
  404. efree(php_ini_search_path);
  405. }
  406. PG(safe_mode) = safe_mode_state;
  407. PG(open_basedir) = open_basedir;
  408. if (fh.handle.fp) {
  409. fh.type = ZEND_HANDLE_FP;
  410. zend_parse_ini_file(&fh, 1, php_config_ini_parser_cb, &extension_lists);
  411. {
  412. zval tmp;
  413. Z_STRLEN(tmp) = strlen(fh.filename);
  414. Z_STRVAL(tmp) = zend_strndup(fh.filename, Z_STRLEN(tmp));
  415. Z_TYPE(tmp) = IS_STRING;
  416. zend_hash_update(&configuration_hash, "cfg_file_path", sizeof("cfg_file_path"), (void *) &tmp, sizeof(zval), NULL);
  417. if (php_ini_opened_path) {
  418. efree(php_ini_opened_path);
  419. }
  420. php_ini_opened_path = zend_strndup(Z_STRVAL(tmp), Z_STRLEN(tmp));
  421. }
  422. }
  423. /* If the config_file_scan_dir is set at compile-time, go and scan this directory and
  424. * parse any .ini files found in this directory. */
  425. if (!sapi_module.php_ini_ignore && strlen(PHP_CONFIG_FILE_SCAN_DIR)) {
  426. struct dirent **namelist;
  427. int ndir, i;
  428. if ((ndir = php_scandir(PHP_CONFIG_FILE_SCAN_DIR, &namelist, 0, php_alphasort)) > 0) {
  429. for (i = 0; i < ndir; i++) {
  430. /* check for a .ini extension */
  431. if (!(p = strrchr(namelist[i]->d_name, '.')) || (p && strcmp(p, ".ini"))) {
  432. free(namelist[i]);
  433. continue;
  434. }
  435. snprintf(ini_file, MAXPATHLEN, "%s%c%s", PHP_CONFIG_FILE_SCAN_DIR, DEFAULT_SLASH, namelist[i]->d_name);
  436. if (VCWD_STAT(ini_file, &sb) == 0) {
  437. if (S_ISREG(sb.st_mode)) {
  438. if ((fh.handle.fp = VCWD_FOPEN(ini_file, "r"))) {
  439. fh.filename = ini_file;
  440. fh.type = ZEND_HANDLE_FP;
  441. zend_parse_ini_file(&fh, 1, php_config_ini_parser_cb, &extension_lists);
  442. /* Here, add it to the list of ini files read */
  443. l = strlen(ini_file);
  444. total_l += l + 2;
  445. p = estrndup(ini_file, l);
  446. zend_llist_add_element(&scanned_ini_list, &p);
  447. }
  448. }
  449. }
  450. free(namelist[i]);
  451. }
  452. free(namelist);
  453. /*
  454. * Don't need an extra byte for the \0 in this malloc as the last
  455. * element will not get a trailing , which gives us the byte for the \0
  456. */
  457. php_ini_scanned_files = (char *) malloc(total_l);
  458. *php_ini_scanned_files = '\0';
  459. for (element = scanned_ini_list.head; element; element = element->next) {
  460. strcat(php_ini_scanned_files, *(char **)element->data);
  461. strcat(php_ini_scanned_files, element->next ? ",\n" : "\n");
  462. }
  463. zend_llist_destroy(&scanned_ini_list);
  464. }
  465. }
  466. return SUCCESS;
  467. }
  468. /* }}} */
  469. /* {{{ php_shutdown_config
  470. */
  471. int php_shutdown_config(void)
  472. {
  473. zend_hash_destroy(&configuration_hash);
  474. if (php_ini_opened_path) {
  475. free(php_ini_opened_path);
  476. }
  477. if (php_ini_scanned_files) {
  478. free(php_ini_scanned_files);
  479. }
  480. return SUCCESS;
  481. }
  482. /* }}} */
  483. /* {{{ php_ini_delayed_modules_startup
  484. */
  485. void php_ini_delayed_modules_startup(TSRMLS_D)
  486. {
  487. zend_llist_apply(&extension_lists.engine, php_load_zend_extension_cb TSRMLS_CC);
  488. zend_llist_apply(&extension_lists.functions, php_load_function_extension_cb TSRMLS_CC);
  489. zend_llist_destroy(&extension_lists.engine);
  490. zend_llist_destroy(&extension_lists.functions);
  491. }
  492. /* }}} */
  493. /* {{{ cfg_get_entry
  494. */
  495. zval *cfg_get_entry(char *name, uint name_length)
  496. {
  497. zval *tmp;
  498. if (zend_hash_find(&configuration_hash, name, name_length, (void **) &tmp) == SUCCESS) {
  499. return tmp;
  500. } else {
  501. return NULL;
  502. }
  503. }
  504. /* }}} */
  505. /* {{{ cfg_get_long
  506. */
  507. PHPAPI int cfg_get_long(char *varname, long *result)
  508. {
  509. zval *tmp, var;
  510. if (zend_hash_find(&configuration_hash, varname, strlen(varname) + 1, (void **) &tmp) == FAILURE) {
  511. *result = (long) NULL;
  512. return FAILURE;
  513. }
  514. var = *tmp;
  515. zval_copy_ctor(&var);
  516. convert_to_long(&var);
  517. *result = Z_LVAL(var);
  518. return SUCCESS;
  519. }
  520. /* }}} */
  521. /* {{{ cfg_get_double
  522. */
  523. PHPAPI int cfg_get_double(char *varname, double *result)
  524. {
  525. zval *tmp, var;
  526. if (zend_hash_find(&configuration_hash, varname, strlen(varname) + 1, (void **) &tmp) == FAILURE) {
  527. *result = (double) 0;
  528. return FAILURE;
  529. }
  530. var = *tmp;
  531. zval_copy_ctor(&var);
  532. convert_to_double(&var);
  533. *result = Z_DVAL(var);
  534. return SUCCESS;
  535. }
  536. /* }}} */
  537. /* {{{ cfg_get_string
  538. */
  539. PHPAPI int cfg_get_string(char *varname, char **result)
  540. {
  541. zval *tmp;
  542. if (zend_hash_find(&configuration_hash, varname, strlen(varname)+1, (void **) &tmp) == FAILURE) {
  543. *result = NULL;
  544. return FAILURE;
  545. }
  546. *result = Z_STRVAL_P(tmp);
  547. return SUCCESS;
  548. }
  549. /* }}} */
  550. /*
  551. * Local variables:
  552. * tab-width: 4
  553. * c-basic-offset: 4
  554. * indent-tabs-mode: t
  555. * End:
  556. * vim600: sw=4 ts=4 fdm=marker
  557. * vim<600: sw=4 ts=4
  558. */