[prev in list] [next in list] [prev in thread] [next in thread] 

List:       phpdoc
Subject:    [PHP-DOC] cvs: pecl /phar config.m4 config.w32 func_interceptors.c func_interceptors.h package.php p
From:       "Greg Beaver" <cellog () php ! net>
Date:       2008-01-11 7:30:02
Message-ID: cvscellog1200036602 () cvsserver
[Download RAW message or body]

This is a MIME encoded message


cellog		Fri Jan 11 07:30:02 2008 UTC

  Added files:                 
    /pecl/phar	func_interceptors.c func_interceptors.h 

  Modified files:              
    /pecl/phar	config.m4 config.w32 package.php phar.c phar_internal.h 
              	phar_object.c stream.c tar.c 
  Log:
  add Phar::interceptFileFuncs()
  To intercept fopen(), file_get_contents(), opendir(), and all the stat-based functions so that
  code like "if (is_readable('./config.inc.php'))" actually works inside of a phar
  [DOC]
  
["cellog-20080111073002.txt" (text/plain)]

http://cvs.php.net/viewvc.cgi/pecl/phar/config.m4?r1=1.18&r2=1.19&diff_format=u
Index: pecl/phar/config.m4
diff -u pecl/phar/config.m4:1.18 pecl/phar/config.m4:1.19
--- pecl/phar/config.m4:1.18	Tue Jan  8 20:31:53 2008
+++ pecl/phar/config.m4	Fri Jan 11 07:30:02 2008
@@ -1,4 +1,4 @@
-dnl $Id: config.m4,v 1.18 2008/01/08 20:31:53 cellog Exp $
+dnl $Id: config.m4,v 1.19 2008/01/11 07:30:02 cellog Exp $
 dnl config.m4 for extension phar
 
 PHP_ARG_ENABLE(phar, for phar support/phar zlib support,
@@ -32,7 +32,7 @@
 	else
 		AC_MSG_RESULT([no])
 	fi
-  PHP_NEW_EXTENSION(phar, tar.c zip.c stream.c dirstream.c phar.c phar_object.c \
phar_path_check.c $PHP_PHAR_SOURCES, $ext_shared) +  PHP_NEW_EXTENSION(phar, tar.c \
zip.c stream.c func_interceptors.c dirstream.c phar.c phar_object.c phar_path_check.c \
$PHP_PHAR_SOURCES, $ext_shared)  PHP_ADD_BUILD_DIR($ext_builddir/lib, 1)
   PHP_SUBST(PHAR_SHARED_LIBADD)
   PHP_ADD_EXTENSION_DEP(phar, zlib, true)
http://cvs.php.net/viewvc.cgi/pecl/phar/config.w32?r1=1.16&r2=1.17&diff_format=u
Index: pecl/phar/config.w32
diff -u pecl/phar/config.w32:1.16 pecl/phar/config.w32:1.17
--- pecl/phar/config.w32:1.16	Tue Jan  8 20:31:53 2008
+++ pecl/phar/config.w32	Fri Jan 11 07:30:02 2008
@@ -1,10 +1,10 @@
-// $Id: config.w32,v 1.16 2008/01/08 20:31:53 cellog Exp $
+// $Id: config.w32,v 1.17 2008/01/11 07:30:02 cellog Exp $
 // vim:ft=javascript
 
 ARG_ENABLE("phar", "enable phar support", "no");
 
 if (PHP_PHAR != "no") {
-	EXTENSION("phar", "tar.c zip.c stream.c dirstream.c phar.c phar_object.c \
phar_path_check.c"); +	EXTENSION("phar", "tar.c zip.c stream.c dirstream.c \
func_interceptors.c phar.c phar_object.c phar_path_check.c");  \
ADD_SOURCES(configure_module_dirname + "/lib", "zip_add.c zip_error.c zip_fclose.c \  \
zip_fread.c zip_open.c zip_source_filep.c  \  zip_strerror.c zip_close.c \
zip_error_get.c \ http://cvs.php.net/viewvc.cgi/pecl/phar/package.php?r1=1.31&r2=1.32&diff_format=u
                
Index: pecl/phar/package.php
diff -u pecl/phar/package.php:1.31 pecl/phar/package.php:1.32
--- pecl/phar/package.php:1.31	Wed Jan  9 08:49:57 2008
+++ pecl/phar/package.php	Fri Jan 11 07:30:02 2008
@@ -6,7 +6,9 @@
  * add Phar::isTar(), Phar::isZip(), and Phar::isPhar() [Greg]
  * add Phar::webPhar() for running a web-based application unmodified
    directly from a phar archive [Greg]
- * include/fopen with include_path all work unmodified within a phar [Greg]
+ * file functions (fopen-based and stat-based) can be instructed to only look for
+   relative paths within a phar via Phar::interceptFileFuncs()
+ * include works unmodified within a phar [Greg]
  * paths with . and .. work (phar://blah.phar/a/../b.php => phar://blah.phar/b.php) \
                [Greg]
  * add support for mkdir()/rmdir() and support for empty directories to phar file \
                format [Greg]
  * add option to compress the entire phar file for phar/tar file format [Greg]
http://cvs.php.net/viewvc.cgi/pecl/phar/phar.c?r1=1.263&r2=1.264&diff_format=u
Index: pecl/phar/phar.c
diff -u pecl/phar/phar.c:1.263 pecl/phar/phar.c:1.264
--- pecl/phar/phar.c:1.263	Thu Jan 10 22:05:29 2008
+++ pecl/phar/phar.c	Fri Jan 11 07:30:02 2008
@@ -17,11 +17,12 @@
   +----------------------------------------------------------------------+
 */
 
-/* $Id: phar.c,v 1.263 2008/01/10 22:05:29 cellog Exp $ */
+/* $Id: phar.c,v 1.264 2008/01/11 07:30:02 cellog Exp $ */
 
 #define PHAR_MAIN 1
 #include "phar_internal.h"
 #include "SAPI.h"
+#include "func_interceptors.h"
 
 ZEND_DECLARE_MODULE_GLOBALS(phar)
 
@@ -1893,13 +1894,13 @@
 /**
  * Remove .. and . references within a phar filename
  */
-static char *phar_fix_filepath(char *path, int *new_len, int cwd TSRMLS_DC) /* {{{ \
*/ +char *phar_fix_filepath(char *path, int *new_len, int use_cwd TSRMLS_DC) /* {{{ \
*/  {
 	char *ptr, *free_path, *new_phar;
 	char *tok;
 	int ptr_length, new_phar_len = 1, path_length = *new_len;
 
-	if (cwd) {
+	if (use_cwd) {
 		free_path = path = estrndup(path, path_length);
 		new_phar_len = PHAR_G(cwd_len);
 		new_phar = estrndup(PHAR_G(cwd), new_phar_len);
@@ -1948,9 +1949,7 @@
 		ptr = tsrm_strtok_r(NULL, "/", &tok);
 	}
 
-	if (free_path) {
-		efree(free_path);
-	}
+	efree(free_path);
 
 	if (path[path_length-1] == '/' && new_phar_len > 1) {
 		new_phar = (char*)erealloc(new_phar, new_phar_len + 2);
@@ -3215,337 +3214,11 @@
 }
 /* }}} */
 
-static void phar_is_dir(INTERNAL_FUNCTION_PARAMETERS)
-{
-	char *filename;
-	int filename_len;
-
-	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &filename, &filename_len) \
                == FAILURE) {
-		return;
-	}
-
-	if (!IS_ABSOLUTE_PATH(filename, filename_len)) {
-		char *arch, *entry, *fname;
-		int arch_len, entry_len, fname_len, free_filename = 0;
-		fname = zend_get_executed_filename(TSRMLS_C);
-
-		/* we are checking for existence of a file within the relative path.  Chances are \
                good that this is
-		   retrieving something from within the phar archive */
-
-		if (strncasecmp(fname, "phar://", 7)) {
-			goto skip_phar;
-		}
-		fname_len = strlen(fname);
-		if (SUCCESS == phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, \
                &entry_len TSRMLS_CC)) {
-			phar_archive_data **pphar;
-
-			efree(entry);
-			entry = filename;
-			/* fopen within phar, if :// is not in the url, then prepend phar://<archive>/ */
-			entry_len = filename_len;
-			if (strstr(entry, "://")) {
-				efree(arch);
-				if (free_filename) {
-					efree(filename);
-				}
-				goto skip_phar;
-			}
-			/* retrieving a file within the current directory, so use this if possible */
-			if (SUCCESS == (zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), arch, arch_len, \
                (void **) &pphar))) {
-				phar_entry_info *etemp;
-
-				entry = phar_fix_filepath(entry, &entry_len, 1 TSRMLS_CC);
-				if (zend_hash_find(&((*pphar)->manifest), entry, entry_len, (void **) &etemp)) {
-					/* this file is not in the current directory, use the original path */
-					efree(entry);
-					efree(arch);
-					RETURN_BOOL(etemp->is_dir);
-				} else {
-					char *key;
-					uint keylen;
-					ulong unused;
-					HashTable *manifest;
-			
-					efree(arch);
-					manifest = &(*pphar)->manifest;
-					zend_hash_internal_pointer_reset(manifest);
-					while (FAILURE != zend_hash_has_more_elements(manifest)) {
-						if (HASH_KEY_NON_EXISTANT == zend_hash_get_current_key_ex(manifest, &key, \
                &keylen, &unused, 0, NULL)) {
-							break;
-						}
-						if (0 != memcmp(key, entry, entry_len)) {
-							/* entry in directory not found */
-							if (SUCCESS != zend_hash_move_forward(manifest)) {
-								break;
-							}
-							continue;
-						} else {
-							if (key[entry_len] != '/') {
-								if (SUCCESS != zend_hash_move_forward(manifest)) {
-									break;
-								}
-								continue;
-							}
-							/* found a file in this path */
-							efree(entry);
-							RETURN_TRUE;
-						}
-					}
-					efree(entry);
-					RETURN_FALSE;
-				}
-			}
-		}
-	}
-skip_phar:
-	PHAR_G(orig_is_dir)(INTERNAL_FUNCTION_PARAM_PASSTHRU);
-	return;
-}
-
-static void phar_fgc(INTERNAL_FUNCTION_PARAMETERS)
-{
-	char *filename;
-	int filename_len;
-	char *contents;
-	zend_bool use_include_path = 0;
-	php_stream *stream;
-	int len, newlen;
-	long offset = -1;
-	long maxlen = PHP_STREAM_COPY_ALL;
-	zval *zcontext = NULL;
-
-	/* Parse arguments */
-	if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, \
"s|br!ll", &filename, &filename_len, &use_include_path, &zcontext, &offset, &maxlen) \
                == FAILURE) {
-		return;
-	}
-	if (use_include_path || !IS_ABSOLUTE_PATH(filename, filename_len)) {
-		char *arch, *entry, *fname;
-		int arch_len, entry_len, fname_len, free_filename = 0;
-		php_stream_context *context = NULL;
-		fname = zend_get_executed_filename(TSRMLS_C);
-
-		if (strncasecmp(fname, "phar://", 7)) {
-			goto skip_phar;
-		}
-		fname_len = strlen(fname);
-		if (SUCCESS == phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, \
                &entry_len TSRMLS_CC)) {
-			char *name;
-			phar_archive_data **pphar;
-
-			efree(entry);
-			entry = filename;
-			/* fopen within phar, if :// is not in the url, then prepend phar://<archive>/ */
-			entry_len = filename_len;
-			if (strstr(entry, "://")) {
-				efree(arch);
-				if (free_filename) {
-					efree(filename);
-				}
-				goto skip_phar;
-			}
-
-			if (ZEND_NUM_ARGS() == 5 && maxlen < 0) {
-				php_error_docref(NULL TSRMLS_CC, E_WARNING, "length must be greater than or \
                equal to zero");
-				RETURN_FALSE;
-			}
-
-			if (!IS_ABSOLUTE_PATH(filename, filename_len)) {
-				/* retrieving a file defaults to within the current directory, so use this if \
                possible */
-				if (SUCCESS == (zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), arch, arch_len, \
                (void **) &pphar))) {
-					name = entry;
-					entry = phar_fix_filepath(entry, &entry_len, 1 TSRMLS_CC);
-					if (!zend_hash_exists(&((*pphar)->manifest), entry, entry_len)) {
-						/* this file is not in the current directory, use the original path */
-						efree(entry);
-						entry = name;
-					}
-				}
-			}
-			/* auto-convert to phar:// */
-			spprintf(&name, 4096, "phar://%s/%s", arch, entry);
-			if (entry != filename) {
-				efree(entry);
-			}
-			efree(arch);
-			context = php_stream_context_from_zval(zcontext, 0);
-			stream = php_stream_open_wrapper_ex(name, "rb", 0 | REPORT_ERRORS, NULL, \
                context);
