Annotation of embedaddon/php/sapi/litespeed/lsapi_main.c, revision 1.1.1.4

1.1       misho       1: /*
                      2:    +----------------------------------------------------------------------+
                      3:    | PHP Version 5                                                        |
                      4:    +----------------------------------------------------------------------+
1.1.1.4 ! misho       5:    | Copyright (c) 1997-2014 The PHP Group                                |
1.1       misho       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: 
1.1.1.2   misho      19: /* $Id$ */
1.1       misho      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);
1.1.1.3   misho     606:     php_printf( "%s", usage );
1.1       misho     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 ZEND_DEBUG
1.1.1.4 ! misho     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());
1.1       misho     723: #else
1.1.1.4 ! misho     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());
1.1       misho     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;
                    803: void litespeed_cleanup(int signal)
                    804: {
                    805:     s_stop = signal;
                    806: }
                    807: 
                    808: 
                    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>
                    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: 
                   1014: static PHP_MINIT_FUNCTION(litespeed)
                   1015: {
                   1016:     /* REGISTER_INI_ENTRIES(); */
                   1017:     return SUCCESS;
                   1018: }
                   1019: 
                   1020: 
                   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: 
                   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 */
                   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 */
                   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: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>