From: Stig Bakken Date: Tue, 15 Jun 1999 21:51:00 +0000 (+0000) Subject: * reverse fsock/string import patches X-Git-Tag: BEFORE_REMOVING_GC_STEP1~132 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8c4411b5da9bf6385e35ad8c0a835f6ffe656203;p=php * reverse fsock/string import patches --- diff --git a/ext/standard/file.c b/ext/standard/file.c index 56325f5879..92abdaeba2 100644 --- a/ext/standard/file.c +++ b/ext/standard/file.c @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP HTML Embedded Scripting Language Version 3.0 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-1999 PHP Development Team (See Credits file) | + | 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: | @@ -13,7 +13,7 @@ | | | 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 | @@ -29,6 +29,7 @@ /* $Id$ */ #include "php.h" #include "php_globals.h" +#include "ext/standard/flock_compat.h" #include #include @@ -47,8 +48,10 @@ #include /* #include */ #endif +#include "ext/standard/head.h" #include "safe_mode.h" -#include "php3_standard.h" +#include "php3_string.h" +#include "file.h" #if HAVE_PWD_H #if MSVC5 #include "win32/pwd.h" @@ -59,25 +62,17 @@ #if HAVE_SYS_TIME_H #include #endif -#if MSVC5 -#include -#else -#include -#include -#include -#endif #include "snprintf.h" #include "fsock.h" #include "fopen-wrappers.h" - -#if HAVE_SYS_FILE_H -#include -#endif +#include "php_globals.h" #if MISSING_FCLOSE_DECL extern int fclose(); #endif +static void _php3_closesocket(int *); + #ifndef THREAD_SAFE static int fgetss_state = 0; int le_fp,le_pp; @@ -130,8 +125,8 @@ extern int le_uploads; # endif #endif -char * -tempnam(const char *dir, const char *pfx) + +char *tempnam(const char *dir, const char *pfx) { int save_errno; char *f, *name; @@ -176,37 +171,37 @@ tempnam(const char *dir, const char *pfx) } #endif + function_entry php3_file_functions[] = { - PHP_FE(pclose, NULL) - PHP_FE(popen, NULL) - PHP_FE(readfile, NULL) - PHP_FE(rewind, NULL) + {"pclose", php3_pclose, NULL}, + {"popen", php3_popen, NULL}, + {"readfile", php3_readfile, NULL}, + {"rewind", php3_rewind, NULL}, + {"rmdir", php3_rmdir, NULL}, {"umask", php3_fileumask, NULL}, - PHP_FE(rmdir, NULL) - PHP_FE(fclose, NULL) - PHP_FE(feof, NULL) - PHP_FE(fgetc, NULL) - PHP_FE(fgets, NULL) - PHP_FE(fgetss, NULL) - PHP_FE(fpassthru, NULL) - PHP_FE(fread, NULL) - PHP_FE(fopen, NULL) - PHP_FE(fseek, NULL) - PHP_FE(ftell, NULL) - PHP_FE(fwrite, NULL) - PHP_FE(set_file_buffer, NULL) + {"fclose", php3_fclose, NULL}, + {"feof", php3_feof, NULL}, + {"fgetc", php3_fgetc, NULL}, + {"fgets", php3_fgets, NULL}, + {"fgetss", php3_fgetss, NULL}, + {"fread", php3_fread, NULL}, + {"fopen", php3_fopen, NULL}, + {"fpassthru", php3_fpassthru, NULL}, + {"fseek", php3_fseek, NULL}, + {"ftell", php3_ftell, NULL}, + {"fwrite", php3_fwrite, NULL}, {"fputs", php3_fwrite, NULL}, - PHP_FE(mkdir, NULL) - PHP_FE(rename, NULL) + {"mkdir", php3_mkdir, NULL}, + {"rename", php3_rename, NULL}, {"copy", php3_file_copy, NULL}, - PHP_FE(tempnam, NULL) - PHP_FE(file, NULL) - PHP_FE(flock, NULL) - PHP_FE(fgetcsv, NULL) - PHP_FE(get_meta_tags, NULL) - PHP_FE(set_socket_blocking, NULL) + {"tempnam", php3_tempnam, NULL}, + {"file", php3_file, NULL}, + {"fgetcsv", php3_fgetcsv, NULL}, + PHP_FE(flock, NULL) + {"get_meta_tags", php3_get_meta_tags, NULL}, + {"set_socket_blocking", php3_set_socket_blocking, NULL}, #if (0 && HAVE_SYS_TIME_H && HAVE_SETSOCKOPT && defined(SO_SNDTIMEO) && defined(SO_RCVTIMEO)) - PHP_FE(set_socket_timeout, NULL) + {"set_socket_timeout", php3_set_socket_timeout, NULL}, #endif {NULL, NULL, NULL} }; @@ -215,9 +210,64 @@ php3_module_entry php3_file_module_entry = { "PHP_file", php3_file_functions, php3_minit_file, NULL, NULL, NULL, NULL, STANDARD_MODULE_PROPERTIES }; + +static int flock_values[] = { LOCK_SH, LOCK_EX, LOCK_UN }; + +/* {{{ proto bool flock(int fp, int operation) + portable file locking */ +PHP_FUNCTION(flock) +{ + pval *arg1, *arg2; + FILE *fp; + int type; + int issock=0; + int *sock, fd=0; + int act = 0; + + if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &arg1, &arg2) == FAILURE) { + WRONG_PARAM_COUNT; + } + + convert_to_long(arg1); + convert_to_long(arg2); + + fp = php3_list_find(arg1->value.lval, &type); + if (type == wsa_fp){ + issock = 1; + sock = php3_list_find(arg1->value.lval, &type); + fd = *sock; + } + + if ((!fp || (type!=le_fp && type!=le_pp)) && (!fd || type!=wsa_fp)) { + php3_error(E_WARNING,"Unable to find file identifier %d",arg1->value.lval); + RETURN_FALSE; + } + + if (!issock) { + fd = fileno(fp); + } + + act = arg2->value.lval & 3; + if(act < 1 || act > 3) { + php3_error(E_WARNING, "illegal value for second argument"); + RETURN_FALSE; + } + /* flock_values contains all possible actions + if (arg2 & 4) we won't block on the lock */ + act = flock_values[act - 1] | (arg2->value.lval & 4 ? LOCK_NB : 0); + if (flock(fd, act) == -1) { + RETURN_FALSE; + } + + RETURN_TRUE; +} +/* }}} */ + + /* {{{ proto array get_meta_tags(string filename [, int use_include_path]) Extracts all meta tag content attributes from a file and returns an array */ -void php3_get_meta_tags(INTERNAL_FUNCTION_PARAMETERS) { +PHP_FUNCTION(get_meta_tags) +{ pval *filename, *arg2; FILE *fp; char buf[8192]; @@ -229,20 +279,20 @@ void php3_get_meta_tags(INTERNAL_FUNCTION_PARAMETERS) { /* check args */ switch (ARG_COUNT(ht)) { - case 1: - if (getParameters(ht,1,&filename) == FAILURE) { - WRONG_PARAM_COUNT; - } - break; - case 2: - if (getParameters(ht,2,&filename,&arg2) == FAILURE) { + case 1: + if (getParameters(ht,1,&filename) == FAILURE) { + WRONG_PARAM_COUNT; + } + break; + case 2: + if (getParameters(ht,2,&filename,&arg2) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_long(arg2); + use_include_path = arg2->value.lval; + break; + default: WRONG_PARAM_COUNT; - } - convert_to_long(arg2); - use_include_path = arg2->value.lval; - break; - default: - WRONG_PARAM_COUNT; } convert_to_string(filename); @@ -257,7 +307,11 @@ void php3_get_meta_tags(INTERNAL_FUNCTION_PARAMETERS) { if (array_init(return_value)==FAILURE) { if (issock) { - SOCK_FCLOSE(socketd); +#if WIN32|WINNT + closesocket(socketd); +#else + close(socketd); +#endif } else { fclose(fp); } @@ -265,7 +319,7 @@ void php3_get_meta_tags(INTERNAL_FUNCTION_PARAMETERS) { } /* Now loop through the file and do the magic quotes thing if needed */ memset(buf,0,8191); - while((issock?SOCK_FGETS(buf,8191,socketd):fgets(buf,8191,fp)) != NULL + while((issock?SOCK_FGETS(buf,8191,socketd):fgets(buf,8191,fp) != NULL) && !php3i_stristr(buf,"")) { if(php3i_stristr(buf,"value.lval; + break; + default: WRONG_PARAM_COUNT; - } - convert_to_long(arg2); - use_include_path = arg2->value.lval; - break; - default: - WRONG_PARAM_COUNT; } convert_to_string(filename); @@ -383,7 +442,7 @@ void php3_file(INTERNAL_FUNCTION_PARAMETERS) { /* Now loop through the file and do the magic quotes thing if needed */ memset(buf,0,8191); - while((issock?SOCK_FGETS(buf,8191,socketd):fgets(buf,8191,fp)) != NULL) { + while(issock?SOCK_FGETS(buf,8191,socketd):fgets(buf,8191,fp) != NULL) { if (PG(magic_quotes_runtime)) { int len; @@ -394,7 +453,11 @@ void php3_file(INTERNAL_FUNCTION_PARAMETERS) { } } if (issock) { - SOCK_FCLOSE(socketd); +#if WIN32|WINNT + closesocket(socketd); +#else + close(socketd); +#endif } else { fclose(fp); } @@ -404,46 +467,52 @@ void php3_file(INTERNAL_FUNCTION_PARAMETERS) { static void __pclose(FILE *pipe) { - PLS_FETCH(); pclose_ret = pclose(pipe); } + static void _php3_closesocket(int *sock) { - if(sock) { - SOCK_FCLOSE(*sock); + int socketd=*sock; + if (socketd){ +#if WIN32|WINNT + closesocket(socketd); +#else + close(socketd); +#endif +#if HAVE_SHUTDOWN + shutdown(socketd, 0); +#endif efree(sock); } } -static void _php3_unlink_uploaded_file(char *file) { + +static void _php3_unlink_uploaded_file(char *file) +{ if(file) { unlink(file); } } -static void php3i_destructor_fclose(FILE *fp) { - (void)fclose(fp); -} int php3_minit_file(INIT_FUNC_ARGS) { - PLS_FETCH(); - - le_fp = register_list_destructors(php3i_destructor_fclose,NULL); + le_fp = register_list_destructors(fclose,NULL); le_pp = register_list_destructors(__pclose,NULL); wsa_fp = register_list_destructors(_php3_closesocket,NULL); le_uploads = register_list_destructors(_php3_unlink_uploaded_file,NULL); return SUCCESS; } + /* {{{ proto string tempnam(string dir, string prefix) Create a unique filename in a directory */ -void php3_tempnam(INTERNAL_FUNCTION_PARAMETERS) { +PHP_FUNCTION(tempnam) +{ pval *arg1, *arg2; char *d; char *t; char p[64]; - PLS_FETCH(); if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &arg1, &arg2) == FAILURE) { WRONG_PARAM_COUNT; @@ -459,9 +528,11 @@ void php3_tempnam(INTERNAL_FUNCTION_PARAMETERS) { } /* }}} */ + /* {{{ proto int fopen(string filename, string mode [, int use_include_path]) Open a file or a URL and return a file pointer */ -void php3_fopen(INTERNAL_FUNCTION_PARAMETERS) { +PHP_FUNCTION(fopen) +{ pval *arg1, *arg2, *arg3; FILE *fp; char *p; @@ -469,23 +540,22 @@ void php3_fopen(INTERNAL_FUNCTION_PARAMETERS) { int id; int use_include_path = 0; int issock=0, socketd=0; - PLS_FETCH(); switch(ARG_COUNT(ht)) { - case 2: - if (getParameters(ht,2,&arg1,&arg2) == FAILURE) { - WRONG_PARAM_COUNT; - } - break; - case 3: - if (getParameters(ht,3,&arg1,&arg2,&arg3) == FAILURE) { + case 2: + if (getParameters(ht,2,&arg1,&arg2) == FAILURE) { + WRONG_PARAM_COUNT; + } + break; + case 3: + if (getParameters(ht,3,&arg1,&arg2,&arg3) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_long(arg3); + use_include_path = arg3->value.lval; + break; + default: WRONG_PARAM_COUNT; - } - convert_to_long(arg3); - use_include_path = arg3->value.lval; - break; - default: - WRONG_PARAM_COUNT; } convert_to_string(arg1); convert_to_string(arg2); @@ -518,13 +588,14 @@ void php3_fopen(INTERNAL_FUNCTION_PARAMETERS) { } /* }}} */ + /* {{{ proto int fclose(int fp) Close an open file pointer */ -void php3_fclose(INTERNAL_FUNCTION_PARAMETERS) { +PHP_FUNCTION(fclose) +{ pval *arg1; int id, type; FILE *fp; - PLS_FETCH(); if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg1) == FAILURE) { WRONG_PARAM_COUNT; @@ -541,9 +612,11 @@ void php3_fclose(INTERNAL_FUNCTION_PARAMETERS) { } /* }}} */ + /* {{{ proto int popen(string command, string mode) Execute a command and open either a read or a write pipe to it */ -void php3_popen(INTERNAL_FUNCTION_PARAMETERS) { +PHP_FUNCTION(popen) +{ pval *arg1, *arg2; FILE *fp; int id; @@ -558,47 +631,51 @@ void php3_popen(INTERNAL_FUNCTION_PARAMETERS) { convert_to_string(arg2); p = estrndup(arg2->value.str.val,arg2->value.str.len); if (PG(safe_mode)){ - b = strchr(arg1->value.str.val,' '); - if (!b) { - b = strrchr(arg1->value.str.val,'/'); - } else { - char *c; - c = arg1->value.str.val; - while((*b!='/')&&(b!=c)) b--; - if (b==c) b=NULL; - } - if (b) { - snprintf(buf,sizeof(buf),"%s%s",PG(safe_mode_exec_dir),b); - } else { - snprintf(buf,sizeof(buf),"%s/%s",PG(safe_mode_exec_dir),arg1->value.str.val); - } - fp = popen(buf,p); - if (!fp) { - php3_error(E_WARNING,"popen(\"%s\",\"%s\") - %s",buf,p,strerror(errno)); - RETURN_FALSE; - } + b = strchr(arg1->value.str.val,' '); + if (!b) { + b = strrchr(arg1->value.str.val,'/'); + } else { + char *c; + c = arg1->value.str.val; + while((*b!='/')&&(b!=c)) { + b--; + } + if (b==c) { + b=NULL; + } + } + if (b) { + snprintf(buf,sizeof(buf),"%s%s",PG(safe_mode_exec_dir),b); + } else { + snprintf(buf,sizeof(buf),"%s/%s",PG(safe_mode_exec_dir),arg1->value.str.val); + } + fp = popen(buf,p); + if (!fp) { + php3_error(E_WARNING,"popen(\"%s\",\"%s\") - %s",buf,p,strerror(errno)); + RETURN_FALSE; + } } else { - fp = popen(arg1->value.str.val,p); - if (!fp) { - php3_error(E_WARNING,"popen(\"%s\",\"%s\") - %s",arg1->value.str.val,p,strerror(errno)); - efree(p); - RETURN_FALSE; - } + fp = popen(arg1->value.str.val,p); + if (!fp) { + php3_error(E_WARNING,"popen(\"%s\",\"%s\") - %s",arg1->value.str.val,p,strerror(errno)); + efree(p); + RETURN_FALSE; + } } -/* #endif */ id = php3_list_insert(fp,le_pp); efree(p); RETURN_LONG(id); } /* }}} */ + /* {{{ proto int pclose(int fp) Close a file pointer opened by popen() */ -void php3_pclose(INTERNAL_FUNCTION_PARAMETERS) { +PHP_FUNCTION(pclose) +{ pval *arg1; int id,type; FILE *fp; - PLS_FETCH(); if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg1) == FAILURE) { WRONG_PARAM_COUNT; @@ -616,15 +693,16 @@ void php3_pclose(INTERNAL_FUNCTION_PARAMETERS) { } /* }}} */ + /* {{{ proto int feof(int fp) Test for end-of-file on a file pointer */ -void php3_feof(INTERNAL_FUNCTION_PARAMETERS) { +PHP_FUNCTION(feof) +{ pval *arg1; FILE *fp; int id, type; int issock=0; int socketd=0, *sock; - PLS_FETCH(); if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg1) == FAILURE) { WRONG_PARAM_COUNT; @@ -642,7 +720,7 @@ void php3_feof(INTERNAL_FUNCTION_PARAMETERS) { /* we're at the eof if the file doesn't exist */ RETURN_TRUE; } - if ((issock?SOCK_FEOF(socketd):feof(fp))) { + if ((issock?(SOCK_FEOF(socketd)):feof(fp))) { RETURN_TRUE; } else { RETURN_FALSE; @@ -650,15 +728,15 @@ void php3_feof(INTERNAL_FUNCTION_PARAMETERS) { } /* }}} */ + /* {{{ proto int set_socket_blocking(int socket descriptor, int mode) Set blocking/non-blocking mode on a socket */ -void php3_set_socket_blocking(INTERNAL_FUNCTION_PARAMETERS) +PHP_FUNCTION(set_socket_blocking) { pval *arg1, *arg2; int id, type, block; int flags; int socketd=0, *sock; - PLS_FETCH(); if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &arg1, &arg2) == FAILURE) { WRONG_PARAM_COUNT; @@ -674,7 +752,6 @@ void php3_set_socket_blocking(INTERNAL_FUNCTION_PARAMETERS) RETURN_FALSE; } socketd=*sock; - _php3_sock_set_blocking(socketd, block == 0 ? 0 : 1); #if WIN32|WINNT /* with ioctlsocket, a non-zero sets nonblocking, a zero sets blocking */ flags=block; @@ -716,7 +793,7 @@ void php3_set_socket_blocking(INTERNAL_FUNCTION_PARAMETERS) #if (0 && HAVE_SYS_TIME_H && HAVE_SETSOCKOPT && defined(SO_SNDTIMEO) && defined(SO_RCVTIMEO)) /* this doesn't work, as it appears those properties are read-only :( */ -void php3_set_socket_timeout(INTERNAL_FUNCTION_PARAMETERS) +PHP_FUNCTION(set_socket_timeout) { pval *socket,*timeout; int type, *sock; @@ -741,9 +818,10 @@ void php3_set_socket_timeout(INTERNAL_FUNCTION_PARAMETERS) } #endif + /* {{{ proto string fgets(int fp, int length) Get a line from file pointer */ -void php3_fgets(INTERNAL_FUNCTION_PARAMETERS) +PHP_FUNCTION(fgets) { pval *arg1, *arg2; FILE *fp; @@ -774,7 +852,7 @@ void php3_fgets(INTERNAL_FUNCTION_PARAMETERS) buf = emalloc(sizeof(char) * (len + 1)); /* needed because recv doesnt put a null at the end*/ memset(buf,0,len+1); - if ((issock?SOCK_FGETS(buf,len,socketd):fgets(buf,len,fp)) == NULL) { + if (!(issock?SOCK_FGETS(buf,len,socketd):fgets(buf,len,fp) != NULL)) { efree(buf); RETVAL_FALSE; } else { @@ -790,16 +868,16 @@ void php3_fgets(INTERNAL_FUNCTION_PARAMETERS) } /* }}} */ + /* {{{ proto string fgetc(int fp) Get a character from file pointer */ -void php3_fgetc(INTERNAL_FUNCTION_PARAMETERS) { +PHP_FUNCTION(fgetc) { pval *arg1; FILE *fp; int id, type; char *buf; int issock=0; int *sock, socketd=0; - PLS_FETCH(); if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg1) == FAILURE) { WRONG_PARAM_COUNT; @@ -827,21 +905,22 @@ void php3_fgetc(INTERNAL_FUNCTION_PARAMETERS) { return_value->value.str.len = 1; return_value->type = IS_STRING; } + return; } /* }}} */ + /* Strip any HTML tags while reading */ /* {{{ proto string fgetss(int fp, int length) Get a line from file pointer and strip HTML tags */ -void php3_fgetss(INTERNAL_FUNCTION_PARAMETERS) +PHP_FUNCTION(fgetss) { pval *fd, *bytes; FILE *fp; - int id, len, type; - char *buf; + int id, len, br, type; + char *buf, *p, *rbuf, *rp, c, lc; int issock=0; int *sock,socketd=0; - PLS_FETCH(); if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &fd, &bytes) == FAILURE) { WRONG_PARAM_COUNT; @@ -867,23 +946,98 @@ void php3_fgetss(INTERNAL_FUNCTION_PARAMETERS) buf = emalloc(sizeof(char) * (len + 1)); /*needed because recv doesnt set null char at end*/ memset(buf,0,len+1); - if (!((issock?SOCK_FGETS(buf,len,socketd):fgets(buf, len, fp)) != NULL)) { + if (!(issock?SOCK_FGETS(buf,len,socketd):fgets(buf, len, fp) != NULL)) { efree(buf); RETURN_FALSE; } - _php3_strip_tags(buf,fgetss_state); - RETURN_STRING(buf,0); + rbuf = estrdup(buf); + c = *buf; + lc = '\0'; + p = buf; + rp = rbuf; + br = 0; + + while (c) { + switch (c) { + case '<': + if (fgetss_state == 0) { + lc = '<'; + fgetss_state = 1; + } + break; + + case '(': + if (fgetss_state == 2) { + if (lc != '\"') { + lc = '('; + br++; + } + } else if (fgetss_state == 0) { + *(rp++) = c; + } + break; + + case ')': + if (fgetss_state == 2) { + if (lc != '\"') { + lc = ')'; + br--; + } + } else if (fgetss_state == 0) { + *(rp++) = c; + } + break; + + case '>': + if (fgetss_state == 1) { + lc = '>'; + fgetss_state = 0; + } else if (fgetss_state == 2) { + if (!br && lc != '\"') { + fgetss_state = 0; + } + } + break; + + case '\"': + if (fgetss_state == 2) { + if (lc == '\"') { + lc = '\0'; + } else if (lc != '\\') { + lc = '\"'; + } + } else if (fgetss_state == 0) { + *(rp++) = c; + } + break; + + case '?': + if (fgetss_state==1) { + br=0; + fgetss_state=2; + break; + } + /* fall-through */ + + default: + if (fgetss_state == 0) { + *(rp++) = c; + } + } + c = *(++p); + } + *rp = '\0'; + efree(buf); + RETVAL_STRING(rbuf,1); + efree(rbuf); } /* }}} */ -/* {{{ proto int fputs(int fp, string str [, int length]) - An alias for fwrite */ -/* }}} */ /* {{{ proto int fwrite(int fp, string str [, int length]) Binary-safe file write */ -void php3_fwrite(INTERNAL_FUNCTION_PARAMETERS) +PHP_FUNCTION(fwrite) { pval *arg1, *arg2, *arg3=NULL; FILE *fp; @@ -892,7 +1046,7 @@ void php3_fwrite(INTERNAL_FUNCTION_PARAMETERS) int issock=0; int *sock, socketd=0; PLS_FETCH(); - + switch (ARG_COUNT(ht)) { case 2: if (getParameters(ht, 2, &arg1, &arg2)==FAILURE) { @@ -942,66 +1096,14 @@ void php3_fwrite(INTERNAL_FUNCTION_PARAMETERS) } /* }}} */ -/* {{{ proto int set_file_buffer(int fp, int buffer) -Set file write buffer */ -/* - wrapper for setvbuf() -*/ -void php3_set_file_buffer(INTERNAL_FUNCTION_PARAMETERS) -{ - pval *arg1, *arg2; - FILE *fp; - int ret,id,type,buff; - int issock=0; - int *sock, socketd=0; - PLS_FETCH(); - - switch (ARG_COUNT(ht)) { - case 2: - if (getParameters(ht, 2, &arg1, &arg2)==FAILURE) { - RETURN_FALSE; - } - convert_to_long(arg1); - convert_to_long(arg2); - break; - default: - WRONG_PARAM_COUNT; - /* NOTREACHED */ - break; - } - - id = arg1->value.lval; - buff = arg2->value.lval; - fp = php3_list_find(id,&type); - if (type==wsa_fp){ - issock=1; - sock = php3_list_find(id,&type); - socketd=*sock; - } - if ((!fp || (type!=le_fp && type!=le_pp)) && (!socketd || type!=wsa_fp)) { - php3_error(E_WARNING,"Unable to find file identifier %d",id); - RETURN_FALSE; - } - - /* if buff is 0 then set to non-buffered */ - if(buff==0){ - ret=setvbuf(fp, NULL, _IONBF, 0); - } - else{ - ret=setvbuf(fp, NULL, _IOFBF, buff); - } - - RETURN_LONG(ret); -} -/* }}} */ /* {{{ proto int rewind(int fp) Rewind the position of a file pointer */ -void php3_rewind(INTERNAL_FUNCTION_PARAMETERS) { +PHP_FUNCTION(rewind) +{ pval *arg1; int id,type; FILE *fp; - PLS_FETCH(); if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg1) == FAILURE) { WRONG_PARAM_COUNT; @@ -1018,14 +1120,15 @@ void php3_rewind(INTERNAL_FUNCTION_PARAMETERS) { } /* }}} */ + /* {{{ proto int ftell(int fp) Get file pointer's read/write position */ -void php3_ftell(INTERNAL_FUNCTION_PARAMETERS) { +PHP_FUNCTION(ftell) +{ pval *arg1; int id, type; long pos; FILE *fp; - PLS_FETCH(); if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg1) == FAILURE) { WRONG_PARAM_COUNT; @@ -1042,14 +1145,15 @@ void php3_ftell(INTERNAL_FUNCTION_PARAMETERS) { } /* }}} */ + /* {{{ proto int fseek(int fp, int offset) Seek on a file pointer */ -void php3_fseek(INTERNAL_FUNCTION_PARAMETERS) { +PHP_FUNCTION(fseek) +{ pval *arg1, *arg2; int ret,id,type; long pos; FILE *fp; - PLS_FETCH(); if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &arg1, &arg2) == FAILURE) { WRONG_PARAM_COUNT; @@ -1078,9 +1182,11 @@ void php3_fseek(INTERNAL_FUNCTION_PARAMETERS) { } /* }}} */ + /* {{{ proto int mkdir(string pathname, int mode) Create a directory */ -void php3_mkdir(INTERNAL_FUNCTION_PARAMETERS) { +PHP_FUNCTION(mkdir) +{ pval *arg1, *arg2; int ret,mode; PLS_FETCH(); @@ -1103,9 +1209,11 @@ void php3_mkdir(INTERNAL_FUNCTION_PARAMETERS) { } /* }}} */ + /* {{{ proto int rmdir(string dirname) Remove a directory */ -void php3_rmdir(INTERNAL_FUNCTION_PARAMETERS) { +PHP_FUNCTION(rmdir) +{ pval *arg1; int ret; PLS_FETCH(); @@ -1126,17 +1234,17 @@ void php3_rmdir(INTERNAL_FUNCTION_PARAMETERS) { } /* }}} */ + /* {{{ proto int readfile(string filename [, int use_include_path]) Output a file or a URL */ -void php3_readfile(INTERNAL_FUNCTION_PARAMETERS) { +PHP_FUNCTION(readfile) +{ pval *arg1, *arg2; char buf[8192]; FILE *fp; int b, size; int use_include_path = 0; - int issock=0, socketd=0; - PLS_FETCH(); /* check args */ switch (ARG_COUNT(ht)) { @@ -1170,14 +1278,16 @@ void php3_readfile(INTERNAL_FUNCTION_PARAMETERS) { RETURN_FALSE; } size= 0; - if (php3_header()) { /* force header if not already sent */ - while(issock?(b=SOCK_FREAD(buf,sizeof(buf),socketd)):(b = fread(buf, 1, sizeof(buf), fp)) > 0) { - PHPWRITE(buf,b); - size += b ; - } + while(issock?(b=SOCK_FGETS(buf,sizeof(buf),socketd)):(b = fread(buf, 1, sizeof(buf), fp)) > 0) { + PHPWRITE(buf,b); + size += b ; } if (issock) { - SOCK_FCLOSE(socketd); +#if WIN32|WINNT + closesocket(socketd); +#else + close(socketd); +#endif } else { fclose(fp); } @@ -1185,13 +1295,14 @@ void php3_readfile(INTERNAL_FUNCTION_PARAMETERS) { } /* }}} */ + /* {{{ proto int umask([int mask]) Return or change the umask */ -void php3_fileumask(INTERNAL_FUNCTION_PARAMETERS) { +PHP_FUNCTION(fileumask) +{ pval *arg1; int oldumask; int arg_count = ARG_COUNT(ht); - PLS_FETCH(); oldumask = umask(077); @@ -1209,19 +1320,20 @@ void php3_fileumask(INTERNAL_FUNCTION_PARAMETERS) { } /* }}} */ + /* * Read to EOF on a file descriptor and write the output to stdout. */ /* {{{ proto int fpassthru(int fp) Output all remaining data from a file pointer */ -void php3_fpassthru(INTERNAL_FUNCTION_PARAMETERS) { +PHP_FUNCTION(fpassthru) +{ pval *arg1; FILE *fp; char buf[8192]; int id, size, b, type; int issock=0; int socketd=0, *sock; - PLS_FETCH(); if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg1) == FAILURE) { WRONG_PARAM_COUNT; @@ -1240,38 +1352,51 @@ void php3_fpassthru(INTERNAL_FUNCTION_PARAMETERS) { } size = 0; if (php3_header()) { /* force headers if not already sent */ - while(issock?(b=SOCK_FREAD(buf,sizeof(buf),socketd)):(b = fread(buf, 1, sizeof(buf), fp)) > 0) { + while(issock?(b=SOCK_FGETS(buf,sizeof(buf),socketd)):(b = fread(buf, 1, sizeof(buf), fp)) > 0) { PHPWRITE(buf,b); size += b ; } } +/* + if (issock) { +#if WIN32|WINNT + closesocket(socketd); +#else + close(socketd); +#endif + } else { + fclose(fp); + } +*/ php3_list_delete(id); RETURN_LONG(size); } /* }}} */ + /* {{{ proto int rename(string old_name, string new_name) Rename a file */ -void php3_rename(INTERNAL_FUNCTION_PARAMETERS) { - pval *OLD, *NEW; - char *old, *new; +PHP_FUNCTION(rename) +{ + pval *old_arg, *new_arg; + char *old_name, *new_name; int ret; PLS_FETCH(); - if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &OLD, &NEW) == FAILURE) { + if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &old_arg, &new_arg) == FAILURE) { WRONG_PARAM_COUNT; } - convert_to_string(OLD); - convert_to_string(NEW); + convert_to_string(old_arg); + convert_to_string(new_arg); - old = OLD->value.str.val; - new = NEW->value.str.val; + old_name = old_arg->value.str.val; + new_name = new_arg->value.str.val; - if (PG(safe_mode) &&(!_php3_checkuid(old,2))) { + if (PG(safe_mode) &&(!_php3_checkuid(old_name, 2))) { RETURN_FALSE; } - ret = rename(old, new); + ret = rename(old_name, new_name); if (ret == -1) { php3_error(E_WARNING, @@ -1283,9 +1408,10 @@ void php3_rename(INTERNAL_FUNCTION_PARAMETERS) { } /* }}} */ + /* {{{ proto int copy(string source_file, string destination_file) Copy a file */ -void php3_file_copy(INTERNAL_FUNCTION_PARAMETERS) +PHP_FUNCTION(file_copy) { pval *source, *target; char buffer[8192]; @@ -1337,9 +1463,10 @@ void php3_file_copy(INTERNAL_FUNCTION_PARAMETERS) } /* }}} */ + /* {{{ proto int fread(int fp, int length) Binary-safe file read */ -void php3_fread(INTERNAL_FUNCTION_PARAMETERS) +PHP_FUNCTION(fread) { pval *arg1, *arg2; FILE *fp; @@ -1373,7 +1500,7 @@ void php3_fread(INTERNAL_FUNCTION_PARAMETERS) return_value->value.str.len = fread(return_value->value.str.val, 1, len, fp); return_value->value.str.val[return_value->value.str.len] = 0; } else { - return_value->value.str.len = SOCK_FREAD(return_value->value.str.val, len, socketd); + return_value->value.str.len = _php3_sock_fread(return_value->value.str.val, len, socketd); } if (PG(magic_quotes_runtime)) { return_value->value.str.val = _php3_addslashes(return_value->value.str.val,return_value->value.str.len,&return_value->value.str.len,1); @@ -1382,105 +1509,30 @@ void php3_fread(INTERNAL_FUNCTION_PARAMETERS) } /* }}} */ -/* aparently needed for pdf to be compiled as a module under windows */ -PHPAPI int php3i_get_le_fp(void){ - PLS_FETCH(); - return le_fp; -} - -static int flock_values[] = { LOCK_SH, LOCK_EX, LOCK_UN }; -/* {{{ proto bool flock(int fp, int operation) - portable file locking */ -PHP_FUNCTION(flock) +/* aparently needed for pdf to be compiled as a module under windows */ +PHPAPI int php3i_get_le_fp(void) { - pval *arg1, *arg2; - FILE *fp; - int type; - int issock=0; - int *sock, fd=0; - int act = 0; - PLS_FETCH(); - - if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &arg1, &arg2) == FAILURE) { - WRONG_PARAM_COUNT; - } - - convert_to_long(arg1); - convert_to_long(arg2); - - fp = php3_list_find(arg1->value.lval, &type); - if (type == wsa_fp){ - issock = 1; - sock = php3_list_find(arg1->value.lval, &type); - fd = *sock; - } - - if ((!fp || (type!=le_fp && type!=le_pp)) && (!fd || type!=wsa_fp)) { - php3_error(E_WARNING,"Unable to find file identifier %d",arg1->value.lval); - RETURN_FALSE; - } - - if (!issock) { - fd = fileno(fp); - } - - act = arg2->value.lval & 3; - if(act < 1 || act > 3) { - php3_error(E_WARNING, "illegal value for second argument"); - RETURN_FALSE; - } - /* flock_values contains all possible actions - if (arg2 & 4) we won't block on the lock */ - act = flock_values[act - 1] | (arg2->value.lval & 4 ? LOCK_NB : 0); - if (flock(fd, act) == -1) { - RETURN_FALSE; - } - - RETURN_TRUE; + return le_fp; } -/* }}} */ - /* {{{ proto array fgetcsv(int fp, int length) get line from file pointer and parse for CSV fields */ -void php3_fgetcsv(INTERNAL_FUNCTION_PARAMETERS) { +PHP_FUNCTION(fgetcsv) { char *temp, *tptr, *bptr; - char delimiter = ','; /* allow this to be set as parameter */ + char delimiter = ','; /* allow this to be set as parameter if required in future version? */ /* first section exactly as php3_fgetss */ - pval *fd, *bytes, *p_delim; + pval *fd, *bytes; FILE *fp; int id, len, type; char *buf; int issock=0; int *sock,socketd=0; - PLS_FETCH(); - switch(ARG_COUNT(ht)) { - case 2: - if (getParameters(ht, 2, &fd, &bytes) == FAILURE) { - WRONG_PARAM_COUNT; - } - break; - - case 3: - if (getParameters(ht, 3, &fd, &bytes, &p_delim) == FAILURE) { - WRONG_PARAM_COUNT; - } - convert_to_string(p_delim); - /* Make sure that there is at least one character in string */ - if (p_delim->value.str.len < 1) { - WRONG_PARAM_COUNT; - } - /* use first character from string */ - delimiter = p_delim->value.str.val[0]; - break; - - default: - WRONG_PARAM_COUNT; - break; + if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &fd, &bytes) == FAILURE) { + WRONG_PARAM_COUNT; } convert_to_long(fd); @@ -1503,7 +1555,7 @@ void php3_fgetcsv(INTERNAL_FUNCTION_PARAMETERS) { buf = emalloc(sizeof(char) * (len + 1)); /*needed because recv doesnt set null char at end*/ memset(buf,0,len+1); - if ((issock?SOCK_FGETS(buf,len,socketd):fgets(buf, len, fp)) == NULL) { + if (!(issock?SOCK_FGETS(buf,len,socketd):fgets(buf, len, fp) != NULL)) { efree(buf); RETURN_FALSE; } @@ -1537,7 +1589,7 @@ void php3_fgetcsv(INTERNAL_FUNCTION_PARAMETERS) { do { /* 1. Strip any leading space */ - while(isspace(*bptr)) bptr++; + while isspace(*bptr) bptr++; /* 2. Read field, leaving bptr pointing at start of next field */ if (*bptr == '"') { /* 2A. handle quote delimited field */ diff --git a/ext/standard/file.h b/ext/standard/file.h index fb873adf3b..2cad2035f7 100644 --- a/ext/standard/file.h +++ b/ext/standard/file.h @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP HTML Embedded Scripting Language Version 3.0 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-1999 PHP Development Team (See Credits file) | + | 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: | @@ -32,38 +32,37 @@ #ifndef _FILE_H #define _FILE_H -#ifndef INIT_FUNC_ARGS -#include "modules.h" -#endif +extern php3_module_entry php3_file_module_entry; +#define php3_file_module_ptr &php3_file_module_entry extern int php3_minit_file(INIT_FUNC_ARGS); -extern void php3_tempnam(INTERNAL_FUNCTION_PARAMETERS); -extern void php3_fopen(INTERNAL_FUNCTION_PARAMETERS); -extern void php3_fclose(INTERNAL_FUNCTION_PARAMETERS); -extern void php3_popen(INTERNAL_FUNCTION_PARAMETERS); -extern void php3_pclose(INTERNAL_FUNCTION_PARAMETERS); -extern void php3_feof(INTERNAL_FUNCTION_PARAMETERS); -extern void php3_fread(INTERNAL_FUNCTION_PARAMETERS); -extern void php3_fgetc(INTERNAL_FUNCTION_PARAMETERS); -extern void php3_fgets(INTERNAL_FUNCTION_PARAMETERS); -extern void php3_fgetss(INTERNAL_FUNCTION_PARAMETERS); -extern void php3_fgetcsv(INTERNAL_FUNCTION_PARAMETERS); -extern void php3_fwrite(INTERNAL_FUNCTION_PARAMETERS); -extern void php3_set_file_buffer(INTERNAL_FUNCTION_PARAMETERS); -extern void php3_rewind(INTERNAL_FUNCTION_PARAMETERS); -extern void php3_ftell(INTERNAL_FUNCTION_PARAMETERS); -extern void php3_fseek(INTERNAL_FUNCTION_PARAMETERS); -extern void php3_mkdir(INTERNAL_FUNCTION_PARAMETERS); -extern void php3_rmdir(INTERNAL_FUNCTION_PARAMETERS); -extern void php3_fpassthru(INTERNAL_FUNCTION_PARAMETERS); -extern void php3_readfile(INTERNAL_FUNCTION_PARAMETERS); -extern void php3_fileumask(INTERNAL_FUNCTION_PARAMETERS); -extern void php3_rename(INTERNAL_FUNCTION_PARAMETERS); -extern void php3_file_copy(INTERNAL_FUNCTION_PARAMETERS); -extern void php3_file(INTERNAL_FUNCTION_PARAMETERS); -extern void php3_set_socket_blocking(INTERNAL_FUNCTION_PARAMETERS); -extern void php3_set_socket_timeout(INTERNAL_FUNCTION_PARAMETERS); -extern void php3_get_meta_tags(INTERNAL_FUNCTION_PARAMETERS); -extern PHP_FUNCTION(flock); +PHP_FUNCTION(tempnam); +PHP_FUNCTION(fopen); +PHP_FUNCTION(fclose); +PHP_FUNCTION(popen); +PHP_FUNCTION(pclose); +PHP_FUNCTION(feof); +PHP_FUNCTION(fread); +PHP_FUNCTION(fgetc); +PHP_FUNCTION(fgets); +PHP_FUNCTION(fgetss); +PHP_FUNCTION(fgetcsv); +PHP_FUNCTION(fwrite); +PHP_FUNCTION(rewind); +PHP_FUNCTION(ftell); +PHP_FUNCTION(fseek); +PHP_FUNCTION(mkdir); +PHP_FUNCTION(rmdir); +PHP_FUNCTION(fpassthru); +PHP_FUNCTION(readfile); +PHP_FUNCTION(fileumask); +PHP_FUNCTION(rename); +PHP_FUNCTION(file_copy); +PHP_FUNCTION(file); +PHP_FUNCTION(set_socket_blocking); +PHP_FUNCTION(set_socket_timeout); +PHP_FUNCTION(get_meta_tags); +PHP_FUNCTION(flock); +#define phpext_file_ptr php3_file_module_ptr #endif /* _FILE_H */ diff --git a/ext/standard/fsock.c b/ext/standard/fsock.c index c1115f9a9a..29bb65ff66 100644 --- a/ext/standard/fsock.c +++ b/ext/standard/fsock.c @@ -28,22 +28,13 @@ +----------------------------------------------------------------------+ */ /* $Id$ */ + #include "php.h" -#include "php_globals.h" #include -#include #if HAVE_UNISTD_H #include #endif -#if HAVE_FCNTL_H -#include -#endif - -#if HAVE_SYS_TIME_H -#include -#endif - #include #if HAVE_SYS_SOCKET_H #include @@ -93,15 +84,11 @@ function_entry fsock_functions[] = { struct php3i_sockbuf { int socket; - unsigned char *readbuf; + char *readbuf; size_t readbuflen; size_t readpos; size_t writepos; struct php3i_sockbuf *next; - struct php3i_sockbuf *prev; - char eof; - char persistent; - char is_blocked; }; static struct php3i_sockbuf *phpsockbuf; @@ -154,102 +141,27 @@ int _php3_is_persistent_sock(int sock) return 0; } /* }}} */ - - -/* {{{ connect_nonb */ -PHPAPI int connect_nonb(int sockfd, struct sockaddr *addr, int addrlen, struct timeval *timeout) - -/* probably won't work on Win32, someone else might try it (read: fix it ;) */ -#if !defined(WIN32) && (defined(O_NONBLOCK) || defined(O_NDELAY)) - -#ifndef O_NONBLOCK -#define O_NONBLOCK O_NDELAY -#endif - -{ - int flags; - int n; - int error = 0; - int len; - int ret = 0; - fd_set rset; - fd_set wset; - - flags = fcntl(sockfd, F_GETFL, 0); - fcntl(sockfd, F_SETFL, flags | O_NONBLOCK); - - if((n = connect(sockfd, addr, addrlen)) < 0) - if(errno != EINPROGRESS) - return -1; - - if(n == 0) - goto ok; - - FD_ZERO(&rset); - FD_SET(sockfd, &rset); - - wset = rset; - - if((n = select(sockfd + 1, &rset, &wset, NULL, timeout)) == 0) { - error = ETIMEDOUT; - } - - if(FD_ISSET(sockfd, &rset) || FD_ISSET(sockfd, &wset)) { - len = sizeof(error); - /* - BSD-derived systems set errno correctly - Solaris returns -1 from getsockopt in case of error - */ - if(getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) - ret = -1; - } else { - /* whoops: sockfd has disappeared */ - ret = -1; - } - -ok: - fcntl(sockfd, F_SETFL, flags); - - if(error) { - errno = error; - ret = -1; - } - return ret; -} -#else -//#warning "compiling without nonblocking connect support" -{ - return connect(sockfd, addr, addrlen); -} -#endif -/* }}} */ - - /* {{{ _php3_fsockopen() */ + /* This function takes an optional third argument which should be passed by reference. The error code from the connect call is written to this variable. */ static void _php3_fsockopen(INTERNAL_FUNCTION_PARAMETERS, int persistent) { - pval *args[5]; + pval *args[4]; int *sock=emalloc(sizeof(int)); int *sockp; int id, arg_count=ARG_COUNT(ht); int socketd = -1; - struct timeval timeout = { 60, 0 }; unsigned short portno; char *key = NULL; - PLS_FETCH(); - if (arg_count > 5 || arg_count < 2 || getParametersArray(ht,arg_count,args)==FAILURE) { + if (arg_count > 4 || arg_count < 2 || getParametersArray(ht,arg_count,args)==FAILURE) { FREE_SOCK; WRONG_PARAM_COUNT; } switch(arg_count) { - case 5: - convert_to_long(args[4]); - timeout.tv_sec = args[4]->value.lval; case 4: if(!ParameterPassedByReference(ht,4)) { php3_error(E_WARNING,"error string argument to fsockopen not passed by reference"); @@ -276,7 +188,7 @@ static void _php3_fsockopen(INTERNAL_FUNCTION_PARAMETERS, int persistent) { if (persistent && _php3_hash_find(&ht_keys, key, strlen(key) + 1, (void *) &sockp) == SUCCESS) { - FREE_SOCK; + efree(key); *sock = *sockp; RETURN_LONG(php3_list_insert(sock, wsa_fp)); } @@ -300,7 +212,7 @@ static void _php3_fsockopen(INTERNAL_FUNCTION_PARAMETERS, int persistent) { server.sin_port = htons(portno); - if (connect_nonb(socketd, (struct sockaddr *)&server, sizeof(server), &timeout) == SOCK_CONN_ERR) { + if (connect(socketd, (struct sockaddr *)&server, sizeof(server)) == SOCK_CONN_ERR) { FREE_SOCK; if(arg_count>2) args[2]->value.lval = errno; if(arg_count>3) { @@ -323,7 +235,7 @@ static void _php3_fsockopen(INTERNAL_FUNCTION_PARAMETERS, int persistent) { unix_addr.sun_family = AF_UNIX; strcpy(unix_addr.sun_path, args[0]->value.str.val); - if (connect_nonb(socketd, (struct sockaddr *) &unix_addr, sizeof(unix_addr), &timeout) == SOCK_CONN_ERR) { + if (connect(socketd, (struct sockaddr *) &unix_addr, sizeof(unix_addr)) == SOCK_CONN_ERR) { FREE_SOCK; if(arg_count>2) args[2]->value.lval = errno; if(arg_count>3) { @@ -355,19 +267,19 @@ static void _php3_fsockopen(INTERNAL_FUNCTION_PARAMETERS, int persistent) { key, strlen(key) + 1, NULL); } if(key) efree(key); - id = php3_list_insert(sock, wsa_fp); + id = php3_list_insert(sock,wsa_fp); RETURN_LONG(id); } /* }}} */ -/* {{{ proto int fsockopen(string hostname, int port [, int errno [, string errstr [, int timeout]]]) +/* {{{ proto int fsockopen(string hostname, int port [, int errno [, string errstr]]) Open Internet or Unix domain socket connection */ PHP_FUNCTION(fsockopen) { _php3_fsockopen(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0); } /* }}} */ -/* {{{ proto int pfsockopen(string hostname, int port [, int errno [, string errstr [, int timeout]]]) +/* {{{ proto int pfsockopen(string hostname, int port [, int errno [, string errstr]]) Open persistent Internet or Unix domain socket connection */ PHP_FUNCTION(pfsockopen) { @@ -375,37 +287,16 @@ PHP_FUNCTION(pfsockopen) } /* }}} */ -#define SOCK_DESTROY(sock) \ - if(sock->readbuf) pefree(sock->readbuf, sock->persistent); \ - if(sock->prev) sock->prev->next = sock->next; \ - if(sock->next) sock->next->prev = sock->prev; \ - if(sock == phpsockbuf) \ - phpsockbuf = sock->next; \ - pefree(sock, sock->persistent) +/* Known issues with the socket buffering code: + * - does not work reliably with persistent sockets yet + * (buffered data is not persistent) + * - php3_fopen_url_wrapper() is still doing single-byte lookahead/read + */ -static void php_cleanup_sockbuf(int persistent) +static php3i_sockbuf *_php3_sock_findsock(int socket) { - php3i_sockbuf *now, *next; - - for(now = phpsockbuf; now; now = next) { - next = now->next; - if(now->persistent == persistent) { - SOCK_DESTROY(now); - } - } -} - -#define TOREAD(sock) ((sock)->writepos - (sock)->readpos) -#define READPTR(sock) ((sock)->readbuf + (sock)->readpos) -#define WRITEPTR(sock) ((sock)->readbuf + (sock)->writepos) + /* FIXME: O(n) could be improved */ -#define SOCK_FIND(sock,socket) \ - php3i_sockbuf *sock; \ - sock = _php3_sock_find(socket); \ - if(!sock) sock = _php3_sock_create(socket) - -static php3i_sockbuf *_php3_sock_find(int socket) -{ php3i_sockbuf *buf = NULL, *tmp; for(tmp = phpsockbuf; tmp; tmp = tmp->next) @@ -415,223 +306,146 @@ static php3i_sockbuf *_php3_sock_find(int socket) } return buf; -} - -static php3i_sockbuf *_php3_sock_create(int socket) -{ - php3i_sockbuf *sock; - int persistent = _php3_is_persistent_sock(socket); - - sock = pecalloc(sizeof(*sock), 1, persistent); - sock->socket = socket; - if((sock->next = phpsockbuf)) - phpsockbuf->prev = sock; - sock->persistent = persistent; - sock->is_blocked = 1; - phpsockbuf = sock; - - return sock; } -int _php3_sock_destroy(int socket) +int _php3_sock_eof(int socket) { + php3i_sockbuf *sockbuf; int ret = 0; - php3i_sockbuf *sock; - sock = _php3_sock_find(socket); - if(sock) { - ret = 1; - SOCK_DESTROY(sock); + sockbuf = _php3_sock_findsock(socket); + if(sockbuf) { + ret = (sockbuf->writepos - sockbuf->readpos) == 0 ? 1 : 0; } - - return ret; -} - -int _php3_sock_close(int socket) -{ - int ret = 0; - php3i_sockbuf *sock; - - sock = _php3_sock_find(socket); - if(sock) { - if(!sock->persistent) { -#if HAVE_SHUTDOWN - shutdown(sock->socket, 0); -#endif -#if WIN32||WINNT - closesocket(sock->socket); -#else - close(sock->socket); -#endif - SOCK_DESTROY(sock); - } - } - return ret; } -#define CHUNK_SIZE 2048 -#define MAX_CHUNKS_PER_READ 10 - - -static size_t _php3_sock_read_limited(php3i_sockbuf *sock, size_t max) +/* {{{ _php3_sock_fgets() */ +int _php3_sock_fgets(char *buf, int maxlen, int socket) { - char buf[CHUNK_SIZE]; - int nr_bytes; - size_t nr_read = 0; + struct php3i_sockbuf *sockbuf; + int bytesread, toread, len, buflen, count = 0; + char *nl; - if(sock->eof || max > CHUNK_SIZE) return nr_read; + sockbuf = _php3_sock_findsock(socket); - nr_bytes = recv(sock->socket, buf, max, 0); - if(nr_bytes > 0) { - if(sock->writepos + nr_bytes > sock->readbuflen) { - sock->readbuflen += CHUNK_SIZE; - sock->readbuf = perealloc(sock->readbuf, sock->readbuflen, - sock->persistent); + if (sockbuf) { + toread = sockbuf->writepos - sockbuf->readpos; + if (toread > maxlen) { + toread = maxlen; + } + if ((nl = memchr(sockbuf->readbuf + sockbuf->readpos, '\n', toread)) != NULL) { + toread = (nl - (sockbuf->readbuf + sockbuf->readpos)) + 1; + } + memcpy(buf, sockbuf->readbuf + sockbuf->readpos, toread); + sockbuf->readpos += toread; + count += toread; + buf += toread; + if (sockbuf->readpos >= sockbuf->writepos) { + sockbuf->readpos = sockbuf->writepos = 0; + } + if (nl != NULL) { + /* if a newline was found, skip the recv() loop */ + goto sock_fgets_exit; } - memcpy(WRITEPTR(sock), buf, nr_bytes); - sock->writepos += nr_bytes; - nr_read = nr_bytes; - } else if(nr_bytes == 0 || (nr_bytes < 0 && errno != EWOULDBLOCK)) { - sock->eof = 1; - } - - return nr_read; -} - -static size_t _php3_sock_read(php3i_sockbuf *sock) -{ - size_t nr_bytes; - size_t nr_read = 0; - int i; - - for(i = 0; !sock->eof && i < MAX_CHUNKS_PER_READ; i++) { - nr_bytes = _php3_sock_read_limited(sock, CHUNK_SIZE); - if(nr_bytes == 0) break; - nr_read += nr_bytes; } - return nr_read; -} - -int _php3_sock_set_blocking(int socket, int mode) -{ - int old; - SOCK_FIND(sock, socket); - - old = sock->is_blocked; - - sock->is_blocked = mode; - - return old; -} - -#define SOCK_FIND_AND_READ \ - SOCK_FIND(sock,socket); \ - _php3_sock_read(sock) - -#define SOCK_FIND_AND_READ_MAX(max) \ - SOCK_FIND(sock, socket); \ - if(sock->is_blocked) _php3_sock_read_limited(sock, max); else _php3_sock_read(sock) - -/* - * FIXME: fgets depends on '\n' as line delimiters - */ - -char *_php3_sock_fgets(char *buf, size_t maxlen, int socket) -{ - char *p = NULL; - char *ret = NULL; - size_t amount = 0; - size_t nr_read; - SOCK_FIND_AND_READ_MAX(1); - - if(maxlen < 0) return ret; - - if(sock->is_blocked) { - for(nr_read = 1; !sock->eof && nr_read < maxlen; ) { - nr_read += _php3_sock_read_limited(sock, 1); - if((p = memchr(READPTR(sock), '\n', TOREAD(sock))) != NULL) break; + nl = NULL; + buflen = 0; + while (count < maxlen && nl == NULL) { + toread = maxlen - count; + bytesread = recv(socket, buf, toread, 0); + if (bytesread <= 0) { + break; + } + if ((nl = memchr(buf, '\n', bytesread)) != NULL) { + len = (nl - buf) + 1; + count += len; + buf += len; + if (len < bytesread) { + buflen = bytesread - len; + break; + } + } else { + count += bytesread; + buf += bytesread; } - } else { - p = memchr(READPTR(sock), '\n', MIN(TOREAD(sock), maxlen - 1)); - } - - if(p) { - amount = (ptrdiff_t) p - (ptrdiff_t) READPTR(sock) + 1; - } else { - amount = MIN(TOREAD(sock), maxlen - 1); } - if(amount > 0) { - memcpy(buf, READPTR(sock), amount); - sock->readpos += amount; + if (buflen > 0) { /* there was data after the "\n" ... */ + if (sockbuf == NULL) { + sockbuf = emalloc(sizeof(struct php3i_sockbuf)); + sockbuf->socket = socket; + sockbuf->readbuf = emalloc(maxlen); + sockbuf->readbuflen = maxlen; + sockbuf->readpos = sockbuf->writepos = 0; + sockbuf->next = phpsockbuf; + phpsockbuf = sockbuf; + } else { + uint needlen = sockbuf->writepos + buflen; + + if (needlen > sockbuf->readbuflen) { + sockbuf->readbuflen += maxlen; + sockbuf->readbuf = erealloc(sockbuf->readbuf, sockbuf->readbuflen); + } + } + memcpy(sockbuf->readbuf + sockbuf->writepos, buf, buflen); + sockbuf->writepos += buflen; } - buf[amount] = '\0'; - - /* signal error only, if we don't return data from this call and - if there is no data to read and if the eof flag is set */ - if(amount || TOREAD(sock) || !sock->eof) - ret = buf; - return ret; + sock_fgets_exit: + *buf = '\0'; + return count; } -/* - * FIXME: fgetc returns EOF, if no data is available on a nonblocking socket. - * I don't have any documentation on the semantics of fgetc in this case. - * - * ss@2ns.de 19990528 - */ +/* }}} */ +/* {{{ _php3_sock_fread() */ -int _php3_sock_fgetc(int socket) +int _php3_sock_fread(char *buf, int maxlen, int socket) { - int ret = EOF; - SOCK_FIND_AND_READ_MAX(1); - - if(TOREAD(sock) > 0) { - ret = *READPTR(sock); - sock->readpos++; + struct php3i_sockbuf *sockbuf = phpsockbuf; + int bytesread, toread, count = 0; + + while (sockbuf) { + if (sockbuf->socket == socket) { + toread = sockbuf->writepos - sockbuf->readpos; + if (toread > maxlen) { + toread = maxlen; + } + memcpy(buf, sockbuf->readbuf + sockbuf->readpos, toread); + sockbuf->readpos += toread; + count += toread; + buf += toread; + break; + } + sockbuf = sockbuf->next; } - return ret; -} - -int _php3_sock_feof(int socket) -{ - int ret = 0; - SOCK_FIND_AND_READ_MAX(1); - - if(!TOREAD(sock) && sock->eof) - ret = 1; - - return ret; -} - -size_t _php3_sock_fread(char *ptr, size_t size, int socket) -{ - size_t ret = 0; - SOCK_FIND_AND_READ_MAX(size); - - if(size < 0) return ret; - - ret = MIN(TOREAD(sock), size); - if(ret) { - memcpy(ptr, READPTR(sock), ret); - sock->readpos += ret; + while (count < maxlen) { + toread = maxlen - count; + bytesread = recv(socket, buf, toread, 0); + if (bytesread <= 0) { + break; + } + count += bytesread; + buf += bytesread; } - return ret; + *buf = '\0'; + return count; } - +/* }}} */ /* {{{ module start/shutdown functions */ /* {{{ _php3_sock_destroy */ -static void _php3_msock_destroy(int *data) +#ifndef THREAD_SAFE +static void _php3_sock_destroy(void *data) { - close(*data); + int *sock = (int *) data; + close(*sock); } +#endif /* }}} */ /* {{{ php3_minit_fsock */ @@ -639,7 +453,7 @@ static int php3_minit_fsock(INIT_FUNC_ARGS) { #ifndef THREAD_SAFE _php3_hash_init(&ht_keys, 0, NULL, NULL, 1); - _php3_hash_init(&ht_socks, 0, NULL, (void (*)(void *))_php3_msock_destroy, 1); + _php3_hash_init(&ht_socks, 0, NULL, _php3_sock_destroy, 1); #endif return SUCCESS; } @@ -652,7 +466,6 @@ static int php3_mshutdown_fsock(SHUTDOWN_FUNC_ARGS) _php3_hash_destroy(&ht_socks); _php3_hash_destroy(&ht_keys); #endif - php_cleanup_sockbuf(1); return SUCCESS; } /* }}} */ @@ -660,7 +473,15 @@ static int php3_mshutdown_fsock(SHUTDOWN_FUNC_ARGS) static int php3_rshutdown_fsock(SHUTDOWN_FUNC_ARGS) { - php_cleanup_sockbuf(0); + struct php3i_sockbuf *sockbuf = phpsockbuf, *this; + + while (sockbuf) { + this = sockbuf; + sockbuf = this->next; + efree(this->readbuf); + efree(this); + } + phpsockbuf = NULL; return SUCCESS; } diff --git a/ext/standard/fsock.h b/ext/standard/fsock.h index 1b2c7e851c..a4a01b1bf9 100644 --- a/ext/standard/fsock.h +++ b/ext/standard/fsock.h @@ -32,21 +32,29 @@ #ifndef _FSOCK_H #define _FSOCK_H +#if WIN32|WINNT +# ifndef WINNT +# define WINNT 1 +# endif +#undef FD_SETSIZE +#include "arpa/inet.h" +#endif + +#if HAVE_NETINET_IN_H +#include +#endif + extern php3_module_entry fsock_module_entry; #define fsock_module_ptr &fsock_module_entry PHP_FUNCTION(fsockopen); PHP_FUNCTION(pfsockopen); -int lookup_hostname(const char *addr, struct in_addr *in); -char *_php3_sock_fgets(char *buf, size_t maxlen, int socket); -size_t _php3_sock_fread(char *buf, size_t maxlen, int socket); -int _php3_sock_feof(int socket); -int _php3_sock_fgetc(int socket); -int _php3_is_persistent_sock(int); -int _php3_sock_set_blocking(int socket, int mode); -int _php3_sock_destroy(int socket); -int _php3_sock_close(int socket); +extern int lookup_hostname(const char *addr, struct in_addr *in); +extern int _php3_sock_fgets(char *buf, int maxlen, int socket); +extern int _php3_sock_fread(char *buf, int maxlen, int socket); +extern int _php3_is_persistent_sock(int); +int _php3_sock_eof(int socket); -PHPAPI int connect_nonb(int sockfd, struct sockaddr *addr, int addrlen, struct timeval *timeout); +#define phpext_fsock_ptr fsock_module_ptr #endif /* _FSOCK_H */ diff --git a/ext/standard/php3_string.h b/ext/standard/php3_string.h index 0de055e0bc..221c8e72d7 100644 --- a/ext/standard/php3_string.h +++ b/ext/standard/php3_string.h @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP HTML Embedded Scripting Language Version 3.0 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-1999 PHP Development Team (See Credits file) | + | 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: | @@ -24,7 +24,7 @@ | contact core@php.net. | +----------------------------------------------------------------------+ | Authors: Rasmus Lerdorf | - | Stig Sæther Bakken | + | Stig Sæther Bakken | +----------------------------------------------------------------------+ */ @@ -47,8 +47,7 @@ PHP_FUNCTION(str_replace); PHP_FUNCTION(chop); PHP_FUNCTION(trim); PHP_FUNCTION(ltrim); -PHP_FUNCTION(similar_text); -extern void soundex(INTERNAL_FUNCTION_PARAMETERS); +void soundex(INTERNAL_FUNCTION_PARAMETERS); PHP_FUNCTION(explode); PHP_FUNCTION(implode); @@ -79,30 +78,15 @@ PHP_FUNCTION(newline_to_br); PHP_FUNCTION(setlocale); PHP_FUNCTION(stristr); PHP_FUNCTION(chunk_split); -PHP_FUNCTION(strip_tags); PHP_FUNCTION(parsestr); PHP_FUNCTION(bin2hex); -#if HAVE_CRYPT -extern php3_module_entry crypt_module_entry; -#define crypt_module_ptr &crypt_module_entry -PHP_FUNCTION(crypt); -extern int php3_minit_crypt(INIT_FUNC_ARGS); -#else -#define crypt_module_ptr NULL -#endif - extern PHPAPI char *_php3_strtoupper(char *s); extern PHPAPI char *_php3_strtolower(char *s); -extern PHPAPI char *_php3_strtr(char *string, int len, char *str_from, char *str_to, int trlen); +extern char *_StrTr(char *string, char *str_from, char *str_to); extern PHPAPI char *_php3_addslashes(char *string, int length, int *new_length, int freeit); extern PHPAPI void _php3_stripslashes(char *string, int *len); extern PHPAPI void _php3_dirname(char *str, int len); extern PHPAPI char *php3i_stristr(unsigned char *s, unsigned char *t); -extern PHPAPI void _php3_trim(pval *str, pval * return_value); -extern PHPAPI void _php3_strip_tags(char *rbuf, int state); -extern PHPAPI void _php3_char_to_str(char *str,uint len,char from,char *to,int to_len,pval *result); -extern PHPAPI void _php3_implode(pval *delim, pval *arr, pval *return_value); -extern PHPAPI void _php3_explode(pval *delim, pval *str, pval *return_value); #endif /* _PHPSTRING_H */ diff --git a/ext/standard/string.c b/ext/standard/string.c index 9f29036eb7..bfc66735a9 100644 --- a/ext/standard/string.c +++ b/ext/standard/string.c @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP HTML Embedded Scripting Language Version 3.0 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-1999 PHP Development Team (See Credits file) | + | 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: | @@ -24,20 +24,24 @@ | contact core@php.net. | +----------------------------------------------------------------------+ | Authors: Rasmus Lerdorf | - | Stig Sæther Bakken | + | Stig Sæther Bakken | | Zeev Suraski | +----------------------------------------------------------------------+ */ + /* $Id$ */ #include #include "php.h" -#include "php_globals.h" -#include "php3_standard.h" +#include "reg.h" +#include "post.h" +#include "php3_string.h" #if HAVE_SETLOCALE #include #endif +#include "zend_execute.h" +#include "php_globals.h" static char hexconvtab[] = "0123456789abcdef"; @@ -84,13 +88,11 @@ PHP_FUNCTION(bin2hex) RETURN_STRINGL(new, newlen, 0); } - /* {{{ proto int strlen(string str) Get string length */ -void php3_strlen(INTERNAL_FUNCTION_PARAMETERS) +PHP_FUNCTION(strlen) { pval *str; - PLS_FETCH(); if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &str) == FAILURE) { WRONG_PARAM_COUNT; @@ -102,7 +104,7 @@ void php3_strlen(INTERNAL_FUNCTION_PARAMETERS) /* {{{ proto int strcmp(string str1, string str2) Binary safe string comparison */ -void php3_strcmp(INTERNAL_FUNCTION_PARAMETERS) +PHP_FUNCTION(strcmp) { pval *s1,*s2; @@ -117,7 +119,7 @@ void php3_strcmp(INTERNAL_FUNCTION_PARAMETERS) /* {{{ proto int strcasecmp(string str1, string str2) Binary safe case-insensitive string comparison */ -void php3_strcasecmp(INTERNAL_FUNCTION_PARAMETERS) +PHP_FUNCTION(strcasecmp) { pval *s1,*s2; @@ -126,13 +128,13 @@ void php3_strcasecmp(INTERNAL_FUNCTION_PARAMETERS) } convert_to_string(s1); convert_to_string(s2); - RETURN_LONG(zend_binary_strcasecmp(s1,s2)); + RETURN_LONG(strcasecmp(s1->value.str.val,s2->value.str.val)); } /* }}} */ /* {{{ proto int strspn(string str, string mask) Find length of initial segment consisting entirely of characters found in mask */ -void php3_strspn(INTERNAL_FUNCTION_PARAMETERS) +PHP_FUNCTION(strspn) { pval *s1,*s2; @@ -147,7 +149,7 @@ void php3_strspn(INTERNAL_FUNCTION_PARAMETERS) /* {{{ proto int strcspn(string str, string mask) Find length of initial segment consisting entirely of characters not found in mask */ -void php3_strcspn(INTERNAL_FUNCTION_PARAMETERS) +PHP_FUNCTION(strcspn) { pval *s1,*s2; @@ -160,17 +162,12 @@ void php3_strcspn(INTERNAL_FUNCTION_PARAMETERS) } /* }}} */ -/* {{{ proto string rtrim(string str) - An alias for chop */ -/* }}} */ - /* {{{ proto string chop(string str) Remove trailing whitespace */ -void php3_chop(INTERNAL_FUNCTION_PARAMETERS) +PHP_FUNCTION(chop) { pval *str; register int i; - PLS_FETCH(); if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &str) == FAILURE) { WRONG_PARAM_COUNT; @@ -195,41 +192,12 @@ void php3_chop(INTERNAL_FUNCTION_PARAMETERS) } /* }}} */ -PHPAPI void _php3_trim(pval *str, pval * return_value) -{ - register int i; - - int len = str->value.str.len; - int trimmed = 0; - char *c = str->value.str.val; - for (i = 0; i < len; i++) { - if (c[i] == ' ' || c[i] == '\n' || c[i] == '\r' || - c[i] == '\t' || c[i] == '\v') { - trimmed++; - } else { - break; - } - } - len-=trimmed; - c+=trimmed; - for (i = len - 1; i >= 0; i--) { - if (c[i] == ' ' || c[i] == '\n' || c[i] == '\r' || - c[i] == '\t' || c[i] == '\v') { - len--; - } else { - break; - } - } - RETVAL_STRINGL(c, len, 1); -} - /* {{{ proto string trim(string str) Strip whitespace from the beginning and end of a string */ -void php3_trim(INTERNAL_FUNCTION_PARAMETERS) +PHP_FUNCTION(trim) { pval *str; register int i; - PLS_FETCH(); if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &str) == FAILURE) { WRONG_PARAM_COUNT; @@ -267,28 +235,57 @@ void php3_trim(INTERNAL_FUNCTION_PARAMETERS) /* {{{ proto string ltrim(string str) Strip whitespace from the beginning of a string */ -void php3_ltrim(INTERNAL_FUNCTION_PARAMETERS) +PHP_FUNCTION(ltrim) { pval *str; - PLS_FETCH(); + register int i; if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &str) == FAILURE) { WRONG_PARAM_COUNT; } convert_to_string(str); + if (str->type == IS_STRING) { - _php3_trim(str, return_value); + int len = str->value.str.len; + int trimmed = 0; + char *c = str->value.str.val; + for (i = 0; i < len; i++) { + if (c[i] == ' ' || c[i] == '\n' || c[i] == '\r' || + c[i] == '\t' || c[i] == '\v') { + trimmed++; + } else { + break; + } + } + RETVAL_STRINGL(c+trimmed, len-trimmed, 1); return; } RETURN_FALSE; } /* }}} */ -void _php3_explode(pval *delim, pval *str, pval *return_value) +/* {{{ proto array(string separator, string str) + Split a string on string separator and return array of components */ +PHP_FUNCTION(explode) { + pval *str, *delim; char *work_str, *p1, *p2; int i = 0; + if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &delim, &str) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_string(str); + convert_to_string(delim); + + if (strlen(delim->value.str.val)==0) { + /* the delimiter must be a valid C string that's at least 1 character long */ + php3_error(E_WARNING,"Empty delimiter"); + RETURN_FALSE; + } + if (array_init(return_value) == FAILURE) { + return; + } work_str = p1 = estrndup(str->value.str.val,str->value.str.len); p2 = strstr(p1, delim->value.str.val); if (p2 == NULL) { @@ -303,47 +300,38 @@ void _php3_explode(pval *delim, pval *str, pval *return_value) } efree(work_str); } +/* }}} */ -/* {{{ proto array explode(string separator, string str) - Split a string on string separator and return array of components */ -void php3_explode(INTERNAL_FUNCTION_PARAMETERS) +/* {{{ proto string implode(array src, string glue) + Join array elements placing glue string between items and return one string */ +PHP_FUNCTION(implode) { - pval *str, *delim; - - if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &delim, &str) == FAILURE) { + pval *arg1, *arg2, *delim, **tmp, *arr; + int len = 0, count = 0; + + if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &arg1, &arg2) == FAILURE) { WRONG_PARAM_COUNT; } - convert_to_string(str); - convert_to_string(delim); - - if (strlen(delim->value.str.val)==0) { - /* the delimiter must be a valid C string that's at least 1 character long */ - php3_error(E_WARNING,"Empty delimiter"); - RETURN_FALSE; - } - if (array_init(return_value) == FAILURE) { + if (arg1->type == IS_ARRAY && arg2->type == IS_STRING) { + arr = arg1; + delim = arg2; + } else if (arg2->type == IS_ARRAY) { + convert_to_string(arg1); + arr = arg2; + delim = arg1; + } else { + php3_error(E_WARNING, "Bad arguments to %s()", + get_active_function_name()); return; } - _php3_explode(delim, str, return_value); -} -/* }}} */ - -/* {{{ proto string join(array src, string glue) - An alias for implode */ -/* }}} */ -void _php3_implode(pval *delim, pval *arr, pval *return_value) -{ - pval *tmp; - int len = 0, count = 0; - PLS_FETCH(); /* convert everything to strings, and calculate length */ _php3_hash_internal_pointer_reset(arr->value.ht); while (_php3_hash_get_current_data(arr->value.ht, (void **) &tmp) == SUCCESS) { - convert_to_string(tmp); - if (tmp->type == IS_STRING && tmp->value.str.val != undefined_variable_string) { - len += tmp->value.str.len; + convert_to_string(*tmp); + if ((*tmp)->type == IS_STRING) { + len += (*tmp)->value.str.len; if (count>0) { len += delim->value.str.len; } @@ -358,9 +346,9 @@ void _php3_implode(pval *delim, pval *arr, pval *return_value) return_value->value.str.val[len] = '\0'; _php3_hash_internal_pointer_reset(arr->value.ht); while (_php3_hash_get_current_data(arr->value.ht, (void **) &tmp) == SUCCESS) { - if (tmp->type == IS_STRING && tmp->value.str.val != undefined_variable_string) { + if ((*tmp)->type == IS_STRING) { count--; - strcat(return_value->value.str.val, tmp->value.str.val); + strcat(return_value->value.str.val, (*tmp)->value.str.val); if (count > 0) { strcat(return_value->value.str.val, delim->value.str.val); } @@ -368,44 +356,19 @@ void _php3_implode(pval *delim, pval *arr, pval *return_value) _php3_hash_move_forward(arr->value.ht); } return_value->type = IS_STRING; + return_value->refcount = 1; + return_value->is_ref = 0; return_value->value.str.len = len; } - - -/* {{{ proto string implode(array src, string glue) - Join array elements placing glue string between items and return one string */ -void php3_implode(INTERNAL_FUNCTION_PARAMETERS) -{ - pval *arg1, *arg2, *delim, *arr; - - if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &arg1, &arg2) == FAILURE) { - WRONG_PARAM_COUNT; - } - - if (arg1->type == IS_ARRAY && arg2->type == IS_STRING) { - arr = arg1; - delim = arg2; - } else if (arg2->type == IS_ARRAY) { - convert_to_string(arg1); - arr = arg2; - delim = arg1; - } else { - php3_error(E_WARNING, "Bad arguments to %s()", - get_active_function_name()); - return; - } - _php3_implode(delim, arr, return_value) ; -} /* }}} */ - #ifndef THREAD_SAFE char *strtok_string; #endif /* {{{ proto string strtok([string str,] string token) Tokenize a string */ -void php3_strtok(INTERNAL_FUNCTION_PARAMETERS) +PHP_FUNCTION(strtok) { pval *str, *tok; #ifndef THREAD_SAFE @@ -415,7 +378,6 @@ void php3_strtok(INTERNAL_FUNCTION_PARAMETERS) char *token = NULL, *tokp=NULL; char *first = NULL; int argc; - PLS_FETCH(); argc = ARG_COUNT(ht); @@ -447,7 +409,7 @@ void php3_strtok(INTERNAL_FUNCTION_PARAMETERS) if (strtok_pos2) { *strtok_pos2 = '\0'; } - RETVAL_STRING(strtok_pos1, 1); + RETVAL_STRING(strtok_pos1,1); #if 0 /* skip 'token' white space for next call to strtok */ while (strtok_pos2 && @@ -480,11 +442,10 @@ PHPAPI char *_php3_strtoupper(char *s) /* {{{ proto string strtoupper(string str) Make a string uppercase */ -void php3_strtoupper(INTERNAL_FUNCTION_PARAMETERS) +PHP_FUNCTION(strtoupper) { pval *arg; char *ret; - PLS_FETCH(); if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg)) { WRONG_PARAM_COUNT; @@ -512,11 +473,10 @@ PHPAPI char *_php3_strtolower(char *s) /* {{{ proto string strtolower(string str) Make a string lowercase */ -void php3_strtolower(INTERNAL_FUNCTION_PARAMETERS) +PHP_FUNCTION(strtolower) { pval *str; char *ret; - PLS_FETCH(); if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &str)) { WRONG_PARAM_COUNT; @@ -530,11 +490,10 @@ void php3_strtolower(INTERNAL_FUNCTION_PARAMETERS) /* {{{ proto string basename(string path) Return the filename component of the path */ -void php3_basename(INTERNAL_FUNCTION_PARAMETERS) +PHP_FUNCTION(basename) { pval *str; char *ret, *c; - PLS_FETCH(); if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &str)) { WRONG_PARAM_COUNT; @@ -583,11 +542,10 @@ PHPAPI void _php3_dirname(char *str, int len) { /* {{{ proto string dirname(string path) Return the directory name component of the path */ -void php3_dirname(INTERNAL_FUNCTION_PARAMETERS) +PHP_FUNCTION(dirname) { pval *str; char *ret; - PLS_FETCH(); if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &str)) { WRONG_PARAM_COUNT; @@ -601,7 +559,7 @@ void php3_dirname(INTERNAL_FUNCTION_PARAMETERS) /* }}} */ -/* case insensitive strstr */ +/* case-insensitve strstr */ PHPAPI char *php3i_stristr(unsigned char *s, unsigned char *t) { int i, j, k, l; @@ -616,13 +574,12 @@ PHPAPI char *php3i_stristr(unsigned char *s, unsigned char *t) return NULL; } -/* {{{ proto string stristr(string haystack, string needle) +/* {{{ proto string strstr(string haystack, string needle) Find first occurrence of a string within another, case insensitive */ -void php3_stristr(INTERNAL_FUNCTION_PARAMETERS) +PHP_FUNCTION(stristr) { pval *haystack, *needle; char *found = NULL; - PLS_FETCH(); if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &haystack, &needle) == FAILURE) { @@ -645,17 +602,12 @@ void php3_stristr(INTERNAL_FUNCTION_PARAMETERS) } /* }}} */ -/* {{{ proto string strchr(string haystack, string needle) - An alias for strstr */ -/* }}} */ - /* {{{ proto string strstr(string haystack, string needle) Find first occurrence of a string within another */ -void php3_strstr(INTERNAL_FUNCTION_PARAMETERS) +PHP_FUNCTION(strstr) { pval *haystack, *needle; char *found = NULL; - PLS_FETCH(); if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &haystack, &needle) == FAILURE) { @@ -683,14 +635,13 @@ void php3_strstr(INTERNAL_FUNCTION_PARAMETERS) } /* }}} */ -/* {{{ proto int strpos(string haystack, string needle [, int offset]) +/* {{{ proto int strpos(string haystack, string needle) Find position of first occurrence of a string within another */ -void php3_strpos(INTERNAL_FUNCTION_PARAMETERS) +PHP_FUNCTION(strpos) { pval *haystack, *needle, *OFFSET; int offset = 0; char *found = NULL; - PLS_FETCH(); switch(ARG_COUNT(ht)) { case 2: @@ -735,11 +686,10 @@ void php3_strpos(INTERNAL_FUNCTION_PARAMETERS) /* {{{ proto int strrpos(string haystack, string needle) Find the last occurrence of a character in a string within another */ -void php3_strrpos(INTERNAL_FUNCTION_PARAMETERS) +PHP_FUNCTION(strrpos) { pval *haystack, *needle; char *found = NULL; - PLS_FETCH(); if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &haystack, &needle) == FAILURE) { WRONG_PARAM_COUNT; @@ -763,11 +713,10 @@ void php3_strrpos(INTERNAL_FUNCTION_PARAMETERS) /* {{{ proto string strrchr(string haystack, string needle) Find the last occurrence of a character in a string within another */ -void php3_strrchr(INTERNAL_FUNCTION_PARAMETERS) +PHP_FUNCTION(strrchr) { pval *haystack, *needle; char *found = NULL; - PLS_FETCH(); if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &haystack, &needle) == FAILURE) { @@ -793,8 +742,7 @@ void php3_strrchr(INTERNAL_FUNCTION_PARAMETERS) /* }}} */ static char * -_php3_chunk_split(char *src, int srclen, char *end, int endlen, - int chunklen, int *destlen) +_php3_chunk_split(char *src, int srclen, char *end, int endlen, int chunklen) { char *dest; char *p, *q; @@ -822,14 +770,13 @@ _php3_chunk_split(char *src, int srclen, char *end, int endlen, } *q = '\0'; - if(destlen) *destlen = q - dest; return(dest); } /* {{{ proto string chunk_split(string str [, int chunklen [, string ending]]) Return split line */ -void php3_chunk_split(INTERNAL_FUNCTION_PARAMETERS) +PHP_FUNCTION(chunk_split) { pval *p_str, *p_chunklen, *p_ending; int argc; @@ -837,13 +784,13 @@ void php3_chunk_split(INTERNAL_FUNCTION_PARAMETERS) char *end = "\r\n"; int endlen = 2; int chunklen = 76; - int result_len; - PLS_FETCH(); argc = ARG_COUNT(ht); - - if(argc < 1 || argc > 3 || getParameters(ht, argc, &p_str, - &p_chunklen, &p_ending) == FAILURE) { + + if(!((argc == 1 && getParameters(ht, 1, &p_str) != FAILURE) || + (argc == 2 && getParameters(ht, 2, &p_str, &p_chunklen) != FAILURE) || + (argc == 3 && getParameters(ht, 3, &p_str, &p_chunklen, + &p_ending) != FAILURE))) { WRONG_PARAM_COUNT; } @@ -865,10 +812,10 @@ void php3_chunk_split(INTERNAL_FUNCTION_PARAMETERS) } result = _php3_chunk_split(p_str->value.str.val, p_str->value.str.len, - end, endlen, chunklen, &result_len); + end, endlen, chunklen); if(result) { - RETVAL_STRINGL(result, result_len, 0); + RETVAL_STRING(result, 0); } else { RETURN_FALSE; } @@ -877,12 +824,11 @@ void php3_chunk_split(INTERNAL_FUNCTION_PARAMETERS) /* {{{ proto string substr(string str, int start [, int length]) Return part of a string */ -void php3_substr(INTERNAL_FUNCTION_PARAMETERS) +PHP_FUNCTION(substr) { pval *string, *from, *len; int argc, l; int f; - PLS_FETCH(); argc = ARG_COUNT(ht); @@ -926,23 +872,22 @@ void php3_substr(INTERNAL_FUNCTION_PARAMETERS) RETURN_FALSE; } - /* Adjust l to match the actual string segment to be returned */ if((f+l) > (int)string->value.str.len) { l = (int)string->value.str.len - f; } - RETVAL_STRINGL(string->value.str.val + f,l,1); + + RETVAL_STRINGL(string->value.str.val + f, l, 1); } /* }}} */ /* {{{ proto string quotemeta(string str) Quote meta characters */ -void php3_quotemeta(INTERNAL_FUNCTION_PARAMETERS) +PHP_FUNCTION(quotemeta) { pval *arg; char *str, *old; char *p, *q; char c; - PLS_FETCH(); if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg) == FAILURE) { WRONG_PARAM_COUNT; @@ -983,10 +928,9 @@ void php3_quotemeta(INTERNAL_FUNCTION_PARAMETERS) /* {{{ proto int ord(string character) Return ASCII value of character */ -void php3_ord(INTERNAL_FUNCTION_PARAMETERS) +PHP_FUNCTION(ord) { pval *str; - PLS_FETCH(); if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &str) == FAILURE) { WRONG_PARAM_COUNT; @@ -998,11 +942,10 @@ void php3_ord(INTERNAL_FUNCTION_PARAMETERS) /* {{{ proto string chr(int ascii) Convert ASCII code to a character */ -void php3_chr(INTERNAL_FUNCTION_PARAMETERS) +PHP_FUNCTION(chr) { pval *num; char temp[2]; - PLS_FETCH(); if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &num) == FAILURE) { WRONG_PARAM_COUNT; @@ -1014,9 +957,9 @@ void php3_chr(INTERNAL_FUNCTION_PARAMETERS) } /* }}} */ -/* {{{ proto string ucfirst(string str) +/* {{{ proto string(string str) Make a string's first character uppercase */ -void php3_ucfirst(INTERNAL_FUNCTION_PARAMETERS) +PHP_FUNCTION(ucfirst) { pval *arg; @@ -1035,7 +978,7 @@ void php3_ucfirst(INTERNAL_FUNCTION_PARAMETERS) /* {{{ proto string ucwords(string str) Uppercase the first character of every word in a string */ -void php3_ucwords(INTERNAL_FUNCTION_PARAMETERS) +PHP_FUNCTION(ucwords) { pval *arg; char *r; @@ -1060,33 +1003,14 @@ void php3_ucwords(INTERNAL_FUNCTION_PARAMETERS) } /* }}} */ -PHPAPI char *_php3_strtr(char *string, int len, char *str_from, char *str_to, int trlen) -{ - int i; - unsigned char xlat[256]; - - if ((trlen < 1) || (len < 1)) - return string; - - for (i = 0; i < 256; xlat[i] = i, i++); - - for (i = 0; i < trlen; i++) { - xlat[(unsigned char) str_from[i]] = str_to[i]; - } - - for (i = 0; i < len; i++) { - string[i] = xlat[(unsigned char) string[i]]; - } - - return string; -} - /* {{{ proto string strtr(string str, string from, string to) Translate characters in str using given translation tables */ -void php3_strtr(INTERNAL_FUNCTION_PARAMETERS) +PHP_FUNCTION(strtr) { /* strtr(STRING,FROM,TO) */ pval *str, *from, *to; - PLS_FETCH(); + unsigned char xlat[256]; + unsigned char *str_from, *str_to, *string; + int i, len1, len2; if (ARG_COUNT(ht) != 3 || getParameters(ht, 3, &str, &from, &to) == FAILURE) { @@ -1096,19 +1020,35 @@ void php3_strtr(INTERNAL_FUNCTION_PARAMETERS) convert_to_string(from); convert_to_string(to); - RETVAL_STRING(_php3_strtr(str->value.str.val, - str->value.str.len, - from->value.str.val, - to->value.str.val, - MIN(from->value.str.len,to->value.str.len)), - 1); + string = (unsigned char*) str->value.str.val; + str_from = (unsigned char*) from->value.str.val; + str_to = (unsigned char*) to->value.str.val; + + len1 = from->value.str.len; + len2 = to->value.str.len; + + if (len1 > len2) { + str_from[len2] = '\0'; + len1 = len2; + } + for (i = 0; i < 256; xlat[i] = i, i++); + + for (i = 0; i < len1; i++) { + xlat[(unsigned char) str_from[i]] = str_to[i]; + } + + for (i = 0; i < str->value.str.len; i++) { + string[i] = xlat[(unsigned char) string[i]]; + } + + RETVAL_STRING((char *)string,1); } /* }}} */ /* {{{ proto string strrev(string str) Reverse a string */ -void php3_strrev(INTERNAL_FUNCTION_PARAMETERS) +PHP_FUNCTION(strrev) { pval *str; int i,len; @@ -1133,87 +1073,14 @@ void php3_strrev(INTERNAL_FUNCTION_PARAMETERS) } /* }}} */ -static void _php3_similar_str(const char *txt1, int len1, const char *txt2, - int len2, int *pos1, int *pos2, int *max) -{ - char *p, *q; - char *end1 = (char *) txt1 + len1; - char *end2 = (char *) txt2 + len2; - int l; - - *max = 0; - for (p = (char *) txt1; p < end1; p++) { - for (q = (char *) txt2; q < end2; q++) { - for (l = 0; (p + l < end1) && (q + l < end2) && (p[l] == q[l]); - l++); - if (l > *max) { - *max = l; - *pos1 = p - txt1; - *pos2 = q - txt2; - } - } - } -} - -static int _php3_similar_char(const char *txt1, int len1, - const char *txt2, int len2) -{ - int sum; - int pos1, pos2, max; - - _php3_similar_str(txt1, len1, txt2, len2, &pos1, &pos2, &max); - if ((sum = max)) { - if (pos1 && pos2) - sum += _php3_similar_char(txt1, pos1, txt2, pos2); - if ((pos1 + max < len1) && (pos2 + max < len2)) - sum += _php3_similar_char(txt1 + pos1 + max, len1 - pos1 - max, - txt2 + pos2 + max, len2 - pos2 -max); - } - return sum; -} -/* {{{ proto int similar_text(string str1, string str2 [, double percent]) - Calculates the similarity between two strings */ -void php3_similar_text(INTERNAL_FUNCTION_PARAMETERS) -{ - pval *t1, *t2, *percent; - int ac = ARG_COUNT(ht); - int sim; - - if (ac < 2 || ac > 3 || - getParameters(ht, ac, &t1, &t2, &percent) == FAILURE) { - WRONG_PARAM_COUNT; - } - - convert_to_string(t1); - convert_to_string(t2); - if(ac > 2) { - convert_to_double(percent); - } - - if((t1->value.str.len + t2->value.str.len) == 0) { - if(ac > 2) - percent->value.dval = 0; - RETURN_LONG(0); - } - - sim = _php3_similar_char(t1->value.str.val, t1->value.str.len, - t2->value.str.val, t2->value.str.len); - - if (ac > 2) { - percent->value.dval = sim * 200.0 / (t1->value.str.len + t2->value.str.len); - } - - RETURN_LONG(sim); -} -/* }}} */ - /* be careful, this edits the string in-place */ PHPAPI void _php3_stripslashes(char *string, int *len) { char *s, *t; int l; char escape_char='\\'; + PLS_FETCH(); if (PG(magic_quotes_sybase)) { escape_char='\''; @@ -1258,7 +1125,7 @@ PHPAPI void _php3_stripslashes(char *string, int *len) /* {{{ proto string addslashes(string str) Escape single quote, double quotes and backslash characters in a string with backslashes */ -void php3_addslashes(INTERNAL_FUNCTION_PARAMETERS) +PHP_FUNCTION(addslashes) { pval *str; @@ -1273,10 +1140,9 @@ void php3_addslashes(INTERNAL_FUNCTION_PARAMETERS) /* {{{ proto string stripslashes(string str) Strip backslashes from a string */ -void php3_stripslashes(INTERNAL_FUNCTION_PARAMETERS) +PHP_FUNCTION(stripslashes) { pval *str; - PLS_FETCH(); if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &str) == FAILURE) { WRONG_PARAM_COUNT; @@ -1314,6 +1180,7 @@ PHPAPI char *_php3_addslashes(char *str, int length, int *new_length, int should char *source,*target; char *end; char c; + PLS_FETCH(); for (source=str,end=source+length,target=new_str; (c = *source) || source 981220 - */ - static char *_php3_str_to_str(char *haystack, int length, char *needle, int needle_len, char *str, int str_len, int *_new_length) { @@ -1466,79 +1328,22 @@ finish: return new; } -#else - -static char *_php3_memstr(char *s, char *c, size_t n, size_t m) -{ - char *p; - - for(p = s; (p - s) < n; p++) - if(memcmp(p, c, m) == 0) - return p; - return NULL; -} - -#define ATTCHSTR(st, sz) \ - nl += sz; \ - n = erealloc(n, nl + 1); \ - memcpy(n + no, st, sz); \ - no += sz - - -static char *_php3_str_to_str(char *a, int al, char *b, int bl, char *c, int cl, - int *newlen) -{ - char *n = NULL, *p, *q; - int nl = 0; - int no = 0; - - /* run through all occurences of b in a */ - for(p = q = a; (p = _php3_memstr(p, b, al - (p - a), bl)); q = p) { - /* attach everything between the previous occ. and this one */ - ATTCHSTR(q, p - q); - /* attach the replacement string c */ - ATTCHSTR(c, cl); - /* jump over string b in a */ - p += bl; - } - - /* anything left over ? */ - if((al - (q - a)) > 0) { - ATTCHSTR(q, al - (q - a)); - } - - if(newlen) *newlen = nl; - n[nl] = '\0'; - - return n; -} - -#undef ATTCHSTR -#endif - /* {{{ proto string str_replace(string needle, string str, string haystack) Replace all occurrences of needle in haystack with str */ -void php3_str_replace(INTERNAL_FUNCTION_PARAMETERS) +PHP_FUNCTION(str_replace) { pval *haystack, *needle, *str; char *new; int len = 0; - if(ARG_COUNT(ht) != 3 || + if(ARG_COUNT(ht) != 3 || getParameters(ht, 3, &needle, &str, &haystack) == FAILURE) { WRONG_PARAM_COUNT; } convert_to_string(haystack); convert_to_string(needle); - convert_to_string(str); - - if(haystack->value.str.len == 0) { - RETURN_STRING(empty_string,1); - } - - if(needle->value.str.len == 1) { - _php3_char_to_str(haystack->value.str.val,haystack->value.str.len,needle->value.str.val[0],str->value.str.val, str->value.str.len ,return_value); + convert_to_string(str); if(needle->value.str.len == 1) { _php3_char_to_str(haystack->value.str.val,haystack->value.str.len,needle->value.str.val[0],str->value.str.val, str->value.str.len ,return_value); return; } @@ -1547,10 +1352,10 @@ void php3_str_replace(INTERNAL_FUNCTION_PARAMETERS) RETURN_FALSE; } - new = _php3_str_to_str(haystack->value.str.val, haystack->value.str.len, - needle->value.str.val, needle->value.str.len, - str->value.str.val, str->value.str.len, - &len); + new = _php3_str_to_str(haystack->value.str.val, haystack->value.str.len, + needle->value.str.val, needle->value.str.len, + str->value.str.val, str->value.str.len, + &len); RETURN_STRINGL(new, len, 0); } /* }}} */ @@ -1724,15 +1529,15 @@ static void _php3_hebrev(INTERNAL_FUNCTION_PARAMETERS,int convert_newlines) /* {{{ proto string hebrev(string str [, int max_chars_per_line]) Convert logical Hebrew text to visual text */ -void php3_hebrev(INTERNAL_FUNCTION_PARAMETERS) +PHP_FUNCTION(hebrev) { _php3_hebrev(INTERNAL_FUNCTION_PARAM_PASSTHRU,0); } /* }}} */ -/* {{{ proto string hebrevc(string str [, int max_chars_per_line]) +/* {{{ proto string hebrev(string str [, int max_chars_per_line]) Convert logical Hebrew text to visual text with newline conversion */ -void php3_hebrev_with_conversion(INTERNAL_FUNCTION_PARAMETERS) +PHP_FUNCTION(hebrev_with_conversion) { _php3_hebrev(INTERNAL_FUNCTION_PARAM_PASSTHRU,1); } @@ -1740,7 +1545,7 @@ void php3_hebrev_with_conversion(INTERNAL_FUNCTION_PARAMETERS) /* {{{ proto string nl2br(string str) Converts newlines to HTML line breaks */ -void php3_newline_to_br(INTERNAL_FUNCTION_PARAMETERS) +PHP_FUNCTION(newline_to_br) { pval *str; @@ -1754,27 +1559,9 @@ void php3_newline_to_br(INTERNAL_FUNCTION_PARAMETERS) } /* }}} */ -/* {{{ proto string strip_tags(string str) - Strips HTML and PHP tags from a string */ -void php3_strip_tags(INTERNAL_FUNCTION_PARAMETERS) -{ - char *buf; - pval *str; - - if (ARG_COUNT(ht)!=1 || getParameters(ht, 1, &str)==FAILURE) { - WRONG_PARAM_COUNT; - } - convert_to_string(str); - buf=estrdup(str->value.str.val); - _php3_strip_tags(buf,0); - RETURN_STRING(buf,0); -} -/* }}} */ - - /* {{{ proto string setlocale(string category, string locale) Set locale information */ -void php3_setlocale(INTERNAL_FUNCTION_PARAMETERS) +PHP_FUNCTION(setlocale) { pval *category, *locale; int cat; @@ -1815,102 +1602,6 @@ void php3_setlocale(INTERNAL_FUNCTION_PARAMETERS) } /* }}} */ -/* A simple little state-machine to strip out html and php tags - - State 0 is the output state, State 1 means we are inside a - normal html tag and state 2 means we are inside a php tag. - - The state variable is passed in to allow a function like fgetss - to maintain state across calls to the function. - - lc holds the last significant character read and br is a bracket - counter. -*/ -void _php3_strip_tags(char *rbuf, int state) { - char *buf, *p, *rp, c, lc; - int br; - - buf = estrdup(rbuf); - c = *buf; - lc = '\0'; - p = buf; - rp = rbuf; - br = 0; - - while (c) { /* This is not binary-safe. Don't see why it should be */ - switch (c) { - case '<': - if (state == 0) { - lc = '<'; - state = 1; - } - break; - - case '(': - if (state == 2) { - if (lc != '\"') { - lc = '('; - br++; - } - } else if (state == 0) { - *(rp++) = c; - } - break; - - case ')': - if (state == 2) { - if (lc != '\"') { - lc = ')'; - br--; - } - } else if (state == 0) { - *(rp++) = c; - } - break; - - case '>': - if (state == 1) { - lc = '>'; - state = 0; - } else if (state == 2) { - if (!br && lc != '\"' && *(p-1)=='?') { - state = 0; - } - } - break; - - case '\"': - if (state == 2) { - if (lc == '\"') { - lc = '\0'; - } else if (lc != '\\') { - lc = '\"'; - } - } else if (state == 0) { - *(rp++) = c; - } - break; - - case '?': - if (state==1 && *(p-1)=='<') { - br=0; - state=2; - break; - } - /* fall-through */ - - default: - if (state == 0) { - *(rp++) = c; - } - break; - } - c = *(++p); - } - *rp = '\0'; - efree(buf); -} - /* {{{ proto void parsestr(string encoded_string) Parses GET/POST/COOKIE data and sets global variables. */ PHP_FUNCTION(parsestr) @@ -1927,7 +1618,6 @@ PHP_FUNCTION(parsestr) } php3_treat_data(PARSE_STRING, res); } -/* }}} */ /* * Local variables: diff --git a/main/fopen_wrappers.c b/main/fopen_wrappers.c index f8cc1be3a8..38d410018b 100644 --- a/main/fopen_wrappers.c +++ b/main/fopen_wrappers.c @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP HTML Embedded Scripting Language Version 3.0 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-1999 PHP Development Team (See Credits file) | + | 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: | @@ -51,6 +51,7 @@ #include "safe_mode.h" #include "php3_realpath.h" +#include "ext/standard/head.h" #include "ext/standard/php3_standard.h" #include "zend_compile.h" @@ -87,128 +88,97 @@ #include #endif -static FILE *php3_fopen_url_wrapper(char *path, char *mode, int options, int *issock, int *socketd); +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_specific_open_basedir(char *basedir, char *path) +PHPAPI int _php3_check_open_basedir(char *path) { char resolved_name[MAXPATHLEN]; - char resolved_basedir[MAXPATHLEN]; char local_open_basedir[MAXPATHLEN]; int local_open_basedir_pos; + PLS_FETCH(); - /* Special case basedir==".": Use script-directory */ - if ((strcmp(basedir, ".") == 0) && - request_info.filename && - *request_info.filename - ) { - strcpy(local_open_basedir, 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) + /* Only check when open_basedir is available */ + if (PG(open_basedir) && *PG(open_basedir)) { + + /* Special case basedir==".": Use script-directory */ + if ((strcmp(PG(open_basedir), ".") == 0) && + request_info.filename && + *request_info.filename ) { - local_open_basedir[local_open_basedir_pos--] = 0; - } -/* stripping unnecessary slashes is left - as an exercise to the underlying OS */ -#if 0 - /* Strip double (back)slashes */ - if (local_open_basedir_pos > 0) { + strcpy(local_open_basedir, 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-1] == '\\') || + (local_open_basedir[local_open_basedir_pos] != '\\') || #endif - (local_open_basedir[local_open_basedir_pos-1] == '/') + (local_open_basedir[local_open_basedir_pos] != '/') ) && - (local_open_basedir_pos > 0) + (local_open_basedir_pos >= 0) ) { local_open_basedir[local_open_basedir_pos--] = 0; } - } -#endif - } else { - /* Else use the unmodified path */ - strcpy(local_open_basedir, basedir); - } - - /* Resolve the real path into resolved_name */ - if ((_php3_realpath(path, resolved_name) != NULL) && (_php3_realpath(local_open_basedir, resolved_basedir) != NULL)) { - /* Check the path */ + +#if 0 + /* Strip double (back)slashes */ + if (local_open_basedir_pos > 0) { + while (( #if WIN32|WINNT - if (strncasecmp(resolved_basedir, resolved_name, strlen(resolved_basedir)) == 0) { -#else - if (strncmp(resolved_basedir, resolved_name, strlen(resolved_basedir)) == 0) { + (local_open_basedir[local_open_basedir_pos-1] == '\\') || #endif - /* File is in the right directory */ - return 0; + (local_open_basedir[local_open_basedir_pos-1] == '/') + ) && + (local_open_basedir_pos > 0) + ) { + local_open_basedir[local_open_basedir_pos--] = 0; + } + } +#endif + } else { - return -1; + /* Else use the unmodified path */ + strcpy(local_open_basedir, PG(open_basedir)); } - } else { - /* Unable to resolve the real path, return -1 */ - return -1; - } -} - -PHPAPI int _php3_check_open_basedir(char *path) -{ - /* Only check when open_basedir is available */ - if (PG(open_basedir) && *PG(open_basedir)) { - char *pathbuf; - char *ptr; - char *end; - - pathbuf = estrdup(PG(open_basedir)); - - ptr = pathbuf; - - while (ptr && *ptr) { + + /* Resolve the real path into resolved_name */ + if (_php3_realpath(path, resolved_name) != NULL) { + /* Check the path */ #if WIN32|WINNT - end = strchr(ptr, ';'); + if (strncasecmp(local_open_basedir, resolved_name, strlen(local_open_basedir)) == 0) { #else - end = strchr(ptr, ':'); + if (strncmp(local_open_basedir, resolved_name, strlen(local_open_basedir)) == 0) { #endif - if (end != NULL) { - *end = '\0'; - end++; - } - - if (_php3_check_specific_open_basedir(ptr, path) == 0) { - efree(pathbuf); + /* 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; } - - ptr = end; + } 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; } - php3_error(E_WARNING, "open_basedir restriction in effect. File is in wrong directory."); - efree(pathbuf); - return -1; + } else { + /* open_basedir is not available, return 0 */ + return 0; } - - /* Nothing to check... */ - 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 */ - /* FIXME Lets not get in the habit of doing stuff like this. This should - be runtime enabled, NOT compile time. */ + PLS_FETCH(); + #if PHP3_URL_FOPEN if (!(options & IGNORE_URL)) { return php3_fopen_url_wrapper(path, mode, options, issock, socketd); @@ -229,17 +199,17 @@ PHPAPI FILE *php3_fopen_wrapper(char *path, char *mode, int options, int *issock #if CGI_BINARY || FHTTPD || USE_SAPI -FILE *php3_fopen_for_parser(void) +PHPAPI FILE *php3_fopen_for_parser(void) { FILE *fp; struct stat st; char *temp, *path_info, *fn; int l; PLS_FETCH(); - + SLS_FETCH(); fn = request_info.filename; - path_info = request_info.path_info; + path_info = SG(request_info).request_uri; #if HAVE_PWD_H if (PG(user_dir) && *PG(user_dir) && path_info && '/' == path_info[0] && '~' == path_info[1]) { @@ -310,17 +280,17 @@ FILE *php3_fopen_for_parser(void) fp = NULL; } if (!fp) { - php3_error(E_ERROR, "Unable to open %s", fn); + php3_error(E_CORE_ERROR, "Unable to open %s", fn); STR_FREE(request_info.filename); /* for same reason as above */ return NULL; } - _php3_hash_index_update(&include_names, 0, (void *) &fn, sizeof(char *), NULL); - - temp = strdup(fn); + + temp = estrdup(fn); _php3_dirname(temp, strlen(temp)); - if (*temp) + if (*temp) { chdir(temp); - free(temp); + } + efree(temp); return fp; } @@ -447,7 +417,7 @@ PHPAPI FILE *php3_fopen_with_path(char *filename, char *mode, char *path, char * * Otherwise, fopen is called as usual and the file pointer is returned. */ -static FILE *php3_fopen_url_wrapper(char *path, char *mode, int options, int *issock, int *socketd) +static FILE *php3_fopen_url_wrapper(const char *path, char *mode, int options, int *issock, int *socketd) { url *resource; int result; @@ -473,9 +443,10 @@ static FILE *php3_fopen_url_wrapper(char *path, char *mode, int options, int *is FILE *fp = NULL; struct sockaddr_in server; unsigned short portno; + char winfeof; if (!strncasecmp(path, "http://", 7)) { - resource = url_parse(path); + resource = url_parse((char *) path); if (resource == NULL) { php3_error(E_WARNING, "Invalid URL specified, %s", path); *issock = BAD_URL; @@ -492,15 +463,16 @@ static FILE *php3_fopen_url_wrapper(char *path, char *mode, int options, int *is free_url(resource); return NULL; } - server.sin_family = AF_INET; + lookup_hostname(resource->host, &server.sin_addr); - if (lookup_hostname(resource->host, &server.sin_addr)) { + if (server.sin_addr.s_addr == -1) { SOCK_FCLOSE(*socketd); *socketd = 0; free_url(resource); return NULL; } server.sin_port = htons(resource->port); + server.sin_family = AF_INET; if (connect(*socketd, (struct sockaddr *) &server, sizeof(server)) == SOCK_CONN_ERR) { SOCK_FCLOSE(*socketd); @@ -582,8 +554,8 @@ static FILE *php3_fopen_url_wrapper(char *path, char *mode, int options, int *is /* Read past http header */ body = 0; location[0] = '\0'; - while (!body && !SOCK_FEOF(*socketd)) { - if ((buf[0] = SOCK_FGETC(*socketd)) == EOF) { + 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); @@ -635,7 +607,7 @@ static FILE *php3_fopen_url_wrapper(char *path, char *mode, int options, int *is *issock = 1; return (fp); } else if (!strncasecmp(path, "ftp://", 6)) { - resource = url_parse(path); + resource = url_parse((char *) path); if (resource == NULL) { php3_error(E_WARNING, "Invalid URL specified, %s", path); *issock = BAD_URL; @@ -657,9 +629,9 @@ static FILE *php3_fopen_url_wrapper(char *path, char *mode, int options, int *is free_url(resource); return NULL; } - server.sin_family = AF_INET; + lookup_hostname(resource->host, &server.sin_addr); - if (lookup_hostname(resource->host, &server.sin_addr)) { + if (server.sin_addr.s_addr == -1) { SOCK_FCLOSE(*socketd); *socketd = 0; free_url(resource); @@ -869,9 +841,9 @@ static FILE *php3_fopen_url_wrapper(char *path, char *mode, int options, int *is free_url(resource); return NULL; } - server.sin_family = AF_INET; + lookup_hostname(resource->host, &server.sin_addr); - if (lookup_hostname(resource->host, &server.sin_addr)) { + if (server.sin_addr.s_addr == -1) { free_url(resource); SOCK_FCLOSE(*socketd); *socketd = 0; @@ -910,15 +882,17 @@ static FILE *php3_fopen_url_wrapper(char *path, char *mode, int options, int *is return (fp); } else { + PLS_FETCH(); + if (options & USE_PATH) { - fp = php3_fopen_with_path(path, mode, PG(include_path), NULL); + fp = php3_fopen_with_path((char *) path, mode, PG(include_path), NULL); } else { int cm=2; if(!strcmp(mode,"r") || !strcmp(mode,"r+")) cm=0; if (options & ENFORCE_SAFE_MODE && PG(safe_mode) && (!_php3_checkuid(path, cm))) { fp = NULL; } else { - if (_php3_check_open_basedir(path)) { + if (_php3_check_open_basedir((char *) path)) { fp = NULL; } else { fp = fopen(path, mode); diff --git a/main/fopen_wrappers.h b/main/fopen_wrappers.h index c078940e36..c1e1420b3c 100644 --- a/main/fopen_wrappers.h +++ b/main/fopen_wrappers.h @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP HTML Embedded Scripting Language Version 3.0 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-1999 PHP Development Team (See Credits file) | + | 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: | @@ -46,18 +46,17 @@ # 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(s) _php3_sock_fgetc((s)) +#define SOCK_FGETC(c,s) recv(s,c,1,0) #define SOCK_FGETS(b,l,s) _php3_sock_fgets((b),(l),(s)) -#define SOCK_FEOF(sock) _php3_sock_feof((sock)) -#define SOCK_FREAD(ptr,size,sock) _php3_sock_fread((ptr),(size),(sock)) -#define SOCK_FCLOSE(s) _php3_sock_close(s) /* values for issock */ #define IS_NOT_SOCKET 0 @@ -70,15 +69,15 @@ extern int wsa_fp; /* a list for open sockets */ extern PHPAPI FILE *php3_fopen_wrapper(char *filename, char *mode, int options, int *issock, int *socketd); -extern FILE *php3_fopen_for_parser(void); +PHPAPI FILE *php3_fopen_for_parser(void); extern PHPAPI int _php3_check_open_basedir(char *path); -extern PHPAPI int _php3_check_specific_open_basedir(char *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);