-			if (free_filename) {
-				efree(filename);
-			}
-			efree(name);
-
-
-			if (!stream) {
-				RETURN_FALSE;
-			}
-
-			if (offset > 0 && php_stream_seek(stream, offset, SEEK_SET) < 0) {
-				php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to seek to position %ld in \
                the stream", offset);
-				php_stream_close(stream);
-				RETURN_FALSE;
-			}
-
-			/* uses mmap if possible */
-			if ((len = php_stream_copy_to_mem(stream, &contents, maxlen, 0)) > 0) {
-		
-				if (PG(magic_quotes_runtime)) {
-					contents = php_addslashes(contents, len, &newlen, 1 TSRMLS_CC); /* 1 = free \
                source string */
-					len = newlen;
-				}
-		
-				RETVAL_STRINGL(contents, len, 0);
-			} else if (len == 0) {
-				RETVAL_EMPTY_STRING();
-			} else {
-				RETVAL_FALSE;
-			}
-
-			php_stream_close(stream);
-			return;
-		}
-	}
-skip_phar:
-	PHAR_G(orig_fgc)(INTERNAL_FUNCTION_PARAM_PASSTHRU);
-	return;
-}
-
-static void phar_file_exists(INTERNAL_FUNCTION_PARAMETERS)
-{
-	char *filename;
-	int filename_len;
-
-	if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, \
                "s", &filename, &filename_len) == FAILURE) {
-		goto skip_phar;
-	}
-	if (!IS_ABSOLUTE_PATH(filename, filename_len)) {
-		char *arch, *entry, *fname;
-		int arch_len, entry_len, fname_len, free_filename = 0;
-		fname = zend_get_executed_filename(TSRMLS_C);
-
-		/* we are checking for existence of a file within the relative path.  Chances are \
                good that this is
-		   retrieving something from within the phar archive */
-
-		if (strncasecmp(fname, "phar://", 7)) {
-			goto skip_phar;
-		}
-		fname_len = strlen(fname);
-		if (SUCCESS == phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, \
                &entry_len TSRMLS_CC)) {
-			phar_archive_data **pphar;
-
-			efree(entry);
-			entry = filename;
-			/* fopen within phar, if :// is not in the url, then prepend phar://<archive>/ */
-			entry_len = filename_len;
-			if (strstr(entry, "://")) {
-				efree(arch);
-				if (free_filename) {
-					efree(filename);
-				}
-				goto skip_phar;
-			}
-			/* retrieving a file within the current directory, so use this if possible */
-			if (SUCCESS == (zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), arch, arch_len, \
                (void **) &pphar))) {
-				entry = phar_fix_filepath(entry, &entry_len, 1 TSRMLS_CC);
-				if (zend_hash_exists(&((*pphar)->manifest), entry, entry_len)) {
-					/* this file is not in the current directory, use the original path */
-					efree(entry);
-					efree(arch);
-					RETURN_TRUE;
-				}
-			}
-			efree(entry);
-			efree(arch);
-		}
-	}
-skip_phar:
-	PHAR_G(file_exists)(INTERNAL_FUNCTION_PARAM_PASSTHRU);
-	return;
-}
-
-static void phar_fopen(INTERNAL_FUNCTION_PARAMETERS)
-{
-	char *filename, *mode;
-	int filename_len, mode_len;
-	zend_bool use_include_path = 0;
-	zval *zcontext = NULL;
-	php_stream *stream;
-
-	if (!zend_hash_num_elements(&(PHAR_GLOBALS->phar_fname_map))) {
-		/* no need to check, include_path not even specified in fopen/ no active phars */
-		goto skip_phar;
-	}
-	if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, \
"ss|br", &filename, &filename_len, &mode, &mode_len, &use_include_path, &zcontext) == \
                FAILURE) {
-		goto skip_phar;
-	}
-	if (use_include_path || !IS_ABSOLUTE_PATH(filename, filename_len)) {
-		char *arch, *entry, *fname;
-		int arch_len, entry_len, fname_len, free_filename = 0;
-		php_stream_context *context = NULL;
-		fname = zend_get_executed_filename(TSRMLS_C);
-
-		if (strncasecmp(fname, "phar://", 7)) {
-			goto skip_phar;
-		}
-		fname_len = strlen(fname);
-		if (SUCCESS == phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, \
                &entry_len TSRMLS_CC)) {
-			char *name;
-			phar_archive_data **pphar;
-
-			efree(entry);
-			entry = filename;
-			/* fopen within phar, if :// is not in the url, then prepend phar://<archive>/ */
-			entry_len = filename_len;
-			if (strstr(entry, "://")) {
-				efree(arch);
-				if (free_filename) {
-					efree(filename);
-				}
-				goto skip_phar;
-			}
-			if (!IS_ABSOLUTE_PATH(filename, filename_len)) {
-				/* retrieving a file defaults to within the current directory, so use this if \
                possible */
-				if (SUCCESS == (zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), arch, arch_len, \
                (void **) &pphar))) {
-					name = entry;
-					entry = phar_fix_filepath(entry, &entry_len, 1 TSRMLS_CC);
-					if (!zend_hash_exists(&((*pphar)->manifest), entry, entry_len)) {
-						/* this file is not in the current directory, use the original path */
-						efree(entry);
-						entry = name;
-					}
-				}
-			}
-			/* auto-convert to phar:// */
-			spprintf(&name, 4096, "phar://%s/%s", arch, entry);
-			if (entry != filename) {
-				efree(entry);
-			}
-			efree(arch);
-			context = php_stream_context_from_zval(zcontext, 0);
-			stream = php_stream_open_wrapper_ex(name, mode, 0 | REPORT_ERRORS, NULL, \
                context);
