php-src/ext/zlib/zlib.c
Zeev Suraski bc415d5a88 * Finalizing the PHP version of SAPI. Support POST and cookies among other things.
* Fully implement ISAPI support - POST and cookies among other things.
* Almost completely rewrote phpinfo().  Allow modules to easily display their
  information in phpinfo() without modifying phpinfo() itself (prototype for
  the module info function was changed, thus the large amount of updated module
  files).
* Initial extended SAPI support for Apache, completely untested.
* CGI now uses SAPI fully as well.
1999-05-09 08:48:05 +00:00

906 lines
21 KiB
C

/*
+----------------------------------------------------------------------+
| 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
#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 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
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
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(ZEND_MODULE_INFO_FUNC_ARGS)
{
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 && PG(include_path) != NULL) {
return php3_gzopen_with_path(path, mode, PG(include_path), NULL);
}
else {
if (options & ENFORCE_SAFE_MODE && PG(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 (PG(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 (PG(safe_mode)) {
snprintf(trypath,MAXPATHLEN,"%s%s",PG(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 (PG(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 (PG(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 (PG(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 (PG(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 && PG(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 (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);
}
return_value->type = IS_STRING;
}
/* }}} */
#endif /* HAVE_ZLIB */
/*
* Local variables:
* tab-width: 4
* End:
*/