2025-01-26 18:33:45 +01:00

312 lines
9.1 KiB
C

/*
Raydium - CQFD Corp.
http://raydium.org/
License: GPL - GNU General Public License, see "gpl.txt" file.
*/
#ifndef DONT_INCLUDE_HEADERS
#include "index.h"
#else
#include "headers/php.h"
#endif
// PHP support for Raydium
// Known bug: recursive Ray/PHP calls are fatal (segfault in zend core).
#include "php_wrappers.c"
// Dirty globals... (needed for WIN32 PHP support)
#ifdef ZTS
zend_compiler_globals *compiler_globals;
zend_executor_globals *executor_globals;
php_core_globals *core_globals;
sapi_globals_struct *sapi_globals;
void ***tsrm_ls;
#endif
// proto
void raydium_file_ext(char *dest, char *from);
static int sapi_raydium_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC)
{
return SAPI_HEADER_SENT_SUCCESSFULLY;
}
static void sapi_raydium_send_header(sapi_header_struct *sapi_header, void *server_context TSRMLS_DC)
{
}
static int php_dummy(sapi_module_struct *sapi_module)
{
return SUCCESS;
}
void raydium_php_error(int type, const char *msg, ...)
{
raydium_log("^cERROR type %i",type);
}
int raydium_php_uwrite(const char *str, uint str_length TSRMLS_DC)
{
if(str_length>=RAYDIUM_MAX_NAME_LEN-15)
{
raydium_log("PHP output is too long, redirected to stdout");
printf("%s",str);
}
else
raydium_log("%s",str);
return SUCCESS;
}
static sapi_module_struct raydium_sapi_module =
{
"RayHandler", /* name */
"Raydium PHP Handler", /* pretty name */
// Since PHP@Win32 is dirty... :
php_dummy, /* startup */
php_dummy, /* shutdown */
NULL, /* activate */
NULL, /* deactivate */
raydium_php_uwrite, /* unbuffered write */
NULL, /* flush */
NULL, /* get uid */
NULL, /* getenv */
raydium_php_error, /* error handler */
NULL, /* header handler */
sapi_raydium_send_headers, /* send headers handler */
sapi_raydium_send_header, /* send header handler */
NULL, /* read POST data */
NULL, /* read Cookies */
NULL,
NULL, /* register server variables */
NULL, /* Log message */
NULL, /* Block interruptions */
NULL, /* Unblock interruptions */
STANDARD_SAPI_MODULE_PROPERTIES
};
void raydium_php_init_request(char *filename)
{
//Must allocate memory for those 3 ones :
//SG(request_info).request_method = "GET";
//SG(request_info).query_string = "";
//SG(request_info).content_type = "text/html";
SG(request_info).request_method = NULL;
SG(request_info).query_string = NULL;
SG(request_info).content_type = NULL;
SG(request_info).request_uri = filename;
SG(request_info).path_translated = filename;
SG(request_info).content_length = 0;
SG(sapi_headers).http_response_code = 200;
SG(server_context) = NULL;
}
int raydium_php_exec(char *name)
{
FILE *fp;
char suffix[32];
zval *vars[RAYDIUM_MAX_REG_VARIABLES];
zend_file_handle file_handle;
zend_llist global_vars;
int i,nvars;
// Do not use rayphp auto-downloading for *.php files
raydium_file_ext(suffix,name);
if(strcasecmp(suffix,"php"))
{
fp=raydium_file_fopen(name,"rb");
if(!fp)
{
raydium_log("php: ERROR: cannot pre-open '%s' file",name);
return 0;
}
fclose(fp);
}
// PHP_ MAJOR and MINOR _VERSION **seems** to be introduced with PHP 4.3
#ifdef PHP_MAJOR_VERSION
// >= 4.3
if(php_module_startup(&raydium_sapi_module,NULL,0) == FAILURE)
#else
if(php_module_startup(&raydium_sapi_module) == FAILURE)
#endif
{
return FAILURE;
}
raydium_php_init_request(name);
zend_llist_init(&global_vars, sizeof(char *), NULL, 0);
zend_alter_ini_entry("html_errors", 12, "0", 1, PHP_INI_SYSTEM, PHP_INI_STAGE_ACTIVATE);
zend_alter_ini_entry("max_execution_time", 19, "0", 1, PHP_INI_SYSTEM, PHP_INI_STAGE_ACTIVATE);
zend_alter_ini_entry("default_socket_timeout",23,"10",2, PHP_INI_SYSTEM, PHP_INI_STAGE_ACTIVATE);
/*
file_handle.type = ZEND_HANDLE_FILENAME;
file_handle.filename = SG(request_info).path_translated;
file_handle.free_filename = 0;
file_handle.opened_path = NULL;
*/
file_handle.handle.fp=VCWD_FOPEN(name,"rb");
if(!file_handle.handle.fp)
{
raydium_log("php: ERROR: cannot post-open '%s' file",name);
return 0;
}
file_handle.filename=name;
file_handle.type = ZEND_HANDLE_FP;
file_handle.free_filename = 0;
file_handle.opened_path = NULL;
// if(php_request_startup(CLS_C ELS_CC PLS_CC SLS_CC) == FAILURE) {
if(php_request_startup(TSRMLS_C) == FAILURE) {
php_module_shutdown(TSRMLS_C);
return FAILURE;
}
SG(headers_sent) = 1;
SG(request_info).no_headers = 1;
// i save "raydium_register_variable_index" here since it may change during script exec
nvars=raydium_register_variable_index;
for(i=0;i<nvars;i++)
{
if(raydium_register_variable_type[i]==RAYDIUM_REGISTER_INT)
{
MAKE_STD_ZVAL(vars[i]); // init
ZVAL_LONG(vars[i],(*(int *)raydium_register_variable_addr[i]));
ZEND_SET_SYMBOL(&EG(symbol_table), raydium_register_variable_name[i], vars[i]);
}
if(raydium_register_variable_type[i]==RAYDIUM_REGISTER_SCHAR)
{
MAKE_STD_ZVAL(vars[i]); // init
ZVAL_LONG(vars[i],(int)(*(char *)raydium_register_variable_addr[i]));
ZEND_SET_SYMBOL(&EG(symbol_table), raydium_register_variable_name[i], vars[i]);
}
if(raydium_register_variable_type[i]==RAYDIUM_REGISTER_FLOAT)
{
MAKE_STD_ZVAL(vars[i]); // init
ZVAL_DOUBLE(vars[i],(*(float *)raydium_register_variable_addr[i]));
ZEND_SET_SYMBOL(&EG(symbol_table), raydium_register_variable_name[i], vars[i]);
}
if(raydium_register_variable_type[i]==RAYDIUM_REGISTER_STR)
{
MAKE_STD_ZVAL(vars[i]); // init
ZVAL_STRING(vars[i],(char *)raydium_register_variable_addr[i],1); // 1 means "duplicate string"
ZEND_SET_SYMBOL(&EG(symbol_table), raydium_register_variable_name[i], vars[i]);
}
if(raydium_register_variable_type[i]==RAYDIUM_REGISTER_ICONST)
{
zend_register_long_constant(raydium_register_variable_name[i],
strlen(raydium_register_variable_name[i])+1,
(*(int *)raydium_register_variable_addr[i]),
CONST_CS,
0 TSRMLS_CC);
}
if(raydium_register_variable_type[i]==RAYDIUM_REGISTER_FCONST)
{
zend_register_double_constant(raydium_register_variable_name[i],
strlen(raydium_register_variable_name[i])+1,
(*(float *)raydium_register_variable_addr[i]),
CONST_CS,
0 TSRMLS_CC);
}
}
#ifdef WIN32
zend_register_functions(NULL, raydium_register_function_list,CG(function_table), MODULE_PERSISTENT,TSRMLS_C);
php_execute_script(&file_handle,TSRMLS_C);
#else
zend_register_functions(NULL, raydium_register_function_list,CG(function_table), MODULE_PERSISTENT);
php_execute_script(&file_handle CLS_CC ELS_CC PLS_CC);
#endif
// now get back variable values
for(i=0;i<nvars;i++)
{
if(raydium_register_variable_type[i]==RAYDIUM_REGISTER_INT)
{
if(vars[i]->type == IS_LONG)
*(int *)raydium_register_variable_addr[i]=vars[i]->value.lval;
else raydium_log("php: (int)%s type have changed ! Cannot read new value.",raydium_register_variable_name[i]);
}
if(raydium_register_variable_type[i]==RAYDIUM_REGISTER_SCHAR)
{
if(vars[i]->type == IS_LONG)
*(char *)raydium_register_variable_addr[i]=vars[i]->value.lval;
else raydium_log("php: (int)%s type have changed ! Cannot read new value.",raydium_register_variable_name[i]);
}
if(raydium_register_variable_type[i]==RAYDIUM_REGISTER_FLOAT)
{
if(vars[i]->type == IS_DOUBLE)
*(float *)raydium_register_variable_addr[i]=vars[i]->value.dval;
else if(vars[i]->type == IS_LONG)
*(float *)raydium_register_variable_addr[i]=vars[i]->value.lval;
else raydium_log("php: (float)%s type have changed ! Cannot read new value.",raydium_register_variable_name[i]);
}
if(raydium_register_variable_type[i]==RAYDIUM_REGISTER_STR)
{
if(vars[i]->type == IS_STRING)
strcpy(raydium_register_variable_addr[i],vars[i]->value.str.val);
else if(vars[i]->type == IS_DOUBLE)
sprintf(raydium_register_variable_addr[i],"%f",vars[i]->value.dval);
else if(vars[i]->type == IS_LONG)
sprintf(raydium_register_variable_addr[i],"%li",vars[i]->value.lval);
else raydium_log("php: (char *)%s type have changed ! Cannot read new value.",raydium_register_variable_name[i]);
}
}
php_request_shutdown(NULL);
raydium_sapi_module.shutdown(&raydium_sapi_module);
return 1;
}
void raydium_php_close(void)
{
sapi_shutdown();
}
void raydium_php_init(void)
{
char *path;
#ifdef ZTS
tsrm_startup(1, 1, 0, NULL);
compiler_globals = ts_resource(compiler_globals_id);
executor_globals = ts_resource(executor_globals_id);
core_globals = ts_resource(core_globals_id);
sapi_globals = ts_resource(sapi_globals_id);
tsrm_ls = ts_resource(0);
#endif
raydium_sapi_module.phpinfo_as_text=1;
path=malloc(strlen(PHP_INI_PATH));
strcpy(path,PHP_INI_PATH);
raydium_sapi_module.php_ini_path_override=path;
sapi_startup(&raydium_sapi_module);
raydium_atexit(raydium_php_close);
raydium_init_cli_option_default("rayphp",raydium_php_rayphp_path,"rayphp");
raydium_log("PHP support: OK");
}