-			efree(name);
-			php_stream_to_zval(stream, return_value);
-			if (free_filename) {
-				efree(filename);
-			}
-			return;
-		}
-	}
-skip_phar:
-	PHAR_G(orig_fopen)(INTERNAL_FUNCTION_PARAM_PASSTHRU);
-	return;
-}
-
 PHP_MINIT_FUNCTION(phar) /* {{{ */
 {
 	ZEND_INIT_MODULE_GLOBALS(phar, php_phar_init_globals_module, NULL);
 	REGISTER_INI_ENTRIES();
 
-	PHAR_G(orig_fopen) = NULL;
-	PHAR_G(orig_fgc) = NULL;
-	PHAR_G(file_exists) = NULL;
-	PHAR_G(orig_is_dir) = NULL;
-	PHAR_G(cwd) = NULL;
-	PHAR_G(cwd_len) = 0;
 	phar_has_gnupg = zend_hash_exists(&module_registry, "gnupg", sizeof("gnupg"));
 	phar_has_bz2 = zend_hash_exists(&module_registry, "bz2", sizeof("bz2"));
 	phar_has_zlib = zend_hash_exists(&module_registry, "zlib", sizeof("zlib"));
@@ -3578,7 +3251,6 @@
 {
 	if (!PHAR_GLOBALS->request_init)
 	{
-		zend_function *orig;
 		PHAR_GLOBALS->request_init = 1;
 		PHAR_GLOBALS->request_ends = 0;
 		PHAR_GLOBALS->request_done = 0;
@@ -3587,26 +3259,9 @@
 		zend_hash_init(&(PHAR_GLOBALS->phar_plain_map), sizeof(const char *),       \
zend_get_hash_value, NULL, 0);  \
zend_hash_init(&(PHAR_GLOBALS->phar_SERVER_mung_list), sizeof(const char *),       \
zend_get_hash_value, NULL, 0);  phar_split_extract_list(TSRMLS_C);
-		PHAR_G(orig_fopen) = PHAR_G(orig_fgc) = PHAR_G(file_exists) = NULL;
-		PHAR_G(orig_is_dir) = NULL;
 		PHAR_G(cwd) = NULL;
 		PHAR_G(cwd_len) = 0;
-		if (SUCCESS == zend_hash_find(CG(function_table), "fopen", 6, (void **)&orig)) {
-			PHAR_G(orig_fopen) = orig->internal_function.handler;
-			orig->internal_function.handler = phar_fopen;
-		}
-		if (SUCCESS == zend_hash_find(CG(function_table), "file_get_contents", 18, (void \
                **)&orig)) {
-			PHAR_G(orig_fgc) = orig->internal_function.handler;
-			orig->internal_function.handler = phar_fgc;
-		}
-		if (SUCCESS == zend_hash_find(CG(function_table), "file_exists", 12, (void \
                **)&orig)) {
-			PHAR_G(file_exists) = orig->internal_function.handler;
-			orig->internal_function.handler = phar_file_exists;
-		}
-		if (SUCCESS == zend_hash_find(CG(function_table), "is_dir", 7, (void **)&orig)) {
-			PHAR_G(orig_is_dir) = orig->internal_function.handler;
-			orig->internal_function.handler = phar_is_dir;
-		}
+		phar_intercept_functions(TSRMLS_C);
 	}
 }
 /* }}} */
@@ -3616,23 +3271,7 @@
 	PHAR_GLOBALS->request_ends = 1;
 	if (PHAR_GLOBALS->request_init)
 	{
-		zend_function *orig;
-		if (PHAR_G(orig_fopen) && SUCCESS == zend_hash_find(CG(function_table), "fopen", \
                6, (void **)&orig)) {
-			orig->internal_function.handler = PHAR_G(orig_fopen);
-		}
-		PHAR_G(orig_fopen) = NULL;
-		if (PHAR_G(file_exists) && SUCCESS == zend_hash_find(CG(function_table), \
                "file_exists", 12, (void **)&orig)) {
-			orig->internal_function.handler = PHAR_G(file_exists);
-		}
-		PHAR_G(file_exists) = NULL;
-		if (PHAR_G(orig_fgc) && SUCCESS == zend_hash_find(CG(function_table), \
                "file_get_contents", 18, (void **)&orig)) {
-			orig->internal_function.handler = PHAR_G(orig_fgc);
-		}
-		PHAR_G(orig_fgc) = NULL;
-		if (PHAR_G(orig_is_dir) && SUCCESS == zend_hash_find(CG(function_table), "is_dir", \
                7, (void **)&orig)) {
-			orig->internal_function.handler = PHAR_G(orig_is_dir);
-		}
-		PHAR_G(orig_is_dir) = NULL;
+		phar_release_functions(TSRMLS_C);
 		zend_hash_destroy(&(PHAR_GLOBALS->phar_alias_map));
 		PHAR_GLOBALS->phar_alias_map.arBuckets = NULL;
 		zend_hash_destroy(&(PHAR_GLOBALS->phar_fname_map));
@@ -3659,7 +3298,7 @@
 	php_info_print_table_header(2, "Phar: PHP Archive support", "enabled");
 	php_info_print_table_row(2, "Phar EXT version", PHAR_EXT_VERSION_STR);
 	php_info_print_table_row(2, "Phar API version", PHAR_API_VERSION_STR);
-	php_info_print_table_row(2, "CVS revision", "$Revision: 1.263 $");
+	php_info_print_table_row(2, "CVS revision", "$Revision: 1.264 $");
 	php_info_print_table_row(2, "Phar-based phar archives", "enabled");
 	php_info_print_table_row(2, "Tar-based phar archives", "enabled");
 #if HAVE_PHAR_ZIP
http://cvs.php.net/viewvc.cgi/pecl/phar/phar_internal.h?r1=1.59&r2=1.60&diff_format=u
Index: pecl/phar/phar_internal.h
diff -u pecl/phar/phar_internal.h:1.59 pecl/phar/phar_internal.h:1.60
--- pecl/phar/phar_internal.h:1.59	Thu Jan 10 15:12:59 2008
+++ pecl/phar/phar_internal.h	Fri Jan 11 07:30:02 2008
@@ -17,7 +17,7 @@
   +----------------------------------------------------------------------+
 */
 
-/* $Id: phar_internal.h,v 1.59 2008/01/10 15:12:59 cellog Exp $ */
+/* $Id: phar_internal.h,v 1.60 2008/01/11 07:30:02 cellog Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -143,9 +143,26 @@
 	int         request_done;
 	int         request_ends;
 	void        (*orig_fopen)(INTERNAL_FUNCTION_PARAMETERS);
-	void        (*orig_fgc)(INTERNAL_FUNCTION_PARAMETERS);
+	void        (*orig_file_get_contents)(INTERNAL_FUNCTION_PARAMETERS);
+	void        (*orig_is_file)(INTERNAL_FUNCTION_PARAMETERS);
+	void        (*orig_is_link)(INTERNAL_FUNCTION_PARAMETERS);
 	void        (*orig_is_dir)(INTERNAL_FUNCTION_PARAMETERS);
-	void        (*file_exists)(INTERNAL_FUNCTION_PARAMETERS);
+	void        (*orig_opendir)(INTERNAL_FUNCTION_PARAMETERS);
+	void        (*orig_file_exists)(INTERNAL_FUNCTION_PARAMETERS);
+	void        (*orig_fileperms)(INTERNAL_FUNCTION_PARAMETERS);
+	void        (*orig_fileinode)(INTERNAL_FUNCTION_PARAMETERS);
+	void        (*orig_filesize)(INTERNAL_FUNCTION_PARAMETERS);
+	void        (*orig_fileowner)(INTERNAL_FUNCTION_PARAMETERS);
+	void        (*orig_filegroup)(INTERNAL_FUNCTION_PARAMETERS);
+	void        (*orig_fileatime)(INTERNAL_FUNCTION_PARAMETERS);
+	void        (*orig_filemtime)(INTERNAL_FUNCTION_PARAMETERS);
+	void        (*orig_filectime)(INTERNAL_FUNCTION_PARAMETERS);
+	void        (*orig_filetype)(INTERNAL_FUNCTION_PARAMETERS);
+	void        (*orig_is_writable)(INTERNAL_FUNCTION_PARAMETERS);
+	void        (*orig_is_readable)(INTERNAL_FUNCTION_PARAMETERS);
+	void        (*orig_is_executable)(INTERNAL_FUNCTION_PARAMETERS);
+	void        (*orig_lstat)(INTERNAL_FUNCTION_PARAMETERS);
+	void        (*orig_stat)(INTERNAL_FUNCTION_PARAMETERS);
 	/* used for includes with . in them inside front controller */
 	char*       cwd;
 	int         cwd_len;
@@ -319,6 +336,7 @@
 int phar_get_archive(phar_archive_data **archive, char *fname, int fname_len, char \
*alias, int alias_len, char **error TSRMLS_DC);  int phar_open_loaded(char *fname, \
int fname_len, char *alias, int alias_len, int options, phar_archive_data** pphar, \
char **error TSRMLS_DC);  
+char *phar_fix_filepath(char *path, int *new_len, int use_cwd TSRMLS_DC);
 phar_entry_info * phar_open_jit(phar_archive_data *phar, phar_entry_info *entry, \
php_stream *fp,  char **error, int for_write TSRMLS_DC);
 int phar_parse_metadata(char **buffer, zval **metadata, int is_zip TSRMLS_DC);
@@ -337,7 +355,6 @@
 int phar_zip_flush(phar_archive_data *archive, char *user_stub, long len, char \
**error TSRMLS_DC);  
 #ifdef PHAR_MAIN
-static void phar_fopen(INTERNAL_FUNCTION_PARAMETERS);
 static int phar_open_fp(php_stream* fp, char *fname, int fname_len, char *alias, int \
alias_len, int options, phar_archive_data** pphar, char **error TSRMLS_DC);  extern \
php_stream_wrapper php_stream_phar_wrapper;  #endif
http://cvs.php.net/viewvc.cgi/pecl/phar/phar_object.c?r1=1.116&r2=1.117&diff_format=u
Index: pecl/phar/phar_object.c
diff -u pecl/phar/phar_object.c:1.116 pecl/phar/phar_object.c:1.117
--- pecl/phar/phar_object.c:1.116	Fri Jan 11 02:52:12 2008
+++ pecl/phar/phar_object.c	Fri Jan 11 07:30:02 2008
@@ -17,9 +17,10 @@
   +----------------------------------------------------------------------+
 */
 
-/* $Id: phar_object.c,v 1.116 2008/01/11 02:52:12 cellog Exp $ */
+/* $Id: phar_object.c,v 1.117 2008/01/11 07:30:02 cellog Exp $ */
 
 #include "phar_internal.h"
+#include "func_interceptors.h"
 
 static zend_class_entry *phar_ce_archive;
 static zend_class_entry *phar_ce_PharException;
@@ -705,6 +706,20 @@
 }
 /* }}} */
 
+/* {{{ proto void Phar::interceptFileFuncs()
+ * instructs phar to intercept fopen, file_get_contents, opendir, and all of the \
stat-related functions + * and return stat on files within the phar for relative \
paths + *
+ * Once called, this cannot be reversed, and continue until the end of the request.
+ *
+ * This allows legacy scripts to be pharred unmodified
+ */
+PHP_METHOD(Phar, interceptFileFuncs)
+{
+	phar_intercept_functions(TSRMLS_C);
+}
+/* }}} */
+
 /* {{{ proto mixed Phar::mapPhar([string alias, [int dataoffset]])
  * Reads the currently executed file (a phar) and registers its manifest */
 PHP_METHOD(Phar, mapPhar)
@@ -2852,6 +2867,7 @@
 	PHP_ME(Phar, mapPhar,               arginfo_phar_mapPhar,      \
ZEND_ACC_PUBLIC|ZEND_ACC_STATIC|ZEND_ACC_FINAL)  PHP_ME(Phar, webPhar,               \
arginfo_phar_webPhar,      ZEND_ACC_PUBLIC|ZEND_ACC_STATIC|ZEND_ACC_FINAL)  \
PHP_ME(Phar, mungServer,            arginfo_phar_mungServer,   \
ZEND_ACC_PUBLIC|ZEND_ACC_STATIC|ZEND_ACC_FINAL) +	PHP_ME(Phar, interceptFileFuncs,    \
NULL,                      ZEND_ACC_PUBLIC|ZEND_ACC_STATIC|ZEND_ACC_FINAL)  \
PHP_ME(Phar, getExtractList,        NULL,                      \
ZEND_ACC_PUBLIC|ZEND_ACC_STATIC|ZEND_ACC_FINAL)  PHP_ME(Phar, \
getSupportedSignatures,NULL,                      \
ZEND_ACC_PUBLIC|ZEND_ACC_STATIC|ZEND_ACC_FINAL)  PHP_ME(Phar, \
getSupportedCompression,NULL,                     \
ZEND_ACC_PUBLIC|ZEND_ACC_STATIC|ZEND_ACC_FINAL) \
                http://cvs.php.net/viewvc.cgi/pecl/phar/stream.c?r1=1.5&r2=1.6&diff_format=u
                
Index: pecl/phar/stream.c
diff -u pecl/phar/stream.c:1.5 pecl/phar/stream.c:1.6
--- pecl/phar/stream.c:1.5	Wed Jan  9 03:47:21 2008
+++ pecl/phar/stream.c	Fri Jan 11 07:30:02 2008
@@ -556,7 +556,7 @@
 	phar_archive_data *phar;
 	phar_entry_info *entry;
 	uint host_len;
-	int retval;
+	int retval, internal_file_len;
 
 	if ((resource = phar_open_url(wrapper, url, "r", flags TSRMLS_CC)) == NULL) {
 		return FAILURE;
@@ -611,8 +611,9 @@
 		php_url_free(resource);
 		return SUCCESS;
 	}
+	internal_file_len = strlen(internal_file);
 	/* search through the manifest of files, and if we have an exact match, it's a file \
                */
-	if (SUCCESS == zend_hash_find(&phar->manifest, internal_file, \
strlen(internal_file), (void**)&entry)) { +	if (SUCCESS == \
zend_hash_find(&phar->manifest, internal_file, internal_file_len, (void**)&entry)) {  \
phar_dostat(phar, entry, ssb, 0, phar->alias, phar->alias_len TSRMLS_CC);  \
php_url_free(resource);  return SUCCESS;
@@ -623,9 +624,9 @@
 			if (HASH_KEY_NON_EXISTANT !=
 					zend_hash_get_current_key_ex(
 						&phar->manifest, &key, &keylen, &unused, 0, NULL)) {
-				if (0 == memcmp(internal_file, key, strlen(internal_file))) {
+				if (0 == memcmp(internal_file, key, internal_file_len)) {
 					/* directory found, all dirs have the same stat */
-					if (key[strlen(internal_file)] == '/') {
+					if (key[internal_file_len] == '/') {
 						phar_dostat(phar, NULL, ssb, 1, phar->alias, phar->alias_len TSRMLS_CC);
 						php_url_free(resource);
 						return SUCCESS;
http://cvs.php.net/viewvc.cgi/pecl/phar/tar.c?r1=1.10&r2=1.11&diff_format=u
Index: pecl/phar/tar.c
diff -u pecl/phar/tar.c:1.10 pecl/phar/tar.c:1.11
--- pecl/phar/tar.c:1.10	Wed Jan  9 08:44:59 2008
+++ pecl/phar/tar.c	Fri Jan 11 07:30:02 2008
@@ -554,7 +554,6 @@
 		/* deferred flush */
 		phar->fp = newfile;
 	} else {
-
 		phar->fp = php_stream_open_wrapper(phar->fname, "w+b", \
IGNORE_URL|STREAM_MUST_SEEK|REPORT_ERRORS, NULL);  if (!phar->fp) {
 			phar->fp = newfile;
@@ -573,6 +572,9 @@
 			filter = php_stream_filter_create("zlib.deflate", &filterparams, \
php_stream_is_persistent(phar->fp) TSRMLS_CC);  zval_dtor(&filterparams);
 			if (!filter) {
+				/* copy contents uncompressed rather than lose them */
+				php_stream_copy_to_stream(newfile, phar->fp, PHP_STREAM_COPY_ALL);
+				php_stream_close(newfile);
 				if (error) {
 					spprintf(error, 4096, "unable to compress all contents of phar \"%s\" using \
zlib, PHP versions older than 5.2.6 have a buggy zlib", phar->fname);  }

http://cvs.php.net/viewvc.cgi/pecl/phar/func_interceptors.c?view=markup&rev=1.1
Index: pecl/phar/func_interceptors.c
+++ pecl/phar/func_interceptors.c
/*
  +----------------------------------------------------------------------+
  | phar php single-file executable PHP extension                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 2005-2008 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt.                                 |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Authors: Gregory Beaver <cellog@php.net>                             |
  +----------------------------------------------------------------------+
*/

/* $Id: func_interceptors.c,v 1.1 2008/01/11 07:30:02 cellog Exp $ */

#include "phar_internal.h"

#define PHAR_FUNC(name) \
	static PHP_NAMED_FUNCTION(name)

PHAR_FUNC(phar_fopen);
PHAR_FUNC(phar_file_get_contents);
PHAR_FUNC(phar_is_file);
PHAR_FUNC(phar_is_link);
PHAR_FUNC(phar_is_dir);
PHAR_FUNC(phar_opendir);
PHAR_FUNC(phar_file_exists);
PHAR_FUNC(phar_fileperms);
PHAR_FUNC(phar_fileinode);
PHAR_FUNC(phar_filesize);
PHAR_FUNC(phar_fileowner);
PHAR_FUNC(phar_filegroup);
PHAR_FUNC(phar_fileatime);
PHAR_FUNC(phar_filemtime);
PHAR_FUNC(phar_filectime);
PHAR_FUNC(phar_filetype);
PHAR_FUNC(phar_is_writable);
PHAR_FUNC(phar_is_readable);
PHAR_FUNC(phar_is_executable);
PHAR_FUNC(phar_lstat);
PHAR_FUNC(phar_stat);

#define PHAR_INTERCEPT(func) \
	PHAR_G(orig_##func) = NULL; \
	if (SUCCESS == zend_hash_find(CG(function_table), #func, sizeof(#func), (void \
**)&orig)) { \  PHAR_G(orig_##func) = orig->internal_function.handler; \
		orig->internal_function.handler = phar_##func; \
	}


void phar_intercept_functions(TSRMLS_D) /* {{{ */
{
	zend_function *orig;

	if (!PHAR_G(request_init)) {
		PHAR_G(cwd) = NULL;
		PHAR_G(cwd_len) = 0;
	} else if (PHAR_G(orig_fopen)) {
		/* don't double-intercept */
		return;
	}
	PHAR_INTERCEPT(fopen);
	PHAR_INTERCEPT(file_get_contents);
	PHAR_INTERCEPT(is_file);
	PHAR_INTERCEPT(is_link);
	PHAR_INTERCEPT(is_dir);
	PHAR_INTERCEPT(opendir);
	PHAR_INTERCEPT(file_exists);
	PHAR_INTERCEPT(fileperms);
	PHAR_INTERCEPT(fileinode);
	PHAR_INTERCEPT(filesize);
	PHAR_INTERCEPT(fileowner);
	PHAR_INTERCEPT(filegroup);
	PHAR_INTERCEPT(fileatime);
	PHAR_INTERCEPT(filemtime);
	PHAR_INTERCEPT(filectime);
	PHAR_INTERCEPT(filetype);
	PHAR_INTERCEPT(is_writable);
	PHAR_INTERCEPT(is_readable);
	PHAR_INTERCEPT(is_executable);
	PHAR_INTERCEPT(lstat);
	PHAR_INTERCEPT(stat);
}

#define PHAR_RELEASE(func) \
	if (PHAR_G(orig_##func) && SUCCESS == zend_hash_find(CG(function_table), #func, \
sizeof(#func), (void **)&orig)) { \  orig->internal_function.handler = \
PHAR_G(orig_##func); \  } \
	PHAR_G(orig_##func) = NULL;


void phar_release_functions(TSRMLS_D) /* {{{ */
{
	zend_function *orig;

	PHAR_RELEASE(fopen);
	PHAR_RELEASE(file_get_contents);
	PHAR_RELEASE(is_file);
	PHAR_RELEASE(is_dir);
	PHAR_RELEASE(opendir);
	PHAR_RELEASE(file_exists);
	PHAR_RELEASE(fileperms);
	PHAR_RELEASE(fileinode);
	PHAR_RELEASE(filesize);
	PHAR_RELEASE(fileowner);
	PHAR_RELEASE(filegroup);
	PHAR_RELEASE(fileatime);
	PHAR_RELEASE(filemtime);
	PHAR_RELEASE(filectime);
	PHAR_RELEASE(filetype);
	PHAR_RELEASE(is_writable);
	PHAR_RELEASE(is_readable);
	PHAR_RELEASE(is_executable);
	PHAR_RELEASE(lstat);
	PHAR_RELEASE(stat);
}
/* }}} */

PHAR_FUNC(phar_opendir)
{
	char *filename;
	int filename_len;
	zval *zcontext = NULL;

	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|z", &filename, \
&filename_len, &zcontext) == FAILURE) {  return;
	}

	if (!IS_ABSOLUTE_PATH(filename, filename_len)) {
		char *arch, *entry, *fname;
		int arch_len, entry_len, fname_len;
		fname = zend_get_executed_filename(TSRMLS_C);

		/* we are checking for existence of a file within the relative path.  Chances are \
good that this is  retrieving something from within the phar archive */

		if (strncasecmp(fname, "phar://", 7)) {
			goto skip_phar;
		}
		fname_len = strlen(fname);
		if (SUCCESS == phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, \
&entry_len TSRMLS_CC)) {  php_stream_context *context = NULL;
			php_stream *stream;
			char *name;

			efree(entry);
			entry = filename;
			/* fopen within phar, if :// is not in the url, then prepend phar://<archive>/ */
			entry_len = filename_len;
			if (strstr(entry, "://")) {
				efree(arch);
				goto skip_phar;
			}
			/* retrieving a file within the current directory, so use this if possible */
			entry = phar_fix_filepath(entry, &entry_len, 1 TSRMLS_CC);

			spprintf(&name, 4096, "phar://%s/%s", arch, entry);
			efree(entry);
			efree(arch);
			if (zcontext) {
				context = php_stream_context_from_zval(zcontext, 0);
			}
			stream = php_stream_opendir(name, REPORT_ERRORS, context);
			efree(name);
			if (!stream) {
				RETURN_FALSE;
			}
			php_stream_to_zval(stream, return_value);
			efree(entry);
			return;
		}
	}
skip_phar:
	PHAR_G(orig_opendir)(INTERNAL_FUNCTION_PARAM_PASSTHRU);
	return;
}

PHAR_FUNC(phar_file_get_contents)
{
	char *filename;
	int filename_len;
	char *contents;
	zend_bool use_include_path = 0;
	php_stream *stream;
	int len, newlen;
	long offset = -1;
	long maxlen = PHP_STREAM_COPY_ALL;
	zval *zcontext = NULL;

	/* Parse arguments */
	if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, \
"s|br!ll", &filename, &filename_len, &use_include_path, &zcontext, &offset, &maxlen) \
== FAILURE) {  return;
	}
	if (use_include_path || !IS_ABSOLUTE_PATH(filename, filename_len)) {
		char *arch, *entry, *fname;
		int arch_len, entry_len, fname_len, free_filename = 0;
		php_stream_context *context = NULL;
		fname = zend_get_executed_filename(TSRMLS_C);

		if (strncasecmp(fname, "phar://", 7)) {
			goto skip_phar;
		}
		fname_len = strlen(fname);
		if (SUCCESS == phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, \
&entry_len TSRMLS_CC)) {  char *name;
			phar_archive_data **pphar;

			efree(entry);
			entry = filename;
			/* fopen within phar, if :// is not in the url, then prepend phar://<archive>/ */
			entry_len = filename_len;
			if (strstr(entry, "://")) {
				efree(arch);
				if (free_filename) {
					efree(filename);
				}
				goto skip_phar;
			}

			if (ZEND_NUM_ARGS() == 5 && maxlen < 0) {
				php_error_docref(NULL TSRMLS_CC, E_WARNING, "length must be greater than or equal \
to zero");  RETURN_FALSE;
			}

			if (!IS_ABSOLUTE_PATH(filename, filename_len)) {
				/* retrieving a file defaults to within the current directory, so use this if \
possible */  if (SUCCESS == (zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), arch, \
arch_len, (void **) &pphar))) {  name = entry;
					entry = phar_fix_filepath(entry, &entry_len, 1 TSRMLS_CC);
					if (!zend_hash_exists(&((*pphar)->manifest), entry, entry_len)) {
						/* this file is not in the current directory, use the original path */
						efree(entry);
						entry = name;
					}
				}
			}
			/* auto-convert to phar:// */
			spprintf(&name, 4096, "phar://%s/%s", arch, entry);
			if (entry != filename) {
				efree(entry);
			}
			efree(arch);
			if (zcontext) {
				context = php_stream_context_from_zval(zcontext, 0);
			}
			stream = php_stream_open_wrapper_ex(name, "rb", 0 | REPORT_ERRORS, NULL, context);
			if (free_filename) {
				efree(filename);
			}
			efree(name);


			if (!stream) {
				RETURN_FALSE;
			}

			if (offset > 0 && php_stream_seek(stream, offset, SEEK_SET) < 0) {
				php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to seek to position %ld in \
the stream", offset);  php_stream_close(stream);
				RETURN_FALSE;
			}

			/* uses mmap if possible */
			if ((len = php_stream_copy_to_mem(stream, &contents, maxlen, 0)) > 0) {
		
				if (PG(magic_quotes_runtime)) {
					contents = php_addslashes(contents, len, &newlen, 1 TSRMLS_CC); /* 1 = free \
source string */  len = newlen;
				}
		
				RETVAL_STRINGL(contents, len, 0);
			} else if (len == 0) {
				RETVAL_EMPTY_STRING();
			} else {
				RETVAL_FALSE;
			}

			php_stream_close(stream);
			return;
		}
	}
skip_phar:
	PHAR_G(orig_file_get_contents)(INTERNAL_FUNCTION_PARAM_PASSTHRU);
	return;
}

PHAR_FUNC(phar_fopen)
{
	char *filename, *mode;
	int filename_len, mode_len;
	zend_bool use_include_path = 0;
	zval *zcontext = NULL;
	php_stream *stream;

	if (!zend_hash_num_elements(&(PHAR_GLOBALS->phar_fname_map))) {
		/* no need to check, include_path not even specified in fopen/ no active phars */
		goto skip_phar;
	}
	if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, \
"ss|br", &filename, &filename_len, &mode, &mode_len, &use_include_path, &zcontext) == \
FAILURE) {  goto skip_phar;
	}
	if (use_include_path || !IS_ABSOLUTE_PATH(filename, filename_len)) {
		char *arch, *entry, *fname;
		int arch_len, entry_len, fname_len, free_filename = 0;
		php_stream_context *context = NULL;
		fname = zend_get_executed_filename(TSRMLS_C);

		if (strncasecmp(fname, "phar://", 7)) {
			goto skip_phar;
		}
		fname_len = strlen(fname);
		if (SUCCESS == phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, \
&entry_len TSRMLS_CC)) {  char *name;
			phar_archive_data **pphar;

			efree(entry);
			entry = filename;
			/* fopen within phar, if :// is not in the url, then prepend phar://<archive>/ */
			entry_len = filename_len;
			if (strstr(entry, "://")) {
				efree(arch);
				if (free_filename) {
					efree(filename);
				}
				goto skip_phar;
			}
			/* retrieving a file defaults to within the current directory, so use this if \
possible */  if (SUCCESS == (zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), arch, \
arch_len, (void **) &pphar))) {  name = entry;
				entry = phar_fix_filepath(entry, &entry_len, 1 TSRMLS_CC);
				if (!zend_hash_exists(&((*pphar)->manifest), entry, entry_len)) {
					/* this file is not in the current directory, use the original path */
					efree(entry);
					entry = name;
				}
			}
			/* auto-convert to phar:// */
			spprintf(&name, 4096, "phar://%s/%s", arch, entry);
			if (entry != filename) {
				efree(entry);
			}
			efree(arch);
			context = php_stream_context_from_zval(zcontext, 0);
			stream = php_stream_open_wrapper_ex(name, mode, 0 | REPORT_ERRORS, NULL, context);
			efree(name);
			if (stream == NULL) {
				RETURN_FALSE;
			}
			php_stream_to_zval(stream, return_value);
			if (zcontext) {
				zend_list_addref(Z_RESVAL_P(zcontext));
			}
			if (free_filename) {
				efree(filename);
			}
			return;
		}
	}
skip_phar:
	PHAR_G(orig_fopen)(INTERNAL_FUNCTION_PARAM_PASSTHRU);
	return;
}

#define IS_LINK_OPERATION(__t) ((__t) == FS_TYPE || (__t) == FS_IS_LINK || (__t) == \
FS_LSTAT) #define IS_EXISTS_CHECK(__t) ((__t) == FS_EXISTS  || (__t) == FS_IS_W || \
(__t) == FS_IS_R || (__t) == FS_IS_X || (__t) == FS_IS_FILE || (__t) == FS_IS_DIR || \
(__t) == FS_IS_LINK) #define IS_ABLE_CHECK(__t) ((__t) == FS_IS_R || (__t) == FS_IS_W \
|| (__t) == FS_IS_X) #define IS_ACCESS_CHECK(__t) (IS_ABLE_CHECK(type) || (__t) == \
FS_EXISTS)

