1 /*
2 +----------------------------------------------------------------------+
3 | PHP Version 5 |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 1997-2013 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$ */
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 */
php_lsapi_startup(sapi_module_struct * sapi_module)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
sapi_lsapi_ini_defaults(HashTable * configuration_hash)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 */
sapi_lsapi_ub_write(const char * str,uint str_length TSRMLS_DC)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 */
sapi_lsapi_flush(void * server_context)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 */
sapi_lsapi_deactivate(TSRMLS_D)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 */
sapi_lsapi_getenv(char * name,size_t name_len TSRMLS_DC)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
add_variable(const char * pKey,int keyLen,const char * pValue,int valLen,void * arg)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)
add_variable_magic_quote(const char * pKey,int keyLen,const char * pValue,int valLen,void * arg)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 */
sapi_lsapi_register_variables(zval * track_vars_array TSRMLS_DC)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 */
sapi_lsapi_read_post(char * buffer,uint count_bytes TSRMLS_DC)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 */
sapi_lsapi_read_cookies(TSRMLS_D)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 */
sapi_lsapi_send_headers(sapi_headers_struct * sapi_headers TSRMLS_DC)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 */
sapi_lsapi_log_message(char * message TSRMLS_DC)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
init_request_info(TSRMLS_D)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
lsapi_chdir_primary_script(zend_file_handle * file_handle)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
lsapi_fopen_primary_script(zend_file_handle * file_handle)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
lsapi_execute_script(zend_file_handle * file_handle TSRMLS_DC)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
lsapi_module_main(int show_source TSRMLS_DC)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
alter_ini(const char * pKey,int keyLen,const char * pValue,int valLen,void * arg)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
override_ini()554 static void override_ini()
555 {
556
557 LSAPI_ForeachSpecialEnv( alter_ini, NULL );
558
559 }
560
processReq(TSRMLS_D)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
cli_usage(TSRMLS_D)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
parse_opt(int argc,char * argv[],int * climode,char ** php_ini_path,char ** php_bind)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
cli_main(int argc,char * argv[])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 ZEND_DEBUG
722 php_printf("PHP %s (%s) (built: %s %s) (DEBUG)\nCopyright (c) 1997-2014 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
723 #else
724 php_printf("PHP %s (%s) (built: %s %s)\nCopyright (c) 1997-2014 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
725 #endif
726 #ifdef PHP_OUTPUT_NEWAPI
727 php_output_end_all(TSRMLS_C);
728 #else
729 php_end_ob_buffers(1 TSRMLS_CC);
730 #endif
731 php_request_shutdown( NULL );
732 }
733 ret = 1;
734 break;
735 case 'c':
736 ++p;
737 /* fall through */
738 case 's':
739 break;
740
741 case 'h':
742 case '?':
743 default:
744 cli_usage(TSRMLS_C);
745 ret = 1;
746 break;
747
748 }
749 }
750 if ( !ret ) {
751 if ( *p ) {
752 zend_file_handle file_handle = {0};
753
754 file_handle.type = ZEND_HANDLE_FP;
755 file_handle.handle.fp = VCWD_FOPEN(*p, "rb");
756
757 if ( file_handle.handle.fp ) {
758 script_filename = *p;
759 php_self = *p;
760
761 SG(request_info).path_translated = estrdup(*p);
762 SG(request_info).argc = argc - (p - argv);
763 SG(request_info).argv = p;
764
765 if (php_request_startup(TSRMLS_C) == FAILURE ) {
766 fclose( file_handle.handle.fp );
767 ret = 2;
768 } else {
769 if (source_highlight) {
770 zend_syntax_highlighter_ini syntax_highlighter_ini;
771
772 php_get_highlight_struct(&syntax_highlighter_ini);
773 highlight_file(SG(request_info).path_translated, &syntax_highlighter_ini TSRMLS_CC);
774 } else {
775 file_handle.filename = *p;
776 file_handle.free_filename = 0;
777 file_handle.opened_path = NULL;
778
779 php_execute_script(&file_handle TSRMLS_CC);
780 }
781
782 php_request_shutdown( NULL );
783 }
784 } else {
785 php_printf("Could not open input file: %s.\n", *p);
786 }
787 } else {
788 cli_usage(TSRMLS_C);
789 }
790 }
791
792 }zend_end_try();
793
794 php_module_shutdown(TSRMLS_C);
795
796 #ifdef ZTS
797 tsrm_shutdown();
798 #endif
799 return ret;
800 }
801
802 static int s_stop;
litespeed_cleanup(int signal)803 void litespeed_cleanup(int signal)
804 {
805 s_stop = signal;
806 }
807
808
start_children(int children)809 void start_children( int children )
810 {
811 struct sigaction act, old_term, old_quit, old_int, old_usr1;
812 int running = 0;
813 int status;
814 pid_t pid;
815
816 /* Create a process group */
817 setsid();
818
819 /* Set up handler to kill children upon exit */
820 act.sa_flags = 0;
821 act.sa_handler = litespeed_cleanup;
822 if( sigaction( SIGTERM, &act, &old_term ) ||
823 sigaction( SIGINT, &act, &old_int ) ||
824 sigaction( SIGUSR1, &act, &old_usr1 ) ||
825 sigaction( SIGQUIT, &act, &old_quit )) {
826 perror( "Can't set signals" );
827 exit( 1 );
828 }
829 s_stop = 0;
830 while( 1 ) {
831 while((!s_stop )&&( running < children )) {
832 pid = fork();
833 switch( pid ) {
834 case 0: /* children process */
835
836 /* don't catch our signals */
837 sigaction( SIGTERM, &old_term, 0 );
838 sigaction( SIGQUIT, &old_quit, 0 );
839 sigaction( SIGINT, &old_int, 0 );
840 sigaction( SIGUSR1, &old_usr1, 0 );
841 return ;
842 case -1:
843 perror( "php (pre-forking)" );
844 exit( 1 );
845 break;
846 default: /* parent process */
847 running++;
848 break;
849 }
850 }
851 if ( s_stop ) {
852 break;
853 }
854 pid = wait( &status );
855 running--;
856 }
857 kill( -getpgrp(), SIGUSR1 );
858 exit( 0 );
859 }
860
861
862
863 #include <fcntl.h>
main(int argc,char * argv[])864 int main( int argc, char * argv[] )
865 {
866 int ret;
867 int bindFd;
868
869 char * php_ini_path = NULL;
870 char * php_bind = NULL;
871 char * p;
872 int n;
873 int climode = 0;
874 struct timeval tv_req_begin;
875 struct timeval tv_req_end;
876 int slow_script_msec = 0;
877 char time_buf[40];
878
879 #ifdef HAVE_SIGNAL_H
880 #if defined(SIGPIPE) && defined(SIG_IGN)
881 signal(SIGPIPE, SIG_IGN);
882 #endif
883 #endif
884
885 #ifdef ZTS
886 tsrm_startup(1, 1, 0, NULL);
887 #endif
888
889 if (argc > 1 ) {
890 if ( parse_opt( argc, argv, &climode,
891 &php_ini_path, &php_bind ) == -1 ) {
892 return 1;
893 }
894 }
895 if ( climode ) {
896 lsapi_sapi_module.phpinfo_as_text = 1;
897 }
898 argv0 = argv[0] + strlen( argv[0] );
899 sapi_startup(&lsapi_sapi_module);
900
901 #ifdef ZTS
902 compiler_globals = ts_resource(compiler_globals_id);
903 executor_globals = ts_resource(executor_globals_id);
904 core_globals = ts_resource(core_globals_id);
905 sapi_globals = ts_resource(sapi_globals_id);
906 tsrm_ls = ts_resource(0);
907
908 SG(request_info).path_translated = NULL;
909 #endif
910
911 lsapi_sapi_module.executable_location = argv[0];
912
913 if ( php_ini_path ) {
914 lsapi_sapi_module.php_ini_path_override = php_ini_path;
915 }
916
917
918 lsapi_sapi_module.ini_defaults = sapi_lsapi_ini_defaults;
919
920 if (php_module_startup(&lsapi_sapi_module, &litespeed_module_entry, 1) == FAILURE) {
921 #ifdef ZTS
922 tsrm_shutdown();
923 #endif
924 return FAILURE;
925 }
926
927 if ( climode ) {
928 return cli_main(argc, argv);
929 }
930
931 if ( php_bind ) {
932 bindFd = LSAPI_CreateListenSock( php_bind, 10 );
933 if ( bindFd == -1 ) {
934 fprintf( stderr,
935 "Failed to bind socket [%s]: %s\n", php_bind, strerror( errno ) );
936 exit( 2 );
937 }
938 if ( bindFd != 0 ) {
939 dup2( bindFd, 0 );
940 close( bindFd );
941 }
942 }
943
944 LSAPI_Init();
945
946 LSAPI_Init_Env_Parameters( NULL );
947
948 slow_script_msec = LSAPI_Get_Slow_Req_Msecs();
949
950 if ( php_bind ) {
951 LSAPI_No_Check_ppid();
952 }
953
954 while( LSAPI_Prefork_Accept_r( &g_req ) >= 0 ) {
955 if ( slow_script_msec ) {
956 gettimeofday( &tv_req_begin, NULL );
957 }
958 ret = processReq(TSRMLS_C);
959 if ( slow_script_msec ) {
960 gettimeofday( &tv_req_end, NULL );
961 n = ((long) tv_req_end.tv_sec - tv_req_begin.tv_sec ) * 1000
962 + (tv_req_end.tv_usec - tv_req_begin.tv_usec) / 1000;
963 if ( n > slow_script_msec )
964 {
965 strftime( time_buf, 30, "%d/%b/%Y:%H:%M:%S", localtime( &tv_req_end.tv_sec ) );
966 fprintf( stderr, "[%s] Slow PHP script: %d ms\n URL: %s %s\n Query String: %s\n Script: %s\n",
967 time_buf, n, LSAPI_GetRequestMethod(),
968 LSAPI_GetScriptName(), LSAPI_GetQueryString(),
969 LSAPI_GetScriptFileName() );
970
971 }
972 }
973 LSAPI_Finish();
974 if ( ret ) {
975 break;
976 }
977 }
978 php_module_shutdown(TSRMLS_C);
979
980 #ifdef ZTS
981 tsrm_shutdown();
982 #endif
983 return ret;
984 }
985
986
987 /* LiteSpeed PHP module starts here */
988
989 #if PHP_MAJOR_VERSION > 4
990
991 /* {{{ arginfo */
992 ZEND_BEGIN_ARG_INFO(arginfo_litespeed__void, 0)
993 ZEND_END_ARG_INFO()
994 /* }}} */
995
996 #else
997 #define arginfo_litespeed__void NULL
998 #endif
999
1000 PHP_FUNCTION(litespeed_request_headers);
1001 PHP_FUNCTION(litespeed_response_headers);
1002
1003 PHP_MINFO_FUNCTION(litespeed);
1004
1005 zend_function_entry litespeed_functions[] = {
1006 PHP_FE(litespeed_request_headers, arginfo_litespeed__void)
1007 PHP_FE(litespeed_response_headers, arginfo_litespeed__void)
1008 PHP_FALIAS(getallheaders, litespeed_request_headers, arginfo_litespeed__void)
1009 PHP_FALIAS(apache_request_headers, litespeed_request_headers, arginfo_litespeed__void)
1010 PHP_FALIAS(apache_response_headers, litespeed_response_headers, arginfo_litespeed__void)
1011 {NULL, NULL, NULL}
1012 };
1013
PHP_MINIT_FUNCTION(litespeed)1014 static PHP_MINIT_FUNCTION(litespeed)
1015 {
1016 /* REGISTER_INI_ENTRIES(); */
1017 return SUCCESS;
1018 }
1019
1020
PHP_MSHUTDOWN_FUNCTION(litespeed)1021 static PHP_MSHUTDOWN_FUNCTION(litespeed)
1022 {
1023 /* UNREGISTER_INI_ENTRIES(); */
1024 return SUCCESS;
1025 }
1026
1027 zend_module_entry litespeed_module_entry = {
1028 STANDARD_MODULE_HEADER,
1029 "litespeed",
1030 litespeed_functions,
1031 PHP_MINIT(litespeed),
1032 PHP_MSHUTDOWN(litespeed),
1033 NULL,
1034 NULL,
1035 NULL,
1036 NO_VERSION_YET,
1037 STANDARD_MODULE_PROPERTIES
1038 };
1039
add_associate_array(const char * pKey,int keyLen,const char * pValue,int valLen,void * arg)1040 static int add_associate_array( const char * pKey, int keyLen, const char * pValue, int valLen,
1041 void * arg )
1042 {
1043 add_assoc_string_ex( (zval *)arg, (char *)pKey, keyLen+1, (char *)pValue, 1 );
1044 return 1;
1045 }
1046
1047
1048 /* {{{ proto array litespeed_request_headers(void)
1049 Fetch all HTTP request headers */
PHP_FUNCTION(litespeed_request_headers)1050 PHP_FUNCTION(litespeed_request_headers)
1051 {
1052 /* TODO: */
1053 if (ZEND_NUM_ARGS() > 0) {
1054 WRONG_PARAM_COUNT;
1055 }
1056 array_init(return_value);
1057
1058 if ( lsapi_mode )
1059 LSAPI_ForeachOrgHeader( add_associate_array, return_value );
1060
1061 }
1062 /* }}} */
1063
1064
1065
1066 /* {{{ proto array litespeed_response_headers(void)
1067 Fetch all HTTP response headers */
PHP_FUNCTION(litespeed_response_headers)1068 PHP_FUNCTION(litespeed_response_headers)
1069 {
1070 sapi_header_struct *h;
1071 zend_llist_position pos;
1072 char * p;
1073 int len;
1074 char headerBuf[SAPI_LSAPI_MAX_HEADER_LENGTH];
1075
1076 if (ZEND_NUM_ARGS() > 0) {
1077 WRONG_PARAM_COUNT;
1078 }
1079
1080 if (!&SG(sapi_headers).headers) {
1081 RETURN_FALSE;
1082 }
1083 array_init(return_value);
1084
1085 h = zend_llist_get_first_ex(&SG(sapi_headers).headers, &pos);
1086 while (h) {
1087 if ( h->header_len > 0 ) {
1088 p = strchr( h->header, ':' );
1089 len = p - h->header;
1090 if (( p )&&( len > 0 )) {
1091 memmove( headerBuf, h->header, len );
1092 while( len > 0 && (isspace( headerBuf[len-1])) ) {
1093 --len;
1094 }
1095 headerBuf[len] = 0;
1096 if ( len ) {
1097 while( isspace(*++p));
1098 add_assoc_string_ex(return_value, headerBuf, len+1, p, 1 );
1099 }
1100 }
1101 }
1102 h = zend_llist_get_next_ex(&SG(sapi_headers).headers, &pos);
1103 }
1104 }
1105
1106 /* }}} */
1107
1108
1109 /*
1110 * Local variables:
1111 * tab-width: 4
1112 * c-basic-offset: 4
1113 * End:
1114 * vim600: sw=4 ts=4 fdm=marker
1115 * vim<600: sw=4 ts=4
1116 */
1117
1118
1119