Back to index

php5  5.3.10
lsapi_main.c
Go to the documentation of this file.
00001 /*
00002    +----------------------------------------------------------------------+
00003    | PHP Version 5                                                        |
00004    +----------------------------------------------------------------------+
00005    | Copyright (c) 1997-2007 The PHP Group                                |
00006    +----------------------------------------------------------------------+
00007    | This source file is subject to version 3.01 of the PHP license,      |
00008    | that is bundled with this package in the file LICENSE, and is        |
00009    | available at through the world-wide-web at the following url:        |
00010    | http://www.php.net/license/3_01.txt.                                 |
00011    | If you did not receive a copy of the PHP license and are unable to   |
00012    | obtain it through the world-wide-web, please send a note to          |
00013    | license@php.net so we can mail you a copy immediately.               |
00014    +----------------------------------------------------------------------+
00015    | Author: George Wang <gwang@litespeedtech.com>                        |
00016    +----------------------------------------------------------------------+
00017 */
00018 
00019 /* $Id: lsapi_main.c 321616 2011-12-31 18:15:06Z gwang $ */
00020 
00021 #include "php.h"
00022 #include "SAPI.h"
00023 #include "php_main.h"
00024 #include "php_ini.h"
00025 #include "php_variables.h"
00026 #include "zend_highlight.h"
00027 #include "zend.h"
00028 
00029 #include "lsapilib.h"
00030 
00031 #include <stdio.h>
00032 
00033 #if HAVE_STDLIB_H
00034 #include <stdlib.h>
00035 #endif
00036 
00037 #if HAVE_UNISTD_H
00038 #include <unistd.h>
00039 #endif
00040 
00041 #ifdef PHP_WIN32
00042 
00043 #include <io.h>
00044 #include <fcntl.h>
00045 #include "win32/php_registry.h"
00046 
00047 #else
00048 
00049 #include <sys/wait.h>
00050 
00051 #endif
00052 
00053 #include <sys/stat.h>
00054 
00055 #if HAVE_SYS_TYPES_H
00056 
00057 #include <sys/types.h>
00058 
00059 #endif
00060 
00061 #if HAVE_SIGNAL_H
00062 
00063 #include <signal.h>
00064 
00065 #endif
00066 
00067 #include <sys/socket.h>
00068 #include <arpa/inet.h>
00069 #include <netinet/in.h>
00070 
00071 
00072 #define SAPI_LSAPI_MAX_HEADER_LENGTH 2048
00073 
00074 static int  lsapi_mode       = 1;
00075 static char *php_self        = "";
00076 static char *script_filename = "";
00077 static int  source_highlight = 0;
00078 static char * argv0 = NULL;
00079 static int  engine = 1;
00080 #ifdef ZTS
00081 zend_compiler_globals    *compiler_globals;
00082 zend_executor_globals    *executor_globals;
00083 php_core_globals         *core_globals;
00084 sapi_globals_struct      *sapi_globals;
00085 void ***tsrm_ls;
00086 #endif
00087 
00088 zend_module_entry litespeed_module_entry;
00089 
00090 /* {{{ php_lsapi_startup
00091  */
00092 static int php_lsapi_startup(sapi_module_struct *sapi_module)
00093 {
00094     if (php_module_startup(sapi_module, NULL, 0)==FAILURE) {
00095         return FAILURE;
00096     }
00097     argv0 = sapi_module->executable_location;
00098     return SUCCESS;
00099 }
00100 /* }}} */
00101 
00102 /* {{{ sapi_lsapi_ini_defaults */
00103 
00104 /* overwriteable ini defaults must be set in sapi_cli_ini_defaults() */
00105 #define INI_DEFAULT(name,value)\
00106     ZVAL_STRING(tmp, value, 0);\
00107     zend_hash_update(configuration_hash, name, sizeof(name), tmp, sizeof(zval), (void**)&entry);\
00108     Z_STRVAL_P(entry) = zend_strndup(Z_STRVAL_P(entry), Z_STRLEN_P(entry))
00109 
00110 static void sapi_lsapi_ini_defaults(HashTable *configuration_hash)
00111 {
00112     zval *tmp, *entry;
00113 
00114 #if PHP_MAJOR_VERSION > 4
00115 /*
00116     MAKE_STD_ZVAL(tmp);
00117 
00118     INI_DEFAULT("register_long_arrays", "0");
00119 
00120     FREE_ZVAL(tmp);
00121 */
00122 #endif
00123 
00124 }
00125 /* }}} */
00126 
00127 
00128 /* {{{ sapi_lsapi_ub_write
00129  */
00130 static int sapi_lsapi_ub_write(const char *str, uint str_length TSRMLS_DC)
00131 {
00132     int ret;
00133     int remain;
00134     if ( lsapi_mode ) {
00135         ret  = LSAPI_Write( str, str_length );
00136         if ( ret < str_length ) {
00137             php_handle_aborted_connection();
00138             return str_length - ret;
00139         }
00140     } else {
00141         remain = str_length;
00142         while( remain > 0 ) {
00143             ret = write( 1, str, remain );
00144             if ( ret <= 0 ) {
00145                 php_handle_aborted_connection();
00146                 return str_length - remain;
00147             }
00148             str += ret;
00149             remain -= ret;
00150         }
00151     }
00152     return str_length;
00153 }
00154 /* }}} */
00155 
00156 
00157 /* {{{ sapi_lsapi_flush
00158  */
00159 static void sapi_lsapi_flush( void * server_context )
00160 {
00161     if ( lsapi_mode ) {
00162         if ( LSAPI_Flush() == -1) {
00163             php_handle_aborted_connection();
00164         }
00165     }
00166 }
00167 /* }}} */
00168 
00169 
00170 /* {{{ sapi_lsapi_deactivate
00171  */
00172 static int sapi_lsapi_deactivate(TSRMLS_D)
00173 {
00174     if ( SG(request_info).path_translated )
00175     {
00176         efree( SG(request_info).path_translated );
00177     }
00178 
00179     return SUCCESS;
00180 }
00181 /* }}} */
00182 
00183 
00184 
00185 
00186 /* {{{ sapi_lsapi_getenv
00187  */
00188 static char *sapi_lsapi_getenv( char * name, size_t name_len TSRMLS_DC )
00189 {
00190     if ( lsapi_mode ) {
00191         return LSAPI_GetEnv( name );
00192     } else {
00193         return getenv( name );
00194     }
00195 }
00196 /* }}} */
00197 
00198 
00199 /*
00200 static int add_variable( const char * pKey, int keyLen, const char * pValue, int valLen,
00201                          void * arg )
00202 {
00203     php_register_variable_safe((char *)pKey, (char *)pValue, valLen, (zval *)arg TSRMLS_CC);
00204     return 1;
00205 }
00206 */
00207 
00208 static int add_variable( const char * pKey, int keyLen, const char * pValue, int valLen,
00209                          void * arg )
00210 {
00211     zval * gpc_element, **gpc_element_p;
00212     HashTable * symtable1 = Z_ARRVAL_P((zval * )arg);
00213     register char * pKey1 = (char *)pKey;
00214 
00215     MAKE_STD_ZVAL(gpc_element);
00216     Z_STRLEN_P( gpc_element ) = valLen;
00217     Z_STRVAL_P( gpc_element ) = estrndup(pValue, valLen);
00218     Z_TYPE_P( gpc_element ) = IS_STRING;
00219 #if PHP_MAJOR_VERSION > 4
00220     zend_symtable_update( symtable1, pKey1, keyLen + 1, &gpc_element, sizeof( zval *), (void **) &gpc_element_p );
00221 #else
00222     zend_hash_update( symtable1, pKey1, keyLen + 1, &gpc_element, sizeof( zval *), (void **) &gpc_element_p );
00223 #endif
00224     return 1;
00225 }
00226 
00227 
00228 #if ((PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION < 4) || PHP_MAJOR_VERSION < 5)
00229 static int add_variable_magic_quote( const char * pKey, int keyLen, const char * pValue, int valLen, 
00230                          void * arg )
00231 {
00232     zval * gpc_element, **gpc_element_p;
00233     HashTable * symtable1 = Z_ARRVAL_P((zval * )arg);
00234     register char * pKey1 = (char *)pKey;
00235 
00236     MAKE_STD_ZVAL(gpc_element);
00237     Z_STRLEN_P( gpc_element ) = valLen;
00238     Z_STRVAL_P( gpc_element ) = php_addslashes((char *)pValue, valLen, &Z_STRLEN_P( gpc_element ), 0 );
00239     Z_TYPE_P( gpc_element ) = IS_STRING;
00240 #if PHP_MAJOR_VERSION > 4
00241     zend_symtable_update( symtable1, pKey1, keyLen + 1, &gpc_element, sizeof( zval *), (void **) &gpc_element_p );
00242 #else
00243     zend_hash_update( symtable1, pKey1, keyLen + 1, &gpc_element, sizeof( zval *), (void **) &gpc_element_p );
00244 #endif
00245     return 1;
00246 }
00247 
00248 #endif
00249 
00250 /* {{{ sapi_lsapi_register_variables
00251  */
00252 static void sapi_lsapi_register_variables(zval *track_vars_array TSRMLS_DC)
00253 {
00254     char * php_self = "";
00255     if ( lsapi_mode ) {
00256         if ( (SG(request_info).request_uri ) )
00257             php_self = (SG(request_info).request_uri );
00258 
00259 #if ((PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION < 4) || PHP_MAJOR_VERSION < 5)
00260         if (!PG(magic_quotes_gpc)) {
00261 #endif
00262             LSAPI_ForeachHeader( add_variable, track_vars_array );
00263             LSAPI_ForeachEnv( add_variable, track_vars_array );
00264             add_variable("PHP_SELF", 8, php_self, strlen( php_self ), track_vars_array );
00265 #if ((PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION < 4) || PHP_MAJOR_VERSION < 5)
00266         } else {
00267             LSAPI_ForeachHeader( add_variable_magic_quote, track_vars_array );
00268             LSAPI_ForeachEnv( add_variable_magic_quote, track_vars_array );
00269             add_variable_magic_quote("PHP_SELF", 8, php_self, strlen( php_self ), track_vars_array );
00270         }
00271 #endif
00272         php_import_environment_variables(track_vars_array TSRMLS_CC);
00273     } else {
00274         php_import_environment_variables(track_vars_array TSRMLS_CC);
00275 
00276         php_register_variable("PHP_SELF", php_self, track_vars_array TSRMLS_CC);
00277         php_register_variable("SCRIPT_NAME", php_self, track_vars_array TSRMLS_CC);
00278         php_register_variable("SCRIPT_FILENAME", script_filename, track_vars_array TSRMLS_CC);
00279         php_register_variable("PATH_TRANSLATED", script_filename, track_vars_array TSRMLS_CC);
00280         php_register_variable("DOCUMENT_ROOT", "", track_vars_array TSRMLS_CC);
00281 
00282     }
00283 }
00284 /* }}} */
00285 
00286 
00287 /* {{{ sapi_lsapi_read_post
00288  */
00289 static int sapi_lsapi_read_post(char *buffer, uint count_bytes TSRMLS_DC)
00290 {
00291     if ( lsapi_mode ) {
00292         return LSAPI_ReadReqBody( buffer, count_bytes );
00293     } else {
00294         return 0;
00295     }
00296 }
00297 /* }}} */
00298 
00299 
00300 
00301 
00302 /* {{{ sapi_lsapi_read_cookies
00303  */
00304 static char *sapi_lsapi_read_cookies(TSRMLS_D)
00305 {
00306     if ( lsapi_mode ) {
00307         return LSAPI_GetHeader( H_COOKIE );
00308     } else {
00309         return NULL;
00310     }
00311 }
00312 /* }}} */
00313 
00314 
00315 /* {{{ sapi_lsapi_send_headers
00316  */
00317 static int sapi_lsapi_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC)
00318 {
00319     sapi_header_struct  *h;
00320     zend_llist_position pos;
00321     if ( lsapi_mode ) {
00322         LSAPI_SetRespStatus( SG(sapi_headers).http_response_code );
00323 
00324         h = zend_llist_get_first_ex(&sapi_headers->headers, &pos);
00325         while (h) {
00326             if ( h->header_len > 0 ) {
00327                 LSAPI_AppendRespHeader(h->header, h->header_len);
00328             }
00329             h = zend_llist_get_next_ex(&sapi_headers->headers, &pos);
00330         }
00331         if (SG(sapi_headers).send_default_content_type) {
00332             char    *hd;
00333             int     len;
00334             char    headerBuf[SAPI_LSAPI_MAX_HEADER_LENGTH];
00335 
00336             hd = sapi_get_default_content_type(TSRMLS_C);
00337             len = snprintf( headerBuf, SAPI_LSAPI_MAX_HEADER_LENGTH - 1,
00338                             "Content-type: %s", hd );
00339             efree(hd);
00340 
00341             LSAPI_AppendRespHeader( headerBuf, len );
00342         }
00343     }
00344     LSAPI_FinalizeRespHeaders();
00345     return SAPI_HEADER_SENT_SUCCESSFULLY;
00346 
00347 
00348 }
00349 /* }}} */
00350 
00351 
00352 /* {{{ sapi_lsapi_send_headers
00353  */
00354 static void sapi_lsapi_log_message(char *message TSRMLS_DC)
00355 {
00356     int len = strlen( message );
00357     LSAPI_Write_Stderr( message, len);
00358 }
00359 /* }}} */
00360 
00361 
00362 /* {{{ sapi_module_struct cgi_sapi_module
00363  */
00364 static sapi_module_struct lsapi_sapi_module =
00365 {
00366     "litespeed",
00367     "LiteSpeed V5.5",
00368 
00369     php_lsapi_startup,              /* startup */
00370     php_module_shutdown_wrapper,    /* shutdown */
00371 
00372     NULL,                           /* activate */
00373     sapi_lsapi_deactivate,          /* deactivate */
00374 
00375     sapi_lsapi_ub_write,            /* unbuffered write */
00376     sapi_lsapi_flush,               /* flush */
00377     NULL,                           /* get uid */
00378     sapi_lsapi_getenv,              /* getenv */
00379 
00380     php_error,                      /* error handler */
00381 
00382     NULL,                           /* header handler */
00383     sapi_lsapi_send_headers,        /* send headers handler */
00384     NULL,                           /* send header handler */
00385 
00386     sapi_lsapi_read_post,           /* read POST data */
00387     sapi_lsapi_read_cookies,        /* read Cookies */
00388 
00389     sapi_lsapi_register_variables,  /* register server variables */
00390     sapi_lsapi_log_message,         /* Log message */
00391 
00392     NULL,                           /* php.ini path override */
00393     NULL,                           /* block interruptions */
00394     NULL,                           /* unblock interruptions */
00395     NULL,                           /* default post reader */
00396     NULL,                           /* treat data */
00397     NULL,                           /* executable location */
00398 
00399     0,                              /* php.ini ignore */
00400 
00401     STANDARD_SAPI_MODULE_PROPERTIES
00402 
00403 };
00404 /* }}} */
00405 
00406 static int init_request_info( TSRMLS_D )
00407 {
00408     char * pContentType = LSAPI_GetHeader( H_CONTENT_TYPE );
00409     char * pAuth;
00410     
00411     SG(request_info).content_type = pContentType ? pContentType : "";
00412     SG(request_info).request_method = LSAPI_GetRequestMethod();
00413     SG(request_info).query_string = LSAPI_GetQueryString();
00414     SG(request_info).request_uri = LSAPI_GetScriptName();
00415     SG(request_info).content_length = LSAPI_GetReqBodyLen();
00416     SG(request_info).path_translated = estrdup( LSAPI_GetScriptFileName());
00417 
00418     /* It is not reset by zend engine, set it to 0. */
00419     SG(sapi_headers).http_response_code = 0;
00420     
00421     pAuth = LSAPI_GetHeader( H_AUTHORIZATION );
00422     php_handle_auth_data(pAuth TSRMLS_CC);
00423 }
00424 
00425 static char s_cur_chdir[4096] = "";
00426 
00427 static int lsapi_chdir_primary_script( zend_file_handle * file_handle )
00428 {
00429 #if PHP_MAJOR_VERSION > 4
00430     char * p;
00431     char ch;
00432 
00433     SG(options) |= SAPI_OPTION_NO_CHDIR;
00434     getcwd( s_cur_chdir, sizeof( s_cur_chdir ) );
00435 
00436     p = strrchr( file_handle->filename, '/' );
00437     if ( *p )
00438     {
00439         *p = 0;
00440         if ( strcmp( file_handle->filename, s_cur_chdir ) != 0 ) {
00441             chdir( file_handle->filename );
00442         }
00443         *p++ = '/';
00444         ch = *p;
00445         *p = 0;
00446         if ( !CWDG(cwd).cwd ||
00447              ( strcmp( file_handle->filename, CWDG(cwd).cwd ) != 0 ) ) {
00448             CWDG(cwd).cwd_length = p - file_handle->filename;
00449             CWDG(cwd).cwd = (char *) realloc(CWDG(cwd).cwd, CWDG(cwd).cwd_length+1);            
00450             memmove( CWDG(cwd).cwd, file_handle->filename, CWDG(cwd).cwd_length+1 );
00451         }
00452         *p = ch;
00453     }
00454     /* virtual_file_ex(&CWDG(cwd), file_handle->filename, NULL, CWD_REALPATH); */
00455 #else
00456     VCWD_CHDIR_FILE( file_handle->filename );
00457 #endif
00458     return 0;
00459 }
00460 
00461 static int lsapi_fopen_primary_script( zend_file_handle * file_handle )
00462 {
00463     FILE * fp;
00464     char * p;
00465     fp = fopen( SG(request_info).path_translated, "rb" );
00466     if ( !fp )
00467     {
00468         return -1;
00469     }
00470     file_handle->type = ZEND_HANDLE_FP;
00471     file_handle->handle.fp = fp;
00472     file_handle->filename = SG(request_info).path_translated;
00473     file_handle->free_filename = 0;
00474     file_handle->opened_path = NULL;
00475 
00476     lsapi_chdir_primary_script( file_handle );
00477 
00478     return 0;
00479 }
00480 
00481 static int lsapi_execute_script( zend_file_handle * file_handle TSRMLS_DC)
00482 {
00483     char *p;
00484     int len;
00485     file_handle->type = ZEND_HANDLE_FILENAME;
00486     file_handle->handle.fd = 0;
00487     file_handle->filename = SG(request_info).path_translated;
00488     file_handle->free_filename = 0;
00489     file_handle->opened_path = NULL;
00490 
00491     p = argv0;
00492     *p++ = ':';
00493     len = strlen( SG(request_info).path_translated );
00494     if ( len > 45 )
00495         len = len - 45;
00496     else
00497         len = 0;
00498     memccpy( p, SG(request_info).path_translated + len, 0, 46 );
00499 
00500     php_execute_script(file_handle TSRMLS_CC);
00501     return 0;
00502 
00503 }
00504 
00505 
00506 static int lsapi_module_main(int show_source TSRMLS_DC)
00507 {
00508     zend_file_handle file_handle = {0};
00509 
00510     if (php_request_startup(TSRMLS_C) == FAILURE ) {
00511         return -1;
00512     }
00513     if (show_source) {
00514         zend_syntax_highlighter_ini syntax_highlighter_ini;
00515 
00516         php_get_highlight_struct(&syntax_highlighter_ini);
00517         highlight_file(SG(request_info).path_translated, &syntax_highlighter_ini TSRMLS_CC);
00518     } else {
00519         lsapi_execute_script( &file_handle TSRMLS_CC);
00520     }
00521     zend_try {
00522         php_request_shutdown(NULL);
00523         *argv0 = 0;
00524     } zend_end_try();
00525     return 0;
00526 }
00527 
00528 
00529 static int alter_ini( const char * pKey, int keyLen, const char * pValue, int valLen,
00530                 void * arg )
00531 {
00532     int type = ZEND_INI_PERDIR;
00533     if ( '\001' == *pKey ) {
00534         ++pKey;
00535         if ( *pKey == 4 ) {
00536             type = ZEND_INI_SYSTEM;
00537         }
00538         ++pKey;
00539         --keyLen;
00540         if (( keyLen == 7 )&&( strncasecmp( pKey, "engine", 6 )== 0 ))
00541         {
00542             if ( *pValue == '0' )
00543                 engine = 0;
00544         }
00545         else
00546             zend_alter_ini_entry((char *)pKey, keyLen,
00547                              (char *)pValue, valLen,
00548                              type, PHP_INI_STAGE_ACTIVATE);
00549     }
00550     return 1;
00551 }
00552 
00553 
00554 static void override_ini()
00555 {
00556 
00557     LSAPI_ForeachSpecialEnv( alter_ini, NULL );
00558 
00559 }
00560 
00561 static int processReq( TSRMLS_D )
00562 {
00563     int ret = 0;
00564     zend_first_try {
00565         /* avoid server_context==NULL checks */
00566         SG(server_context) = (void *) 1;
00567 
00568         engine = 1;
00569         override_ini();
00570 
00571         if ( engine ) {
00572             init_request_info( TSRMLS_C );
00573 
00574             if ( lsapi_module_main( source_highlight TSRMLS_CC ) == -1 ) {
00575                 ret = -1;
00576             }
00577         } else {
00578             LSAPI_AppendRespHeader( "status: 403", 11 );
00579             LSAPI_AppendRespHeader( "content-type: text/html", 23 );
00580             LSAPI_Write( "Forbidden: PHP engine is disable.\n", 34 );
00581         }
00582     } zend_end_try();
00583     return ret;
00584 }
00585 
00586 static void cli_usage( TSRMLS_D )
00587 {
00588     static const char * usage =
00589         "Usage: php\n"
00590         "      php -[b|c|h|i|q|s|v|?] [<file>] [args...]\n"
00591         "  Run in LSAPI mode, only '-b', '-s' and '-c' are effective\n"
00592         "  Run in Command Line Interpreter mode when parameters are specified\n"
00593         "\n"
00594         "  -b <address:port>|<port> Bind Path for external LSAPI Server mode\n"
00595         "  -c <path>|<file> Look for php.ini file in this directory\n"
00596         "  -h    This help\n"
00597         "  -i    PHP information\n"
00598         "  -q    Quiet-mode.  Suppress HTTP Header output.\n"
00599         "  -s    Display colour syntax highlighted source.\n"
00600         "  -v    Version number\n"
00601         "  -?    This help\n"
00602         "\n"
00603         "  args...    Arguments passed to script.\n";
00604     php_output_startup();
00605     php_output_activate(TSRMLS_C);
00606     php_printf( usage );
00607 #ifdef PHP_OUTPUT_NEWAPI
00608     php_output_end_all(TSRMLS_C);
00609 #else
00610     php_end_ob_buffers(1 TSRMLS_CC);
00611 #endif
00612 }
00613 
00614 static int parse_opt( int argc, char * argv[], int *climode,
00615                         char **php_ini_path, char ** php_bind )
00616 {
00617     char ** p = &argv[1];
00618     char ** argend= &argv[argc];
00619     int c;
00620     while (( p < argend )&&(**p == '-' )) {
00621         c = *((*p)+1);
00622         ++p;
00623         switch( c ) {
00624         case 'b':
00625             if ( p >= argend ) {
00626                 fprintf( stderr, "TCP or socket address must be specified following '-b' option.\n");
00627                 return -1;
00628             }
00629             *php_bind = *p++;
00630             break;
00631             
00632         case 'c':
00633             if ( p >= argend ) {
00634                 fprintf( stderr, "<path> or <file> must be specified following '-c' option.\n");
00635 
00636                 return -1;
00637             }
00638             *php_ini_path = *p++;
00639             break;
00640         case 's':
00641             source_highlight = 1;
00642             break;    
00643         case 'h':
00644         case 'i':
00645         case 'q':
00646         case 'v':
00647         case '?':
00648         default:
00649             *climode = 1;
00650             break;
00651         }
00652     }
00653     if ( p - argv < argc ) {
00654         *climode = 1;
00655     }
00656     return 0;
00657 }
00658 
00659 static int cli_main( int argc, char * argv[] )
00660 {
00661 
00662     static const char * ini_defaults[] = {
00663         "report_zend_debug",    "0",
00664         "display_errors",       "1",
00665         "register_argc_argv",   "1",
00666         "html_errors",          "0",
00667         "implicit_flush",       "1",
00668         "output_buffering",     "0",
00669         "max_execution_time",   "0",
00670         "max_input_time",       "-1",
00671         NULL
00672     };
00673 
00674     const char ** ini;
00675     char ** p = &argv[1];
00676     char ** argend= &argv[argc];
00677     int ret = 0;
00678     int c;
00679     lsapi_mode = 0;        /* enter CLI mode */
00680 
00681 #ifdef PHP_WIN32
00682     _fmode = _O_BINARY;            /*sets default for file streams to binary */
00683     setmode(_fileno(stdin), O_BINARY);    /* make the stdio mode be binary */
00684     setmode(_fileno(stdout), O_BINARY);   /* make the stdio mode be binary */
00685     setmode(_fileno(stderr), O_BINARY);   /* make the stdio mode be binary */
00686 #endif
00687 
00688     zend_first_try     {
00689         SG(server_context) = (void *) 1;
00690 
00691         zend_uv.html_errors = 0; /* tell the engine we're in non-html mode */
00692         CG(in_compilation) = 0; /* not initialized but needed for several options */
00693         EG(uninitialized_zval_ptr) = NULL;
00694 
00695         for( ini = ini_defaults; *ini; ini+=2 ) {
00696             zend_alter_ini_entry( (char *)*ini, strlen( *ini )+1,
00697                                 (char *)*(ini+1), strlen( *(ini+1) ),
00698                                 PHP_INI_SYSTEM, PHP_INI_STAGE_ACTIVATE);
00699         }
00700 
00701         while (( p < argend )&&(**p == '-' )) {
00702             c = *((*p)+1);
00703             ++p;
00704             switch( c ) {
00705             case 'q':
00706                 break;
00707             case 'i':
00708                 if (php_request_startup(TSRMLS_C) != FAILURE) {
00709                     php_print_info(0xFFFFFFFF TSRMLS_CC);
00710 #ifdef PHP_OUTPUT_NEWAPI
00711                     php_output_end_all(TSRMLS_C);
00712 #else
00713                     php_end_ob_buffers(1 TSRMLS_CC);
00714 #endif
00715                     php_request_shutdown( NULL );
00716                 }
00717                 ret = 1;
00718                 break;
00719             case 'v':
00720                 if (php_request_startup(TSRMLS_C) != FAILURE) {
00721 #if ZEND_DEBUG
00722                     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());
00723 #else
00724                     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());
00725 #endif
00726 #ifdef PHP_OUTPUT_NEWAPI
00727                     php_output_end_all(TSRMLS_C);
00728 #else
00729                     php_end_ob_buffers(1 TSRMLS_CC);
00730 #endif
00731                     php_request_shutdown( NULL );
00732                 }
00733                 ret = 1;
00734                 break;
00735             case 'c':
00736                 ++p;
00737             /* fall through */
00738             case 's':
00739                 break;
00740                 
00741             case 'h':
00742             case '?':
00743             default:
00744                 cli_usage(TSRMLS_C);
00745                 ret = 1;
00746                 break;
00747 
00748             }
00749         }
00750         if ( !ret ) {
00751             if ( *p ) {
00752                 zend_file_handle file_handle = {0};
00753 
00754                 file_handle.type = ZEND_HANDLE_FP;
00755                 file_handle.handle.fp = VCWD_FOPEN(*p, "rb");
00756 
00757                 if ( file_handle.handle.fp ) {
00758                     script_filename = *p;
00759                     php_self = *p;
00760 
00761                     SG(request_info).path_translated = estrdup(*p);
00762                     SG(request_info).argc = argc - (p - argv);
00763                     SG(request_info).argv = p;
00764 
00765                     if (php_request_startup(TSRMLS_C) == FAILURE ) {
00766                         fclose( file_handle.handle.fp );
00767                         ret = 2;
00768                     } else {
00769                         if (source_highlight) {
00770                             zend_syntax_highlighter_ini syntax_highlighter_ini;
00771                     
00772                             php_get_highlight_struct(&syntax_highlighter_ini);
00773                             highlight_file(SG(request_info).path_translated, &syntax_highlighter_ini TSRMLS_CC);
00774                         } else {
00775                             file_handle.filename = *p;
00776                             file_handle.free_filename = 0;
00777                             file_handle.opened_path = NULL;
00778 
00779                             php_execute_script(&file_handle TSRMLS_CC);
00780                         }
00781 
00782                         php_request_shutdown( NULL );
00783                     }
00784                 } else {
00785                     php_printf("Could not open input file: %s.\n", *p);
00786                 }
00787             } else {
00788                 cli_usage(TSRMLS_C);
00789             }
00790         }
00791 
00792     }zend_end_try();
00793 
00794     php_module_shutdown(TSRMLS_C);
00795 
00796 #ifdef ZTS
00797     tsrm_shutdown();
00798 #endif
00799     return ret;
00800 }
00801 
00802 static int s_stop;
00803 void litespeed_cleanup(int signal)
00804 {
00805     s_stop = signal;
00806 }
00807 
00808 
00809 void start_children( int children )
00810 {
00811     struct sigaction act, old_term, old_quit, old_int, old_usr1;
00812     int running = 0;
00813     int status;
00814     pid_t pid;
00815 
00816     /* Create a process group */
00817     setsid();
00818 
00819     /* Set up handler to kill children upon exit */
00820     act.sa_flags = 0;
00821     act.sa_handler = litespeed_cleanup;
00822     if( sigaction( SIGTERM, &act, &old_term ) ||
00823         sigaction( SIGINT,  &act, &old_int  ) ||
00824         sigaction( SIGUSR1, &act, &old_usr1 ) ||
00825         sigaction( SIGQUIT, &act, &old_quit )) {
00826         perror( "Can't set signals" );
00827         exit( 1 );
00828     }
00829     s_stop = 0;
00830     while( 1 ) {
00831         while((!s_stop )&&( running < children )) {
00832             pid = fork();
00833             switch( pid ) {
00834             case 0: /* children process */
00835 
00836                 /* don't catch our signals */
00837                 sigaction( SIGTERM, &old_term, 0 );
00838                 sigaction( SIGQUIT, &old_quit, 0 );
00839                 sigaction( SIGINT,  &old_int,  0 );
00840                 sigaction( SIGUSR1, &old_usr1, 0 );
00841                 return ;
00842             case -1:
00843                 perror( "php (pre-forking)" );
00844                 exit( 1 );
00845                 break;
00846             default: /* parent process */
00847                 running++;
00848                 break;
00849             }
00850         } 
00851         if ( s_stop ) {
00852             break;
00853         }
00854         pid = wait( &status );
00855         running--;
00856     }
00857     kill( -getpgrp(), SIGUSR1 );
00858     exit( 0 );
00859 }
00860 
00861 
00862 
00863 #include <fcntl.h>
00864 int main( int argc, char * argv[] )
00865 {
00866     int ret;
00867     int bindFd;
00868 
00869     char * php_ini_path = NULL;
00870     char * php_bind     = NULL;
00871     char * p;
00872     int n;
00873     int climode = 0;
00874     struct timeval tv_req_begin;
00875     struct timeval tv_req_end;
00876     int slow_script_msec = 0;
00877     char time_buf[40];
00878     
00879 #ifdef HAVE_SIGNAL_H
00880 #if defined(SIGPIPE) && defined(SIG_IGN)
00881     signal(SIGPIPE, SIG_IGN);
00882 #endif
00883 #endif
00884 
00885 #ifdef ZTS
00886     tsrm_startup(1, 1, 0, NULL);
00887 #endif
00888 
00889     if (argc > 1 ) {
00890         if ( parse_opt( argc, argv, &climode, 
00891                 &php_ini_path, &php_bind ) == -1 ) {
00892             return 1;
00893         }
00894     }
00895     if ( climode ) {
00896         lsapi_sapi_module.phpinfo_as_text = 1;
00897     }
00898     argv0 = argv[0] + strlen( argv[0] );
00899     sapi_startup(&lsapi_sapi_module);
00900 
00901 #ifdef ZTS
00902     compiler_globals = ts_resource(compiler_globals_id);
00903     executor_globals = ts_resource(executor_globals_id);
00904     core_globals = ts_resource(core_globals_id);
00905     sapi_globals = ts_resource(sapi_globals_id);
00906     tsrm_ls = ts_resource(0);
00907 
00908     SG(request_info).path_translated = NULL;
00909 #endif
00910 
00911     lsapi_sapi_module.executable_location = argv[0];
00912 
00913     if ( php_ini_path ) {
00914         lsapi_sapi_module.php_ini_path_override = php_ini_path;
00915     }
00916 
00917 
00918     lsapi_sapi_module.ini_defaults = sapi_lsapi_ini_defaults;
00919 
00920     if (php_module_startup(&lsapi_sapi_module, &litespeed_module_entry, 1) == FAILURE) {
00921 #ifdef ZTS
00922         tsrm_shutdown();
00923 #endif
00924         return FAILURE;
00925     }
00926 
00927     if ( climode ) {
00928         return cli_main(argc, argv);
00929     }
00930 
00931     if ( php_bind ) {
00932         bindFd = LSAPI_CreateListenSock( php_bind, 10 );
00933         if ( bindFd == -1 ) {
00934             fprintf( stderr,
00935                      "Failed to bind socket [%s]: %s\n", php_bind, strerror( errno ) );
00936             exit( 2 );
00937         }
00938         if ( bindFd != 0 ) {
00939             dup2( bindFd, 0 );
00940             close( bindFd );
00941         }
00942     }
00943 
00944     LSAPI_Init();
00945    
00946     LSAPI_Init_Env_Parameters( NULL );
00947 
00948     slow_script_msec = LSAPI_Get_Slow_Req_Msecs();
00949 
00950     if ( php_bind ) {
00951         LSAPI_No_Check_ppid();
00952     }
00953 
00954     while( LSAPI_Prefork_Accept_r( &g_req ) >= 0 ) {
00955         if ( slow_script_msec ) {
00956             gettimeofday( &tv_req_begin, NULL );
00957         }
00958         ret = processReq(TSRMLS_C);
00959         if ( slow_script_msec ) {
00960             gettimeofday( &tv_req_end, NULL );
00961             n = ((long) tv_req_end.tv_sec - tv_req_begin.tv_sec ) * 1000 
00962                 + (tv_req_end.tv_usec - tv_req_begin.tv_usec) / 1000;
00963             if ( n > slow_script_msec )
00964             {
00965                 strftime( time_buf, 30, "%d/%b/%Y:%H:%M:%S", localtime( &tv_req_end.tv_sec ) );
00966                 fprintf( stderr, "[%s] Slow PHP script: %d ms\n  URL: %s %s\n  Query String: %s\n  Script: %s\n",
00967                          time_buf, n,  LSAPI_GetRequestMethod(), 
00968                          LSAPI_GetScriptName(), LSAPI_GetQueryString(),
00969                          LSAPI_GetScriptFileName() );
00970 
00971             }
00972         }
00973         LSAPI_Finish();
00974         if ( ret ) {
00975             break;
00976         }
00977     }
00978     php_module_shutdown(TSRMLS_C);
00979 
00980 #ifdef ZTS
00981     tsrm_shutdown();
00982 #endif
00983     return ret;
00984 }
00985 
00986 
00987 /*   LiteSpeed PHP module starts here */
00988 
00989 #if PHP_MAJOR_VERSION > 4
00990 
00991 /* {{{ arginfo */
00992 ZEND_BEGIN_ARG_INFO(arginfo_litespeed__void, 0)
00993 ZEND_END_ARG_INFO()
00994 /* }}} */
00995 
00996 #else
00997 #define arginfo_litespeed__void NULL
00998 #endif
00999 
01000 PHP_FUNCTION(litespeed_request_headers);
01001 PHP_FUNCTION(litespeed_response_headers);
01002 
01003 PHP_MINFO_FUNCTION(litespeed);
01004 
01005 zend_function_entry litespeed_functions[] = {
01006     PHP_FE(litespeed_request_headers,     arginfo_litespeed__void)
01007     PHP_FE(litespeed_response_headers,     arginfo_litespeed__void)
01008     PHP_FALIAS(getallheaders,             litespeed_request_headers,     arginfo_litespeed__void)
01009     PHP_FALIAS(apache_request_headers,     litespeed_request_headers,     arginfo_litespeed__void)
01010     PHP_FALIAS(apache_response_headers, litespeed_response_headers, arginfo_litespeed__void)
01011     {NULL, NULL, NULL}
01012 };
01013 
01014 static PHP_MINIT_FUNCTION(litespeed)
01015 {
01016     /* REGISTER_INI_ENTRIES(); */
01017     return SUCCESS;
01018 }
01019 
01020 
01021 static PHP_MSHUTDOWN_FUNCTION(litespeed)
01022 {
01023     /* UNREGISTER_INI_ENTRIES(); */
01024     return SUCCESS;
01025 }
01026 
01027 zend_module_entry litespeed_module_entry = {
01028     STANDARD_MODULE_HEADER,
01029     "litespeed",
01030     litespeed_functions,
01031     PHP_MINIT(litespeed),
01032     PHP_MSHUTDOWN(litespeed),
01033     NULL,
01034     NULL,
01035     NULL,
01036     NO_VERSION_YET,
01037     STANDARD_MODULE_PROPERTIES
01038 };
01039 
01040 static int add_associate_array( const char * pKey, int keyLen, const char * pValue, int valLen,
01041                          void * arg )
01042 {
01043     add_assoc_string_ex( (zval *)arg, (char *)pKey, keyLen+1, (char *)pValue, 1 );
01044     return 1;
01045 }
01046 
01047 
01048 /* {{{ proto array litespeed_request_headers(void)
01049    Fetch all HTTP request headers */
01050 PHP_FUNCTION(litespeed_request_headers)
01051 {
01052     /* TODO: */
01053     if (ZEND_NUM_ARGS() > 0) {
01054         WRONG_PARAM_COUNT;
01055     }
01056     array_init(return_value);
01057 
01058     if ( lsapi_mode )
01059         LSAPI_ForeachOrgHeader( add_associate_array, return_value );
01060 
01061 }
01062 /* }}} */
01063 
01064 
01065 
01066 /* {{{ proto array litespeed_response_headers(void)
01067    Fetch all HTTP response headers */
01068 PHP_FUNCTION(litespeed_response_headers)
01069 {
01070     sapi_header_struct  *h;
01071     zend_llist_position pos;
01072     char *       p;
01073     int          len;
01074     char         headerBuf[SAPI_LSAPI_MAX_HEADER_LENGTH];
01075 
01076     if (ZEND_NUM_ARGS() > 0) {
01077         WRONG_PARAM_COUNT;
01078     }
01079 
01080     if (!&SG(sapi_headers).headers) {
01081         RETURN_FALSE;
01082     }
01083     array_init(return_value);
01084 
01085     h = zend_llist_get_first_ex(&SG(sapi_headers).headers, &pos);
01086     while (h) {
01087         if ( h->header_len > 0 ) {
01088             p = strchr( h->header, ':' );
01089             len = p - h->header;
01090             if (( p )&&( len > 0 )) {
01091                 memmove( headerBuf, h->header, len );
01092                 while( len > 0 && (isspace( headerBuf[len-1])) ) {
01093                     --len;
01094                 }
01095                 headerBuf[len] = 0;
01096                 if ( len ) {
01097                     while( isspace(*++p));
01098                     add_assoc_string_ex(return_value, headerBuf, len+1, p, 1 );
01099                 }
01100             }
01101         }
01102         h = zend_llist_get_next_ex(&SG(sapi_headers).headers, &pos);
01103     }  
01104 }
01105 
01106 /* }}} */
01107 
01108 
01109 /*
01110  * Local variables:
01111  * tab-width: 4
01112  * c-basic-offset: 4
01113  * End:
01114  * vim600: sw=4 ts=4 fdm=marker
01115  * vim<600: sw=4 ts=4
01116  */
01117 
01118