/* {{{ php_stat
 */
PHPAPI void phar_fancy_stat(struct stat *stat_sb, int type, zval *return_value \
TSRMLS_DC) {
	zval *stat_dev, *stat_ino, *stat_mode, *stat_nlink, *stat_uid, *stat_gid, \
                *stat_rdev,
		 *stat_size, *stat_atime, *stat_mtime, *stat_ctime, *stat_blksize, *stat_blocks;
	php_stream_statbuf ssb;
	int rmask=S_IROTH, wmask=S_IWOTH, xmask=S_IXOTH; /* access rights defaults to other \
*/  char *stat_sb_names[13] = {
		"dev", "ino", "mode", "nlink", "uid", "gid", "rdev",
		"size", "atime", "mtime", "ctime", "blksize", "blocks"
	};

#ifndef NETWARE
	if (type >= FS_IS_W && type <= FS_IS_X) {
		if(stat_sb->st_uid==getuid()) {
			rmask=S_IRUSR;
			wmask=S_IWUSR;
			xmask=S_IXUSR;
		} else if(stat_sb->st_gid==getgid()) {
			rmask=S_IRGRP;
			wmask=S_IWGRP;
			xmask=S_IXGRP;
		} else {
			int   groups, n, i;
			gid_t *gids;

			groups = getgroups(0, NULL);
			if(groups > 0) {
				gids=(gid_t *)safe_emalloc(groups, sizeof(gid_t), 0);
				n=getgroups(groups, gids);
				for(i=0;i<n;i++){
					if(stat_sb->st_gid==gids[i]) {
						rmask=S_IRGRP;
						wmask=S_IWGRP;
						xmask=S_IXGRP;
						break;
					}
				}
				efree(gids);
			}
		}
	}
#endif

	switch (type) {
	case FS_PERMS:
		RETURN_LONG((long)stat_sb->st_mode);
	case FS_INODE:
		RETURN_LONG((long)stat_sb->st_ino);
	case FS_SIZE:
		RETURN_LONG((long)stat_sb->st_size);
	case FS_OWNER:
		RETURN_LONG((long)stat_sb->st_uid);
	case FS_GROUP:
		RETURN_LONG((long)stat_sb->st_gid);
	case FS_ATIME:
#ifdef NETWARE
		RETURN_LONG((long)stat_sb->st_atime.tv_sec);
#else
		RETURN_LONG((long)stat_sb->st_atime);
#endif
	case FS_MTIME:
#ifdef NETWARE
		RETURN_LONG((long)stat_sb->st_mtime.tv_sec);
#else
		RETURN_LONG((long)stat_sb->st_mtime);
#endif
	case FS_CTIME:
#ifdef NETWARE
		RETURN_LONG((long)stat_sb->st_ctime.tv_sec);
#else
		RETURN_LONG((long)stat_sb->st_ctime);
#endif
	case FS_TYPE:
		if (S_ISLNK(stat_sb->st_mode)) {
			RETURN_STRING("link", 1);
		}
		switch(stat_sb->st_mode & S_IFMT) {
		case S_IFIFO: RETURN_STRING("fifo", 1);
		case S_IFCHR: RETURN_STRING("char", 1);
		case S_IFDIR: RETURN_STRING("dir", 1);
		case S_IFBLK: RETURN_STRING("block", 1);
		case S_IFREG: RETURN_STRING("file", 1);
#if defined(S_IFSOCK) && !defined(ZEND_WIN32)&&!defined(__BEOS__)
		case S_IFSOCK: RETURN_STRING("socket", 1);
#endif
		}
		php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Unknown file type (%d)", \
stat_sb->st_mode&S_IFMT);  RETURN_STRING("unknown", 1);
	case FS_IS_W:
		RETURN_BOOL((stat_sb->st_mode & wmask) != 0);
	case FS_IS_R:
		RETURN_BOOL((stat_sb->st_mode&rmask)!=0);
	case FS_IS_X:
		RETURN_BOOL((stat_sb->st_mode&xmask)!=0 && !S_ISDIR(stat_sb->st_mode));
	case FS_IS_FILE:
		RETURN_BOOL(S_ISREG(stat_sb->st_mode));
	case FS_IS_DIR:
		RETURN_BOOL(S_ISDIR(stat_sb->st_mode));
	case FS_IS_LINK:
		RETURN_BOOL(S_ISLNK(stat_sb->st_mode));
	case FS_EXISTS:
		RETURN_TRUE; /* the false case was done earlier */
	case FS_LSTAT:
		/* FALLTHROUGH */
	case FS_STAT:
		array_init(return_value);

		MAKE_LONG_ZVAL_INCREF(stat_dev, stat_sb->st_dev);
		MAKE_LONG_ZVAL_INCREF(stat_ino, stat_sb->st_ino);
		MAKE_LONG_ZVAL_INCREF(stat_mode, stat_sb->st_mode);
		MAKE_LONG_ZVAL_INCREF(stat_nlink, stat_sb->st_nlink);
		MAKE_LONG_ZVAL_INCREF(stat_uid, stat_sb->st_uid);
		MAKE_LONG_ZVAL_INCREF(stat_gid, stat_sb->st_gid);
#ifdef HAVE_ST_RDEV
		MAKE_LONG_ZVAL_INCREF(stat_rdev, stat_sb->st_rdev);
#else
		MAKE_LONG_ZVAL_INCREF(stat_rdev, -1);
#endif
		MAKE_LONG_ZVAL_INCREF(stat_size, stat_sb->st_size);
#ifdef NETWARE
		MAKE_LONG_ZVAL_INCREF(stat_atime, (stat_sb->st_atime).tv_sec);
		MAKE_LONG_ZVAL_INCREF(stat_mtime, (stat_sb->st_mtime).tv_sec);
		MAKE_LONG_ZVAL_INCREF(stat_ctime, (stat_sb->st_ctime).tv_sec);
#else
		MAKE_LONG_ZVAL_INCREF(stat_atime, stat_sb->st_atime);
		MAKE_LONG_ZVAL_INCREF(stat_mtime, stat_sb->st_mtime);
		MAKE_LONG_ZVAL_INCREF(stat_ctime, stat_sb->st_ctime);
#endif
#ifdef HAVE_ST_BLKSIZE
		MAKE_LONG_ZVAL_INCREF(stat_blksize, stat_sb->st_blksize);
#else
		MAKE_LONG_ZVAL_INCREF(stat_blksize,-1);
#endif
#ifdef HAVE_ST_BLOCKS
		MAKE_LONG_ZVAL_INCREF(stat_blocks, stat_sb->st_blocks);
#else
		MAKE_LONG_ZVAL_INCREF(stat_blocks,-1);
#endif
		/* Store numeric indexes in propper order */
		zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_dev, sizeof(zval \
*), NULL);  zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_ino, \
sizeof(zval *), NULL);  zend_hash_next_index_insert(HASH_OF(return_value), (void \
*)&stat_mode, sizeof(zval *), NULL);  \
zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_nlink, sizeof(zval \
*), NULL);  zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_uid, \
sizeof(zval *), NULL);  zend_hash_next_index_insert(HASH_OF(return_value), (void \
*)&stat_gid, sizeof(zval *), NULL);

		zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_rdev, sizeof(zval \
*), NULL);  zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_size, \
sizeof(zval *), NULL);  zend_hash_next_index_insert(HASH_OF(return_value), (void \
*)&stat_atime, sizeof(zval *), NULL);  \
zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_mtime, sizeof(zval \
*), NULL);  zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_ctime, \
sizeof(zval *), NULL);  zend_hash_next_index_insert(HASH_OF(return_value), (void \
*)&stat_blksize, sizeof(zval *), NULL);  \
zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_blocks, sizeof(zval \
*), NULL);

		/* Store string indexes referencing the same zval*/
		zend_hash_update(HASH_OF(return_value), stat_sb_names[0], \
strlen(stat_sb_names[0])+1, (void *) &stat_dev, sizeof(zval *), NULL);  \
zend_hash_update(HASH_OF(return_value), stat_sb_names[1], strlen(stat_sb_names[1])+1, \
(void *) &stat_ino, sizeof(zval *), NULL);  zend_hash_update(HASH_OF(return_value), \
stat_sb_names[2], strlen(stat_sb_names[2])+1, (void *) &stat_mode, sizeof(zval *), \
NULL);  zend_hash_update(HASH_OF(return_value), stat_sb_names[3], \
strlen(stat_sb_names[3])+1, (void *) &stat_nlink, sizeof(zval *), NULL);  \
zend_hash_update(HASH_OF(return_value), stat_sb_names[4], strlen(stat_sb_names[4])+1, \
(void *) &stat_uid, sizeof(zval *), NULL);  zend_hash_update(HASH_OF(return_value), \
stat_sb_names[5], strlen(stat_sb_names[5])+1, (void *) &stat_gid, sizeof(zval *), \
NULL);  zend_hash_update(HASH_OF(return_value), stat_sb_names[6], \
strlen(stat_sb_names[6])+1, (void *) &stat_rdev, sizeof(zval *), NULL);  \
zend_hash_update(HASH_OF(return_value), stat_sb_names[7], strlen(stat_sb_names[7])+1, \
(void *) &stat_size, sizeof(zval *), NULL);  zend_hash_update(HASH_OF(return_value), \
stat_sb_names[8], strlen(stat_sb_names[8])+1, (void *) &stat_atime, sizeof(zval *), \
NULL);  zend_hash_update(HASH_OF(return_value), stat_sb_names[9], \
strlen(stat_sb_names[9])+1, (void *) &stat_mtime, sizeof(zval *), NULL);  \
zend_hash_update(HASH_OF(return_value), stat_sb_names[10], \
strlen(stat_sb_names[10])+1, (void *) &stat_ctime, sizeof(zval *), NULL);  \
zend_hash_update(HASH_OF(return_value), stat_sb_names[11], \
strlen(stat_sb_names[11])+1, (void *) &stat_blksize, sizeof(zval *), NULL);  \
zend_hash_update(HASH_OF(return_value), stat_sb_names[12], \
strlen(stat_sb_names[12])+1, (void *) &stat_blocks, sizeof(zval *), NULL);

		return;
	}
	php_error_docref(NULL TSRMLS_CC, E_WARNING, "Didn't understand stat call");
	RETURN_FALSE;
}
/* }}} */

