Index: php.c
===================================================================
--- php.c	(revision 0)
+++ php.c	(revision 1)
@@ -0,0 +1,302 @@
+/*
+    Raydium - CQFD Corp.
+    http://raydium.cqfd-corp.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"
+// use this macro when registering your functions
+#define C2PHP ZEND_FN
+
+
+#ifdef RAYDIUM_NETWORK_ONLY
+#define raydium_file_fopen fopen
+#endif
+
+// 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
+
+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 to 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 prefix[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 rayphp/* files ! :)
+    strncpy(prefix,name,7);
+    prefix[7]=0;
+    if(strcasecmp(prefix,"rayphp/"))
+    {
+	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);
+/*
+    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_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(raydium_register_function_list,CG(function_table), MODULE_PERSISTENT,TSRMLS_C);
+ php_execute_script(&file_handle,TSRMLS_C);
+#else
+ zend_register_functions(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_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);
+atexit(raydium_php_close);
+raydium_log("PHP support: OK");
+}