mirror of
https://github.com/php/php-src.git
synced 2024-12-12 03:15:29 +08:00
2190 lines
58 KiB
C
2190 lines
58 KiB
C
/*
|
|
+----------------------------------------------------------------------+
|
|
| PHP HTML Embedded Scripting Language Version 3.0 |
|
|
+----------------------------------------------------------------------+
|
|
| Copyright (c) 1997,1998 PHP Development Team (See Credits file) |
|
|
+----------------------------------------------------------------------+
|
|
| This program is free software; you can redistribute it and/or modify |
|
|
| it under the terms of one of the following licenses: |
|
|
| |
|
|
| A) the GNU General Public License as published by the Free Software |
|
|
| Foundation; either version 2 of the License, or (at your option) |
|
|
| any later version. |
|
|
| |
|
|
| B) the PHP License as published by the PHP Development Team and |
|
|
| included in the distribution in the file: LICENSE |
|
|
| |
|
|
| This program is distributed in the hope that it will be useful, |
|
|
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
|
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
|
| GNU General Public License for more details. |
|
|
| |
|
|
| You should have received a copy of both licenses referred to here. |
|
|
| If you did not, or have any questions about PHP licensing, please |
|
|
| contact core@php.net. |
|
|
+----------------------------------------------------------------------+
|
|
| Authors: Andi Gutmans <andi@zend.com> |
|
|
| Zeev Suraski <zeev@zend.com> |
|
|
| Rasmus Lerdorf <rasmus@lerdorf.on.ca> |
|
|
+----------------------------------------------------------------------+
|
|
*/
|
|
|
|
/* $Id$ */
|
|
|
|
/* #define CRASH_DETECTION */
|
|
|
|
#define SHUTDOWN_DEBUG(resource) fprintf(stderr, "*** Shutting down " resource "\n" )
|
|
#undef SHUTDOWN_DEBUG
|
|
#define SHUTDOWN_DEBUG(resource)
|
|
|
|
#ifdef THREAD_SAFE
|
|
#include "tls.h"
|
|
#endif
|
|
#include <stdio.h>
|
|
#include "php.h"
|
|
#ifdef MSVC5
|
|
#include "win32/time.h"
|
|
#include "win32/signal.h"
|
|
#include <process.h>
|
|
#else
|
|
#include "build-defs.h"
|
|
#endif
|
|
#if HAVE_SYS_TIME_H
|
|
#include <sys/time.h>
|
|
#endif
|
|
#if HAVE_UNISTD_H
|
|
#include <unistd.h>
|
|
#endif
|
|
#if HAVE_SIGNAL_H
|
|
#include <signal.h>
|
|
#endif
|
|
#if HAVE_SETLOCALE
|
|
#include <locale.h>
|
|
#endif
|
|
#include "zend.h"
|
|
#include "php_ini.h"
|
|
#include "php_globals.h"
|
|
#include "main.h"
|
|
#include "control_structures.h"
|
|
#include "fopen-wrappers.h"
|
|
#include "functions/basic_functions.h"
|
|
#include "functions/info.h"
|
|
#include "functions/head.h"
|
|
#include "functions/post.h"
|
|
#include "functions/head.h"
|
|
#include "functions/type.h"
|
|
#include "snprintf.h"
|
|
#if WIN32|WINNT
|
|
#include <io.h>
|
|
#include <fcntl.h>
|
|
#include "win32/syslog.h"
|
|
#else
|
|
#include <syslog.h>
|
|
#endif
|
|
|
|
#include "zend_compile.h"
|
|
#include "zend_execute.h"
|
|
#include "zend_highlight.h"
|
|
#include "zend_indent.h"
|
|
|
|
#if USE_SAPI
|
|
#include "serverapi/sapi.h"
|
|
void *gLock;
|
|
#ifndef THREAD_SAFE
|
|
struct sapi_request_info *sapi_rqst;
|
|
#endif
|
|
#endif
|
|
|
|
#if MSVC5 || !defined(HAVE_GETOPT)
|
|
#include "getopt.h"
|
|
#endif
|
|
|
|
|
|
#ifdef ZTS
|
|
int compiler_globals_id;
|
|
int executor_globals_id;
|
|
#endif
|
|
|
|
#ifndef ZTS
|
|
php_core_globals core_globals;
|
|
#endif
|
|
|
|
void *gLock; /*mutex variable */
|
|
|
|
|
|
#define PHP_MODE_STANDARD 1
|
|
#define PHP_MODE_HIGHLIGHT 2
|
|
#define PHP_MODE_INDENT 3
|
|
|
|
/* True globals (no need for thread safety) */
|
|
HashTable configuration_hash;
|
|
char *php3_ini_path = NULL;
|
|
|
|
PHP_INI_MH(OnSetPrecision)
|
|
{
|
|
ELS_FETCH();
|
|
|
|
EG(precision) = atoi(new_value);
|
|
return SUCCESS;
|
|
}
|
|
|
|
|
|
/* Need to convert to strings and make use of:
|
|
* DEFAULT_SHORT_OPEN_TAG
|
|
* PHP_SAFE_MODE
|
|
*
|
|
* Need to be read from the environment (?):
|
|
* PHP_AUTO_PREPEND_FILE
|
|
* PHP_AUTO_APPEND_FILE
|
|
*/
|
|
|
|
#ifndef SAFE_MODE_EXEC_DIR
|
|
# define SAFE_MODE_EXEC_DIR "/"
|
|
#endif
|
|
|
|
#ifdef PHP_PROG_SENDMAIL
|
|
# define DEFAULT_SENDMAIL_PATH PHP_PROG_SENDMAIL " -t"
|
|
#else
|
|
# define DEFAULT_SENDMAIL_PATH NULL
|
|
#endif
|
|
|
|
PHP_INI_BEGIN()
|
|
PHP_INI_ENTRY("short_open_tag", "1", PHP_INI_ALL, OnUpdateInt, (void *) XtOffsetOf(php_core_globals, short_tags))
|
|
PHP_INI_ENTRY("asp_tags", "0", PHP_INI_ALL, OnUpdateInt, (void *) XtOffsetOf(php_core_globals, asp_tags))
|
|
PHP_INI_ENTRY("precision", "14", PHP_INI_ALL, OnSetPrecision, NULL)
|
|
|
|
PHP_INI_ENTRY("highlight.comment", HL_COMMENT_COLOR, PHP_INI_ALL, NULL, NULL)
|
|
PHP_INI_ENTRY("highlight.default", HL_DEFAULT_COLOR, PHP_INI_ALL, NULL, NULL)
|
|
PHP_INI_ENTRY("highlight.html", HL_HTML_COLOR, PHP_INI_ALL, NULL, NULL)
|
|
PHP_INI_ENTRY("highlight.string", HL_STRING_COLOR, PHP_INI_ALL, NULL, NULL)
|
|
PHP_INI_ENTRY("highlight.bg", HL_BG_COLOR, PHP_INI_ALL, NULL, NULL)
|
|
PHP_INI_ENTRY("highlight.keyword", HL_KEYWORD_COLOR, PHP_INI_ALL, NULL, NULL)
|
|
|
|
PHP_INI_ENTRY("magic_quotes_gpc", "1", PHP_INI_ALL, OnUpdateInt, (void *) XtOffsetOf(php_core_globals, magic_quotes_gpc))
|
|
PHP_INI_ENTRY("magic_quotes_runtime", "0", PHP_INI_ALL, OnUpdateInt, (void *) XtOffsetOf(php_core_globals, magic_quotes_runtime))
|
|
PHP_INI_ENTRY("magic_quotes_sybase", "0", PHP_INI_ALL, OnUpdateInt, (void *) XtOffsetOf(php_core_globals, magic_quotes_sybase))
|
|
|
|
PHP_INI_ENTRY("safe_mode", "0", PHP_INI_SYSTEM, OnUpdateInt, (void *) XtOffsetOf(php_core_globals, safe_mode))
|
|
PHP_INI_ENTRY("sql.safe_mode", "0", PHP_INI_SYSTEM, OnUpdateInt, (void *) XtOffsetOf(php_core_globals, sql_safe_mode))
|
|
PHP_INI_ENTRY("safe_mode_exec_dir", SAFE_MODE_EXEC_DIR, PHP_INI_SYSTEM, OnUpdateString, (void *) XtOffsetOf(php_core_globals, safe_mode_exec_dir))
|
|
|
|
PHP_INI_ENTRY("SMTP", "localhost", PHP_INI_ALL, NULL, NULL)
|
|
PHP_INI_ENTRY("sendmail_path", DEFAULT_SENDMAIL_PATH, PHP_INI_SYSTEM, NULL, NULL)
|
|
PHP_INI_ENTRY("sendmail_from", NULL, PHP_INI_ALL, NULL, NULL)
|
|
|
|
PHP_INI_ENTRY("display_errors", "1", PHP_INI_ALL, OnUpdateInt, (void *) XtOffsetOf(php_core_globals, display_errors))
|
|
PHP_INI_ENTRY("track_errors", "0", PHP_INI_ALL, OnUpdateInt, (void *) XtOffsetOf(php_core_globals, track_errors))
|
|
PHP_INI_ENTRY("log_errors", "0", PHP_INI_ALL, OnUpdateInt, (void *) XtOffsetOf(php_core_globals, log_errors))
|
|
|
|
PHP_INI_ENTRY("auto_prepend_file", NULL, PHP_INI_ALL, OnUpdateString, (void *) XtOffsetOf(php_core_globals, auto_prepend_file))
|
|
PHP_INI_ENTRY("auto_append_file", NULL, PHP_INI_ALL, OnUpdateString, (void *) XtOffsetOf(php_core_globals, auto_append_file))
|
|
PHP_INI_END()
|
|
|
|
|
|
|
|
#ifndef THREAD_SAFE
|
|
/*
|
|
* Globals yet to be protected
|
|
*/
|
|
int initialized; /* keep track of which resources were successfully initialized */
|
|
static int module_initialized = 0;
|
|
unsigned char header_is_being_sent;
|
|
|
|
#if WIN32|WINNT
|
|
unsigned int wintimer;
|
|
unsigned int timerstart;
|
|
unsigned int wintimer_counter = 0;
|
|
#endif
|
|
|
|
#if APACHE
|
|
request_rec *php3_rqst = NULL; /* request record pointer for apache module version */
|
|
#endif
|
|
|
|
/*
|
|
* End of globals to be protected
|
|
*/
|
|
|
|
#endif
|
|
|
|
php3_ini_structure php3_ini;
|
|
php3_ini_structure php3_ini_master;
|
|
|
|
void _php3_build_argv(char * ELS_DC);
|
|
static void php3_timeout(int dummy);
|
|
static void php3_set_timeout(long seconds INLINE_TLS);
|
|
|
|
|
|
|
|
|
|
|
|
#if APACHE
|
|
void php3_apache_puts(const char *s)
|
|
{
|
|
TLS_VARS;
|
|
|
|
if (GLOBAL(php3_rqst)) {
|
|
rputs(s, GLOBAL(php3_rqst));
|
|
} else {
|
|
fputs(s, stdout);
|
|
}
|
|
}
|
|
|
|
void php3_apache_putc(char c)
|
|
{
|
|
TLS_VARS;
|
|
|
|
if (GLOBAL(php3_rqst)) {
|
|
rputc(c, GLOBAL(php3_rqst));
|
|
} else {
|
|
fputc(c, stdout);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
void php3_log_err(char *log_message)
|
|
{
|
|
FILE *log_file;
|
|
TLS_VARS;
|
|
|
|
/* Try to use the specified logging location. */
|
|
if (php3_ini.error_log != NULL) {
|
|
#if HAVE_SYSLOG_H
|
|
if (strcmp(php3_ini.error_log, "syslog")) {
|
|
syslog(LOG_NOTICE, log_message);
|
|
return;
|
|
} else {
|
|
#endif
|
|
log_file = fopen(php3_ini.error_log, "a");
|
|
if (log_file != NULL) {
|
|
fprintf(log_file, log_message);
|
|
fprintf(log_file, "\n");
|
|
fclose(log_file);
|
|
return;
|
|
}
|
|
#if HAVE_SYSLOG_H
|
|
}
|
|
#endif
|
|
}
|
|
/* Otherwise fall back to the default logging location. */
|
|
#if APACHE
|
|
if (GLOBAL(php3_rqst)) {
|
|
#if MODULE_MAGIC_NUMBER >= 19970831
|
|
aplog_error(NULL, 0, APLOG_ERR | APLOG_NOERRNO, php3_rqst->server, log_message);
|
|
#else
|
|
log_error(log_message, php3_rqst->server);
|
|
#endif
|
|
} else {
|
|
fprintf(stderr, log_message);
|
|
fprintf(stderr, "\n");
|
|
}
|
|
#endif /*APACHE */
|
|
|
|
#if CGI_BINARY
|
|
if (php3_header()) {
|
|
fprintf(stderr, log_message);
|
|
fprintf(stderr, "\n");
|
|
}
|
|
#endif
|
|
}
|
|
|
|
|
|
/* is 4K big enough? */
|
|
#define PRINTF_BUFFER_SIZE 1024*4
|
|
|
|
/* wrapper for modules to use PHPWRITE */
|
|
PHPAPI int php3_write(void *buf, int size)
|
|
{
|
|
TLS_VARS;
|
|
return PHPWRITE(buf, size);
|
|
}
|
|
|
|
PHPAPI int php3_printf(const char *format,...)
|
|
{
|
|
va_list args;
|
|
int ret;
|
|
char buffer[PRINTF_BUFFER_SIZE];
|
|
int size;
|
|
|
|
va_start(args, format);
|
|
size = vsprintf(buffer, format, args);
|
|
ret = PHPWRITE(buffer, size);
|
|
va_end(args);
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
/* extended error handling function */
|
|
PHPAPI void php3_error(int type, const char *format,...)
|
|
{
|
|
va_list args;
|
|
char *error_filename = NULL;
|
|
uint error_lineno;
|
|
char buffer[1024];
|
|
int size = 0;
|
|
ELS_FETCH();
|
|
|
|
if (!(type & E_CORE)) {
|
|
if (!GLOBAL(initialized)) { /* don't display further errors after php3_request_shutdown() */
|
|
return;
|
|
}
|
|
}
|
|
switch (type) {
|
|
case E_CORE_ERROR:
|
|
case E_CORE_WARNING:
|
|
error_filename = NULL;
|
|
error_lineno = 0;
|
|
break;
|
|
case E_PARSE:
|
|
case E_COMPILE_ERROR:
|
|
case E_COMPILE_WARNING: {
|
|
CLS_FETCH();
|
|
|
|
error_filename = zend_get_compiled_filename();
|
|
error_lineno = CG(zend_lineno);
|
|
}
|
|
break;
|
|
case E_ERROR:
|
|
case E_NOTICE:
|
|
case E_WARNING:
|
|
error_filename = zend_get_executed_filename(ELS_C);
|
|
error_lineno = zend_get_executed_lineno(ELS_C);
|
|
break;
|
|
default:
|
|
error_filename = NULL;
|
|
error_lineno = 0;
|
|
break;
|
|
}
|
|
|
|
if (EG(error_reporting) & type || (type & E_CORE)) {
|
|
char *error_type_str;
|
|
|
|
switch (type) {
|
|
case E_ERROR:
|
|
case E_CORE_ERROR:
|
|
case E_COMPILE_ERROR:
|
|
error_type_str = "Fatal error";
|
|
break;
|
|
case E_WARNING:
|
|
case E_CORE_WARNING:
|
|
case E_COMPILE_WARNING:
|
|
error_type_str = "Warning";
|
|
break;
|
|
case E_PARSE:
|
|
error_type_str = "Parse error";
|
|
break;
|
|
case E_NOTICE:
|
|
error_type_str = "Warning";
|
|
break;
|
|
default:
|
|
error_type_str = "Unknown error";
|
|
break;
|
|
}
|
|
|
|
/* get include file name */
|
|
if (PG(log_errors) || PG(display_errors)) {
|
|
va_start(args, format);
|
|
size = vsnprintf(buffer, sizeof(buffer) - 1, format, args);
|
|
va_end(args);
|
|
buffer[sizeof(buffer) - 1] = 0;
|
|
|
|
if (PG(log_errors)) {
|
|
char log_buffer[1024];
|
|
|
|
snprintf(log_buffer, 1024, "PHP 3 %s: %s in %s on line %d", error_type_str, buffer, error_filename, error_lineno);
|
|
php3_log_err(log_buffer);
|
|
}
|
|
if (PG(display_errors)) {
|
|
if(php3_ini.error_prepend_string) {
|
|
PUTS(php3_ini.error_prepend_string);
|
|
}
|
|
php3_printf("<br>\n<b>%s</b>: %s in <b>%s</b> on line <b>%d</b><br>\n", error_type_str, buffer, error_filename, error_lineno);
|
|
if(php3_ini.error_append_string) {
|
|
PUTS(php3_ini.error_append_string);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (PG(track_errors)) {
|
|
pval tmp;
|
|
|
|
va_start(args, format);
|
|
size = vsnprintf(buffer, sizeof(buffer) - 1, format, args);
|
|
va_end(args);
|
|
buffer[sizeof(buffer) - 1] = 0;
|
|
|
|
tmp.value.str.val = (char *) estrndup(buffer, size);
|
|
tmp.value.str.len = size;
|
|
tmp.type = IS_STRING;
|
|
|
|
_php3_hash_update(EG(active_symbol_table), "php_errormsg", sizeof("php_errormsg"), (void *) & tmp, sizeof(pval), NULL);
|
|
}
|
|
|
|
switch (type) {
|
|
case E_ERROR:
|
|
case E_CORE_ERROR:
|
|
/*case E_PARSE: the parser would return 1 (failure), we can bail out nicely */
|
|
case E_COMPILE_ERROR:
|
|
zend_bailout();
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
#if HAVE_SETITIMER
|
|
static void php3_timeout(int dummy)
|
|
{
|
|
TLS_VARS;
|
|
|
|
php3_error(E_ERROR, "Maximum execution time of %d seconds exceeded", php3_ini.max_execution_time);
|
|
}
|
|
#endif
|
|
|
|
/* This one doesn't exists on QNX */
|
|
#ifndef SIGPROF
|
|
#define SIGPROF 27
|
|
#endif
|
|
|
|
static void php3_set_timeout(long seconds INLINE_TLS)
|
|
{
|
|
#if WIN32|WINNT
|
|
if (seconds > 0) {
|
|
GLOBAL(timerstart) = (unsigned int) clock();
|
|
GLOBAL(wintimer) = GLOBAL(timerstart) + (CLOCKS_PER_SEC * seconds);
|
|
} else {
|
|
GLOBAL(wintimer) = 0;
|
|
}
|
|
#else
|
|
#if HAVE_SETITIMER
|
|
struct itimerval t_r; /* timeout requested */
|
|
|
|
t_r.it_value.tv_sec = seconds;
|
|
t_r.it_value.tv_usec = t_r.it_interval.tv_sec = t_r.it_interval.tv_usec = 0;
|
|
|
|
setitimer(ITIMER_PROF, &t_r, NULL);
|
|
signal(SIGPROF, php3_timeout);
|
|
#endif
|
|
#endif
|
|
}
|
|
|
|
|
|
static void php3_unset_timeout(INLINE_TLS_VOID)
|
|
{
|
|
#if WIN32|WINNT
|
|
GLOBAL(wintimer) = 0;
|
|
#else
|
|
#if HAVE_SETITIMER
|
|
struct itimerval no_timeout;
|
|
|
|
no_timeout.it_value.tv_sec = no_timeout.it_value.tv_usec = no_timeout.it_interval.tv_sec = no_timeout.it_interval.tv_usec = 0;
|
|
|
|
setitimer(ITIMER_PROF, &no_timeout, NULL);
|
|
#endif
|
|
#endif
|
|
}
|
|
|
|
|
|
void php3_set_time_limit(INTERNAL_FUNCTION_PARAMETERS)
|
|
{
|
|
pval *new_timeout;
|
|
|
|
if (PG(safe_mode)) {
|
|
php3_error(E_WARNING, "Cannot set time limit in safe mode");
|
|
RETURN_FALSE;
|
|
}
|
|
if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &new_timeout) == FAILURE) {
|
|
WRONG_PARAM_COUNT;
|
|
}
|
|
convert_to_long(new_timeout);
|
|
/* FIXME ** This is BAD...in a threaded situation, any user
|
|
can set the timeout for php on a server wide basis.
|
|
INI variables should not be reset via a user script
|
|
|
|
Fix what? At least on Unix, timers like these are
|
|
per-thread timers. Well, with a little work they will
|
|
be. If we use a bound thread and proper masking it
|
|
should work fine. Is this FIXME a WIN32 problem? Is
|
|
there no way to do per-thread timers on WIN32?
|
|
*/
|
|
php3_unset_timeout(_INLINE_TLS_VOID);
|
|
php3_set_timeout(new_timeout->value.lval _INLINE_TLS);
|
|
}
|
|
|
|
|
|
static FILE *php_fopen_wrapper_for_zend(const char *filename)
|
|
{
|
|
int issock=0, socketd=0;
|
|
|
|
FILE *retval=php3_fopen_wrapper((char *) filename, "r", USE_PATH|IGNORE_URL_WIN, &issock, &socketd);
|
|
if (issock) {
|
|
retval = fdopen(socketd, "r");
|
|
}
|
|
return retval;
|
|
}
|
|
|
|
|
|
static void php_message_handler_for_zend(long message, void *data)
|
|
{
|
|
switch (message) {
|
|
case ZMSG_ENABLE_TRACK_VARS:
|
|
php3_ini.track_vars = 1;
|
|
break;
|
|
case ZMSG_FAILED_INCLUDE_FOPEN:
|
|
php3_error(E_WARNING, "Failed opening '%s' for inclusion", php3_strip_url_passwd((char *) data));
|
|
break;
|
|
case ZMSG_FAILED_REQUIRE_FOPEN:
|
|
php3_error(E_ERROR, "Failed opening required '%s'", php3_strip_url_passwd((char *) data));
|
|
break;
|
|
case ZMSG_FAILED_HIGHLIGHT_FOPEN:
|
|
php3_error(E_WARNING, "Failed opening '%s' for highlighting", php3_strip_url_passwd((char *) data));
|
|
break;
|
|
case ZMSG_MEMORY_LEAK_DETECTED: {
|
|
mem_header *t = (mem_header *) data;
|
|
ELS_FETCH();
|
|
|
|
if (EG(error_reporting)&E_WARNING) {
|
|
#if ZEND_DEBUG
|
|
# if APACHE /* log into the errorlog, since at this time we can't send messages to the browser */
|
|
char memory_leak_buf[512];
|
|
|
|
snprintf(memory_leak_buf,512,"Possible PHP3 memory leak detected (harmless): %d bytes from %s:%d",t->size,t->filename,t->lineno);
|
|
# if MODULE_MAGIC_NUMBER >= 19970831
|
|
aplog_error(NULL, 0, APLOG_ERR | APLOG_NOERRNO, GLOBAL(php3_rqst)->server, memory_leak_buf);
|
|
# else
|
|
log_error(memory_leak_buf,GLOBAL(php3_rqst)->server);
|
|
# endif
|
|
# else
|
|
php3_printf("Freeing 0x%0.8X (%d bytes), allocated in %s on line %d<br>\n",(void *)((char *)t+sizeof(mem_header)+PLATFORM_PADDING),t->size,t->filename,t->lineno);
|
|
# endif
|
|
#endif
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
int php3_request_startup(CLS_D ELS_DC)
|
|
{
|
|
zend_output_startup();
|
|
#if APACHE && defined(CRASH_DETECTION)
|
|
{
|
|
char log_message[256];
|
|
|
|
snprintf(log_message,256,"php3_request_startup(): script='%s', pid=%d",php3_rqst->filename,getpid());
|
|
log_error(log_message, php3_rqst->server);
|
|
}
|
|
#endif
|
|
|
|
php3_set_timeout(php3_ini.max_execution_time _INLINE_TLS);
|
|
|
|
GLOBAL(initialized) = 0;
|
|
|
|
#if APACHE
|
|
/*
|
|
* For the Apache module version, this bit of code registers a cleanup
|
|
* function that gets triggered when our request pool is destroyed.
|
|
* We need this because at any point in our code we can be interrupted
|
|
* and that may happen before we have had time to free our memory.
|
|
* The php3_shutdown function needs to free all outstanding allocated
|
|
* memory.
|
|
*/
|
|
block_alarms();
|
|
register_cleanup(GLOBAL(php3_rqst)->pool, NULL, php3_request_shutdown, php3_request_shutdown_for_exec);
|
|
unblock_alarms();
|
|
#endif
|
|
|
|
/* initialize global variables */
|
|
{
|
|
EG(error_reporting) = php3_ini.errors;
|
|
GLOBAL(header_is_being_sent) = 0;
|
|
GLOBAL(php3_track_vars) = php3_ini.track_vars;
|
|
}
|
|
|
|
if (php3_init_request_info((void *) &php3_ini)) {
|
|
php3_printf("Unable to initialize request info.\n");
|
|
return FAILURE;
|
|
}
|
|
GLOBAL(initialized) |= INIT_REQUEST_INFO;
|
|
|
|
init_compiler(CLS_C ELS_CC);
|
|
init_executor(CLS_C ELS_CC);
|
|
|
|
startup_scanner(CLS_C);
|
|
|
|
|
|
return SUCCESS;
|
|
}
|
|
|
|
|
|
void php3_request_shutdown_for_exec(void *dummy)
|
|
{
|
|
TLS_VARS;
|
|
|
|
/* used to close fd's in the 3..255 range here, but it's problematic
|
|
*/
|
|
shutdown_memory_manager(1, 1);
|
|
}
|
|
|
|
|
|
int return_one(void *p)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
|
|
void php3_request_shutdown(void *dummy INLINE_TLS)
|
|
{
|
|
#if FHTTPD
|
|
char tmpline[128];
|
|
int i, serverdefined;
|
|
#endif
|
|
#if APACHE && defined(CRASH_DETECTION)
|
|
{
|
|
char log_message[256];
|
|
|
|
snprintf(log_message,256,"php3_request_shutdown(): script='%s', pid=%d",php3_rqst->filename,getpid());
|
|
log_error(log_message, php3_rqst->server);
|
|
}
|
|
#endif
|
|
CLS_FETCH();
|
|
ELS_FETCH();
|
|
|
|
php3_header();
|
|
zend_end_ob_buffering(1);
|
|
|
|
|
|
php3_call_shutdown_functions();
|
|
|
|
GLOBAL(initialized) &= ~INIT_ENVIRONMENT; /* does not require any special shutdown */
|
|
|
|
php_ini_rshutdown();
|
|
|
|
shutdown_scanner(CLS_C);
|
|
|
|
shutdown_compiler(CLS_C);
|
|
shutdown_executor(ELS_C);
|
|
|
|
if (GLOBAL(initialized) & INIT_REQUEST_INFO) {
|
|
SHUTDOWN_DEBUG("Request info");
|
|
php3_destroy_request_info((void *) &php3_ini);
|
|
GLOBAL(initialized) &= ~INIT_REQUEST_INFO;
|
|
}
|
|
if (GLOBAL(initialized) & INIT_SCANNER) {
|
|
SHUTDOWN_DEBUG("Scanner");
|
|
reset_scanner(CLS_C);
|
|
GLOBAL(initialized) &= ~INIT_SCANNER;
|
|
}
|
|
SHUTDOWN_DEBUG("Memory manager");
|
|
shutdown_memory_manager(0, 0);
|
|
if (GLOBAL(initialized)) {
|
|
php3_error(E_WARNING, "Unknown resources in request shutdown function");
|
|
}
|
|
php3_unset_timeout(_INLINE_TLS_VOID);
|
|
|
|
|
|
#if CGI_BINARY
|
|
fflush(stdout);
|
|
if(GLOBAL(request_info).php_argv0) {
|
|
free(GLOBAL(request_info).php_argv0);
|
|
GLOBAL(request_info).php_argv0 = NULL;
|
|
}
|
|
#endif
|
|
#if FHTTPD
|
|
if (response) {
|
|
if (!headermade) {
|
|
makestandardheader(response, 200, "text/html", "fhttpd", req && req->keepalive);
|
|
} else {
|
|
if (headerfirstline)
|
|
putlinetoheader(response, headerfirstline);
|
|
else
|
|
putlinetoheader(response, "HTTP/1.0 200 OK\r\n");
|
|
serverdefined = 0;
|
|
for (i = 0; i < headerlines; i++) {
|
|
if (!strncmp(currentheader[i], "Server:", 7))
|
|
serverdefined = 1;
|
|
putlinetoheader(response, currentheader[i]);
|
|
}
|
|
if (!serverdefined)
|
|
putlinetoheader(response, "Server: fhttpd\r\n");
|
|
if (response->datasize) {
|
|
sprintf(tmpline, "Content-Length: %ld\r\n", response->datasize);
|
|
putlinetoheader(response, tmpline);
|
|
if (req && req->keepalive)
|
|
putlinetoheader(response,
|
|
"Connection: Keep-Alive\r\nKeep-Alive: max=0, timeout=30\r\n");
|
|
}
|
|
php3_fhttpd_free_header();
|
|
}
|
|
sendresponse(server, response);
|
|
if (response->datasize)
|
|
finishresponse(server, response);
|
|
else
|
|
finishdropresponse(server, response);
|
|
deleteresponse(response);
|
|
}
|
|
response = NULL;
|
|
if (req)
|
|
deleterequest(req);
|
|
req = NULL;
|
|
#endif
|
|
#if USE_SAPI
|
|
GLOBAL(sapi_rqst)->flush(GLOBAL(sapi_rqst)->scid);
|
|
#endif
|
|
}
|
|
|
|
|
|
static int php3_config_ini_startup(ELS_D)
|
|
{
|
|
/* set the memory limit to a reasonable number so that we can get
|
|
* through this startup phase properly
|
|
*/
|
|
php3_ini.memory_limit=1<<23; /* 8MB */
|
|
|
|
if (php3_init_config() == FAILURE) {
|
|
php3_printf("PHP: Unable to parse configuration file.\n");
|
|
return FAILURE;
|
|
}
|
|
#if !(USE_SAPI)
|
|
GLOBAL(module_initialized) |= INIT_CONFIG;
|
|
#endif
|
|
/* initialize run-time variables */
|
|
/* I have remarked out some stuff
|
|
that may or may not be needed */
|
|
{
|
|
char *temp;
|
|
|
|
if (cfg_get_long("max_execution_time", &php3_ini.max_execution_time) == FAILURE) {
|
|
php3_ini.max_execution_time = 30;
|
|
}
|
|
if (cfg_get_long("memory_limit", &php3_ini.memory_limit) == FAILURE) {
|
|
php3_ini.memory_limit = 1<<23; /* 8MB */
|
|
}
|
|
if (cfg_get_long("error_reporting", &php3_ini.errors) == FAILURE) {
|
|
php3_ini.errors = E_ALL & ~E_NOTICE;
|
|
}
|
|
EG(error_reporting) = php3_ini.errors;
|
|
if (cfg_get_string("error_log", &php3_ini.error_log) == FAILURE) {
|
|
php3_ini.error_log = NULL;
|
|
}
|
|
if (cfg_get_long("y2k_compliance", &php3_ini.y2k_compliance) == FAILURE) {
|
|
php3_ini.y2k_compliance = 0;
|
|
}
|
|
if (cfg_get_long("define_syslog_variables", &php3_ini.define_syslog_variables) == FAILURE) {
|
|
php3_ini.define_syslog_variables = 0;
|
|
}
|
|
if (cfg_get_string("doc_root", &php3_ini.doc_root) == FAILURE) {
|
|
if ((temp = getenv("PHP_DOCUMENT_ROOT"))) {
|
|
php3_ini.doc_root = temp;
|
|
} else {
|
|
php3_ini.doc_root = NULL;
|
|
}
|
|
}
|
|
if (cfg_get_string("user_dir", &php3_ini.user_dir) == FAILURE) {
|
|
if ((temp = getenv("PHP_USER_DIR"))) {
|
|
php3_ini.user_dir = temp;
|
|
} else {
|
|
php3_ini.user_dir = NULL;
|
|
}
|
|
}
|
|
if (cfg_get_long("track_vars", &php3_ini.track_vars) == FAILURE) {
|
|
php3_ini.track_vars = PHP_TRACK_VARS;
|
|
}
|
|
if (cfg_get_string("include_path", &php3_ini.include_path) == FAILURE) {
|
|
if ((temp = getenv("PHP_INCLUDE_PATH"))) {
|
|
php3_ini.include_path = temp;
|
|
} else {
|
|
php3_ini.include_path = NULL;
|
|
}
|
|
}
|
|
if (cfg_get_string("upload_tmp_dir", &php3_ini.upload_tmp_dir) == FAILURE) {
|
|
/* php3_ini.upload_tmp_dir = UPLOAD_TMPDIR; */
|
|
php3_ini.upload_tmp_dir = NULL;
|
|
}
|
|
if (cfg_get_long("upload_max_filesize", &php3_ini.upload_max_filesize) == FAILURE) {
|
|
php3_ini.upload_max_filesize = 2097152; /* 2 Meg default */
|
|
}
|
|
if (cfg_get_string("extension_dir", &php3_ini.extension_dir) == FAILURE) {
|
|
php3_ini.extension_dir = NULL;
|
|
}
|
|
if (cfg_get_long("engine", &php3_ini.engine) == FAILURE) {
|
|
php3_ini.engine = 1;
|
|
}
|
|
if (cfg_get_long("last_modified", &php3_ini.last_modified) == FAILURE) {
|
|
php3_ini.last_modified = 0;
|
|
}
|
|
if (cfg_get_long("xbithack", &php3_ini.xbithack) == FAILURE) {
|
|
php3_ini.xbithack = 0;
|
|
}
|
|
if (cfg_get_string("browscap", &php3_ini.browscap) == FAILURE) {
|
|
php3_ini.browscap = NULL;
|
|
}
|
|
if (cfg_get_string("arg_separator", &php3_ini.arg_separator) == FAILURE) {
|
|
php3_ini.arg_separator = "&";
|
|
}
|
|
if (cfg_get_string("gpc_order", &php3_ini.gpc_order) == FAILURE) {
|
|
php3_ini.gpc_order = "GPC";
|
|
}
|
|
if (cfg_get_string("error_prepend_string", &php3_ini.error_prepend_string) == FAILURE) {
|
|
php3_ini.error_prepend_string = NULL;
|
|
}
|
|
if (cfg_get_string("error_append_string", &php3_ini.error_append_string) == FAILURE) {
|
|
php3_ini.error_append_string = NULL;
|
|
}
|
|
if (cfg_get_string("open_basedir", &php3_ini.open_basedir) == FAILURE) {
|
|
php3_ini.open_basedir = NULL;
|
|
}
|
|
if (cfg_get_long("enable_dl", &php3_ini.enable_dl) == FAILURE) {
|
|
php3_ini.enable_dl = 1;
|
|
}
|
|
/* THREADX Will have to look into this on windows
|
|
* Make a master copy to use as a basis for every per-dir config.
|
|
* Without two copies we would have a previous requst's per-dir
|
|
* config carry forward to the next one.
|
|
*/
|
|
memcpy(&php3_ini_master, &php3_ini, sizeof(php3_ini));
|
|
}
|
|
return SUCCESS;
|
|
}
|
|
|
|
static void php3_config_ini_shutdown(INLINE_TLS_VOID)
|
|
{
|
|
#if USE_SAPI
|
|
php3_shutdown_config();
|
|
#else
|
|
if (GLOBAL(module_initialized) & INIT_CONFIG) {
|
|
php3_shutdown_config();
|
|
GLOBAL(module_initialized) &= ~INIT_CONFIG;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
int php3_module_startup(CLS_D ELS_DC)
|
|
{
|
|
zend_utility_functions zuf;
|
|
zend_utility_values zuv;
|
|
int module_number=0; /* for REGISTER_INI_ENTRIES() */
|
|
|
|
#if (WIN32|WINNT) && !(USE_SAPI)
|
|
WORD wVersionRequested;
|
|
WSADATA wsaData;
|
|
|
|
wVersionRequested = MAKEWORD(2, 0);
|
|
#else
|
|
if (GLOBAL(module_initialized)) {
|
|
return SUCCESS;
|
|
}
|
|
#endif
|
|
|
|
zend_output_startup();
|
|
|
|
zuf.error_function = php3_error;
|
|
zuf.printf_function = php3_printf;
|
|
zuf.write_function = zend_body_write;
|
|
zuf.fopen_function = php_fopen_wrapper_for_zend;
|
|
zuf.message_handler = php_message_handler_for_zend;
|
|
zuf.block_interruptions = BLOCK_INTERRUPTIONS;
|
|
zuf.unblock_interruptions = UNBLOCK_INTERRUPTIONS;
|
|
|
|
zend_startup(&zuf, NULL);
|
|
|
|
#if HAVE_SETLOCALE
|
|
setlocale(LC_CTYPE, "");
|
|
#endif
|
|
|
|
EG(error_reporting) = E_ALL;
|
|
|
|
#if (WIN32|WINNT) && !(USE_SAPI)
|
|
/* start up winsock services */
|
|
if (WSAStartup(wVersionRequested, &wsaData) != 0) {
|
|
php3_printf("\nwinsock.dll unusable. %d\n", WSAGetLastError());
|
|
return FAILURE;
|
|
}
|
|
GLOBAL(module_initialized) |= INIT_WINSOCK;
|
|
#endif
|
|
|
|
SET_MUTEX(gLock);
|
|
le_index_ptr = _register_list_destructors(NULL, NULL, 0);
|
|
FREE_MUTEX(gLock);
|
|
|
|
if (php3_config_ini_startup(ELS_C) == FAILURE) {
|
|
return FAILURE;
|
|
}
|
|
|
|
php_ini_mstartup();
|
|
REGISTER_INI_ENTRIES();
|
|
|
|
zuv.short_tags = (unsigned char) PG(short_tags);
|
|
zuv.asp_tags = (unsigned char) PG(asp_tags);
|
|
zend_set_utility_values(&zuv);
|
|
|
|
if (module_startup_modules() == FAILURE) {
|
|
php3_printf("Unable to start modules\n");
|
|
return FAILURE;
|
|
}
|
|
return SUCCESS;
|
|
}
|
|
|
|
|
|
|
|
void php3_module_shutdown_for_exec(void)
|
|
{
|
|
/* used to close fd's in the range 3.255 here, but it's problematic */
|
|
}
|
|
|
|
void php3_module_shutdown()
|
|
{
|
|
int module_number=0; /* for UNREGISTER_INI_ENTRIES() */
|
|
CLS_FETCH();
|
|
ELS_FETCH();
|
|
|
|
#if !USE_SAPI
|
|
/* close down the ini config */
|
|
php3_config_ini_shutdown(_INLINE_TLS_VOID);
|
|
#endif
|
|
|
|
#if (WIN32|WINNT) && !(USE_SAPI)
|
|
/*close winsock */
|
|
if (GLOBAL(module_initialized) & INIT_WINSOCK) {
|
|
WSACleanup();
|
|
GLOBAL(module_initialized) &= ~INIT_WINSOCK;
|
|
}
|
|
#endif
|
|
|
|
if (GLOBAL(module_initialized)) {
|
|
php3_error(E_WARNING, "Unknown resource in module shutdown");
|
|
}
|
|
#if CGI_BINARY
|
|
fflush(stdout);
|
|
#endif
|
|
#if 0 /* SAPI */
|
|
GLOBAL(sapi_rqst)->flush(GLOBAL(sapi_rqst)->scid);
|
|
#endif
|
|
|
|
zend_shutdown();
|
|
UNREGISTER_INI_ENTRIES();
|
|
php_ini_mshutdown();
|
|
shutdown_memory_manager(0, 1);
|
|
}
|
|
|
|
|
|
/* in 3.1 some of this should move into sapi */
|
|
int _php3_hash_environment(void)
|
|
{
|
|
char **env, *p, *t;
|
|
unsigned char _gpc_flags[3] = {0,0,0};
|
|
pval *tmp;
|
|
ELS_FETCH();
|
|
|
|
p = php3_ini.gpc_order;
|
|
while(*p) {
|
|
switch(*p++) {
|
|
case 'p':
|
|
case 'P':
|
|
if (!_gpc_flags[0] && php3_headers_unsent() && GLOBAL(request_info).request_method && !strcasecmp(GLOBAL(request_info).request_method, "post")) {
|
|
php3_treat_data(PARSE_POST, NULL); /* POST Data */
|
|
_gpc_flags[0]=1;
|
|
}
|
|
break;
|
|
case 'c':
|
|
case 'C':
|
|
if (!_gpc_flags[1]) {
|
|
php3_treat_data(PARSE_COOKIE, NULL); /* Cookie Data */
|
|
_gpc_flags[1]=1;
|
|
}
|
|
break;
|
|
case 'g':
|
|
case 'G':
|
|
if (!_gpc_flags[2]) {
|
|
php3_treat_data(PARSE_GET, NULL); /* GET Data */
|
|
_gpc_flags[2]=1;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
for (env = environ; env != NULL && *env != NULL; env++) {
|
|
p = strchr(*env, '=');
|
|
if (!p) { /* malformed entry? */
|
|
continue;
|
|
}
|
|
t = estrndup(*env, p - *env);
|
|
tmp = (pval *) emalloc(sizeof(pval));
|
|
tmp->value.str.len = strlen(p + 1);
|
|
tmp->value.str.val = estrndup(p + 1, tmp->value.str.len);
|
|
tmp->type = IS_STRING;
|
|
tmp->refcount=1;
|
|
tmp->is_ref=0;
|
|
/* environmental variables never take precedence over get/post/cookie variables */
|
|
_php3_hash_add(&EG(symbol_table), t, p - *env + 1, &tmp, sizeof(pval *), NULL);
|
|
efree(t);
|
|
}
|
|
|
|
#if APACHE
|
|
{
|
|
pval **tmp_ptr;
|
|
register int i;
|
|
array_header *arr = table_elts(GLOBAL(php3_rqst)->subprocess_env);
|
|
table_entry *elts = (table_entry *) arr->elts;
|
|
int len;
|
|
|
|
for (i = 0; i < arr->nelts; i++) {
|
|
len = strlen(elts[i].key);
|
|
t = elts[i].key;
|
|
tmp = (pval *) emalloc(sizeof(pval));
|
|
if (elts[i].val) {
|
|
tmp->value.str.len = strlen(elts[i].val);
|
|
tmp->value.str.val = estrndup(elts[i].val, tmp->value.str.len);
|
|
} else {
|
|
tmp->value.str.len = 0;
|
|
tmp->value.str.val = empty_string;
|
|
}
|
|
tmp->refcount=1;
|
|
tmp->is_ref=0;
|
|
tmp->type = IS_STRING;
|
|
_php3_hash_update(&EG(symbol_table), t, strlen(t)+1, &tmp, sizeof(pval *), NULL);
|
|
}
|
|
/* insert special variables */
|
|
if (_php3_hash_find(&EG(symbol_table), "SCRIPT_FILENAME", sizeof("SCRIPT_FILENAME"), (void **) &tmp_ptr) == SUCCESS) {
|
|
(*tmp_ptr)->refcount++;
|
|
_php3_hash_update(&EG(symbol_table), "PATH_TRANSLATED", sizeof("PATH_TRANSLATED"), tmp_ptr, sizeof(pval *), NULL);
|
|
}
|
|
tmp = (pval *) emalloc(sizeof(pval));
|
|
tmp->value.str.len = strlen(GLOBAL(php3_rqst)->uri);
|
|
tmp->value.str.val = estrndup(GLOBAL(php3_rqst)->uri, tmp->value.str.len);
|
|
tmp->refcount=1;
|
|
tmp->is_ref=0;
|
|
tmp->type = IS_STRING;
|
|
_php3_hash_update(&EG(symbol_table), "PHP_SELF", sizeof("PHP_SELF"), (void *) &tmp, sizeof(pval *), NULL);
|
|
}
|
|
#else
|
|
#if FHTTPD
|
|
{
|
|
int i, j;
|
|
if (req) {
|
|
for (i = 0; i < req->nlines; i++) {
|
|
if (req->lines[i].paramc > 1 && req->lines[i].params[0] && req->lines[i].params[1]) {
|
|
tmp = (pval *) emalloc(sizeof(pval));
|
|
tmp->value.str.len = strlen(req->lines[i].params[1]);
|
|
tmp->value.str.val = estrndup(req->lines[i].params[1], tmp->value.str.len);
|
|
tmp->type = IS_STRING;
|
|
tmp->refcount=1;
|
|
tmp->is_ref=0;
|
|
_php3_hash_update(&EG(symbol_table), req->lines[i].params[0],
|
|
strlen(req->lines[i].params[0]) + 1, &tmp,
|
|
sizeof(pval *), NULL);
|
|
}
|
|
}
|
|
if (req->script_name_resolved) {
|
|
i = strlen(req->script_name_resolved);
|
|
tmp = (pval *) emalloc(sizeof(pval));
|
|
tmp->value.str.len = i;
|
|
tmp->value.str.val = estrndup(req->script_name_resolved, i);
|
|
tmp->type = IS_STRING;
|
|
tmp->refcount=1;
|
|
tmp->is_ref=0;
|
|
_php3_hash_update(&EG(symbol_table), "PATH_TRANSLATED",
|
|
sizeof("PATH_TRANSLATED"),
|
|
&tmp, sizeof(pval *), NULL);
|
|
if (req->script_name) {
|
|
j = i - strlen(req->script_name);
|
|
if (j > 0
|
|
&& !strcmp(req->script_name_resolved + j,
|
|
req->script_name)) {
|
|
tmp = (pval *) emalloc(sizeof(pval));
|
|
tmp->value.str.len = j;
|
|
tmp->value.str.val = estrndup(req->script_name_resolved, j);
|
|
tmp->type = IS_STRING;
|
|
tmp->refcount=1;
|
|
tmp->is_ref=0;
|
|
_php3_hash_update(&EG(symbol_table), "DOCUMENT_ROOT",
|
|
sizeof("DOCUMENT_ROOT"),
|
|
&tmp, sizeof(pval *), NULL);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
{
|
|
/* Build the special-case PHP_SELF variable for the CGI version */
|
|
char *pi;
|
|
#if FORCE_CGI_REDIRECT
|
|
pi = GLOBAL(request_info).path_info;
|
|
tmp = (pval *) emalloc(sizeof(pval));
|
|
tmp->value.str.val = emalloc(((pi)?strlen(pi):0) + 1);
|
|
tmp->value.str.len = _php3_sprintf(tmp->value.str.val, "%s", (pi ? pi : "")); /* SAFE */
|
|
tmp->type = IS_STRING;
|
|
tmp->refcount=1;
|
|
tmp->is_ref=0;
|
|
#else
|
|
int l = 0;
|
|
char *sn;
|
|
sn = GLOBAL(request_info).script_name;
|
|
pi = GLOBAL(request_info).path_info;
|
|
if (sn)
|
|
l += strlen(sn);
|
|
if (pi)
|
|
l += strlen(pi);
|
|
if (pi && sn && !strcmp(pi, sn)) {
|
|
l -= strlen(pi);
|
|
pi = NULL;
|
|
}
|
|
tmp = (pval *) emalloc(sizeof(pval));
|
|
tmp->value.str.val = emalloc(l + 1);
|
|
tmp->value.str.len = _php3_sprintf(tmp->value.str.val, "%s%s", (sn ? sn : ""), (pi ? pi : "")); /* SAFE */
|
|
tmp->type = IS_STRING;
|
|
tmp->refcount=1;
|
|
tmp->is_ref=0;
|
|
#endif
|
|
_php3_hash_update(&EG(symbol_table), "PHP_SELF", sizeof("PHP_SELF"), (void *) & tmp, sizeof(pval *), NULL);
|
|
}
|
|
#endif
|
|
|
|
|
|
/* need argc/argv support as well */
|
|
_php3_build_argv(GLOBAL(request_info).query_string ELS_CC);
|
|
|
|
GLOBAL(initialized) |= INIT_ENVIRONMENT;
|
|
|
|
return SUCCESS;
|
|
}
|
|
|
|
void _php3_build_argv(char *s ELS_DC)
|
|
{
|
|
pval *arr, *tmp;
|
|
int count = 0;
|
|
char *ss, *space;
|
|
|
|
arr = (pval *) emalloc(sizeof(pval));
|
|
arr->value.ht = (HashTable *) emalloc(sizeof(HashTable));
|
|
if (_php3_hash_init(arr->value.ht, 0, NULL, PVAL_PTR_DTOR, 0) == FAILURE) {
|
|
php3_error(E_WARNING, "Unable to create argv array");
|
|
} else {
|
|
arr->type = IS_ARRAY;
|
|
arr->refcount=1;
|
|
arr->is_ref=0;
|
|
_php3_hash_update(&EG(symbol_table), "argv", sizeof("argv"), &arr, sizeof(pval *), NULL);
|
|
}
|
|
/* now pick out individual entries */
|
|
ss = s;
|
|
while (ss) {
|
|
space = strchr(ss, '+');
|
|
if (space) {
|
|
*space = '\0';
|
|
}
|
|
/* auto-type */
|
|
tmp = (pval *) emalloc(sizeof(pval));
|
|
tmp->type = IS_STRING;
|
|
tmp->value.str.len = strlen(ss);
|
|
tmp->value.str.val = estrndup(ss, tmp->value.str.len);
|
|
tmp->refcount=1;
|
|
tmp->is_ref=0;
|
|
count++;
|
|
if (_php3_hash_next_index_insert(arr->value.ht, &tmp, sizeof(pval *), NULL)==FAILURE) {
|
|
if (tmp->type == IS_STRING) {
|
|
efree(tmp->value.str.val);
|
|
}
|
|
}
|
|
if (space) {
|
|
*space = '+';
|
|
ss = space + 1;
|
|
} else {
|
|
ss = space;
|
|
}
|
|
}
|
|
tmp = (pval *) emalloc(sizeof(pval));
|
|
tmp->value.lval = count;
|
|
tmp->type = IS_LONG;
|
|
tmp->refcount=1;
|
|
tmp->is_ref=0;
|
|
_php3_hash_add(&EG(symbol_table), "argc", sizeof("argc"), &tmp, sizeof(pval *), NULL);
|
|
}
|
|
|
|
|
|
#include "logos.h"
|
|
|
|
static void php3_parse(zend_file_handle *primary_file CLS_DC ELS_DC)
|
|
{
|
|
zend_file_handle *prepend_file_p, *append_file_p;
|
|
zend_file_handle prepend_file, append_file;
|
|
|
|
if (request_info.query_string && request_info.query_string[0]=='=') {
|
|
if (!strcmp(request_info.query_string+1, "PHPE9568F34-D428-11d2-A769-00AA001ACF42")) {
|
|
char *header_line = estrndup("Content-type: image/gif", sizeof("Content-type: image/gif")-1);
|
|
|
|
php4i_add_header_information(header_line);
|
|
PHPWRITE(php4_logo, sizeof(php4_logo));
|
|
efree(header_line);
|
|
return;
|
|
} else if (!strcmp(request_info.query_string+1, "PHPE9568F35-D428-11d2-A769-00AA001ACF42")) {
|
|
char *header_line = estrndup("Content-type: image/gif", sizeof("Content-type: image/gif")-1);
|
|
|
|
php4i_add_header_information(header_line);
|
|
PHPWRITE(zendtech_logo, sizeof(zendtech_logo));
|
|
efree(header_line);
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (setjmp(EG(bailout))!=0) {
|
|
return;
|
|
}
|
|
_php3_hash_environment();
|
|
|
|
|
|
if (PG(auto_prepend_file) && PG(auto_prepend_file)[0]) {
|
|
prepend_file.filename = PG(auto_prepend_file);
|
|
prepend_file.type = ZEND_HANDLE_FILENAME;
|
|
prepend_file_p = &prepend_file;
|
|
} else {
|
|
prepend_file_p = NULL;
|
|
}
|
|
if (PG(auto_append_file) && PG(auto_append_file)[0]) {
|
|
append_file.filename = PG(auto_append_file);
|
|
append_file.type = ZEND_HANDLE_FILENAME;
|
|
append_file_p = &append_file;
|
|
} else {
|
|
append_file_p = NULL;
|
|
}
|
|
EG(main_op_array) = zend_compile_files(0 CLS_CC, 3, prepend_file_p, primary_file, append_file_p);
|
|
if (EG(main_op_array)) {
|
|
EG(active_op_array) = EG(main_op_array);
|
|
zend_execute(EG(main_op_array) ELS_CC);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#if CGI_BINARY
|
|
|
|
static void _php3_usage(char *argv0)
|
|
{
|
|
char *prog;
|
|
|
|
prog = strrchr(argv0, '/');
|
|
if (prog) {
|
|
prog++;
|
|
} else {
|
|
prog = "php";
|
|
}
|
|
|
|
php3_printf("Usage: %s [-q] [-h]"
|
|
" [-s]"
|
|
" [-v] [-i] [-f <file>] | "
|
|
"{<file> [args...]}\n"
|
|
" -q Quiet-mode. Suppress HTTP Header output.\n"
|
|
" -s Display colour syntax highlighted source.\n"
|
|
" -f<file> Parse <file>. Implies `-q'\n"
|
|
" -v Version number\n"
|
|
" -c<path> Look for php3.ini file in this directory\n"
|
|
#if SUPPORT_INTERACTIVE
|
|
" -a Run interactively\n"
|
|
#endif
|
|
" -e Generate extended information for debugger/profiler\n"
|
|
" -i PHP information\n"
|
|
" -h This help\n", prog);
|
|
}
|
|
|
|
/* some systems are missing these from their header files */
|
|
extern char *optarg;
|
|
extern int optind;
|
|
|
|
#if THREAD_SAFE
|
|
extern flex_globals *yy_init_tls(void);
|
|
extern void yy_destroy_tls(void);
|
|
#endif
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
int cgi = 0, c, i, len;
|
|
zend_file_handle file_handle;
|
|
char *s;
|
|
/* temporary locals */
|
|
char *_cgi_filename=NULL;
|
|
int _cgi_started=0;
|
|
int behavior=PHP_MODE_STANDARD;
|
|
#if SUPPORT_INTERACTIVE
|
|
int interactive=0;
|
|
#endif
|
|
/* end of temporary locals */
|
|
#ifdef ZTS
|
|
zend_compiler_globals *compiler_globals;
|
|
zend_executor_globals *executor_globals;
|
|
#endif
|
|
|
|
|
|
if (setjmp(EG(bailout))!=0) {
|
|
return -1;
|
|
}
|
|
|
|
#ifdef ZTS
|
|
sapi_startup(1,1,0);
|
|
compiler_globals_id = ts_allocate_id(sizeof(zend_compiler_globals));
|
|
executor_globals_id = ts_allocate_id(sizeof(zend_executor_globals));
|
|
|
|
compiler_globals = ts_resource(compiler_globals_id);
|
|
executor_globals = ts_resource(executor_globals_id);
|
|
#endif
|
|
|
|
|
|
#if WIN32|WINNT
|
|
_fmode = _O_BINARY; /*sets default for file streams to binary */
|
|
setmode(_fileno(stdin), O_BINARY); /* make the stdio mode be binary */
|
|
setmode(_fileno(stdout), O_BINARY); /* make the stdio mode be binary */
|
|
setmode(_fileno(stderr), O_BINARY); /* make the stdio mode be binary */
|
|
#endif
|
|
|
|
|
|
/* Make sure we detect we are a cgi - a bit redundancy here,
|
|
but the default case is that we have to check only the first one. */
|
|
if (getenv("SERVER_SOFTWARE")
|
|
|| getenv("SERVER_NAME")
|
|
|| getenv("GATEWAY_INTERFACE")
|
|
|| getenv("REQUEST_METHOD")) {
|
|
cgi = 1;
|
|
if (argc > 1)
|
|
GLOBAL(request_info).php_argv0 = strdup(argv[1]);
|
|
else GLOBAL(request_info).php_argv0 = NULL;
|
|
#if FORCE_CGI_REDIRECT
|
|
if (!getenv("REDIRECT_STATUS")) {
|
|
PUTS("<b>Security Alert!</b> PHP CGI cannot be accessed directly.\n\
|
|
\n\
|
|
<P>This PHP CGI binary was compiled with force-cgi-redirect enabled. This\n\
|
|
means that a page will only be served up if the REDIRECT_STATUS CGI variable is\n\
|
|
set. This variable is set, for example, by Apache's Action directive redirect.\n\
|
|
<P>You may disable this restriction by recompiling the PHP binary with the\n\
|
|
--disable-force-cgi-redirect switch. If you do this and you have your PHP CGI\n\
|
|
binary accessible somewhere in your web tree, people will be able to circumvent\n\
|
|
.htaccess security by loading files through the PHP parser. A good way around\n\
|
|
this is to define doc_root in your php3.ini file to something other than your\n\
|
|
top-level DOCUMENT_ROOT. This way you can separate the part of your web space\n\n\
|
|
which uses PHP from the normal part using .htaccess security. If you do not have\n\
|
|
any .htaccess restrictions anywhere on your site you can leave doc_root undefined.\n\
|
|
\n");
|
|
|
|
/* remove that detailed explanation some time */
|
|
|
|
return FAILURE;
|
|
}
|
|
#endif /* FORCE_CGI_REDIRECT */
|
|
}
|
|
|
|
|
|
CG(extended_info) = 0;
|
|
|
|
if (!cgi) { /* never execute the arguments if you are a CGI */
|
|
GLOBAL(request_info).php_argv0 = NULL;
|
|
while ((c = getopt(argc, argv, "c:qvisnaeh?vf:")) != -1) {
|
|
switch (c) {
|
|
case 'f':
|
|
if (!_cgi_started){
|
|
if (php3_module_startup(CLS_C ELS_CC) == FAILURE || php3_request_startup(CLS_C ELS_CC) == FAILURE) {
|
|
return FAILURE;
|
|
}
|
|
}
|
|
_cgi_started=1;
|
|
_cgi_filename = estrdup(optarg);
|
|
/* break missing intentionally */
|
|
case 'q':
|
|
php3_noheader();
|
|
break;
|
|
case 'v':
|
|
if (!_cgi_started) {
|
|
if (php3_module_startup(CLS_C ELS_CC) == FAILURE || php3_request_startup(CLS_C ELS_CC) == FAILURE) {
|
|
return FAILURE;
|
|
}
|
|
}
|
|
php3_printf("%s\n", PHP_VERSION);
|
|
exit(1);
|
|
break;
|
|
case 'i':
|
|
if (!_cgi_started) {
|
|
if (php3_module_startup(CLS_C ELS_CC) == FAILURE || php3_request_startup(CLS_C ELS_CC) == FAILURE) {
|
|
return FAILURE;
|
|
}
|
|
}
|
|
_cgi_started=1;
|
|
php3_TreatHeaders();
|
|
_php3_info();
|
|
exit(1);
|
|
break;
|
|
case 's':
|
|
behavior=PHP_MODE_HIGHLIGHT;
|
|
break;
|
|
case 'n':
|
|
behavior=PHP_MODE_INDENT;
|
|
break;
|
|
case 'c':
|
|
GLOBAL(php3_ini_path) = strdup(optarg); /* intentional leak */
|
|
break;
|
|
case 'a':
|
|
#if SUPPORT_INTERACTIVE
|
|
printf("Interactive mode enabled\n\n");
|
|
interactive=1;
|
|
#else
|
|
printf("Interactive mode not supported!\n\n");
|
|
#endif
|
|
break;
|
|
case 'e':
|
|
CG(extended_info) = 1;
|
|
break;
|
|
case 'h':
|
|
case '?':
|
|
php3_noheader();
|
|
zend_output_startup();
|
|
_php3_usage(argv[0]);
|
|
exit(1);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
} /* not cgi */
|
|
|
|
#if SUPPORT_INTERACTIVE
|
|
EG(interactive) = interactive;
|
|
#endif
|
|
|
|
if (!_cgi_started) {
|
|
if (php3_module_startup(CLS_C ELS_CC) == FAILURE || php3_request_startup(CLS_C ELS_CC) == FAILURE) {
|
|
return FAILURE;
|
|
}
|
|
}
|
|
file_handle.filename = "-";
|
|
file_handle.type = ZEND_HANDLE_FP;
|
|
file_handle.handle.fp = stdin;
|
|
if (_cgi_filename) {
|
|
GLOBAL(request_info).filename = _cgi_filename;
|
|
}
|
|
|
|
php3_TreatHeaders();
|
|
|
|
if (!cgi) {
|
|
if (!GLOBAL(request_info).query_string) {
|
|
for (i = optind, len = 0; i < argc; i++)
|
|
len += strlen(argv[i]) + 1;
|
|
|
|
s = malloc(len + 1); /* leak - but only for command line version, so ok */
|
|
*s = '\0'; /* we are pretending it came from the environment */
|
|
for (i = optind, len = 0; i < argc; i++) {
|
|
strcat(s, argv[i]);
|
|
if (i < (argc - 1))
|
|
strcat(s, "+");
|
|
}
|
|
GLOBAL(request_info).query_string = s;
|
|
}
|
|
if (!GLOBAL(request_info).filename && argc > optind)
|
|
GLOBAL(request_info).filename = argv[optind];
|
|
}
|
|
/* If for some reason the CGI interface is not setting the
|
|
PATH_TRANSLATED correctly, request_info.filename is NULL.
|
|
We still call php3_fopen_for_parser, because if you set doc_root
|
|
or user_dir configuration directives, PATH_INFO is used to construct
|
|
the filename as a side effect of php3_fopen_for_parser.
|
|
*/
|
|
if (cgi || GLOBAL(request_info).filename) {
|
|
file_handle.filename = GLOBAL(request_info).filename;
|
|
file_handle.handle.fp = php3_fopen_for_parser();
|
|
}
|
|
|
|
if (cgi && !file_handle.handle.fp) {
|
|
PUTS("No input file specified.\n");
|
|
#if 0 /* this is here for debuging under windows */
|
|
if (argc) {
|
|
i = 0;
|
|
php3_printf("\nargc %d\n",argc);
|
|
while (i <= argc) {
|
|
php3_printf("%s\n",argv[i]);
|
|
i++;
|
|
}
|
|
}
|
|
#endif
|
|
php3_request_shutdown((void *) 0 _INLINE_TLS);
|
|
php3_module_shutdown(_INLINE_TLS_VOID);
|
|
return FAILURE;
|
|
} else if (file_handle.handle.fp && file_handle.handle.fp!=stdin) {
|
|
/* #!php support */
|
|
c = fgetc(file_handle.handle.fp);
|
|
if (c == '#') {
|
|
while (c != 10 && c != 13) {
|
|
c = fgetc(file_handle.handle.fp); /* skip to end of line */
|
|
}
|
|
CG(zend_lineno)++;
|
|
} else {
|
|
rewind(file_handle.handle.fp);
|
|
}
|
|
GLOBAL(initialized) |= INIT_SCANNER;
|
|
/* This shouldn't be necessary - if it is - it should move to Zend
|
|
* phprestart(GLOBAL(phpin));
|
|
*/
|
|
}
|
|
|
|
switch (behavior) {
|
|
case PHP_MODE_STANDARD:
|
|
php3_parse(&file_handle CLS_CC ELS_CC);
|
|
break;
|
|
case PHP_MODE_HIGHLIGHT: {
|
|
zend_syntax_highlighter_ini syntax_highlighter_ini;
|
|
|
|
if (open_file_for_scanning(&file_handle CLS_CC)==SUCCESS) {
|
|
php_get_highlight_struct(&syntax_highlighter_ini);
|
|
zend_highlight(&syntax_highlighter_ini);
|
|
fclose(file_handle.handle.fp);
|
|
}
|
|
return 0;
|
|
}
|
|
break;
|
|
case PHP_MODE_INDENT:
|
|
open_file_for_scanning(&file_handle CLS_CC);
|
|
zend_indent();
|
|
fclose(file_handle.handle.fp);
|
|
return 0;
|
|
break;
|
|
}
|
|
|
|
if (GLOBAL(initialized)) {
|
|
php3_header(); /* Make sure headers have been sent */
|
|
php3_request_shutdown((void *) 0 _INLINE_TLS);
|
|
php3_module_shutdown(_INLINE_TLS_VOID);
|
|
#ifdef THREAD_SAFE
|
|
yy_destroy_tls();
|
|
tls_shutdown();
|
|
tls_destroy();
|
|
#endif
|
|
return SUCCESS;
|
|
} else {
|
|
return FAILURE;
|
|
}
|
|
}
|
|
#endif /* CGI_BINARY */
|
|
|
|
|
|
#if APACHE
|
|
PHPAPI int apache_php3_module_main(request_rec * r, int fd, int display_source_mode)
|
|
{
|
|
zend_file_handle file_handle;
|
|
#ifdef ZTS
|
|
zend_compiler_globals cg;
|
|
zend_executor_globals eg;
|
|
zend_compiler_globals *compiler_globals=&cg;
|
|
zend_executor_globals *executor_globals=⪚
|
|
#endif
|
|
|
|
GLOBAL(php3_rqst) = r;
|
|
|
|
if (php3_request_startup(CLS_C ELS_CC) == FAILURE) {
|
|
return FAILURE;
|
|
}
|
|
php3_TreatHeaders();
|
|
file_handle.type = ZEND_HANDLE_FD;
|
|
file_handle.handle.fd = fd;
|
|
file_handle.filename = request_info.filename;
|
|
GLOBAL(initialized) |= INIT_SCANNER;
|
|
(void) php3_parse(&file_handle CLS_CC ELS_CC);
|
|
|
|
if (GLOBAL(initialized)) {
|
|
php3_header(); /* Make sure headers have been sent */
|
|
zend_end_ob_buffering(1);
|
|
}
|
|
return (OK);
|
|
}
|
|
#endif /* APACHE */
|
|
|
|
#if FHTTPD
|
|
|
|
char *get_pretokenized_name(void)
|
|
{
|
|
char *pretokenized_name = NULL;
|
|
|
|
if (GLOBAL(request_info).filename) {
|
|
int length = strlen(GLOBAL(request_info).filename);
|
|
|
|
if (length > (sizeof(".php3") - 1) && !strcmp(GLOBAL(request_info).filename + length - sizeof(".php3") + 1, ".php3")) {
|
|
pretokenized_name = (char *) emalloc(length + 2);
|
|
strcpy(pretokenized_name, GLOBAL(request_info).filename);
|
|
strcat(pretokenized_name, "p");
|
|
} else {
|
|
length += sizeof(".php3p");
|
|
pretokenized_name = (char *) emalloc(length + 1);
|
|
strcpy(pretokenized_name, GLOBAL(request_info).filename);
|
|
strcat(pretokenized_name, ".php3p");
|
|
}
|
|
} else {
|
|
pretokenized_name = estrdup("stdin.php3p");
|
|
}
|
|
return pretokenized_name;
|
|
}
|
|
|
|
|
|
void _php3_usage(char *progname)
|
|
{
|
|
fprintf(stderr,
|
|
"Usage: %s [options] [appname] [username] [hostname] [portname]\n"
|
|
"Options:\n"
|
|
" -d Daemon mode -- never attempt terminal I/O\n"
|
|
" -s Socket mode, fhttpd internal use only\n"
|
|
" -p Pipe mode, fhttpd internal use only\n"
|
|
" -u<mask> Set umask\n"
|
|
" -t<time> Idle timeout in seconds, 0 - disable\n"
|
|
" -S Display colour syntax highlighted source\n"
|
|
" -P Make and execute a pretokenized script\n"
|
|
" (.php3p file) or, if pretokenized script, newer\n"
|
|
" than original file exists, execute it instead\n"
|
|
" -E Execute a pretokenized (.php3p) script\n"
|
|
" -c<path> Look for php3.ini file in this directory\n"
|
|
" (must appear before any other options)\n"
|
|
" -v Version number\n"
|
|
" -h This help\n",
|
|
progname);
|
|
}
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
int c, i, processing_error;
|
|
FILE *in = NULL;
|
|
FILE *in2;
|
|
int preprocess_mode = PREPROCESS_NONE;
|
|
int argc1;
|
|
char **argv1;
|
|
int human = 1, fd2;
|
|
int i0 = 0, i1 = 0;
|
|
char *pn;
|
|
struct stat statbuf, pstatbuf;
|
|
#ifdef ZTS
|
|
zend_compiler_globals cg;
|
|
zend_executor_globals eg;
|
|
zend_compiler_globals *compiler_globals=&cg;
|
|
zend_executor_globals *executor_globals=⪚
|
|
#endif
|
|
|
|
#ifdef THREAD_SAFE
|
|
php3_globals_struct *php3_globals;
|
|
flex_globals *php_flex_gbl;
|
|
tls_startup();
|
|
tls_create();
|
|
php_flex_gbl = yy_init_tls();
|
|
php3_globals = TlsGetValue(TlsIndex);
|
|
|
|
if ((php3_globals == 0) && (GetLastError() != 0)) {
|
|
PUTS("TlsGetValue error\n");
|
|
return FAILURE;
|
|
}
|
|
#endif
|
|
|
|
#if HAVE_SETLOCALE
|
|
setlocale(LC_CTYPE, "");
|
|
#endif
|
|
|
|
if (php3_module_startup(CLS_C ELS_CC) == FAILURE) {
|
|
return FAILURE;
|
|
}
|
|
signal(SIGPIPE, SIG_IGN);
|
|
umask(077);
|
|
|
|
while ((c = getopt(argc, argv, "spdu:t:c:PESvh")) != -1) {
|
|
switch (c) {
|
|
case 'd':
|
|
human = 0;
|
|
break;
|
|
case 's':
|
|
i0 = 1;
|
|
break;
|
|
case 'p':
|
|
i1 = 1;
|
|
break;
|
|
case 'u':
|
|
if (*optarg == '0')
|
|
umask(strtoul(optarg, NULL, 8));
|
|
else
|
|
umask(strtoul(optarg, NULL, 10));
|
|
break;
|
|
case 't':
|
|
idle_timeout = atoi(optarg);
|
|
break;
|
|
case 'c':
|
|
GLOBAL(php3_ini_path) = strdup(optarg); /* intentional leak */
|
|
break;
|
|
case 'P': /* preprocess */
|
|
preprocess_mode = PREPROCESS_PREPROCESS;
|
|
break;
|
|
case 'E': /* execute preprocessed script */
|
|
preprocess_mode = PREPROCESS_EXECUTE;
|
|
break;
|
|
case 'S':
|
|
printf ("Not implemented yet\n");
|
|
break;
|
|
case 'v':
|
|
printf("%s\n", PHP_VERSION);
|
|
exit(1);
|
|
break;
|
|
case 'h':
|
|
case ':':
|
|
case '?':
|
|
_php3_usage(argv[0]);
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
argc1 = argc - optind;
|
|
argv1 = (char **) malloc(sizeof(char *) * (argc1 + 2));
|
|
if (!argv1)
|
|
return -1;
|
|
argv1 += 2;
|
|
for (i = optind; i < argc; i++)
|
|
argv1[i - optind] = argv[i];
|
|
|
|
if (i0) {
|
|
argv1--;
|
|
*argv1 = "-s";
|
|
argc1++;
|
|
} else {
|
|
if (i1) {
|
|
argv1--;
|
|
*argv1 = "-p";
|
|
argc1++;
|
|
}
|
|
}
|
|
argv1--;
|
|
argc1++;
|
|
*argv1 = *argv;
|
|
|
|
server = createserver();
|
|
if (!server)
|
|
return -1;
|
|
|
|
switch (servproc_init(server, human, argc1, argv1)) {
|
|
case 0:
|
|
break;
|
|
case APP_ERR_HUMAN:
|
|
_php3_usage(argv[0]);
|
|
exit(1);
|
|
break;
|
|
case APP_ERR_CONFIG:
|
|
fprintf(stderr, "%s: configuration error\n", server->app_progname);
|
|
exit(1);
|
|
break;
|
|
case APP_ERR_READ:
|
|
fprintf(stderr, "%s: read error\n", server->app_progname);
|
|
exit(1);
|
|
break;
|
|
case APP_ERR_HOSTNAME:
|
|
fprintf(stderr, "%s: can't resolve server hostname\n", server->app_progname);
|
|
exit(1);
|
|
break;
|
|
case APP_ERR_SOCKET:
|
|
fprintf(stderr, "%s: can't create socket\n", server->app_progname);
|
|
exit(1);
|
|
break;
|
|
case APP_ERR_CONNECT:
|
|
fprintf(stderr, "%s: can't connect\n", server->app_progname);
|
|
exit(1);
|
|
break;
|
|
case APP_ERR_APPCONNECT:
|
|
fprintf(stderr, "%s: connect error\n", server->app_progname);
|
|
exit(1);
|
|
break;
|
|
case APP_ERR_USER:
|
|
fprintf(stderr, "%s: login error\n", server->app_progname);
|
|
exit(1);
|
|
break;
|
|
case APP_ERR_PASSWORD:
|
|
fprintf(stderr, "%s: login error\n", server->app_progname);
|
|
exit(1);
|
|
break;
|
|
case APP_ERR_APPLICATION:
|
|
fprintf(stderr, "%s: application rejected by server\n", server->app_progname);
|
|
exit(1);
|
|
break;
|
|
case APP_ERR_INSANE:
|
|
case APP_ERR_DAEMON:
|
|
case APP_ERR_AUTH:
|
|
default:
|
|
if (server->infd < 0)
|
|
exit(1);
|
|
}
|
|
|
|
if (server->infd == 0 && server->outfd == 1) {
|
|
close(2);
|
|
fd2 = open("/dev/null", O_WRONLY);
|
|
if (fd2 != 2) {
|
|
dup2(fd2, 2);
|
|
close(fd2);
|
|
}
|
|
}
|
|
setcapabilities(server, APP_CAP_KEEPALIVE);
|
|
|
|
exit_status = 0;
|
|
while (!exit_status) {
|
|
processing_error = 0;
|
|
if (php3_request_startup(_INLINE_TLS_VOID) == FAILURE) {
|
|
processing_error = 1;
|
|
}
|
|
if (!processing_error) {
|
|
GLOBAL(phpin) = NULL;
|
|
GLOBAL(current_lineno) = 0;
|
|
|
|
php3_TreatHeaders();
|
|
|
|
in = php3_fopen_for_parser();
|
|
|
|
GLOBAL(php3_preprocess) = preprocess_mode;
|
|
|
|
if (!in) {
|
|
PUTS("No input file specified.\n");
|
|
php3_request_shutdown((void *) 0 _INLINE_TLS);
|
|
processing_error = 1;
|
|
} else {
|
|
if (GLOBAL(php3_preprocess) == PREPROCESS_PREPROCESS) {
|
|
pn = get_pretokenized_name();
|
|
if (pn) {
|
|
if (!stat(pn, &pstatbuf)
|
|
&& !fstat(fileno(in), &statbuf)
|
|
&& S_ISREG(pstatbuf.st_mode)
|
|
&& statbuf.st_mtime < pstatbuf.st_mtime) {
|
|
in2 = fopen(pn, "r");
|
|
if (in2) {
|
|
fclose(in);
|
|
in = in2;
|
|
GLOBAL(php3_preprocess) = PREPROCESS_EXECUTE;
|
|
}
|
|
}
|
|
efree(pn);
|
|
}
|
|
}
|
|
if (GLOBAL(php3_preprocess) != PREPROCESS_EXECUTE) {
|
|
/* #!php support */
|
|
c = fgetc(in);
|
|
if (c == '#') {
|
|
while (c != 10 && c != 13) {
|
|
c = fgetc(in); /* skip to end of line */
|
|
}
|
|
CG(phplineno)++;
|
|
} else {
|
|
rewind(in);
|
|
}
|
|
}
|
|
GLOBAL(phpin) = in;
|
|
GLOBAL(initialized) |= INIT_SCANNER;
|
|
phprestart(GLOBAL(phpin));
|
|
|
|
if (!processing_error) {
|
|
if (GLOBAL(php3_preprocess) == PREPROCESS_EXECUTE) {
|
|
if (tcm_load(&GLOBAL(token_cache_manager), GLOBAL(phpin))==FAILURE) {
|
|
/* should bail out on an error, don't know how to do it in fhttpd */
|
|
}
|
|
GLOBAL(php3_preprocess) = PREPROCESS_NONE;
|
|
}
|
|
if (GLOBAL(php3_preprocess)!=PREPROCESS_NONE) {
|
|
pval yylval;
|
|
|
|
while (phplex(&yylval)); /* create the token cache */
|
|
tcm_save(&GLOBAL(token_cache_manager));
|
|
seek_token(&GLOBAL(token_cache_manager), 0, NULL);
|
|
GLOBAL(php3_preprocess) = PREPROCESS_NONE;
|
|
}
|
|
php3_parse(GLOBAL(phpin) CLS_CC ELS_CC);
|
|
|
|
}
|
|
}
|
|
}
|
|
if (GLOBAL(initialized)) {
|
|
php3_header(); /* Make sure headers have been sent */
|
|
php3_request_shutdown((void *) 0 _INLINE_TLS);
|
|
}
|
|
}
|
|
php3_module_shutdown(_INLINE_TLS_VOID);
|
|
#ifdef THREAD_SAFE
|
|
if (GLOBAL(initialized)) {
|
|
yy_destroy_tls();
|
|
tls_shutdown();
|
|
tls_destroy();
|
|
}
|
|
#endif
|
|
return 0;
|
|
}
|
|
#endif /* FHTTPD */
|
|
|
|
#if USE_SAPI
|
|
|
|
PHPAPI int php3_sapi_main(struct sapi_request_info *sapi_info)
|
|
{
|
|
#if DEBUG
|
|
char logmessage[1024];
|
|
#endif
|
|
FILE *in = NULL;
|
|
int c;
|
|
YY_TLS_VARS;
|
|
TLS_VARS;
|
|
|
|
GLOBAL(php3_preprocess) = sapi_info->preprocess;
|
|
GLOBAL(php3_display_source) = sapi_info->display_source_mode;
|
|
GLOBAL(sapi_rqst) = sapi_info;
|
|
|
|
#if DEBUG
|
|
snprintf(logmessage,1024,"%d:php3_sapi_main: entry\n",GLOBAL(sapi_rqst)->scid);
|
|
OutputDebugString(logmessage);
|
|
#endif
|
|
|
|
/* if (php3_module_startup(php3_globals) == FAILURE) {
|
|
return FAILURE;
|
|
}*/
|
|
|
|
if (php3_request_startup(CLS_C ELS_CC) == FAILURE) {
|
|
#if DEBUG
|
|
snprintf(logmessage,1024,"%d:php3_sapi_main: request starup failed\n",GLOBAL(sapi_rqst)->scid);
|
|
OutputDebugString(logmessage);
|
|
#endif
|
|
return FAILURE;
|
|
}
|
|
if (sapi_info->preprocess == PREPROCESS_PREPROCESS || sapi_info->quiet_mode) {
|
|
php3_noheader();
|
|
}
|
|
if (sapi_info->info_only) {
|
|
_php3_info();
|
|
php3_request_shutdown((void *) GLOBAL(sapi_rqst), php3_globals);
|
|
/*php3_module_shutdown(php3_globals);*/
|
|
#if DEBUG
|
|
snprintf(logmessage,1024,"%d:php3_sapi_main: info_only\n",GLOBAL(sapi_rqst)->scid);
|
|
OutputDebugString(logmessage);
|
|
#endif
|
|
return (1);
|
|
}
|
|
/* if its not cgi, require that we have a filename now */
|
|
#if DEBUG
|
|
snprintf(logmessage,1024,"%d:php3_sapi_main: File: %s\n",GLOBAL(sapi_rqst)->scid,GLOBAL(sapi_rqst)->filename);
|
|
OutputDebugString(logmessage);
|
|
#endif
|
|
if (!sapi_info->cgi && !sapi_info->filename) {
|
|
php3_printf("No input file specified.\n");
|
|
php3_request_shutdown((void *) GLOBAL(sapi_rqst), php3_globals);
|
|
/*php3_module_shutdown(php3_globals);*/
|
|
#if DEBUG
|
|
snprintf(logmessage,1024,"%d:php3_sapi_main: No input file specified\n",GLOBAL(sapi_rqst)->scid);
|
|
OutputDebugString(logmessage);
|
|
#endif
|
|
return FAILURE;
|
|
}
|
|
/*
|
|
if request_info.filename is null and cgi, fopen_for_parser is responsible
|
|
request_info.filename will only be estrduped in fopen_for parser
|
|
if it is null at this point
|
|
*/
|
|
in = php3_fopen_for_parser();
|
|
|
|
if (sapi_info->cgi && !in) {
|
|
php3_printf("No input file specified for cgi.\n");
|
|
php3_request_shutdown((void *) GLOBAL(sapi_rqst), php3_globals);
|
|
/*php3_module_shutdown(php3_globals);*/
|
|
#if DEBUG
|
|
snprintf(logmessage,1024,"%d:php3_sapi_main: No input file specified for cgi.\n",GLOBAL(sapi_rqst)->scid);
|
|
OutputDebugString(logmessage);
|
|
#endif
|
|
return FAILURE;
|
|
}
|
|
if (sapi_info->cgi && in) {
|
|
/* #!php support */
|
|
c = fgetc(in);
|
|
if (c == '#') {
|
|
while (c != 10 && c != 13) {
|
|
c = fgetc(in); /* skip to end of line */
|
|
}
|
|
} else {
|
|
rewind(in);
|
|
}
|
|
}
|
|
if (in) {
|
|
GLOBAL(phpin) = in;
|
|
phprestart(GLOBAL(phpin));
|
|
GLOBAL(initialized) |= INIT_SCANNER;
|
|
}
|
|
if (sapi_info->display_source_mode) {
|
|
GLOBAL(php3_display_source) = 1;
|
|
PUTS("<html><head><title>Source for ");
|
|
PUTS(sapi_info->filename);
|
|
PUTS("</title></head><body bgcolor=\"");
|
|
PUTS(php3_ini.highlight_bg);
|
|
PUTS("\" text=\"");
|
|
PUTS(php3_ini.highlight_html);
|
|
PUTS("\">\n"); /* color: seashell */
|
|
}
|
|
if (sapi_info->display_source_mode && sapi_info->preprocess == PREPROCESS_PREPROCESS) {
|
|
php3_printf("Can't preprocess while displaying source.<br>\n");
|
|
return FAILURE;
|
|
}
|
|
if (sapi_info->preprocess == PREPROCESS_EXECUTE) {
|
|
tcm_load(&GLOBAL(token_cache_manager));
|
|
GLOBAL(php3_preprocess) = PREPROCESS_NONE;
|
|
}
|
|
if (sapi_info->preprocess==PREPROCESS_NONE) {
|
|
#if DEBUG
|
|
snprintf(logmessage,1024,"%d:php3_sapi_main: start php3_parse() file:%s\n",GLOBAL(sapi_rqst)->scid,GLOBAL(sapi_rqst)->filename);
|
|
OutputDebugString(logmessage);
|
|
#endif
|
|
php3_parse(GLOBAL(phpin) _INLINE_TLS);
|
|
#if DEBUG
|
|
snprintf(logmessage,1024,"%d:php3_sapi_main: done php3_parse()\n",GLOBAL(sapi_rqst)->scid);
|
|
OutputDebugString(logmessage);
|
|
#endif
|
|
} else {
|
|
pval yylval;
|
|
|
|
#if DEBUG
|
|
snprintf(logmessage,1024,"%d:php3_sapi_main: entering phplex()\n",GLOBAL(sapi_rqst)->scid);
|
|
OutputDebugString(logmessage);
|
|
#endif
|
|
#ifdef THREAD_SAFE
|
|
while (phplex(&yylval, php3_globals, php_gbl)); /* create the token cache */
|
|
#else
|
|
while (phplex(&yylval)); /* create the token cache */
|
|
#endif
|
|
#if DEBUG
|
|
snprintf(logmessage,1024,"%d:php3_sapi_main: done phplex()\n",GLOBAL(sapi_rqst)->scid);
|
|
OutputDebugString(logmessage);
|
|
#endif
|
|
tcm_save(&GLOBAL(token_cache_manager));
|
|
}
|
|
|
|
if (sapi_info->display_source_mode) {
|
|
php3_printf("\n</html>\n");
|
|
}
|
|
if (GLOBAL(initialized)) {
|
|
php3_header(); /* Make sure headers have been sent */
|
|
php3_request_shutdown((void *) GLOBAL(sapi_rqst), php3_globals);
|
|
/*php3_module_shutdown(php3_globals);*/
|
|
#if DEBUG
|
|
snprintf(logmessage,1024,"%d:php3_sapi_main: success!\n",GLOBAL(sapi_rqst)->scid);
|
|
OutputDebugString(logmessage);
|
|
#endif
|
|
return SUCCESS;
|
|
} else {
|
|
#if DEBUG
|
|
snprintf(logmessage,1024,"%d:php3_sapi_main: request not initialized!\n",GLOBAL(sapi_rqst)->scid);
|
|
OutputDebugString(logmessage);
|
|
#endif
|
|
return FAILURE;
|
|
}
|
|
}
|
|
#if WIN32|WINNT
|
|
extern int tls_create(void);
|
|
extern int tls_destroy(void);
|
|
extern int tls_startup(void);
|
|
extern int tls_shutdown(void);
|
|
extern flex_globals *yy_init_tls(void);
|
|
extern void yy_destroy_tls(void);
|
|
extern VOID ErrorExit(LPTSTR lpszMessage);
|
|
|
|
BOOL WINAPI DllMain(HANDLE hModule,
|
|
DWORD ul_reason_for_call,
|
|
LPVOID lpReserved)
|
|
{
|
|
php3_globals_struct *php3_globals;
|
|
#if DEBUG
|
|
OutputDebugString("PHP_Core DllMain Entry\n");
|
|
#endif
|
|
switch (ul_reason_for_call) {
|
|
case DLL_PROCESS_ATTACH:
|
|
/*
|
|
I should be loading ini vars here
|
|
and doing whatever true global inits
|
|
need to be done
|
|
*/
|
|
_fmode = _O_BINARY; /*sets default for file streams to binary */
|
|
/* make the stdio mode be binary */
|
|
setmode(_fileno(stdin), O_BINARY);
|
|
setmode(_fileno(stdout), O_BINARY);
|
|
setmode(_fileno(stderr), O_BINARY);
|
|
setlocale(LC_CTYPE, "");
|
|
|
|
CREATE_MUTEX(gLock, "GENERAL");
|
|
|
|
if (!tls_startup())
|
|
return 0;
|
|
if (!tls_create())
|
|
return 0;
|
|
php3_globals = TlsGetValue(TlsIndex);
|
|
yy_init_tls();
|
|
if (php3_config_ini_startup(_INLINE_TLS_VOID) == FAILURE) {
|
|
return 0;
|
|
}
|
|
if (php3_module_startup(php3_globals) == FAILURE) {
|
|
ErrorExit("module startup failed");
|
|
return 0;
|
|
}
|
|
|
|
#if DEBUG
|
|
OutputDebugString("PHP_Core DllMain Process Attached\n");
|
|
#endif
|
|
break;
|
|
case DLL_THREAD_ATTACH:
|
|
#if DEBUG
|
|
OutputDebugString("PHP_Core DllMain Thread Attach\n");
|
|
#endif
|
|
if (!tls_create())
|
|
return 0;
|
|
php3_globals = TlsGetValue(TlsIndex);
|
|
yy_init_tls();
|
|
if (php3_module_startup(php3_globals) == FAILURE) {
|
|
ErrorExit("module startup failed");
|
|
#if DEBUG
|
|
OutputDebugString("PHP_Core DllMain module startup failed\n");
|
|
#endif
|
|
return 0;
|
|
}
|
|
break;
|
|
case DLL_THREAD_DETACH:
|
|
#if DEBUG
|
|
OutputDebugString("PHP_Core DllMain Detache\n");
|
|
#endif
|
|
php3_globals = TlsGetValue(TlsIndex);
|
|
php3_module_shutdown(php3_globals);
|
|
if (!tls_destroy())
|
|
#if DEBUG
|
|
OutputDebugString("PHP_Core DllMain Detache Error tls_destroy\n");
|
|
#endif
|
|
return 0;
|
|
yy_destroy_tls();
|
|
break;
|
|
case DLL_PROCESS_DETACH:
|
|
/*
|
|
close down anything down in process_attach
|
|
*/
|
|
php3_globals = TlsGetValue(TlsIndex);
|
|
php3_module_shutdown(php3_globals);
|
|
|
|
php3_config_ini_shutdown(_INLINE_TLS_VOID);
|
|
|
|
if (!tls_destroy())
|
|
#if DEBUG
|
|
OutputDebugString("PHP_Core DllMain tls_destroy failed\n");
|
|
#endif
|
|
return 0;
|
|
if (!tls_shutdown())
|
|
#if DEBUG
|
|
OutputDebugString("PHP_Core DllMain tls_shutdown failed\n");
|
|
#endif
|
|
return 0;
|
|
yy_destroy_tls();
|
|
#if DEBUG
|
|
OutputDebugString("PHP_Core DllMain Process Detatched\n");
|
|
#endif
|
|
break;
|
|
}
|
|
#if DEBUG
|
|
OutputDebugString("PHP_Core DllMain Successful Exit\n");
|
|
#endif
|
|
return 1;
|
|
}
|
|
|
|
#endif
|
|
#endif
|
|
/*
|
|
* Local variables:
|
|
* tab-width: 4
|
|
* c-basic-offset: 4
|
|
* End:
|
|
*/
|