cellog Wed Jan 9 07:09:03 2008 UTC
Added files:
/pecl/phar/tests/tar tar_gzip.phpt
Modified files:
/pecl/phar TODO package.php phar.c phar_internal.h phar_object.c
tar.c
Log:
implement whole-file compression of phars for phar/tar-based phars
still not 100% working, add failing test
add Phar::isCompressed(), which returns either 0, Phar::GZ, or Phar::BZ2
[DOC]
http://cvs.php.net/viewvc.cgi/pecl/phar/TODO?r1=1.49&r2=1.50&diff_format=u
Index: pecl/phar/TODO
diff -u pecl/phar/TODO:1.49 pecl/phar/TODO:1.50
--- pecl/phar/TODO:1.49 Wed Jan 9 03:53:41 2008
+++ pecl/phar/TODO Wed Jan 9 07:09:03 2008
@@ -68,6 +68,5 @@
X Phar::copy($from, $to); [Greg]
X Phar::delete($what) [Greg]
X Phar::buildFromIterator(Iterator $it[, string $base_directory]) [Greg]
- * Layout: Option to compress all content rather than single files.
- That excludes stub and manifest haeder. (tar only)
+ X Layout: Option to compress all content rather than single files. (tar/phar
only) [Greg]
X clean crap paths like phar://blah.phar/file//../to\\here.php [Greg]
http://cvs.php.net/viewvc.cgi/pecl/phar/package.php?r1=1.29&r2=1.30&diff_format=u
Index: pecl/phar/package.php
diff -u pecl/phar/package.php:1.29 pecl/phar/package.php:1.30
--- pecl/phar/package.php:1.29 Wed Jan 9 03:53:41 2008
+++ pecl/phar/package.php Wed Jan 9 07:09:03 2008
@@ -9,6 +9,7 @@
* include/fopen with include_path all work 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]
* implement Phar::copy(string $from, string $to) [Greg]
* implement Phar::buildFromIterator(Iterator $it[, string $base_directory])
[Greg]
* add mapping of include/require from within a phar to location within phar
[Greg]
http://cvs.php.net/viewvc.cgi/pecl/phar/phar.c?r1=1.258&r2=1.259&diff_format=u
Index: pecl/phar/phar.c
diff -u pecl/phar/phar.c:1.258 pecl/phar/phar.c:1.259
--- pecl/phar/phar.c:1.258 Wed Jan 9 03:47:21 2008
+++ pecl/phar/phar.c Wed Jan 9 07:09:03 2008
@@ -17,7 +17,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: phar.c,v 1.258 2008/01/09 03:47:21 cellog Exp $ */
+/* $Id: phar.c,v 1.259 2008/01/09 07:09:03 cellog Exp $ */
#define PHAR_MAIN 1
#include "phar_internal.h"
@@ -979,7 +979,7 @@
* This is used by phar_open_filename to process the manifest, but can be
called
* directly.
*/
-int phar_open_file(php_stream *fp, char *fname, int fname_len, char *alias,
int alias_len, long halt_offset, phar_archive_data** pphar, char **error
TSRMLS_DC) /* {{{ */
+int phar_open_file(php_stream *fp, char *fname, int fname_len, char *alias,
int alias_len, long halt_offset, phar_archive_data** pphar, php_uint32
compression, char **error TSRMLS_DC) /* {{{ */
{
char b32[4], *buffer, *endbuffer, *savebuf;
phar_archive_data *mydata = NULL;
@@ -1066,7 +1066,11 @@
PHAR_GET_32(buffer, manifest_flags);
- manifest_flags &= ~PHAR_HDR_COMPRESSION_MASK;
+ manifest_flags &= ~PHAR_HDR_COMPRESSION_MASK;
+
+ manifest_flags &= ~PHAR_FILE_COMPRESSION_MASK;
+ /* remember whether this entire phar was compressed with gz/bzip2 */
+ manifest_flags |= compression;
/* The lowest nibble contains the phar wide flags. The compression
flags can */
/* be ignored on reading because it is being generated anyways. */
@@ -1624,14 +1628,14 @@
{
const char token[] = "__HALT_COMPILER();";
const char zip_magic[] = "PK\x03\x04";
+ const char gz_magic[] = "\x1f\x8b\x08";
+ const char bz_magic[] = "BZh";
char *pos, buffer[1024 + sizeof(token)], test = '\0';
const long readsize = sizeof(buffer) - sizeof(token);
const long tokenlen = sizeof(token) - 1;
long halt_offset;
size_t got;
-
- /* Maybe it's better to compile the file instead of just searching, */
- /* but we only want the offset. So we want a .re scanner to find it. */
+ php_uint32 compression = PHAR_FILE_COMPRESSED_NONE;
if (error) {
*error = NULL;
@@ -1643,6 +1647,9 @@
buffer[sizeof(buffer)-1] = '\0';
memset(buffer, 32, sizeof(token));
halt_offset = 0;
+
+ /* Maybe it's better to compile the file instead of just searching, */
+ /* but we only want the offset. So we want a .re scanner to find it. */
while(!php_stream_eof(fp)) {
if ((got = php_stream_read(fp, buffer+tokenlen, readsize)) <
(size_t) tokenlen) {
MAPPHAR_ALLOC_FAIL("internal corruption of phar \"%s\"
(truncated entry)")
@@ -1650,19 +1657,85 @@
if (!test) {
test = '\1';
pos = buffer+tokenlen;
+ if (!memcmp(pos, gz_magic, 3)) {
+ char err = 0;
+ php_stream_filter *filter;
+ php_stream *temp;
+ /* to properly decompress, we have to tell zlib
to look for a zlib or gzip header */
+ zval filterparams;
+
+ array_init(&filterparams);
+ add_assoc_long(&filterparams, "window",
MAX_WBITS + 32);
+ /* entire file is gzip-compressed, uncompress
to temporary file */
+ if (!(temp = php_stream_fopen_tmpfile())) {
+ MAPPHAR_ALLOC_FAIL("unable to create
temporary file for decompression of gzipped phar archive \"%s\"")
+ }
+ php_stream_rewind(fp);
+ filter =
php_stream_filter_create("zlib.inflate", &filterparams,
php_stream_is_persistent(fp) TSRMLS_CC);
+ if (!filter) {
+ err = 1;
+ add_assoc_long(&filterparams, "window",
MAX_WBITS);
+ filter =
php_stream_filter_create("zlib.inflate", &filterparams,
php_stream_is_persistent(fp) TSRMLS_CC);
+ }
+ zval_dtor(&filterparams);
+ php_stream_filter_append(&temp->writefilters,
filter);
+ if (0 == php_stream_copy_to_stream(fp, temp,
PHP_STREAM_COPY_ALL)) {
+ if (err) {
+ MAPPHAR_ALLOC_FAIL("unable to
decompress gzipped phar archive \"%s\", ext/zlib is buggy in PHP versions older
than 5.2.6")
+ }
+ php_stream_close(temp);
+ MAPPHAR_ALLOC_FAIL("unable to
decompress gzipped phar archive \"%s\" to temporary file")
+ }
+ php_stream_filter_flush(filter, 1);
+ php_stream_filter_remove(filter, 1 TSRMLS_CC);
+ php_stream_close(fp);
+ fp = temp;
+ php_stream_rewind(fp);
+ compression = PHAR_FILE_COMPRESSED_GZ;
+
+ /* now, start over */
+ test = '\0';
+ continue;
+ } else if (!memcmp(pos, bz_magic, 3)) {
+ php_stream_filter *filter;
+ php_stream *temp;
+
+ /* entire file is bzip-compressed, uncompress
to temporary file */
+ if (!(temp = php_stream_fopen_tmpfile())) {
+ MAPPHAR_ALLOC_FAIL("unable to create
temporary file for decompression of bzipped phar archive \"%s\"")
+ }
+ php_stream_rewind(fp);
+ filter =
php_stream_filter_create("bzip2.decompress", NULL, php_stream_is_persistent(fp)
TSRMLS_CC);
+ php_stream_filter_append(&temp->writefilters,
filter);
+ if (0 == php_stream_copy_to_stream(fp, temp,
PHP_STREAM_COPY_ALL)) {
+ php_stream_close(temp);
+ MAPPHAR_ALLOC_FAIL("unable to
decompress gzipped phar archive \"%s\" to temporary file")
+ }
+ php_stream_filter_flush(filter, 1);
+ php_stream_filter_remove(filter, 1 TSRMLS_CC);
+ php_stream_close(fp);
+ fp = temp;
+ php_stream_rewind(fp);
+ compression = PHAR_FILE_COMPRESSED_BZ2;
+
+ /* now, start over */
+ test = '\0';
+ continue;
+ }
if (!memcmp(pos, zip_magic, 4)) {
php_stream_close(fp);
return phar_open_zipfile(fname, fname_len,
alias, alias_len, pphar, error TSRMLS_CC);
}
if (got > 512) {
if (phar_is_tar(pos)) {
- return phar_open_tarfile(fp, fname,
fname_len, alias, alias_len, options, pphar, error TSRMLS_CC);
+ php_stream_rewind(fp);
+ return phar_open_tarfile(fp, fname,
fname_len, alias, alias_len, options, pphar, compression, error TSRMLS_CC);
}
}
}
if ((pos = strstr(buffer, token)) != NULL) {
halt_offset += (pos - buffer); /* no -tokenlen+tokenlen
here */
- return phar_open_file(fp, fname, fname_len, alias,
alias_len, halt_offset, pphar, error TSRMLS_CC);
+ return phar_open_file(fp, fname, fname_len, alias,
alias_len, halt_offset, pphar, compression, error TSRMLS_CC);
}
halt_offset += got;
@@ -1969,7 +2042,7 @@
return FAILURE;
}
- return phar_open_file(fp, fname, fname_len, alias, alias_len,
halt_offset, NULL, error TSRMLS_CC);
+ return phar_open_file(fp, fname, fname_len, alias, alias_len,
halt_offset, NULL, PHAR_FILE_COMPRESSED_NONE, error TSRMLS_CC);
}
/* }}} */
@@ -2266,7 +2339,7 @@
* user_stub contains either a string, or a resource pointer, if len is a
negative length.
* user_stub and len should be both 0 if the default or existing stub should
be used
*/
-int phar_flush(phar_archive_data *archive, char *user_stub, long len, char
**error TSRMLS_DC) /* {{{ */
+int phar_flush(phar_archive_data *phar, char *user_stub, long len, char
**error TSRMLS_DC) /* {{{ */
{
static const char newstub[] = "<?php __HALT_COMPILER(); ?>\r\n";
phar_entry_info *entry, *newentry;
@@ -2293,19 +2366,19 @@
}
#if HAVE_PHAR_ZIP
- if (archive->is_zip) {
- return phar_zip_flush(archive, user_stub, len, error TSRMLS_CC);
+ if (phar->is_zip) {
+ return phar_zip_flush(phar, user_stub, len, error TSRMLS_CC);
}
#endif
- if (archive->is_tar) {
- return phar_tar_flush(archive, user_stub, len, error TSRMLS_CC);
+ if (phar->is_tar) {
+ return phar_tar_flush(phar, user_stub, len, error TSRMLS_CC);
}
- if (archive->fp && !archive->is_brandnew) {
- oldfile = archive->fp;
+ if (phar->fp && !phar->is_brandnew) {
+ oldfile = phar->fp;
closeoldfile = 0;
php_stream_rewind(oldfile);
} else {
- oldfile = php_stream_open_wrapper(archive->fname, "rb", 0,
NULL);
+ oldfile = php_stream_open_wrapper(phar->fname, "rb", 0, NULL);
closeoldfile = oldfile != NULL;
}
newfile = php_stream_fopen_tmpfile();
@@ -2328,7 +2401,7 @@
}
php_stream_close(newfile);
if (error) {
- spprintf(error, 0, "unable to access
resource to copy stub to new phar \"%s\"", archive->fname);
+ spprintf(error, 0, "unable to access
resource to copy stub to new phar \"%s\"", phar->fname);
}
return EOF;
}
@@ -2344,7 +2417,7 @@
}
php_stream_close(newfile);
if (error) {
- spprintf(error, 0, "unable to read
resource to copy stub to new phar \"%s\"", archive->fname);
+ spprintf(error, 0, "unable to read
resource to copy stub to new phar \"%s\"", phar->fname);
}
return EOF;
}
@@ -2359,7 +2432,7 @@
}
php_stream_close(newfile);
if (error) {
- spprintf(error, 0, "illegal stub for phar
\"%s\"", archive->fname);
+ spprintf(error, 0, "illegal stub for phar
\"%s\"", phar->fname);
}
if (free_user_stub) {
efree(user_stub);
@@ -2374,39 +2447,39 @@
}
php_stream_close(newfile);
if (error) {
- spprintf(error, 0, "unable to create stub from
string in new phar \"%s\"", archive->fname);
+ spprintf(error, 0, "unable to create stub from
string in new phar \"%s\"", phar->fname);
}
if (free_user_stub) {
efree(user_stub);
}
return EOF;
}
- archive->halt_offset = len + 5;
+ phar->halt_offset = len + 5;
if (free_user_stub) {
efree(user_stub);
}
} else {
- if (archive->halt_offset && oldfile && !archive->is_brandnew) {
- if (archive->halt_offset !=
php_stream_copy_to_stream(oldfile, newfile, archive->halt_offset)) {
+ if (phar->halt_offset && oldfile && !phar->is_brandnew) {
+ if (phar->halt_offset !=
php_stream_copy_to_stream(oldfile, newfile, phar->halt_offset)) {
if (closeoldfile) {
php_stream_close(oldfile);
}
php_stream_close(newfile);
if (error) {
- spprintf(error, 0, "unable to copy stub
of old phar to new phar \"%s\"", archive->fname);
+ spprintf(error, 0, "unable to copy stub
of old phar to new phar \"%s\"", phar->fname);
}
return EOF;
}
} else {
/* this is a brand new phar */
- archive->halt_offset = sizeof(newstub)-1;
+ phar->halt_offset = sizeof(newstub)-1;
if (sizeof(newstub)-1 != php_stream_write(newfile,
newstub, sizeof(newstub)-1)) {
if (closeoldfile) {
php_stream_close(oldfile);
}
php_stream_close(newfile);
if (error) {
- spprintf(error, 0, "unable to create
stub in new phar \"%s\"", archive->fname);
+ spprintf(error, 0, "unable to create
stub in new phar \"%s\"", phar->fname);
}
return EOF;
}
@@ -2418,13 +2491,13 @@
/* Check whether we can get rid of some of the deleted entries which are
* unused. However some might still be in use so even after this
clean-up
* we need to skip entries marked is_deleted. */
- zend_hash_apply(&archive->manifest, phar_flush_clean_deleted_apply
TSRMLS_CC);
+ zend_hash_apply(&phar->manifest, phar_flush_clean_deleted_apply
TSRMLS_CC);
/* compress as necessary, calculate crcs, serialize meta-data, manifest
size, and file sizes */
main_metadata_str.c = 0;
- if (archive->metadata) {
+ if (phar->metadata) {
PHP_VAR_SERIALIZE_INIT(metadata_hash);
- php_var_serialize(&main_metadata_str, &archive->metadata,
&metadata_hash TSRMLS_CC);
+ php_var_serialize(&main_metadata_str, &phar->metadata,
&metadata_hash TSRMLS_CC);
PHP_VAR_SERIALIZE_DESTROY(metadata_hash);
} else {
main_metadata_str.len = 0;
@@ -2432,10 +2505,10 @@
new_manifest_count = 0;
offset = 0;
buf = (char *) emalloc(8192);
- for (zend_hash_internal_pointer_reset(&archive->manifest);
- zend_hash_has_more_elements(&archive->manifest) == SUCCESS;
- zend_hash_move_forward(&archive->manifest)) {
- if (zend_hash_get_current_data(&archive->manifest, (void
**)&entry) == FAILURE) {
+ for (zend_hash_internal_pointer_reset(&phar->manifest);
+ zend_hash_has_more_elements(&phar->manifest) == SUCCESS;
+ zend_hash_move_forward(&phar->manifest)) {
+ if (zend_hash_get_current_data(&phar->manifest, (void
**)&entry) == FAILURE) {
continue;
}
if (entry->cfp) {
@@ -2471,9 +2544,9 @@
if (oldfile && !entry->is_modified) {
continue;
}
- if (!entry->fp || (entry->is_modified && entry->fp ==
archive->fp)) {
+ if (!entry->fp || (entry->is_modified && entry->fp ==
phar->fp)) {
/* re-open internal file pointer just-in-time */
- newentry = phar_open_jit(archive, entry, oldfile,
error, 0 TSRMLS_CC);
+ newentry = phar_open_jit(phar, entry, oldfile, error, 0
TSRMLS_CC);
if (!newentry) {
/* major problem re-opening, so we ignore this
file and the error */
efree(*error);
@@ -2483,14 +2556,14 @@
entry = newentry;
}
file = entry->fp;
- if (file == archive->fp) {
- if (-1 == php_stream_seek(file,
entry->offset_within_phar + archive->internal_file_start, SEEK_SET)) {
+ if (file == phar->fp) {
+ if (-1 == php_stream_seek(file,
entry->offset_within_phar + phar->internal_file_start, SEEK_SET)) {
if (closeoldfile) {
php_stream_close(oldfile);
}
php_stream_close(newfile);
if (error) {
- spprintf(error, 0, "unable to seek to
start of file \"%s\" while creating new phar \"%s\"", entry->filename,
archive->fname);
+ spprintf(error, 0, "unable to seek to
start of file \"%s\" while creating new phar \"%s\"", entry->filename,
phar->fname);
}
return EOF;
}
@@ -2517,11 +2590,11 @@
php_stream_close(newfile);
if (entry->flags & PHAR_ENT_COMPRESSED_GZ) {
if (error) {
- spprintf(error, 0, "unable to gzip
compress file \"%s\" to new phar \"%s\"", entry->filename, archive->fname);
+ spprintf(error, 0, "unable to gzip
compress file \"%s\" to new phar \"%s\"", entry->filename, phar->fname);
}
} else {
if (error) {
- spprintf(error, 0, "unable to bzip2
compress file \"%s\" to new phar \"%s\"", entry->filename, archive->fname);
+ spprintf(error, 0, "unable to bzip2
compress file \"%s\" to new phar \"%s\"", entry->filename, phar->fname);
}
}
efree(buf);
@@ -2544,14 +2617,14 @@
return EOF;
}
php_stream_flush(file);
- if (file == archive->fp) {
- if (-1 == php_stream_seek(file,
entry->offset_within_phar + archive->internal_file_start, SEEK_SET)) {
+ if (file == phar->fp) {
+ if (-1 == php_stream_seek(file,
entry->offset_within_phar + phar->internal_file_start, SEEK_SET)) {
if (closeoldfile) {
php_stream_close(oldfile);
}
php_stream_close(newfile);
if (error) {
- spprintf(error, 0, "unable to seek to
start of file \"%s\" while creating new phar \"%s\"", entry->filename,
archive->fname);
+ spprintf(error, 0, "unable to seek to
start of file \"%s\" while creating new phar \"%s\"", entry->filename,
phar->fname);
}
return EOF;
}
@@ -2582,34 +2655,34 @@
* 4: phar metadata length
* ?: phar metadata
*/
- restore_alias_len = archive->alias_len;
- if (!archive->is_explicit_alias) {
- archive->alias_len = 0;
+ restore_alias_len = phar->alias_len;
+ if (!phar->is_explicit_alias) {
+ phar->alias_len = 0;
}
- manifest_len = offset + archive->alias_len + sizeof(manifest) +
main_metadata_str.len;
+ manifest_len = offset + phar->alias_len + sizeof(manifest) +
main_metadata_str.len;
phar_set_32(manifest, manifest_len);
phar_set_32(manifest+4, new_manifest_count);
*(manifest + 8) = (unsigned char) (((PHAR_API_VERSION) >> 8) & 0xFF);
*(manifest + 9) = (unsigned char) (((PHAR_API_VERSION) & 0xF0));
phar_set_32(manifest+10, global_flags);
- phar_set_32(manifest+14, archive->alias_len);
+ phar_set_32(manifest+14, phar->alias_len);
/* write the manifest header */
if (sizeof(manifest) != php_stream_write(newfile, manifest,
sizeof(manifest))
- || (size_t)archive->alias_len != php_stream_write(newfile,
archive->alias, archive->alias_len)) {
+ || (size_t)phar->alias_len != php_stream_write(newfile, phar->alias,
phar->alias_len)) {
if (closeoldfile) {
php_stream_close(oldfile);
}
php_stream_close(newfile);
- archive->alias_len = restore_alias_len;
+ phar->alias_len = restore_alias_len;
if (error) {
- spprintf(error, 0, "unable to write manifest header of
new phar \"%s\"", archive->fname);
+ spprintf(error, 0, "unable to write manifest header of
new phar \"%s\"", phar->fname);
}
return EOF;
}
- archive->alias_len = restore_alias_len;
+ phar->alias_len = restore_alias_len;
phar_set_32(manifest, main_metadata_str.len);
if (main_metadata_str.len) {
@@ -2620,9 +2693,9 @@
php_stream_close(oldfile);
}
php_stream_close(newfile);
- archive->alias_len = restore_alias_len;
+ phar->alias_len = restore_alias_len;
if (error) {
- spprintf(error, 0, "unable to write manifest
meta-data of new phar \"%s\"", archive->fname);
+ spprintf(error, 0, "unable to write manifest
meta-data of new phar \"%s\"", phar->fname);
}
return EOF;
}
@@ -2633,9 +2706,9 @@
php_stream_close(oldfile);
}
php_stream_close(newfile);
- archive->alias_len = restore_alias_len;
+ phar->alias_len = restore_alias_len;
if (error) {
- spprintf(error, 0, "unable to write manifest
header of new phar \"%s\"", archive->fname);
+ spprintf(error, 0, "unable to write manifest
header of new phar \"%s\"", phar->fname);
}
return EOF;
}
@@ -2646,10 +2719,10 @@
manifest_ftell = php_stream_tell(newfile);
/* now write the manifest */
- for (zend_hash_internal_pointer_reset(&archive->manifest);
- zend_hash_has_more_elements(&archive->manifest) == SUCCESS;
- zend_hash_move_forward(&archive->manifest)) {
- if (zend_hash_get_current_data(&archive->manifest, (void
**)&entry) == FAILURE) {
+ for (zend_hash_internal_pointer_reset(&phar->manifest);
+ zend_hash_has_more_elements(&phar->manifest) == SUCCESS;
+ zend_hash_move_forward(&phar->manifest)) {
+ if (zend_hash_get_current_data(&phar->manifest, (void
**)&entry) == FAILURE) {
continue;
}
if (entry->is_deleted) {
@@ -2669,7 +2742,7 @@
}
php_stream_close(newfile);
if (error) {
- spprintf(error, 0, "unable to write filename of
file \"%s\" to manifest of new phar \"%s\"", entry->filename, archive->fname);
+ spprintf(error, 0, "unable to write filename of
file \"%s\" to manifest of new phar \"%s\"", entry->filename, phar->fname);
}
return EOF;
}
@@ -2679,7 +2752,7 @@
}
php_stream_close(newfile);
if (error) {
- spprintf(error, 0, "unable to write filename of
directory \"%s\" to manifest of new phar \"%s\"", entry->filename,
archive->fname);
+ spprintf(error, 0, "unable to write filename of
directory \"%s\" to manifest of new phar \"%s\"", entry->filename, phar->fname);
}
return EOF;
}
@@ -2706,7 +2779,7 @@
}
php_stream_close(newfile);
if (error) {
- spprintf(error, 0, "unable to write temporary
manifest of file \"%s\" to manifest of new phar \"%s\"", entry->filename,
archive->fname);
+ spprintf(error, 0, "unable to write temporary
manifest of file \"%s\" to manifest of new phar \"%s\"", entry->filename,
phar->fname);
}
return EOF;
}
@@ -2714,10 +2787,10 @@
/* now copy the actual file data to the new phar */
offset = 0;
- for (zend_hash_internal_pointer_reset(&archive->manifest);
- zend_hash_has_more_elements(&archive->manifest) == SUCCESS;
- zend_hash_move_forward(&archive->manifest)) {
- if (zend_hash_get_current_data(&archive->manifest, (void
**)&entry) == FAILURE) {
+ for (zend_hash_internal_pointer_reset(&phar->manifest);
+ zend_hash_has_more_elements(&phar->manifest) == SUCCESS;
+ zend_hash_move_forward(&phar->manifest)) {
+ if (zend_hash_get_current_data(&phar->manifest, (void
**)&entry) == FAILURE) {
continue;
}
if (entry->is_deleted) {
@@ -2728,14 +2801,14 @@
php_stream_rewind(file);
} else if (entry->fp && (entry->is_modified || !oldfile)) {
file = entry->fp;
- if (file == archive->fp) {
- if (-1 == php_stream_seek(file,
entry->offset_within_phar + archive->internal_file_start, SEEK_SET)) {
+ if (file == phar->fp) {
+ if (-1 == php_stream_seek(file,
entry->offset_within_phar + phar->internal_file_start, SEEK_SET)) {
if (closeoldfile) {
php_stream_close(oldfile);
}
php_stream_close(newfile);
if (error) {
- spprintf(error, 0, "unable to
seek to start of file \"%s\" while creating new phar \"%s\"", entry->filename,
archive->fname);
+ spprintf(error, 0, "unable to
seek to start of file \"%s\" while creating new phar \"%s\"", entry->filename,
phar->fname);
}
return EOF;
}
@@ -2749,17 +2822,17 @@
}
php_stream_close(newfile);
if (error) {
- spprintf(error, 0, "unable to seek to
start of file \"%s\" while creating new phar \"%s\"", entry->filename,
archive->fname);
+ spprintf(error, 0, "unable to seek to
start of file \"%s\" while creating new phar \"%s\"", entry->filename,
phar->fname);
}
return EOF;
}
- if (-1 == php_stream_seek(oldfile,
entry->offset_within_phar + archive->internal_file_start, SEEK_SET)) {
+ if (-1 == php_stream_seek(oldfile,
entry->offset_within_phar + phar->internal_file_start, SEEK_SET)) {
if (closeoldfile) {
php_stream_close(oldfile);
}
php_stream_close(newfile);
if (error) {
- spprintf(error, 0, "unable to seek to
start of file \"%s\" while creating new phar \"%s\"", entry->filename,
archive->fname);
+ spprintf(error, 0, "unable to seek to
start of file \"%s\" while creating new phar \"%s\"", entry->filename,
phar->fname);
}
return EOF;
}
@@ -2776,7 +2849,7 @@
}
php_stream_close(newfile);
if (error) {
- spprintf(error, 0, "unable to write contents of
file \"%s\" to new phar \"%s\"", entry->filename, archive->fname);
+ spprintf(error, 0, "unable to write contents of
file \"%s\" to new phar \"%s\"", entry->filename, phar->fname);
}
return EOF;
}
@@ -2786,7 +2859,7 @@
entry->cfp = 0;
}
if (entry->fp && entry->fp_refcount == 0) {
- if (entry->fp != archive->fp) {
+ if (entry->fp != phar->fp) {
php_stream_close(entry->fp);
}
entry->fp = 0;
@@ -2801,11 +2874,11 @@
php_stream_rewind(newfile);
- if (archive->signature) {
- efree(archive->signature);
+ if (phar->signature) {
+ efree(phar->signature);
}
- switch(archive->sig_flags) {
+ switch(phar->sig_flags) {
#if HAVE_HASH_EXT
case PHAR_SIG_SHA512: {
unsigned char digest[64];
@@ -2818,7 +2891,7 @@
PHP_SHA512Final(digest, &context);
php_stream_write(newfile, (char *) digest,
sizeof(digest));
sig_flags |= PHAR_SIG_SHA512;
- archive->sig_len = phar_hex_str((const char*)digest,
sizeof(digest), &archive->signature);
+ phar->sig_len = phar_hex_str((const char*)digest,
sizeof(digest), &phar->signature);
break;
}
case PHAR_SIG_SHA256: {
@@ -2832,7 +2905,7 @@
PHP_SHA256Final(digest, &context);
php_stream_write(newfile, (char *) digest,
sizeof(digest));
sig_flags |= PHAR_SIG_SHA256;
- archive->sig_len = phar_hex_str((const char*)digest,
sizeof(digest), &archive->signature);
+ phar->sig_len = phar_hex_str((const char*)digest,
sizeof(digest), &phar->signature);
break;
}
#else
@@ -2843,7 +2916,7 @@
}
php_stream_close(newfile);
if (error) {
- spprintf(error, 0, "unable to write contents of
file \"%s\" to new phar \"%s\" with requested hash type", entry->filename,
archive->fname);
+ spprintf(error, 0, "unable to write contents of
file \"%s\" to new phar \"%s\" with requested hash type", entry->filename,
phar->fname);
}
return EOF;
#endif
@@ -2861,7 +2934,7 @@
PHP_SHA1Final(digest, &context);
php_stream_write(newfile, (char *) digest,
sizeof(digest));
sig_flags |= PHAR_SIG_SHA1;
- archive->sig_len = phar_hex_str((const char*)digest,
sizeof(digest), &archive->signature);
+ phar->sig_len = phar_hex_str((const char*)digest,
sizeof(digest), &phar->signature);
break;
}
case PHAR_SIG_MD5: {
@@ -2875,51 +2948,80 @@
PHP_MD5Final(digest, &context);
php_stream_write(newfile, (char *) digest,
sizeof(digest));
sig_flags |= PHAR_SIG_MD5;
- archive->sig_len = phar_hex_str((const char*)digest,
sizeof(digest), &archive->signature);
+ phar->sig_len = phar_hex_str((const char*)digest,
sizeof(digest), &phar->signature);
break;
}
}
phar_set_32(sig_buf, sig_flags);
php_stream_write(newfile, sig_buf, 4);
php_stream_write(newfile, "GBMB", 4);
- archive->sig_flags = sig_flags;
+ phar->sig_flags = sig_flags;
}
/* finally, close the temp file, rename the original phar,
move the temp to the old phar, unlink the old phar, and reload it
into memory
*/
- if (archive->fp) {
- php_stream_close(archive->fp);
+ if (phar->fp) {
+ php_stream_close(phar->fp);
}
if (closeoldfile) {
php_stream_close(oldfile);
}
- archive->internal_file_start = halt_offset + manifest_len + 4;
- archive->is_brandnew = 0;
+ phar->internal_file_start = halt_offset + manifest_len + 4;
+ phar->is_brandnew = 0;
php_stream_rewind(newfile);
- if (archive->donotflush) {
+ if (phar->donotflush) {
/* deferred flush */
- archive->fp = newfile;
+ phar->fp = newfile;
} else {
- archive->fp = php_stream_open_wrapper(archive->fname, "w+b",
IGNORE_URL|STREAM_MUST_SEEK|REPORT_ERRORS, NULL);
- if (!archive->fp) {
- archive->fp = newfile;
+ phar->fp = php_stream_open_wrapper(phar->fname, "w+b",
IGNORE_URL|STREAM_MUST_SEEK|REPORT_ERRORS, NULL);
+ if (!phar->fp) {
+ phar->fp = newfile;
if (error) {
- spprintf(error, 0, "unable to open new phar
\"%s\" for writing", archive->fname);
+ spprintf(error, 0, "unable to open new phar
\"%s\" for writing", phar->fname);
}
return EOF;
}
- php_stream_copy_to_stream(newfile, archive->fp,
PHP_STREAM_COPY_ALL);
- php_stream_close(newfile);
- /* we could also reopen the file in "rb" mode but there is no
need for that */
+ if (phar->flags & PHAR_FILE_COMPRESSED_GZ) {
+ php_stream_filter *filter;
+ /* to properly compress, we have to tell zlib to add a
zlib header */
+ zval filterparams;
+
+ array_init(&filterparams);
+ add_assoc_long(&filterparams, "window", MAX_WBITS);
+ filter = php_stream_filter_create("zlib.deflate",
&filterparams, php_stream_is_persistent(phar->fp) TSRMLS_CC);
+ zval_dtor(&filterparams);
+ php_stream_filter_append(&phar->fp->writefilters,
filter);
+ php_stream_copy_to_stream(newfile, phar->fp,
PHP_STREAM_COPY_ALL);
+ php_stream_filter_flush(filter, 1);
+ php_stream_filter_remove(filter, 1 TSRMLS_CC);
+ php_stream_close(phar->fp);
+ /* use the temp stream as our base */
+ phar->fp = newfile;
+ } else if (phar->flags & PHAR_FILE_COMPRESSED_BZ2) {
+ php_stream_filter *filter;
+
+ filter = php_stream_filter_create("bzip2.compress",
NULL, php_stream_is_persistent(phar->fp) TSRMLS_CC);
+ php_stream_filter_append(&phar->fp->writefilters,
filter);
+ php_stream_copy_to_stream(newfile, phar->fp,
PHP_STREAM_COPY_ALL);
+ php_stream_filter_flush(filter, 1);
+ php_stream_filter_remove(filter, 1 TSRMLS_CC);
+ php_stream_close(phar->fp);
+ /* use the temp stream as our base */
+ phar->fp = newfile;
+ } else {
+ php_stream_copy_to_stream(newfile, phar->fp,
PHP_STREAM_COPY_ALL);
+ /* we could also reopen the file in "rb" mode but there
is no need for that */
+ php_stream_close(newfile);
+ }
}
- if (-1 == php_stream_seek(archive->fp, archive->halt_offset, SEEK_SET))
{
+ if (-1 == php_stream_seek(phar->fp, phar->halt_offset, SEEK_SET)) {
if (error) {
- spprintf(error, 0, "unable to seek to
__HALT_COMPILER(); in new phar \"%s\"", archive->fname);
+ spprintf(error, 0, "unable to seek to
__HALT_COMPILER(); in new phar \"%s\"", phar->fname);
}
return EOF;
}
@@ -3161,7 +3263,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.258 $");
+ php_info_print_table_row(2, "CVS revision", "$Revision: 1.259 $");
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.57&r2=1.58&diff_format=u
Index: pecl/phar/phar_internal.h
diff -u pecl/phar/phar_internal.h:1.57 pecl/phar/phar_internal.h:1.58
--- pecl/phar/phar_internal.h:1.57 Wed Jan 9 03:47:21 2008
+++ pecl/phar/phar_internal.h Wed Jan 9 07:09:03 2008
@@ -17,7 +17,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: phar_internal.h,v 1.57 2008/01/09 03:47:21 cellog Exp $ */
+/* $Id: phar_internal.h,v 1.58 2008/01/09 07:09:03 cellog Exp $ */
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -93,6 +93,12 @@
#define PHAR_HDR_COMPRESSED_BZ2 0x00002000
#define PHAR_HDR_SIGNATURE 0x00010000
+/* flags for defining that the entire file should be compressed */
+#define PHAR_FILE_COMPRESSION_MASK 0x00F00000
+#define PHAR_FILE_COMPRESSED_NONE 0x00000000
+#define PHAR_FILE_COMPRESSED_GZ 0x00100000
+#define PHAR_FILE_COMPRESSED_BZ2 0x00200000
+
#define PHAR_SIG_MD5 0x0001
#define PHAR_SIG_SHA1 0x0002
#define PHAR_SIG_SHA256 0x0003
@@ -311,10 +317,10 @@
/* tar functions in tar.c */
int phar_is_tar(char *buf);
-int phar_open_tarfile(php_stream* fp, char *fname, int fname_len, char *alias,
int alias_len, int options, phar_archive_data** pphar, char **error TSRMLS_DC);
+int phar_open_tarfile(php_stream* fp, char *fname, int fname_len, char *alias,
int alias_len, int options, phar_archive_data** pphar, php_uint32 compression,
char **error TSRMLS_DC);
int phar_flush(phar_archive_data *archive, char *user_stub, long len, char
**error TSRMLS_DC);
int phar_open_or_create_tar(char *fname, int fname_len, char *alias, int
alias_len, int options, phar_archive_data** pphar, char **error TSRMLS_DC);
-int phar_tar_flush(phar_archive_data *archive, char *user_stub, long len, char
**error TSRMLS_DC);
+int phar_tar_flush(phar_archive_data *phar, char *user_stub, long len, char
**error TSRMLS_DC);
/* zip functions in zip.c */
int phar_open_zipfile(char *fname, int fname_len, char *alias, int alias_len,
phar_archive_data** pphar, char **error TSRMLS_DC);
http://cvs.php.net/viewvc.cgi/pecl/phar/phar_object.c?r1=1.113&r2=1.114&diff_format=u
Index: pecl/phar/phar_object.c
diff -u pecl/phar/phar_object.c:1.113 pecl/phar/phar_object.c:1.114
--- pecl/phar/phar_object.c:1.113 Wed Jan 9 00:58:36 2008
+++ pecl/phar/phar_object.c Wed Jan 9 07:09:03 2008
@@ -17,7 +17,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: phar_object.c,v 1.113 2008/01/09 00:58:36 cellog Exp $ */
+/* $Id: phar_object.c,v 1.114 2008/01/09 07:09:03 cellog Exp $ */
#include "phar_internal.h"
@@ -1224,6 +1224,23 @@
}
/* }}} */
+/* {{{ proto bool Phar::isCompressed()
+ * Returns Phar::GZ or PHAR::BZ2 if the entire phar archive is compressed
(.tar.gz/tar.bz and so on)
+ */
+PHP_METHOD(Phar, isCompressed)
+{
+ PHAR_ARCHIVE_OBJECT();
+
+ if (phar_obj->arc.archive->flags & PHAR_FILE_COMPRESSED_GZ) {
+ RETURN_LONG(PHAR_ENT_COMPRESSED_GZ);
+ }
+ if (phar_obj->arc.archive->flags & PHAR_FILE_COMPRESSED_BZ2) {
+ RETURN_LONG(PHAR_ENT_COMPRESSED_BZ2);
+ }
+ RETURN_LONG(0);
+}
+/* }}} */
+
/* {{{ proto bool Phar::delete(string file)
* Delete a file from within the Phar
*/
@@ -2776,6 +2793,7 @@
PHP_ME(Phar, isTar, NULL,
ZEND_ACC_PUBLIC)
PHP_ME(Phar, isZip, NULL,
ZEND_ACC_PUBLIC)
PHP_ME(Phar, isPhar, NULL,
ZEND_ACC_PUBLIC)
+ PHP_ME(Phar, isCompressed, NULL,
ZEND_ACC_PUBLIC)
#endif
/* static member functions */
PHP_ME(Phar, apiVersion, NULL,
ZEND_ACC_PUBLIC|ZEND_ACC_STATIC|ZEND_ACC_FINAL)
http://cvs.php.net/viewvc.cgi/pecl/phar/tar.c?r1=1.8&r2=1.9&diff_format=u
Index: pecl/phar/tar.c
diff -u pecl/phar/tar.c:1.8 pecl/phar/tar.c:1.9
--- pecl/phar/tar.c:1.8 Wed Jan 9 03:47:21 2008
+++ pecl/phar/tar.c Wed Jan 9 07:09:03 2008
@@ -143,7 +143,7 @@
return FAILURE;
}
-int phar_open_tarfile(php_stream* fp, char *fname, int fname_len, char *alias,
int alias_len, int options, phar_archive_data** pphar, char **error TSRMLS_DC)
/* {{{ */
+int phar_open_tarfile(php_stream* fp, char *fname, int fname_len, char *alias,
int alias_len, int options, phar_archive_data** pphar, php_uint32 compression,
char **error TSRMLS_DC) /* {{{ */
{
char buf[512], *actual_alias = NULL;
phar_entry_info entry = {0};
@@ -155,7 +155,6 @@
if (error) {
*error = NULL;
}
- php_stream_seek(fp, 0, SEEK_SET);
read = php_stream_read(fp, buf, sizeof(buf));
if (read != sizeof(buf)) {
@@ -172,6 +171,8 @@
zend_hash_init(&myphar->manifest, sizeof(phar_entry_info),
zend_get_hash_value, destroy_phar_manifest_entry, 0);
myphar->is_tar = 1;
+ /* remember whether this entire phar was compressed with gz/bzip2 */
+ myphar->flags = compression;
entry.is_tar = 1;
entry.is_crc_checked = 1;
@@ -401,7 +402,7 @@
return ZEND_HASH_APPLY_KEEP;
}
-int phar_tar_flush(phar_archive_data *archive, char *user_stub, long len, char
**error TSRMLS_DC) /* {{{ */
+int phar_tar_flush(phar_archive_data *phar, char *user_stub, long len, char
**error TSRMLS_DC) /* {{{ */
{
phar_entry_info entry = {0};
static const char newstub[] = "<?php // tar-based phar archive stub
file\n__HALT_COMPILER();";
@@ -416,16 +417,16 @@
entry.is_crc_checked = 1;
entry.is_tar = 1;
entry.tar_type = '0';
- entry.phar = archive;
+ entry.phar = phar;
/* set alias */
- if (archive->is_explicit_alias) {
+ if (phar->is_explicit_alias) {
entry.filename = estrndup(".phar/alias.txt",
sizeof(".phar/alias.txt")-1);
entry.filename_len = sizeof(".phar/alias.txt")-1;
entry.fp = php_stream_fopen_tmpfile();
- entry.crc32 = phar_tar_checksum(archive->alias,
archive->alias_len);
- php_stream_write(entry.fp, archive->alias, archive->alias_len);
- entry.uncompressed_filesize = archive->alias_len;
- zend_hash_update(&archive->manifest, entry.filename,
entry.filename_len, (void*)&entry, sizeof(phar_entry_info), NULL);
+ entry.crc32 = phar_tar_checksum(phar->alias, phar->alias_len);
+ php_stream_write(entry.fp, phar->alias, phar->alias_len);
+ entry.uncompressed_filesize = phar->alias_len;
+ zend_hash_update(&phar->manifest, entry.filename,
entry.filename_len, (void*)&entry, sizeof(phar_entry_info), NULL);
}
/* set stub */
@@ -435,7 +436,7 @@
/* resource passed in */
if (!(php_stream_from_zval_no_verify(stubfile, (zval
**)user_stub))) {
if (error) {
- spprintf(error, 0, "unable to access
resource to copy stub to new tar-based phar \"%s\"", archive->fname);
+ spprintf(error, 0, "unable to access
resource to copy stub to new tar-based phar \"%s\"", phar->fname);
}
return EOF;
}
@@ -447,7 +448,7 @@
user_stub = 0;
if (!(len = php_stream_copy_to_mem(stubfile,
&user_stub, len, 0)) || !user_stub) {
if (error) {
- spprintf(error, 0, "unable to read
resource to copy stub to new tar-based phar \"%s\"", archive->fname);
+ spprintf(error, 0, "unable to read
resource to copy stub to new tar-based phar \"%s\"", phar->fname);
}
return EOF;
}
@@ -458,7 +459,7 @@
if ((pos = strstr(user_stub, "__HALT_COMPILER();")) == NULL)
{
if (error) {
- spprintf(error, 0, "illegal stub for tar-based
phar \"%s\"", archive->fname);
+ spprintf(error, 0, "illegal stub for tar-based
phar \"%s\"", phar->fname);
}
if (free_user_stub) {
efree(user_stub);
@@ -472,7 +473,7 @@
if ((size_t)len != php_stream_write(entry.fp, user_stub, len)
|| 5 != php_stream_write(entry.fp, " ?>\r\n", 5)) {
if (error) {
- spprintf(error, 0, "unable to create stub from
string in new tar-based phar \"%s\"", archive->fname);
+ spprintf(error, 0, "unable to create stub from
string in new tar-based phar \"%s\"", phar->fname);
}
if (free_user_stub) {
efree(user_stub);
@@ -482,33 +483,33 @@
}
entry.filename = estrndup(".phar/stub.php",
sizeof(".phar/stub.php")-1);
entry.filename_len = sizeof(".phar/stub.php")-1;
- zend_hash_update(&archive->manifest, entry.filename,
entry.filename_len, (void*)&entry, sizeof(phar_entry_info), NULL);
+ zend_hash_update(&phar->manifest, entry.filename,
entry.filename_len, (void*)&entry, sizeof(phar_entry_info), NULL);
if (free_user_stub) {
efree(user_stub);
}
} else {
- if (!zend_hash_exists(&archive->manifest, ".phar/stub.php",
sizeof(".phar/stub.php")-1)) {
+ if (!zend_hash_exists(&phar->manifest, ".phar/stub.php",
sizeof(".phar/stub.php")-1)) {
/* this is a brand new phar */
entry.fp = php_stream_fopen_tmpfile();
if (sizeof(newstub)-1 != php_stream_write(entry.fp,
newstub, sizeof(newstub)-1)) {
if (error) {
- spprintf(error, 0, "unable to create
stub in new tar-based phar \"%s\"", archive->fname);
+ spprintf(error, 0, "unable to create
stub in new tar-based phar \"%s\"", phar->fname);
}
return EOF;
}
entry.uncompressed_filesize = sizeof(newstub) - 1;
entry.filename = estrndup(".phar/stub.php",
sizeof(".phar/stub.php")-1);
entry.filename_len = sizeof(".phar/stub.php")-1;
- zend_hash_add(&archive->manifest, entry.filename,
entry.filename_len, (void*)&entry, sizeof(phar_entry_info), NULL);
+ zend_hash_add(&phar->manifest, entry.filename,
entry.filename_len, (void*)&entry, sizeof(phar_entry_info), NULL);
}
}
- if (archive->fp && !archive->is_brandnew) {
- oldfile = archive->fp;
+ if (phar->fp && !phar->is_brandnew) {
+ oldfile = phar->fp;
closeoldfile = 0;
php_stream_rewind(oldfile);
} else {
- oldfile = php_stream_open_wrapper(archive->fname, "rb", 0,
NULL);
+ oldfile = php_stream_open_wrapper(phar->fname, "rb", 0, NULL);
closeoldfile = oldfile != NULL;
}
newfile = php_stream_fopen_tmpfile();
@@ -526,7 +527,7 @@
pass.new = newfile;
pass.error = error;
- zend_hash_apply_with_argument(&archive->manifest, (apply_func_arg_t)
phar_tar_writeheaders, (void *) &pass TSRMLS_CC);
+ zend_hash_apply_with_argument(&phar->manifest, (apply_func_arg_t)
phar_tar_writeheaders, (void *) &pass TSRMLS_CC);
/* add final zero blocks */
buf = (char *) ecalloc(1024, 1);
@@ -541,29 +542,59 @@
php_stream_close(newfile);
return EOF;
}
- if (archive->fp) {
- php_stream_close(archive->fp);
+ if (phar->fp) {
+ php_stream_close(phar->fp);
}
- archive->is_brandnew = 0;
+ phar->is_brandnew = 0;
php_stream_rewind(newfile);
- if (archive->donotflush) {
+ if (phar->donotflush) {
/* deferred flush */
- archive->fp = newfile;
+ phar->fp = newfile;
} else {
- archive->fp = php_stream_open_wrapper(archive->fname, "w+b",
IGNORE_URL|STREAM_MUST_SEEK|REPORT_ERRORS, NULL);
- if (!archive->fp) {
- archive->fp = newfile;
+
+ phar->fp = php_stream_open_wrapper(phar->fname, "w+b",
IGNORE_URL|STREAM_MUST_SEEK|REPORT_ERRORS, NULL);
+ if (!phar->fp) {
+ phar->fp = newfile;
if (error) {
- spprintf(error, 0, "unable to open new phar
\"%s\" for writing", archive->fname);
+ spprintf(error, 0, "unable to open new phar
\"%s\" for writing", phar->fname);
}
return EOF;
}
- php_stream_copy_to_stream(newfile, archive->fp,
PHP_STREAM_COPY_ALL);
- php_stream_close(newfile);
- /* we could also reopen the file in "rb" mode but there is no
need for that */
+ if (phar->flags & PHAR_FILE_COMPRESSED_GZ) {
+ php_stream_filter *filter;
+ /* to properly compress, we have to tell zlib to add a
zlib header */
+ zval filterparams;
+
+ array_init(&filterparams);
+ add_assoc_long(&filterparams, "window", MAX_WBITS);
+ filter = php_stream_filter_create("zlib.deflate",
&filterparams, php_stream_is_persistent(phar->fp) TSRMLS_CC);
+ zval_dtor(&filterparams);
+ php_stream_filter_append(&phar->fp->writefilters,
filter);
+ php_stream_copy_to_stream(newfile, phar->fp,
PHP_STREAM_COPY_ALL);
+ php_stream_filter_flush(filter, 1);
+ php_stream_filter_remove(filter, 1 TSRMLS_CC);
+ php_stream_close(phar->fp);
+ /* use the temp stream as our base */
+ phar->fp = newfile;
+ } else if (phar->flags & PHAR_FILE_COMPRESSED_BZ2) {
+ php_stream_filter *filter;
+
+ filter = php_stream_filter_create("bzip2.compress",
NULL, php_stream_is_persistent(phar->fp) TSRMLS_CC);
+ php_stream_filter_append(&phar->fp->writefilters,
filter);
+ php_stream_copy_to_stream(newfile, phar->fp,
PHP_STREAM_COPY_ALL);
+ php_stream_filter_flush(filter, 1);
+ php_stream_filter_remove(filter, 1 TSRMLS_CC);
+ php_stream_close(phar->fp);
+ /* use the temp stream as our base */
+ phar->fp = newfile;
+ } else {
+ php_stream_copy_to_stream(newfile, phar->fp,
PHP_STREAM_COPY_ALL);
+ /* we could also reopen the file in "rb" mode but there
is no need for that */
+ php_stream_close(newfile);
+ }
}
return EOF;
}
http://cvs.php.net/viewvc.cgi/pecl/phar/tests/tar/tar_gzip.phpt?view=markup&rev=1.1
Index: pecl/phar/tests/tar/tar_gzip.phpt
+++ pecl/phar/tests/tar/tar_gzip.phpt
--TEST--
Phar: tar-based phar, gzipped tar
--SKIPIF--
<?php if (!extension_loaded('phar')) die('skip'); ?>
<?php if (!extension_loaded("spl")) die("skip SPL not available"); ?>
<?php if (!extension_loaded("zlib")) die("skip zlib not available"); ?>
--INI--
phar.readonly=0
--FILE--
<?php
include dirname(__FILE__) . '/tarmaker.php.inc';
$fname = dirname(__FILE__) . '/tar_gzip.phar';
$pname = 'phar://' . $fname;
$fname2 = dirname(__FILE__) . '/tar_gzip.phar.tar';
$pname2 = 'phar://' . $fname2;
$a = new tarmaker($fname, 'zlib');
$a->init();
$a->addFile('tar_004.php', '<?php var_dump(__FILE__);');
$a->addFile('internal/file/here', "hi there!\n");
$a->mkDir('internal/dir');
$a->mkDir('dir');
$a->addFile('.phar/stub.php', '<?php
Phar::mapPhar();
var_dump("it worked");
include "phar://" . __FILE__ . "/tar_004.php";
');
$a->close();
include $fname;
$a = new Phar($fname);
$a['test'] = 'hi';
copy($fname, $fname2);
$b = new Phar($fname2);
var_dump($b->isCompressed == Phar::GZ);
__HALT_COMPILER();
?>
===DONE===
--CLEAN--
<?php
@unlink(dirname(__FILE__) . '/tar_gzip.phar');
@unlink(dirname(__FILE__) . '/tar_gzip.phar.tar');
?>
--EXPECTF--
string(9) "it worked"
string(%d) "phar://%star_gzip.phar/tar_004.php"
bool(true)
===DONE===