PHPAPI void phar_file_stat(const char *filename, php_stat_len filename_length, int \
type, void (*orig_stat_func)(INTERNAL_FUNCTION_PARAMETERS), \
INTERNAL_FUNCTION_PARAMETERS) {
	if (!filename_length) {
		RETURN_FALSE;
	}

	if (!IS_ABSOLUTE_PATH(filename, filename_len)) {
		char *arch, *entry, *fname;
		int arch_len, entry_len, fname_len;
		fname = zend_get_executed_filename(TSRMLS_C);
		struct stat sb = {0};
		phar_entry_info *data = NULL;
		char *tmp;
		int tmp_len;

		/* we are checking for existence of a file within the relative path.  Chances are \
good that this is  retrieving something from within the phar archive */

		if (strncasecmp(fname, "phar://", 7)) {
			goto skip_phar;
		}
		fname_len = strlen(fname);
		if (SUCCESS == phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, \
&entry_len TSRMLS_CC)) {  phar_archive_data **pphar;

			efree(entry);
			entry = (char *)filename;
			/* fopen within phar, if :// is not in the url, then prepend phar://<archive>/ */
			entry_len = (int) filename_length;
			if (strstr(entry, "://")) {
				efree(arch);
				goto skip_phar;
			}
			if (SUCCESS == (zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), arch, arch_len, \
(void **) &pphar))) {  entry = phar_fix_filepath(entry, &entry_len, 1 TSRMLS_CC);
				if (SUCCESS == zend_hash_find(&((*pphar)->manifest), entry, entry_len, (void **) \
&data)) {  efree(entry);
					goto stat_entry;
				} else {
					char *save = PHAR_G(cwd), *save2 = entry;
					int save_len = PHAR_G(cwd_len), save2_len = entry_len;

					/* this file is not in the current directory, use the original path */
					entry = (char *)filename;
					PHAR_G(cwd) = "/";
					PHAR_G(cwd_len) = 0;
					/* clean path without cwd */
					entry = phar_fix_filepath(entry, &entry_len, 1 TSRMLS_CC);
					if (SUCCESS == zend_hash_find(&((*pphar)->manifest), entry, entry_len, (void **) \
&data)) {  PHAR_G(cwd) = save;
						PHAR_G(cwd_len) = save_len;
						efree(entry);
						efree(save2);
						goto stat_entry;
					} else {
						phar_archive_data *phar = *pphar;
						char *key;
						uint keylen;
						ulong unused;

						/* original not found either, this is possibly a directory relative to cwd */
						zend_hash_internal_pointer_reset(&phar->manifest);
						while (FAILURE != zend_hash_has_more_elements(&phar->manifest)) {
							if (HASH_KEY_NON_EXISTANT !=
									zend_hash_get_current_key_ex(
										&phar->manifest, &key, &keylen, &unused, 0, NULL)) {
								if (0 == memcmp(save2, key, save2_len)) {
									PHAR_G(cwd) = save;
									PHAR_G(cwd_len) = save_len;
									efree(save2);
									efree(entry);
									/* directory found, all dirs have the same stat */
									if (key[save2_len] == '/') {
										sb.st_size = 0;
										sb.st_mode = 0777;
										sb.st_mode |= S_IFDIR; /* regular directory */
#ifdef NETWARE
										sb.st_mtime.tv_sec = phar->max_timestamp;
										sb.st_atime.tv_sec = phar->max_timestamp;
										sb.st_ctime.tv_sec = phar->max_timestamp;
#else
										sb.st_mtime = phar->max_timestamp;
										sb.st_atime = phar->max_timestamp;
										sb.st_ctime = phar->max_timestamp;
#endif
										goto statme_baby;
									}
								}
							}
							if (SUCCESS != zend_hash_move_forward(&phar->manifest)) {
								break;
							}
						}
					}
					PHAR_G(cwd) = save;
					PHAR_G(cwd_len) = save_len;
					efree(entry);
					efree(save2);
					/* Error Occured */
					if (!IS_EXISTS_CHECK(type)) {
						php_error_docref(NULL TSRMLS_CC, E_WARNING, "%sstat failed for %s", \
IS_LINK_OPERATION(type) ? "L" : "", filename);  }
					RETURN_FALSE;
				}
			}
