summaryrefslogtreecommitdiff
path: root/main
diff options
context:
space:
mode:
Diffstat (limited to 'main')
-rw-r--r--main/alloca.c505
-rw-r--r--main/config.w32.h294
-rw-r--r--main/configuration-parser.y415
-rw-r--r--main/configuration-scanner.l170
-rw-r--r--main/fopen_wrappers.c1000
-rw-r--r--main/fopen_wrappers.h90
-rw-r--r--main/internal_functions_registry.h57
-rw-r--r--main/logos.h805
-rw-r--r--main/main.c2222
-rw-r--r--main/php.h485
-rw-r--r--main/php3_compat.h80
-rw-r--r--main/php_ini.c148
-rw-r--r--main/php_ini.h48
-rw-r--r--main/php_version.h1
-rw-r--r--main/safe_mode.c156
-rw-r--r--main/safe_mode.h7
-rw-r--r--main/snprintf.c935
-rw-r--r--main/snprintf.h56
-rw-r--r--main/win95nt.h74
19 files changed, 7548 insertions, 0 deletions
diff --git a/main/alloca.c b/main/alloca.c
new file mode 100644
index 0000000000..aa512d9a1c
--- /dev/null
+++ b/main/alloca.c
@@ -0,0 +1,505 @@
+/* alloca.c -- allocate automatically reclaimed memory
+ (Mostly) portable public-domain implementation -- D A Gwyn
+
+ This implementation of the PWB library alloca function,
+ which is used to allocate space off the run-time stack so
+ that it is automatically reclaimed upon procedure exit,
+ was inspired by discussions with J. Q. Johnson of Cornell.
+ J.Otto Tennant <jot@cray.com> contributed the Cray support.
+
+ There are some preprocessor constants that can
+ be defined when compiling for your specific system, for
+ improved efficiency; however, the defaults should be okay.
+
+ The general concept of this implementation is to keep
+ track of all alloca-allocated blocks, and reclaim any
+ that are found to be deeper in the stack than the current
+ invocation. This heuristic does not reclaim storage as
+ soon as it becomes invalid, but it will do so eventually.
+
+ As a special case, alloca(0) reclaims storage without
+ allocating any. It is a good idea to use alloca(0) in
+ your main control loop, etc. to force garbage collection. */
+
+#include <config.h>
+
+#if !HAVE_ALLOCA
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#ifdef emacs
+#include "blockinput.h"
+#endif
+
+/* If compiling with GCC 2, this file's not needed. */
+#if !defined (__GNUC__) || __GNUC__ < 2
+
+/* If someone has defined alloca as a macro,
+ there must be some other way alloca is supposed to work. */
+#ifndef alloca
+
+#ifdef emacs
+#ifdef static
+/* actually, only want this if static is defined as ""
+ -- this is for usg, in which emacs must undefine static
+ in order to make unexec workable
+ */
+#ifndef STACK_DIRECTION
+you
+lose
+-- must know STACK_DIRECTION at compile-time
+#endif /* STACK_DIRECTION undefined */
+#endif /* static */
+#endif /* emacs */
+
+/* If your stack is a linked list of frames, you have to
+ provide an "address metric" ADDRESS_FUNCTION macro. */
+
+#if defined (CRAY) && defined (CRAY_STACKSEG_END)
+long i00afunc ();
+#define ADDRESS_FUNCTION(arg) (char *) i00afunc (&(arg))
+#else
+#define ADDRESS_FUNCTION(arg) &(arg)
+#endif
+
+#if __STDC__
+typedef void *pointer;
+#else
+typedef char *pointer;
+#endif
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+/* Different portions of Emacs need to call different versions of
+ malloc. The Emacs executable needs alloca to call xmalloc, because
+ ordinary malloc isn't protected from input signals. On the other
+ hand, the utilities in lib-src need alloca to call malloc; some of
+ them are very simple, and don't have an xmalloc routine.
+
+ Non-Emacs programs expect this to call use xmalloc.
+
+ Callers below should use malloc. */
+
+#ifndef emacs
+#define malloc xmalloc
+#endif
+extern pointer malloc ();
+
+/* Define STACK_DIRECTION if you know the direction of stack
+ growth for your system; otherwise it will be automatically
+ deduced at run-time.
+
+ STACK_DIRECTION > 0 => grows toward higher addresses
+ STACK_DIRECTION < 0 => grows toward lower addresses
+ STACK_DIRECTION = 0 => direction of growth unknown */
+
+#ifndef STACK_DIRECTION
+#define STACK_DIRECTION 0 /* Direction unknown. */
+#endif
+
+#if STACK_DIRECTION != 0
+
+#define STACK_DIR STACK_DIRECTION /* Known at compile-time. */
+
+#else /* STACK_DIRECTION == 0; need run-time code. */
+
+static int stack_dir; /* 1 or -1 once known. */
+#define STACK_DIR stack_dir
+
+static void
+find_stack_direction ()
+{
+ static char *addr = NULL; /* Address of first `dummy', once known. */
+ auto char dummy; /* To get stack address. */
+
+ if (addr == NULL)
+ { /* Initial entry. */
+ addr = ADDRESS_FUNCTION (dummy);
+
+ find_stack_direction (); /* Recurse once. */
+ }
+ else
+ {
+ /* Second entry. */
+ if (ADDRESS_FUNCTION (dummy) > addr)
+ stack_dir = 1; /* Stack grew upward. */
+ else
+ stack_dir = -1; /* Stack grew downward. */
+ }
+}
+
+#endif /* STACK_DIRECTION == 0 */
+
+/* An "alloca header" is used to:
+ (a) chain together all alloca'ed blocks;
+ (b) keep track of stack depth.
+
+ It is very important that sizeof(header) agree with malloc
+ alignment chunk size. The following default should work okay. */
+
+#ifndef ALIGN_SIZE
+#define ALIGN_SIZE sizeof(double)
+#endif
+
+typedef union hdr
+{
+ char align[ALIGN_SIZE]; /* To force sizeof(header). */
+ struct
+ {
+ union hdr *next; /* For chaining headers. */
+ char *deep; /* For stack depth measure. */
+ } h;
+} header;
+
+static header *last_alloca_header = NULL; /* -> last alloca header. */
+
+/* Return a pointer to at least SIZE bytes of storage,
+ which will be automatically reclaimed upon exit from
+ the procedure that called alloca. Originally, this space
+ was supposed to be taken from the current stack frame of the
+ caller, but that method cannot be made to work for some
+ implementations of C, for example under Gould's UTX/32. */
+
+pointer
+alloca (size)
+ unsigned size;
+{
+ auto char probe; /* Probes stack depth: */
+ register char *depth = ADDRESS_FUNCTION (probe);
+
+#if STACK_DIRECTION == 0
+ if (STACK_DIR == 0) /* Unknown growth direction. */
+ find_stack_direction ();
+#endif
+
+ /* Reclaim garbage, defined as all alloca'd storage that
+ was allocated from deeper in the stack than currently. */
+
+ {
+ register header *hp; /* Traverses linked list. */
+
+#ifdef emacs
+ BLOCK_INPUT;
+#endif
+
+ for (hp = last_alloca_header; hp != NULL;)
+ if ((STACK_DIR > 0 && hp->h.deep > depth)
+ || (STACK_DIR < 0 && hp->h.deep < depth))
+ {
+ register header *np = hp->h.next;
+
+ free ((pointer) hp); /* Collect garbage. */
+
+ hp = np; /* -> next header. */
+ }
+ else
+ break; /* Rest are not deeper. */
+
+ last_alloca_header = hp; /* -> last valid storage. */
+
+#ifdef emacs
+ UNBLOCK_INPUT;
+#endif
+ }
+
+ if (size == 0)
+ return NULL; /* No allocation required. */
+
+ /* Allocate combined header + user data storage. */
+
+ {
+ register pointer new = malloc (sizeof (header) + size);
+ /* Address of header. */
+
+ if (new == 0)
+ abort();
+
+ ((header *) new)->h.next = last_alloca_header;
+ ((header *) new)->h.deep = depth;
+
+ last_alloca_header = (header *) new;
+
+ /* User storage begins just after header. */
+
+ return (pointer) ((char *) new + sizeof (header));
+ }
+}
+
+#if defined (CRAY) && defined (CRAY_STACKSEG_END)
+
+#ifdef DEBUG_I00AFUNC
+#include <stdio.h>
+#endif
+
+#ifndef CRAY_STACK
+#define CRAY_STACK
+#ifndef CRAY2
+/* Stack structures for CRAY-1, CRAY X-MP, and CRAY Y-MP */
+struct stack_control_header
+ {
+ long shgrow:32; /* Number of times stack has grown. */
+ long shaseg:32; /* Size of increments to stack. */
+ long shhwm:32; /* High water mark of stack. */
+ long shsize:32; /* Current size of stack (all segments). */
+ };
+
+/* The stack segment linkage control information occurs at
+ the high-address end of a stack segment. (The stack
+ grows from low addresses to high addresses.) The initial
+ part of the stack segment linkage control information is
+ 0200 (octal) words. This provides for register storage
+ for the routine which overflows the stack. */
+
+struct stack_segment_linkage
+ {
+ long ss[0200]; /* 0200 overflow words. */
+ long sssize:32; /* Number of words in this segment. */
+ long ssbase:32; /* Offset to stack base. */
+ long:32;
+ long sspseg:32; /* Offset to linkage control of previous
+ segment of stack. */
+ long:32;
+ long sstcpt:32; /* Pointer to task common address block. */
+ long sscsnm; /* Private control structure number for
+ microtasking. */
+ long ssusr1; /* Reserved for user. */
+ long ssusr2; /* Reserved for user. */
+ long sstpid; /* Process ID for pid based multi-tasking. */
+ long ssgvup; /* Pointer to multitasking thread giveup. */
+ long sscray[7]; /* Reserved for Cray Research. */
+ long ssa0;
+ long ssa1;
+ long ssa2;
+ long ssa3;
+ long ssa4;
+ long ssa5;
+ long ssa6;
+ long ssa7;
+ long sss0;
+ long sss1;
+ long sss2;
+ long sss3;
+ long sss4;
+ long sss5;
+ long sss6;
+ long sss7;
+ };
+
+#else /* CRAY2 */
+/* The following structure defines the vector of words
+ returned by the STKSTAT library routine. */
+struct stk_stat
+ {
+ long now; /* Current total stack size. */
+ long maxc; /* Amount of contiguous space which would
+ be required to satisfy the maximum
+ stack demand to date. */
+ long high_water; /* Stack high-water mark. */
+ long overflows; /* Number of stack overflow ($STKOFEN) calls. */
+ long hits; /* Number of internal buffer hits. */
+ long extends; /* Number of block extensions. */
+ long stko_mallocs; /* Block allocations by $STKOFEN. */
+ long underflows; /* Number of stack underflow calls ($STKRETN). */
+ long stko_free; /* Number of deallocations by $STKRETN. */
+ long stkm_free; /* Number of deallocations by $STKMRET. */
+ long segments; /* Current number of stack segments. */
+ long maxs; /* Maximum number of stack segments so far. */
+ long pad_size; /* Stack pad size. */
+ long current_address; /* Current stack segment address. */
+ long current_size; /* Current stack segment size. This
+ number is actually corrupted by STKSTAT to
+ include the fifteen word trailer area. */
+ long initial_address; /* Address of initial segment. */
+ long initial_size; /* Size of initial segment. */
+ };
+
+/* The following structure describes the data structure which trails
+ any stack segment. I think that the description in 'asdef' is
+ out of date. I only describe the parts that I am sure about. */
+
+struct stk_trailer
+ {
+ long this_address; /* Address of this block. */
+ long this_size; /* Size of this block (does not include
+ this trailer). */
+ long unknown2;
+ long unknown3;
+ long link; /* Address of trailer block of previous
+ segment. */
+ long unknown5;
+ long unknown6;
+ long unknown7;
+ long unknown8;
+ long unknown9;
+ long unknown10;
+ long unknown11;
+ long unknown12;
+ long unknown13;
+ long unknown14;
+ };
+
+#endif /* CRAY2 */
+#endif /* not CRAY_STACK */
+
+#ifdef CRAY2
+/* Determine a "stack measure" for an arbitrary ADDRESS.
+ I doubt that "lint" will like this much. */
+
+static long
+i00afunc (long *address)
+{
+ struct stk_stat status;
+ struct stk_trailer *trailer;
+ long *block, size;
+ long result = 0;
+
+ /* We want to iterate through all of the segments. The first
+ step is to get the stack status structure. We could do this
+ more quickly and more directly, perhaps, by referencing the
+ $LM00 common block, but I know that this works. */
+
+ STKSTAT (&status);
+
+ /* Set up the iteration. */
+
+ trailer = (struct stk_trailer *) (status.current_address
+ + status.current_size
+ - 15);
+
+ /* There must be at least one stack segment. Therefore it is
+ a fatal error if "trailer" is null. */
+
+ if (trailer == 0)
+ abort ();
+
+ /* Discard segments that do not contain our argument address. */
+
+ while (trailer != 0)
+ {
+ block = (long *) trailer->this_address;
+ size = trailer->this_size;
+ if (block == 0 || size == 0)
+ abort ();
+ trailer = (struct stk_trailer *) trailer->link;
+ if ((block <= address) && (address < (block + size)))
+ break;
+ }
+
+ /* Set the result to the offset in this segment and add the sizes
+ of all predecessor segments. */
+
+ result = address - block;
+
+ if (trailer == 0)
+ {
+ return result;
+ }
+
+ do
+ {
+ if (trailer->this_size <= 0)
+ abort ();
+ result += trailer->this_size;
+ trailer = (struct stk_trailer *) trailer->link;
+ }
+ while (trailer != 0);
+
+ /* We are done. Note that if you present a bogus address (one
+ not in any segment), you will get a different number back, formed
+ from subtracting the address of the first block. This is probably
+ not what you want. */
+
+ return (result);
+}
+
+#else /* not CRAY2 */
+/* Stack address function for a CRAY-1, CRAY X-MP, or CRAY Y-MP.
+ Determine the number of the cell within the stack,
+ given the address of the cell. The purpose of this
+ routine is to linearize, in some sense, stack addresses
+ for alloca. */
+
+static long
+i00afunc (long address)
+{
+ long stkl = 0;
+
+ long size, pseg, this_segment, stack;
+ long result = 0;
+
+ struct stack_segment_linkage *ssptr;
+
+ /* Register B67 contains the address of the end of the
+ current stack segment. If you (as a subprogram) store
+ your registers on the stack and find that you are past
+ the contents of B67, you have overflowed the segment.
+
+ B67 also points to the stack segment linkage control
+ area, which is what we are really interested in. */
+
+ stkl = CRAY_STACKSEG_END ();
+ ssptr = (struct stack_segment_linkage *) stkl;
+
+ /* If one subtracts 'size' from the end of the segment,
+ one has the address of the first word of the segment.
+
+ If this is not the first segment, 'pseg' will be
+ nonzero. */
+
+ pseg = ssptr->sspseg;
+ size = ssptr->sssize;
+
+ this_segment = stkl - size;
+
+ /* It is possible that calling this routine itself caused
+ a stack overflow. Discard stack segments which do not
+ contain the target address. */
+
+ while (!(this_segment <= address && address <= stkl))
+ {
+#ifdef DEBUG_I00AFUNC
+ fprintf (stderr, "%011o %011o %011o\n", this_segment, address, stkl);
+#endif
+ if (pseg == 0)
+ break;
+ stkl = stkl - pseg;
+ ssptr = (struct stack_segment_linkage *) stkl;
+ size = ssptr->sssize;
+ pseg = ssptr->sspseg;
+ this_segment = stkl - size;
+ }
+
+ result = address - this_segment;
+
+ /* If you subtract pseg from the current end of the stack,
+ you get the address of the previous stack segment's end.
+ This seems a little convoluted to me, but I'll bet you save
+ a cycle somewhere. */
+
+ while (pseg != 0)
+ {
+#ifdef DEBUG_I00AFUNC
+ fprintf (stderr, "%011o %011o\n", pseg, size);
+#endif
+ stkl = stkl - pseg;
+ ssptr = (struct stack_segment_linkage *) stkl;
+ size = ssptr->sssize;
+ pseg = ssptr->sspseg;
+ result += size;
+ }
+ return (result);
+}
+
+#endif /* not CRAY2 */
+#endif /* CRAY */
+
+#endif /* no alloca */
+#endif /* not GCC version 2 */
+#endif /* HAVE_ALLOCA */
diff --git a/main/config.w32.h b/main/config.w32.h
new file mode 100644
index 0000000000..141287ae55
--- /dev/null
+++ b/main/config.w32.h
@@ -0,0 +1,294 @@
+/* config.w32.h. Configure file for win32 platforms */
+/* tested only with MS Visual C++ V5 */
+
+
+/* if you have resolv.lib and lib44bsd95.lib you can compile the extra
+ dns functions located in dns.c. Set this to 1. add resolv.lib and
+ lib33bsd95.lib to the project settings, and add the path to the
+ bind include directory to the preprocessor settings. These libs
+ are availabe in the ntbind distribution */
+#define HAVE_BINDLIB 1
+
+/* set to enable bcmath */
+#define WITH_BCMATH 1
+/* should be added to runtime config*/
+#define PHP3_URL_FOPEN 1
+
+/* ----------------------------------------------------------------
+ The following are defaults for run-time configuration
+ ---------------------------------------------------------------*/
+
+#define PHP_SAFE_MODE 0
+#define MAGIC_QUOTES 0
+/* This is the default configuration file to read */
+#define CONFIGURATION_FILE_PATH "php3.ini"
+#define USE_CONFIG_FILE 1
+
+/* Undefine if you want stricter XML/SGML compliance by default */
+/* this disables "<?expression?>" and "<?=expression?>" */
+#define DEFAULT_SHORT_OPEN_TAG 1
+
+#define PHP_TRACK_VARS 1
+
+/* ----------------------------------------------------------------
+ The following defines are for those modules which require
+ external libraries to compile. These will be removed from
+ here in a future beta, as these modules will be moved out to dll's
+ ---------------------------------------------------------------*/
+#if !defined(COMPILE_DL)
+#define HAVE_SNMP 0
+#define HAVE_MYSQL 0
+# define HAVE_ERRMSG_H 0 /*needed for mysql 3.21.17 and up*/
+#define HAVE_LDAP 0
+#define DBASE 0
+#define NDBM 0
+#define GDBM 0
+#define BSD2 0
+#define HAVE_CRYPT 0
+#define HAVE_ORACLE 0
+#define HAVE_ADABAS 0
+#define HAVE_SOLID 0
+#define HAVE_MSQL 0
+#define HAVE_PGSQL 0
+#define HAVE_SYBASE 0
+#define HAVE_LIBGD 0
+#define HAVE_FILEPRO 0
+#define HAVE_ZLIB 0
+#endif
+/* ----------------------------------------------------------------
+ The following may or may not be (or need to be) ported to the
+ windows environment.
+ ---------------------------------------------------------------*/
+
+/* Define if you have the link function. */
+#define HAVE_LINK 0
+
+/* Define if you have the lockf function. */
+/* #undef HAVE_LOCKF */
+
+/* Define if you have the lrand48 function. */
+/* #undef HAVE_LRAND48 */
+
+/* Define if you have the srand48 function. */
+/* #undef HAVE_SRAND48 */
+
+/* Define if you have the symlink function. */
+#define HAVE_SYMLINK 0
+
+/* Define if you have the usleep function. */
+#define HAVE_USLEEP 1
+
+#define NEED_ISBLANK 1
+/* ----------------------------------------------------------------
+ The following may be changed and played with right now, but
+ will move to the "don't touch" list below eventualy.
+ ---------------------------------------------------------------*/
+
+/*#define APACHE 0 defined in preprocessor section*/
+
+
+/* ----------------------------------------------------------------
+ The following should never need to be played with
+ Functions defined to 0 or remarked out are either already
+ handled by the standard VC libraries, or are no longer needed, or
+ simply will/can not be ported.
+
+ DONT TOUCH!!!!! Unless you realy know what your messing with!
+ ---------------------------------------------------------------*/
+
+#define DISCARD_PATH 1
+#define HAVE_SETITIMER 0
+#define HAVE_IODBC 0 /*getting rid of old odbc*/
+#define HAVE_UODBC 0
+#define HAVE_LIBDL 1
+#define HAVE_SENDMAIL 1
+#define HAVE_GETTIMEOFDAY 1
+#define HAVE_PUTENV 1
+#define HAVE_LIMITS_H 1
+
+#define HAVE_TZSET 1
+/* Define if you have the flock function. */
+#define HAVE_FLOCK 1
+
+/* Define if using alloca.c. */
+/* #undef C_ALLOCA */
+
+/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems.
+ This function is required for alloca.c support on those systems. */
+/* #undef CRAY_STACKSEG_END */
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+/* #undef gid_t */
+
+/* Define if you have alloca, as a function or macro. */
+#define HAVE_ALLOCA 1
+
+/* Define if you have <alloca.h> and it should be used (not on Ultrix). */
+/* #undef HAVE_ALLOCA_H */
+
+/* Define if you have <sys/time.h> */
+#define HAVE_SYS_TIME_H 0
+
+/* Define if you have <signal.h> */
+#define HAVE_SIGNAL_H 1
+
+/* Define if you don't have vprintf but do have _doprnt. */
+/* #undef HAVE_DOPRNT */
+
+/* Define if your struct stat has st_blksize. */
+#define HAVE_ST_BLKSIZE 0
+
+/* Define if your struct stat has st_blocks. */
+#define HAVE_ST_BLOCKS 0
+
+/* Define if your struct stat has st_rdev. */
+#define HAVE_ST_RDEV 1
+
+/* Define if utime(file, NULL) sets file's timestamp to the present. */
+#define HAVE_UTIME_NULL 1
+
+/* Define if you have the vprintf function. */
+#define HAVE_VPRINTF 1
+
+/* Define to `unsigned' if <sys/types.h> doesn't define. */
+/* #undef size_t */
+
+/* If using the C implementation of alloca, define if you know the
+ direction of stack growth for your system; otherwise it will be
+ automatically deduced at run-time.
+ STACK_DIRECTION > 0 => grows toward higher addresses
+ STACK_DIRECTION < 0 => grows toward lower addresses
+ STACK_DIRECTION = 0 => direction of growth unknown
+ */
+/* #undef STACK_DIRECTION */
+
+/* Define if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Define if your <sys/time.h> declares struct tm. */
+/* #undef TM_IN_SYS_TIME */
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+/* #undef uid_t */
+
+/* Define both of these if you want the bundled REGEX library */
+#define REGEX 1
+#define HSREGEX 1
+
+/* Define if you have the gcvt function. */
+#define HAVE_GCVT 1
+
+/* Define if you have the getlogin function. */
+#define HAVE_GETLOGIN 1
+
+/* Define if you have the gettimeofday function. */
+#define HAVE_GETTIMEOFDAY 1
+
+/* Define if you have the memcpy function. */
+#define HAVE_MEMCPY 1
+
+/* Define if you have the memmove function. */
+#define HAVE_MEMMOVE 1
+
+/* Define if you have the putenv function. */
+#define HAVE_PUTENV 1
+
+/* Define if you have the regcomp function. */
+#define HAVE_REGCOMP 1
+
+/* Define if you have the setlocale function. */
+#define HAVE_SETLOCALE 1
+
+/* Define if you have the setvbuf function. */
+#ifndef HAVE_BINDLIB
+#define HAVE_SETVBUF 1
+#endif
+
+/* Define if you have the snprintf function. */
+#define HAVE_SNPRINTF 1
+#define HAVE_VSNPRINTF 1
+/* Define if you have the strcasecmp function. */
+#define HAVE_STRCASECMP 1
+
+/* Define if you have the strdup function. */
+#define HAVE_STRDUP 1
+
+/* Define if you have the strerror function. */
+#define HAVE_STRERROR 1
+
+/* Define if you have the strstr function. */
+#define HAVE_STRSTR 1
+
+/* Define if you have the tempnam function. */
+#define HAVE_TEMPNAM 1
+
+/* Define if you have the utime function. */
+#define HAVE_UTIME 1
+
+/* Define if you have the <crypt.h> header file. */
+/* #undef HAVE_CRYPT_H */
+
+/* Define if you have the <dirent.h> header file. */
+#define HAVE_DIRENT_H 0
+
+/* Define if you have the <fcntl.h> header file. */
+#define HAVE_FCNTL_H 1
+
+/* Define if you have the <grp.h> header file. */
+#define HAVE_GRP_H 0
+
+/* Define if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define if you have the <ndir.h> header file. */
+/* #undef HAVE_NDIR_H */
+
+/* Define if you have the <pwd.h> header file. */
+#define HAVE_PWD_H 1
+
+/* Define if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define if you have the <sys/dir.h> header file. */
+/* #undef HAVE_SYS_DIR_H */
+
+/* Define if you have the <sys/file.h> header file. */
+#define HAVE_SYS_FILE_H 1
+
+/* Define if you have the <sys/ndir.h> header file. */
+/* #undef HAVE_SYS_NDIR_H */
+
+/* Define if you have the <sys/socket.h> header file. */
+#define HAVE_SYS_SOCKET_H 0
+
+/* Define if you have the <sys/wait.h> header file. */
+#define HAVE_SYS_WAIT_H 0
+
+/* Define if you have the <syslog.h> header file. */
+#define HAVE_SYSLOG_H 1
+
+/* Define if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 0
+
+/* Define if you have the crypt library (-lcrypt). */
+/* #undef HAVE_LIBCRYPT 0 */
+
+/* Define if you have the dl library (-ldl). */
+#define HAVE_LIBDL 1
+
+/* Define if you have the m library (-lm). */
+#define HAVE_LIBM 1
+
+/* Define if you have the nsl library (-lnsl). */
+/* #undef HAVE_LIBNSL */
+
+/* Define if you have the socket library (-lsocket). */
+/* #undef HAVE_LIBSOCKET */
+
+/* Define if you have the cuserid function. */
+#define HAVE_CUSERID 0
+
+/* Define if you have the rint function. */
+#undef HAVE_RINT
+
+#define HAVE_STRFTIME 1
diff --git a/main/configuration-parser.y b/main/configuration-parser.y
new file mode 100644
index 0000000000..9a6e77470b
--- /dev/null
+++ b/main/configuration-parser.y
@@ -0,0 +1,415 @@
+%{
+/*
+ +----------------------------------------------------------------------+
+ | 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: Zeev Suraski <zeev@zend.com> |
+ +----------------------------------------------------------------------+
+ */
+
+
+
+/* $Id$ */
+
+#define DEBUG_CFG_PARSER 1
+#include "php.h"
+#include "functions/dl.h"
+#include "functions/file.h"
+#include "functions/php3_browscap.h"
+#include "zend_extensions.h"
+
+#if WIN32
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <winbase.h>
+#include "win32/wfile.h"
+#endif
+
+#undef YYSTYPE
+#define YYSTYPE pval
+
+#define PARSING_MODE_CFG 0
+#define PARSING_MODE_BROWSCAP 1
+
+static HashTable configuration_hash;
+#ifndef THREAD_SAFE
+extern HashTable browser_hash;
+extern char *php3_ini_path;
+#endif
+static HashTable *active__php3_hash_table;
+static pval *current_section;
+static char *currently_parsed_filename;
+
+static int parsing_mode;
+
+pval yylval;
+
+extern int cfglex(pval *cfglval);
+extern FILE *cfgin;
+extern int cfglineno;
+extern void init_cfg_scanner(void);
+
+pval *cfg_get_entry(char *name, uint name_length)
+{
+ pval *tmp;
+
+ if (_php3_hash_find(&configuration_hash, name, name_length, (void **) &tmp)==SUCCESS) {
+ return tmp;
+ } else {
+ return NULL;
+ }
+}
+
+
+PHPAPI int cfg_get_long(char *varname,long *result)
+{
+ pval *tmp,var;
+
+ if (_php3_hash_find(&configuration_hash,varname,strlen(varname)+1,(void **) &tmp)==FAILURE) {
+ *result=(long)NULL;
+ return FAILURE;
+ }
+ var = *tmp;
+ pval_copy_constructor(&var);
+ convert_to_long(&var);
+ *result = var.value.lval;
+ return SUCCESS;
+}
+
+
+PHPAPI int cfg_get_double(char *varname,double *result)
+{
+ pval *tmp,var;
+
+ if (_php3_hash_find(&configuration_hash,varname,strlen(varname)+1,(void **) &tmp)==FAILURE) {
+ *result=(double)0;
+ return FAILURE;
+ }
+ var = *tmp;
+ pval_copy_constructor(&var);
+ convert_to_double(&var);
+ *result = var.value.dval;
+ return SUCCESS;
+}
+
+
+PHPAPI int cfg_get_string(char *varname, char **result)
+{
+ pval *tmp;
+
+ if (_php3_hash_find(&configuration_hash,varname,strlen(varname)+1,(void **) &tmp)==FAILURE) {
+ *result=NULL;
+ return FAILURE;
+ }
+ *result = tmp->value.str.val;
+ return SUCCESS;
+}
+
+
+static void yyerror(char *str)
+{
+ fprintf(stderr,"PHP: Error parsing %s on line %d\n",currently_parsed_filename,cfglineno);
+}
+
+
+static void pvalue_config_destructor(pval *pvalue)
+{
+ if (pvalue->type == IS_STRING && pvalue->value.str.val != empty_string) {
+ free(pvalue->value.str.val);
+ }
+}
+
+
+static void pvalue_browscap_destructor(pval *pvalue)
+{
+ if (pvalue->type == IS_OBJECT || pvalue->type == IS_ARRAY) {
+ _php3_hash_destroy(pvalue->value.ht);
+ free(pvalue->value.ht);
+ }
+}
+
+
+int php3_init_config(void)
+{
+ TLS_VARS;
+
+ if (_php3_hash_init(&configuration_hash, 0, NULL, (void (*)(void *))pvalue_config_destructor, 1)==FAILURE) {
+ return FAILURE;
+ }
+
+#if USE_CONFIG_FILE
+ {
+ char *env_location,*default_location,*php_ini_path;
+ int safe_mode_state = php3_ini.safe_mode;
+ char *opened_path;
+ int free_default_location=0;
+
+ env_location = getenv("PHPRC");
+ if (!env_location) {
+ env_location="";
+ }
+#if WIN32|WINNT
+ {
+ if (GLOBAL(php3_ini_path)) {
+ default_location = GLOBAL(php3_ini_path);
+ } else {
+ default_location = (char *) malloc(512);
+
+ if (!GetWindowsDirectory(default_location,255)) {
+ default_location[0]=0;
+ }
+ free_default_location=1;
+ }
+ }
+#else
+ if (!GLOBAL(php3_ini_path)) {
+ default_location = CONFIGURATION_FILE_PATH;
+ } else {
+ default_location = GLOBAL(php3_ini_path);
+ }
+#endif
+
+/* build a path */
+ php_ini_path = (char *) malloc(sizeof(".")+strlen(env_location)+strlen(default_location)+2+1);
+
+ if (!GLOBAL(php3_ini_path)) {
+#if WIN32|WINNT
+ sprintf(php_ini_path,".;%s;%s",env_location,default_location);
+#else
+ sprintf(php_ini_path,".:%s:%s",env_location,default_location);
+#endif
+ } else {
+ /* if path was set via -c flag, only look there */
+ strcpy(php_ini_path,default_location);
+ }
+ php3_ini.safe_mode = 0;
+ cfgin = php3_fopen_with_path("php3.ini","r",php_ini_path,&opened_path);
+ free(php_ini_path);
+ if (free_default_location) {
+ free(default_location);
+ }
+ php3_ini.safe_mode = safe_mode_state;
+
+ if (!cfgin) {
+# if WIN32|WINNT
+ return FAILURE;
+# else
+ return SUCCESS; /* having no configuration file is ok */
+# endif
+ }
+
+ if (opened_path) {
+ pval tmp;
+
+ tmp.value.str.val = opened_path;
+ tmp.value.str.len = strlen(opened_path);
+ tmp.type = IS_STRING;
+ _php3_hash_update(&configuration_hash,"cfg_file_path",sizeof("cfg_file_path"),(void *) &tmp,sizeof(pval),NULL);
+#if 0
+ php3_printf("INI file opened at '%s'\n",opened_path);
+#endif
+ }
+
+ init_cfg_scanner();
+ active__php3_hash_table = &configuration_hash;
+ parsing_mode = PARSING_MODE_CFG;
+ currently_parsed_filename = "php3.ini";
+ yyparse();
+ fclose(cfgin);
+ }
+
+#endif
+
+ return SUCCESS;
+}
+
+
+int php3_minit_browscap(INIT_FUNC_ARGS)
+{
+ TLS_VARS;
+
+ if (php3_ini.browscap) {
+ if (_php3_hash_init(&GLOBAL(browser_hash), 0, NULL, (void (*)(void *))pvalue_browscap_destructor, 1)==FAILURE) {
+ return FAILURE;
+ }
+
+ cfgin = fopen(php3_ini.browscap,"r");
+ if (!cfgin) {
+ php3_error(E_WARNING,"Cannot open '%s' for reading",php3_ini.browscap);
+ return FAILURE;
+ }
+ init_cfg_scanner();
+ active__php3_hash_table = &GLOBAL(browser_hash);
+ parsing_mode = PARSING_MODE_BROWSCAP;
+ currently_parsed_filename = php3_ini.browscap;
+ yyparse();
+ fclose(cfgin);
+ }
+
+ return SUCCESS;
+}
+
+
+int php3_shutdown_config(void)
+{
+ _php3_hash_destroy(&configuration_hash);
+ return SUCCESS;
+}
+
+
+int php3_mshutdown_browscap(void)
+{
+ TLS_VARS;
+
+ if (php3_ini.browscap) {
+ _php3_hash_destroy(&GLOBAL(browser_hash));
+ }
+ return SUCCESS;
+}
+
+
+static void convert_browscap_pattern(pval *pattern)
+{
+ register int i,j;
+ char *t;
+
+ for (i=0; i<pattern->value.str.len; i++) {
+ if (pattern->value.str.val[i]=='*' || pattern->value.str.val[i]=='?') {
+ break;
+ }
+ }
+
+ if (i==pattern->value.str.len) { /* no wildcards */
+ return;
+ }
+
+ t = (char *) malloc(pattern->value.str.len*2);
+
+ for (i=0,j=0; i<pattern->value.str.len; i++,j++) {
+ switch (pattern->value.str.val[i]) {
+ case '?':
+ t[j] = '.';
+ break;
+ case '*':
+ t[j++] = '.';
+ t[j] = '*';
+ break;
+ case '.':
+ t[j++] = '\\';
+ t[j] = '.';
+ break;
+ default:
+ t[j] = pattern->value.str.val[i];
+ break;
+ }
+ }
+ t[j]=0;
+ free(pattern->value.str.val);
+ pattern->value.str.val = t;
+ pattern->value.str.len = j;
+ return;
+}
+
+%}
+
+%pure_parser
+%token TC_STRING
+%token TC_ENCAPSULATED_STRING
+%token SECTION
+%token CFG_TRUE
+%token CFG_FALSE
+%token EXTENSION
+%token T_ZEND_EXTENSION
+
+%%
+
+statement_list:
+ statement_list statement
+ | /* empty */
+;
+
+statement:
+ string '=' string_or_value {
+#if 0
+ printf("'%s' = '%s'\n",$1.value.str.val,$3.value.str.val);
+#endif
+ $3.type = IS_STRING;
+ if (parsing_mode==PARSING_MODE_CFG) {
+ _php3_hash_update(active__php3_hash_table, $1.value.str.val, $1.value.str.len+1, &$3, sizeof(pval), NULL);
+ } else if (parsing_mode==PARSING_MODE_BROWSCAP) {
+ php3_str_tolower($1.value.str.val,$1.value.str.len);
+ _php3_hash_update(current_section->value.ht, $1.value.str.val, $1.value.str.len+1, &$3, sizeof(pval), NULL);
+ }
+ free($1.value.str.val);
+ }
+ | string { free($1.value.str.val); }
+ | EXTENSION '=' string {
+ pval dummy;
+#if 0
+ printf("Loading '%s'\n",$3.value.str.val);
+#endif
+
+ php3_dl(&$3,MODULE_PERSISTENT,&dummy);
+ }
+ | T_ZEND_EXTENSION '=' string { zend_load_extension($3.value.str.val); free($3.value.str.val); }
+ | SECTION {
+ if (parsing_mode==PARSING_MODE_BROWSCAP) {
+ pval tmp;
+
+ /*printf("'%s' (%d)\n",$1.value.str.val,$1.value.str.len+1);*/
+ tmp.value.ht = (HashTable *) malloc(sizeof(HashTable));
+ _php3_hash_init(tmp.value.ht, 0, NULL, (void (*)(void *))pvalue_config_destructor, 1);
+ tmp.type = IS_OBJECT;
+ _php3_hash_update(active__php3_hash_table, $1.value.str.val, $1.value.str.len+1, (void *) &tmp, sizeof(pval), (void **) &current_section);
+ tmp.value.str.val = php3_strndup($1.value.str.val,$1.value.str.len);
+ tmp.value.str.len = $1.value.str.len;
+ tmp.type = IS_STRING;
+ convert_browscap_pattern(&tmp);
+ _php3_hash_update(current_section->value.ht,"browser_name_pattern",sizeof("browser_name_pattern"),(void *) &tmp, sizeof(pval), NULL);
+ }
+ free($1.value.str.val);
+ }
+ | '\n'
+;
+
+
+string:
+ TC_STRING { $$ = $1; }
+ | TC_ENCAPSULATED_STRING { $$ = $1; }
+;
+
+string_or_value:
+ string { $$ = $1; }
+ | CFG_TRUE { $$ = $1; }
+ | CFG_FALSE { $$ = $1; }
+ | '\n' { $$.value.str.val = strdup(""); $$.value.str.len=0; $$.type = IS_STRING; }
+;
+
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ */
diff --git a/main/configuration-scanner.l b/main/configuration-scanner.l
new file mode 100644
index 0000000000..096a4a8248
--- /dev/null
+++ b/main/configuration-scanner.l
@@ -0,0 +1,170 @@
+%{
+
+/*
+ +----------------------------------------------------------------------+
+ | 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 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. |
+ | |
+ | 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 the GNU General Public License |
+ | along with this program; if not, write to the Free Software |
+ | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
+ +----------------------------------------------------------------------+
+ | Authors: Zeev Suraski <zeev@zend.com> |
+ +----------------------------------------------------------------------+
+*/
+
+
+#include "php.h"
+#include "configuration-parser.h"
+
+#undef YYSTYPE
+#define YYSTYPE pval
+
+#define YY_DECL cfglex(pval *cfglval)
+
+
+void init_cfg_scanner()
+{
+ cfglineno=1;
+}
+
+
+%}
+
+%option noyywrap
+%option yylineno
+
+%%
+
+<INITIAL>"extension" {
+#if 0
+ printf("found extension\n");
+#endif
+ return EXTENSION;
+}
+
+
+<INITIAL>"zend_extension" {
+ return T_ZEND_EXTENSION;
+}
+
+<INITIAL>[ ]*("true"|"on"|"yes")[ ]* {
+ cfglval->value.str.val = php3_strndup("1",1);
+ cfglval->value.str.len = 1;
+ cfglval->type = IS_STRING;
+ return CFG_TRUE;
+}
+
+
+<INITIAL>[ ]*("false"|"off"|"no")[ ]* {
+ cfglval->value.str.val = php3_strndup("",0);
+ cfglval->value.str.len = 0;
+ cfglval->type = IS_STRING;
+ return CFG_FALSE;
+}
+
+
+<INITIAL>[[][^[]+[\]]([\n]?|"\r\n"?) {
+ /* SECTION */
+
+ /* eat trailng ] */
+ while (yyleng>0 && (yytext[yyleng-1]=='\n' || yytext[yyleng-1]=='\r' || yytext[yyleng-1]==']')) {
+ yyleng--;
+ yytext[yyleng]=0;
+ }
+
+ /* eat leading [ */
+ yytext++;
+ yyleng--;
+
+ cfglval->value.str.val = php3_strndup(yytext,yyleng);
+ cfglval->value.str.len = yyleng;
+ cfglval->type = IS_STRING;
+ return SECTION;
+}
+
+
+<INITIAL>["][^\n\r"]*["] {
+ /* ENCAPSULATED TC_STRING */
+ register int i;
+
+ /* eat trailing " */
+ yytext[yyleng-1]=0;
+
+ /* eat leading " */
+ yytext++;
+
+ cfglval->value.str.val = php3_strndup(yytext,yyleng);
+ cfglval->value.str.len = yyleng;
+ cfglval->type = IS_STRING;
+ return TC_ENCAPSULATED_STRING;
+}
+
+
+<INITIAL>[^=\n\r\t;"]+ {
+ /* STRING */
+ register int i;
+
+ /* eat trailing whitespace */
+ for (i=yyleng-1; i>=0; i--) {
+ if (yytext[i]==' ' || yytext[i]=='\t') {
+ yytext[i]=0;
+ yyleng--;
+ } else {
+ break;
+ }
+ }
+ /* eat leading whitespace */
+ while (yytext[0]) {
+ if (yytext[0]==' ' || yytext[0]=='\t') {
+ yytext++;
+ yyleng--;
+ } else {
+ break;
+ }
+ }
+ if (yyleng!=0) {
+ cfglval->value.str.val = php3_strndup(yytext,yyleng);
+ cfglval->value.str.len = yyleng;
+ cfglval->type = IS_STRING;
+ return TC_STRING;
+ } else {
+ /* whitespace */
+ }
+}
+
+
+
+<INITIAL>[=\n] {
+ return yytext[0];
+}
+
+<INITIAL>"\r\n" {
+ return '\n';
+}
+
+<INITIAL>[;][^\r\n]*[\r\n]? {
+ /* comment */
+ return '\n';
+}
+
+<INITIAL>[ \t] {
+ /* eat whitespace */
+}
+
+<INITIAL>. {
+#if DEBUG
+ php3_error(E_NOTICE,"Unexpected character on line %d: '%s' (ASCII %d)\n",yylineno,yytext,yytext[0]);
+#endif
+}
diff --git a/main/fopen_wrappers.c b/main/fopen_wrappers.c
new file mode 100644
index 0000000000..02f97208b8
--- /dev/null
+++ b/main/fopen_wrappers.c
@@ -0,0 +1,1000 @@
+/*
+ +----------------------------------------------------------------------+
+ | 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: Rasmus Lerdorf <rasmus@lerdorf.on.ca> |
+ | Jim Winstead <jimw@php.net> |
+ +----------------------------------------------------------------------+
+ */
+/* $Id$ */
+
+#ifdef THREAD_SAFE
+#include "tls.h"
+#endif
+
+#include "php.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#if MSVC5
+#include <windows.h>
+#include <winsock.h>
+#define O_RDONLY _O_RDONLY
+#include "win32/param.h"
+#else
+#include <sys/param.h>
+#endif
+
+#include "safe_mode.h"
+#include "php3_realpath.h"
+#include "functions/head.h"
+#include "functions/url.h"
+#include "functions/base64.h"
+#include "functions/fsock.h"
+#include "functions/php3_string.h"
+#include "zend_compile.h"
+
+#if HAVE_PWD_H
+#if MSVC5
+#include "win32/pwd.h"
+#else
+#include <pwd.h>
+#endif
+#endif
+
+#include <sys/types.h>
+#if HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+
+#ifndef S_ISREG
+#define S_ISREG(mode) (((mode)&S_IFMT) == S_IFREG)
+#endif
+
+#if MSVC5
+#include <winsock.h>
+#else
+#include <netinet/in.h>
+#include <netdb.h>
+#include <arpa/inet.h>
+#endif
+
+#if MSVC5
+#undef AF_UNIX
+#endif
+
+#if defined(AF_UNIX)
+#include <sys/un.h>
+#endif
+
+static FILE *php3_fopen_url_wrapper(const char *path, char *mode, int options, int *issock, int *socketd);
+
+int _php3_getftpresult(int socketd);
+
+/*
+ When open_basedir is not NULL, check if the given filename is located in
+ open_basedir. Returns -1 if error or not in the open_basedir, else 0
+
+ When open_basedir is NULL, always return 0
+*/
+PHPAPI int _php3_check_open_basedir(char *path)
+{
+ char resolved_name[MAXPATHLEN];
+ char local_open_basedir[MAXPATHLEN];
+ int local_open_basedir_pos;
+
+ /* Only check when open_basedir is available */
+ if (php3_ini.open_basedir && *php3_ini.open_basedir) {
+
+ /* Special case basedir==".": Use script-directory */
+ if ((strcmp(php3_ini.open_basedir, ".") == 0) &&
+ GLOBAL(request_info).filename &&
+ *GLOBAL(request_info).filename
+ ) {
+ strcpy(local_open_basedir, GLOBAL(request_info).filename);
+ local_open_basedir_pos = strlen(local_open_basedir) - 1;
+
+ /* Strip filename */
+ while ((
+#if WIN32|WINNT
+ (local_open_basedir[local_open_basedir_pos] != '\\') ||
+#endif
+ (local_open_basedir[local_open_basedir_pos] != '/')
+ ) &&
+ (local_open_basedir_pos >= 0)
+ ) {
+ local_open_basedir[local_open_basedir_pos--] = 0;
+ }
+
+ /* Strip double (back)slashes */
+ if (local_open_basedir_pos > 0) {
+ while ((
+#if WIN32|WINNT
+ (local_open_basedir[local_open_basedir_pos-1] == '\\') ||
+#endif
+ (local_open_basedir[local_open_basedir_pos-1] == '/')
+ ) &&
+ (local_open_basedir_pos > 0)
+ ) {
+ local_open_basedir[local_open_basedir_pos--] = 0;
+ }
+ }
+
+ } else {
+ /* Else use the unmodified path */
+ strcpy(local_open_basedir, php3_ini.open_basedir);
+ }
+
+ /* Resolve the real path into resolved_name */
+ if (_php3_realpath(path, resolved_name) != NULL) {
+ /* Check the path */
+#if WIN32|WINNT
+ if (strncasecmp(local_open_basedir, resolved_name, strlen(local_open_basedir)) == 0) {
+#else
+ if (strncmp(local_open_basedir, resolved_name, strlen(local_open_basedir)) == 0) {
+#endif
+ /* File is in the right directory */
+ return 0;
+ } else {
+ php3_error(E_WARNING, "open_basedir restriction in effect. File is in wrong directory.");
+ return -1;
+ }
+ } else {
+ /* Unable to resolve the real path, return -1 */
+ php3_error(E_WARNING, "open_basedir restriction in effect. Unable to verify location of file.");
+ return -1;
+ }
+ } else {
+ /* open_basedir is not available, return 0 */
+ return 0;
+ }
+}
+
+PHPAPI FILE *php3_fopen_wrapper(char *path, char *mode, int options, int *issock, int *socketd)
+{
+ int cm=2; /* checkuid mode: 2 = if file does not exist, check directory */
+#if PHP3_URL_FOPEN
+ if (!(options & IGNORE_URL)) {
+ return php3_fopen_url_wrapper(path, mode, options, issock, socketd);
+ }
+#endif
+
+ if (options & USE_PATH && php3_ini.include_path != NULL) {
+ return php3_fopen_with_path(path, mode, php3_ini.include_path, NULL);
+ } else {
+ if(!strcmp(mode,"r") || !strcmp(mode,"r+")) cm=0;
+ if (options & ENFORCE_SAFE_MODE && php3_ini.safe_mode && (!_php3_checkuid(path, cm))) {
+ return NULL;
+ }
+ if (_php3_check_open_basedir(path)) return NULL;
+ return fopen(path, mode);
+ }
+}
+
+#if CGI_BINARY || FHTTPD || USE_SAPI
+
+FILE *php3_fopen_for_parser(void)
+{
+ FILE *fp;
+ struct stat st;
+ char *temp, *path_info, *fn;
+ int l;
+ TLS_VARS;
+
+
+ fn = GLOBAL(request_info).filename;
+ path_info = GLOBAL(request_info).path_info;
+#if HAVE_PWD_H
+ if (php3_ini.user_dir && *php3_ini.user_dir
+ && path_info && '/' == path_info[0] && '~' == path_info[1]) {
+
+ char user[32];
+ struct passwd *pw;
+ char *s = strchr(path_info + 2, '/');
+
+ fn = NULL; /* discard the original filename, it must not be used */
+ if (s) { /* if there is no path name after the file, do not bother
+ to try open the directory */
+ l = s - (path_info + 2);
+ if (l > sizeof(user) - 1)
+ l = sizeof(user) - 1;
+ memcpy(user, path_info + 2, l);
+ user[l] = '\0';
+
+ pw = getpwnam(user);
+ if (pw && pw->pw_dir) {
+ fn = emalloc(strlen(php3_ini.user_dir) + strlen(path_info) + strlen(pw->pw_dir) + 4);
+ if (fn) {
+ strcpy(fn, pw->pw_dir); /* safe */
+ strcat(fn, "/"); /* safe */
+ strcat(fn, php3_ini.user_dir); /* safe */
+ strcat(fn, "/"); /* safe */
+ strcat(fn, s + 1); /* safe (shorter than path_info) */
+ STR_FREE(GLOBAL(request_info).filename);
+ GLOBAL(request_info).filename = fn;
+ }
+ }
+ }
+ } else
+#endif
+#if WIN32
+ if (php3_ini.doc_root && path_info && ('/' == *php3_ini.doc_root ||
+ '\\' == *php3_ini.doc_root || strstr(php3_ini.doc_root,":\\") ||
+ strstr(php3_ini.doc_root,":/"))) {
+#else
+ if (php3_ini.doc_root && '/' == *php3_ini.doc_root && path_info) {
+#endif
+ l = strlen(php3_ini.doc_root);
+ fn = emalloc(l + strlen(path_info) + 2);
+ if (fn) {
+ memcpy(fn, php3_ini.doc_root, l);
+ if ('/' != fn[l - 1] || '\\' != fn[l - 1]) /* l is never 0 */
+ fn[l++] = '/';
+ if ('/' == path_info[0])
+ l--;
+ strcpy(fn + l, path_info);
+ STR_FREE(GLOBAL(request_info).filename);
+ GLOBAL(request_info).filename = fn;
+ }
+ } /* if doc_root && path_info */
+ if (!fn) {
+ /* we have to free request_info.filename here because
+ php3_destroy_request_info assumes that it will get
+ freed when the include_names hash is emptied, but
+ we're not adding it in this case */
+ STR_FREE(GLOBAL(request_info).filename);
+ GLOBAL(request_info).filename = NULL;
+ return NULL;
+ }
+ fp = fopen(fn, "r");
+
+ /* refuse to open anything that is not a regular file */
+ if (fp && (0 > fstat(fileno(fp), &st) || !S_ISREG(st.st_mode))) {
+ fclose(fp);
+ fp = NULL;
+ }
+ if (!fp) {
+ php3_error(E_CORE_ERROR, "Unable to open %s", fn);
+ STR_FREE(GLOBAL(request_info).filename); /* for same reason as above */
+ return NULL;
+ }
+
+ temp = estrdup(fn);
+ _php3_dirname(temp, strlen(temp));
+ if (*temp) {
+ chdir(temp);
+ }
+ efree(temp);
+
+ return fp;
+}
+
+#endif /* CGI_BINARY || USE_SAPI */
+
+/*
+ * Tries to open a file with a PATH-style list of directories.
+ * If the filename starts with "." or "/", the path is ignored.
+ */
+PHPAPI FILE *php3_fopen_with_path(char *filename, char *mode, char *path, char **opened_path)
+{
+ char *pathbuf, *ptr, *end;
+ char trypath[MAXPATHLEN + 1];
+ struct stat sb;
+ FILE *fp;
+ int cm=2;
+ TLS_VARS;
+
+ if(!strcmp(mode,"r") || !strcmp(mode,"r+")) cm=0;
+ if (opened_path) {
+ *opened_path = NULL;
+ }
+ /* Relative path open */
+ if (*filename == '.') {
+ if (php3_ini.safe_mode && (!_php3_checkuid(filename, cm))) {
+ return NULL;
+ }
+ if (_php3_check_open_basedir(filename)) return NULL;
+ fp = fopen(filename, mode);
+ if (fp && opened_path) {
+ *opened_path = expand_filepath(filename);
+ }
+ return fp;
+ }
+ /* Absolute path open - prepend document_root in safe mode */
+#if WIN32|WINNT
+ if ((*filename == '\\') || (*filename == '/') || (filename[1] == ':')) {
+#else
+ if (*filename == '/') {
+#endif
+ if (php3_ini.safe_mode) {
+ if(php3_ini.doc_root) {
+ snprintf(trypath, MAXPATHLEN, "%s%s", php3_ini.doc_root, filename);
+ } else {
+ strncpy(trypath,filename,MAXPATHLEN);
+ }
+ if (!_php3_checkuid(trypath, cm)) {
+ return NULL;
+ }
+ if (_php3_check_open_basedir(trypath)) return NULL;
+ fp = fopen(trypath, mode);
+ if (fp && opened_path) {
+ *opened_path = expand_filepath(trypath);
+ }
+ return fp;
+ } else {
+ if (_php3_check_open_basedir(filename)) return NULL;
+ return fopen(filename, mode);
+ }
+ }
+ if (!path || (path && !*path)) {
+ if (php3_ini.safe_mode && (!_php3_checkuid(filename, cm))) {
+ return NULL;
+ }
+ if (_php3_check_open_basedir(filename)) return NULL;
+ fp = fopen(filename, mode);
+ if (fp && opened_path) {
+ *opened_path = strdup(filename);
+ }
+ return fp;
+ }
+ pathbuf = estrdup(path);
+
+ ptr = pathbuf;
+
+ while (ptr && *ptr) {
+#if WIN32|WINNT
+ end = strchr(ptr, ';');
+#else
+ end = strchr(ptr, ':');
+#endif
+ if (end != NULL) {
+ *end = '\0';
+ end++;
+ }
+ snprintf(trypath, MAXPATHLEN, "%s/%s", ptr, filename);
+ if (php3_ini.safe_mode) {
+ if (stat(trypath, &sb) == 0 && (!_php3_checkuid(trypath, cm))) {
+ efree(pathbuf);
+ return NULL;
+ }
+ }
+ if ((fp = fopen(trypath, mode)) != NULL) {
+ if (_php3_check_open_basedir(trypath)) {
+ fclose(fp);
+ efree(pathbuf);
+ return NULL;
+ }
+ if (opened_path) {
+ *opened_path = expand_filepath(trypath);
+ }
+ efree(pathbuf);
+ return fp;
+ }
+ ptr = end;
+ }
+ efree(pathbuf);
+ return NULL;
+}
+
+/*
+ * If the specified path starts with "http://" (insensitive to case),
+ * a socket is opened to the specified web server and a file pointer is
+ * position at the start of the body of the response (past any headers).
+ * This makes a HTTP/1.0 request, and knows how to pass on the username
+ * and password for basic authentication.
+ *
+ * If the specified path starts with "ftp://" (insensitive to case),
+ * a pair of sockets are used to request the specified file and a file
+ * pointer to the requested file is returned. Passive mode ftp is used,
+ * so if the server doesn't suppor this, it will fail!
+ *
+ * Otherwise, fopen is called as usual and the file pointer is returned.
+ */
+
+static FILE *php3_fopen_url_wrapper(const char *path, char *mode, int options, int *issock, int *socketd)
+{
+ url *resource;
+ int result;
+ char *scratch;
+ unsigned char *tmp;
+
+ char tmp_line[256];
+ char location[256];
+ int chptr = 0;
+ char *tpath, *ttpath;
+ int body = 0;
+ int reqok = 0;
+ int lineone = 1;
+ int i;
+ char buf[2];
+
+ char oldch1 = 0;
+ char oldch2 = 0;
+ char oldch3 = 0;
+ char oldch4 = 0;
+ char oldch5 = 0;
+
+ FILE *fp = NULL;
+ struct sockaddr_in server;
+ unsigned short portno;
+ char winfeof;
+
+ if (!strncasecmp(path, "http://", 7)) {
+ resource = url_parse((char *) path);
+ if (resource == NULL) {
+ php3_error(E_WARNING, "Invalid URL specified, %s", path);
+ *issock = BAD_URL;
+ return NULL;
+ }
+ /* use port 80 if one wasn't specified */
+ if (resource->port == 0)
+ resource->port = 80;
+
+ *socketd = socket(AF_INET, SOCK_STREAM, 0);
+ if (*socketd == SOCK_ERR) {
+ SOCK_FCLOSE(*socketd);
+ *socketd = 0;
+ free_url(resource);
+ return NULL;
+ }
+ server.sin_addr.s_addr = lookup_hostname(resource->host);
+ server.sin_family = AF_INET;
+
+ if (server.sin_addr.s_addr == -1) {
+ SOCK_FCLOSE(*socketd);
+ *socketd = 0;
+ free_url(resource);
+ return NULL;
+ }
+ server.sin_port = htons(resource->port);
+
+ if (connect(*socketd, (struct sockaddr *) &server, sizeof(server)) == SOCK_CONN_ERR) {
+ SOCK_FCLOSE(*socketd);
+ *socketd = 0;
+ free_url(resource);
+ return NULL;
+ }
+#if 0
+ if ((fp = fdopen(*socketd, "r+")) == NULL) {
+ free_url(resource);
+ return NULL;
+ }
+#ifdef HAVE_SETVBUF
+ if ((setvbuf(fp, NULL, _IONBF, 0)) != 0) {
+ free_url(resource);
+ return NULL;
+ }
+#endif
+#endif /*win32 */
+
+ /* tell remote http which file to get */
+ SOCK_WRITE("GET ", *socketd);
+ if (resource->path != NULL) {
+ SOCK_WRITE(resource->path, *socketd);
+ } else {
+ SOCK_WRITE("/", *socketd);
+ }
+
+ /* append the query string, if any */
+ if (resource->query != NULL) {
+ SOCK_WRITE("?", *socketd);
+ SOCK_WRITE(resource->query, *socketd);
+ }
+ SOCK_WRITE(" HTTP/1.0\n", *socketd);
+
+ /* send authorization header if we have user/pass */
+ if (resource->user != NULL && resource->pass != NULL) {
+ scratch = (char *) emalloc(strlen(resource->user) + strlen(resource->pass) + 2);
+ if (!scratch) {
+ free_url(resource);
+ return NULL;
+ }
+ strcpy(scratch, resource->user);
+ strcat(scratch, ":");
+ strcat(scratch, resource->pass);
+ tmp = _php3_base64_encode((unsigned char *)scratch, strlen(scratch), NULL);
+
+ SOCK_WRITE("Authorization: Basic ", *socketd);
+ /* output "user:pass" as base64-encoded string */
+ SOCK_WRITE((char *)tmp, *socketd);
+ SOCK_WRITE("\n", *socketd);
+ efree(scratch);
+ efree(tmp);
+ }
+ /* if the user has configured who they are, send a From: line */
+ if (cfg_get_string("from", &scratch) == SUCCESS) {
+ SOCK_WRITE("From: ", *socketd);
+ SOCK_WRITE(scratch, *socketd);
+ SOCK_WRITE("\n", *socketd);
+ }
+ /* send a Host: header so name-based virtual hosts work */
+ SOCK_WRITE("Host: ", *socketd);
+ SOCK_WRITE(resource->host, *socketd);
+ if(resource->port!=80) {
+ sprintf(tmp_line,"%i",resource->port);
+ SOCK_WRITE(":", *socketd);
+ SOCK_WRITE(tmp_line, *socketd);
+ }
+ SOCK_WRITE("\n", *socketd);
+
+ /* identify ourselves */
+ SOCK_WRITE("User-Agent: PHP/", *socketd);
+ SOCK_WRITE(PHP_VERSION, *socketd);
+ SOCK_WRITE("\n", *socketd);
+
+ /* end the headers */
+ SOCK_WRITE("\n", *socketd);
+
+ /* Read past http header */
+ body = 0;
+ location[0] = '\0';
+ while (!body && recv(*socketd, (char *) &winfeof, 1, MSG_PEEK)) {
+ if (SOCK_FGETC(buf, *socketd) == SOCK_RECV_ERR) {
+ SOCK_FCLOSE(*socketd);
+ *socketd = 0;
+ free_url(resource);
+ return NULL;
+ }
+ oldch5 = oldch4;
+ oldch4 = oldch3;
+ oldch3 = oldch2;
+ oldch2 = oldch1;
+ oldch1 = *buf;
+
+ tmp_line[chptr++] = *buf;
+ if (*buf == 10 || *buf == 13) {
+ tmp_line[chptr] = '\0';
+ chptr = 0;
+ if (!strncasecmp(tmp_line, "Location: ", 10)) {
+ tpath = tmp_line + 10;
+ strcpy(location, tpath);
+ }
+ }
+ if (lineone && (*buf == 10 || *buf == 13)) {
+ lineone = 0;
+ }
+ if (lineone && oldch5 == ' ' && oldch4 == '2' && oldch3 == '0' &&
+ oldch2 == '0' && oldch1 == ' ') {
+ reqok = 1;
+ }
+ if (oldch4 == 13 && oldch3 == 10 && oldch2 == 13 && oldch1 == 10) {
+ body = 1;
+ }
+ if (oldch2 == 10 && oldch1 == 10) {
+ body = 1;
+ }
+ if (oldch2 == 13 && oldch1 == 13) {
+ body = 1;
+ }
+ }
+ if (!reqok) {
+ SOCK_FCLOSE(*socketd);
+ *socketd = 0;
+ free_url(resource);
+ if (location[0] != '\0') {
+ return php3_fopen_url_wrapper(location, mode, options, issock, socketd);
+ } else {
+ return NULL;
+ }
+ }
+ free_url(resource);
+ *issock = 1;
+ return (fp);
+ } else if (!strncasecmp(path, "ftp://", 6)) {
+ resource = url_parse((char *) path);
+ if (resource == NULL) {
+ php3_error(E_WARNING, "Invalid URL specified, %s", path);
+ *issock = BAD_URL;
+ return NULL;
+ } else if (resource->path == NULL) {
+ php3_error(E_WARNING, "No file-path specified");
+ free_url(resource);
+ *issock = BAD_URL;
+ return NULL;
+ }
+ /* use port 21 if one wasn't specified */
+ if (resource->port == 0)
+ resource->port = 21;
+
+ *socketd = socket(AF_INET, SOCK_STREAM, 0);
+ if (*socketd == SOCK_ERR) {
+ SOCK_FCLOSE(*socketd);
+ *socketd = 0;
+ free_url(resource);
+ return NULL;
+ }
+ server.sin_addr.s_addr = lookup_hostname(resource->host);
+ server.sin_family = AF_INET;
+
+ if (server.sin_addr.s_addr == -1) {
+ SOCK_FCLOSE(*socketd);
+ *socketd = 0;
+ free_url(resource);
+ return NULL;
+ }
+ server.sin_port = htons(resource->port);
+
+ if (connect(*socketd, (struct sockaddr *) &server, sizeof(server)) == SOCK_CONN_ERR) {
+ SOCK_FCLOSE(*socketd);
+ *socketd = 0;
+ free_url(resource);
+ return NULL;
+ }
+#if 0
+ if ((fpc = fdopen(*socketd, "r+")) == NULL) {
+ free_url(resource);
+ return NULL;
+ }
+#ifdef HAVE_SETVBUF
+ if ((setvbuf(fpc, NULL, _IONBF, 0)) != 0) {
+ free_url(resource);
+ fclose(fpc);
+ return NULL;
+ }
+#endif
+#endif
+
+ /* Start talking to ftp server */
+ result = _php3_getftpresult(*socketd);
+ if (result > 299 || result < 200) {
+ free_url(resource);
+ SOCK_FCLOSE(*socketd);
+ *socketd = 0;
+ return NULL;
+ }
+ /* send the user name */
+ SOCK_WRITE("USER ", *socketd);
+ if (resource->user != NULL) {
+ _php3_rawurldecode(resource->user, strlen(resource->user));
+ SOCK_WRITE(resource->user, *socketd);
+ } else {
+ SOCK_WRITE("anonymous", *socketd);
+ }
+ SOCK_WRITE("\n", *socketd);
+
+ /* get the response */
+ result = _php3_getftpresult(*socketd);
+
+ /* if a password is required, send it */
+ if (result >= 300 && result <= 399) {
+ SOCK_WRITE("PASS ", *socketd);
+ if (resource->pass != NULL) {
+ _php3_rawurldecode(resource->pass, strlen(resource->pass));
+ SOCK_WRITE(resource->pass, *socketd);
+ } else {
+ /* if the user has configured who they are,
+ send that as the password */
+ if (cfg_get_string("from", &scratch) == SUCCESS) {
+ SOCK_WRITE(scratch, *socketd);
+ } else {
+ SOCK_WRITE("anonymous", *socketd);
+ }
+ }
+ SOCK_WRITE("\n", *socketd);
+
+ /* read the response */
+ result = _php3_getftpresult(*socketd);
+ if (result > 299 || result < 200) {
+ free_url(resource);
+ SOCK_FCLOSE(*socketd);
+ *socketd = 0;
+ return NULL;
+ }
+ } else if (result > 299 || result < 200) {
+ free_url(resource);
+ SOCK_FCLOSE(*socketd);
+ *socketd = 0;
+ return NULL;
+ }
+
+ /* find out the size of the file (verifying it exists) */
+ SOCK_WRITE("SIZE ", *socketd);
+ SOCK_WRITE(resource->path, *socketd);
+ SOCK_WRITE("\n", *socketd);
+
+ /* read the response */
+ result = _php3_getftpresult(*socketd);
+ if (mode[0] == 'r') {
+ /* when reading file, it must exist */
+ if (result > 299 || result < 200) {
+ php3_error(E_WARNING, "File not found");
+ free_url(resource);
+ SOCK_FCLOSE(*socketd);
+ *socketd = 0;
+ errno = ENOENT;
+ return NULL;
+ }
+ } else {
+ /* when writing file, it must NOT exist */
+ if (result <= 299 && result >= 200) {
+ php3_error(E_WARNING, "File already exists");
+ free_url(resource);
+ SOCK_FCLOSE(*socketd);
+ *socketd = 0;
+ errno = EEXIST;
+ return NULL;
+ }
+ }
+
+ /* set the connection to be binary */
+ SOCK_WRITE("TYPE I\n", *socketd);
+ result = _php3_getftpresult(*socketd);
+ if (result > 299 || result < 200) {
+ free_url(resource);
+ SOCK_FCLOSE(*socketd);
+ *socketd = 0;
+ return NULL;
+ }
+ /* set up the passive connection */
+ SOCK_WRITE("PASV\n", *socketd);
+ while (SOCK_FGETS(tmp_line, 256, *socketd) &&
+ !(isdigit((int) tmp_line[0]) && isdigit((int) tmp_line[1]) &&
+ isdigit((int) tmp_line[2]) && tmp_line[3] == ' '));
+
+ /* make sure we got a 227 response */
+ if (strncmp(tmp_line, "227", 3)) {
+ free_url(resource);
+ SOCK_FCLOSE(*socketd);
+ *socketd = 0;
+ return NULL;
+ }
+ /* parse pasv command (129,80,95,25,13,221) */
+ tpath = tmp_line;
+
+ /* skip over the "227 Some message " part */
+ for (tpath += 4; *tpath && !isdigit((int) *tpath); tpath++);
+ if (!*tpath) {
+ free_url(resource);
+ SOCK_FCLOSE(*socketd);
+ *socketd = 0;
+ return NULL;
+ }
+ /* skip over the host ip, we just assume it's the same */
+ for (i = 0; i < 4; i++) {
+ for (; isdigit((int) *tpath); tpath++);
+ if (*tpath == ',') {
+ tpath++;
+ } else {
+ SOCK_FCLOSE(*socketd);
+ *socketd = 0;
+ return NULL;
+ }
+ }
+
+ /* pull out the MSB of the port */
+ portno = (unsigned short) strtol(tpath, &ttpath, 10) * 256;
+ if (ttpath == NULL) {
+ /* didn't get correct response from PASV */
+ free_url(resource);
+ SOCK_FCLOSE(*socketd);
+ *socketd = 0;
+ return NULL;
+ }
+ tpath = ttpath;
+ if (*tpath == ',') {
+ tpath++;
+ } else {
+ free_url(resource);
+ SOCK_FCLOSE(*socketd);
+ *socketd = 0;
+ return NULL;
+ }
+
+ /* pull out the LSB of the port */
+ portno += (unsigned short) strtol(tpath, &ttpath, 10);
+
+ if (ttpath == NULL) {
+ /* didn't get correct response from PASV */
+ free_url(resource);
+ SOCK_FCLOSE(*socketd);
+ *socketd = 0;
+ return NULL;
+ }
+
+ if (mode[0] == 'r') {
+ /* retrieve file */
+ SOCK_WRITE("RETR ", *socketd);
+ } else {
+ /* store file */
+ SOCK_WRITE("STOR ", *socketd);
+ }
+ if (resource->path != NULL) {
+ SOCK_WRITE(resource->path, *socketd);
+ } else {
+ SOCK_WRITE("/", *socketd);
+ }
+
+ /* close control connection */
+ SOCK_WRITE("\nQUIT\n", *socketd);
+ SOCK_FCLOSE(*socketd);
+
+ /* open the data channel */
+ *socketd = socket(AF_INET, SOCK_STREAM, 0);
+ if (*socketd == SOCK_ERR) {
+ SOCK_FCLOSE(*socketd);
+ *socketd = 0;
+ free_url(resource);
+ return NULL;
+ }
+ server.sin_addr.s_addr = lookup_hostname(resource->host);
+ server.sin_family = AF_INET;
+
+ if (server.sin_addr.s_addr == -1) {
+ free_url(resource);
+ SOCK_FCLOSE(*socketd);
+ *socketd = 0;
+ return NULL;
+ }
+ server.sin_port = htons(portno);
+
+ if (connect(*socketd, (struct sockaddr *) &server, sizeof(server)) == SOCK_CONN_ERR) {
+ free_url(resource);
+ SOCK_FCLOSE(*socketd);
+ *socketd = 0;
+ return NULL;
+ }
+#if 0
+ if (mode[0] == 'r') {
+ if ((fp = fdopen(*socketd, "r+")) == NULL) {
+ free_url(resource);
+ return NULL;
+ }
+ } else {
+ if ((fp = fdopen(*socketd, "w+")) == NULL) {
+ free_url(resource);
+ return NULL;
+ }
+ }
+#ifdef HAVE_SETVBUF
+ if ((setvbuf(fp, NULL, _IONBF, 0)) != 0) {
+ free_url(resource);
+ fclose(fp);
+ return NULL;
+ }
+#endif
+#endif
+ free_url(resource);
+ *issock = 1;
+ return (fp);
+
+ } else {
+ if (options & USE_PATH) {
+ fp = php3_fopen_with_path((char *) path, mode, php3_ini.include_path, NULL);
+ } else {
+ int cm=2;
+ if(!strcmp(mode,"r") || !strcmp(mode,"r+")) cm=0;
+ if (options & ENFORCE_SAFE_MODE && php3_ini.safe_mode && (!_php3_checkuid(path, cm))) {
+ fp = NULL;
+ } else {
+ if (_php3_check_open_basedir((char *) path)) {
+ fp = NULL;
+ } else {
+ fp = fopen(path, mode);
+ }
+ }
+ }
+
+ *issock = 0;
+
+ return (fp);
+ }
+
+ /* NOTREACHED */
+ SOCK_FCLOSE(*socketd);
+ *socketd = 0;
+ return NULL;
+}
+
+int _php3_getftpresult(int socketd)
+{
+ char tmp_line[256];
+
+ while (SOCK_FGETS(tmp_line, 256, socketd) &&
+ !(isdigit((int) tmp_line[0]) && isdigit((int) tmp_line[1]) &&
+ isdigit((int) tmp_line[2]) && tmp_line[3] == ' '));
+
+ return strtol(tmp_line, NULL, 10);
+}
+
+PHPAPI int php3_isurl(char *path)
+{
+ return (!strncasecmp(path, "http://", 7) || !strncasecmp(path, "ftp://", 6));
+}
+
+
+PHPAPI char *php3_strip_url_passwd(char *url)
+{
+ register char *p = url, *url_start;
+
+ while (*p) {
+ if (*p==':' && *(p+1)=='/' && *(p+2)=='/') {
+ /* found protocol */
+ url_start = p = p+3;
+
+ while (*p) {
+ if (*p=='@') {
+ int i;
+
+ for (i=0; i<3 && url_start<p; i++, url_start++) {
+ *url_start = '.';
+ }
+ for (; *p; p++) {
+ *url_start++ = *p;
+ }
+ *url_start=0;
+ break;
+ }
+ p++;
+ }
+ return url;
+ }
+ p++;
+ }
+ return url;
+}
+
+
+PHPAPI char *expand_filepath(char *filepath)
+{
+ char *retval = NULL;
+
+ if (filepath[0] == '.') {
+ char *cwd = malloc(MAXPATHLEN + 1);
+
+ if (getcwd(cwd, MAXPATHLEN)) {
+ char *cwd_end = cwd + strlen(cwd);
+
+ if (filepath[1] == '.') { /* parent directory - .. */
+ /* erase the last directory name from the path */
+ while (*cwd_end != '/') {
+ *cwd_end-- = 0;
+ }
+ filepath++; /* make filepath appear as a current directory path */
+ }
+ if (cwd_end > cwd && *cwd_end == '/') { /* remove trailing slashes */
+ *cwd_end-- = 0;
+ }
+ retval = (char *) malloc(strlen(cwd) + strlen(filepath) - 1 + 1);
+ strcpy(retval, cwd);
+ strcat(retval, filepath + 1);
+ free(cwd);
+ }
+ }
+ if (!retval) {
+ retval = strdup(filepath);
+ }
+ return retval;
+}
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ */
diff --git a/main/fopen_wrappers.h b/main/fopen_wrappers.h
new file mode 100644
index 0000000000..0b3834a1e3
--- /dev/null
+++ b/main/fopen_wrappers.h
@@ -0,0 +1,90 @@
+/*
+ +----------------------------------------------------------------------+
+ | 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: Jim Winstead <jimw@php.net> |
+ +----------------------------------------------------------------------+
+ */
+/* $Id$ */
+
+#ifndef _FOPEN_WRAPPERS_H
+#define _FOPEN_WRAPPERS_H
+
+#define IGNORE_PATH 0
+#define USE_PATH 1
+#define IGNORE_URL 2
+/* There's no USE_URL. */
+#if WIN32|WINNT
+# define IGNORE_URL_WIN 2
+#else
+# define IGNORE_URL_WIN 0
+#endif
+#define ENFORCE_SAFE_MODE 4
+
+#if WIN32|WINNT
+# define SOCK_ERR INVALID_SOCKET
+# define SOCK_CONN_ERR SOCKET_ERROR
+# define SOCK_RECV_ERR SOCKET_ERROR
+# define SOCK_FCLOSE(s) closesocket(s)
+#else
+# define SOCK_ERR -1
+# define SOCK_CONN_ERR -1
+# define SOCK_RECV_ERR -1
+# define SOCK_FCLOSE(s) close(s)
+#endif
+#define SOCK_WRITE(d,s) send(s,d,strlen(d),0)
+#define SOCK_WRITEL(d,l,s) send(s,d,l,0)
+#define SOCK_FGETC(c,s) recv(s,c,1,0)
+#define SOCK_FGETS(b,l,s) _php3_sock_fgets((b),(l),(s))
+
+/* values for issock */
+#define IS_NOT_SOCKET 0
+#define IS_SOCKET 1
+#define BAD_URL 2
+
+#ifndef THREAD_SAFE
+extern int wsa_fp; /* a list for open sockets */
+#endif
+
+extern PHPAPI FILE *php3_fopen_wrapper(char *filename, char *mode, int options, int *issock, int *socketd);
+
+extern FILE *php3_fopen_for_parser(void);
+
+extern PHPAPI int _php3_check_open_basedir(char *path);
+
+extern PHPAPI FILE *php3_fopen_with_path(char *filename, char *mode, char *path, char **opened_path);
+
+extern PHPAPI int php3_isurl(char *path);
+extern PHPAPI char *php3_strip_url_passwd(char *path);
+extern PHPAPI int php3_write(void *buf, int size);
+
+extern PHPAPI char *expand_filepath(char *filepath);
+
+#endif
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ */
diff --git a/main/internal_functions_registry.h b/main/internal_functions_registry.h
new file mode 100644
index 0000000000..6e58de6ef1
--- /dev/null
+++ b/main/internal_functions_registry.h
@@ -0,0 +1,57 @@
+/*
+ +----------------------------------------------------------------------+
+ | 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> |
+ +----------------------------------------------------------------------+
+ */
+
+
+/* $Id$ */
+
+#ifndef _INTERNAL_FUNCTIONS_REGISTRY_H
+#define _INTERNAL_FUNCTIONS_REGISTRY_H
+
+extern int php3_init_mime(INIT_FUNC_ARGS);
+
+#if APACHE
+extern php3_module_entry apache_module_entry;
+#define apache_module_ptr &apache_module_entry
+extern void php3_virtual(INTERNAL_FUNCTION_PARAMETERS);
+#else
+#define apache_module_ptr NULL
+#endif
+
+/* environment functions */
+extern int php3_init_environment(void);
+
+#endif
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ */
diff --git a/main/logos.h b/main/logos.h
new file mode 100644
index 0000000000..6c91b0ae56
--- /dev/null
+++ b/main/logos.h
@@ -0,0 +1,805 @@
+unsigned char zendtech_logo[] = {
+ 71, 73, 70, 56, 57, 97, 100, 0, 89, 0,
+ 247, 255, 0, 255, 255, 255, 8, 8, 8, 16,
+ 16, 16, 33, 33, 33, 49, 49, 49, 57, 57,
+ 57, 66, 66, 66, 74, 74, 74, 82, 82, 82,
+ 90, 90, 90, 99, 99, 99, 115, 115, 115, 123,
+ 123, 123, 140, 140, 140, 148, 148, 148, 156, 156,
+ 156, 165, 165, 165, 173, 173, 173, 181, 181, 181,
+ 189, 189, 189, 206, 206, 206, 222, 222, 222, 239,
+ 239, 239, 148, 156, 156, 239, 247, 255, 0, 8,
+ 16, 189, 198, 214, 123, 132, 148, 231, 239, 255,
+ 99, 107, 123, 16, 33, 66, 0, 8, 24, 181,
+ 189, 206, 140, 148, 165, 115, 123, 140, 222, 231,
+ 255, 24, 41, 90, 181, 189, 214, 165, 173, 198,
+ 140, 148, 173, 82, 99, 156, 24, 41, 99, 0,
+ 8, 33, 189, 198, 231, 156, 165, 198, 123, 132,
+ 165, 165, 181, 239, 90, 107, 173, 74, 90, 148,
+ 24, 33, 66, 49, 74, 165, 214, 222, 255, 189,
+ 198, 239, 140, 148, 181, 123, 132, 173, 99, 107,
+ 140, 90, 99, 140, 49, 57, 90, 57, 74, 148,
+ 49, 66, 140, 16, 24, 57, 8, 16, 49, 206,
+ 214, 255, 165, 173, 214, 140, 156, 231, 140, 156,
+ 239, 107, 123, 198, 115, 132, 214, 123, 140, 231,
+ 99, 115, 198, 90, 107, 189, 41, 49, 90, 82,
+ 99, 189, 66, 82, 156, 33, 41, 82, 90, 115,
+ 239, 82, 107, 231, 57, 74, 165, 74, 99, 214,
+ 49, 66, 148, 49, 66, 156, 57, 82, 206, 33,
+ 49, 123, 57, 82, 214, 16, 24, 66, 24, 41,
+ 123, 189, 198, 247, 181, 189, 239, 189, 198, 255,
+ 132, 140, 189, 107, 115, 165, 140, 156, 247, 74,
+ 82, 132, 132, 148, 239, 123, 140, 239, 115, 132,
+ 231, 57, 66, 115, 99, 115, 206, 107, 123, 222,
+ 57, 66, 123, 49, 57, 107, 90, 107, 206, 90,
+ 107, 214, 82, 99, 198, 66, 82, 181, 57, 74,
+ 181, 49, 66, 165, 24, 33, 82, 66, 90, 231,
+ 49, 66, 173, 41, 57, 148, 24, 33, 90, 41,
+ 57, 156, 33, 49, 140, 33, 49, 148, 8, 16,
+ 66, 181, 189, 247, 173, 181, 239, 156, 165, 231,
+ 132, 140, 198, 107, 115, 173, 74, 82, 140, 66,
+ 74, 132, 107, 123, 231, 99, 115, 231, 82, 99,
+ 214, 74, 90, 198, 82, 99, 222, 74, 90, 206,
+ 66, 82, 189, 33, 41, 99, 66, 82, 198, 57,
+ 74, 189, 57, 74, 198, 49, 66, 181, 49, 66,
+ 189, 41, 57, 165, 24, 33, 99, 16, 24, 82,
+ 8, 16, 74, 173, 181, 247, 165, 173, 239, 165,
+ 173, 247, 140, 148, 214, 156, 165, 239, 148, 156,
+ 239, 132, 140, 214, 156, 165, 255, 115, 123, 189,
+ 123, 132, 206, 132, 140, 222, 115, 123, 198, 123,
+ 132, 214, 99, 107, 173, 123, 132, 222, 99, 107,
+ 189, 90, 99, 173, 74, 82, 148, 82, 90, 165,
+ 90, 99, 181, 74, 82, 156, 82, 90, 173, 90,
+ 99, 189, 41, 49, 115, 74, 90, 231, 41, 49,
+ 132, 33, 41, 107, 66, 82, 222, 33, 41, 123,
+ 24, 33, 107, 24, 33, 123, 16, 24, 90, 148,
+ 156, 255, 140, 148, 255, 115, 123, 222, 123, 132,
+ 239, 107, 115, 214, 123, 132, 247, 99, 107, 206,
+ 107, 115, 222, 115, 123, 239, 99, 107, 222, 82,
+ 90, 189, 74, 82, 173, 49, 57, 148, 247, 247,
+ 255, 198, 198, 206, 214, 214, 222, 222, 222, 231,
+ 165, 165, 173, 156, 156, 165, 115, 115, 123, 239,
+ 239, 255, 107, 107, 115, 214, 214, 231, 198, 198,
+ 214, 231, 231, 255, 222, 222, 247, 140, 140, 156,
+ 66, 66, 74, 123, 123, 140, 222, 222, 255, 206,
+ 206, 239, 132, 132, 156, 41, 41, 49, 165, 165,
+ 198, 123, 123, 148, 156, 156, 189, 74, 74, 90,
+ 198, 198, 255, 132, 132, 173, 24, 24, 33, 156,
+ 156, 214, 41, 41, 57, 148, 148, 206, 165, 165,
+ 231, 99, 99, 140, 156, 156, 222, 173, 173, 247,
+ 74, 74, 107, 165, 165, 239, 165, 165, 247, 82,
+ 82, 123, 132, 132, 198, 140, 140, 214, 123, 123,
+ 189, 74, 74, 115, 90, 90, 140, 99, 99, 156,
+ 66, 66, 107, 90, 90, 148, 74, 74, 123, 99,
+ 99, 165, 49, 49, 82, 123, 123, 206, 66, 66,
+ 115, 82, 82, 148, 8, 8, 16, 41, 41, 82,
+ 24, 24, 49, 41, 41, 90, 33, 33, 74, 24,
+ 24, 57, 41, 41, 99, 24, 24, 66, 8, 8,
+ 24, 16, 16, 49, 24, 24, 74, 8, 8, 41,
+ 16, 16, 90, 8, 8, 49, 8, 8, 57, 0,
+ 0, 8, 0, 0, 16, 0, 0, 24, 0, 0,
+ 0, 44, 0, 0, 0, 0, 100, 0, 89, 0,
+ 0, 8, 255, 0, 255, 9, 28, 72, 176, 160,
+ 193, 131, 8, 19, 42, 92, 200, 176, 161, 195,
+ 135, 16, 35, 74, 156, 72, 177, 162, 197, 139,
+ 24, 51, 106, 220, 200, 177, 34, 0, 3, 14,
+ 1, 76, 96, 104, 0, 64, 199, 147, 9, 63,
+ 58, 124, 48, 114, 97, 73, 148, 48, 11, 126,
+ 36, 32, 0, 193, 2, 5, 2, 6, 10, 88,
+ 176, 0, 228, 130, 145, 11, 6, 8, 28, 176,
+ 64, 160, 0, 5, 11, 26, 152, 28, 202, 51,
+ 231, 63, 162, 65, 99, 90, 252, 56, 193, 130,
+ 72, 11, 20, 4, 18, 176, 80, 97, 2, 0,
+ 164, 35, 85, 254, 123, 57, 160, 66, 87, 0,
+ 75, 21, 0, 160, 96, 246, 159, 90, 182, 22,
+ 64, 74, 157, 248, 81, 0, 0, 4, 79, 239,
+ 254, 155, 16, 97, 232, 191, 159, 255, 196, 190,
+ 140, 48, 33, 192, 63, 4, 38, 5, 88, 40,
+ 250, 116, 175, 5, 2, 135, 231, 82, 84, 41,
+ 118, 66, 81, 177, 2, 1, 11, 54, 185, 249,
+ 31, 5, 145, 19, 20, 12, 124, 240, 85, 242,
+ 100, 144, 149, 139, 90, 16, 61, 16, 112, 5,
+ 198, 47, 87, 11, 124, 73, 186, 65, 79, 130,
+ 106, 27, 152, 150, 72, 89, 174, 229, 191, 185,
+ 20, 24, 104, 64, 0, 240, 130, 224, 6, 34,
+ 124, 93, 96, 33, 88, 114, 11, 2, 41, 80,
+ 64, 128, 64, 183, 205, 228, 0, 32, 239, 126,
+ 216, 91, 224, 239, 191, 86, 39, 48, 255, 99,
+ 208, 146, 185, 72, 158, 224, 69, 50, 51, 170,
+ 60, 23, 131, 127, 4, 118, 1, 168, 128, 119,
+ 187, 253, 251, 248, 243, 235, 223, 207, 191, 191,
+ 255, 255, 0, 6, 40, 96, 63, 213, 240, 115,
+ 145, 129, 4, 241, 51, 13, 74, 253, 32, 216,
+ 16, 63, 14, 58, 84, 141, 10, 7, 22, 100,
+ 79, 63, 21, 69, 88, 80, 63, 24, 62, 216,
+ 96, 68, 238, 188, 115, 160, 131, 246, 188, 163,
+ 33, 68, 39, 14, 244, 193, 7, 13, 113, 152,
+ 226, 66, 241, 196, 112, 224, 135, 242, 20, 104,
+ 17, 132, 8, 181, 163, 194, 139, 3, 245, 179,
+ 227, 68, 42, 120, 211, 97, 69, 25, 244, 67,
+ 79, 14, 25, 189, 200, 143, 10, 63, 34, 228,
+ 227, 144, 17, 241, 35, 14, 61, 23, 113, 88,
+ 142, 61, 73, 190, 216, 142, 62, 248, 188, 168,
+ 66, 151, 21, 197, 67, 78, 61, 22, 249, 232,
+ 13, 150, 25, 65, 89, 144, 10, 115, 52, 57,
+ 16, 132, 248, 184, 41, 81, 61, 230, 228, 161,
+ 130, 139, 16, 230, 169, 231, 158, 255, 24, 200,
+ 79, 61, 243, 96, 67, 97, 150, 8, 169, 176,
+ 200, 62, 245, 248, 217, 103, 63, 248, 240, 32,
+ 103, 65, 245, 212, 163, 102, 130, 60, 88, 99,
+ 14, 15, 246, 168, 16, 233, 166, 156, 110, 218,
+ 78, 6, 1, 64, 216, 143, 34, 90, 80, 169,
+ 17, 63, 44, 26, 196, 15, 62, 139, 220, 131,
+ 79, 61, 160, 102, 255, 144, 1, 62, 84, 232,
+ 51, 41, 65, 211, 84, 147, 78, 58, 242, 216,
+ 67, 38, 65, 25, 168, 192, 5, 29, 225, 128,
+ 113, 15, 166, 61, 216, 147, 236, 178, 246, 224,
+ 51, 205, 171, 155, 226, 147, 137, 20, 237, 112,
+ 228, 207, 137, 25, 244, 240, 198, 42, 84, 196,
+ 217, 78, 61, 172, 46, 242, 168, 170, 237, 216,
+ 147, 206, 54, 56, 228, 208, 32, 132, 58, 210,
+ 195, 137, 15, 118, 36, 49, 138, 32, 130, 144,
+ 64, 175, 189, 248, 174, 225, 65, 175, 248, 220,
+ 67, 73, 39, 84, 140, 91, 145, 63, 80, 178,
+ 107, 79, 34, 169, 188, 113, 143, 61, 211, 240,
+ 176, 198, 27, 60, 180, 195, 163, 65, 253, 196,
+ 131, 205, 58, 93, 214, 35, 128, 61, 246, 72,
+ 193, 13, 49, 218, 184, 114, 6, 18, 162, 216,
+ 34, 10, 18, 36, 219, 114, 139, 14, 163, 144,
+ 176, 134, 30, 146, 100, 98, 143, 62, 60, 224,
+ 115, 235, 68, 58, 38, 24, 128, 10, 84, 164,
+ 18, 71, 41, 166, 172, 17, 195, 27, 166, 40,
+ 130, 79, 181, 40, 226, 115, 14, 30, 74, 240,
+ 192, 131, 7, 247, 140, 226, 202, 12, 192, 248,
+ 64, 135, 54, 142, 96, 157, 181, 35, 142, 108,
+ 65, 11, 26, 59, 20, 65, 71, 38, 84, 76,
+ 243, 229, 28, 54, 107, 216, 79, 6, 56, 254,
+ 179, 46, 63, 161, 30, 196, 104, 135, 16, 214,
+ 51, 205, 61, 166, 184, 1, 135, 27, 82, 228,
+ 255, 109, 10, 15, 245, 72, 156, 96, 159, 252,
+ 220, 156, 193, 59, 225, 100, 131, 199, 14, 163,
+ 204, 147, 135, 24, 88, 0, 3, 0, 48, 148,
+ 87, 78, 57, 49, 201, 48, 242, 5, 16, 51,
+ 8, 1, 113, 15, 84, 220, 163, 200, 34, 84,
+ 208, 83, 243, 59, 242, 184, 83, 141, 175, 211,
+ 212, 195, 240, 7, 223, 178, 77, 120, 130, 92,
+ 54, 216, 78, 59, 141, 146, 32, 5, 20, 129,
+ 220, 2, 67, 18, 80, 36, 210, 171, 10, 237,
+ 96, 168, 103, 63, 245, 124, 224, 207, 65, 133,
+ 199, 144, 137, 21, 117, 200, 114, 11, 51, 211,
+ 76, 51, 192, 245, 214, 91, 63, 128, 246, 218,
+ 19, 160, 65, 39, 166, 140, 162, 199, 38, 234,
+ 108, 130, 71, 39, 122, 144, 81, 78, 57, 188,
+ 178, 93, 252, 7, 76, 70, 250, 237, 237, 112,
+ 227, 200, 79, 6, 251, 116, 27, 105, 163, 107,
+ 228, 205, 137, 6, 219, 35, 128, 39, 76, 145,
+ 130, 53, 232, 239, 3, 28, 202, 192, 7, 234,
+ 161, 169, 91, 213, 141, 30, 66, 176, 66, 52,
+ 28, 177, 160, 135, 48, 160, 24, 67, 176, 4,
+ 35, 184, 81, 9, 81, 220, 34, 14, 138, 192,
+ 84, 156, 52, 181, 41, 38, 113, 172, 7, 248,
+ 200, 20, 9, 111, 23, 170, 12, 180, 163, 7,
+ 171, 184, 7, 21, 158, 182, 134, 81, 72, 1,
+ 23, 66, 168, 128, 97, 4, 240, 2, 55, 196,
+ 1, 21, 137, 184, 135, 62, 255, 152, 244, 165,
+ 34, 126, 136, 121, 224, 122, 195, 45, 26, 49,
+ 2, 161, 56, 100, 0, 22, 72, 134, 15, 28,
+ 1, 10, 83, 164, 34, 21, 170, 72, 196, 27,
+ 132, 230, 180, 119, 96, 138, 99, 60, 160, 7,
+ 21, 160, 118, 15, 15, 196, 32, 6, 12, 51,
+ 155, 252, 84, 192, 131, 85, 92, 49, 17, 225,
+ 43, 197, 19, 160, 160, 142, 93, 24, 102, 0,
+ 70, 104, 3, 28, 80, 145, 138, 85, 204, 129,
+ 7, 251, 168, 25, 62, 94, 197, 163, 251, 169,
+ 64, 30, 130, 104, 2, 17, 156, 152, 0, 158,
+ 56, 210, 145, 134, 17, 136, 114, 124, 0, 139,
+ 29, 188, 129, 4, 166, 64, 197, 207, 80, 97,
+ 10, 83, 144, 192, 101, 107, 88, 195, 61, 214,
+ 96, 175, 78, 154, 178, 94, 36, 40, 35, 166,
+ 158, 101, 143, 123, 164, 2, 21, 168, 40, 133,
+ 27, 220, 0, 5, 25, 164, 161, 18, 118, 252,
+ 199, 52, 96, 97, 8, 55, 88, 113, 21, 171,
+ 56, 84, 156, 234, 225, 143, 15, 76, 44, 0,
+ 2, 112, 152, 20, 96, 81, 65, 249, 228, 34,
+ 23, 0, 120, 38, 0, 32, 48, 144, 3, 0,
+ 192, 7, 102, 40, 5, 189, 4, 33, 133, 56,
+ 192, 1, 17, 106, 128, 3, 20, 112, 81, 138,
+ 82, 72, 225, 156, 82, 144, 165, 222, 160, 32,
+ 78, 55, 236, 64, 10, 100, 32, 129, 18, 202,
+ 24, 3, 87, 74, 65, 111, 112, 128, 131, 26,
+ 154, 144, 255, 6, 66, 12, 33, 151, 187, 236,
+ 165, 41, 182, 149, 143, 90, 217, 172, 31, 197,
+ 155, 88, 6, 236, 38, 136, 80, 68, 131, 0,
+ 200, 164, 192, 12, 176, 48, 131, 103, 206, 128,
+ 23, 21, 12, 0, 5, 136, 177, 7, 40, 140,
+ 162, 147, 233, 196, 133, 26, 12, 17, 8, 63,
+ 248, 1, 9, 104, 104, 67, 19, 100, 208, 4,
+ 53, 168, 161, 13, 134, 32, 68, 26, 10, 225,
+ 135, 51, 248, 225, 22, 79, 120, 167, 32, 142,
+ 64, 47, 41, 124, 243, 165, 105, 176, 197, 25,
+ 206, 0, 8, 87, 240, 226, 142, 102, 104, 67,
+ 223, 222, 160, 8, 69, 204, 97, 136, 176, 114,
+ 81, 66, 234, 198, 131, 29, 208, 129, 24, 194,
+ 40, 6, 47, 136, 65, 135, 73, 208, 33, 23,
+ 85, 11, 198, 64, 130, 145, 139, 45, 4, 130,
+ 113, 113, 116, 131, 26, 208, 48, 132, 103, 44,
+ 67, 4, 200, 56, 193, 35, 202, 80, 136, 186,
+ 150, 33, 27, 102, 136, 130, 24, 168, 113, 2,
+ 100, 48, 96, 3, 53, 160, 68, 18, 204, 41,
+ 75, 40, 192, 52, 13, 97, 248, 65, 13, 54,
+ 32, 130, 13, 60, 3, 160, 97, 104, 67, 41,
+ 18, 182, 138, 16, 14, 115, 109, 71, 204, 81,
+ 61, 214, 0, 142, 25, 116, 161, 12, 70, 128,
+ 133, 23, 104, 209, 10, 170, 97, 65, 2, 8,
+ 98, 134, 5, 162, 209, 135, 39, 124, 212, 134,
+ 180, 52, 66, 13, 228, 50, 16, 102, 255, 108,
+ 0, 8, 78, 168, 197, 51, 8, 96, 130, 107,
+ 44, 160, 130, 2, 9, 192, 49, 178, 112, 11,
+ 195, 246, 147, 166, 118, 240, 133, 118, 106, 123,
+ 71, 88, 168, 65, 155, 149, 117, 234, 16, 139,
+ 23, 128, 204, 82, 236, 3, 246, 24, 131, 21,
+ 232, 96, 139, 29, 236, 0, 10, 126, 136, 133,
+ 15, 146, 225, 8, 31, 28, 99, 32, 19, 224,
+ 64, 23, 208, 80, 10, 50, 152, 98, 12, 223,
+ 45, 66, 8, 34, 105, 144, 4, 92, 225, 7,
+ 66, 97, 198, 1, 16, 34, 128, 26, 32, 161,
+ 16, 81, 136, 2, 32, 174, 160, 155, 132, 76,
+ 35, 169, 165, 40, 96, 101, 247, 49, 68, 14,
+ 73, 21, 137, 248, 136, 7, 58, 172, 160, 13,
+ 89, 128, 2, 13, 178, 216, 194, 12, 24, 209,
+ 10, 31, 80, 83, 32, 9, 0, 64, 52, 190,
+ 182, 131, 82, 236, 64, 13, 103, 0, 66, 4,
+ 232, 27, 128, 237, 13, 68, 1, 86, 208, 5,
+ 125, 7, 114, 61, 130, 12, 32, 27, 83, 152,
+ 130, 19, 234, 240, 0, 130, 8, 96, 0, 78,
+ 25, 74, 100, 129, 198, 212, 16, 78, 23, 161,
+ 214, 77, 208, 172, 238, 145, 135, 107, 88, 193,
+ 10, 140, 136, 70, 52, 236, 0, 139, 87, 204,
+ 192, 2, 78, 20, 64, 5, 114, 129, 133, 86,
+ 236, 193, 21, 234, 232, 130, 38, 92, 113, 141,
+ 245, 252, 67, 0, 200, 208, 0, 13, 86, 208,
+ 11, 2, 32, 192, 255, 10, 123, 8, 194, 138,
+ 171, 105, 2, 26, 208, 64, 23, 9, 24, 8,
+ 50, 152, 112, 10, 34, 236, 194, 41, 211, 184,
+ 64, 9, 104, 32, 140, 7, 84, 112, 0, 102,
+ 144, 65, 41, 180, 152, 15, 69, 48, 88, 5,
+ 4, 91, 23, 66, 234, 198, 198, 121, 116, 226,
+ 18, 151, 224, 196, 14, 112, 49, 11, 14, 228,
+ 130, 49, 255, 96, 64, 52, 71, 48, 131, 25,
+ 112, 195, 15, 104, 72, 67, 25, 140, 49, 144,
+ 94, 52, 130, 207, 164, 32, 194, 10, 174, 192,
+ 7, 54, 176, 1, 18, 239, 129, 15, 13, 246,
+ 64, 10, 82, 236, 193, 7, 251, 253, 71, 1,
+ 136, 240, 7, 43, 176, 70, 0, 205, 224, 245,
+ 31, 246, 96, 133, 150, 76, 35, 12, 207, 21,
+ 68, 83, 29, 125, 100, 23, 78, 12, 110, 200,
+ 115, 157, 195, 74, 129, 137, 17, 0, 3, 4,
+ 145, 100, 6, 90, 38, 23, 141, 47, 4, 162,
+ 13, 104, 8, 131, 11, 130, 205, 0, 31, 16,
+ 97, 15, 180, 248, 2, 19, 230, 125, 138, 83,
+ 176, 129, 15, 33, 16, 200, 1, 188, 80, 239,
+ 63, 244, 89, 23, 193, 125, 4, 31, 114, 249,
+ 143, 101, 212, 186, 222, 125, 62, 234, 83, 204,
+ 240, 220, 129, 86, 182, 91, 196, 115, 240, 131,
+ 248, 81, 46, 18, 132, 194, 10, 82, 180, 194,
+ 114, 35, 240, 76, 98, 56, 162, 15, 132, 32,
+ 68, 33, 196, 224, 139, 6, 56, 37, 24, 13,
+ 255, 72, 121, 3, 30, 96, 7, 132, 179, 225,
+ 20, 124, 96, 245, 63, 246, 253, 114, 54, 144,
+ 130, 9, 62, 112, 98, 22, 188, 208, 139, 161,
+ 16, 161, 222, 53, 255, 130, 14, 117, 57, 228,
+ 84, 172, 161, 169, 12, 198, 71, 145, 18, 202,
+ 16, 138, 83, 161, 201, 62, 176, 194, 22, 88,
+ 177, 129, 106, 230, 34, 25, 93, 254, 131, 31,
+ 106, 177, 7, 38, 124, 161, 0, 9, 17, 192,
+ 53, 236, 253, 242, 83, 44, 161, 192, 7, 248,
+ 249, 41, 122, 77, 10, 26, 200, 197, 6, 65,
+ 64, 59, 31, 236, 141, 112, 90, 228, 18, 209,
+ 138, 30, 104, 163, 121, 112, 100, 73, 43, 36,
+ 3, 96, 72, 28, 29, 24, 17, 4, 90, 208,
+ 226, 26, 78, 9, 64, 5, 50, 199, 10, 86,
+ 48, 130, 106, 30, 247, 194, 121, 17, 50, 13,
+ 23, 184, 252, 222, 50, 167, 57, 41, 16, 78,
+ 135, 96, 219, 32, 18, 185, 70, 192, 18, 232,
+ 254, 114, 63, 27, 230, 217, 106, 144, 130, 180,
+ 145, 222, 119, 217, 49, 143, 31, 246, 96, 199,
+ 35, 40, 65, 137, 34, 200, 162, 12, 181, 216,
+ 66, 158, 5, 34, 106, 96, 204, 96, 4, 28,
+ 240, 1, 22, 124, 112, 245, 45, 32, 0, 184,
+ 2, 168, 222, 52, 4, 64, 128, 107, 216, 156,
+ 15, 243, 166, 5, 218, 189, 176, 249, 178, 51,
+ 162, 62, 54, 232, 130, 3, 4, 82, 0, 126,
+ 147, 254, 11, 194, 64, 106, 255, 234, 11, 56,
+ 58, 20, 74, 74, 84, 147, 238, 71, 14, 178,
+ 16, 142, 28, 204, 99, 12, 158, 16, 133, 25,
+ 104, 209, 140, 72, 66, 17, 154, 0, 24, 1,
+ 29, 176, 48, 140, 8, 72, 128, 23, 91, 160,
+ 9, 117, 160, 29, 15, 160, 12, 64, 0, 4,
+ 144, 208, 8, 163, 69, 11, 124, 134, 121, 250,
+ 166, 118, 64, 119, 5, 193, 214, 2, 180, 32,
+ 1, 193, 245, 3, 76, 80, 115, 167, 32, 116,
+ 167, 87, 4, 174, 165, 48, 164, 19, 39, 198,
+ 164, 39, 228, 162, 2, 227, 64, 13, 57, 224,
+ 14, 122, 240, 9, 178, 80, 11, 75, 160, 13,
+ 96, 39, 73, 248, 71, 12, 62, 64, 12, 0,
+ 176, 123, 190, 208, 5, 164, 64, 11, 98, 5,
+ 31, 197, 96, 5, 221, 208, 5, 65, 208, 13,
+ 219, 149, 129, 48, 151, 121, 94, 80, 115, 47,
+ 199, 8, 158, 199, 4, 202, 96, 102, 9, 0,
+ 9, 181, 240, 114, 76, 224, 2, 10, 55, 0,
+ 159, 224, 6, 130, 32, 67, 250, 131, 80, 215,
+ 230, 35, 226, 112, 13, 223, 64, 9, 224, 0,
+ 9, 221, 208, 13, 88, 208, 99, 32, 54, 110,
+ 104, 129, 127, 187, 7, 1, 142, 208, 10, 93,
+ 0, 2, 3, 129, 0, 188, 0, 101, 116, 80,
+ 12, 14, 0, 1, 87, 192, 103, 124, 80, 117,
+ 51, 7, 129, 246, 38, 129, 2, 33, 13, 167,
+ 16, 4, 106, 24, 106, 202, 224, 2, 117, 80,
+ 12, 205, 255, 33, 16, 211, 240, 2, 163, 32,
+ 52, 205, 130, 64, 109, 163, 16, 112, 35, 44,
+ 223, 112, 5, 86, 48, 3, 201, 144, 12, 24,
+ 53, 16, 5, 128, 0, 7, 80, 138, 166, 120,
+ 0, 21, 4, 1, 192, 144, 12, 51, 224, 3,
+ 61, 168, 75, 10, 208, 0, 12, 0, 118, 1,
+ 32, 1, 117, 112, 132, 15, 120, 10, 83, 192,
+ 121, 193, 102, 136, 127, 224, 118, 3, 65, 0,
+ 191, 208, 0, 193, 224, 68, 240, 129, 6, 163,
+ 128, 70, 71, 115, 137, 77, 23, 0, 174, 163,
+ 4, 59, 0, 10, 162, 0, 4, 160, 214, 16,
+ 16, 128, 5, 93, 80, 11, 78, 96, 9, 49,
+ 120, 16, 211, 80, 2, 167, 80, 11, 50, 119,
+ 12, 152, 16, 114, 128, 144, 99, 117, 208, 139,
+ 186, 200, 7, 37, 96, 140, 6, 49, 0, 153,
+ 224, 81, 30, 208, 58, 72, 131, 34, 127, 162,
+ 2, 246, 176, 6, 58, 208, 23, 16, 225, 11,
+ 145, 208, 4, 80, 160, 3, 183, 20, 108, 5,
+ 193, 12, 210, 96, 6, 83, 96, 6, 128, 104,
+ 0, 151, 32, 3, 50, 32, 114, 81, 112, 5,
+ 114, 209, 2, 128, 16, 96, 179, 96, 2, 203,
+ 69, 16, 4, 240, 2, 134, 128, 8, 166, 32,
+ 15, 42, 224, 122, 81, 162, 35, 242, 16, 10,
+ 117, 176, 12, 8, 0, 13, 9, 176, 146, 10,
+ 208, 146, 46, 249, 146, 9, 128, 0, 32, 48,
+ 3, 101, 80, 78, 181, 84, 6, 90, 255, 128,
+ 0, 4, 112, 61, 7, 112, 3, 151, 16, 8,
+ 33, 231, 7, 210, 144, 146, 29, 128, 2, 38,
+ 6, 5, 49, 37, 9, 34, 0, 13, 208, 128,
+ 7, 105, 208, 6, 253, 4, 8, 143, 224, 12,
+ 7, 192, 12, 3, 192, 12, 208, 128, 3, 73,
+ 128, 11, 179, 148, 2, 173, 19, 55, 18, 65,
+ 113, 242, 224, 9, 116, 16, 6, 58, 112, 11,
+ 180, 64, 7, 35, 128, 1, 207, 212, 150, 109,
+ 137, 22, 209, 96, 6, 182, 208, 8, 209, 240,
+ 9, 166, 112, 67, 109, 112, 8, 128, 112, 6,
+ 160, 181, 50, 79, 240, 151, 80, 16, 144, 58,
+ 224, 93, 238, 53, 10, 178, 244, 82, 252, 164,
+ 3, 57, 245, 4, 180, 4, 83, 131, 192, 151,
+ 70, 240, 9, 80, 80, 78, 157, 196, 71, 136,
+ 194, 140, 14, 241, 39, 107, 144, 9, 87, 208,
+ 9, 107, 32, 8, 183, 176, 5, 62, 0, 12,
+ 207, 132, 1, 164, 201, 150, 164, 201, 1, 51,
+ 48, 9, 77, 96, 10, 165, 32, 4, 117, 224,
+ 9, 130, 48, 10, 110, 128, 8, 109, 0, 5,
+ 238, 116, 78, 163, 176, 155, 232, 52, 47, 245,
+ 114, 4, 152, 148, 78, 178, 100, 78, 157, 180,
+ 155, 178, 36, 78, 112, 176, 3, 124, 67, 6,
+ 59, 245, 73, 169, 16, 68, 74, 23, 37, 244,
+ 48, 6, 90, 240, 8, 157, 64, 15, 201, 66,
+ 2, 103, 112, 85, 190, 231, 3, 222, 249, 157,
+ 222, 25, 13, 218, 255, 48, 4, 82, 112, 15,
+ 245, 228, 9, 215, 224, 9, 120, 243, 51, 125,
+ 243, 73, 74, 16, 74, 164, 244, 73, 162, 116,
+ 70, 80, 243, 48, 86, 84, 47, 243, 116, 15,
+ 247, 240, 6, 41, 144, 73, 196, 233, 50, 49,
+ 32, 15, 78, 195, 3, 247, 208, 42, 109, 114,
+ 51, 7, 81, 15, 229, 128, 13, 227, 48, 14,
+ 244, 16, 42, 118, 243, 6, 155, 16, 13, 196,
+ 32, 158, 221, 192, 13, 23, 154, 161, 24, 74,
+ 4, 160, 160, 4, 12, 195, 70, 99, 112, 7,
+ 107, 192, 3, 175, 148, 8, 66, 99, 58, 60,
+ 32, 15, 30, 64, 15, 244, 96, 158, 95, 100,
+ 15, 60, 64, 5, 15, 179, 69, 50, 52, 160,
+ 30, 176, 6, 8, 243, 156, 66, 211, 43, 207,
+ 162, 2, 211, 224, 15, 95, 178, 15, 251, 112,
+ 39, 13, 161, 2, 41, 8, 43, 130, 115, 63,
+ 248, 64, 2, 234, 160, 12, 86, 192, 13, 143,
+ 96, 9, 146, 32, 9, 82, 90, 165, 149, 224,
+ 9, 243, 224, 40, 129, 243, 45, 100, 128, 7,
+ 84, 64, 5, 90, 68, 5, 28, 211, 44, 201,
+ 18, 163, 51, 212, 3, 40, 4, 163, 60, 176,
+ 8, 138, 16, 67, 98, 170, 44, 49, 170, 8,
+ 111, 144, 8, 90, 116, 15, 40, 52, 13, 176,
+ 35, 49, 16, 178, 80, 201,
+ 98, 76, 11, 161, 2, 213, 240, 43, 5, 177,
+ 51, 243, 144, 13, 86, 144, 13, 148, 128, 2,
+ 232, 128, 14, 228, 255, 192, 168, 139, 74, 14,
+ 230, 64, 6, 32, 217, 14, 161, 82, 56, 246,
+ 128, 7, 236, 64, 5, 139, 192, 45, 40, 244,
+ 37, 104, 186, 15, 115, 64, 5, 251, 128, 166,
+ 248, 208, 3, 250, 160, 169, 77, 181, 8, 115,
+ 128, 66, 61, 144, 63, 138, 144, 15, 192, 20,
+ 67, 153, 98, 109, 151, 200, 40, 251, 144, 54,
+ 9, 81, 15, 38, 50, 105, 245, 64, 14, 87,
+ 32, 13, 99, 176, 14, 240, 224, 14, 238, 48,
+ 172, 71, 0, 15, 71, 112, 4, 238, 16, 3,
+ 132, 228, 32, 171, 98, 14, 163, 208, 84, 1,
+ 211, 41, 131, 52, 66, 33, 25, 41, 95, 130,
+ 15, 250, 208, 169, 216, 170, 173, 249, 179, 8,
+ 170, 186, 140, 39, 66, 113, 217, 234, 167, 20,
+ 179, 171, 147, 22, 15, 89, 224, 13, 241, 144,
+ 41, 190, 66, 68, 154, 2, 175, 231, 183, 33,
+ 107, 192, 14, 111, 208, 64, 123, 82, 56, 46,
+ 84, 169, 121, 130, 80, 46, 244, 54, 9, 148,
+ 173, 154, 130, 153, 9, 18, 176, 137, 82, 16,
+ 237, 48, 13, 19, 211, 171, 229, 176, 35, 148,
+ 154, 39, 161, 18, 177, 1, 80, 169, 114, 163,
+ 15, 100, 48, 6, 96, 130, 34, 125, 162, 42,
+ 133, 163, 167, 153, 201, 15, 4, 179, 33, 12,
+ 225, 14, 216, 160, 176, 151, 168, 40, 19, 35,
+ 16, 252, 160, 15, 251, 32, 15, 233, 128, 38,
+ 73, 50, 59, 40, 34, 146, 15, 34, 14, 234,
+ 255, 146, 178, 11, 177, 36, 105, 243, 14, 130,
+ 58, 34, 56, 203, 60, 8, 42, 55, 222, 144,
+ 3, 130, 179, 177, 19, 193, 40, 137, 162, 32,
+ 63, 155, 179, 36, 24, 150, 75, 219, 39, 233,
+ 64, 0, 73, 123, 35, 11, 132, 32, 7, 251,
+ 32, 70, 155, 32, 77, 235, 180, 26, 43, 32,
+ 94, 251, 181, 96, 27, 182, 98, 59, 182, 100,
+ 11, 182, 108, 56, 110, 180, 133, 16, 34, 49,
+ 25, 45, 193, 16, 128, 97, 31, 0, 208, 19,
+ 113, 91, 18, 105, 123, 16, 44, 65, 17, 119,
+ 219, 16, 3, 144, 145, 166, 97, 0, 57, 161,
+ 18, 126, 251, 20, 77, 113, 102, 60, 225, 19,
+ 20, 192, 19, 218, 65, 19, 54, 129, 19, 58,
+ 81, 184, 153, 49, 18, 59, 113, 27, 141, 187,
+ 0, 144, 113, 19, 52, 54, 184, 130, 27, 21,
+ 39, 129, 25, 111, 97, 22, 91, 113, 22, 72,
+ 49, 31, 94, 81, 20, 85, 113, 21, 89, 1,
+ 31, 92, 225, 21, 61, 246, 19, 159, 171, 186,
+ 90, 193, 21, 159, 161, 0, 93, 33, 16, 157,
+ 91, 1, 110, 177, 22, 21, 16, 23, 155, 43,
+ 23, 1, 240, 105, 67, 193, 23, 126, 177, 0,
+ 167, 139, 24, 52, 161, 23, 3, 160, 23, 192,
+ 11, 31, 31, 177, 0, 18, 144, 188, 4, 160,
+ 18, 201, 219, 0, 150, 49, 18, 189, 203, 24,
+ 66, 81, 21, 144, 81, 31, 29, 33, 22, 242,
+ 49, 1, 161, 17, 24, 105, 182, 251, 182, 123,
+ 113, 25, 190, 65, 190, 232, 197, 19, 94, 65,
+ 91, 191, 33, 22, 63, 1, 24, 159, 225, 189,
+ 172, 241, 15, 164, 17, 191, 219, 43, 23, 14,
+ 0, 0, 12, 112, 27, 178, 209, 26, 109, 187,
+ 190, 229, 251, 15, 251, 251, 15, 175, 241, 19,
+ 1, 252, 26, 0, 204, 26, 237, 59, 18, 181,
+ 33, 185, 180, 11, 0, 5, 86, 191, 3, 65,
+ 1, 187, 64, 29, 182, 129, 28, 196, 33, 190,
+ 254, 235, 29, 69, 113, 28, 194, 17, 1, 22,
+ 176, 19, 150, 129, 28, 30, 156, 19, 28, 140,
+ 0, 20, 48, 189, 209, 49, 29, 213, 113, 24,
+ 61, 161, 28, 124, 155, 17, 152, 33, 0, 202,
+ 97, 1, 186, 97, 30, 19, 80, 28, 253, 107,
+ 190, 227, 155, 25, 225, 81, 185, 64, 209, 195,
+ 173, 97, 21, 93, 241, 182, 50, 12, 0, 52,
+ 12, 31, 242, 65, 31, 101, 123, 17, 15, 144,
+ 136, 75, 28, 19, 118, 81, 183, 79, 140, 18,
+ 238, 56, 197, 86, 124, 197, 49, 17, 16, 0,
+ 59 };
+
+unsigned char php4_logo[] = {
+ 71, 73, 70, 56, 57, 97, 100, 0, 56, 0,
+ 247, 255, 0, 255, 255, 255, 8, 8, 8, 16,
+ 16, 16, 24, 24, 24, 33, 33, 33, 41, 41,
+ 41, 49, 49, 49, 57, 57, 57, 66, 66, 66,
+ 74, 74, 74, 82, 82, 82, 90, 90, 90, 99,
+ 99, 99, 115, 115, 115, 123, 123, 123, 132, 132,
+ 132, 140, 140, 140, 148, 148, 148, 156, 156, 156,
+ 165, 165, 165, 173, 173, 173, 181, 181, 181, 189,
+ 189, 189, 198, 198, 198, 206, 206, 206, 214, 214,
+ 214, 222, 222, 222, 231, 231, 231, 239, 239, 239,
+ 247, 247, 247, 115, 115, 90, 156, 156, 115, 140,
+ 140, 99, 132, 132, 90, 165, 165, 107, 214, 214,
+ 115, 156, 156, 82, 181, 181, 90, 189, 189, 90,
+ 198, 198, 90, 222, 222, 99, 214, 214, 90, 222,
+ 222, 90, 206, 206, 82, 41, 41, 16, 231, 231,
+ 90, 107, 107, 41, 214, 214, 82, 173, 173, 66,
+ 239, 239, 90, 222, 222, 82, 66, 66, 24, 156,
+ 156, 57, 231, 231, 82, 239, 239, 82, 99, 99,
+ 33, 198, 198, 66, 148, 148, 49, 132, 132, 41,
+ 82, 82, 24, 16, 16, 0, 214, 222, 107, 181,
+ 189, 82, 206, 214, 90, 189, 198, 107, 173, 181,
+ 90, 165, 173, 99, 148, 156, 82, 148, 156, 99,
+ 173, 181, 132, 140, 148, 99, 148, 156, 115, 156,
+ 165, 115, 99, 107, 90, 148, 156, 140, 132, 140,
+ 132, 115, 123, 115, 247, 255, 255, 198, 206, 206,
+ 140, 148, 148, 156, 165, 165, 115, 123, 123, 239,
+ 255, 255, 123, 132, 132, 66, 74, 74, 231, 247,
+ 255, 189, 198, 206, 222, 239, 255, 90, 99, 107,
+ 231, 239, 247, 239, 247, 255, 198, 206, 214, 165,
+ 173, 181, 99, 107, 115, 214, 222, 231, 148, 156,
+ 165, 115, 123, 132, 82, 90, 99, 132, 148, 173,
+ 222, 231, 247, 189, 198, 214, 156, 165, 181, 57,
+ 66, 82, 24, 33, 49, 198, 206, 222, 165, 173,
+ 189, 206, 222, 255, 181, 198, 231, 148, 165, 198,
+ 66, 74, 90, 90, 107, 140, 74, 90, 123, 33,
+ 41, 57, 49, 66, 99, 214, 222, 239, 206, 214,
+ 231, 181, 189, 206, 140, 148, 165, 115, 123, 140,
+ 107, 115, 132, 82, 90, 107, 74, 82, 99, 49,
+ 57, 74, 181, 198, 239, 156, 173, 214, 107, 123,
+ 165, 99, 115, 156, 90, 107, 148, 82, 99, 140,
+ 66, 82, 123, 57, 74, 115, 222, 231, 255, 189,
+ 198, 222, 156, 165, 189, 123, 132, 156, 156, 173,
+ 222, 148, 165, 214, 123, 140, 189, 115, 132, 181,
+ 90, 107, 156, 24, 33, 57, 214, 222, 247, 198,
+ 206, 231, 181, 189, 214, 173, 181, 206, 148, 156,
+ 181, 132, 140, 165, 107, 115, 140, 82, 90, 115,
+ 66, 74, 99, 148, 165, 222, 107, 123, 173, 41,
+ 49, 74, 90, 107, 165, 82, 99, 156, 66, 82,
+ 132, 156, 165, 198, 123, 132, 165, 90, 99, 132,
+ 107, 123, 181, 57, 66, 99, 99, 115, 173, 82,
+ 99, 165, 206, 214, 247, 181, 189, 222, 173, 181,
+ 214, 165, 173, 206, 148, 156, 189, 132, 140, 173,
+ 156, 165, 206, 123, 132, 173, 74, 82, 115, 66,
+ 74, 107, 49, 57, 90, 57, 66, 107, 41, 49,
+ 82, 148, 156, 198, 140, 148, 189, 132, 140, 181,
+ 115, 123, 165, 107, 115, 156, 99, 107, 148, 82,
+ 90, 132, 74, 82, 123, 66, 74, 115, 49, 57,
+ 99, 189, 198, 255, 156, 165, 214, 148, 156, 206,
+ 140, 148, 198, 132, 140, 189, 123, 132, 181, 123,
+ 132, 189, 99, 107, 156, 90, 99, 148, 82, 90,
+ 140, 90, 99, 156, 66, 74, 123, 57, 66, 115,
+ 165, 173, 231, 140, 148, 206, 107, 115, 173, 99,
+ 107, 165, 82, 90, 148, 74, 82, 140, 99, 107,
+ 173, 82, 90, 156, 231, 231, 239, 239, 239, 247,
+ 247, 247, 255, 198, 198, 206, 206, 206, 214, 181,
+ 181, 189, 165, 165, 173, 173, 173, 181, 189, 189,
+ 198, 140, 140, 148, 115, 115, 123, 231, 231, 247,
+ 239, 239, 255, 107, 107, 115, 123, 123, 132, 206,
+ 206, 222, 214, 214, 231, 222, 222, 239, 99, 99,
+ 107, 198, 198, 214, 90, 90, 99, 74, 74, 82,
+ 156, 156, 173, 140, 140, 156, 148, 148, 165, 132,
+ 132, 148, 198, 198, 222, 206, 206, 231, 165, 165,
+ 189, 173, 173, 198, 107, 107, 123, 148, 148, 173,
+ 181, 181, 214, 90, 90, 107, 41, 41, 49, 82,
+ 82, 99, 123, 123, 148, 74, 74, 90, 99, 99,
+ 123, 90, 90, 115, 57, 57, 74, 74, 74, 99,
+ 66, 66, 90, 24, 24, 33, 57, 57, 82, 49,
+ 49, 74, 41, 41, 66, 41, 41, 74, 0, 0,
+ 0, 44, 0, 0, 0, 0, 100, 0, 56, 0,
+ 0, 8, 255, 0, 1, 8, 28, 72, 176, 160,
+ 193, 131, 8, 19, 42, 92, 200, 176, 161, 195,
+ 135, 16, 35, 74, 156, 72, 177, 162, 197, 139,
+ 24, 51, 58, 108, 210, 1, 218, 51, 112, 224,
+ 188, 120, 1, 247, 12, 90, 135, 104, 26, 7,
+ 62, 131, 36, 171, 15, 177, 63, 179, 78, 101,
+ 72, 249, 16, 218, 55, 50, 144, 78, 201, 154,
+ 21, 76, 216, 178, 101, 128, 134, 13, 3, 42,
+ 116, 217, 31, 90, 157, 98, 173, 163, 227, 13,
+ 26, 69, 104, 166, 50, 45, 219, 132, 139, 213,
+ 170, 77, 203, 152, 117, 242, 66, 243, 96, 7,
+ 47, 143, 78, 93, 10, 246, 243, 103, 209, 160,
+ 203, 134, 50, 27, 198, 172, 237, 48, 91, 204,
+ 54, 109, 178, 37, 215, 86, 45, 84, 236, 154,
+ 58, 212, 230, 107, 217, 170, 16, 62, 84, 180,
+ 80, 97, 194, 200, 155, 183, 105, 58, 116, 237,
+ 48, 199, 84, 172, 100, 139, 22, 17, 243, 169,
+ 73, 152, 166, 203, 139, 52, 101, 218, 204, 185,
+ 51, 49, 81, 146, 53, 153, 141, 43, 119, 19,
+ 32, 90, 145, 200, 56, 69, 8, 46, 81, 160,
+ 16, 47, 108, 196, 176, 225, 226, 159, 11, 27,
+ 45, 140, 12, 219, 116, 78, 113, 198, 111, 166,
+ 126, 133, 82, 22, 76, 50, 49, 77, 196, 58,
+ 111, 110, 166, 188, 57, 103, 230, 202, 125, 238,
+ 222, 20, 40, 144, 173, 78, 86, 124, 15, 132,
+ 246, 107, 19, 137, 217, 49, 98, 232, 255, 248,
+ 247, 111, 134, 108, 27, 66, 134, 221, 130, 194,
+ 193, 34, 52, 66, 189, 20, 125, 234, 19, 57,
+ 185, 243, 251, 248, 243, 111, 246, 25, 247, 86,
+ 177, 97, 238, 112, 37, 80, 41, 203, 120, 32,
+ 219, 108, 48, 144, 87, 94, 120, 179, 17, 177,
+ 12, 37, 21, 104, 7, 209, 24, 164, 240, 146,
+ 136, 34, 202, 216, 167, 95, 38, 208, 233, 215,
+ 33, 135, 249, 17, 179, 12, 93, 129, 220, 98,
+ 136, 55, 207, 92, 130, 135, 12, 224, 213, 16,
+ 192, 63, 44, 148, 103, 195, 129, 49, 120, 178,
+ 9, 24, 51, 65, 164, 205, 26, 136, 32, 131,
+ 161, 134, 27, 118, 6, 139, 2, 3, 232, 67,
+ 64, 60, 236, 4, 249, 161, 114, 196, 236, 86,
+ 76, 49, 181, 108, 50, 196, 129, 54, 204, 0,
+ 35, 13, 11, 130, 135, 222, 50, 120, 80, 32,
+ 161, 66, 209, 140, 178, 199, 49, 192, 40, 163,
+ 89, 144, 206, 65, 34, 128, 130, 5, 160, 129,
+ 230, 114, 207, 61, 183, 200, 84, 184, 188, 242,
+ 3, 120, 227, 253, 131, 67, 130, 51, 104, 25,
+ 67, 10, 203, 220, 2, 65, 142, 11, 105, 163,
+ 134, 46, 136, 132, 114, 230, 155, 205, 89, 163,
+ 224, 63, 12, 148, 194, 104, 126, 205, 16, 211,
+ 202, 61, 224, 97, 249, 207, 13, 48, 140, 199,
+ 2, 12, 224, 197, 208, 130, 27, 183, 60, 96,
+ 193, 66, 77, 12, 114, 197, 26, 159, 44, 58,
+ 105, 103, 205, 68, 255, 240, 40, 4, 176, 188,
+ 154, 95, 43, 84, 156, 199, 195, 163, 143, 234,
+ 48, 155, 108, 119, 148, 234, 101, 66, 219, 104,
+ 161, 69, 42, 153, 184, 106, 235, 102, 192, 52,
+ 240, 104, 5, 138, 44, 219, 92, 165, 185, 80,
+ 193, 96, 14, 51, 100, 59, 67, 140, 60, 204,
+ 128, 67, 120, 178, 77, 114, 139, 3, 19, 124,
+ 57, 80, 52, 77, 104, 17, 139, 51, 210, 54,
+ 7, 75, 2, 10, 6, 240, 77, 187, 206, 185,
+ 178, 15, 139, 52, 202, 198, 39, 131, 178, 181,
+ 224, 215, 20, 229, 30, 180, 77, 19, 224, 40,
+ 162, 44, 103, 176, 160, 51, 14, 60, 11, 55,
+ 204, 112, 56, 237, 204, 115, 137, 114, 116, 16,
+ 16, 47, 55, 14, 135, 115, 135, 33, 191, 116,
+ 166, 10, 195, 32, 59, 60, 78, 23, 118, 160,
+ 2, 204, 102, 197, 188, 18, 4, 149, 224, 242,
+ 121, 94, 120, 64, 104, 130, 135, 3, 195, 22,
+ 52, 176, 54, 201, 28, 204, 217, 55, 6, 240,
+ 234, 243, 63, 5, 116, 243, 9, 103, 236, 252,
+ 236, 179, 1, 230, 68, 155, 137, 57, 70, 63,
+ 26, 128, 2, 235, 92, 178, 76, 43, 73, 132,
+ 122, 30, 14, 255, 236, 224, 167, 18, 204, 96,
+ 97, 234, 151, 77, 100, 161, 69, 34, 236, 222,
+ 215, 140, 23, 3, 52, 205, 43, 3, 209, 54,
+ 51, 129, 218, 188, 158, 211, 76, 51, 15, 192,
+ 173, 224, 0, 212, 92, 130, 75, 43, 37, 188,
+ 255, 124, 32, 14, 44, 130, 215, 131, 50, 172,
+ 56, 48, 168, 65, 114, 84, 1, 75, 217, 247,
+ 41, 114, 1, 175, 1, 68, 254, 162, 207, 216,
+ 100, 162, 136, 3, 118, 43, 152, 0, 27, 153,
+ 112, 227, 180, 228, 63, 19, 176, 197, 50, 160,
+ 176, 114, 39, 203, 252, 138, 42, 198, 38, 225,
+ 144, 219, 30, 65, 218, 32, 202, 248, 125, 177,
+ 200, 170, 32, 3, 27, 104, 160, 251, 5, 14,
+ 172, 169, 32, 1, 191, 244, 2, 175, 130, 17,
+ 96, 96, 60, 6, 20, 244, 204, 38, 33, 191,
+ 32, 16, 47, 6, 186, 107, 144, 1, 5, 10,
+ 240, 250, 64, 42, 182, 184, 130, 199, 9, 86,
+ 255, 26, 195, 8, 178, 12, 19, 134, 225, 24,
+ 24, 68, 202, 33, 202, 108, 152, 138, 231, 10,
+ 98, 99, 138, 41, 169, 64, 66, 72, 52, 22,
+ 240, 234, 14, 36, 22, 147, 23, 192, 52, 165,
+ 244, 95, 202, 55, 212, 120, 84, 1, 8, 1,
+ 139, 180, 145, 167, 0, 80, 121, 159, 41, 210,
+ 1, 141, 225, 145, 71, 1, 233, 200, 196, 38,
+ 92, 129, 11, 35, 164, 192, 79, 40, 40, 66,
+ 31, 54, 145, 7, 7, 60, 128, 2, 175, 27,
+ 72, 22, 144, 1, 12, 157, 41, 231, 17, 206,
+ 83, 80, 57, 148, 163, 8, 104, 40, 143, 60,
+ 231, 32, 195, 228, 254, 65, 0, 72, 40, 135,
+ 11, 143, 66, 0, 33, 202, 240, 168, 5, 68,
+ 176, 51, 138, 192, 198, 163, 255, 14, 32, 135,
+ 205, 12, 227, 73, 111, 136, 194, 17, 144, 240,
+ 129, 37, 252, 97, 25, 184, 24, 135, 3, 200,
+ 181, 1, 131, 60, 2, 50, 65, 242, 134, 1,
+ 255, 33, 128, 66, 52, 39, 29, 41, 36, 79,
+ 53, 174, 241, 40, 5, 68, 165, 51, 66, 84,
+ 208, 2, 222, 145, 70, 242, 60, 64, 82, 202,
+ 65, 199, 16, 193, 193, 25, 209, 200, 165, 45,
+ 204, 192, 69, 37, 194, 145, 13, 195, 81, 160,
+ 138, 6, 137, 5, 49, 128, 100, 54, 105, 204,
+ 208, 0, 181, 82, 78, 58, 10, 240, 168, 107,
+ 80, 224, 81, 14, 136, 69, 103, 146, 225, 44,
+ 5, 61, 192, 20, 236, 35, 15, 5, 122, 209,
+ 28, 48, 60, 42, 1, 116, 132, 83, 38, 6,
+ 41, 154, 86, 180, 225, 1, 75, 152, 0, 6,
+ 66, 88, 144, 62, 44, 195, 132, 157, 249, 69,
+ 5, 122, 216, 49, 88, 25, 50, 94, 207, 168,
+ 155, 130, 38, 160, 180, 205, 248, 98, 1, 143,
+ 154, 64, 42, 28, 24, 128, 12, 244, 114, 57,
+ 12, 120, 20, 3, 230, 128, 159, 69, 180, 162,
+ 21, 52, 3, 36, 66, 254, 48, 140, 32, 193,
+ 66, 2, 143, 234, 70, 40, 88, 8, 133, 28,
+ 70, 3, 152, 10, 186, 192, 135, 56, 113, 128,
+ 71, 89, 193, 20, 249, 251, 199, 0, 188, 144,
+ 190, 88, 190, 240, 31, 17, 32, 4, 136, 148,
+ 195, 28, 80, 240, 195, 1, 21, 88, 136, 48,
+ 152, 65, 255, 72, 231, 148, 162, 146, 228, 137,
+ 64, 115, 30, 241, 206, 39, 64, 131, 145, 228,
+ 25, 128, 55, 148, 3, 137, 45, 234, 195, 27,
+ 133, 152, 33, 2, 212, 209, 28, 73, 60, 74,
+ 0, 27, 72, 100, 156, 56, 147, 11, 76, 144,
+ 203, 92, 4, 9, 134, 45, 52, 177, 164, 230,
+ 168, 131, 152, 133, 248, 16, 44, 0, 170, 78,
+ 47, 100, 64, 162, 242, 236, 76, 0, 53, 247,
+ 8, 166, 41, 40, 9, 112, 220, 140, 50, 58,
+ 145, 206, 127, 52, 0, 26, 219, 188, 15, 49,
+ 246, 177, 143, 143, 42, 164, 19, 88, 241, 144,
+ 23, 210, 73, 128, 50, 92, 66, 21, 168, 168,
+ 3, 54, 170, 247, 168, 8, 188, 195, 81, 10,
+ 106, 128, 70, 57, 212, 205, 172, 150, 34, 10,
+ 143, 226, 70, 212, 84, 209, 9, 67, 180, 99,
+ 139, 255, 48, 0, 7, 182, 58, 79, 14, 45,
+ 3, 19, 249, 160, 25, 72, 7, 194, 142, 91,
+ 48, 67, 63, 138, 200, 0, 228, 64, 231, 51,
+ 7, 160, 33, 17, 186, 36, 143, 4, 124, 209,
+ 153, 68, 176, 116, 2, 165, 160, 170, 254, 36,
+ 55, 195, 187, 101, 192, 77, 249, 41, 6, 28,
+ 224, 129, 207, 185, 10, 228, 25, 212, 209, 15,
+ 44, 222, 150, 185, 127, 60, 0, 28, 161, 128,
+ 5, 56, 201, 115, 141, 100, 116, 134, 19, 14,
+ 252, 135, 52, 74, 129, 80, 187, 25, 0, 3,
+ 114, 40, 169, 114, 90, 1, 135, 108, 255, 60,
+ 224, 2, 12, 145, 196, 127, 242, 83, 10, 204,
+ 217, 13, 1, 21, 248, 198, 54, 209, 25, 175,
+ 133, 118, 70, 77, 10, 18, 128, 23, 216, 209,
+ 88, 163, 9, 192, 1, 28, 240, 130, 105, 241,
+ 211, 12, 201, 154, 225, 1, 17, 208, 0, 67,
+ 192, 225, 31, 98, 64, 231, 187, 155, 73, 135,
+ 98, 255, 161, 128, 5, 152, 119, 1, 12, 104,
+ 128, 4, 50, 208, 129, 82, 64, 71, 28, 220,
+ 56, 111, 3, 126, 200, 25, 113, 48, 224, 188,
+ 15, 248, 70, 57, 30, 53, 128, 243, 154, 151,
+ 27, 15, 168, 0, 7, 160, 1, 9, 217, 62,
+ 103, 25, 175, 128, 67, 23, 228, 218, 144, 117,
+ 8, 162, 24, 248, 1, 71, 107, 7, 0, 142,
+ 111, 88, 248, 27, 115, 112, 196, 35, 96, 49,
+ 221, 205, 152, 226, 194, 22, 230, 100, 103, 254,
+ 119, 225, 57, 112, 194, 166, 228, 113, 64, 22,
+ 64, 60, 7, 52, 108, 184, 195, 249, 113, 197,
+ 25, 232, 65, 62, 135, 116, 192, 19, 174, 216,
+ 132, 115, 20, 161, 129, 25, 30, 64, 146, 244,
+ 114, 78, 40, 124, 75, 158, 9, 176, 245, 77,
+ 213, 133, 195, 61, 31, 16, 48, 135, 124, 227,
+ 13, 172, 168, 166, 114, 98, 49, 75, 53, 30,
+ 19, 86, 237, 250, 197, 104, 85, 123, 101, 52,
+ 85, 183, 31, 112, 104, 64, 55, 178, 27, 17,
+ 47, 172, 34, 199, 162, 228, 3, 4, 30, 213,
+ 0, 24, 7, 25, 255, 97, 47, 92, 167, 129,
+ 241, 147, 62, 92, 192, 1, 14, 220, 48, 28,
+ 110, 37, 226, 13, 86, 128, 162, 24, 26, 74,
+ 199, 150, 43, 247, 230, 230, 68, 84, 65, 7,
+ 152, 23, 163, 154, 161, 9, 87, 192, 161, 31,
+ 220, 232, 198, 215, 40, 146, 129, 55, 128, 194,
+ 24, 203, 216, 204, 51, 20, 64, 128, 78, 23,
+ 160, 12, 115, 110, 23, 23, 10, 208, 105, 2,
+ 56, 128, 12, 139, 102, 6, 109, 249, 145, 231,
+ 0, 179, 82, 34, 29, 176, 67, 43, 114, 81,
+ 12, 77, 168, 35, 11, 208, 200, 117, 22, 52,
+ 10, 222, 121, 246, 250, 215, 162, 100, 14, 33,
+ 160, 129, 107, 104, 104, 67, 146, 192, 246, 117,
+ 51, 156, 225, 138, 126, 48, 130, 30, 81, 48,
+ 156, 5, 44, 11, 17, 40, 176, 162, 21, 160,
+ 216, 68, 63, 11, 29, 100, 70, 7, 98, 31,
+ 140, 232, 71, 235, 176, 123, 1, 106, 71, 100,
+ 26, 245, 120, 102, 142, 53, 19, 106, 110, 123,
+ 136, 67, 196, 216, 4, 109, 225, 208, 134, 62,
+ 50, 153, 80, 41, 225, 64, 53, 236, 241, 204,
+ 63, 223, 181, 173, 238, 86, 146, 84, 4, 241,
+ 10, 48, 183, 161, 213, 16, 168, 128, 52, 23,
+ 163, 1, 9, 240, 251, 21, 173, 200, 113, 166,
+ 231, 230, 235, 96, 91, 188, 226, 24, 7, 239,
+ 220, 152, 227, 140, 98, 180, 2, 204, 244, 110,
+ 192, 3, 252, 200, 222, 174, 24, 164, 3, 26,
+ 255, 152, 64, 61, 42, 241, 10, 136, 187, 162,
+ 24, 153, 6, 81, 187, 23, 13, 34, 209, 20,
+ 3, 20, 152, 184, 51, 38, 228, 97, 219, 110,
+ 64, 128, 2, 37, 55, 57, 66, 58, 48, 189,
+ 110, 192, 3, 20, 251, 120, 197, 62, 114, 97,
+ 140, 77, 48, 195, 25, 246, 217, 184, 204, 51,
+ 46, 115, 138, 39, 75, 19, 204, 40, 134, 43,
+ 90, 129, 137, 126, 244, 131, 31, 248, 88, 176,
+ 7, 35, 0, 116, 115, 11, 29, 0, 40, 183,
+ 128, 4, 186, 97, 143, 74, 236, 3, 19, 152,
+ 80, 122, 196, 113, 81, 12, 167, 47, 195, 25,
+ 151, 113, 206, 101, 68, 19, 151, 98, 24, 3,
+ 20, 92, 247, 186, 215, 205, 16, 134, 86, 27,
+ 78, 2, 22, 208, 128, 217, 207, 78, 16, 14,
+ 100, 192, 2, 19, 128, 64, 54, 236, 145, 135,
+ 124, 188, 2, 19, 254, 128, 187, 210, 33, 142,
+ 109, 80, 120, 222, 243, 185, 120, 102, 203, 187,
+ 46, 248, 126, 232, 161, 13, 120, 88, 240, 3,
+ 86, 255, 4, 196, 103, 128, 3, 139, 103, 252,
+ 65, 56, 176, 1, 12, 84, 96, 2, 79, 120,
+ 64, 59, 186, 128, 7, 121, 84, 62, 31, 68,
+ 125, 5, 63, 50, 159, 121, 126, 232, 97, 31,
+ 102, 48, 3, 61, 242, 16, 6, 44, 112, 35,
+ 27, 146, 94, 125, 4, 36, 80, 1, 232, 117,
+ 32, 246, 178, 95, 72, 7, 56, 160, 1, 12,
+ 88, 128, 2, 19, 136, 0, 83, 4, 32, 176,
+ 132, 213, 143, 252, 252, 30, 76, 255, 3, 166,
+ 176, 250, 241, 71, 96, 2, 20, 176, 0, 244,
+ 96, 159, 125, 198, 111, 63, 119, 211, 184, 128,
+ 5, 42, 64, 129, 254, 79, 224, 255, 0, 72,
+ 1, 21, 80, 1, 22, 112, 1, 208, 179, 1,
+ 244, 87, 127, 10, 232, 21, 215, 7, 123, 28,
+ 0, 123, 215, 119, 125, 11, 56, 129, 20, 88,
+ 129, 22, 120, 129, 24, 152, 129, 14, 17, 16,
+ 0, 59 };
diff --git a/main/main.c b/main/main.c
new file mode 100644
index 0000000000..841f4327d3
--- /dev/null
+++ b/main/main.c
@@ -0,0 +1,2222 @@
+/*
+ +----------------------------------------------------------------------+
+ | 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 "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
+
+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;
+
+#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 (php3_ini.log_errors || php3_ini.display_errors) {
+ va_start(args, format);
+ size = vsnprintf(buffer, sizeof(buffer) - 1, format, args);
+ va_end(args);
+ buffer[sizeof(buffer) - 1] = 0;
+
+ if (php3_ini.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 (php3_ini.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 (php3_ini.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 (php3_ini.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;
+ EG(precision) = php3_ini.precision;
+ }
+
+ 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 */
+
+ zend_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("precision", &php3_ini.precision) == FAILURE) {
+ php3_ini.precision = 14;
+ }
+ if (cfg_get_string("SMTP", &php3_ini.smtp) == FAILURE) {
+ php3_ini.smtp = "localhost";
+ }
+ if (cfg_get_string("sendmail_path", &php3_ini.sendmail_path) == FAILURE
+ || !php3_ini.sendmail_path[0]) {
+#ifdef PHP_PROG_SENDMAIL
+ php3_ini.sendmail_path = PHP_PROG_SENDMAIL " -t";
+#else
+ php3_ini.sendmail_path = NULL;
+#endif
+ }
+ if (cfg_get_string("sendmail_from", &php3_ini.sendmail_from) == FAILURE) {
+ php3_ini.sendmail_from = NULL;
+ }
+ 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("track_errors", &php3_ini.track_errors) == FAILURE) {
+ php3_ini.track_errors = 0;
+ }
+ if (cfg_get_long("display_errors", &php3_ini.display_errors) == FAILURE) {
+ php3_ini.display_errors = 1;
+ }
+ if (cfg_get_long("log_errors", &php3_ini.log_errors) == FAILURE) {
+ php3_ini.log_errors = 0;
+ }
+ if (cfg_get_long("warn_plus_overloading", &php3_ini.warn_plus_overloading) == FAILURE) {
+ php3_ini.warn_plus_overloading = 0;
+ }
+ if (cfg_get_long("magic_quotes_gpc", &php3_ini.magic_quotes_gpc) == FAILURE) {
+ php3_ini.magic_quotes_gpc = MAGIC_QUOTES;
+ }
+ if (cfg_get_long("magic_quotes_runtime", &php3_ini.magic_quotes_runtime) == FAILURE) {
+ php3_ini.magic_quotes_runtime = MAGIC_QUOTES;
+ }
+ if (cfg_get_long("magic_quotes_sybase", &php3_ini.magic_quotes_sybase) == FAILURE) {
+ php3_ini.magic_quotes_sybase = 0;
+ }
+ 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_long("short_open_tag", &php3_ini.short_open_tag) == FAILURE) {
+ php3_ini.short_open_tag = DEFAULT_SHORT_OPEN_TAG;
+ }
+ if (cfg_get_long("asp_tags", &php3_ini.asp_tags) == FAILURE) {
+ php3_ini.asp_tags = 0;
+ }
+ 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("safe_mode", &php3_ini.safe_mode) == FAILURE) {
+ php3_ini.safe_mode = PHP_SAFE_MODE;
+ }
+ if (cfg_get_string("safe_mode_exec_dir", &php3_ini.safe_mode_exec_dir) == FAILURE) {
+#ifdef PHP_SAFE_MODE_EXEC_DIR
+ php3_ini.safe_mode_exec_dir = PHP_SAFE_MODE_EXEC_DIR;
+#else
+ php3_ini.safe_mode_exec_dir = "/";
+#endif
+ }
+ 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("auto_prepend_file", &php3_ini.auto_prepend_file) == FAILURE) {
+ if ((temp = getenv("PHP_AUTO_PREPEND_FILE"))) {
+ php3_ini.auto_prepend_file = temp;
+ } else {
+ php3_ini.auto_prepend_file = NULL;
+ }
+ }
+ if (cfg_get_string("auto_append_file", &php3_ini.auto_append_file) == FAILURE) {
+ if ((temp = getenv("PHP_AUTO_APPEND_FILE"))) {
+ php3_ini.auto_append_file = temp;
+ } else {
+ php3_ini.auto_append_file = 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("sql.safe_mode", &php3_ini.sql_safe_mode) == FAILURE) {
+ php3_ini.sql_safe_mode = 0;
+ }
+ /* Syntax highlighting */
+ if (cfg_get_string("highlight.comment", &php3_ini.highlight_comment) == FAILURE) {
+ php3_ini.highlight_comment = HL_COMMENT_COLOR;
+ }
+ if (cfg_get_string("highlight.default", &php3_ini.highlight_default) == FAILURE) {
+ php3_ini.highlight_default = HL_DEFAULT_COLOR;
+ }
+ if (cfg_get_string("highlight.html", &php3_ini.highlight_html) == FAILURE) {
+ php3_ini.highlight_html = HL_HTML_COLOR;
+ }
+ if (cfg_get_string("highlight.string", &php3_ini.highlight_string) == FAILURE) {
+ php3_ini.highlight_string = HL_STRING_COLOR;
+ }
+ if (cfg_get_string("highlight.bg", &php3_ini.highlight_bg) == FAILURE) {
+ php3_ini.highlight_bg = HL_BG_COLOR;
+ }
+ if (cfg_get_string("highlight.keyword", &php3_ini.highlight_keyword) == FAILURE) {
+ php3_ini.highlight_keyword = HL_KEYWORD_COLOR;
+ }
+ 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;
+
+#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;
+
+ zuv.short_tags = DEFAULT_SHORT_OPEN_TAG;
+ zuv.asp_tags = 0;
+
+ zend_startup(&zuf, &zuv, NULL);
+
+ zend_ini_mstartup();
+
+#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);
+
+
+
+ /* We cannot do the config starup until after all the above
+ happens, otherwise loading modules from ini file breaks */
+#if !USE_SAPI
+ if (php3_config_ini_startup(ELS_C) == FAILURE) {
+ return FAILURE;
+ }
+#endif
+
+ 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()
+{
+ CLS_FETCH();
+ ELS_FETCH();
+
+ zend_ini_mshutdown();
+
+#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();
+ 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 0
+ if (php3_ini.auto_prepend_file && php3_ini.auto_prepend_file[0]) {
+ require_filename(php3_ini.auto_prepend_file CLS_CC);
+ }
+ require_file(primary_file CLS_CC);
+ if (php3_ini.auto_append_file && php3_ini.auto_append_file[0]) {
+ require_filename(php3_ini.auto_append_file CLS_CC);
+ }
+ pass_two(CG(main_op_array));
+#endif
+
+ if (php3_ini.auto_prepend_file && php3_ini.auto_prepend_file[0]) {
+ prepend_file.filename = php3_ini.auto_prepend_file;
+ prepend_file.type = ZEND_HANDLE_FILENAME;
+ prepend_file_p = &prepend_file;
+ } else {
+ prepend_file_p = NULL;
+ }
+ if (php3_ini.auto_append_file && php3_ini.auto_append_file[0]) {
+ append_file.filename = php3_ini.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':
+ 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=&eg;
+#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=&eg;
+#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:
+ */
diff --git a/main/php.h b/main/php.h
new file mode 100644
index 0000000000..610c68897d
--- /dev/null
+++ b/main/php.h
@@ -0,0 +1,485 @@
+/*
+ +----------------------------------------------------------------------+
+ | 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> |
+ +----------------------------------------------------------------------+
+ */
+
+/* $Id$ */
+
+#ifndef _PHP_H
+#define _PHP_H
+
+#define YYDEBUG 0
+
+#define CGI_BINARY (!APACHE && !USE_SAPI && !FHTTPD)
+
+#include "php_version.h"
+#include "zend.h"
+#include "zend_API.h"
+
+
+extern unsigned char first_arg_force_ref[];
+extern unsigned char first_arg_allow_ref[];
+extern unsigned char second_arg_force_ref[];
+extern unsigned char second_arg_allow_ref[];
+
+
+/* somebody stealing BOOL from windows. pick something else!
+#ifndef BOOL
+#define BOOL MYBOOL
+#endif
+*/
+
+
+#if MSVC5
+#include "config.w32.h"
+#include "win95nt.h"
+# if defined(COMPILE_DL)
+# define PHPAPI __declspec(dllimport)
+# else
+# define PHPAPI __declspec(dllexport)
+# endif
+#else
+# include "config.h"
+# define PHPAPI
+# define THREAD_LS
+#endif
+
+
+/* PHP's DEBUG value must match Zend's ZEND_DEBUG value */
+#undef DEBUG
+#define DEBUG ZEND_DEBUG
+
+
+#if DEBUG || !(defined(__GNUC__)||defined(WIN32))
+#ifdef inline
+#undef inline
+#endif
+#define inline
+#endif
+
+
+#if HAVE_UNIX_H
+#include <unix.h>
+#endif
+
+#if HAVE_ALLOCA_H
+#include <alloca.h>
+#endif
+
+#include "request_info.h"
+
+#if HAVE_LIBDL
+# if MSVC5
+# include <windows.h>
+# define dlclose FreeLibrary
+# define dlopen(a,b) LoadLibrary(a)
+# define dlsym GetProcAddress
+# else
+#if HAVE_DLFCN_H && !(defined(_AIX) && APACHE)
+# include <dlfcn.h>
+#endif
+# endif
+#endif
+
+/*Thread Safety*/
+#if THREAD_SAFE
+#define GLOBAL(a) php3_globals->a
+#define STATIC GLOBAL
+#define TLS_VARS \
+ php3_globals_struct *php3_globals; \
+ php3_globals = TlsGetValue(TlsIndex);
+#define CREATE_MUTEX(a,b) a = CreateMutex (NULL, FALSE, b);
+#define SET_MUTEX(a) WaitForSingleObject( a, INFINITE );
+#define FREE_MUTEX(a) ReleaseMutex(a);
+
+/*redirect variables to the flex structure*/
+#if !defined(YY_BUFFER_NEW) && !defined(COMPILE_DL)
+#include "FlexSafe.h"
+#endif
+
+#define INLINE_TLS ,struct php3_global_struct *php3_globals
+#define INLINE_TLS_VOID struct php3_global_struct *php3_globals
+#define _INLINE_TLS ,php3_globals
+#define _INLINE_TLS_VOID php3_globals
+
+#else
+#define GLOBAL(a) a
+#define STATIC GLOBAL
+#define TLS_VARS
+#define CREATE_MUTEX(a,b)
+#define SET_MUTEX(a)
+#define FREE_MUTEX(a)
+
+/* needed in control structures */
+#define INLINE_TLS
+#define INLINE_TLS_VOID void
+#define _INLINE_TLS
+#define _INLINE_TLS_VOID
+
+#endif
+
+/*
+ * Then the ODBC support can use both iodbc and Solid,
+ * uncomment this.
+ * #define HAVE_ODBC (HAVE_IODBC|HAVE_SOLID)
+ */
+
+#include <stdlib.h>
+#include <ctype.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if HAVE_STDARG_H
+#include <stdarg.h>
+#else
+# if HAVE_SYS_VARARGS_H
+# include <sys/varargs.h>
+# endif
+#endif
+
+
+#include "zend_hash.h"
+#include "php3_compat.h"
+#include "zend_alloc.h"
+#include "zend_stack.h"
+
+typedef zval pval;
+
+#define pval_copy_constructor zval_copy_ctor
+#define pval_destructor zval_dtor
+
+#if REGEX
+#include "regex/regex.h"
+#define _REGEX_H 1 /* this should stop Apache from loading the system version of regex.h */
+#define _RX_H 1 /* Try defining these for Linux to */
+#define __REGEXP_LIBRARY_H__ 1 /* avoid Apache including regex.h */
+#define _H_REGEX 1 /* This one is for AIX */
+#else
+#include <regex.h>
+#endif
+
+#if STDC_HEADERS
+# include <string.h>
+#else
+# ifndef HAVE_MEMCPY
+# define memcpy(d, s, n) bcopy((s), (d), (n))
+# define memmove(d, s, n) bcopy ((s), (d), (n))
+# endif
+#endif
+
+#include "safe_mode.h"
+
+#ifndef HAVE_STRERROR
+extern char *strerror(int);
+#endif
+
+#include "fopen-wrappers.h"
+
+#include "mod_php3.h" /* the php3_ini structure comes from here */
+
+#if APACHE /* apache httpd */
+# if HAVE_AP_CONFIG_H
+#include "ap_config.h"
+# endif
+# if HAVE_OLD_COMPAT_H
+#include "compat.h"
+# endif
+# if HAVE_AP_COMPAT_H
+#include "ap_compat.h"
+# endif
+#include "httpd.h"
+#include "http_main.h"
+#include "http_core.h"
+#include "http_request.h"
+#include "http_protocol.h"
+#include "http_config.h"
+#include "http_log.h"
+#define BLOCK_INTERRUPTIONS block_alarms
+#define UNBLOCK_INTERRUPTIONS unblock_alarms
+# ifndef THREAD_SAFE
+extern request_rec *php3_rqst;
+# endif
+#endif
+
+#if HAVE_PWD_H
+# if MSVC5
+#include "win32/pwd.h"
+#include "win32/param.h"
+# else
+#include <pwd.h>
+#include <sys/param.h>
+# endif
+#endif
+#if CGI_BINARY /* CGI version */
+#define BLOCK_INTERRUPTIONS NULL
+#define UNBLOCK_INTERRUPTIONS NULL
+#endif
+
+#if HAVE_LIMITS_H
+#include <limits.h>
+#endif
+
+#ifndef LONG_MAX
+#define LONG_MAX 2147483647L
+#endif
+
+#ifndef LONG_MIN
+#define LONG_MIN (- LONG_MAX - 1)
+#endif
+
+#if FHTTPD /* fhttpd */
+#define BLOCK_INTERRUPTIONS NULL
+#define UNBLOCK_INTERRUPTIONS NULL
+#endif
+
+#if (!HAVE_SNPRINTF)
+#define snprintf ap_snprintf
+#define vsnprintf ap_vsnprintf
+extern int ap_snprintf(char *, size_t, const char *, ...);
+extern int ap_vsnprintf(char *, size_t, const char *, va_list);
+#endif
+
+#define EXEC_INPUT_BUF 4096
+
+
+#if FHTTPD
+
+#include <servproc.h>
+
+#ifndef IDLE_TIMEOUT
+#define IDLE_TIMEOUT 120
+#endif
+#ifndef SIGACTARGS
+#define SIGACTARGS int n
+#endif
+
+extern struct http_server *server;
+extern struct request *req;
+extern struct httpresponse *response;
+extern int global_alarmflag;
+extern int idle_timeout;
+extern int exit_status;
+extern int headermade;
+extern char **currentheader;
+extern char *headerfirstline;
+extern int headerlines;
+
+void alarmhandler(SIGACTARGS);
+void setalarm(int t);
+int checkinput(int h);
+
+extern PHPAPI void php3_fhttpd_free_header(void);
+extern PHPAPI void php3_fhttpd_puts_header(char *s);
+extern PHPAPI void php3_fhttpd_puts(char *s);
+extern PHPAPI void php3_fhttpd_putc(char c);
+extern PHPAPI int php3_fhttpd_write(char *a,int n);
+# if !defined(COMPILE_DL)
+# define PUTS(s) php3_fhttpd_puts(s)
+# define PUTC(c) php3_fhttpd_putc(c)
+# define PHPWRITE(a,n) php3_fhttpd_write((a),(n))
+# endif
+#endif
+
+
+
+#define DONT_FREE 0
+#define DO_FREE 1
+
+#define PHP3_MIME_TYPE "application/x-httpd-php3"
+
+/* macros */
+#undef MIN
+#undef MAX
+#undef COPY_STRING
+#define DO_OR_DIE(retvalue) if (retvalue==FAILURE) { return FAILURE; }
+#define MAX(a,b) (((a)>(b))?(a):(b))
+#define MIN(a,b) (((a)<(b))?(a):(b))
+#define STR_FREE(ptr) if (ptr && ptr!=empty_string && ptr!=undefined_variable_string) { efree(ptr); }
+#define COPY_STRING(yy) (yy).value.str.val = (char *) estrndup((yy).value.str.val,(yy).value.str.len)
+
+#ifndef MAXPATHLEN
+#define MAXPATHLEN 256 /* Should be safe for any weird systems that do not define it */
+#endif
+
+#define PHP_NAMED_FUNCTION(name) void name(INTERNAL_FUNCTION_PARAMETERS)
+#define PHP_FUNCTION(name) PHP_NAMED_FUNCTION(php3_##name)
+
+#define PHP_NAMED_FE(php_name, name, arg_types) { #php_name, name, arg_types },
+#define PHP_FE(name, arg_types) PHP_NAMED_FE(name, php3_##name, arg_types)
+
+
+
+
+
+/* global variables */
+#ifndef THREAD_SAFE
+extern pval *data;
+#if (!PHP_ISAPI)
+extern char **environ;
+#endif
+#endif
+extern PHPAPI int le_index_ptr; /* list entry type for index pointers */
+
+extern void phperror(char *error);
+extern PHPAPI void php3_error(int type, const char *format,...);
+extern PHPAPI int php3_printf(const char *format,...);
+extern void php3_log_err(char *log_message);
+extern int Debug(char *format,...);
+extern int cfgparse(void);
+
+extern void html_putc(char c);
+
+#define zenderror phperror
+#define zendlex phplex
+
+#define phpparse zendparse
+#define phprestart zendrestart
+#define phpin zendin
+
+/* functions */
+#ifndef THREAD_SAFE
+extern int end_current_file_execution(int *retval);
+#endif
+extern int _php3_hash_environment(void);
+extern int module_startup_modules(void);
+
+/* needed for modules only */
+extern PHPAPI int php3i_get_le_fp(void);
+
+/*from basic functions*/
+extern PHPAPI int _php3_error_log(int opt_err,char *message,char *opt,char *headers);
+
+PHPAPI int cfg_get_long(char *varname, long *result);
+PHPAPI int cfg_get_double(char *varname, double *result);
+PHPAPI int cfg_get_string(char *varname, char **result);
+
+extern PHPAPI php3_ini_structure php3_ini;
+
+
+/* Output support */
+#include "output.h"
+#define PHPWRITE(str, str_len) zend_body_write((str), (str_len))
+#define PUTS(str) zend_body_write((str), strlen((str)))
+#define PUTC(c) zend_body_write(&(c), 1), (c)
+#define PHPWRITE_H(str, str_len) zend_header_write((str), (str_len))
+#define PUTS_H(str) zend_header_write((str), strlen((str)))
+#define PUTC_H(c) zend_header_write(&(c), 1), (c)
+
+
+#include "zend_operators.h"
+#include "zend_variables.h"
+#include "zend_constants.h"
+
+#define RETVAL_LONG(l) { return_value->type = IS_LONG; \
+ return_value->value.lval = l; }
+#define RETVAL_DOUBLE(d) { return_value->type = IS_DOUBLE; \
+ return_value->value.dval = d; }
+#define RETVAL_STRING(s,duplicate) { char *__s=(s); \
+ return_value->value.str.len = strlen(__s); \
+ return_value->value.str.val = (duplicate?estrndup(__s,return_value->value.str.len):__s); \
+ return_value->type = IS_STRING; }
+#define RETVAL_STRINGL(s,l,duplicate) { char *__s=(s); int __l=l; \
+ return_value->value.str.len = __l; \
+ return_value->value.str.val = (duplicate?estrndup(__s,__l):__s); \
+ return_value->type = IS_STRING; }
+
+#define RETVAL_FALSE {var_reset(return_value);}
+#define RETVAL_TRUE RETVAL_LONG(1L)
+
+#define RETURN_LONG(l) { return_value->type = IS_LONG; \
+ return_value->value.lval = l; \
+ return; }
+#define RETURN_DOUBLE(d) { return_value->type = IS_DOUBLE; \
+ return_value->value.dval = d; \
+ return; }
+#define RETURN_STRING(s,duplicate) { char *__s=(s); \
+ return_value->value.str.len = strlen(__s); \
+ return_value->value.str.val = (duplicate?estrndup(__s,return_value->value.str.len):__s); \
+ return_value->type = IS_STRING; \
+ return; }
+#define RETURN_STRINGL(s,l,duplicate) { char *__s=(s); int __l=l; \
+ return_value->value.str.len = __l; \
+ return_value->value.str.val = (duplicate?estrndup(__s,__l):__s); \
+ return_value->type = IS_STRING; \
+ return; }
+
+/*#define RETURN_NEG RETURN_LONG(-1L) */
+#define RETURN_ZERO RETURN_LONG(0L)
+#define RETURN_FALSE {var_reset(return_value); return;}
+#define RETURN_TRUE RETURN_LONG(1L)
+
+#define SET_VAR_STRING(n,v) { \
+ { \
+ pval var; \
+ char *str=v; /* prevent 'v' from being evaluated more than once */ \
+ var.value.str.val = (str); \
+ var.value.str.len = strlen((str)); \
+ var.type = IS_STRING; \
+ _php3_hash_update(&EG(symbol_table), (n), strlen((n))+1, &var, sizeof(pval),NULL); \
+ } \
+ }
+#define SET_VAR_STRINGL(n,v,l) { \
+ { \
+ pval var; \
+ char *name=(n); \
+ var.value.str.val = (v); \
+ var.value.str.len = (l); \
+ var.type = IS_STRING; \
+ _php3_hash_update(&EG(symbol_table), name, strlen(name)+1, &var, sizeof(pval),NULL); \
+ } \
+ }
+#define SET_VAR_LONG(n,v) { \
+ { \
+ pval var; \
+ var.value.lval = (v); \
+ var.type = IS_LONG; \
+ _php3_hash_update(&EG(symbol_table), (n), strlen((n))+1, &var, sizeof(pval),NULL); \
+ } \
+ }
+#define SET_VAR_DOUBLE(n,v) { \
+ { \
+ pval var; \
+ var.value.dval = (v); \
+ var.type = IS_DOUBLE; \
+ _php3_hash_update(&EG(symbol_table)), (n), strlen((n))+1, &var, sizeof(pval),NULL); \
+ } \
+ }
+
+#ifndef THREAD_SAFE
+extern int yylineno;
+#endif
+extern void phprestart(FILE *input_file);
+
+#endif
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ */
diff --git a/main/php3_compat.h b/main/php3_compat.h
new file mode 100644
index 0000000000..060786a2a4
--- /dev/null
+++ b/main/php3_compat.h
@@ -0,0 +1,80 @@
+#ifndef _PHP3_COMPAT_H
+#define _PHP3_COMPAT_H
+
+#define _php3_hash_init zend_hash_init
+#define _php3_hash_destroy zend_hash_destroy
+
+#define _php3_hash_clean zend_hash_clean
+
+#define _php3_hash_add_or_update zend_hash_add_or_update
+#define _php3_hash_add zend_hash_add
+#define _php3_hash_update zend_hash_update
+#define _php3_hash_update_ptr zend_hash_update_ptr
+
+#define _php3_hash_quick_add_or_update zend_hash_quick_add_or_update
+#define _php3_hash_quick_add zend_hash_quick_add
+#define _php3_hash_quick_update zend_hash_quick_update
+
+#define _php3_hash_index_update_or_next_insert zend_hash_index_update_or_next_insert
+#define _php3_hash_index_update zend_hash_index_update
+#define _php3_hash_next_index_insert zend_hash_next_index_insert
+
+#define _php3_hash_pointer_update zend_hash_pointer_update
+
+#define _php3_hash_pointer_index_update_or_next_insert zend_hash_pointer_index_update_or_next_insert
+#define _php3_hash_pointer_index_update zend_hash_pointer_index_update
+#define _php3_hash_next_index_pointer_update zend_hash_next_index_pointer_update
+
+#define _php3_hash_del_key_or_index zend_hash_del_key_or_index
+#define _php3_hash_del zend_hash_del
+#define _php3_hash_index_del zend_hash_index_del
+
+#define _php3_hash_find zend_hash_find
+#define _php3_hash_quick_find zend_hash_quick_find
+#define _php3_hash_index_find zend_hash_index_find
+
+#define _php3_hash_exists zend_hash_exists
+#define _php3_hash_index_exists zend_hash_index_exists
+#define _php3_hash_is_pointer zend_hash_is_pointer
+#define _php3_hash_index_is_pointer zend_hash_index_is_pointer
+#define _php3_hash_next_free_element zend_hash_next_free_element
+
+#define _php3_hash_move_forward zend_hash_move_forward
+#define _php3_hash_move_backwards zend_hash_move_backwards
+#define _php3_hash_get_current_key zend_hash_get_current_key
+#define _php3_hash_get_current_data zend_hash_get_current_data
+#define _php3_hash_internal_pointer_reset zend_hash_internal_pointer_reset
+#define _php3_hash_internal_pointer_end zend_hash_internal_pointer_end
+
+#define _php3_hash_copy zend_hash_copy
+#define _php3_hash_merge zend_hash_merge
+#define _php3_hash_sort zend_hash_sort
+#define _php3_hash_minmax zend_hash_minmax
+
+#define _php3_hash_num_elements zend_hash_num_elements
+
+#define _php3_hash_apply zend_hash_apply
+#define _php3_hash_apply_with_argument zend_hash_apply_with_argument
+
+
+
+
+#define php3_module_entry zend_module_entry
+
+#define php3_strndup zend_strndup
+#define php3_str_tolower zend_str_tolower
+#define php3_binary_strcmp zend_binary_strcmp
+
+
+#define php3_list_insert zend_list_insert
+#define php3_list_find zend_list_find
+#define php3_list_delete zend_list_delete
+
+#define php3_plist_insert zend_plist_insert
+#define php3_plist_find zend_plist_find
+#define php3_plist_delete zend_plist_delete
+
+#define zend_print_pval zend_print_zval
+#define zend_print_pval_r zend_print_zval_r
+
+#endif /* _PHP3_COMPAT_H */
diff --git a/main/php_ini.c b/main/php_ini.c
new file mode 100644
index 0000000000..49464fdc99
--- /dev/null
+++ b/main/php_ini.c
@@ -0,0 +1,148 @@
+#include <stdlib.h>
+
+#include "php.h"
+#include "php_ini.h"
+#include "zend_alloc.h"
+
+static HashTable known_directives;
+
+
+/*
+ * hash_apply functions
+ */
+static int zend_remove_ini_entries(zend_ini_entry *ini_entry, int *module_number)
+{
+ if (ini_entry->module_number == *module_number) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+
+static int zend_restore_ini_entry(zend_ini_entry *ini_entry)
+{
+ if (ini_entry->modified) {
+ efree(ini_entry->value);
+ ini_entry->value = ini_entry->orig_value;
+ ini_entry->value_length = ini_entry->orig_value_length;
+ ini_entry->modified = 0;
+ }
+ return 0;
+}
+
+/*
+ * Startup / shutdown
+ */
+int zend_ini_mstartup()
+{
+ if (_php3_hash_init(&known_directives, 100, NULL, NULL, 1)==FAILURE) {
+ return FAILURE;
+ }
+ return SUCCESS;
+}
+
+
+int zend_ini_mshutdown()
+{
+ _php3_hash_destroy(&known_directives);
+ return SUCCESS;
+}
+
+
+int zend_ini_rshutdown()
+{
+ _php3_hash_apply(&known_directives, (int (*)(void *)) zend_restore_ini_entry);
+ return SUCCESS;
+}
+
+/*
+ * Registration / unregistration
+ */
+
+int zend_register_ini_entries(zend_ini_entry *ini_entry, int module_number)
+{
+ zend_ini_entry *p = ini_entry;
+ zend_ini_entry *hashed_ini_entry;
+ pval *default_value;
+
+ while (p->name) {
+ p->module_number = module_number;
+ if (_php3_hash_add(&known_directives, p->name, p->name_length, p, sizeof(zend_ini_entry), (void **) &hashed_ini_entry)==FAILURE) {
+ zend_unregister_ini_entries(module_number);
+ return FAILURE;
+ }
+ if ((default_value=cfg_get_entry(p->name, p->name_length))) {
+ hashed_ini_entry->value = default_value->value.str.val;
+ hashed_ini_entry->value_length = default_value->value.str.len;
+ }
+ hashed_ini_entry->modified = 0;
+ p++;
+ }
+ return SUCCESS;
+}
+
+
+void zend_unregister_ini_entries(int module_number)
+{
+ _php3_hash_apply_with_argument(&known_directives, (int (*)(void *, void *)) zend_remove_ini_entries, (void *) &module_number);
+}
+
+int zend_alter_ini_entry(char *name, uint name_length, char *new_value, uint new_value_length, int modify_type)
+{
+ zend_ini_entry *ini_entry;
+
+ if (_php3_hash_find(&known_directives, name, name_length, (void **) &ini_entry)==FAILURE) {
+ return FAILURE;
+ }
+
+ if (!(ini_entry->modifyable & modify_type)) {
+ return FAILURE;
+ }
+
+ ini_entry->value = estrndup(new_value, new_value_length);
+ ini_entry->value_length = new_value_length;
+ ini_entry->modified = 1;
+
+ return SUCCESS;
+}
+
+
+/*
+ * Data retrieval
+ */
+
+long zend_ini_long(char *name, uint name_length)
+{
+ zend_ini_entry *ini_entry;
+
+ if (_php3_hash_find(&known_directives, name, name_length, (void **) &ini_entry)==SUCCESS) {
+ return (long) atoi(ini_entry->value);
+ }
+
+ return 0;
+}
+
+
+double zend_ini_double(char *name, uint name_length)
+{
+ zend_ini_entry *ini_entry;
+
+ if (_php3_hash_find(&known_directives, name, name_length, (void **) &ini_entry)==SUCCESS) {
+ return (double) strtod(ini_entry->value, NULL);
+ }
+
+ return 0.0;
+}
+
+
+char *zend_ini_string(char *name, uint name_length)
+{
+ zend_ini_entry *ini_entry;
+
+ if (_php3_hash_find(&known_directives, name, name_length, (void **) &ini_entry)==SUCCESS) {
+ return ini_entry->value;
+ }
+
+ return "";
+}
diff --git a/main/php_ini.h b/main/php_ini.h
new file mode 100644
index 0000000000..00d4a45ebf
--- /dev/null
+++ b/main/php_ini.h
@@ -0,0 +1,48 @@
+#ifndef _ZEND_INI_H
+#define _ZEND_INI_H
+
+
+#define ZEND_INI_USER (1<<0)
+#define ZEND_INI_PERDIR (1<<1)
+#define ZEND_INI_SYSTEM (1<<2)
+
+#define ZEND_INI_ALL (ZEND_INI_USER|ZEND_INI_PERDIR|ZEND_INI_SYSTEM)
+
+typedef struct {
+ int module_number;
+ int modifyable;
+ char *name;
+ uint name_length;
+
+ char *value;
+ uint value_length;
+
+ char *orig_value;
+ uint orig_value_length;
+ int modified;
+} zend_ini_entry;
+
+
+int zend_ini_mstartup();
+int zend_ini_mshutdown();
+int zend_ini_rshutdown();
+
+int zend_register_ini_entries(zend_ini_entry *ini_entry, int module_number);
+void zend_unregister_ini_entries(int module_number);
+int zend_alter_ini_entry(char *name, uint name_length, char *new_value, uint new_value_length, int modify_type);
+
+long zend_ini_long(char *name, uint name_length);
+double zend_ini_double(char *name, uint name_length);
+char *zend_ini_string(char *name, uint name_length);
+
+#define ZEND_INI_BEGIN() static zend_ini_entry ini_entries[] = {
+#define ZEND_INI_ENTRY(name, default_value, modifyable) { 0, modifyable, name, sizeof(name), default_value, sizeof(default_value)-1, NULL, 0, 0 },
+#define ZEND_INI_END() { 0, 0, NULL, 0, NULL, 0, NULL, 0, 0 } };
+
+#define INI_INT(name) zend_ini_long((name), sizeof(name))
+#define INI_FLT(name) zend_ini_double((name), sizeof(name))
+#define INI_STR(name) zend_ini_string((name), sizeof(name))
+
+pval *cfg_get_entry(char *name, uint name_length);
+
+#endif /* _ZEND_INI_H */
diff --git a/main/php_version.h b/main/php_version.h
new file mode 100644
index 0000000000..a2042691b9
--- /dev/null
+++ b/main/php_version.h
@@ -0,0 +1 @@
+#define PHP_VERSION "4.0pa1"
diff --git a/main/safe_mode.c b/main/safe_mode.c
new file mode 100644
index 0000000000..8b712408ee
--- /dev/null
+++ b/main/safe_mode.c
@@ -0,0 +1,156 @@
+/*
+ +----------------------------------------------------------------------+
+ | 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: Rasmus Lerdorf <rasmus@lerdorf.on.ca> |
+ +----------------------------------------------------------------------+
+ */
+/* $Id$ */
+#ifdef THREAD_SAFE
+#include "tls.h"
+#endif
+#include "php.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <sys/stat.h>
+#include "functions/pageinfo.h"
+#include "safe_mode.h"
+
+/*
+ * _php3_checkuid
+ *
+ * This function has four modes:
+ *
+ * 0 - return invalid (0) if file does not exist
+ * 1 - return valid (1) if file does not exist
+ * 2 - if file does not exist, check directory
+ * 3 - only check directory (needed for mkdir)
+ */
+PHPAPI int _php3_checkuid(const char *fn, int mode) {
+ struct stat sb;
+ int ret;
+ long uid=0L, duid=0L;
+ char *s;
+
+ if (!fn) return(0); /* path must be provided */
+
+ /*
+ * If given filepath is a URL, allow - safe mode stuff
+ * related to URL's is checked in individual functions
+ */
+ if (!strncasecmp(fn,"http://",7) || !strncasecmp(fn,"ftp://",6)) {
+ return(1);
+ }
+
+ if (mode<3) {
+ ret = stat(fn,&sb);
+ if (ret<0 && mode < 2) {
+ php3_error(E_WARNING,"Unable to access %s",fn);
+ return(mode);
+ }
+ if (ret>-1) {
+ uid=sb.st_uid;
+ if (uid==_php3_getuid()) return(1);
+ }
+ }
+ s = strrchr(fn,'/');
+
+ /* This loop gets rid of trailing slashes which could otherwise be
+ * used to confuse the function.
+ */
+ while(s && *(s+1)=='\0' && s>fn) {
+ s='\0';
+ s = strrchr(fn,'/');
+ }
+
+ if (s) {
+ *s='\0';
+ ret = stat(fn,&sb);
+ *s='/';
+ if (ret<0) {
+ php3_error(E_WARNING, "Unable to access %s",fn);
+ return(0);
+ }
+ duid = sb.st_uid;
+ } else {
+ s = emalloc(MAXPATHLEN+1);
+ if (!getcwd(s,MAXPATHLEN)) {
+ php3_error(E_WARNING, "Unable to access current working directory");
+ return(0);
+ }
+ ret = stat(s,&sb);
+ efree(s);
+ if (ret<0) {
+ php3_error(E_WARNING, "Unable to access %s",s);
+ return(0);
+ }
+ duid = sb.st_uid;
+ }
+ if (duid == (uid=_php3_getuid())) return(1);
+ else {
+ php3_error(E_WARNING, "SAFE MODE Restriction in effect. The script whose uid is %ld is not allowed to access %s owned by uid %ld",uid,fn,duid);
+ return(0);
+ }
+}
+
+
+PHPAPI char *_php3_get_current_user()
+{
+#if CGI_BINARY || USE_SAPI || FHTTPD
+ struct stat statbuf;
+#endif
+ struct passwd *pwd;
+ int uid;
+ TLS_VARS;
+
+ if (GLOBAL(request_info).current_user) {
+ return GLOBAL(request_info).current_user;
+ }
+
+ /* FIXME: I need to have this somehow handled if
+ USE_SAPI is defined, because cgi will also be
+ interfaced in USE_SAPI */
+#if CGI_BINARY || USE_SAPI || FHTTPD
+ if (!GLOBAL(request_info).filename || (stat(GLOBAL(request_info).filename,&statbuf)==-1)) {
+ return empty_string;
+ }
+ uid = statbuf.st_uid;
+#endif
+#if APACHE
+ uid = GLOBAL(php3_rqst)->finfo.st_uid;
+#endif
+
+ if ((pwd=getpwuid(uid))==NULL) {
+ return empty_string;
+ }
+ GLOBAL(request_info).current_user_length = strlen(pwd->pw_name);
+ GLOBAL(request_info).current_user = estrndup(pwd->pw_name,GLOBAL(request_info).current_user_length);
+
+ return GLOBAL(request_info).current_user;
+}
diff --git a/main/safe_mode.h b/main/safe_mode.h
new file mode 100644
index 0000000000..3ae320b46d
--- /dev/null
+++ b/main/safe_mode.h
@@ -0,0 +1,7 @@
+#ifndef _SAFE_MODE_H_
+#define _SAFE_MODE_H_
+
+extern PHPAPI int _php3_checkuid(const char *filename, int mode);
+extern PHPAPI char *_php3_get_current_user(void);
+
+#endif
diff --git a/main/snprintf.c b/main/snprintf.c
new file mode 100644
index 0000000000..32bff374e2
--- /dev/null
+++ b/main/snprintf.c
@@ -0,0 +1,935 @@
+/* ====================================================================
+ * Copyright (c) 1995-1998 The Apache Group. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the Apache Group
+ * for use in the Apache HTTP server project (http://www.apache.org/)."
+ *
+ * 4. The names "Apache Server" and "Apache Group" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission.
+ *
+ * 5. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the Apache Group
+ * for use in the Apache HTTP server project (http://www.apache.org/)."
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Group and was originally based
+ * on public domain software written at the National Center for
+ * Supercomputing Applications, University of Illinois, Urbana-Champaign.
+ * For more information on the Apache Group and the Apache HTTP server
+ * project, please see <http://www.apache.org/>.
+ *
+ * This code is based on, and used with the permission of, the
+ * SIO stdio-replacement strx_* functions by Panos Tsirigotis
+ * <panos@alumni.cs.colorado.edu> for xinetd.
+ */
+
+#include "config.h"
+
+#if !defined(APACHE) || (!APACHE)
+#if !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF)
+
+#include <stdio.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <stdarg.h>
+#include <string.h>
+#include <stdlib.h>
+#include <math.h>
+
+#include "php.h"
+
+#ifdef HAVE_GCVT
+
+#define ap_ecvt ecvt
+#define ap_fcvt fcvt
+#define ap_gcvt gcvt
+
+#else
+
+/*
+ * cvt.c - IEEE floating point formatting routines for FreeBSD
+ * from GNU libc-4.6.27
+ */
+
+/*
+ * ap_ecvt converts to decimal
+ * the number of digits is specified by ndigit
+ * decpt is set to the position of the decimal point
+ * sign is set to 0 for positive, 1 for negative
+ */
+
+#define NDIG 80
+
+static char *
+ ap_cvt(double arg, int ndigits, int *decpt, int *sign, int eflag)
+{
+ register int r2;
+ double fi, fj;
+ register char *p, *p1;
+ static char buf[NDIG];
+
+ if (ndigits >= NDIG - 1)
+ ndigits = NDIG - 2;
+ r2 = 0;
+ *sign = 0;
+ p = &buf[0];
+ if (arg < 0) {
+ *sign = 1;
+ arg = -arg;
+ }
+ arg = modf(arg, &fi);
+ p1 = &buf[NDIG];
+ /*
+ * Do integer part
+ */
+ if (fi != 0) {
+ p1 = &buf[NDIG];
+ while (fi != 0) {
+ fj = modf(fi / 10, &fi);
+ *--p1 = (int) ((fj + .03) * 10) + '0';
+ r2++;
+ }
+ while (p1 < &buf[NDIG])
+ *p++ = *p1++;
+ } else if (arg > 0) {
+ while ((fj = arg * 10) < 1) {
+ arg = fj;
+ r2--;
+ }
+ }
+ p1 = &buf[ndigits];
+ if (eflag == 0)
+ p1 += r2;
+ *decpt = r2;
+ if (p1 < &buf[0]) {
+ buf[0] = '\0';
+ return (buf);
+ }
+ while (p <= p1 && p < &buf[NDIG]) {
+ arg *= 10;
+ arg = modf(arg, &fj);
+ *p++ = (int) fj + '0';
+ }
+ if (p1 >= &buf[NDIG]) {
+ buf[NDIG - 1] = '\0';
+ return (buf);
+ }
+ p = p1;
+ *p1 += 5;
+ while (*p1 > '9') {
+ *p1 = '0';
+ if (p1 > buf)
+ ++ * --p1;
+ else {
+ *p1 = '1';
+ (*decpt)++;
+ if (eflag == 0) {
+ if (p > buf)
+ *p = '0';
+ p++;
+ }
+ }
+ }
+ *p = '\0';
+ return (buf);
+}
+
+static char *
+ ap_ecvt(double arg, int ndigits, int *decpt, int *sign)
+{
+ return (ap_cvt(arg, ndigits, decpt, sign, 1));
+}
+
+static char *
+ ap_fcvt(double arg, int ndigits, int *decpt, int *sign)
+{
+ return (ap_cvt(arg, ndigits, decpt, sign, 0));
+}
+
+/*
+ * ap_gcvt - Floating output conversion to
+ * minimal length string
+ */
+
+static char *
+ ap_gcvt(double number, int ndigit, char *buf)
+{
+ int sign, decpt;
+ register char *p1, *p2;
+ register i;
+
+ p1 = ap_ecvt(number, ndigit, &decpt, &sign);
+ p2 = buf;
+ if (sign)
+ *p2++ = '-';
+ for (i = ndigit - 1; i > 0 && p1[i] == '0'; i--)
+ ndigit--;
+ if ((decpt >= 0 && decpt - ndigit > 4)
+ || (decpt < 0 && decpt < -3)) { /* use E-style */
+ decpt--;
+ *p2++ = *p1++;
+ *p2++ = '.';
+ for (i = 1; i < ndigit; i++)
+ *p2++ = *p1++;
+ *p2++ = 'e';
+ if (decpt < 0) {
+ decpt = -decpt;
+ *p2++ = '-';
+ } else
+ *p2++ = '+';
+ if (decpt / 100 > 0)
+ *p2++ = decpt / 100 + '0';
+ if (decpt / 10 > 0)
+ *p2++ = (decpt % 100) / 10 + '0';
+ *p2++ = decpt % 10 + '0';
+ } else {
+ if (decpt <= 0) {
+ if (*p1 != '0')
+ *p2++ = '.';
+ while (decpt < 0) {
+ decpt++;
+ *p2++ = '0';
+ }
+ }
+ for (i = 1; i <= ndigit; i++) {
+ *p2++ = *p1++;
+ if (i == decpt)
+ *p2++ = '.';
+ }
+ if (ndigit < decpt) {
+ while (ndigit++ < decpt)
+ *p2++ = '0';
+ *p2++ = '.';
+ }
+ }
+ if (p2[-1] == '.')
+ p2--;
+ *p2 = '\0';
+ return (buf);
+}
+
+#endif /* HAVE_CVT */
+
+typedef enum {
+ NO = 0, YES = 1
+} boolean_e;
+
+#define FALSE 0
+#define TRUE 1
+#define NUL '\0'
+#define INT_NULL ((int *)0)
+#define WIDE_INT long
+
+typedef WIDE_INT wide_int;
+typedef unsigned WIDE_INT u_wide_int;
+typedef int bool_int;
+
+#define S_NULL "(null)"
+#define S_NULL_LEN 6
+
+#define FLOAT_DIGITS 6
+#define EXPONENT_LENGTH 10
+
+/*
+ * NUM_BUF_SIZE is the size of the buffer used for arithmetic conversions
+ *
+ * XXX: this is a magic number; do not decrease it
+ */
+#define NUM_BUF_SIZE 512
+
+
+/*
+ * Descriptor for buffer area
+ */
+struct buf_area {
+ char *buf_end;
+ char *nextb; /* pointer to next byte to read/write */
+};
+
+typedef struct buf_area buffy;
+
+/*
+ * The INS_CHAR macro inserts a character in the buffer and writes
+ * the buffer back to disk if necessary
+ * It uses the char pointers sp and bep:
+ * sp points to the next available character in the buffer
+ * bep points to the end-of-buffer+1
+ * While using this macro, note that the nextb pointer is NOT updated.
+ *
+ * NOTE: Evaluation of the c argument should not have any side-effects
+ */
+#define INS_CHAR( c, sp, bep, cc ) \
+ { \
+ if ( sp < bep ) \
+ { \
+ *sp++ = c ; \
+ cc++ ; \
+ } \
+ }
+
+#define NUM( c ) ( c - '0' )
+
+#define STR_TO_DEC( str, num ) \
+ num = NUM( *str++ ) ; \
+ while ( isdigit((int)*str ) ) \
+ { \
+ num *= 10 ; \
+ num += NUM( *str++ ) ; \
+ }
+
+/*
+ * This macro does zero padding so that the precision
+ * requirement is satisfied. The padding is done by
+ * adding '0's to the left of the string that is going
+ * to be printed.
+ */
+#define FIX_PRECISION( adjust, precision, s, s_len ) \
+ if ( adjust ) \
+ while ( s_len < precision ) \
+ { \
+ *--s = '0' ; \
+ s_len++ ; \
+ }
+
+/*
+ * Macro that does padding. The padding is done by printing
+ * the character ch.
+ */
+#define PAD( width, len, ch ) do \
+ { \
+ INS_CHAR( ch, sp, bep, cc ) ; \
+ width-- ; \
+ } \
+ while ( width > len )
+
+/*
+ * Prefix the character ch to the string str
+ * Increase length
+ * Set the has_prefix flag
+ */
+#define PREFIX( str, length, ch ) *--str = ch ; length++ ; has_prefix = YES
+
+
+/*
+ * Convert num to its decimal format.
+ * Return value:
+ * - a pointer to a string containing the number (no sign)
+ * - len contains the length of the string
+ * - is_negative is set to TRUE or FALSE depending on the sign
+ * of the number (always set to FALSE if is_unsigned is TRUE)
+ *
+ * The caller provides a buffer for the string: that is the buf_end argument
+ * which is a pointer to the END of the buffer + 1 (i.e. if the buffer
+ * is declared as buf[ 100 ], buf_end should be &buf[ 100 ])
+ */
+static char *
+ conv_10(register wide_int num, register bool_int is_unsigned,
+ register bool_int * is_negative, char *buf_end, register int *len)
+{
+ register char *p = buf_end;
+ register u_wide_int magnitude;
+
+ if (is_unsigned) {
+ magnitude = (u_wide_int) num;
+ *is_negative = FALSE;
+ } else {
+ *is_negative = (num < 0);
+
+ /*
+ * On a 2's complement machine, negating the most negative integer
+ * results in a number that cannot be represented as a signed integer.
+ * Here is what we do to obtain the number's magnitude:
+ * a. add 1 to the number
+ * b. negate it (becomes positive)
+ * c. convert it to unsigned
+ * d. add 1
+ */
+ if (*is_negative) {
+ wide_int t = num + 1;
+
+ magnitude = ((u_wide_int) - t) + 1;
+ } else
+ magnitude = (u_wide_int) num;
+ }
+
+ /*
+ * We use a do-while loop so that we write at least 1 digit
+ */
+ do {
+ register u_wide_int new_magnitude = magnitude / 10;
+
+ *--p = magnitude - new_magnitude * 10 + '0';
+ magnitude = new_magnitude;
+ }
+ while (magnitude);
+
+ *len = buf_end - p;
+ return (p);
+}
+
+
+
+/*
+ * Convert a floating point number to a string formats 'f', 'e' or 'E'.
+ * The result is placed in buf, and len denotes the length of the string
+ * The sign is returned in the is_negative argument (and is not placed
+ * in buf).
+ */
+static char *
+ conv_fp(register char format, register double num,
+ boolean_e add_dp, int precision, bool_int * is_negative, char *buf, int *len)
+{
+ register char *s = buf;
+ register char *p;
+ int decimal_point;
+
+ if (format == 'f')
+ p = ap_fcvt(num, precision, &decimal_point, is_negative);
+ else /* either e or E format */
+ p = ap_ecvt(num, precision + 1, &decimal_point, is_negative);
+
+ /*
+ * Check for Infinity and NaN
+ */
+ if (isalpha((int)*p)) {
+ *len = strlen(strcpy(buf, p));
+ *is_negative = FALSE;
+ return (buf);
+ }
+ if (format == 'f') {
+ if (decimal_point <= 0) {
+ *s++ = '0';
+ if (precision > 0) {
+ *s++ = '.';
+ while (decimal_point++ < 0)
+ *s++ = '0';
+ } else if (add_dp) {
+ *s++ = '.';
+ }
+ } else {
+ while (decimal_point-- > 0) {
+ *s++ = *p++;
+ }
+ if (precision > 0 || add_dp) {
+ *s++ = '.';
+ }
+ }
+ } else {
+ *s++ = *p++;
+ if (precision > 0 || add_dp)
+ *s++ = '.';
+ }
+
+ /*
+ * copy the rest of p, the NUL is NOT copied
+ */
+ while (*p)
+ *s++ = *p++;
+
+ if (format != 'f') {
+ char temp[EXPONENT_LENGTH]; /* for exponent conversion */
+ int t_len;
+ bool_int exponent_is_negative;
+
+ *s++ = format; /* either e or E */
+ decimal_point--;
+ if (decimal_point != 0) {
+ p = conv_10((wide_int) decimal_point, FALSE, &exponent_is_negative,
+ &temp[EXPONENT_LENGTH], &t_len);
+ *s++ = exponent_is_negative ? '-' : '+';
+
+ /*
+ * Make sure the exponent has at least 2 digits
+ */
+ if (t_len == 1)
+ *s++ = '0';
+ while (t_len--)
+ *s++ = *p++;
+ } else {
+ *s++ = '+';
+ *s++ = '0';
+ *s++ = '0';
+ }
+ }
+ *len = s - buf;
+ return (buf);
+}
+
+
+/*
+ * Convert num to a base X number where X is a power of 2. nbits determines X.
+ * For example, if nbits is 3, we do base 8 conversion
+ * Return value:
+ * a pointer to a string containing the number
+ *
+ * The caller provides a buffer for the string: that is the buf_end argument
+ * which is a pointer to the END of the buffer + 1 (i.e. if the buffer
+ * is declared as buf[ 100 ], buf_end should be &buf[ 100 ])
+ */
+static char *
+ conv_p2(register u_wide_int num, register int nbits,
+ char format, char *buf_end, register int *len)
+{
+ register int mask = (1 << nbits) - 1;
+ register char *p = buf_end;
+ static char low_digits[] = "0123456789abcdef";
+ static char upper_digits[] = "0123456789ABCDEF";
+ register char *digits = (format == 'X') ? upper_digits : low_digits;
+
+ do {
+ *--p = digits[num & mask];
+ num >>= nbits;
+ }
+ while (num);
+
+ *len = buf_end - p;
+ return (p);
+}
+
+
+/*
+ * Do format conversion placing the output in buffer
+ */
+static int format_converter(register buffy * odp, const char *fmt,
+ va_list ap)
+{
+ register char *sp;
+ register char *bep;
+ register int cc = 0;
+ register int i;
+
+ register char *s = NULL;
+ char *q;
+ int s_len;
+
+ register int min_width = 0;
+ int precision = 0;
+ enum {
+ LEFT, RIGHT
+ } adjust;
+ char pad_char;
+ char prefix_char;
+
+ double fp_num;
+ wide_int i_num = (wide_int) 0;
+ u_wide_int ui_num;
+
+ char num_buf[NUM_BUF_SIZE];
+ char char_buf[2]; /* for printing %% and %<unknown> */
+
+ /*
+ * Flag variables
+ */
+ boolean_e is_long;
+ boolean_e alternate_form;
+ boolean_e print_sign;
+ boolean_e print_blank;
+ boolean_e adjust_precision;
+ boolean_e adjust_width;
+ bool_int is_negative;
+
+ sp = odp->nextb;
+ bep = odp->buf_end;
+
+ while (*fmt) {
+ if (*fmt != '%') {
+ INS_CHAR(*fmt, sp, bep, cc);
+ } else {
+ /*
+ * Default variable settings
+ */
+ adjust = RIGHT;
+ alternate_form = print_sign = print_blank = NO;
+ pad_char = ' ';
+ prefix_char = NUL;
+
+ fmt++;
+
+ /*
+ * Try to avoid checking for flags, width or precision
+ */
+ if (isascii((int)*fmt) && !islower((int)*fmt)) {
+ /*
+ * Recognize flags: -, #, BLANK, +
+ */
+ for (;; fmt++) {
+ if (*fmt == '-')
+ adjust = LEFT;
+ else if (*fmt == '+')
+ print_sign = YES;
+ else if (*fmt == '#')
+ alternate_form = YES;
+ else if (*fmt == ' ')
+ print_blank = YES;
+ else if (*fmt == '0')
+ pad_char = '0';
+ else
+ break;
+ }
+
+ /*
+ * Check if a width was specified
+ */
+ if (isdigit((int)*fmt)) {
+ STR_TO_DEC(fmt, min_width);
+ adjust_width = YES;
+ } else if (*fmt == '*') {
+ min_width = va_arg(ap, int);
+ fmt++;
+ adjust_width = YES;
+ if (min_width < 0) {
+ adjust = LEFT;
+ min_width = -min_width;
+ }
+ } else
+ adjust_width = NO;
+
+ /*
+ * Check if a precision was specified
+ *
+ * XXX: an unreasonable amount of precision may be specified
+ * resulting in overflow of num_buf. Currently we
+ * ignore this possibility.
+ */
+ if (*fmt == '.') {
+ adjust_precision = YES;
+ fmt++;
+ if (isdigit((int)*fmt)) {
+ STR_TO_DEC(fmt, precision);
+ } else if (*fmt == '*') {
+ precision = va_arg(ap, int);
+ fmt++;
+ if (precision < 0)
+ precision = 0;
+ } else
+ precision = 0;
+ } else
+ adjust_precision = NO;
+ } else
+ adjust_precision = adjust_width = NO;
+
+ /*
+ * Modifier check
+ */
+ if (*fmt == 'l') {
+ is_long = YES;
+ fmt++;
+ } else
+ is_long = NO;
+
+ /*
+ * Argument extraction and printing.
+ * First we determine the argument type.
+ * Then, we convert the argument to a string.
+ * On exit from the switch, s points to the string that
+ * must be printed, s_len has the length of the string
+ * The precision requirements, if any, are reflected in s_len.
+ *
+ * NOTE: pad_char may be set to '0' because of the 0 flag.
+ * It is reset to ' ' by non-numeric formats
+ */
+ switch (*fmt) {
+ case 'u':
+ if (is_long)
+ i_num = va_arg(ap, u_wide_int);
+ else
+ i_num = (wide_int) va_arg(ap, unsigned int);
+ /*
+ * The rest also applies to other integer formats, so fall
+ * into that case.
+ */
+ case 'd':
+ case 'i':
+ /*
+ * Get the arg if we haven't already.
+ */
+ if ((*fmt) != 'u') {
+ if (is_long)
+ i_num = va_arg(ap, wide_int);
+ else
+ i_num = (wide_int) va_arg(ap, int);
+ };
+ s = conv_10(i_num, (*fmt) == 'u', &is_negative,
+ &num_buf[NUM_BUF_SIZE], &s_len);
+ FIX_PRECISION(adjust_precision, precision, s, s_len);
+
+ if (*fmt != 'u') {
+ if (is_negative)
+ prefix_char = '-';
+ else if (print_sign)
+ prefix_char = '+';
+ else if (print_blank)
+ prefix_char = ' ';
+ }
+ break;
+
+
+ case 'o':
+ if (is_long)
+ ui_num = va_arg(ap, u_wide_int);
+ else
+ ui_num = (u_wide_int) va_arg(ap, unsigned int);
+ s = conv_p2(ui_num, 3, *fmt,
+ &num_buf[NUM_BUF_SIZE], &s_len);
+ FIX_PRECISION(adjust_precision, precision, s, s_len);
+ if (alternate_form && *s != '0') {
+ *--s = '0';
+ s_len++;
+ }
+ break;
+
+
+ case 'x':
+ case 'X':
+ if (is_long)
+ ui_num = (u_wide_int) va_arg(ap, u_wide_int);
+ else
+ ui_num = (u_wide_int) va_arg(ap, unsigned int);
+ s = conv_p2(ui_num, 4, *fmt,
+ &num_buf[NUM_BUF_SIZE], &s_len);
+ FIX_PRECISION(adjust_precision, precision, s, s_len);
+ if (alternate_form && i_num != 0) {
+ *--s = *fmt; /* 'x' or 'X' */
+ *--s = '0';
+ s_len += 2;
+ }
+ break;
+
+
+ case 's':
+ s = va_arg(ap, char *);
+ if (s != NULL) {
+ s_len = strlen(s);
+ if (adjust_precision && precision < s_len)
+ s_len = precision;
+ } else {
+ s = S_NULL;
+ s_len = S_NULL_LEN;
+ }
+ pad_char = ' ';
+ break;
+
+
+ case 'f':
+ case 'e':
+ case 'E':
+ fp_num = va_arg(ap, double);
+
+ s = conv_fp(*fmt, fp_num, alternate_form,
+ (adjust_precision == NO) ? FLOAT_DIGITS : precision,
+ &is_negative, &num_buf[1], &s_len);
+ if (is_negative)
+ prefix_char = '-';
+ else if (print_sign)
+ prefix_char = '+';
+ else if (print_blank)
+ prefix_char = ' ';
+ break;
+
+
+ case 'g':
+ case 'G':
+ if (adjust_precision == NO)
+ precision = FLOAT_DIGITS;
+ else if (precision == 0)
+ precision = 1;
+ /*
+ * * We use &num_buf[ 1 ], so that we have room for the sign
+ */
+ s = ap_gcvt(va_arg(ap, double), precision, &num_buf[1]);
+ if (*s == '-')
+ prefix_char = *s++;
+ else if (print_sign)
+ prefix_char = '+';
+ else if (print_blank)
+ prefix_char = ' ';
+
+ s_len = strlen(s);
+
+ if (alternate_form && (q = strchr(s, '.')) == NULL)
+ s[s_len++] = '.';
+ if (*fmt == 'G' && (q = strchr(s, 'e')) != NULL)
+ *q = 'E';
+ break;
+
+
+ case 'c':
+ char_buf[0] = (char) (va_arg(ap, int));
+ s = &char_buf[0];
+ s_len = 1;
+ pad_char = ' ';
+ break;
+
+
+ case '%':
+ char_buf[0] = '%';
+ s = &char_buf[0];
+ s_len = 1;
+ pad_char = ' ';
+ break;
+
+
+ case 'n':
+ *(va_arg(ap, int *)) = cc;
+ break;
+
+ /*
+ * Always extract the argument as a "char *" pointer. We
+ * should be using "void *" but there are still machines
+ * that don't understand it.
+ * If the pointer size is equal to the size of an unsigned
+ * integer we convert the pointer to a hex number, otherwise
+ * we print "%p" to indicate that we don't handle "%p".
+ */
+ case 'p':
+ ui_num = (u_wide_int) va_arg(ap, char *);
+
+ if (sizeof(char *) <= sizeof(u_wide_int))
+ s = conv_p2(ui_num, 4, 'x',
+ &num_buf[NUM_BUF_SIZE], &s_len);
+ else {
+ s = "%p";
+ s_len = 2;
+ }
+ pad_char = ' ';
+ break;
+
+
+ case NUL:
+ /*
+ * The last character of the format string was %.
+ * We ignore it.
+ */
+ continue;
+
+
+ /*
+ * The default case is for unrecognized %'s.
+ * We print %<char> to help the user identify what
+ * option is not understood.
+ * This is also useful in case the user wants to pass
+ * the output of format_converter to another function
+ * that understands some other %<char> (like syslog).
+ * Note that we can't point s inside fmt because the
+ * unknown <char> could be preceded by width etc.
+ */
+ default:
+ char_buf[0] = '%';
+ char_buf[1] = *fmt;
+ s = char_buf;
+ s_len = 2;
+ pad_char = ' ';
+ break;
+ }
+
+ if (prefix_char != NUL) {
+ *--s = prefix_char;
+ s_len++;
+ }
+ if (adjust_width && adjust == RIGHT && min_width > s_len) {
+ if (pad_char == '0' && prefix_char != NUL) {
+ INS_CHAR(*s, sp, bep, cc)
+ s++;
+ s_len--;
+ min_width--;
+ }
+ PAD(min_width, s_len, pad_char);
+ }
+ /*
+ * Print the string s.
+ */
+ for (i = s_len; i != 0; i--) {
+ INS_CHAR(*s, sp, bep, cc);
+ s++;
+ }
+
+ if (adjust_width && adjust == LEFT && min_width > s_len)
+ PAD(min_width, s_len, pad_char);
+ }
+ fmt++;
+ }
+ odp->nextb = sp;
+ return (cc);
+}
+
+
+/*
+ * This is the general purpose conversion function.
+ */
+static void strx_printv(int *ccp, char *buf, size_t len, const char *format,
+ va_list ap)
+{
+ buffy od;
+ int cc;
+
+ /*
+ * First initialize the descriptor
+ * Notice that if no length is given, we initialize buf_end to the
+ * highest possible address.
+ */
+ od.buf_end = len ? &buf[len] : (char *) ~0;
+ od.nextb = buf;
+
+ /*
+ * Do the conversion
+ */
+ cc = format_converter(&od, format, ap);
+ if (len == 0 || od.nextb <= od.buf_end)
+ *(od.nextb) = '\0';
+ if (ccp)
+ *ccp = cc;
+}
+
+
+int ap_snprintf(char *buf, size_t len, const char *format,...)
+{
+ int cc;
+ va_list ap;
+
+ va_start(ap, format);
+ strx_printv(&cc, buf, (len - 1), format, ap);
+ va_end(ap);
+ return (cc);
+}
+
+
+int ap_vsnprintf(char *buf, size_t len, const char *format, va_list ap)
+{
+ int cc;
+
+ strx_printv(&cc, buf, (len - 1), format, ap);
+ return (cc);
+}
+
+#endif /* HAVE_SNPRINTF */
+#endif /* APACHE */
diff --git a/main/snprintf.h b/main/snprintf.h
new file mode 100644
index 0000000000..95d133213a
--- /dev/null
+++ b/main/snprintf.h
@@ -0,0 +1,56 @@
+/*
+ +----------------------------------------------------------------------+
+ | 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: Stig Sæther Bakken <ssb@guardian.no> |
+ +----------------------------------------------------------------------+
+ */
+
+#ifndef _PHP3_SNPRINTF_H
+#define _PHP3_SNPRINTF_H
+
+#ifndef HAVE_SNPRINTF
+extern int ap_snprintf(char *, size_t, const char *, ...);
+#define snprintf ap_snprintf
+#endif
+
+#ifndef HAVE_VSNPRINTF
+extern int ap_vsnprintf(char *, size_t, const char *, va_list ap);
+#define vsnprintf ap_vsnprintf
+#endif
+
+#if BROKEN_SPRINTF
+int _php3_sprintf (char* s, const char* format, ...);
+#else
+#define _php3_sprintf sprintf
+#endif
+
+#endif /* _PHP3_SNPRINTF_H */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ */
diff --git a/main/win95nt.h b/main/win95nt.h
new file mode 100644
index 0000000000..0808a84638
--- /dev/null
+++ b/main/win95nt.h
@@ -0,0 +1,74 @@
+/* Defines and types for Windows 95/NT */
+#define WIN32_LEAN_AND_MEAN
+#include <io.h>
+#include <malloc.h>
+#include <direct.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <sys/types.h>
+typedef int uid_t;
+typedef int gid_t;
+typedef int mode_t;
+typedef char * caddr_t;
+#define lstat(x, y) stat(x, y)
+#define _IFIFO 0010000 /* fifo */
+#define _IFBLK 0060000 /* block special */
+#define _IFLNK 0120000 /* symbolic link */
+#define S_IFIFO _IFIFO
+#define S_IFBLK _IFBLK
+#define S_IFLNK _IFLNK
+#define pclose _pclose
+#define popen _popen
+#define chdir(path) SetCurrentDirectory(path)
+#define mkdir(a,b) _mkdir(a)
+#define rmdir _rmdir
+#define getpid _getpid
+#if !(APACHE)
+#define sleep(t) Sleep(t*1000)
+#endif
+#define getcwd _getcwd
+#define snprintf _snprintf
+#define off_t _off_t
+#define vsnprintf _vsnprintf
+typedef unsigned int uint;
+typedef unsigned long ulong;
+#if !NSAPI
+#define strcasecmp(s1, s2) stricmp(s1, s2)
+#define strncasecmp(s1, s2, n) strnicmp(s1, s2, n)
+typedef long pid_t;
+#endif
+
+/* missing in vc5 math.h */
+#define M_PI 3.14159265358979323846
+#define M_TWOPI (M_PI * 2.0)
+#define M_PI_2 1.57079632679489661923
+#define M_PI_4 0.78539816339744830962
+
+#if !DEBUG
+#ifdef inline
+#undef inline
+#endif
+#define inline __inline
+#endif
+
+/* General Windows stuff */
+#define WINDOWS 1
+
+/* Prevent use of VC5 OpenFile function */
+#define NOOPENFILE
+
+/* sendmail is built-in */
+#ifdef PHP_PROG_SENDMAIL
+#undef PHP_PROG_SENDMAIL
+#define PHP_PROG_SENDMAIL "Built in mailer"
+#endif
+
+#define CONVERT_TO_WIN_FS(Filename) \
+{ \
+ char *stemp; \
+ if (Filename) \
+ for (stemp = Filename; *stemp; stemp++) \
+ if ( *stemp == '/') \
+ *stemp = '\\'; \
+}