diff options
Diffstat (limited to 'ext/zlib/zlib.c')
| -rw-r--r-- | ext/zlib/zlib.c | 926 |
1 files changed, 926 insertions, 0 deletions
diff --git a/ext/zlib/zlib.c b/ext/zlib/zlib.c new file mode 100644 index 0000000000..e8f80c4450 --- /dev/null +++ b/ext/zlib/zlib.c @@ -0,0 +1,926 @@ +/* + +----------------------------------------------------------------------+ + | PHP HTML Embedded Scripting Language Version 3.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997,1998 PHP Development Team (See Credits file) | + +----------------------------------------------------------------------+ + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by | + | the Free Software Foundation; either version 2 of the License, or | + | (at your option) any later version. | + | | + | This program is distributed in the hope that it will be useful, | + | but WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | + | GNU General Public License for more details. | + | | + | You should have received a copy of the GNU General Public License | + | along with this program; if not, write to the Free Software | + | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | + +----------------------------------------------------------------------+ + | Authors: Rasmus Lerdorf <rasmus@lerdorf.on.ca> | + | Stefan Röhrich <sr@linux.de> | + +----------------------------------------------------------------------+ + */ +/* $Id$ */ +#if !PHP_31 && defined(THREAD_SAFE) +#undef THREAD_SAFE +#endif +#define IS_EXT_MODULE + +#ifdef THREAD_SAFE +#include "tls.h" +#endif +#include "php.h" + +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#if (WIN32|WINNT) +#include <windows.h> +#include <winsock.h> +#define O_RDONLY _O_RDONLY +#if PHP_31 +#include "os/nt/param.h" +#else +#include "win32/param.h" +#endif +#else +#include <sys/param.h> +/* #include <sys/uio.h> */ +#endif +#include "ext/standard/head.h" +#include "safe_mode.h" +#include "ext/standard/php3_standard.h" +#include "php3_zlib.h" +#include "fopen-wrappers.h" +#if HAVE_PWD_H +#if WIN32|WINNT +#include "win32/pwd.h" +#else +#include <pwd.h> +#endif +#endif +#include "snprintf.h" +#if HAVE_ZLIB +#if defined(HAVE_UNISTD_H) && (WIN32|WINNT) +#undef HAVE_UNISTD_H +#endif + +#include <zlib.h> + +#if COMPILE_DL +#if PHP_31 +#include "ext/phpdl.h" +#else +#include "dl/phpdl.h" +#endif +#ifndef PUTS +#define PUTS(a) php3_printf("%s",a) +#endif +#ifndef PUTC +#define PUTC(a) PUTS(a) +#endif +#ifndef PHPWRITE +#define PHPWRITE(a,n) php3_write((a),(n)) +#endif +#endif + + + +#if defined(THREAD_SAFE) +typedef struct zlib_global_struct{ +#endif + int gzgetss_state; + int le_zp; +#if PHP_31 + int magic_quotes_runtime; + int safe_mode; + char *include_path; + char *doc_root; +#endif +#if defined(THREAD_SAFE) +}zlib_global_struct; +#endif + +#if defined(THREAD_SAFE) +DWORD ZLIBtls; +static int numthreads=0; +void *zlib_mutex; + +#define ZLIB_GLOBAL(a) zlib_globals->a + +#define ZLIB_TLS_VARS zlib_global_struct *PHP3_TLS_GET(ZLIBtls,zlib_globals); + +#else +#define ZLIB_GLOBAL(a) a +#define ZLIB_TLS_VARS +#endif + +#if PHP_31 +# define ZLIB_INI(a) ZLIB_GLOBAL(a) +#else +# define ZLIB_INI(a) php3_ini.a +#endif + +function_entry php3_zlib_functions[] = { + {"readgzfile", php3_readgzfile, NULL}, + {"gzrewind", php3_gzrewind, NULL}, + {"gzclose", php3_gzclose, NULL}, + {"gzeof", php3_gzeof, NULL}, + {"gzgetc", php3_gzgetc, NULL}, + {"gzgets", php3_gzgets, NULL}, + {"gzgetss", php3_gzgetss, NULL}, + {"gzread", php3_gzread, NULL}, + {"gzopen", php3_gzopen, NULL}, + {"gzpassthru", php3_gzpassthru, NULL}, + {"gzseek", php3_gzseek, NULL}, + {"gztell", php3_gztell, NULL}, + {"gzwrite", php3_gzwrite, NULL}, + {"gzputs", php3_gzwrite, NULL}, + {"gzfile", php3_gzfile, NULL}, + {NULL, NULL, NULL} +}; + +php3_module_entry php3_zlib_module_entry = { + "zlib", php3_zlib_functions, php3_minit_zlib, php3_mshutdown_zlib, NULL, NULL, php3_info_zlib, STANDARD_MODULE_PROPERTIES +}; + +#if defined(COMPILE_DL) +DLEXPORT php3_module_entry *get_module(void) { return &php3_zlib_module_entry; } +#endif + +int php3_minit_zlib(INIT_FUNC_ARGS) +{ +#ifdef THREAD_SAFE + zlib_global_struct *zlib_globals; + PHP3_MUTEX_ALLOC(zlib_mutex); + PHP3_MUTEX_LOCK(zlib_mutex); + numthreads++; + if (numthreads==1){ + if (!PHP3_TLS_PROC_STARTUP(ZLIBtls)){ + PHP3_MUTEX_UNLOCK(zlib_mutex); + PHP3_MUTEX_FREE(zlib_mutex); + return FAILURE; + } + } + PHP3_MUTEX_UNLOCK(zlib_mutex); + if(!PHP3_TLS_THREAD_INIT(ZLIBtls,zlib_globals,zlib_global_struct)){ + PHP3_MUTEX_FREE(zlib_mutex); + return FAILURE; + } +#endif + /* get our ini variables here */ + cfg_get_long("safe_mode",&ZLIB_INI(safe_mode)); + cfg_get_long("magic_quotes_runtime",&ZLIB_INI(magic_quotes_runtime)); + cfg_get_string("doc_root",&ZLIB_INI(doc_root)); + cfg_get_string("include_path",&ZLIB_INI(include_path)); + + ZLIB_GLOBAL(le_zp) = register_list_destructors(gzclose,NULL); + return SUCCESS; +} + +int php3_mshutdown_zlib(SHUTDOWN_FUNC_ARGS){ +#if defined(THREAD_SAFE) + ZLIB_TLS_VARS; + PHP3_TLS_THREAD_FREE(zlib_globals); + PHP3_MUTEX_LOCK(zlib_mutex); + numthreads--; + if (numthreads<1){ + PHP3_TLS_PROC_SHUTDOWN(ZLIBtls); + PHP3_MUTEX_UNLOCK(zlib_mutex); + PHP3_MUTEX_FREE(zlib_mutex); + return SUCCESS; + } + PHP3_MUTEX_UNLOCK(zlib_mutex); +#endif + return SUCCESS; +} + +void php3_info_zlib(void) +{ + PUTS("Zlib support active (compiled with "); + PUTS(ZLIB_VERSION); + PUTS(", linked with "); + PUTS((char *)zlibVersion()); + PUTS(")."); +} + +static gzFile *php3_gzopen_with_path(char *filename, char *mode, char *path, char **opened_path); + +static gzFile php3_gzopen_wrapper(char *path, char *mode, int options) +{ + ZLIB_TLS_VARS; + if (options & USE_PATH && ZLIB_INI(include_path) != NULL) { + return php3_gzopen_with_path(path, mode, ZLIB_INI(include_path), NULL); + } + else { + if (options & ENFORCE_SAFE_MODE && ZLIB_INI(safe_mode) && (!_php3_checkuid(path,1))) { + return NULL; + } + if (_php3_check_open_basedir(path)) return NULL; + return gzopen(path, mode); + } +} + +/* + * Tries to open a .gz-file with a PATH-style list of directories. + * If the filename starts with "." or "/", the path is ignored. + */ +static gzFile *php3_gzopen_with_path(char *filename, char *mode, char *path, char **opened_path) +{ + char *pathbuf, *ptr, *end; + char trypath[MAXPATHLEN + 1]; + struct stat sb; + gzFile *zp; + ZLIB_TLS_VARS; + + if (opened_path) { + *opened_path = NULL; + } + + /* Relative path open */ + if (*filename == '.') { + if (ZLIB_INI(safe_mode) &&(!_php3_checkuid(filename,2))) { + return(NULL); + } + if (_php3_check_open_basedir(filename)) return NULL; + zp = gzopen(filename, mode); + if (zp && opened_path) { + *opened_path = expand_filepath(filename); + } + return zp; + } + + /* Absolute path open - prepend document_root in safe mode */ +#if WIN32|WINNT + if ((*filename == '\\')||(*filename == '/')||(filename[1] == ':')) { +#else + if (*filename == '/') { +#endif + if (ZLIB_INI(safe_mode)) { + snprintf(trypath,MAXPATHLEN,"%s%s",ZLIB_INI(doc_root),filename); + if (!_php3_checkuid(trypath,2)) { + return(NULL); + } + if (_php3_check_open_basedir(trypath)) return NULL; + zp = gzopen(trypath, mode); + if (zp && opened_path) { + *opened_path = expand_filepath(trypath); + } + return zp; + } else { + if (_php3_check_open_basedir(filename)) return NULL; + return gzopen(filename, mode); + } + } + + if (!path || (path && !*path)) { + if (ZLIB_INI(safe_mode) &&(!_php3_checkuid(filename,2))) { + return(NULL); + } + if (_php3_check_open_basedir(filename)) return NULL; + zp = gzopen(filename, mode); + if (zp && opened_path) { + *opened_path = strdup(filename); + } + return zp; + } + + pathbuf = estrdup(path); + + ptr = pathbuf; + + while (ptr && *ptr) { +#if WIN32|WINNT + end = strchr(ptr, ';'); +#else + end = strchr(ptr, ':'); +#endif + if (end != NULL) { + *end = '\0'; + end++; + } + snprintf(trypath, MAXPATHLEN, "%s/%s", ptr, filename); + if (ZLIB_INI(safe_mode)) { + if (stat(trypath,&sb) == 0 &&(!_php3_checkuid(trypath,2))) { + efree(pathbuf); + return(NULL); + } + } + if ((zp = gzopen(trypath, mode)) != NULL) { + if (_php3_check_open_basedir(trypath)) { + gzclose(zp); + efree(pathbuf); + return NULL; + } + if (opened_path) { + *opened_path = expand_filepath(trypath); + } + efree(pathbuf); + return zp; + } + ptr = end; + } + efree(pathbuf); + return NULL; +} + +/* {{{ proto array gzfile(string filename) +Read und uncompress entire .gz-file into an array */ +void php3_gzfile(INTERNAL_FUNCTION_PARAMETERS) { + pval *filename, *arg2; + gzFile zp; + char *slashed, buf[8192]; + register int i=0; + int use_include_path = 0; + ZLIB_TLS_VARS; + + /* 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) { + WRONG_PARAM_COUNT; + } + convert_to_long(arg2); + use_include_path = arg2->value.lval; + break; + default: + WRONG_PARAM_COUNT; + } + convert_to_string(filename); + + zp = php3_gzopen_wrapper(filename->value.str.val,"r", use_include_path|ENFORCE_SAFE_MODE); + if (!zp) { + php3_error(E_WARNING,"gzFile(\"%s\") - %s",filename->value.str.val,strerror(errno)); + RETURN_FALSE; + } + + /* Initialize return array */ + if (array_init(return_value) == FAILURE) { + RETURN_FALSE; + } + + /* Now loop through the file and do the magic quotes thing if needed */ + memset(buf,0,8191); + while((int)gzgets(zp, buf, 8191)) { + if (ZLIB_INI(magic_quotes_runtime)) { + int len; + + slashed = _php3_addslashes(buf,0,&len,0); /* 0 = don't free source string */ + add_index_stringl(return_value, i++, slashed, len, 0); + } else { + add_index_string(return_value, i++, buf, 1); + } + } + gzclose(zp); +} +/* }}} */ + +/* {{{ proto int gzopen(string filename, string mode [, int use_include_path]) +Open a .gz-file and return a .gz-file pointer */ +void php3_gzopen(INTERNAL_FUNCTION_PARAMETERS) { + pval *arg1, *arg2, *arg3; + gzFile *zp; + char *p; + int id; + int use_include_path = 0; + ZLIB_TLS_VARS; + + 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) { + 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); + p = estrndup(arg2->value.str.val,arg2->value.str.len); + + /* + * We need a better way of returning error messages from + * php3_gzopen_wrapper(). + */ + zp = php3_gzopen_wrapper(arg1->value.str.val, p, use_include_path|ENFORCE_SAFE_MODE); + if (!zp) { + php3_error(E_WARNING,"gzopen(\"%s\",\"%s\") - %s", + arg1->value.str.val, p, strerror(errno)); + efree(p); + RETURN_FALSE; + } + ZLIB_GLOBAL(gzgetss_state)=0; + id = php3_list_insert(zp,ZLIB_GLOBAL(le_zp)); + efree(p); + RETURN_LONG(id); +} +/* }}} */ + +/* {{{ proto int gzclose(int zp) +Close an open .gz-file pointer */ +void php3_gzclose(INTERNAL_FUNCTION_PARAMETERS) { + pval *arg1; + int id, type; + gzFile *zp; + ZLIB_TLS_VARS; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg1) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_long(arg1); + id=arg1->value.lval; + zp = php3_list_find(id,&type); + if (!zp || (type!=ZLIB_GLOBAL(le_zp))) { + php3_error(E_WARNING,"Unable to find gz-file identifier %d",id); + RETURN_FALSE; + } + php3_list_delete(id); + RETURN_TRUE; +} +/* }}} */ + +/* {{{ proto int gzeof(int zp) +Test for end-of-file on a .gz-file pointer */ +void php3_gzeof(INTERNAL_FUNCTION_PARAMETERS) { + pval *arg1; + gzFile *zp; + int id, type; + ZLIB_TLS_VARS; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg1) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_long(arg1); + id = arg1->value.lval; + zp = php3_list_find(id,&type); + if ((!zp || (type!=ZLIB_GLOBAL(le_zp)))) { + php3_error(E_WARNING,"Unable to find gz-file identifier %d",id); + /* we're at the eof if the file doesn't exist */ + RETURN_TRUE; + } + if ((gzeof(zp))) { + RETURN_TRUE; + } else { + RETURN_FALSE; + } +} +/* }}} */ + +/* {{{ proto string gzgets(int zp, int length) +Get a line from .gz-file pointer */ +void php3_gzgets(INTERNAL_FUNCTION_PARAMETERS) { + pval *arg1, *arg2; + gzFile *zp; + int id, len, type; + char *buf; + ZLIB_TLS_VARS; + + if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &arg1, &arg2) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_long(arg1); + convert_to_long(arg2); + id = arg1->value.lval; + len = arg2->value.lval; + + zp = php3_list_find(id,&type); + if (!zp || (type!=ZLIB_GLOBAL(le_zp))) { + php3_error(E_WARNING,"Unable to find gz-file identifier %d",id); + RETURN_FALSE; + } + buf = emalloc(sizeof(char) * (len + 1)); + /* needed because recv doesnt put a null at the end*/ + memset(buf,0,len+1); + if (!((int)gzgets(zp, buf, len))) { + efree(buf); + RETVAL_FALSE; + } else { + if (ZLIB_INI(magic_quotes_runtime)) { + return_value->value.str.val = _php3_addslashes(buf,0,&return_value->value.str.len,1); + } else { + return_value->value.str.val = buf; + return_value->value.str.len = strlen(return_value->value.str.val); + } + return_value->type = IS_STRING; + } + return; +} +/* }}} */ + +/* {{{ proto string gzgetc(int zp) +Get a character from .gz-file pointer */ +void php3_gzgetc(INTERNAL_FUNCTION_PARAMETERS) { + pval *arg1; + gzFile *zp; + int id, type, c; + char *buf; + ZLIB_TLS_VARS; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg1) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_long(arg1); + id = arg1->value.lval; + + zp = php3_list_find(id,&type); + if (!zp || (type!=ZLIB_GLOBAL(le_zp))) { + php3_error(E_WARNING,"Unable to find gz-file identifier %d",id); + RETURN_FALSE; + } + buf = emalloc(sizeof(char) * 2); + if ((c=gzgetc(zp)) == (-1)) { + efree(buf); + RETVAL_FALSE; + } else { + buf[0]=(char)c; + buf[1]='\0'; + return_value->value.str.val = buf; + return_value->value.str.len = 1; + return_value->type = IS_STRING; + } + return; +} +/* }}} */ + +/* Strip any HTML tags while reading */ +/* {{{ proto string gzgetss(int zp, int length) +Get a line from file pointer and strip HTML tags */ +void php3_gzgetss(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *fd, *bytes; + gzFile *zp; + int id, len, br, type; + char *buf, *p, *rbuf, *rp, c, lc; + ZLIB_TLS_VARS; + + if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &fd, &bytes) == FAILURE) { + WRONG_PARAM_COUNT; + } + + convert_to_long(fd); + convert_to_long(bytes); + + id = fd->value.lval; + len = bytes->value.lval; + + zp = php3_list_find(id,&type); + if (!zp || (type!=ZLIB_GLOBAL(le_zp))) { + php3_error(E_WARNING, "Unable to find gz-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 (!((int)gzgets(zp, buf, len))) { + efree(buf); + RETURN_FALSE; + } + + rbuf = estrdup(buf); + c = *buf; + lc = '\0'; + p = buf; + rp = rbuf; + br = 0; + + while (c) { + switch (c) { + case '<': + if (ZLIB_GLOBAL(gzgetss_state) == 0) { + lc = '<'; + ZLIB_GLOBAL(gzgetss_state) = 1; + } + break; + + case '(': + if (ZLIB_GLOBAL(gzgetss_state) == 2) { + if (lc != '\"') { + lc = '('; + br++; + } + } else if (ZLIB_GLOBAL(gzgetss_state) == 0) { + *(rp++) = c; + } + break; + + case ')': + if (ZLIB_GLOBAL(gzgetss_state) == 2) { + if (lc != '\"') { + lc = ')'; + br--; + } + } else if (ZLIB_GLOBAL(gzgetss_state) == 0) { + *(rp++) = c; + } + break; + + case '>': + if (ZLIB_GLOBAL(gzgetss_state) == 1) { + lc = '>'; + ZLIB_GLOBAL(gzgetss_state) = 0; + } else if (ZLIB_GLOBAL(gzgetss_state) == 2) { + if (!br && lc != '\"') { + ZLIB_GLOBAL(gzgetss_state) = 0; + } + } + break; + + case '\"': + if (ZLIB_GLOBAL(gzgetss_state) == 2) { + if (lc == '\"') { + lc = '\0'; + } else if (lc != '\\') { + lc = '\"'; + } + } else if (ZLIB_GLOBAL(gzgetss_state) == 0) { + *(rp++) = c; + } + break; + + case '?': + if (ZLIB_GLOBAL(gzgetss_state)==1) { + br=0; + ZLIB_GLOBAL(gzgetss_state)=2; + break; + } + /* fall-through */ + + default: + if (ZLIB_GLOBAL(gzgetss_state) == 0) { + *(rp++) = c; + } + } + c = *(++p); + } + *rp = '\0'; + efree(buf); + RETVAL_STRING(rbuf,1); + efree(rbuf); +} +/* }}} */ + +/* {{{ proto int gzwrite(int zp, string str [, int length]) +Binary-safe .gz-file write */ +void php3_gzwrite(INTERNAL_FUNCTION_PARAMETERS) { + pval *arg1, *arg2, *arg3=NULL; + gzFile *zp; + int ret,id,type; + int num_bytes; + ZLIB_TLS_VARS; + + switch (ARG_COUNT(ht)) { + case 2: + if (getParameters(ht, 2, &arg1, &arg2)==FAILURE) { + RETURN_FALSE; + } + convert_to_string(arg2); + num_bytes = arg2->value.str.len; + break; + case 3: + if (getParameters(ht, 3, &arg1, &arg2, &arg3)==FAILURE) { + RETURN_FALSE; + } + convert_to_string(arg2); + convert_to_long(arg3); + num_bytes = MIN(arg3->value.lval, arg2->value.str.len); + break; + default: + WRONG_PARAM_COUNT; + /* NOTREACHED */ + break; + } + convert_to_long(arg1); + id = arg1->value.lval; + + zp = php3_list_find(id,&type); + if (!zp || (type!=ZLIB_GLOBAL(le_zp))) { + php3_error(E_WARNING,"Unable to find gz-file identifier %d",id); + RETURN_FALSE; + } + + /* strip slashes only if the length wasn't specified explicitly */ + if (!arg3 && ZLIB_INI(magic_quotes_runtime)) { + _php3_stripslashes(arg2->value.str.val,&num_bytes); + } + + ret = gzwrite(zp, arg2->value.str.val,num_bytes); + RETURN_LONG(ret); +} +/* }}} */ + +/* {{{ proto int gzrewind(int zp) +Rewind the position of a .gz-file pointer */ +void php3_gzrewind(INTERNAL_FUNCTION_PARAMETERS) { + pval *arg1; + int id,type; + gzFile *zp; + ZLIB_TLS_VARS; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg1) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_long(arg1); + id = arg1->value.lval; + zp = php3_list_find(id,&type); + if (!zp || (type!=ZLIB_GLOBAL(le_zp))) { + php3_error(E_WARNING,"Unable to find gz-file identifier %d",id); + RETURN_FALSE; + } + gzrewind(zp); + RETURN_TRUE; +} +/* }}} */ + +/* {{{ proto int gztell(int zp) +Get .gz-file pointer's read/write position */ +void php3_gztell(INTERNAL_FUNCTION_PARAMETERS) { + pval *arg1; + int id, type; + long pos; + gzFile *zp; + ZLIB_TLS_VARS; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg1) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_long(arg1); + id = arg1->value.lval; + zp = php3_list_find(id,&type); + if (!zp || (type!=ZLIB_GLOBAL(le_zp))) { + php3_error(E_WARNING,"Unable to find gz-file identifier %d",id); + RETURN_FALSE; + } + pos = gztell(zp); + RETURN_LONG(pos); +} +/* }}} */ + +/* {{{ proto int gzseek(int zp, int offset) +Seek on a file pointer */ +void php3_gzseek(INTERNAL_FUNCTION_PARAMETERS) { + pval *arg1, *arg2; + int ret,id,type; + long pos; + gzFile *zp; + ZLIB_TLS_VARS; + + if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &arg1, &arg2) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_long(arg1); + convert_to_long(arg2); + pos = arg2->value.lval; + id = arg1->value.lval; + zp = php3_list_find(id,&type); + if (!zp || (type!=ZLIB_GLOBAL(le_zp))) { + php3_error(E_WARNING,"Unable to find gz-file identifier %d",id); + RETURN_FALSE; + } + ret = gzseek(zp,pos,SEEK_SET); + RETURN_LONG(ret); +} +/* }}} */ + +/* + * Read a file and write the ouput to stdout + */ +/* {{{ proto int readgzfile(string filename [, int use_include_path]) +Output a .gz-file */ +void php3_readgzfile(INTERNAL_FUNCTION_PARAMETERS) { + pval *arg1, *arg2; + char buf[8192]; + gzFile *zp; + int b, size; + int use_include_path = 0; + + + /* check args */ + switch (ARG_COUNT(ht)) { + case 1: + if (getParameters(ht,1,&arg1) == FAILURE) { + WRONG_PARAM_COUNT; + } + break; + case 2: + if (getParameters(ht,2,&arg1,&arg2) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_long(arg2); + use_include_path = arg2->value.lval; + break; + default: + WRONG_PARAM_COUNT; + } + convert_to_string(arg1); + + /* + * We need a better way of returning error messages from + * php3_gzopen_wrapper(). + */ + zp = php3_gzopen_wrapper(arg1->value.str.val,"r", use_include_path|ENFORCE_SAFE_MODE); + if (!zp){ + php3_error(E_WARNING,"ReadGzFile(\"%s\") - %s",arg1->value.str.val,strerror(errno)); + RETURN_FALSE; + } + size= 0; + while((b = gzread(zp, buf, sizeof(buf))) > 0) { + PHPWRITE(buf,b); + size += b ; + } + gzclose(zp); + RETURN_LONG(size); +} +/* }}} */ + +/* + * Read to EOF on a file descriptor and write the output to stdout. + */ +/* {{{ proto int gzpassthru(int zp) +Output all remaining data from a .gz-file pointer */ +void php3_gzpassthru(INTERNAL_FUNCTION_PARAMETERS) { + pval *arg1; + gzFile *zp; + char buf[8192]; + int id, size, b, type; + ZLIB_TLS_VARS; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg1) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_long(arg1); + id = arg1->value.lval; + zp = php3_list_find(id,&type); + if (!zp || (type!=ZLIB_GLOBAL(le_zp))) { + php3_error(E_WARNING,"Unable to find gz-file identifier %d",id); + RETURN_FALSE; + } + size = 0; + while((b = gzread(zp, buf, sizeof(buf))) > 0) { + PHPWRITE(buf,b); + size += b ; + } +/* gzclose(zp); */ + php3_list_delete(id); + RETURN_LONG(size); +} +/* }}} */ + +/* {{{ proto int gzread(int zp, int length) +Binary-safe file read */ +void php3_gzread(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *arg1, *arg2; + gzFile *zp; + int id, len, type; + ZLIB_TLS_VARS; + + if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &arg1, &arg2) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_long(arg1); + convert_to_long(arg2); + id = arg1->value.lval; + len = arg2->value.lval; + + zp = php3_list_find(id,&type); + if (!zp || (type!=ZLIB_GLOBAL(le_zp))) { + php3_error(E_WARNING,"Unable to find gz-file identifier %d",id); + RETURN_FALSE; + } + return_value->value.str.val = emalloc(sizeof(char) * (len + 1)); + /* needed because recv doesnt put a null at the end*/ + + return_value->value.str.len = gzread(zp, return_value->value.str.val, len); + return_value->value.str.val[return_value->value.str.len] = 0; + + if (ZLIB_INI(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); + } + return_value->type = IS_STRING; +} +/* }}} */ + +#endif /* HAVE_ZLIB */ +/* + * Local variables: + * tab-width: 4 + * End: + */ |