stat_entry:
			if (!data->is_dir) {
				sb.st_size = data->uncompressed_filesize;
				sb.st_mode = data->flags & PHAR_ENT_PERM_MASK;
				sb.st_mode |= S_IFREG; /* regular file */
				/* timestamp is just the timestamp when this was added to the phar */
#ifdef NETWARE
				sb.st_mtime.tv_sec = data->timestamp;
				sb.st_atime.tv_sec = data->timestamp;
				sb.st_ctime.tv_sec = data->timestamp;
#else
				sb.st_mtime = data->timestamp;
				sb.st_atime = data->timestamp;
				sb.st_ctime = data->timestamp;
#endif
			} else {
				sb.st_size = 0;
				sb.st_mode = data->flags & PHAR_ENT_PERM_MASK;
				sb.st_mode |= S_IFDIR; /* regular directory */
				/* timestamp is just the timestamp when this was added to the phar */
#ifdef NETWARE
				sb.st_mtime.tv_sec = data->timestamp;
				sb.st_atime.tv_sec = data->timestamp;
				sb.st_ctime.tv_sec = data->timestamp;
#else
				sb.st_mtime = data->timestamp;
				sb.st_atime = data->timestamp;
				sb.st_ctime = data->timestamp;
#endif
			}

statme_baby:
			efree(arch);
			if (!(*pphar)->is_writeable) {
				sb.st_mode = (sb.st_mode & 0555) | (sb.st_mode & ~0777);
			}
		
			sb.st_nlink = 1;
			sb.st_rdev = -1;
			if (data) {
				tmp_len = data->filename_len + (*pphar)->alias_len;
			} else {
				tmp_len = (*pphar)->alias_len + 1;
			}
			tmp = (char *) emalloc(tmp_len);
			memcpy(tmp, (*pphar)->alias, (*pphar)->alias_len);
			if (data) {
				memcpy(tmp + (*pphar)->alias_len, data->filename, data->filename_len);
			} else {
				*(tmp + (*pphar)->alias_len) = '/';
			}
			/* this is only for APC, so use /dev/null device - no chance of conflict there! */
			sb.st_dev = 0xc;
			/* generate unique inode number for alias/filename, so no phars will conflict */
			sb.st_ino = (unsigned short)zend_get_hash_value(tmp, tmp_len);
			efree(tmp);
