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.

611 lines
16 KiB

27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
Generalized server-API build process on UNIX. Each SAPI implementation now has its own directory under sapi/, just like extensions have theirs under ext/. To make the final targets appear in the main dir, the top-level Makefile includes sapi/NN/Makefile.inc from the selected sapi backend. This is a plan Makefile stub without any autoconf substitutions. Each SAPI backend also has its own config.m4 like extensions (read at the end of diversion 2) and config.h.stub files. Each SAPI backend has to contain: config.m4: just like for extensions, this file contains autoconf/automake directives that end up in the configure script. The only difference is that the sapi config.m4 files are read in diversion (output block) 2 instead of 3. The sapi config.m4 files should set two variables: PHP_SAPI (which sapi backend to choose) and SAPI_TARGET (the name of the resulting library or program, previously BINNAME). If they are not specified, they will default to "cgi" and "php", respectively. Makefile.inc: has to exist, has to define "INSTALL_IT" to the command used to install the final target (or ":" for no operation). It also has to define a plain Makefile rule (without autoconf substitutions) to build $(SAPI_TARGET) Makefile.am: just what you think. Make sure your target is called "libphpsapi_NNN.a", where NNN is the value of PHP_SAPI. Some testing and fixing probably remains. To make everything hang together, I've done some ugly tricks that I can imagine causing some problems. I've built and run the CGI version and built the Apache DSO.
27 years ago
27 years ago
Generalized server-API build process on UNIX. Each SAPI implementation now has its own directory under sapi/, just like extensions have theirs under ext/. To make the final targets appear in the main dir, the top-level Makefile includes sapi/NN/Makefile.inc from the selected sapi backend. This is a plan Makefile stub without any autoconf substitutions. Each SAPI backend also has its own config.m4 like extensions (read at the end of diversion 2) and config.h.stub files. Each SAPI backend has to contain: config.m4: just like for extensions, this file contains autoconf/automake directives that end up in the configure script. The only difference is that the sapi config.m4 files are read in diversion (output block) 2 instead of 3. The sapi config.m4 files should set two variables: PHP_SAPI (which sapi backend to choose) and SAPI_TARGET (the name of the resulting library or program, previously BINNAME). If they are not specified, they will default to "cgi" and "php", respectively. Makefile.inc: has to exist, has to define "INSTALL_IT" to the command used to install the final target (or ":" for no operation). It also has to define a plain Makefile rule (without autoconf substitutions) to build $(SAPI_TARGET) Makefile.am: just what you think. Make sure your target is called "libphpsapi_NNN.a", where NNN is the value of PHP_SAPI. Some testing and fixing probably remains. To make everything hang together, I've done some ugly tricks that I can imagine causing some problems. I've built and run the CGI version and built the Apache DSO.
27 years ago
27 years ago
Generalized server-API build process on UNIX. Each SAPI implementation now has its own directory under sapi/, just like extensions have theirs under ext/. To make the final targets appear in the main dir, the top-level Makefile includes sapi/NN/Makefile.inc from the selected sapi backend. This is a plan Makefile stub without any autoconf substitutions. Each SAPI backend also has its own config.m4 like extensions (read at the end of diversion 2) and config.h.stub files. Each SAPI backend has to contain: config.m4: just like for extensions, this file contains autoconf/automake directives that end up in the configure script. The only difference is that the sapi config.m4 files are read in diversion (output block) 2 instead of 3. The sapi config.m4 files should set two variables: PHP_SAPI (which sapi backend to choose) and SAPI_TARGET (the name of the resulting library or program, previously BINNAME). If they are not specified, they will default to "cgi" and "php", respectively. Makefile.inc: has to exist, has to define "INSTALL_IT" to the command used to install the final target (or ":" for no operation). It also has to define a plain Makefile rule (without autoconf substitutions) to build $(SAPI_TARGET) Makefile.am: just what you think. Make sure your target is called "libphpsapi_NNN.a", where NNN is the value of PHP_SAPI. Some testing and fixing probably remains. To make everything hang together, I've done some ugly tricks that I can imagine causing some problems. I've built and run the CGI version and built the Apache DSO.
27 years ago
Generalized server-API build process on UNIX. Each SAPI implementation now has its own directory under sapi/, just like extensions have theirs under ext/. To make the final targets appear in the main dir, the top-level Makefile includes sapi/NN/Makefile.inc from the selected sapi backend. This is a plan Makefile stub without any autoconf substitutions. Each SAPI backend also has its own config.m4 like extensions (read at the end of diversion 2) and config.h.stub files. Each SAPI backend has to contain: config.m4: just like for extensions, this file contains autoconf/automake directives that end up in the configure script. The only difference is that the sapi config.m4 files are read in diversion (output block) 2 instead of 3. The sapi config.m4 files should set two variables: PHP_SAPI (which sapi backend to choose) and SAPI_TARGET (the name of the resulting library or program, previously BINNAME). If they are not specified, they will default to "cgi" and "php", respectively. Makefile.inc: has to exist, has to define "INSTALL_IT" to the command used to install the final target (or ":" for no operation). It also has to define a plain Makefile rule (without autoconf substitutions) to build $(SAPI_TARGET) Makefile.am: just what you think. Make sure your target is called "libphpsapi_NNN.a", where NNN is the value of PHP_SAPI. Some testing and fixing probably remains. To make everything hang together, I've done some ugly tricks that I can imagine causing some problems. I've built and run the CGI version and built the Apache DSO.
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
Generalized server-API build process on UNIX. Each SAPI implementation now has its own directory under sapi/, just like extensions have theirs under ext/. To make the final targets appear in the main dir, the top-level Makefile includes sapi/NN/Makefile.inc from the selected sapi backend. This is a plan Makefile stub without any autoconf substitutions. Each SAPI backend also has its own config.m4 like extensions (read at the end of diversion 2) and config.h.stub files. Each SAPI backend has to contain: config.m4: just like for extensions, this file contains autoconf/automake directives that end up in the configure script. The only difference is that the sapi config.m4 files are read in diversion (output block) 2 instead of 3. The sapi config.m4 files should set two variables: PHP_SAPI (which sapi backend to choose) and SAPI_TARGET (the name of the resulting library or program, previously BINNAME). If they are not specified, they will default to "cgi" and "php", respectively. Makefile.inc: has to exist, has to define "INSTALL_IT" to the command used to install the final target (or ":" for no operation). It also has to define a plain Makefile rule (without autoconf substitutions) to build $(SAPI_TARGET) Makefile.am: just what you think. Make sure your target is called "libphpsapi_NNN.a", where NNN is the value of PHP_SAPI. Some testing and fixing probably remains. To make everything hang together, I've done some ugly tricks that I can imagine causing some problems. I've built and run the CGI version and built the Apache DSO.
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
  1. /*
  2. +----------------------------------------------------------------------+
  3. | PHP version 4.0 |
  4. +----------------------------------------------------------------------+
  5. | Copyright (c) 1997, 1998, 1999 The PHP Group |
  6. +----------------------------------------------------------------------+
  7. | This source file is subject to version 2.0 of the PHP license, |
  8. | that is bundled with this package in the file LICENSE, and is |
  9. | available at through the world-wide-web at |
  10. | http://www.php.net/license/2_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. | Authors: Rasmus Lerdorf <rasmus@php.net> |
  16. | (with helpful hints from Dean Gaudet <dgaudet@arctic.org> |
  17. | PHP 4.0 patches by Zeev Suraski <zeev@zend.com> |
  18. +----------------------------------------------------------------------+
  19. */
  20. /* $Id$ */
  21. #include "httpd.h"
  22. #include "http_config.h"
  23. #if MODULE_MAGIC_NUMBER > 19980712
  24. # include "ap_compat.h"
  25. #else
  26. # if MODULE_MAGIC_NUMBER > 19980324
  27. # include "compat.h"
  28. # endif
  29. #endif
  30. #include "http_core.h"
  31. #include "http_main.h"
  32. #include "http_protocol.h"
  33. #include "http_request.h"
  34. #include "http_log.h"
  35. #include "zend.h"
  36. #include "php.h"
  37. #include "php_ini.h"
  38. #include "php_globals.h"
  39. #include "SAPI.h"
  40. #include "main.h"
  41. #include "zend_compile.h"
  42. #include "zend_execute.h"
  43. #include "zend_highlight.h"
  44. #include "zend_indent.h"
  45. #include "ext/standard/php3_standard.h"
  46. #include "util_script.h"
  47. #include "php_version.h"
  48. #include "mod_php4.h"
  49. #if HAVE_MOD_DAV
  50. # include "mod_dav.h"
  51. #endif
  52. PHPAPI int apache_php_module_main(request_rec *r, int fd, int display_source_mode SLS_DC);
  53. /* ### these should be defined in mod_php4.h or somewhere else */
  54. #define USE_PATH 1
  55. #define IGNORE_URL 2
  56. module MODULE_VAR_EXPORT php4_module;
  57. int saved_umask;
  58. static unsigned char apache_php_initialized;
  59. typedef struct _php_per_dir_entry {
  60. char *key;
  61. char *value;
  62. uint key_length;
  63. uint value_length;
  64. int type;
  65. } php_per_dir_entry;
  66. #if WIN32|WINNT
  67. /* popenf isn't working on Windows, use open instead*/
  68. # ifdef popenf
  69. # undef popenf
  70. # endif
  71. # define popenf(p,n,f,m) open((n),(f),(m))
  72. # ifdef pclosef
  73. # undef pclosef
  74. # endif
  75. # define pclosef(p,f) close(f)
  76. #else
  77. # define php3i_popenf(p,n,f,m) popenf((p),(n),(f),(m))
  78. #endif
  79. php_apache_info_struct php_apache_info; /* active config */
  80. /* some systems are missing these from their header files */
  81. void php_save_umask()
  82. {
  83. saved_umask = umask(077);
  84. umask(saved_umask);
  85. }
  86. static int zend_apache_ub_write(const char *str, uint str_length)
  87. {
  88. int ret;
  89. SLS_FETCH();
  90. if (SG(server_context)) {
  91. ret = rwrite(str, str_length, (request_rec *) SG(server_context));
  92. } else {
  93. ret = fwrite(str, 1, str_length, stdout);
  94. }
  95. if(ret != str_length) {
  96. PG(connection_status) = PHP_CONNECTION_ABORTED;
  97. if(!PG(ignore_user_abort)) zend_bailout();
  98. }
  99. return ret;
  100. }
  101. int sapi_apache_read_post(char *buffer, uint count_bytes SLS_DC)
  102. {
  103. uint total_read_bytes=0, read_bytes;
  104. request_rec *r = (request_rec *) SG(server_context);
  105. void (*handler)(int);
  106. handler = signal(SIGPIPE, SIG_IGN);
  107. while (total_read_bytes<count_bytes) {
  108. hard_timeout("Read POST information", r); /* start timeout timer */
  109. read_bytes = get_client_block(r, buffer+total_read_bytes, count_bytes-total_read_bytes);
  110. reset_timeout(r);
  111. if (read_bytes<=0) {
  112. break;
  113. }
  114. total_read_bytes += read_bytes;
  115. }
  116. signal(SIGPIPE, handler);
  117. return total_read_bytes;
  118. }
  119. char *sapi_apache_read_cookies(SLS_D)
  120. {
  121. return (char *) table_get(((request_rec *) SG(server_context))->subprocess_env, "HTTP_COOKIE");
  122. }
  123. int sapi_apache_header_handler(sapi_header_struct *sapi_header, sapi_headers_struct *sapi_headers SLS_DC)
  124. {
  125. char *header_name, *header_content, *p;
  126. request_rec *r = (request_rec *) SG(server_context);
  127. header_name = sapi_header->header;
  128. header_content = p = strchr(header_name, ':');
  129. if (!p) {
  130. return 0;
  131. }
  132. *p = 0;
  133. do {
  134. header_content++;
  135. } while (*header_content==' ');
  136. if (!strcasecmp(header_name, "Content-Type")) {
  137. r->content_type = pstrdup(r->pool, header_content);
  138. } else if (!strcasecmp(header_name, "Set-Cookie")) {
  139. table_add(r->headers_out, header_name, header_content);
  140. } else {
  141. table_set(r->headers_out, header_name, header_content);
  142. }
  143. *p = ':'; /* a well behaved header handler shouldn't change its original arguments */
  144. efree(sapi_header->header);
  145. return 0; /* don't use the default SAPI mechanism, Apache duplicates this functionality */
  146. }
  147. int sapi_apache_send_headers(sapi_headers_struct *sapi_headers SLS_DC)
  148. {
  149. ((request_rec *) SG(server_context))->status = SG(sapi_headers).http_response_code;
  150. send_http_header((request_rec *) SG(server_context));
  151. return SAPI_HEADER_SENT_SUCCESSFULLY;
  152. }
  153. sapi_module_struct sapi_module = {
  154. "PHP Language", /* name */
  155. php_module_startup, /* startup */
  156. php_module_shutdown_wrapper, /* shutdown */
  157. zend_apache_ub_write, /* unbuffered write */
  158. php_error, /* error handler */
  159. sapi_apache_header_handler, /* header handler */
  160. sapi_apache_send_headers, /* send headers handler */
  161. NULL, /* send header handler */
  162. sapi_apache_read_post, /* read POST data */
  163. sapi_apache_read_cookies, /* read Cookies */
  164. STANDARD_SAPI_MODULE_PROPERTIES
  165. };
  166. void php_restore_umask()
  167. {
  168. umask(saved_umask);
  169. }
  170. static void init_request_info(SLS_D)
  171. {
  172. request_rec *r = ((request_rec *) SG(server_context));
  173. char *content_length = (char *) table_get(r->subprocess_env, "CONTENT_LENGTH");
  174. const char *authorization=NULL;
  175. char *tmp;
  176. SG(request_info).query_string = r->args;
  177. SG(request_info).path_translated = r->filename;
  178. SG(request_info).request_uri = r->uri;
  179. SG(request_info).request_method = (char *)r->method;
  180. SG(request_info).content_type = (char *) table_get(r->subprocess_env, "CONTENT_TYPE");
  181. SG(request_info).content_length = (content_length ? atoi(content_length) : 0);
  182. if (r->headers_in) {
  183. authorization = table_get(r->headers_in, "Authorization");
  184. }
  185. if (authorization
  186. /* && !auth_type(r) */
  187. && !strcmp(getword(r->pool, &authorization, ' '), "Basic")) {
  188. tmp = uudecode(r->pool, authorization);
  189. SG(request_info).auth_user = getword_nulls_nc(r->pool, &tmp, ':');
  190. if (SG(request_info).auth_user) {
  191. SG(request_info).auth_user = estrdup(SG(request_info).auth_user);
  192. }
  193. SG(request_info).auth_password = tmp;
  194. if (SG(request_info).auth_password) {
  195. SG(request_info).auth_password = estrdup(SG(request_info).auth_password);
  196. }
  197. } else {
  198. SG(request_info).auth_user = NULL;
  199. SG(request_info).auth_password = NULL;
  200. }
  201. }
  202. static int php_apache_alter_ini_entries(php_per_dir_entry *per_dir_entry)
  203. {
  204. php_alter_ini_entry(per_dir_entry->key, per_dir_entry->key_length+1, per_dir_entry->value, per_dir_entry->value_length+1, per_dir_entry->type);
  205. return 0;
  206. }
  207. int send_php(request_rec *r, int display_source_mode, char *filename)
  208. {
  209. int fd, retval;
  210. HashTable *per_dir_conf;
  211. SLS_FETCH();
  212. if (setjmp(EG(bailout))!=0) {
  213. return OK;
  214. }
  215. per_dir_conf = (HashTable *) get_module_config(r->per_dir_config, &php4_module);
  216. zend_hash_apply((HashTable *) per_dir_conf, (int (*)(void *)) php_apache_alter_ini_entries);
  217. /* We don't accept OPTIONS requests, but take everything else */
  218. if (r->method_number == M_OPTIONS) {
  219. r->allowed |= (1 << METHODS) - 1;
  220. return DECLINED;
  221. }
  222. /* Make sure file exists */
  223. if (filename == NULL && r->finfo.st_mode == 0) {
  224. return NOT_FOUND;
  225. }
  226. /* If PHP parser engine has been turned off with an "engine off"
  227. * directive, then decline to handle this request
  228. */
  229. if (!php_apache_info.engine) {
  230. r->content_type = "text/html";
  231. r->allowed |= (1 << METHODS) - 1;
  232. return DECLINED;
  233. }
  234. if (filename == NULL) {
  235. filename = r->filename;
  236. }
  237. /* Open the file */
  238. if ((fd = popenf(r->pool, filename, O_RDONLY, 0)) == -1) {
  239. log_reason("file permissions deny server access", filename, r);
  240. return FORBIDDEN;
  241. }
  242. /* Apache 1.2 has a more complex mechanism for reading POST data */
  243. #if MODULE_MAGIC_NUMBER > 19961007
  244. if ((retval = setup_client_block(r, REQUEST_CHUNKED_ERROR)))
  245. return retval;
  246. #endif
  247. if (php_apache_info.last_modified) {
  248. #if MODULE_MAGIC_NUMBER < 19970912
  249. if ((retval = set_last_modified(r, r->finfo.st_mtime))) {
  250. return retval;
  251. }
  252. #else
  253. update_mtime (r, r->finfo.st_mtime);
  254. set_last_modified(r);
  255. set_etag(r);
  256. #endif
  257. }
  258. /* Assume output will be HTML. Individual scripts may change this
  259. further down the line */
  260. r->content_type = "text/html";
  261. /* Init timeout */
  262. hard_timeout("send", r);
  263. SG(server_context) = r;
  264. php_save_umask();
  265. chdir_file(filename);
  266. add_common_vars(r);
  267. add_cgi_vars(r);
  268. init_request_info(SLS_C);
  269. apache_php_module_main(r, fd, display_source_mode SLS_CC);
  270. /* Done, restore umask, turn off timeout, close file and return */
  271. php_restore_umask();
  272. kill_timeout(r);
  273. pclosef(r->pool, fd);
  274. return OK;
  275. }
  276. int send_parsed_php(request_rec * r)
  277. {
  278. return send_php(r, 0, NULL);
  279. }
  280. int send_parsed_php_source(request_rec * r)
  281. {
  282. return send_php(r, 1, NULL);
  283. }
  284. static int destroy_per_dir_entry(php_per_dir_entry *per_dir_entry)
  285. {
  286. free(per_dir_entry->key);
  287. free(per_dir_entry->value);
  288. return 1;
  289. }
  290. static void copy_per_dir_entry(php_per_dir_entry *per_dir_entry)
  291. {
  292. php_per_dir_entry tmp = *per_dir_entry;
  293. per_dir_entry->key = (char *) malloc(tmp.key_length+1);
  294. memcpy(per_dir_entry->key, tmp.key, tmp.key_length);
  295. per_dir_entry->key[per_dir_entry->key_length] = 0;
  296. per_dir_entry->value = (char *) malloc(tmp.value_length+1);
  297. memcpy(per_dir_entry->value, tmp.value, tmp.value_length);
  298. per_dir_entry->value[per_dir_entry->value_length] = 0;
  299. }
  300. static void php_destroy_per_dir_info(HashTable *per_dir_info)
  301. {
  302. zend_hash_destroy(per_dir_info);
  303. free(per_dir_info);
  304. }
  305. static void *php_create_dir(pool *p, char *dummy)
  306. {
  307. HashTable *per_dir_info;
  308. per_dir_info = (HashTable *) malloc(sizeof(HashTable));
  309. zend_hash_init(per_dir_info, 5, NULL, (int (*)(void *)) destroy_per_dir_entry, 1);
  310. register_cleanup(p, (void *) per_dir_info, (void (*)(void *)) php_destroy_per_dir_info, (void (*)(void *)) zend_hash_destroy);
  311. return per_dir_info;
  312. }
  313. static void *php_merge_dir(pool *p, void *basev, void *addv)
  314. {
  315. php_per_dir_entry tmp;
  316. zend_hash_merge((HashTable *) addv, (HashTable *) basev, (void (*)(void *)) copy_per_dir_entry, &tmp, sizeof(php_per_dir_entry), 0);
  317. return addv;
  318. }
  319. #if MODULE_MAGIC_NUMBER > 19961007
  320. #define CONST_PREFIX const
  321. #else
  322. #define CONST_PREFIX
  323. #endif
  324. CONST_PREFIX char *php_apache_value_handler_ex(cmd_parms *cmd, HashTable *conf, char *arg1, char *arg2, int mode)
  325. {
  326. php_per_dir_entry per_dir_entry;
  327. if (!apache_php_initialized) {
  328. sapi_startup(&sapi_module);
  329. php_module_startup(&sapi_module);
  330. apache_php_initialized = 1;
  331. }
  332. per_dir_entry.type = mode;
  333. per_dir_entry.key_length = strlen(arg1);
  334. per_dir_entry.value_length = strlen(arg2);
  335. per_dir_entry.key = (char *) malloc(per_dir_entry.key_length+1);
  336. memcpy(per_dir_entry.key, arg1, per_dir_entry.key_length);
  337. per_dir_entry.key[per_dir_entry.key_length] = 0;
  338. per_dir_entry.value = (char *) malloc(per_dir_entry.value_length+1);
  339. memcpy(per_dir_entry.value, arg2, per_dir_entry.value_length);
  340. per_dir_entry.value[per_dir_entry.value_length] = 0;
  341. zend_hash_update((HashTable *) conf, per_dir_entry.key, per_dir_entry.key_length, &per_dir_entry, sizeof(php_per_dir_entry), NULL);
  342. return NULL;
  343. }
  344. CONST_PREFIX char *php_apache_value_handler(cmd_parms *cmd, HashTable *conf, char *arg1, char *arg2)
  345. {
  346. return php_apache_value_handler_ex(cmd, conf, arg1, arg2, PHP_INI_PERDIR);
  347. }
  348. CONST_PREFIX char *php_apache_admin_value_handler(cmd_parms *cmd, HashTable *conf, char *arg1, char *arg2)
  349. {
  350. return php_apache_value_handler_ex(cmd, conf, arg1, arg2, PHP_INI_SYSTEM);
  351. }
  352. CONST_PREFIX char *php_apache_flag_handler_ex(cmd_parms *cmd, HashTable *conf, char *arg1, char *arg2, int mode)
  353. {
  354. char bool_val[2];
  355. if (!strcasecmp(arg2, "On")) {
  356. bool_val[0] = '1';
  357. } else {
  358. bool_val[0] = '0';
  359. }
  360. bool_val[1] = 0;
  361. return php_apache_value_handler_ex(cmd, conf, arg1, bool_val, mode);
  362. }
  363. CONST_PREFIX char *php_apache_flag_handler(cmd_parms *cmd, HashTable *conf, char *arg1, char *arg2)
  364. {
  365. return php_apache_flag_handler_ex(cmd, conf, arg1, arg2, PHP_INI_PERDIR);
  366. }
  367. CONST_PREFIX char *php_apache_admin_flag_handler(cmd_parms *cmd, HashTable *conf, char *arg1, char *arg2)
  368. {
  369. return php_apache_flag_handler_ex(cmd, conf, arg1, arg2, PHP_INI_SYSTEM);
  370. }
  371. int php_xbithack_handler(request_rec * r)
  372. {
  373. php_apache_info_struct *conf;
  374. conf = (php_apache_info_struct *) get_module_config(r->per_dir_config, &php4_module);
  375. if (!(r->finfo.st_mode & S_IXUSR)) {
  376. r->allowed |= (1 << METHODS) - 1;
  377. return DECLINED;
  378. }
  379. if (conf->xbithack == 0) {
  380. r->allowed |= (1 << METHODS) - 1;
  381. return DECLINED;
  382. }
  383. return send_parsed_php(r);
  384. }
  385. static void apache_php_module_shutdown_wrapper(void)
  386. {
  387. apache_php_initialized = 0;
  388. sapi_module.shutdown(&sapi_module);
  389. }
  390. void php_init_handler(server_rec *s, pool *p)
  391. {
  392. register_cleanup(p, NULL, (void (*)(void *))apache_php_module_shutdown_wrapper, php_module_shutdown_for_exec);
  393. if (!apache_php_initialized) {
  394. sapi_startup(&sapi_module);
  395. php_module_startup(&sapi_module);
  396. apache_php_initialized = 1;
  397. }
  398. #if MODULE_MAGIC_NUMBER >= 19980527
  399. if (PG(expose_php)) {
  400. ap_add_version_component("PHP/" PHP_VERSION);
  401. }
  402. #endif
  403. }
  404. #if HAVE_MOD_DAV
  405. extern int phpdav_mkcol_test_handler(request_rec *r);
  406. extern int phpdav_mkcol_create_handler(request_rec *r);
  407. /* conf is being read twice (both here and in send_php()) */
  408. int send_parsed_php_dav_script(request_rec *r)
  409. {
  410. php_apache_info_struct *conf;
  411. conf = (php_apache_info_struct *) get_module_config(r->per_dir_config,
  412. &php4_module);
  413. return send_php(r, 0, 0, conf->dav_script);
  414. }
  415. static int php_type_checker(request_rec *r)
  416. {
  417. php_apache_info_struct *conf;
  418. conf = (php_apache_info_struct *)get_module_config(r->per_dir_config,
  419. &php4_module);
  420. /* If DAV support is enabled, use mod_dav's type checker. */
  421. if (conf->dav_script) {
  422. dav_api_set_request_handler(r, send_parsed_php_dav_script);
  423. dav_api_set_mkcol_handlers(r, phpdav_mkcol_test_handler,
  424. phpdav_mkcol_create_handler);
  425. /* leave the rest of the request to mod_dav */
  426. return dav_api_type_checker(r);
  427. }
  428. return DECLINED;
  429. }
  430. #else /* HAVE_MOD_DAV */
  431. # define php_type_checker NULL
  432. #endif /* HAVE_MOD_DAV */
  433. handler_rec php_handlers[] =
  434. {
  435. {"application/x-httpd-php", send_parsed_php},
  436. {"application/x-httpd-php-source", send_parsed_php_source},
  437. {"text/html", php_xbithack_handler},
  438. {NULL}
  439. };
  440. command_rec php_commands[] =
  441. {
  442. {"php_value", php_apache_value_handler, NULL, OR_OPTIONS, TAKE2, "PHP Value Modifier"},
  443. {"php_flag", php_apache_flag_handler, NULL, OR_OPTIONS, TAKE2, "PHP Flag Modifier"},
  444. {"php_admin_value", php_apache_admin_value_handler, NULL, ACCESS_CONF|RSRC_CONF, TAKE2, "PHP Value Modifier (Admin)"},
  445. {"php_admin_flag", php_apache_admin_flag_handler, NULL, ACCESS_CONF|RSRC_CONF, TAKE2, "PHP Flag Modifier (Admin)"},
  446. {NULL}
  447. };
  448. module MODULE_VAR_EXPORT php4_module =
  449. {
  450. STANDARD_MODULE_STUFF,
  451. php_init_handler, /* initializer */
  452. php_create_dir, /* per-directory config creator */
  453. php_merge_dir, /* dir merger */
  454. NULL, /* per-server config creator */
  455. NULL, /* merge server config */
  456. php_commands, /* command table */
  457. php_handlers, /* handlers */
  458. NULL, /* filename translation */
  459. NULL, /* check_user_id */
  460. NULL, /* check auth */
  461. NULL, /* check access */
  462. php_type_checker, /* type_checker */
  463. NULL, /* fixups */
  464. NULL /* logger */
  465. #if MODULE_MAGIC_NUMBER >= 19970103
  466. ,NULL /* header parser */
  467. #endif
  468. #if MODULE_MAGIC_NUMBER >= 19970719
  469. ,NULL /* child_init */
  470. #endif
  471. #if MODULE_MAGIC_NUMBER >= 19970728
  472. ,NULL /* child_exit */
  473. #endif
  474. #if MODULE_MAGIC_NUMBER >= 19970902
  475. ,NULL /* post read-request */
  476. #endif
  477. };
  478. /*
  479. * Local variables:
  480. * tab-width: 4
  481. * c-basic-offset: 4
  482. * End:
  483. */