From: Stig Bakken Date: Wed, 16 Jun 1999 17:06:53 +0000 (+0000) Subject: * fixed some #if/#ifdef issues X-Git-Tag: BEFORE_REMOVING_GC_STEP1~128 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=117a2fba0719f071678d172031388a2707041141;p=php * fixed some #if/#ifdef issues * hand-patched in php3 changes from 3.0.6 to HEAD in these files: fopen-wrappers.[ch] ext/standard/file.[ch] ext/standard/fsock.[ch] ext/standard/php3_string.h ext/standard/string.c * added some new file/socket macros for more readable code: FP_FGETS(buf,len,sock,fp,issock) FP_FREAD(buf,len,sock,fp,issock) FP_FEOF(sock,fp,issock) FP_FGETC(sock,fp,issock) --- diff --git a/acconfig.h.in b/acconfig.h.in index b97a59589f..55c94a3790 100644 --- a/acconfig.h.in +++ b/acconfig.h.in @@ -26,10 +26,10 @@ /* Define if you have dirent.h but opendir() resides in libc rather than in libdir */ /* This will cause HAVE_DIRENT_H defined twice sometimes, but it should be problem */ -#define HAVE_DIRENT_H 0 +#undef HAVE_DIRENT_H /* Define if you have the resolv library (-lresolv). */ -#define HAVE_LIBRESOLV 0 +#undef HAVE_LIBRESOLV /* Define if you have the pam library (-lpam). */ #define HAVE_LIBPAM 0 @@ -62,10 +62,10 @@ #define HSREGEX 0 /* Define if you have and want to use libnsl */ -#define HAVE_LIBNSL 0 +#undef HAVE_LIBNSL /* Define if you have and want to use libsocket */ -#define HAVE_LIBSOCKET 0 +#undef HAVE_LIBSOCKET /* Define if you have the sendmail program available */ #define HAVE_SENDMAIL 0 @@ -92,12 +92,6 @@ #define DEBUG 0 #endif -/* Define if your system has the gettimeofday() call */ -#define HAVE_GETTIMEOFDAY 0 - -/* Define if your system has the putenv() library call */ -#define HAVE_PUTENV 0 - /* Define if you want to enable PHP RPC (experimental) */ #define PHP_RPC 0 diff --git a/configure.in.in b/configure.in.in index a41505db63..7fd049642d 100644 --- a/configure.in.in +++ b/configure.in.in @@ -211,7 +211,7 @@ else fi AC_MISSING_FCLOSE_DECL dnl QNX requires unix.h to allow functions in libunix to work properly -AC_CHECK_HEADERS(fcntl.h unistd.h crypt.h sys/file.h memory.h pwd.h grp.h sys/socket.h sys/wait.h syslog.h string.h sys/varargs.h stdarg.h sys/time.h signal.h netinet/in.h dlfcn.h limits.h sys/types.h unix.h arpa/inet.h) +AC_CHECK_HEADERS(fcntl.h unistd.h crypt.h sys/file.h memory.h pwd.h grp.h sys/socket.h sys/wait.h syslog.h string.h sys/varargs.h stdarg.h sys/time.h signal.h netinet/in.h dlfcn.h limits.h sys/types.h unix.h arpa/inet.h locale.h) dnl Checks for typedefs, structures, and compiler characteristics. AC_STRUCT_TM diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index 8f138e71ac..0bbb11afb0 100644 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -147,8 +147,8 @@ function_entry basic_functions[] = { {"strrpos", php3_strrpos, NULL}, {"strrev", php3_strrev, NULL}, {"hebrev", php3_hebrev, NULL}, - {"hebrevc", php3_hebrev_with_conversion,NULL}, - {"nl2br", php3_newline_to_br, NULL}, + PHP_FE(hebrevc, NULL) + PHP_FE(nl2br, NULL) {"basename", php3_basename, NULL}, {"dirname", php3_dirname, NULL}, {"stripslashes", php3_stripslashes, NULL}, @@ -236,7 +236,7 @@ function_entry basic_functions[] = { {"base_convert",php3_base_convert, NULL}, {"number_format", php3_number_format, NULL}, -#if HAVE_PUTENV +#ifdef HAVE_PUTENV {"putenv", php3_putenv, NULL}, #endif {"microtime", php3_microtime, NULL}, @@ -328,7 +328,7 @@ php3_module_entry basic_functions_module = { STANDARD_MODULE_PROPERTIES }; -#if HAVE_PUTENV +#ifdef HAVE_PUTENV static HashTable putenv_ht; static void _php3_putenv_destructor(putenv_entry *pe) @@ -378,6 +378,7 @@ int php3_minit_basic(INIT_FUNC_ARGS) test_class_startup(); REGISTER_INI_ENTRIES(); + return SUCCESS; } @@ -392,7 +393,7 @@ int php3_mshutdown_basic(SHUTDOWN_FUNC_ARGS) int php3_rinit_basic(INIT_FUNC_ARGS) { strtok_string = NULL; -#if HAVE_PUTENV +#ifdef HAVE_PUTENV if (_php3_hash_init(&putenv_ht, 1, NULL, (void (*)(void *)) _php3_putenv_destructor, 0) == FAILURE) { return FAILURE; } @@ -406,9 +407,10 @@ int php3_rinit_basic(INIT_FUNC_ARGS) int php3_rshutdown_basic(SHUTDOWN_FUNC_ARGS) { STR_FREE(strtok_string); -#if HAVE_PUTENV +#ifdef HAVE_PUTENV _php3_hash_destroy(&putenv_ht); #endif + return SUCCESS; } @@ -468,7 +470,7 @@ PHP_FUNCTION(getenv) } -#if HAVE_PUTENV +#ifdef HAVE_PUTENV PHP_FUNCTION(putenv) { diff --git a/ext/standard/dir.c b/ext/standard/dir.c index 4cd10202b8..48a548cda8 100644 --- a/ext/standard/dir.c +++ b/ext/standard/dir.c @@ -34,8 +34,8 @@ #include "php3_dir.h" -#if HAVE_DIRENT_H -#include +#ifdef HAVE_DIRENT_H +# include #endif #if HAVE_UNISTD_H diff --git a/ext/standard/file.c b/ext/standard/file.c index eef2696b92..7501bd0eea 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,1998 PHP Development Team (See Credits file) | + | Copyright (c) 1997-1999 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: | @@ -26,7 +26,11 @@ | Authors: Rasmus Lerdorf | +----------------------------------------------------------------------+ */ + /* $Id$ */ + +/* Synced with php3 revision 1.218 1999-06-16 [ssb] */ + #include "php.h" #include "php_globals.h" #include "ext/standard/flock_compat.h" @@ -59,14 +63,25 @@ #include #endif #endif -#if HAVE_SYS_TIME_H -#include +#ifdef HAVE_SYS_TIME_H +# include +#endif +#if WIN32|WINNT +# include +#else +# include +# include +# include #endif #include "snprintf.h" #include "fsock.h" #include "fopen-wrappers.h" #include "php_globals.h" +#ifdef HAVE_SYS_FILE_H +# include +#endif + #if MISSING_FCLOSE_DECL extern int fclose(); #endif @@ -115,7 +130,9 @@ extern int le_uploads; * SUCH DAMAGE. */ -#include +#ifdef HAVE_UNISTD_H +# include +#endif #ifndef MAXPATHLEN # ifdef PATH_MAX @@ -173,41 +190,48 @@ char *tempnam(const char *dir, const char *pfx) function_entry php3_file_functions[] = { - {"pclose", php3_pclose, NULL}, - {"popen", php3_popen, NULL}, - {"readfile", php3_readfile, NULL}, - {"rewind", php3_rewind, NULL}, - {"rmdir", php3_rmdir, NULL}, - {"umask", php3_fileumask, 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}, - {"mkdir", php3_mkdir, NULL}, - {"rename", php3_rename, NULL}, - {"copy", php3_file_copy, 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)) - {"set_socket_timeout", php3_set_socket_timeout, NULL}, + PHP_FE(pclose, NULL) + PHP_FE(popen, NULL) + PHP_FE(readfile, NULL) + PHP_FE(rewind, NULL) + PHP_FE(rmdir, NULL) + PHP_FE(umask, NULL) + PHP_FE(fclose, NULL) + PHP_FE(feof, NULL) + PHP_FE(fgetc, NULL) + PHP_FE(fgets, NULL) + PHP_FE(fgetss, NULL) + PHP_FE(fread, NULL) + PHP_FE(fopen, NULL) + PHP_FE(fpassthru, NULL) + PHP_FE(fseek, NULL) + PHP_FE(ftell, NULL) + PHP_FE(fwrite, NULL) + {"fputs", php3_fwrite, NULL}, + PHP_FE(mkdir, NULL) + PHP_FE(rename, NULL) + PHP_FE(copy, NULL) + PHP_FE(tempnam, NULL) + PHP_FE(file, NULL) + PHP_FE(fgetcsv, NULL) + PHP_FE(flock, NULL) + PHP_FE(get_meta_tags, NULL) + PHP_FE(set_socket_blocking, NULL) +#if (0 && defined(HAVE_SYS_TIME_H) && HAVE_SETSOCKOPT && defined(SO_SNDTIMEO) && defined(SO_RCVTIMEO)) + PHP_FE(set_socket_timeout, NULL) #endif {NULL, NULL, NULL} }; php3_module_entry php3_file_module_entry = { - "PHP_file", php3_file_functions, php3_minit_file, NULL, NULL, NULL, NULL, STANDARD_MODULE_PROPERTIES + "File functions", + php3_file_functions, + php3_minit_file, + NULL, + NULL, + NULL, + NULL, + STANDARD_MODULE_PROPERTIES }; @@ -307,20 +331,16 @@ PHP_FUNCTION(get_meta_tags) if (array_init(return_value)==FAILURE) { if (issock) { -#if WIN32|WINNT - closesocket(socketd); -#else - close(socketd); -#endif + SOCK_FCLOSE(socketd); } else { fclose(fp); } RETURN_FALSE; } /* 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) - && !php3i_stristr(buf,"")) { + memset(buf, 0, 8191); + while((FP_FGETS(buf,8191,socketd,fp,issock) != NULL) + && !php3i_stristr(buf,"")) { if(php3i_stristr(buf,"value.lval; sock = php3_list_find(id,&type); - if (type!=wsa_fp) { + if (type != wsa_fp) { php3_error(E_WARNING,"%d is not a socket id",id); RETURN_FALSE; } - socketd=*sock; -#if WIN32|WINNT - /* with ioctlsocket, a non-zero sets nonblocking, a zero sets blocking */ - flags=block; - if (ioctlsocket(socketd,FIONBIO,&flags)==SOCKET_ERROR){ - php3_error(E_WARNING,"%s",WSAGetLastError()); + socketd = *sock; + if(_php3_set_sock_blocking(socketd, block) == FAILURE) RETURN_FALSE; - } else { - RETURN_TRUE; - } -#else - flags = fcntl(socketd, F_GETFL); -# ifdef O_NONBLOCK - /* POSIX version */ - if (block) { - if ((flags & O_NONBLOCK)) { - flags ^= O_NONBLOCK; - } - } else { - if (!(flags & O_NONBLOCK)) { - flags |= O_NONBLOCK; - } - } -# else -# ifdef O_NDELAY - /* old non-POSIX version */ - if (block) { - flags |= O_NDELAY; - } else { - flags ^= O_NDELAY; - } -# endif -# endif - fcntl(socketd,F_SETFL,flags); - /* FIXME: Shouldnt we return true on this function? */ -#endif + _php3_sock_set_blocking(socketd, block == 0 ? 0 : 1); + RETURN_TRUE; } /* }}} */ -#if (0 && HAVE_SYS_TIME_H && HAVE_SETSOCKOPT && defined(SO_SNDTIMEO) && defined(SO_RCVTIMEO)) +#if (0 && defined(HAVE_SYS_TIME_H) && HAVE_SETSOCKOPT && defined(SO_SNDTIMEO) && defined(SO_RCVTIMEO)) /* this doesn't work, as it appears those properties are read-only :( */ PHP_FUNCTION(set_socket_timeout) { @@ -852,7 +861,7 @@ PHP_FUNCTION(fgets) 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 (FP_FGETS(buf, len, socketd, fp, issock) == NULL) { efree(buf); RETVAL_FALSE; } else { @@ -896,7 +905,7 @@ PHP_FUNCTION(fgetc) { RETURN_FALSE; } buf = emalloc(sizeof(char) * 2); - if (!(issock?(SOCK_FGETC(buf,socketd)):(*buf=fgetc(fp)))) { + if (!(*buf = FP_FGETC(socketd, fp, issock))) { efree(buf); RETVAL_FALSE; } else { @@ -905,7 +914,6 @@ PHP_FUNCTION(fgetc) { return_value->value.str.len = 1; return_value->type = IS_STRING; } - return; } /* }}} */ @@ -917,8 +925,8 @@ PHP_FUNCTION(fgetss) { pval *fd, *bytes; FILE *fp; - int id, len, br, type; - char *buf, *p, *rbuf, *rp, c, lc; + int id, len, type; + char *buf; int issock=0; int *sock,socketd=0; @@ -933,9 +941,9 @@ PHP_FUNCTION(fgetss) len = bytes->value.lval; fp = php3_list_find(id,&type); - if (type==wsa_fp){ - issock=1; - sock = 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)) { @@ -945,95 +953,20 @@ PHP_FUNCTION(fgetss) 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)) { + memset(buf, 0, len + 1); + if (FP_FGETS(buf, len, socketd, fp, issock) == NULL) { efree(buf); RETURN_FALSE; } - 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); + _php3_strip_tags(buf, fgetss_state); + RETURN_STRING(buf, 0); } /* }}} */ +/* {{{ 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 */ @@ -1097,6 +1030,59 @@ PHP_FUNCTION(fwrite) /* }}} */ +/* {{{ 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 */ PHP_FUNCTION(rewind) @@ -1277,17 +1263,13 @@ PHP_FUNCTION(readfile) } RETURN_FALSE; } - size= 0; - while(issock?(b=SOCK_FGETS(buf,sizeof(buf),socketd)):(b = fread(buf, 1, sizeof(buf), fp)) > 0) { - PHPWRITE(buf,b); - size += b ; + size = 0; + while ((b = FP_FREAD(buf, sizeof(buf), socketd, fp, issock)) > 0) { + PHPWRITE(buf, b); + size += b; } if (issock) { -#if WIN32|WINNT - closesocket(socketd); -#else - close(socketd); -#endif + SOCK_FCLOSE(socketd); } else { fclose(fp); } @@ -1298,7 +1280,7 @@ PHP_FUNCTION(readfile) /* {{{ proto int umask([int mask]) Return or change the umask */ -PHP_FUNCTION(fileumask) +PHP_FUNCTION(umask) { pval *arg1; int oldumask; @@ -1352,22 +1334,11 @@ PHP_FUNCTION(fpassthru) } size = 0; if (php3_header()) { /* force headers if not already sent */ - while(issock?(b=SOCK_FGETS(buf,sizeof(buf),socketd)):(b = fread(buf, 1, sizeof(buf), fp)) > 0) { + while ((b = FP_FREAD(buf, sizeof(buf), socketd, fp, issock)) > 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); } @@ -1411,7 +1382,7 @@ PHP_FUNCTION(rename) /* {{{ proto int copy(string source_file, string destination_file) Copy a file */ -PHP_FUNCTION(file_copy) +PHP_FUNCTION(copy) { pval *source, *target; char buffer[8192]; @@ -1500,7 +1471,7 @@ PHP_FUNCTION(fread) 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 = _php3_sock_fread(return_value->value.str.val, len, socketd); + return_value->value.str.len = 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); @@ -1520,19 +1491,42 @@ PHPAPI int php3i_get_le_fp(void) get line from file pointer and parse for CSV fields */ PHP_FUNCTION(fgetcsv) { char *temp, *tptr, *bptr; - char delimiter = ','; /* allow this to be set as parameter if required in future version? */ + char delimiter = ','; /* allow this to be set as parameter */ /* first section exactly as php3_fgetss */ - pval *fd, *bytes; + pval *fd, *bytes, *p_delim; FILE *fp; int id, len, type; char *buf; int issock=0; int *sock,socketd=0; + PLS_FETCH(); - if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &fd, &bytes) == FAILURE) { - WRONG_PARAM_COUNT; + 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; + /* NOTREACHED */ + break; } convert_to_long(fd); @@ -1541,21 +1535,22 @@ PHP_FUNCTION(fgetcsv) { id = fd->value.lval; len = bytes->value.lval; - fp = php3_list_find(id,&type); - if (type==wsa_fp){ - issock=1; + fp = php3_list_find(id, &type); + if (type == wsa_fp){ + issock = 1; sock = php3_list_find(id,&type); - socketd=*sock; + socketd = *sock; } - if ((!fp || (type!=le_fp && type!=le_pp)) && (!socketd || type!=wsa_fp)) { + 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; } 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)) { + memset(buf, 0, len + 1); + if (FP_FGETS(buf, len, socketd, fp, issock) == NULL) { efree(buf); RETURN_FALSE; } @@ -1575,7 +1570,7 @@ PHP_FUNCTION(fgetcsv) { /* reserve workspace for building each individual field */ temp = emalloc(sizeof(char) * len); /* unlikely but possible! */ - tptr=temp; + tptr = temp; /* Initialize return array */ if (array_init(return_value) == FAILURE) { @@ -1589,7 +1584,7 @@ PHP_FUNCTION(fgetcsv) { 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 */ @@ -1629,6 +1624,7 @@ PHP_FUNCTION(fgetcsv) { efree(temp); efree(buf); } + /* }}} */ /* diff --git a/ext/standard/file.h b/ext/standard/file.h index 2cad2035f7..cc6ab07f9f 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,1998 PHP Development Team (See Credits file) | + | Copyright (c) 1997-1999 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: | @@ -29,6 +29,8 @@ /* $Id$ */ +/* Synced with php3 revision 1.30 1999-06-16 [ssb] */ + #ifndef _FILE_H #define _FILE_H @@ -55,14 +57,17 @@ PHP_FUNCTION(mkdir); PHP_FUNCTION(rmdir); PHP_FUNCTION(fpassthru); PHP_FUNCTION(readfile); -PHP_FUNCTION(fileumask); +PHP_FUNCTION(umask); PHP_FUNCTION(rename); -PHP_FUNCTION(file_copy); +PHP_FUNCTION(copy); PHP_FUNCTION(file); PHP_FUNCTION(set_socket_blocking); PHP_FUNCTION(set_socket_timeout); +PHP_FUNCTION(set_file_buffer); PHP_FUNCTION(get_meta_tags); PHP_FUNCTION(flock); +PHPAPI int _php3_set_sock_blocking(int socketd, int block); + #define phpext_file_ptr php3_file_module_ptr #endif /* _FILE_H */ diff --git a/ext/standard/filestat.c b/ext/standard/filestat.c index 2844ae2346..bcd02fc388 100644 --- a/ext/standard/filestat.c +++ b/ext/standard/filestat.c @@ -417,12 +417,12 @@ static void _php3_stat(const char *filename, int type, pval *return_value) add_next_index_long(return_value, stat_sb->st_atime); add_next_index_long(return_value, stat_sb->st_mtime); add_next_index_long(return_value, stat_sb->st_ctime); -#if HAVE_ST_BLKSIZE +#ifdef HAVE_ST_BLKSIZE add_next_index_long(return_value, stat_sb->st_blksize); #else add_next_index_long(return_value, -1); #endif -#if HAVE_ST_BLOCKS +#ifdef HAVE_ST_BLOCKS add_next_index_long(return_value, stat_sb->st_blocks); #else add_next_index_long(return_value, -1); diff --git a/ext/standard/flock_compat.c b/ext/standard/flock_compat.c index 2d809a718f..08939f3e97 100644 --- a/ext/standard/flock_compat.c +++ b/ext/standard/flock_compat.c @@ -44,7 +44,7 @@ #include #endif -#if !HAVE_FLOCK +#ifndef HAVE_FLOCK int flock(int fd, int operation) #if HAVE_STRUCT_FLOCK { @@ -161,7 +161,7 @@ int flock(int fd, int operation) return 0; } #endif -#endif /* !HAVE_FLOCK */ +#endif /* !defined(HAVE_FLOCK) */ #if !(HAVE_INET_ATON) diff --git a/ext/standard/flock_compat.h b/ext/standard/flock_compat.h index 37ed5e8861..59c8e3bea4 100644 --- a/ext/standard/flock_compat.h +++ b/ext/standard/flock_compat.h @@ -1,7 +1,7 @@ #ifndef _FLOCK_COMPAT_H #define _FLOCK_COMPAT_H -#if !HAVE_FLOCK +#ifndef HAVE_FLOCK # define LOCK_SH 1 # define LOCK_EX 2 # define LOCK_NB 4 diff --git a/ext/standard/fsock.c b/ext/standard/fsock.c index 29bb65ff66..e77de96dbb 100644 --- a/ext/standard/fsock.c +++ b/ext/standard/fsock.c @@ -30,13 +30,23 @@ /* $Id$ */ #include "php.h" +#include "php_globals.h" #include -#if HAVE_UNISTD_H +#include +#ifdef HAVE_UNISTD_H #include #endif +#ifdef HAVE_FCNTL_H +# include +#endif + +#ifdef HAVE_SYS_TIME_H +# include +#endif + #include -#if HAVE_SYS_SOCKET_H +#ifdef HAVE_SYS_SOCKET_H #include #endif #ifdef WIN32 @@ -62,7 +72,7 @@ #include "url.h" #include "fsock.h" -#ifndef THREAD_SAFE +#ifndef ZTS extern int le_fp; #endif @@ -74,40 +84,53 @@ extern int le_fp; #include "build-defs.h" #endif +#ifndef ZTS +static HashTable ht_keys; +static HashTable ht_socks; +#endif + static unsigned char third_and_fourth_args_force_ref[] = { 4, BYREF_NONE, BYREF_NONE, BYREF_FORCE, BYREF_FORCE }; function_entry fsock_functions[] = { - PHP_FE(fsockopen, third_and_fourth_args_force_ref) - PHP_FE(pfsockopen, third_and_fourth_args_force_ref) - {NULL, NULL, NULL} + PHP_FE(fsockopen, third_and_fourth_args_force_ref) + PHP_FE(pfsockopen, third_and_fourth_args_force_ref) + {NULL, NULL, NULL} }; struct php3i_sockbuf { int socket; - char *readbuf; + unsigned 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; typedef struct php3i_sockbuf php3i_sockbuf; -static int php3_minit_fsock(INIT_FUNC_ARGS); -static int php3_mshutdown_fsock(SHUTDOWN_FUNC_ARGS); -static int php3_rshutdown_fsock(SHUTDOWN_FUNC_ARGS); - php3_module_entry fsock_module_entry = { - "Socket functions", fsock_functions, php3_minit_fsock, php3_mshutdown_fsock, NULL, php3_rshutdown_fsock, NULL, STANDARD_MODULE_PROPERTIES + "Socket functions", + fsock_functions, + php3_minit_fsock, + php3_mshutdown_fsock, + NULL, + php3_rshutdown_fsock, + NULL, + STANDARD_MODULE_PROPERTIES }; - -#ifndef THREAD_SAFE + +#ifndef ZTS static HashTable ht_keys; static HashTable ht_socks; #endif + /* {{{ lookup_hostname */ /* @@ -117,7 +140,7 @@ int lookup_hostname(const char *addr, struct in_addr *in) { struct hostent *host_info; - if(!inet_aton(addr, in)) { + if (!inet_aton(addr, in)) { host_info = gethostbyname(addr); if (host_info == 0) { /* Error: unknown host */ @@ -141,6 +164,76 @@ 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 /* !defined(WIN32) && ... */ + return connect(sockfd, addr, addrlen); +#endif +} +/* }}} */ /* {{{ _php3_fsockopen() */ /* @@ -149,19 +242,25 @@ int _php3_is_persistent_sock(int sock) to this variable. */ static void _php3_fsockopen(INTERNAL_FUNCTION_PARAMETERS, int persistent) { - pval *args[4]; + pval *args[5]; 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 > 4 || arg_count < 2 || getParametersArray(ht,arg_count,args)==FAILURE) { + if (arg_count > 5 || 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; + /* fall-through */ case 4: if(!ParameterPassedByReference(ht,4)) { php3_error(E_WARNING,"error string argument to fsockopen not passed by reference"); @@ -212,7 +311,7 @@ static void _php3_fsockopen(INTERNAL_FUNCTION_PARAMETERS, int persistent) { server.sin_port = htons(portno); - if (connect(socketd, (struct sockaddr *)&server, sizeof(server)) == SOCK_CONN_ERR) { + if (connect_nonb(socketd, (struct sockaddr *)&server, sizeof(server), &timeout) == SOCK_CONN_ERR) { FREE_SOCK; if(arg_count>2) args[2]->value.lval = errno; if(arg_count>3) { @@ -235,7 +334,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(socketd, (struct sockaddr *) &unix_addr, sizeof(unix_addr)) == SOCK_CONN_ERR) { + if (connect_nonb(socketd, (struct sockaddr *) &unix_addr, sizeof(unix_addr), &timeout) == SOCK_CONN_ERR) { FREE_SOCK; if(arg_count>2) args[2]->value.lval = errno; if(arg_count>3) { @@ -320,168 +419,337 @@ int _php3_sock_eof(int socket) return ret; } -/* {{{ _php3_sock_fgets() */ -int _php3_sock_fgets(char *buf, int maxlen, int socket) +#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) + +static void php_cleanup_sockbuf(int persistent) { - struct php3i_sockbuf *sockbuf; - int bytesread, toread, len, buflen, count = 0; - char *nl; - - sockbuf = _php3_sock_findsock(socket); - - if (sockbuf) { - toread = sockbuf->writepos - sockbuf->readpos; - if (toread > maxlen) { - toread = maxlen; + php3i_sockbuf *now, *next; + + for(now = phpsockbuf; now; now = next) { + next = now->next; + if(now->persistent == persistent) { + SOCK_DESTROY(now); } - if ((nl = memchr(sockbuf->readbuf + sockbuf->readpos, '\n', toread)) != NULL) { - toread = (nl - (sockbuf->readbuf + sockbuf->readpos)) + 1; + } +} + +#define TOREAD(sock) ((sock)->writepos - (sock)->readpos) +#define READPTR(sock) ((sock)->readbuf + (sock)->readpos) +#define WRITEPTR(sock) ((sock)->readbuf + (sock)->writepos) +#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) { + if (tmp->socket == socket) { + buf = tmp; + break; } - memcpy(buf, sockbuf->readbuf + sockbuf->readpos, toread); - sockbuf->readpos += toread; - count += toread; - buf += toread; - if (sockbuf->readpos >= sockbuf->writepos) { - sockbuf->readpos = sockbuf->writepos = 0; + } + 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 ret = 0; + php3i_sockbuf *sock; + + sock = _php3_sock_find(socket); + if (sock) { + ret = 1; + SOCK_DESTROY(sock); + } + + 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); } - if (nl != NULL) { - /* if a newline was found, skip the recv() loop */ - goto sock_fgets_exit; + } + + 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) +{ + char buf[CHUNK_SIZE]; + int nr_bytes; + size_t nr_read = 0; + + if (sock->eof || max > CHUNK_SIZE) { + return nr_read; + } + + 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); } + 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; } - nl = NULL; - buflen = 0; - while (count < maxlen && nl == NULL) { - toread = maxlen - count; - bytesread = recv(socket, buf, toread, 0); - if (bytesread <= 0) { - break; + return nr_read; +} + +#if !defined(MSG_DONTWAIT) && defined(__GLIBC__) && __GLIBC__ == 2 +# define MSG_DONTWAIT 0x40 +#endif + +/* only for blocking sockets */ +static size_t _php3_sock_queued_data(php3i_sockbuf *sock) +{ + int nr_bytes; + char buf[CHUNK_SIZE]; + int flags = MSG_PEEK; + +#ifdef MSG_DONTWAIT + flags |= MSG_DONTWAIT; +#else + _php3_set_sock_blocking(sock->socket, 1); +#endif + + nr_bytes = recv(sock->socket, buf, CHUNK_SIZE, flags); + +#ifndef MSG_DONTWAIT + _php3_set_sock_blocking(sock->socket, 0); +#endif + + return (nr_bytes < 0 ? 0 : nr_bytes); +} + +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_MAX(max) \ + SOCK_FIND(sock, socket); \ + if(sock->is_blocked) _php3_sock_read_limited(sock, max); else _php3_sock_read(sock) + +/* {{{ _php3_sock_fgets() */ +/* + * 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; + size_t nr_toread; + SOCK_FIND(sock, socket); + + if (maxlen < 0) { + return ret; + } + + if (sock->is_blocked) { + nr_toread = _php3_sock_queued_data(sock); + if (!nr_toread) { + nr_toread = 1; } - if ((nl = memchr(buf, '\n', bytesread)) != NULL) { - len = (nl - buf) + 1; - count += len; - buf += len; - if (len < bytesread) { - buflen = bytesread - len; + for (nr_read = 1; !sock->eof && nr_read < maxlen; ) { + nr_read += _php3_sock_read_limited(sock, nr_toread); + if ((p = memchr(READPTR(sock), '\n', TOREAD(sock))) != NULL) { break; } - } else { - count += bytesread; - buf += bytesread; + nr_toread = 1; } + } else { + _php3_sock_read(sock); + p = memchr(READPTR(sock), '\n', MIN(TOREAD(sock), maxlen - 1)); } - 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; + 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; + } + 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; } - sock_fgets_exit: - *buf = '\0'; - return count; + return ret; } /* }}} */ + +/* + * 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 + */ + +int _php3_sock_fgetc(int socket) +{ + int ret = EOF; + SOCK_FIND_AND_READ_MAX(1); + + if (TOREAD(sock) > 0) { + ret = *READPTR(sock); + sock->readpos++; + } + + 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; +} + /* {{{ _php3_sock_fread() */ -int _php3_sock_fread(char *buf, int maxlen, int socket) +size_t _php3_sock_fread(char *ptr, size_t size, int socket) { - 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; + size_t ret = 0; + SOCK_FIND_AND_READ_MAX(size); + + if (size < 0) { + return ret; } - while (count < maxlen) { - toread = maxlen - count; - bytesread = recv(socket, buf, toread, 0); - if (bytesread <= 0) { - break; - } - count += bytesread; - buf += bytesread; + ret = MIN(TOREAD(sock), size); + if (ret) { + memcpy(ptr, READPTR(sock), ret); + sock->readpos += ret; } - *buf = '\0'; - return count; + return ret; } /* }}} */ /* {{{ module start/shutdown functions */ /* {{{ _php3_sock_destroy */ -#ifndef THREAD_SAFE -static void _php3_sock_destroy(void *data) +#ifndef ZTS +static void _php3_msock_destroy(int *data) { - int *sock = (int *) data; - close(*sock); + close(*data); } #endif /* }}} */ /* {{{ php3_minit_fsock */ -static int php3_minit_fsock(INIT_FUNC_ARGS) +int php3_minit_fsock(INIT_FUNC_ARGS) { -#ifndef THREAD_SAFE +#ifndef ZTS _php3_hash_init(&ht_keys, 0, NULL, NULL, 1); - _php3_hash_init(&ht_socks, 0, NULL, _php3_sock_destroy, 1); + _php3_hash_init(&ht_socks, 0, NULL, (void (*)(void *))_php3_msock_destroy, 1); #endif return SUCCESS; } /* }}} */ /* {{{ php3_mshutdown_fsock */ -static int php3_mshutdown_fsock(SHUTDOWN_FUNC_ARGS) +int php3_mshutdown_fsock(SHUTDOWN_FUNC_ARGS) { -#ifndef THREAD_SAFE +#ifndef ZTS _php3_hash_destroy(&ht_socks); _php3_hash_destroy(&ht_keys); #endif + php_cleanup_sockbuf(1); return SUCCESS; } /* }}} */ /* {{{ php3_rshutdown_fsock() */ -static int php3_rshutdown_fsock(SHUTDOWN_FUNC_ARGS) +int php3_rshutdown_fsock(SHUTDOWN_FUNC_ARGS) { - struct php3i_sockbuf *sockbuf = phpsockbuf, *this; - - while (sockbuf) { - this = sockbuf; - sockbuf = this->next; - efree(this->readbuf); - efree(this); - } - phpsockbuf = NULL; + php_cleanup_sockbuf(0); return SUCCESS; } diff --git a/ext/standard/fsock.h b/ext/standard/fsock.h index a4a01b1bf9..b788bf7f17 100644 --- a/ext/standard/fsock.h +++ b/ext/standard/fsock.h @@ -33,28 +33,36 @@ #define _FSOCK_H #if WIN32|WINNT -# ifndef WINNT -# define WINNT 1 -# endif -#undef FD_SETSIZE -#include "arpa/inet.h" +# ifndef WINNT +# define WINNT 1 +# endif +# undef FD_SETSIZE +# include "arpa/inet.h" #endif -#if HAVE_NETINET_IN_H -#include +#ifdef HAVE_NETINET_IN_H +# include #endif extern php3_module_entry fsock_module_entry; -#define fsock_module_ptr &fsock_module_entry +#define phpext_fsock_ptr &fsock_module_entry PHP_FUNCTION(fsockopen); PHP_FUNCTION(pfsockopen); 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 char *_php3_sock_fgets(char *buf, size_t maxlen, int socket); +extern size_t _php3_sock_fread(char *buf, size_t maxlen, int socket); +extern int _php3_sock_feof(int socket); +extern int _php3_sock_fgetc(int socket); extern int _php3_is_persistent_sock(int); -int _php3_sock_eof(int socket); +extern int _php3_sock_set_blocking(int socket, int mode); +extern int _php3_sock_destroy(int socket); +extern int _php3_sock_close(int socket); -#define phpext_fsock_ptr fsock_module_ptr +PHPAPI int connect_nonb(int sockfd, struct sockaddr *addr, int addrlen, struct timeval *timeout); + +int php3_minit_fsock(INIT_FUNC_ARGS); +int php3_mshutdown_fsock(SHUTDOWN_FUNC_ARGS); +int php3_rshutdown_fsock(SHUTDOWN_FUNC_ARGS); #endif /* _FSOCK_H */ diff --git a/ext/standard/microtime.c b/ext/standard/microtime.c index 7dd3e9b66c..f2a0f9c542 100644 --- a/ext/standard/microtime.c +++ b/ext/standard/microtime.c @@ -41,7 +41,7 @@ #include "snprintf.h" #include -#if HAVE_GETTIMEOFDAY +#ifdef HAVE_GETTIMEOFDAY #if MSVC5 #include "win32/time.h" #else @@ -56,7 +56,7 @@ Returns a string containing the current time in seconds and microseconds */ PHP_FUNCTION(microtime) { -#if HAVE_GETTIMEOFDAY +#ifdef HAVE_GETTIMEOFDAY struct timeval tp; long sec = 0L; double msec = 0.0; @@ -77,7 +77,7 @@ PHP_FUNCTION(microtime) returns the current time as array */ PHP_FUNCTION(gettimeofday) { -#if HAVE_GETTIMEOFDAY +#ifdef HAVE_GETTIMEOFDAY struct timeval tp; struct timezone tz; diff --git a/ext/standard/php3_string.h b/ext/standard/php3_string.h index 221c8e72d7..01b50b07da 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,1998 PHP Development Team (See Credits file) | + | Copyright (c) 1997-1999 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: | @@ -31,6 +31,8 @@ /* $Id$ */ +/* Synced with php3 revision 1.43 1999-06-16 [ssb] */ + #ifndef _PHPSTRING_H #define _PHPSTRING_H @@ -67,26 +69,34 @@ PHP_FUNCTION(ucwords); PHP_FUNCTION(strtr); PHP_FUNCTION(strrev); PHP_FUNCTION(hebrev); -PHP_FUNCTION(hebrev_with_conversion); +PHP_FUNCTION(hebrevc); PHP_FUNCTION(user_sprintf); PHP_FUNCTION(user_printf); PHP_FUNCTION(addslashes); PHP_FUNCTION(stripslashes); PHP_FUNCTION(chr); PHP_FUNCTION(ord); -PHP_FUNCTION(newline_to_br); +PHP_FUNCTION(nl2br); PHP_FUNCTION(setlocale); PHP_FUNCTION(stristr); PHP_FUNCTION(chunk_split); PHP_FUNCTION(parsestr); PHP_FUNCTION(bin2hex); +PHP_FUNCTION(similar_text); extern PHPAPI char *_php3_strtoupper(char *s); extern PHPAPI char *_php3_strtolower(char *s); -extern char *_StrTr(char *string, char *str_from, char *str_to); +extern PHPAPI char *_php3_strtr(char *string, int len, char *str_from, char *str_to, int trlen); 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, int mode); +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 bfc66735a9..1a5aecd3de 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,1998 PHP Development Team (See Credits file) | + | Copyright (c) 1997-1999 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,21 +24,22 @@ | contact core@php.net. | +----------------------------------------------------------------------+ | Authors: Rasmus Lerdorf | - | Stig Sæther Bakken | + | Stig Sæther Bakken | | Zeev Suraski | +----------------------------------------------------------------------+ */ - /* $Id$ */ +/* Synced with php3 revision 1.193 1999-06-16 [ssb] */ + #include #include "php.h" #include "reg.h" #include "post.h" #include "php3_string.h" -#if HAVE_SETLOCALE -#include +#ifdef HAVE_LOCALE_H +# include #endif #include "zend_execute.h" #include "php_globals.h" @@ -128,7 +129,7 @@ PHP_FUNCTION(strcasecmp) } convert_to_string(s1); convert_to_string(s2); - RETURN_LONG(strcasecmp(s1->value.str.val,s2->value.str.val)); + RETURN_LONG(zend_binary_strcasecmp(s1, s2)); } /* }}} */ @@ -162,12 +163,51 @@ PHP_FUNCTION(strcspn) } /* }}} */ +PHPAPI void _php3_trim(pval *str, pval * return_value, int mode) +/* mode 1 : trim left + mode 2 : trim right + mode 3 : trim left and right +*/ +{ + register int i; + int len = str->value.str.len; + int trimmed = 0; + char *c = str->value.str.val; + + if (mode & 1) { + 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; + } + if (mode & 2) { + 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 rtrim(string str) + An alias for chop */ +/* }}} */ + /* {{{ proto string chop(string str) Remove trailing whitespace */ PHP_FUNCTION(chop) { pval *str; - register int i; if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &str) == FAILURE) { WRONG_PARAM_COUNT; @@ -175,17 +215,7 @@ PHP_FUNCTION(chop) convert_to_string(str); if (str->type == IS_STRING) { - int len = str->value.str.len; - char *c = str->value.str.val; - 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); + _php3_trim(str, return_value, 2); return; } RETURN_FALSE; @@ -197,7 +227,6 @@ PHP_FUNCTION(chop) PHP_FUNCTION(trim) { pval *str; - register int i; if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &str) == FAILURE) { WRONG_PARAM_COUNT; @@ -205,28 +234,7 @@ PHP_FUNCTION(trim) convert_to_string(str); if (str->type == IS_STRING) { - 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); + _php3_trim(str, return_value, 3); return; } RETURN_FALSE; @@ -238,54 +246,24 @@ PHP_FUNCTION(trim) PHP_FUNCTION(ltrim) { pval *str; - 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) { - 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); + _php3_trim(str, return_value, 1); return; } RETURN_FALSE; } /* }}} */ -/* {{{ proto array(string separator, string str) - Split a string on string separator and return array of components */ -PHP_FUNCTION(explode) +void _php3_explode(pval *delim, pval *str, pval *return_value) { - 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) { @@ -300,38 +278,46 @@ PHP_FUNCTION(explode) } efree(work_str); } -/* }}} */ -/* {{{ proto string implode(array src, string glue) - Join array elements placing glue string between items and return one string */ -PHP_FUNCTION(implode) +/* {{{ proto array explode(string separator, string str) + Split a string on string separator and return array of components */ +PHP_FUNCTION(explode) { - pval *arg1, *arg2, *delim, **tmp, *arr; - int len = 0, count = 0; - - if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &arg1, &arg2) == FAILURE) { + pval *str, *delim; + + if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &delim, &str) == FAILURE) { WRONG_PARAM_COUNT; } + convert_to_string(str); + convert_to_string(delim); - 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()); + 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; } + _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; /* 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) { - len += (*tmp)->value.str.len; + convert_to_string(tmp); + if (tmp->type == IS_STRING && tmp->value.str.val != undefined_variable_string) { + len += tmp->value.str.len; if (count>0) { len += delim->value.str.len; } @@ -346,9 +332,9 @@ PHP_FUNCTION(implode) 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) { + if (tmp->type == IS_STRING && tmp->value.str.val != undefined_variable_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); } @@ -356,12 +342,37 @@ PHP_FUNCTION(implode) _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 */ +PHP_FUNCTION(implode) +{ + 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 @@ -559,7 +570,7 @@ PHP_FUNCTION(dirname) /* }}} */ -/* case-insensitve strstr */ +/* case insensitve strstr */ PHPAPI char *php3i_stristr(unsigned char *s, unsigned char *t) { int i, j, k, l; @@ -635,7 +646,7 @@ PHP_FUNCTION(strstr) } /* }}} */ -/* {{{ proto int strpos(string haystack, string needle) +/* {{{ proto int strpos(string haystack, string needle [, int offset]) Find position of first occurrence of a string within another */ PHP_FUNCTION(strpos) { @@ -742,7 +753,8 @@ PHP_FUNCTION(strrchr) /* }}} */ static char * -_php3_chunk_split(char *src, int srclen, char *end, int endlen, int chunklen) +_php3_chunk_split(char *src, int srclen, char *end, int endlen, + int chunklen, int *destlen) { char *dest; char *p, *q; @@ -770,6 +782,9 @@ _php3_chunk_split(char *src, int srclen, char *end, int endlen, int chunklen) } *q = '\0'; + if (destlen) { + *destlen = q - dest; + } return(dest); } @@ -784,16 +799,15 @@ PHP_FUNCTION(chunk_split) char *end = "\r\n"; int endlen = 2; int chunklen = 76; + int result_len; argc = ARG_COUNT(ht); - 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))) { + if (argc < 1 || argc > 3 || + getParameters(ht, argc, &p_str, &p_chunklen, &p_ending) == FAILURE) { WRONG_PARAM_COUNT; } - + switch(argc) { case 3: convert_to_string(p_ending); @@ -812,10 +826,10 @@ PHP_FUNCTION(chunk_split) } result = _php3_chunk_split(p_str->value.str.val, p_str->value.str.len, - end, endlen, chunklen); + end, endlen, chunklen, &result_len); if(result) { - RETVAL_STRING(result, 0); + RETVAL_STRINGL(result, result_len, 0); } else { RETURN_FALSE; } @@ -997,20 +1011,42 @@ PHP_FUNCTION(ucwords) if(*(r+1)){ r++; *r=toupper((unsigned char)*r); - } else break; + } else { + break; + } } RETVAL_STRING(arg->value.str.val,1); } /* }}} */ +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 */ PHP_FUNCTION(strtr) { /* strtr(STRING,FROM,TO) */ pval *str, *from, *to; - 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) { @@ -1020,28 +1056,12 @@ PHP_FUNCTION(strtr) convert_to_string(from); convert_to_string(to); - 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); + 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); } /* }}} */ @@ -1073,6 +1093,82 @@ PHP_FUNCTION(strrev) } /* }}} */ +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 */ +PHP_FUNCTION(similar_text) +{ + 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) @@ -1223,7 +1319,7 @@ PHPAPI char *_php3_addslashes(char *str, int length, int *new_length, int should #define _isblank(c) (((((unsigned char) c)==' ' || ((unsigned char) c)=='\t')) ? 1 : 0) #define _isnewline(c) (((((unsigned char) c)=='\n' || ((unsigned char) c)=='\r')) ? 1 : 0) -static void _php3_char_to_str(char *str,uint len,char from,char *to,int to_len,pval *result) +PHPAPI void _php3_char_to_str(char *str,uint len,char from,char *to,int to_len,pval *result) { int char_count=0; char *source,*target,*tmp,*source_end=str+len, *tmp_end=NULL; @@ -1259,6 +1355,7 @@ static void _php3_char_to_str(char *str,uint len,char from,char *to,int to_len,p *target = 0; } +#if 0 /* * this is a binary safe equivalent to strnstr * note that we don't check for the end in str_to_str but here @@ -1328,6 +1425,56 @@ 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 */ PHP_FUNCTION(str_replace) @@ -1343,7 +1490,19 @@ PHP_FUNCTION(str_replace) convert_to_string(haystack); convert_to_string(needle); - 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); + 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); return; } @@ -1353,9 +1512,8 @@ PHP_FUNCTION(str_replace) } 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); + needle->value.str.val, needle->value.str.len, + str->value.str.val, str->value.str.len, &len); RETURN_STRINGL(new, len, 0); } /* }}} */ @@ -1535,9 +1693,9 @@ PHP_FUNCTION(hebrev) } /* }}} */ -/* {{{ proto string hebrev(string str [, int max_chars_per_line]) +/* {{{ proto string hebrevc(string str [, int max_chars_per_line]) Convert logical Hebrew text to visual text with newline conversion */ -PHP_FUNCTION(hebrev_with_conversion) +PHP_FUNCTION(hebrevc) { _php3_hebrev(INTERNAL_FUNCTION_PARAM_PASSTHRU,1); } @@ -1545,7 +1703,7 @@ PHP_FUNCTION(hebrev_with_conversion) /* {{{ proto string nl2br(string str) Converts newlines to HTML line breaks */ -PHP_FUNCTION(newline_to_br) +PHP_FUNCTION(nl2br) { pval *str; @@ -1559,6 +1717,23 @@ PHP_FUNCTION(newline_to_br) } /* }}} */ +/* {{{ proto string strip_tags(string str) + Strips HTML and PHP tags from a string */ +PHP_FUNCTION(strip_tags) +{ + 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 */ PHP_FUNCTION(setlocale) @@ -1569,7 +1744,7 @@ PHP_FUNCTION(setlocale) if (ARG_COUNT(ht)!=2 || getParameters(ht, 2, &category, &locale)==FAILURE) WRONG_PARAM_COUNT; -#if HAVE_SETLOCALE +#ifdef HAVE_SETLOCALE convert_to_string(category); convert_to_string(locale); if (!strcasecmp ("LC_ALL", category->value.str.val)) @@ -1618,6 +1793,103 @@ PHP_FUNCTION(parsestr) } php3_treat_data(PARSE_STRING, res); } +/* }}} */ + +/* 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); +} /* * Local variables: diff --git a/main/config.w32.h b/main/config.w32.h index ba1827b102..97003d6576 100644 --- a/main/config.w32.h +++ b/main/config.w32.h @@ -60,7 +60,7 @@ ---------------------------------------------------------------*/ /* Define if you have the link function. */ -#define HAVE_LINK 0 +#undef HAVE_LINK /* Define if you have the lockf function. */ /* #undef HAVE_LOCKF */ @@ -72,10 +72,10 @@ /* #undef HAVE_SRAND48 */ /* Define if you have the symlink function. */ -#define HAVE_SYMLINK 0 +#undef HAVE_SYMLINK /* Define if you have the usleep function. */ -#define HAVE_USLEEP 1 +#undef HAVE_USLEEP #define NEED_ISBLANK 1 /* ---------------------------------------------------------------- @@ -96,7 +96,7 @@ ---------------------------------------------------------------*/ #define DISCARD_PATH 1 -#define HAVE_SETITIMER 0 +#undef HAVE_SETITIMER #define HAVE_IODBC 0 /*getting rid of old odbc*/ #define HAVE_UODBC 0 #define HAVE_LIBDL 1 @@ -107,7 +107,7 @@ #define HAVE_TZSET 1 /* Define if you have the flock function. */ -#define HAVE_FLOCK 0 +#undef HAVE_FLOCK /* Define if using alloca.c. */ /* #undef C_ALLOCA */ @@ -126,7 +126,7 @@ /* #undef HAVE_ALLOCA_H */ /* Define if you have */ -#define HAVE_SYS_TIME_H 0 +#undef HAVE_SYS_TIME_H /* Define if you have */ #define HAVE_SIGNAL_H 1 @@ -135,10 +135,10 @@ /* #undef HAVE_DOPRNT */ /* Define if your struct stat has st_blksize. */ -#define HAVE_ST_BLKSIZE 0 +#undef HAVE_ST_BLKSIZE /* Define if your struct stat has st_blocks. */ -#define HAVE_ST_BLOCKS 0 +#undef HAVE_ST_BLOCKS /* Define if your struct stat has st_rdev. */ #define HAVE_ST_RDEV 1 @@ -228,7 +228,7 @@ /* #undef HAVE_CRYPT_H */ /* Define if you have the header file. */ -#define HAVE_DIRENT_H 0 +#undef HAVE_DIRENT_H /* Define if you have the header file. */ #define HAVE_FCNTL_H 1 diff --git a/main/fopen_wrappers.c b/main/fopen_wrappers.c index 38d410018b..ae7b52afde 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,1998 PHP Development Team (See Credits file) | + | Copyright (c) 1997-1999 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: | @@ -29,6 +29,8 @@ */ /* $Id$ */ +/* Synced with php3 revision 1.62 1999-06-16 [ssb] */ + #include "php.h" #include "php_globals.h" #include "SAPI.h" @@ -98,80 +100,94 @@ int _php3_getftpresult(int socketd); When open_basedir is NULL, always return 0 */ -PHPAPI int _php3_check_open_basedir(char *path) +PHPAPI int _php3_check_specific_open_basedir(char *basedir, char *path) { char resolved_name[MAXPATHLEN]; + char resolved_basedir[MAXPATHLEN]; char local_open_basedir[MAXPATHLEN]; int local_open_basedir_pos; PLS_FETCH(); - /* 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 + /* Special case basedir==".": Use script-directory */ + if ((strcmp(PG(open_basedir), ".") == 0) && + SG(request_info).path_translated && + *SG(request_info).path_translated ) { - strcpy(local_open_basedir, request_info.filename); - local_open_basedir_pos = strlen(local_open_basedir) - 1; + strcpy(local_open_basedir, SG(request_info).path_translated); + local_open_basedir_pos = strlen(local_open_basedir) - 1; - /* Strip filename */ - while (( + /* Strip filename */ + while (( #if WIN32|WINNT - (local_open_basedir[local_open_basedir_pos] != '\\') || + (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] != '/') + ) && + (local_open_basedir_pos >= 0) ) { - local_open_basedir[local_open_basedir_pos--] = 0; - } - -#if 0 - /* Strip double (back)slashes */ - if (local_open_basedir_pos > 0) { - while (( + local_open_basedir[local_open_basedir_pos--] = 0; + } + } 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 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; - } - } + if (strncasecmp(resolved_basedir, resolved_name, strlen(resolved_basedir)) == 0) { +#else + if (strncmp(resolved_basedir, resolved_name, strlen(resolved_basedir)) == 0) { #endif - + /* File is in the right directory */ + return 0; } else { - /* Else use the unmodified path */ - strcpy(local_open_basedir, PG(open_basedir)); + return -1; } - - /* Resolve the real path into resolved_name */ - if (_php3_realpath(path, resolved_name) != NULL) { - /* Check the path */ + } 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) { #if WIN32|WINNT - if (strncasecmp(local_open_basedir, resolved_name, strlen(local_open_basedir)) == 0) { + end = strchr(ptr, ';'); #else - if (strncmp(local_open_basedir, resolved_name, strlen(local_open_basedir)) == 0) { + end = strchr(ptr, ':'); #endif - /* File is in the right directory */ + if (end != NULL) { + *end = '\0'; + end++; + } + + if (_php3_check_specific_open_basedir(ptr, path) == 0) { + efree(pathbuf); 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; + + ptr = end; } - } else { - /* open_basedir is not available, return 0 */ - return 0; + php3_error(E_WARNING, "open_basedir restriction in effect. File is in wrong directory."); + efree(pathbuf); + return -1; } + + /* Nothing to check... */ + return 0; } PHPAPI FILE *php3_fopen_wrapper(char *path, char *mode, int options, int *issock, int *socketd) @@ -179,6 +195,8 @@ PHPAPI FILE *php3_fopen_wrapper(char *path, char *mode, int options, int *issock int cm=2; /* checkuid mode: 2 = if file does not exist, check directory */ PLS_FETCH(); + /* FIXME Lets not get in the habit of doing stuff like this. This should + be runtime enabled, NOT compile time. */ #if PHP3_URL_FOPEN if (!(options & IGNORE_URL)) { return php3_fopen_url_wrapper(path, mode, options, issock, socketd); @@ -208,7 +226,7 @@ PHPAPI FILE *php3_fopen_for_parser(void) PLS_FETCH(); SLS_FETCH(); - fn = request_info.filename; + fn = SG(request_info).path_translated; path_info = SG(request_info).request_uri; #if HAVE_PWD_H if (PG(user_dir) && *PG(user_dir) @@ -236,8 +254,8 @@ PHPAPI FILE *php3_fopen_for_parser(void) strcat(fn, PG(user_dir)); /* safe */ strcat(fn, "/"); /* safe */ strcat(fn, s + 1); /* safe (shorter than path_info) */ - STR_FREE(request_info.filename); - request_info.filename = fn; + STR_FREE(SG(request_info).path_translated); + SG(request_info).path_translated = fn; } } } @@ -259,17 +277,17 @@ PHPAPI FILE *php3_fopen_for_parser(void) if ('/' == path_info[0]) l--; strcpy(fn + l, path_info); - STR_FREE(request_info.filename); - request_info.filename = fn; + STR_FREE(SG(request_info).path_translated); + SG(request_info).path_translated = fn; } } /* if doc_root && path_info */ if (!fn) { - /* we have to free request_info.filename here because + /* we have to free SG(request_info).path_translated 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(request_info.filename); - request_info.filename = NULL; + STR_FREE(SG(request_info).path_translated); + SG(request_info).path_translated = NULL; return NULL; } fp = fopen(fn, "r"); @@ -281,7 +299,7 @@ PHPAPI FILE *php3_fopen_for_parser(void) } if (!fp) { php3_error(E_CORE_ERROR, "Unable to open %s", fn); - STR_FREE(request_info.filename); /* for same reason as above */ + STR_FREE(SG(request_info).path_translated); /* for same reason as above */ return NULL; } @@ -443,7 +461,6 @@ static FILE *php3_fopen_url_wrapper(const char *path, char *mode, int options, i FILE *fp = NULL; struct sockaddr_in server; unsigned short portno; - char winfeof; if (!strncasecmp(path, "http://", 7)) { resource = url_parse((char *) path); @@ -463,16 +480,15 @@ static FILE *php3_fopen_url_wrapper(const char *path, char *mode, int options, i free_url(resource); return NULL; } - lookup_hostname(resource->host, &server.sin_addr); + server.sin_family = AF_INET; - if (server.sin_addr.s_addr == -1) { + if (lookup_hostname(resource->host, &server.sin_addr)) { 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); @@ -554,8 +570,8 @@ static FILE *php3_fopen_url_wrapper(const char *path, char *mode, int options, i /* 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) { + while (!body && !SOCK_FEOF(*socketd)) { + if ((buf[0] = SOCK_FGETC(*socketd)) == EOF) { SOCK_FCLOSE(*socketd); *socketd = 0; free_url(resource); @@ -629,9 +645,9 @@ static FILE *php3_fopen_url_wrapper(const char *path, char *mode, int options, i free_url(resource); return NULL; } - lookup_hostname(resource->host, &server.sin_addr); + server.sin_family = AF_INET; - if (server.sin_addr.s_addr == -1) { + if (lookup_hostname(resource->host, &server.sin_addr)) { SOCK_FCLOSE(*socketd); *socketd = 0; free_url(resource); @@ -712,6 +728,16 @@ static FILE *php3_fopen_url_wrapper(const char *path, char *mode, int options, i 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; + } + /* find out the size of the file (verifying it exists) */ SOCK_WRITE("SIZE ", *socketd); SOCK_WRITE(resource->path, *socketd); @@ -741,15 +767,6 @@ static FILE *php3_fopen_url_wrapper(const char *path, char *mode, int options, i } } - /* 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) && @@ -841,9 +858,9 @@ static FILE *php3_fopen_url_wrapper(const char *path, char *mode, int options, i free_url(resource); return NULL; } - lookup_hostname(resource->host, &server.sin_addr); + server.sin_family = AF_INET; - if (server.sin_addr.s_addr == -1) { + if (lookup_hostname(resource->host, &server.sin_addr)) { free_url(resource); SOCK_FCLOSE(*socketd); *socketd = 0; diff --git a/main/fopen_wrappers.h b/main/fopen_wrappers.h index c1e1420b3c..c5c69db70f 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,1998 PHP Development Team (See Credits file) | + | Copyright (c) 1997-1999 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: | @@ -28,6 +28,8 @@ */ /* $Id$ */ +/* Synced with php3 revision 1.25 1999-06-16 [ssb] */ + #ifndef _FOPEN_WRAPPERS_H #define _FOPEN_WRAPPERS_H @@ -46,17 +48,27 @@ # 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_FGETC(s) _php3_sock_fgetc((s)) #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) + +#define FP_FGETS(buf,len,sock,fp,issock) \ + ((issock)?SOCK_FGETS(buf,len,sock):fgets(buf,len,fp)) +#define FP_FREAD(buf,len,sock,fp,issock) \ + ((issock)?SOCK_FREAD(buf,len,sock):fread(buf,1,len,fp)) +#define FP_FEOF(sock,fp,issock) \ + ((issock)?SOCK_FEOF(sock):feof(fp)) +#define FP_FGETC(sock,fp,issock) \ + ((issock)?SOCK_FGETC(sock):fgetc(fp)) /* values for issock */ #define IS_NOT_SOCKET 0 @@ -72,12 +84,12 @@ extern PHPAPI FILE *php3_fopen_wrapper(char *filename, char *mode, int options, 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); diff --git a/main/main.c b/main/main.c index d7aa597033..ecedb01693 100644 --- a/main/main.c +++ b/main/main.c @@ -465,7 +465,7 @@ PHPAPI void php3_error(int type, const char *format,...) -#if HAVE_SETITIMER +#ifdef HAVE_SETITIMER static void php3_timeout(int dummy) { PLS_FETCH(); @@ -483,7 +483,7 @@ static void php3_set_timeout(long seconds) { #if WIN32|WINNT #else -# if HAVE_SETITIMER +# ifdef HAVE_SETITIMER struct itimerval t_r; /* timeout requested */ t_r.it_value.tv_sec = seconds; @@ -500,7 +500,7 @@ static void php3_unset_timeout() { #if WIN32|WINNT #else -# if HAVE_SETITIMER +# ifdef 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; diff --git a/win32/time.c b/win32/time.c index ea0e2d1acb..c1089283e3 100644 --- a/win32/time.c +++ b/win32/time.c @@ -70,7 +70,7 @@ void usleep(unsigned int useconds) } -#if HAVE_SETITIMER +#ifdef HAVE_SETITIMER #ifndef THREAD_SAFE