#ifndef PHP_WIN32
			sb.st_blksize = -1;
			sb.st_blocks = -1;
#endif
			phar_fancy_stat(&sb, type, return_value TSRMLS_CC);
			return;
		}
	}
skip_phar:
	orig_stat_func(INTERNAL_FUNCTION_PARAM_PASSTHRU);
	return;
}

#define PharFileFunction(fname, funcnum, orig) \
void fname(INTERNAL_FUNCTION_PARAMETERS) { \
	char *filename; \
	int filename_len; \
	\
	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &filename, &filename_len) \
== FAILURE) { \  return; \
	} \
	\
	phar_file_stat(filename, (php_stat_len) filename_len, funcnum, PHAR_G(orig), \
INTERNAL_FUNCTION_PARAM_PASSTHRU); \ }
/* }}} */

/* {{{ proto int fileperms(string filename)
   Get file permissions */
PharFileFunction(phar_fileperms, FS_PERMS, orig_fileperms)
/* }}} */

/* {{{ proto int fileinode(string filename)
   Get file inode */
PharFileFunction(phar_fileinode, FS_INODE, orig_fileinode)
/* }}} */

/* {{{ proto int filesize(string filename)
   Get file size */
PharFileFunction(phar_filesize, FS_SIZE, orig_filesize)
/* }}} */

