Annotation of embedaddon/php/sapi/litespeed/lsapi_main.c, revision 1.1.1.1
1.1 misho 1: /*
2: +----------------------------------------------------------------------+
3: | PHP Version 5 |
4: +----------------------------------------------------------------------+
5: | Copyright (c) 1997-2007 The PHP Group |
6: +----------------------------------------------------------------------+
7: | This source file is subject to version 3.01 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 the following url: |
10: | http://www.php.net/license/3_01.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: George Wang <gwang@litespeedtech.com> |
16: +----------------------------------------------------------------------+
17: */
18:
19: /* $Id: lsapi_main.c 321616 2011-12-31 18:15:06Z gwang $ */
20:
21: #include "php.h"
22: #include "SAPI.h"
23: #include "php_main.h"
24: #include "php_ini.h"
25: #include "php_variables.h"
26: #include "zend_highlight.h"
27: #include "zend.h"
28:
29: #include "lsapilib.h"
30:
31: #include <stdio.h>
32:
33: #if HAVE_STDLIB_H
34: #include <stdlib.h>
35: #endif
36:
37: #if HAVE_UNISTD_H
38: #include <unistd.h>
39: #endif
40:
41: #ifdef PHP_WIN32
42:
43: #include <io.h>
44: #include <fcntl.h>
45: #include "win32/php_registry.h"
46:
47: #else
48:
49: #include <sys/wait.h>
50:
51: #endif
52:
53: #include <sys/stat.h>
54:
55: #if HAVE_SYS_TYPES_H
56:
57: #include <sys/types.h>
58:
59: #endif
60:
61: #if HAVE_SIGNAL_H
62:
63: #include <signal.h>
64:
65: #endif
66:
67: #include <sys/socket.h>
68: #include <arpa/inet.h>
69: #include <netinet/in.h>
70:
71:
72: #define SAPI_LSAPI_MAX_HEADER_LENGTH 2048
73:
74: static int lsapi_mode = 1;
75: static char *php_self = "";
76: static char *script_filename = "";
77: static int source_highlight = 0;
78: static char * argv0 = NULL;
79: static int engine = 1;
80: #ifdef ZTS
81: zend_compiler_globals *compiler_globals;
82: zend_executor_globals *executor_globals;
83: php_core_globals *core_globals;
84: sapi_globals_struct *sapi_globals;
85: void ***tsrm_ls;
86: #endif
87:
88: zend_module_entry litespeed_module_entry;
89:
90: /* {{{ php_lsapi_startup
91: */
92: static int php_lsapi_startup(sapi_module_struct *sapi_module)
93: {
94: if (php_module_startup(sapi_module, NULL, 0)==FAILURE) {
95: return FAILURE;
96: }
97: argv0 = sapi_module->executable_location;
98: return SUCCESS;
99: }
100: /* }}} */
101:
102: /* {{{ sapi_lsapi_ini_defaults */
103:
104: /* overwriteable ini defaults must be set in sapi_cli_ini_defaults() */
105: #define INI_DEFAULT(name,value)\
106: ZVAL_STRING(tmp, value, 0);\
107: zend_hash_update(configuration_hash, name, sizeof(name), tmp, sizeof(zval), (void**)&entry);\
108: Z_STRVAL_P(entry) = zend_strndup(Z_STRVAL_P(entry), Z_STRLEN_P(entry))
109:
110: static void sapi_lsapi_ini_defaults(HashTable *configuration_hash)
111: {
112: zval *tmp, *entry;
113:
114: #if PHP_MAJOR_VERSION > 4
115: /*
116: MAKE_STD_ZVAL(tmp);
117:
118: INI_DEFAULT("register_long_arrays", "0");
119:
120: FREE_ZVAL(tmp);
121: */
122: #endif
123:
124: }
125: /* }}} */
126:
127:
128: /* {{{ sapi_lsapi_ub_write
129: */
130: static int sapi_lsapi_ub_write(const char *str, uint str_length TSRMLS_DC)
131: {
132: int ret;
133: int remain;
134: if ( lsapi_mode ) {
135: ret = LSAPI_Write( str, str_length );
136: if ( ret < str_length ) {
137: php_handle_aborted_connection();
138: return str_length - ret;
139: }
140: } else {
141: remain = str_length;
142: while( remain > 0 ) {
143: ret = write( 1, str, remain );
144: if ( ret <= 0 ) {
145: php_handle_aborted_connection();
146: return str_length - remain;
147: }
148: str += ret;
149: remain -= ret;
150: }
151: }
152: return str_length;
153: }
154: /* }}} */
155:
156:
157: /* {{{ sapi_lsapi_flush
158: */
159: static void sapi_lsapi_flush( void * server_context )
160: {
161: if ( lsapi_mode ) {
162: if ( LSAPI_Flush() == -1) {
163: php_handle_aborted_connection();
164: }
165: }
166: }
167: /* }}} */
168:
169:
170: /* {{{ sapi_lsapi_deactivate
171: */
172: static int sapi_lsapi_deactivate(TSRMLS_D)
173: {
174: if ( SG(request_info).path_translated )
175: {
176: efree( SG(request_info).path_translated );
177: }
178:
179: return SUCCESS;
180: }
181: /* }}} */
182:
183:
184:
185:
186: /* {{{ sapi_lsapi_getenv
187: */
188: static char *sapi_lsapi_getenv( char * name, size_t name_len TSRMLS_DC )
189: {
190: if ( lsapi_mode ) {
191: return LSAPI_GetEnv( name );
192: } else {
193: return getenv( name );
194: }
195: }
196: /* }}} */
197:
198:
199: /*
200: static int add_variable( const char * pKey, int keyLen, const char * pValue, int valLen,
201: void * arg )
202: {
203: php_register_variable_safe((char *)pKey, (char *)pValue, valLen, (zval *)arg TSRMLS_CC);
204: return 1;
205: }
206: */
207:
208: static int add_variable( const char * pKey, int keyLen, const char * pValue, int valLen,
209: void * arg )
210: {
211: zval * gpc_element, **gpc_element_p;
212: HashTable * symtable1 = Z_ARRVAL_P((zval * )arg);
213: register char * pKey1 = (char *)pKey;
214:
215: MAKE_STD_ZVAL(gpc_element);
216: Z_STRLEN_P( gpc_element ) = valLen;
217: Z_STRVAL_P( gpc_element ) = estrndup(pValue, valLen);
218: Z_TYPE_P( gpc_element ) = IS_STRING;
219: #if PHP_MAJOR_VERSION > 4
220: zend_symtable_update( symtable1, pKey1, keyLen + 1, &gpc_element, sizeof( zval *), (void **) &gpc_element_p );
221: #else
222: zend_hash_update( symtable1, pKey1, keyLen + 1, &gpc_element, sizeof( zval *), (void **) &gpc_element_p );
223: #endif
224: return 1;
225: }
226:
227:
228: #if ((PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION < 4) || PHP_MAJOR_VERSION < 5)
229: static int add_variable_magic_quote( const char * pKey, int keyLen, const char * pValue, int valLen,
230: void * arg )
231: {
232: zval * gpc_element, **gpc_element_p;
233: HashTable * symtable1 = Z_ARRVAL_P((zval * )arg);
234: register char * pKey1 = (char *)pKey;
235:
236: MAKE_STD_ZVAL(gpc_element);
237: Z_STRLEN_P( gpc_element ) = valLen;
238: Z_STRVAL_P( gpc_element ) = php_addslashes((char *)pValue, valLen, &Z_STRLEN_P( gpc_element ), 0 );
239: Z_TYPE_P( gpc_element ) = IS_STRING;
240: #if PHP_MAJOR_VERSION > 4
241: zend_symtable_update( symtable1, pKey1, keyLen + 1, &gpc_element, sizeof( zval *), (void **) &gpc_element_p );
242: #else
243: zend_hash_update( symtable1, pKey1, keyLen + 1, &gpc_element, sizeof( zval *), (void **) &gpc_element_p );
244: #endif
245: return 1;
246: }
247:
248: #endif
249:
250: /* {{{ sapi_lsapi_register_variables
251: */
252: static void sapi_lsapi_register_variables(zval *track_vars_array TSRMLS_DC)
253: {
254: char * php_self = "";
255: if ( lsapi_mode ) {
256: if ( (SG(request_info).request_uri ) )
257: php_self = (SG(request_info).request_uri );
258:
259: #if ((PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION < 4) || PHP_MAJOR_VERSION < 5)
260: if (!PG(magic_quotes_gpc)) {
261: #endif
262: LSAPI_ForeachHeader( add_variable, track_vars_array );
263: LSAPI_ForeachEnv( add_variable, track_vars_array );
264: add_variable("PHP_SELF", 8, php_self, strlen( php_self ), track_vars_array );
265: #if ((PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION < 4) || PHP_MAJOR_VERSION < 5)
266: } else {
267: LSAPI_ForeachHeader( add_variable_magic_quote, track_vars_array );
268: LSAPI_ForeachEnv( add_variable_magic_quote, track_vars_array );
269: add_variable_magic_quote("PHP_SELF", 8, php_self, strlen( php_self ), track_vars_array );
270: }
271: #endif
272: php_import_environment_variables(track_vars_array TSRMLS_CC);
273: } else {
274: php_import_environment_variables(track_vars_array TSRMLS_CC);
275:
276: php_register_variable("PHP_SELF", php_self, track_vars_array TSRMLS_CC);
277: php_register_variable("SCRIPT_NAME", php_self, track_vars_array TSRMLS_CC);
278: php_register_variable("SCRIPT_FILENAME", script_filename, track_vars_array TSRMLS_CC);
279: php_register_variable("PATH_TRANSLATED", script_filename, track_vars_array TSRMLS_CC);
280: php_register_variable("DOCUMENT_ROOT", "", track_vars_array TSRMLS_CC);
281:
282: }
283: }
284: /* }}} */
285:
286:
287: /* {{{ sapi_lsapi_read_post
288: */
289: static int sapi_lsapi_read_post(char *buffer, uint count_bytes TSRMLS_DC)
290: {
291: if ( lsapi_mode ) {
292: return LSAPI_ReadReqBody( buffer, count_bytes );
293: } else {
294: return 0;
295: }
296: }
297: /* }}} */
298:
299:
300:
301:
302: /* {{{ sapi_lsapi_read_cookies
303: */
304: static char *sapi_lsapi_read_cookies(TSRMLS_D)
305: {
306: if ( lsapi_mode ) {
307: return LSAPI_GetHeader( H_COOKIE );
308: } else {
309: return NULL;
310: }
311: }
312: /* }}} */
313:
314:
315: /* {{{ sapi_lsapi_send_headers
316: */
317: static int sapi_lsapi_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC)
318: {
319: sapi_header_struct *h;
320: zend_llist_position pos;
321: if ( lsapi_mode ) {
322: LSAPI_SetRespStatus( SG(sapi_headers).http_response_code );
323:
324: h = zend_llist_get_first_ex(&sapi_headers->headers, &pos);
325: while (h) {
326: if ( h->header_len > 0 ) {
327: LSAPI_AppendRespHeader(h->header, h->header_len);
328: }
329: h = zend_llist_get_next_ex(&sapi_headers->headers, &pos);
330: }
331: if (SG(sapi_headers).send_default_content_type) {
332: char *hd;
333: int len;
334: char headerBuf[SAPI_LSAPI_MAX_HEADER_LENGTH];
335:
336: hd = sapi_get_default_content_type(TSRMLS_C);
337: len = snprintf( headerBuf, SAPI_LSAPI_MAX_HEADER_LENGTH - 1,
338: "Content-type: %s", hd );
339: efree(hd);
340:
341: LSAPI_AppendRespHeader( headerBuf, len );
342: }
343: }
344: LSAPI_FinalizeRespHeaders();
345: return SAPI_HEADER_SENT_SUCCESSFULLY;
346:
347:
348: }
349: /* }}} */
350:
351:
352: /* {{{ sapi_lsapi_send_headers
353: */
354: static void sapi_lsapi_log_message(char *message TSRMLS_DC)
355: {
356: int len = strlen( message );
357: LSAPI_Write_Stderr( message, len);
358: }
359: /* }}} */
360:
361:
362: /* {{{ sapi_module_struct cgi_sapi_module
363: */
364: static sapi_module_struct lsapi_sapi_module =
365: {
366: "litespeed",
367: "LiteSpeed V5.5",
368:
369: php_lsapi_startup, /* startup */
370: php_module_shutdown_wrapper, /* shutdown */
371:
372: NULL, /* activate */
373: sapi_lsapi_deactivate, /* deactivate */
374:
375: sapi_lsapi_ub_write, /* unbuffered write */
376: sapi_lsapi_flush, /* flush */
377: NULL, /* get uid */
378: sapi_lsapi_getenv, /* getenv */
379:
380: php_error, /* error handler */
381:
382: NULL, /* header handler */
383: sapi_lsapi_send_headers, /* send headers handler */
384: NULL, /* send header handler */
385:
386: sapi_lsapi_read_post, /* read POST data */
387: sapi_lsapi_read_cookies, /* read Cookies */
388:
389: sapi_lsapi_register_variables, /* register server variables */
390: sapi_lsapi_log_message, /* Log message */
391:
392: NULL, /* php.ini path override */
393: NULL, /* block interruptions */
394: NULL, /* unblock interruptions */
395: NULL, /* default post reader */
396: NULL, /* treat data */
397: NULL, /* executable location */
398:
399: 0, /* php.ini ignore */
400:
401: STANDARD_SAPI_MODULE_PROPERTIES
402:
403: };
404: /* }}} */
405:
406: static int init_request_info( TSRMLS_D )
407: {
408: char * pContentType = LSAPI_GetHeader( H_CONTENT_TYPE );
409: char * pAuth;
410:
411: SG(request_info).content_type = pContentType ? pContentType : "";
412: SG(request_info).request_method = LSAPI_GetRequestMethod();
413: SG(request_info).query_string = LSAPI_GetQueryString();
414: SG(request_info).request_uri = LSAPI_GetScriptName();
415: SG(request_info).content_length = LSAPI_GetReqBodyLen();
416: SG(request_info).path_translated = estrdup( LSAPI_GetScriptFileName());
417:
418: /* It is not reset by zend engine, set it to 0. */
419: SG(sapi_headers).http_response_code = 0;
420:
421: pAuth = LSAPI_GetHeader( H_AUTHORIZATION );
422: php_handle_auth_data(pAuth TSRMLS_CC);
423: }
424:
425: static char s_cur_chdir[4096] = "";
426:
427: static int lsapi_chdir_primary_script( zend_file_handle * file_handle )
428: {
429: #if PHP_MAJOR_VERSION > 4
430: char * p;
431: char ch;
432:
433: SG(options) |= SAPI_OPTION_NO_CHDIR;
434: getcwd( s_cur_chdir, sizeof( s_cur_chdir ) );
435:
436: p = strrchr( file_handle->filename, '/' );
437: if ( *p )
438: {
439: *p = 0;
440: if ( strcmp( file_handle->filename, s_cur_chdir ) != 0 ) {
441: chdir( file_handle->filename );
442: }
443: *p++ = '/';
444: ch = *p;
445: *p = 0;
446: if ( !CWDG(cwd).cwd ||
447: ( strcmp( file_handle->filename, CWDG(cwd).cwd ) != 0 ) ) {
448: CWDG(cwd).cwd_length = p - file_handle->filename;
449: CWDG(cwd).cwd = (char *) realloc(CWDG(cwd).cwd, CWDG(cwd).cwd_length+1);
450: memmove( CWDG(cwd).cwd, file_handle->filename, CWDG(cwd).cwd_length+1 );
451: }
452: *p = ch;
453: }
454: /* virtual_file_ex(&CWDG(cwd), file_handle->filename, NULL, CWD_REALPATH); */
455: #else
456: VCWD_CHDIR_FILE( file_handle->filename );
457: #endif
458: return 0;
459: }
460:
461: static int lsapi_fopen_primary_script( zend_file_handle * file_handle )
462: {
463: FILE * fp;
464: char * p;
465: fp = fopen( SG(request_info).path_translated, "rb" );
466: if ( !fp )
467: {
468: return -1;
469: }
470: file_handle->type = ZEND_HANDLE_FP;
471: file_handle->handle.fp = fp;
472: file_handle->filename = SG(request_info).path_translated;
473: file_handle->free_filename = 0;
474: file_handle->opened_path = NULL;
475:
476: lsapi_chdir_primary_script( file_handle );
477:
478: return 0;
479: }
480:
481: static int lsapi_execute_script( zend_file_handle * file_handle TSRMLS_DC)
482: {
483: char *p;
484: int len;
485: file_handle->type = ZEND_HANDLE_FILENAME;
486: file_handle->handle.fd = 0;
487: file_handle->filename = SG(request_info).path_translated;
488: file_handle->free_filename = 0;
489: file_handle->opened_path = NULL;
490:
491: p = argv0;
492: *p++ = ':';
493: len = strlen( SG(request_info).path_translated );
494: if ( len > 45 )
495: len = len - 45;
496: else
497: len = 0;
498: memccpy( p, SG(request_info).path_translated + len, 0, 46 );
499:
500: php_execute_script(file_handle TSRMLS_CC);
501: return 0;
502:
503: }
504:
505:
506: static int lsapi_module_main(int show_source TSRMLS_DC)
507: {
508: zend_file_handle file_handle = {0};
509:
510: if (php_request_startup(TSRMLS_C) == FAILURE ) {
511: return -1;
512: }
513: if (show_source) {
514: zend_syntax_highlighter_ini syntax_highlighter_ini;
515:
516: php_get_highlight_struct(&syntax_highlighter_ini);
517: highlight_file(SG(request_info).path_translated, &syntax_highlighter_ini TSRMLS_CC);
518: } else {
519: lsapi_execute_script( &file_handle TSRMLS_CC);
520: }
521: zend_try {
522: php_request_shutdown(NULL);
523: *argv0 = 0;
524: } zend_end_try();
525: return 0;
526: }
527:
528:
529: static int alter_ini( const char * pKey, int keyLen, const char * pValue, int valLen,
530: void * arg )
531: {
532: int type = ZEND_INI_PERDIR;
533: if ( '\001' == *pKey ) {
534: ++pKey;
535: if ( *pKey == 4 ) {
536: type = ZEND_INI_SYSTEM;
537: }
538: ++pKey;
539: --keyLen;
540: if (( keyLen == 7 )&&( strncasecmp( pKey, "engine", 6 )== 0 ))
541: {
542: if ( *pValue == '0' )
543: engine = 0;
544: }
545: else
546: zend_alter_ini_entry((char *)pKey, keyLen,
547: (char *)pValue, valLen,
548: type, PHP_INI_STAGE_ACTIVATE);
549: }
550: return 1;
551: }
552:
553:
554: static void override_ini()
555: {
556:
557: LSAPI_ForeachSpecialEnv( alter_ini, NULL );
558:
559: }
560:
561: static int processReq( TSRMLS_D )
562: {
563: int ret = 0;
564: zend_first_try {
565: /* avoid server_context==NULL checks */
566: SG(server_context) = (void *) 1;
567:
568: engine = 1;
569: override_ini();
570:
571: if ( engine ) {
572: init_request_info( TSRMLS_C );
573:
574: if ( lsapi_module_main( source_highlight TSRMLS_CC ) == -1 ) {
575: ret = -1;
576: }
577: } else {
578: LSAPI_AppendRespHeader( "status: 403", 11 );
579: LSAPI_AppendRespHeader( "content-type: text/html", 23 );
580: LSAPI_Write( "Forbidden: PHP engine is disable.\n", 34 );
581: }
582: } zend_end_try();
583: return ret;
584: }
585:
586: static void cli_usage( TSRMLS_D )
587: {
588: static const char * usage =
589: "Usage: php\n"
590: " php -[b|c|h|i|q|s|v|?] [<file>] [args...]\n"
591: " Run in LSAPI mode, only '-b', '-s' and '-c' are effective\n"
592: " Run in Command Line Interpreter mode when parameters are specified\n"
593: "\n"
594: " -b <address:port>|<port> Bind Path for external LSAPI Server mode\n"
595: " -c <path>|<file> Look for php.ini file in this directory\n"
596: " -h This help\n"
597: " -i PHP information\n"
598: " -q Quiet-mode. Suppress HTTP Header output.\n"
599: " -s Display colour syntax highlighted source.\n"
600: " -v Version number\n"
601: " -? This help\n"
602: "\n"
603: " args... Arguments passed to script.\n";
604: php_output_startup();
605: php_output_activate(TSRMLS_C);
606: php_printf( usage );
607: #ifdef PHP_OUTPUT_NEWAPI
608: php_output_end_all(TSRMLS_C);
609: #else
610: php_end_ob_buffers(1 TSRMLS_CC);
611: #endif
612: }
613:
614: static int parse_opt( int argc, char * argv[], int *climode,
615: char **php_ini_path, char ** php_bind )
616: {
617: char ** p = &argv[1];
618: char ** argend= &argv[argc];
619: int c;
620: while (( p < argend )&&(**p == '-' )) {
621: c = *((*p)+1);
622: ++p;
623: switch( c ) {
624: case 'b':
625: if ( p >= argend ) {
626: fprintf( stderr, "TCP or socket address must be specified following '-b' option.\n");
627: return -1;
628: }
629: *php_bind = *p++;
630: break;
631:
632: case 'c':
633: if ( p >= argend ) {
634: fprintf( stderr, "<path> or <file> must be specified following '-c' option.\n");
635:
636: return -1;
637: }
638: *php_ini_path = *p++;
639: break;
640: case 's':
641: source_highlight = 1;
642: break;
643: case 'h':
644: case 'i':
645: case 'q':
646: case 'v':
647: case '?':
648: default:
649: *climode = 1;
650: break;
651: }
652: }
653: if ( p - argv < argc ) {
654: *climode = 1;
655: }
656: return 0;
657: }
658:
659: static int cli_main( int argc, char * argv[] )
660: {
661:
662: static const char * ini_defaults[] = {
663: "report_zend_debug", "0",
664: "display_errors", "1",
665: "register_argc_argv", "1",
666: "html_errors", "0",
667: "implicit_flush", "1",
668: "output_buffering", "0",
669: "max_execution_time", "0",
670: "max_input_time", "-1",
671: NULL
672: };
673:
674: const char ** ini;
675: char ** p = &argv[1];
676: char ** argend= &argv[argc];
677: int ret = 0;
678: int c;
679: lsapi_mode = 0; /* enter CLI mode */
680:
681: #ifdef PHP_WIN32
682: _fmode = _O_BINARY; /*sets default for file streams to binary */
683: setmode(_fileno(stdin), O_BINARY); /* make the stdio mode be binary */
684: setmode(_fileno(stdout), O_BINARY); /* make the stdio mode be binary */
685: setmode(_fileno(stderr), O_BINARY); /* make the stdio mode be binary */
686: #endif
687:
688: zend_first_try {
689: SG(server_context) = (void *) 1;
690:
691: zend_uv.html_errors = 0; /* tell the engine we're in non-html mode */
692: CG(in_compilation) = 0; /* not initialized but needed for several options */
693: EG(uninitialized_zval_ptr) = NULL;
694:
695: for( ini = ini_defaults; *ini; ini+=2 ) {
696: zend_alter_ini_entry( (char *)*ini, strlen( *ini )+1,
697: (char *)*(ini+1), strlen( *(ini+1) ),
698: PHP_INI_SYSTEM, PHP_INI_STAGE_ACTIVATE);
699: }
700:
701: while (( p < argend )&&(**p == '-' )) {
702: c = *((*p)+1);
703: ++p;
704: switch( c ) {
705: case 'q':
706: break;
707: case 'i':
708: if (php_request_startup(TSRMLS_C) != FAILURE) {
709: php_print_info(0xFFFFFFFF TSRMLS_CC);
710: #ifdef PHP_OUTPUT_NEWAPI
711: php_output_end_all(TSRMLS_C);
712: #else
713: php_end_ob_buffers(1 TSRMLS_CC);
714: #endif
715: php_request_shutdown( NULL );
716: }
717: ret = 1;
718: break;
719: case 'v':
720: if (php_request_startup(TSRMLS_C) != FAILURE) {
721: #if SUHOSIN_PATCH
722: #if ZEND_DEBUG
723: php_printf("PHP %s with Suhosin-Patch (%s) (built: %s %s) (DEBUG)\nCopyright (c) 1997-2011 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
724: #else
725: php_printf("PHP %s with Suhosin-Patch (%s) (built: %s %s)\nCopyright (c) 1997-2011 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
726: #endif
727: #else
728: #if ZEND_DEBUG
729: php_printf("PHP %s (%s) (built: %s %s) (DEBUG)\nCopyright (c) 1997-2004 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
730: #else
731: php_printf("PHP %s (%s) (built: %s %s)\nCopyright (c) 1997-2004 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
732: #endif
733: #endif
734: #ifdef PHP_OUTPUT_NEWAPI
735: php_output_end_all(TSRMLS_C);
736: #else
737: php_end_ob_buffers(1 TSRMLS_CC);
738: #endif
739: php_request_shutdown( NULL );
740: }
741: ret = 1;
742: break;
743: case 'c':
744: ++p;
745: /* fall through */
746: case 's':
747: break;
748:
749: case 'h':
750: case '?':
751: default:
752: cli_usage(TSRMLS_C);
753: ret = 1;
754: break;
755:
756: }
757: }
758: if ( !ret ) {
759: if ( *p ) {
760: zend_file_handle file_handle = {0};
761:
762: file_handle.type = ZEND_HANDLE_FP;
763: file_handle.handle.fp = VCWD_FOPEN(*p, "rb");
764:
765: if ( file_handle.handle.fp ) {
766: script_filename = *p;
767: php_self = *p;
768:
769: SG(request_info).path_translated = estrdup(*p);
770: SG(request_info).argc = argc - (p - argv);
771: SG(request_info).argv = p;
772:
773: if (php_request_startup(TSRMLS_C) == FAILURE ) {
774: fclose( file_handle.handle.fp );
775: ret = 2;
776: } else {
777: if (source_highlight) {
778: zend_syntax_highlighter_ini syntax_highlighter_ini;
779:
780: php_get_highlight_struct(&syntax_highlighter_ini);
781: highlight_file(SG(request_info).path_translated, &syntax_highlighter_ini TSRMLS_CC);
782: } else {
783: file_handle.filename = *p;
784: file_handle.free_filename = 0;
785: file_handle.opened_path = NULL;
786:
787: php_execute_script(&file_handle TSRMLS_CC);
788: }
789:
790: php_request_shutdown( NULL );
791: }
792: } else {
793: php_printf("Could not open input file: %s.\n", *p);
794: }
795: } else {
796: cli_usage(TSRMLS_C);
797: }
798: }
799:
800: }zend_end_try();
801:
802: php_module_shutdown(TSRMLS_C);
803:
804: #ifdef ZTS
805: tsrm_shutdown();
806: #endif
807: return ret;
808: }
809:
810: static int s_stop;
811: void litespeed_cleanup(int signal)
812: {
813: s_stop = signal;
814: }
815:
816:
817: void start_children( int children )
818: {
819: struct sigaction act, old_term, old_quit, old_int, old_usr1;
820: int running = 0;
821: int status;
822: pid_t pid;
823:
824: /* Create a process group */
825: setsid();
826:
827: /* Set up handler to kill children upon exit */
828: act.sa_flags = 0;
829: act.sa_handler = litespeed_cleanup;
830: if( sigaction( SIGTERM, &act, &old_term ) ||
831: sigaction( SIGINT, &act, &old_int ) ||
832: sigaction( SIGUSR1, &act, &old_usr1 ) ||
833: sigaction( SIGQUIT, &act, &old_quit )) {
834: perror( "Can't set signals" );
835: exit( 1 );
836: }
837: s_stop = 0;
838: while( 1 ) {
839: while((!s_stop )&&( running < children )) {
840: pid = fork();
841: switch( pid ) {
842: case 0: /* children process */
843:
844: /* don't catch our signals */
845: sigaction( SIGTERM, &old_term, 0 );
846: sigaction( SIGQUIT, &old_quit, 0 );
847: sigaction( SIGINT, &old_int, 0 );
848: sigaction( SIGUSR1, &old_usr1, 0 );
849: return ;
850: case -1:
851: perror( "php (pre-forking)" );
852: exit( 1 );
853: break;
854: default: /* parent process */
855: running++;
856: break;
857: }
858: }
859: if ( s_stop ) {
860: break;
861: }
862: pid = wait( &status );
863: running--;
864: }
865: kill( -getpgrp(), SIGUSR1 );
866: exit( 0 );
867: }
868:
869:
870:
871: #include <fcntl.h>
872: int main( int argc, char * argv[] )
873: {
874: int ret;
875: int bindFd;
876:
877: char * php_ini_path = NULL;
878: char * php_bind = NULL;
879: char * p;
880: int n;
881: int climode = 0;
882: struct timeval tv_req_begin;
883: struct timeval tv_req_end;
884: int slow_script_msec = 0;
885: char time_buf[40];
886:
887: #ifdef HAVE_SIGNAL_H
888: #if defined(SIGPIPE) && defined(SIG_IGN)
889: signal(SIGPIPE, SIG_IGN);
890: #endif
891: #endif
892:
893: #ifdef ZTS
894: tsrm_startup(1, 1, 0, NULL);
895: #endif
896:
897: if (argc > 1 ) {
898: if ( parse_opt( argc, argv, &climode,
899: &php_ini_path, &php_bind ) == -1 ) {
900: return 1;
901: }
902: }
903: if ( climode ) {
904: lsapi_sapi_module.phpinfo_as_text = 1;
905: }
906: argv0 = argv[0] + strlen( argv[0] );
907: sapi_startup(&lsapi_sapi_module);
908:
909: #ifdef ZTS
910: compiler_globals = ts_resource(compiler_globals_id);
911: executor_globals = ts_resource(executor_globals_id);
912: core_globals = ts_resource(core_globals_id);
913: sapi_globals = ts_resource(sapi_globals_id);
914: tsrm_ls = ts_resource(0);
915:
916: SG(request_info).path_translated = NULL;
917: #endif
918:
919: lsapi_sapi_module.executable_location = argv[0];
920:
921: if ( php_ini_path ) {
922: lsapi_sapi_module.php_ini_path_override = php_ini_path;
923: }
924:
925:
926: lsapi_sapi_module.ini_defaults = sapi_lsapi_ini_defaults;
927:
928: if (php_module_startup(&lsapi_sapi_module, &litespeed_module_entry, 1) == FAILURE) {
929: #ifdef ZTS
930: tsrm_shutdown();
931: #endif
932: return FAILURE;
933: }
934:
935: if ( climode ) {
936: return cli_main(argc, argv);
937: }
938:
939: if ( php_bind ) {
940: bindFd = LSAPI_CreateListenSock( php_bind, 10 );
941: if ( bindFd == -1 ) {
942: fprintf( stderr,
943: "Failed to bind socket [%s]: %s\n", php_bind, strerror( errno ) );
944: exit( 2 );
945: }
946: if ( bindFd != 0 ) {
947: dup2( bindFd, 0 );
948: close( bindFd );
949: }
950: }
951:
952: LSAPI_Init();
953:
954: LSAPI_Init_Env_Parameters( NULL );
955:
956: slow_script_msec = LSAPI_Get_Slow_Req_Msecs();
957:
958: if ( php_bind ) {
959: LSAPI_No_Check_ppid();
960: }
961:
962: while( LSAPI_Prefork_Accept_r( &g_req ) >= 0 ) {
963: if ( slow_script_msec ) {
964: gettimeofday( &tv_req_begin, NULL );
965: }
966: ret = processReq(TSRMLS_C);
967: if ( slow_script_msec ) {
968: gettimeofday( &tv_req_end, NULL );
969: n = ((long) tv_req_end.tv_sec - tv_req_begin.tv_sec ) * 1000
970: + (tv_req_end.tv_usec - tv_req_begin.tv_usec) / 1000;
971: if ( n > slow_script_msec )
972: {
973: strftime( time_buf, 30, "%d/%b/%Y:%H:%M:%S", localtime( &tv_req_end.tv_sec ) );
974: fprintf( stderr, "[%s] Slow PHP script: %d ms\n URL: %s %s\n Query String: %s\n Script: %s\n",
975: time_buf, n, LSAPI_GetRequestMethod(),
976: LSAPI_GetScriptName(), LSAPI_GetQueryString(),
977: LSAPI_GetScriptFileName() );
978:
979: }
980: }
981: LSAPI_Finish();
982: if ( ret ) {
983: break;
984: }
985: }
986: php_module_shutdown(TSRMLS_C);
987:
988: #ifdef ZTS
989: tsrm_shutdown();
990: #endif
991: return ret;
992: }
993:
994:
995: /* LiteSpeed PHP module starts here */
996:
997: #if PHP_MAJOR_VERSION > 4
998:
999: /* {{{ arginfo */
1000: ZEND_BEGIN_ARG_INFO(arginfo_litespeed__void, 0)
1001: ZEND_END_ARG_INFO()
1002: /* }}} */
1003:
1004: #else
1005: #define arginfo_litespeed__void NULL
1006: #endif
1007:
1008: PHP_FUNCTION(litespeed_request_headers);
1009: PHP_FUNCTION(litespeed_response_headers);
1010:
1011: PHP_MINFO_FUNCTION(litespeed);
1012:
1013: zend_function_entry litespeed_functions[] = {
1014: PHP_FE(litespeed_request_headers, arginfo_litespeed__void)
1015: PHP_FE(litespeed_response_headers, arginfo_litespeed__void)
1016: PHP_FALIAS(getallheaders, litespeed_request_headers, arginfo_litespeed__void)
1017: PHP_FALIAS(apache_request_headers, litespeed_request_headers, arginfo_litespeed__void)
1018: PHP_FALIAS(apache_response_headers, litespeed_response_headers, arginfo_litespeed__void)
1019: {NULL, NULL, NULL}
1020: };
1021:
1022: static PHP_MINIT_FUNCTION(litespeed)
1023: {
1024: /* REGISTER_INI_ENTRIES(); */
1025: return SUCCESS;
1026: }
1027:
1028:
1029: static PHP_MSHUTDOWN_FUNCTION(litespeed)
1030: {
1031: /* UNREGISTER_INI_ENTRIES(); */
1032: return SUCCESS;
1033: }
1034:
1035: zend_module_entry litespeed_module_entry = {
1036: STANDARD_MODULE_HEADER,
1037: "litespeed",
1038: litespeed_functions,
1039: PHP_MINIT(litespeed),
1040: PHP_MSHUTDOWN(litespeed),
1041: NULL,
1042: NULL,
1043: NULL,
1044: NO_VERSION_YET,
1045: STANDARD_MODULE_PROPERTIES
1046: };
1047:
1048: static int add_associate_array( const char * pKey, int keyLen, const char * pValue, int valLen,
1049: void * arg )
1050: {
1051: add_assoc_string_ex( (zval *)arg, (char *)pKey, keyLen+1, (char *)pValue, 1 );
1052: return 1;
1053: }
1054:
1055:
1056: /* {{{ proto array litespeed_request_headers(void)
1057: Fetch all HTTP request headers */
1058: PHP_FUNCTION(litespeed_request_headers)
1059: {
1060: /* TODO: */
1061: if (ZEND_NUM_ARGS() > 0) {
1062: WRONG_PARAM_COUNT;
1063: }
1064: array_init(return_value);
1065:
1066: if ( lsapi_mode )
1067: LSAPI_ForeachOrgHeader( add_associate_array, return_value );
1068:
1069: }
1070: /* }}} */
1071:
1072:
1073:
1074: /* {{{ proto array litespeed_response_headers(void)
1075: Fetch all HTTP response headers */
1076: PHP_FUNCTION(litespeed_response_headers)
1077: {
1078: sapi_header_struct *h;
1079: zend_llist_position pos;
1080: char * p;
1081: int len;
1082: char headerBuf[SAPI_LSAPI_MAX_HEADER_LENGTH];
1083:
1084: if (ZEND_NUM_ARGS() > 0) {
1085: WRONG_PARAM_COUNT;
1086: }
1087:
1088: if (!&SG(sapi_headers).headers) {
1089: RETURN_FALSE;
1090: }
1091: array_init(return_value);
1092:
1093: h = zend_llist_get_first_ex(&SG(sapi_headers).headers, &pos);
1094: while (h) {
1095: if ( h->header_len > 0 ) {
1096: p = strchr( h->header, ':' );
1097: len = p - h->header;
1098: if (( p )&&( len > 0 )) {
1099: memmove( headerBuf, h->header, len );
1100: while( len > 0 && (isspace( headerBuf[len-1])) ) {
1101: --len;
1102: }
1103: headerBuf[len] = 0;
1104: if ( len ) {
1105: while( isspace(*++p));
1106: add_assoc_string_ex(return_value, headerBuf, len+1, p, 1 );
1107: }
1108: }
1109: }
1110: h = zend_llist_get_next_ex(&SG(sapi_headers).headers, &pos);
1111: }
1112: }
1113:
1114: /* }}} */
1115:
1116:
1117: /*
1118: * Local variables:
1119: * tab-width: 4
1120: * c-basic-offset: 4
1121: * End:
1122: * vim600: sw=4 ts=4 fdm=marker
1123: * vim<600: sw=4 ts=4
1124: */
1125:
1126:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>