diff options
Diffstat (limited to 'main')
-rw-r--r-- | main/alloca.c | 505 | ||||
-rw-r--r-- | main/config.w32.h | 294 | ||||
-rw-r--r-- | main/configuration-parser.y | 415 | ||||
-rw-r--r-- | main/configuration-scanner.l | 170 | ||||
-rw-r--r-- | main/fopen_wrappers.c | 1000 | ||||
-rw-r--r-- | main/fopen_wrappers.h | 90 | ||||
-rw-r--r-- | main/internal_functions_registry.h | 57 | ||||
-rw-r--r-- | main/logos.h | 805 | ||||
-rw-r--r-- | main/main.c | 2222 | ||||
-rw-r--r-- | main/php.h | 485 | ||||
-rw-r--r-- | main/php3_compat.h | 80 | ||||
-rw-r--r-- | main/php_ini.c | 148 | ||||
-rw-r--r-- | main/php_ini.h | 48 | ||||
-rw-r--r-- | main/php_version.h | 1 | ||||
-rw-r--r-- | main/safe_mode.c | 156 | ||||
-rw-r--r-- | main/safe_mode.h | 7 | ||||
-rw-r--r-- | main/snprintf.c | 935 | ||||
-rw-r--r-- | main/snprintf.h | 56 | ||||
-rw-r--r-- | main/win95nt.h | 74 |
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 **) ¤t_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=⪚ +#endif + + GLOBAL(php3_rqst) = r; + + if (php3_request_startup(CLS_C ELS_CC) == FAILURE) { + return FAILURE; + } + php3_TreatHeaders(); + file_handle.type = ZEND_HANDLE_FD; + file_handle.handle.fd = fd; + file_handle.filename = request_info.filename; + GLOBAL(initialized) |= INIT_SCANNER; + (void) php3_parse(&file_handle CLS_CC ELS_CC); + + if (GLOBAL(initialized)) { + php3_header(); /* Make sure headers have been sent */ + zend_end_ob_buffering(1); + } + return (OK); +} +#endif /* APACHE */ + +#if FHTTPD + +char *get_pretokenized_name(void) +{ + char *pretokenized_name = NULL; + + if (GLOBAL(request_info).filename) { + int length = strlen(GLOBAL(request_info).filename); + + if (length > (sizeof(".php3") - 1) && !strcmp(GLOBAL(request_info).filename + length - sizeof(".php3") + 1, ".php3")) { + pretokenized_name = (char *) emalloc(length + 2); + strcpy(pretokenized_name, GLOBAL(request_info).filename); + strcat(pretokenized_name, "p"); + } else { + length += sizeof(".php3p"); + pretokenized_name = (char *) emalloc(length + 1); + strcpy(pretokenized_name, GLOBAL(request_info).filename); + strcat(pretokenized_name, ".php3p"); + } + } else { + pretokenized_name = estrdup("stdin.php3p"); + } + return pretokenized_name; +} + + +void _php3_usage(char *progname) +{ + fprintf(stderr, + "Usage: %s [options] [appname] [username] [hostname] [portname]\n" + "Options:\n" + " -d Daemon mode -- never attempt terminal I/O\n" + " -s Socket mode, fhttpd internal use only\n" + " -p Pipe mode, fhttpd internal use only\n" + " -u<mask> Set umask\n" + " -t<time> Idle timeout in seconds, 0 - disable\n" + " -S Display colour syntax highlighted source\n" + " -P Make and execute a pretokenized script\n" + " (.php3p file) or, if pretokenized script, newer\n" + " than original file exists, execute it instead\n" + " -E Execute a pretokenized (.php3p) script\n" + " -c<path> Look for php3.ini file in this directory\n" + " (must appear before any other options)\n" + " -v Version number\n" + " -h This help\n", + progname); +} + +int main(int argc, char **argv) +{ + int c, i, processing_error; + FILE *in = NULL; + FILE *in2; + int preprocess_mode = PREPROCESS_NONE; + int argc1; + char **argv1; + int human = 1, fd2; + int i0 = 0, i1 = 0; + char *pn; + struct stat statbuf, pstatbuf; +#ifdef ZTS + zend_compiler_globals cg; + zend_executor_globals eg; + zend_compiler_globals *compiler_globals=&cg; + zend_executor_globals *executor_globals=⪚ +#endif + +#ifdef THREAD_SAFE + php3_globals_struct *php3_globals; + flex_globals *php_flex_gbl; + tls_startup(); + tls_create(); + php_flex_gbl = yy_init_tls(); + php3_globals = TlsGetValue(TlsIndex); + + if ((php3_globals == 0) && (GetLastError() != 0)) { + PUTS("TlsGetValue error\n"); + return FAILURE; + } +#endif + +#if HAVE_SETLOCALE + setlocale(LC_CTYPE, ""); +#endif + + if (php3_module_startup(CLS_C ELS_CC) == FAILURE) { + return FAILURE; + } + signal(SIGPIPE, SIG_IGN); + umask(077); + + while ((c = getopt(argc, argv, "spdu:t:c:PESvh")) != -1) { + switch (c) { + case 'd': + human = 0; + break; + case 's': + i0 = 1; + break; + case 'p': + i1 = 1; + break; + case 'u': + if (*optarg == '0') + umask(strtoul(optarg, NULL, 8)); + else + umask(strtoul(optarg, NULL, 10)); + break; + case 't': + idle_timeout = atoi(optarg); + break; + case 'c': + GLOBAL(php3_ini_path) = strdup(optarg); /* intentional leak */ + break; + case 'P': /* preprocess */ + preprocess_mode = PREPROCESS_PREPROCESS; + break; + case 'E': /* execute preprocessed script */ + preprocess_mode = PREPROCESS_EXECUTE; + break; + case 'S': + printf ("Not implemented yet\n"); + break; + case 'v': + printf("%s\n", PHP_VERSION); + exit(1); + break; + case 'h': + case ':': + case '?': + _php3_usage(argv[0]); + return -1; + } + } + + argc1 = argc - optind; + argv1 = (char **) malloc(sizeof(char *) * (argc1 + 2)); + if (!argv1) + return -1; + argv1 += 2; + for (i = optind; i < argc; i++) + argv1[i - optind] = argv[i]; + + if (i0) { + argv1--; + *argv1 = "-s"; + argc1++; + } else { + if (i1) { + argv1--; + *argv1 = "-p"; + argc1++; + } + } + argv1--; + argc1++; + *argv1 = *argv; + + server = createserver(); + if (!server) + return -1; + + switch (servproc_init(server, human, argc1, argv1)) { + case 0: + break; + case APP_ERR_HUMAN: + _php3_usage(argv[0]); + exit(1); + break; + case APP_ERR_CONFIG: + fprintf(stderr, "%s: configuration error\n", server->app_progname); + exit(1); + break; + case APP_ERR_READ: + fprintf(stderr, "%s: read error\n", server->app_progname); + exit(1); + break; + case APP_ERR_HOSTNAME: + fprintf(stderr, "%s: can't resolve server hostname\n", server->app_progname); + exit(1); + break; + case APP_ERR_SOCKET: + fprintf(stderr, "%s: can't create socket\n", server->app_progname); + exit(1); + break; + case APP_ERR_CONNECT: + fprintf(stderr, "%s: can't connect\n", server->app_progname); + exit(1); + break; + case APP_ERR_APPCONNECT: + fprintf(stderr, "%s: connect error\n", server->app_progname); + exit(1); + break; + case APP_ERR_USER: + fprintf(stderr, "%s: login error\n", server->app_progname); + exit(1); + break; + case APP_ERR_PASSWORD: + fprintf(stderr, "%s: login error\n", server->app_progname); + exit(1); + break; + case APP_ERR_APPLICATION: + fprintf(stderr, "%s: application rejected by server\n", server->app_progname); + exit(1); + break; + case APP_ERR_INSANE: + case APP_ERR_DAEMON: + case APP_ERR_AUTH: + default: + if (server->infd < 0) + exit(1); + } + + if (server->infd == 0 && server->outfd == 1) { + close(2); + fd2 = open("/dev/null", O_WRONLY); + if (fd2 != 2) { + dup2(fd2, 2); + close(fd2); + } + } + setcapabilities(server, APP_CAP_KEEPALIVE); + + exit_status = 0; + while (!exit_status) { + processing_error = 0; + if (php3_request_startup(_INLINE_TLS_VOID) == FAILURE) { + processing_error = 1; + } + if (!processing_error) { + GLOBAL(phpin) = NULL; + GLOBAL(current_lineno) = 0; + + php3_TreatHeaders(); + + in = php3_fopen_for_parser(); + + GLOBAL(php3_preprocess) = preprocess_mode; + + if (!in) { + PUTS("No input file specified.\n"); + php3_request_shutdown((void *) 0 _INLINE_TLS); + processing_error = 1; + } else { + if (GLOBAL(php3_preprocess) == PREPROCESS_PREPROCESS) { + pn = get_pretokenized_name(); + if (pn) { + if (!stat(pn, &pstatbuf) + && !fstat(fileno(in), &statbuf) + && S_ISREG(pstatbuf.st_mode) + && statbuf.st_mtime < pstatbuf.st_mtime) { + in2 = fopen(pn, "r"); + if (in2) { + fclose(in); + in = in2; + GLOBAL(php3_preprocess) = PREPROCESS_EXECUTE; + } + } + efree(pn); + } + } + if (GLOBAL(php3_preprocess) != PREPROCESS_EXECUTE) { + /* #!php support */ + c = fgetc(in); + if (c == '#') { + while (c != 10 && c != 13) { + c = fgetc(in); /* skip to end of line */ + } + CG(phplineno)++; + } else { + rewind(in); + } + } + GLOBAL(phpin) = in; + GLOBAL(initialized) |= INIT_SCANNER; + phprestart(GLOBAL(phpin)); + + if (!processing_error) { + if (GLOBAL(php3_preprocess) == PREPROCESS_EXECUTE) { + if (tcm_load(&GLOBAL(token_cache_manager), GLOBAL(phpin))==FAILURE) { + /* should bail out on an error, don't know how to do it in fhttpd */ + } + GLOBAL(php3_preprocess) = PREPROCESS_NONE; + } + if (GLOBAL(php3_preprocess)!=PREPROCESS_NONE) { + pval yylval; + + while (phplex(&yylval)); /* create the token cache */ + tcm_save(&GLOBAL(token_cache_manager)); + seek_token(&GLOBAL(token_cache_manager), 0, NULL); + GLOBAL(php3_preprocess) = PREPROCESS_NONE; + } + php3_parse(GLOBAL(phpin) CLS_CC ELS_CC); + + } + } + } + if (GLOBAL(initialized)) { + php3_header(); /* Make sure headers have been sent */ + php3_request_shutdown((void *) 0 _INLINE_TLS); + } + } + php3_module_shutdown(_INLINE_TLS_VOID); +#ifdef THREAD_SAFE + if (GLOBAL(initialized)) { + yy_destroy_tls(); + tls_shutdown(); + tls_destroy(); + } +#endif + return 0; +} +#endif /* FHTTPD */ + +#if USE_SAPI + +PHPAPI int php3_sapi_main(struct sapi_request_info *sapi_info) +{ +#if DEBUG + char logmessage[1024]; +#endif + FILE *in = NULL; + int c; + YY_TLS_VARS; + TLS_VARS; + + GLOBAL(php3_preprocess) = sapi_info->preprocess; + GLOBAL(php3_display_source) = sapi_info->display_source_mode; + GLOBAL(sapi_rqst) = sapi_info; + +#if DEBUG + snprintf(logmessage,1024,"%d:php3_sapi_main: entry\n",GLOBAL(sapi_rqst)->scid); + OutputDebugString(logmessage); +#endif + +/* if (php3_module_startup(php3_globals) == FAILURE) { + return FAILURE; + }*/ + + if (php3_request_startup(CLS_C ELS_CC) == FAILURE) { +#if DEBUG + snprintf(logmessage,1024,"%d:php3_sapi_main: request starup failed\n",GLOBAL(sapi_rqst)->scid); + OutputDebugString(logmessage); +#endif + return FAILURE; + } + if (sapi_info->preprocess == PREPROCESS_PREPROCESS || sapi_info->quiet_mode) { + php3_noheader(); + } + if (sapi_info->info_only) { + _php3_info(); + php3_request_shutdown((void *) GLOBAL(sapi_rqst), php3_globals); + /*php3_module_shutdown(php3_globals);*/ +#if DEBUG + snprintf(logmessage,1024,"%d:php3_sapi_main: info_only\n",GLOBAL(sapi_rqst)->scid); + OutputDebugString(logmessage); +#endif + return (1); + } + /* if its not cgi, require that we have a filename now */ +#if DEBUG + snprintf(logmessage,1024,"%d:php3_sapi_main: File: %s\n",GLOBAL(sapi_rqst)->scid,GLOBAL(sapi_rqst)->filename); + OutputDebugString(logmessage); +#endif + if (!sapi_info->cgi && !sapi_info->filename) { + php3_printf("No input file specified.\n"); + php3_request_shutdown((void *) GLOBAL(sapi_rqst), php3_globals); + /*php3_module_shutdown(php3_globals);*/ +#if DEBUG + snprintf(logmessage,1024,"%d:php3_sapi_main: No input file specified\n",GLOBAL(sapi_rqst)->scid); + OutputDebugString(logmessage); +#endif + return FAILURE; + } + /* + if request_info.filename is null and cgi, fopen_for_parser is responsible + request_info.filename will only be estrduped in fopen_for parser + if it is null at this point + */ + in = php3_fopen_for_parser(); + + if (sapi_info->cgi && !in) { + php3_printf("No input file specified for cgi.\n"); + php3_request_shutdown((void *) GLOBAL(sapi_rqst), php3_globals); + /*php3_module_shutdown(php3_globals);*/ +#if DEBUG + snprintf(logmessage,1024,"%d:php3_sapi_main: No input file specified for cgi.\n",GLOBAL(sapi_rqst)->scid); + OutputDebugString(logmessage); +#endif + return FAILURE; + } + if (sapi_info->cgi && in) { + /* #!php support */ + c = fgetc(in); + if (c == '#') { + while (c != 10 && c != 13) { + c = fgetc(in); /* skip to end of line */ + } + } else { + rewind(in); + } + } + if (in) { + GLOBAL(phpin) = in; + phprestart(GLOBAL(phpin)); + GLOBAL(initialized) |= INIT_SCANNER; + } + if (sapi_info->display_source_mode) { + GLOBAL(php3_display_source) = 1; + PUTS("<html><head><title>Source for "); + PUTS(sapi_info->filename); + PUTS("</title></head><body bgcolor=\""); + PUTS(php3_ini.highlight_bg); + PUTS("\" text=\""); + PUTS(php3_ini.highlight_html); + PUTS("\">\n"); /* color: seashell */ + } + if (sapi_info->display_source_mode && sapi_info->preprocess == PREPROCESS_PREPROCESS) { + php3_printf("Can't preprocess while displaying source.<br>\n"); + return FAILURE; + } + if (sapi_info->preprocess == PREPROCESS_EXECUTE) { + tcm_load(&GLOBAL(token_cache_manager)); + GLOBAL(php3_preprocess) = PREPROCESS_NONE; + } + if (sapi_info->preprocess==PREPROCESS_NONE) { +#if DEBUG + snprintf(logmessage,1024,"%d:php3_sapi_main: start php3_parse() file:%s\n",GLOBAL(sapi_rqst)->scid,GLOBAL(sapi_rqst)->filename); + OutputDebugString(logmessage); +#endif + php3_parse(GLOBAL(phpin) _INLINE_TLS); +#if DEBUG + snprintf(logmessage,1024,"%d:php3_sapi_main: done php3_parse()\n",GLOBAL(sapi_rqst)->scid); + OutputDebugString(logmessage); +#endif + } else { + pval yylval; + +#if DEBUG + snprintf(logmessage,1024,"%d:php3_sapi_main: entering phplex()\n",GLOBAL(sapi_rqst)->scid); + OutputDebugString(logmessage); +#endif +#ifdef THREAD_SAFE + while (phplex(&yylval, php3_globals, php_gbl)); /* create the token cache */ +#else + while (phplex(&yylval)); /* create the token cache */ +#endif +#if DEBUG + snprintf(logmessage,1024,"%d:php3_sapi_main: done phplex()\n",GLOBAL(sapi_rqst)->scid); + OutputDebugString(logmessage); +#endif + tcm_save(&GLOBAL(token_cache_manager)); + } + + if (sapi_info->display_source_mode) { + php3_printf("\n</html>\n"); + } + if (GLOBAL(initialized)) { + php3_header(); /* Make sure headers have been sent */ + php3_request_shutdown((void *) GLOBAL(sapi_rqst), php3_globals); + /*php3_module_shutdown(php3_globals);*/ +#if DEBUG + snprintf(logmessage,1024,"%d:php3_sapi_main: success!\n",GLOBAL(sapi_rqst)->scid); + OutputDebugString(logmessage); +#endif + return SUCCESS; + } else { +#if DEBUG + snprintf(logmessage,1024,"%d:php3_sapi_main: request not initialized!\n",GLOBAL(sapi_rqst)->scid); + OutputDebugString(logmessage); +#endif + return FAILURE; + } +} +#if WIN32|WINNT +extern int tls_create(void); +extern int tls_destroy(void); +extern int tls_startup(void); +extern int tls_shutdown(void); +extern flex_globals *yy_init_tls(void); +extern void yy_destroy_tls(void); +extern VOID ErrorExit(LPTSTR lpszMessage); + +BOOL WINAPI DllMain(HANDLE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved) +{ + php3_globals_struct *php3_globals; +#if DEBUG + OutputDebugString("PHP_Core DllMain Entry\n"); +#endif + switch (ul_reason_for_call) { + case DLL_PROCESS_ATTACH: + /* + I should be loading ini vars here + and doing whatever true global inits + need to be done + */ + _fmode = _O_BINARY; /*sets default for file streams to binary */ + /* make the stdio mode be binary */ + setmode(_fileno(stdin), O_BINARY); + setmode(_fileno(stdout), O_BINARY); + setmode(_fileno(stderr), O_BINARY); + setlocale(LC_CTYPE, ""); + + CREATE_MUTEX(gLock, "GENERAL"); + + if (!tls_startup()) + return 0; + if (!tls_create()) + return 0; + php3_globals = TlsGetValue(TlsIndex); + yy_init_tls(); + if (php3_config_ini_startup(_INLINE_TLS_VOID) == FAILURE) { + return 0; + } + if (php3_module_startup(php3_globals) == FAILURE) { + ErrorExit("module startup failed"); + return 0; + } + +#if DEBUG + OutputDebugString("PHP_Core DllMain Process Attached\n"); +#endif + break; + case DLL_THREAD_ATTACH: +#if DEBUG + OutputDebugString("PHP_Core DllMain Thread Attach\n"); +#endif + if (!tls_create()) + return 0; + php3_globals = TlsGetValue(TlsIndex); + yy_init_tls(); + if (php3_module_startup(php3_globals) == FAILURE) { + ErrorExit("module startup failed"); +#if DEBUG + OutputDebugString("PHP_Core DllMain module startup failed\n"); +#endif + return 0; + } + break; + case DLL_THREAD_DETACH: +#if DEBUG + OutputDebugString("PHP_Core DllMain Detache\n"); +#endif + php3_globals = TlsGetValue(TlsIndex); + php3_module_shutdown(php3_globals); + if (!tls_destroy()) +#if DEBUG + OutputDebugString("PHP_Core DllMain Detache Error tls_destroy\n"); +#endif + return 0; + yy_destroy_tls(); + break; + case DLL_PROCESS_DETACH: + /* + close down anything down in process_attach + */ + php3_globals = TlsGetValue(TlsIndex); + php3_module_shutdown(php3_globals); + + php3_config_ini_shutdown(_INLINE_TLS_VOID); + + if (!tls_destroy()) +#if DEBUG + OutputDebugString("PHP_Core DllMain tls_destroy failed\n"); +#endif + return 0; + if (!tls_shutdown()) +#if DEBUG + OutputDebugString("PHP_Core DllMain tls_shutdown failed\n"); +#endif + return 0; + yy_destroy_tls(); +#if DEBUG + OutputDebugString("PHP_Core DllMain Process Detatched\n"); +#endif + break; + } +#if DEBUG + OutputDebugString("PHP_Core DllMain Successful Exit\n"); +#endif + return 1; +} + +#endif +#endif +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + */ 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 = '\\'; \ +} |