/* {{{ proto int fileowner(string filename)
   Get file owner */
PharFileFunction(phar_fileowner, FS_OWNER, orig_fileowner)
/* }}} */

/* {{{ proto int filegroup(string filename)
   Get file group */
PharFileFunction(phar_filegroup, FS_GROUP, orig_filegroup)
/* }}} */

/* {{{ proto int fileatime(string filename)
   Get last access time of file */
PharFileFunction(phar_fileatime, FS_ATIME, orig_fileatime)
/* }}} */

/* {{{ proto int filemtime(string filename)
   Get last modification time of file */
PharFileFunction(phar_filemtime, FS_MTIME, orig_filemtime)
/* }}} */

/* {{{ proto int filectime(string filename)
   Get inode modification time of file */
PharFileFunction(phar_filectime, FS_CTIME, orig_filectime)
/* }}} */

/* {{{ proto string filetype(string filename)
   Get file type */
PharFileFunction(phar_filetype, FS_TYPE, orig_filetype)
/* }}} */

/* {{{ proto bool is_writable(string filename)
   Returns true if file can be written */
PharFileFunction(phar_is_writable, FS_IS_W, orig_is_writable)
/* }}} */

/* {{{ proto bool is_readable(string filename)
   Returns true if file can be read */
PharFileFunction(phar_is_readable, FS_IS_R, orig_is_readable)
/* }}} */

/* {{{ proto bool is_executable(string filename)
   Returns true if file is executable */
PharFileFunction(phar_is_executable, FS_IS_X, orig_is_executable)
/* }}} */

/* {{{ proto bool is_executable(string filename)
   Returns true if file is executable */
PharFileFunction(phar_file_exists, FS_EXISTS, orig_file_exists)
/* }}} */

/* {{{ proto bool is_executable(string filename)
   Returns true if file is executable */
PharFileFunction(phar_is_dir, FS_IS_DIR, orig_is_dir)
/* }}} */

PHAR_FUNC(phar_is_file)
{
	char *filename;
	int filename_len;

	if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, \
"s", &filename, &filename_len) == FAILURE) {  goto skip_phar;
	}
	if (!IS_ABSOLUTE_PATH(filename, filename_len)) {
		char *arch, *entry, *fname;
		int arch_len, entry_len, fname_len, free_filename = 0;
		fname = zend_get_executed_filename(TSRMLS_C);

		/* we are checking for existence of a file within the relative path.  Chances are \
good that this is  retrieving something from within the phar archive */

		if (strncasecmp(fname, "phar://", 7)) {
			goto skip_phar;
		}
		fname_len = strlen(fname);
		if (SUCCESS == phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, \
&entry_len TSRMLS_CC)) {  phar_archive_data **pphar;

			efree(entry);
			entry = filename;
			/* fopen within phar, if :// is not in the url, then prepend phar://<archive>/ */
			entry_len = filename_len;
			if (strstr(entry, "://")) {
				efree(arch);
				if (free_filename) {
					efree(filename);
				}
				goto skip_phar;
			}
			/* retrieving a file within the current directory, so use this if possible */
			if (SUCCESS == (zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), arch, arch_len, \
(void **) &pphar))) {  entry = phar_fix_filepath(entry, &entry_len, 1 TSRMLS_CC);
				if (zend_hash_exists(&((*pphar)->manifest), entry, entry_len)) {
					/* this file is not in the current directory, use the original path */
					efree(entry);
					efree(arch);
					RETURN_TRUE;
				}
			}
			efree(entry);
			efree(arch);
			RETURN_FALSE;
		}
	}
skip_phar:
	PHAR_G(orig_is_file)(INTERNAL_FUNCTION_PARAM_PASSTHRU);
	return;
}

PHAR_FUNC(phar_is_link)
{
	char *filename;
	int filename_len;

	if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, \
"s", &filename, &filename_len) == FAILURE) {  goto skip_phar;
	}
	if (!IS_ABSOLUTE_PATH(filename, filename_len)) {
		char *arch, *entry, *fname;
		int arch_len, entry_len, fname_len, free_filename = 0;
		fname = zend_get_executed_filename(TSRMLS_C);

		/* we are checking for existence of a file within the relative path.  Chances are \
good that this is  retrieving something from within the phar archive */

		if (strncasecmp(fname, "phar://", 7)) {
			goto skip_phar;
		}
		fname_len = strlen(fname);
		if (SUCCESS == phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, \
&entry_len TSRMLS_CC)) {  phar_archive_data **pphar;

			efree(entry);
			entry = filename;
			/* fopen within phar, if :// is not in the url, then prepend phar://<archive>/ */
			entry_len = filename_len;
			if (strstr(entry, "://")) {
				efree(arch);
				if (free_filename) {
					efree(filename);
				}
				goto skip_phar;
			}
			/* retrieving a file within the current directory, so use this if possible */
			if (SUCCESS == (zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), arch, arch_len, \
(void **) &pphar))) {  phar_entry_info *etemp;

				entry = phar_fix_filepath(entry, &entry_len, 1 TSRMLS_CC);
				if (SUCCESS == zend_hash_find(&((*pphar)->manifest), entry, entry_len, (void **) \
                &etemp)) {
					/* this file is not in the current directory, use the original path */
					efree(entry);
					efree(arch);
					RETURN_BOOL(etemp->link);
				}
			}
			efree(entry);
			efree(arch);
			RETURN_FALSE;
		}
	}
skip_phar:
	PHAR_G(orig_file_exists)(INTERNAL_FUNCTION_PARAM_PASSTHRU);
	return;
}

/* {{{ proto array lstat(string filename)
   Give information about a file or symbolic link */
PharFileFunction(phar_lstat, FS_LSTAT, orig_lstat)
/* }}} */

/* {{{ proto array stat(string filename)
   Give information about a file */
PharFileFunction(phar_stat, FS_STAT, orig_stat)
/* }}} */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: noet sw=4 ts=4 fdm=marker
 * vim<600: noet sw=4 ts=4
 */

http://cvs.php.net/viewvc.cgi/pecl/phar/func_interceptors.h?view=markup&rev=1.1
Index: pecl/phar/func_interceptors.h
+++ pecl/phar/func_interceptors.h
/*
  +----------------------------------------------------------------------+
  | phar php single-file executable PHP extension                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 2006-2007 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt.                                 |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Authors: Gregory Beaver <cellog@php.net>                             |
  |          Marcus Boerger <helly@php.net>                              |
  +----------------------------------------------------------------------+
*/

/* $Id: func_interceptors.h,v 1.1 2008/01/11 07:30:02 cellog Exp $ */

BEGIN_EXTERN_C()
void phar_intercept_functions(TSRMLS_D);
void phar_release_functions(TSRMLS_D);
END_EXTERN_C()

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: noet sw=4 ts=4 fdm=marker
 * vim<600: noet sw=4 ts=4
 */



[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic