├── EXPERIMENTAL ├── CREDITS ├── README ├── tests ├── _files │ ├── gnucpio.cpio │ ├── bsdtar.cpio.bz2 │ ├── bsdtar.cpio.gz │ ├── bsdtar.tar.bz2 │ ├── bsdtar.tar.gz │ ├── gnucpio.cpio.gz │ ├── gnutar.tar.bz2 │ ├── gnutar.tar.gz │ ├── gnucpio.cpio.bz2 │ ├── mkdir-torture.tar.gz │ ├── mkdir-torture.tar.bz2 │ ├── extracting-unwritable-dirs.tar.bz2 │ ├── extracting-unwritable-dirs.tar.gz │ ├── try-to-extract-with-umask-777.tar.bz2 │ ├── try-to-extract-with-umask-777.tar.gz │ ├── bsdtar.cpio │ ├── bsdtar.tar │ ├── gnutar.tar │ └── try-to-extract-with-umask-777.tar ├── unlink_entry.inc ├── add │ ├── 002.phpt │ ├── 003.phpt │ └── 001.phpt ├── list │ ├── 001.phpt │ ├── 004.phpt │ ├── 005.phpt │ ├── 002.phpt │ ├── 003.phpt │ ├── 008.phpt │ └── 006.phpt ├── list_bz2 │ ├── 001.phpt │ ├── 004.phpt │ ├── 005.phpt │ ├── 002.phpt │ ├── 003.phpt │ ├── 008.phpt │ └── 006.phpt ├── list_gz │ ├── 001.phpt │ ├── 004.phpt │ ├── 005.phpt │ ├── 002.phpt │ ├── 003.phpt │ ├── 008.phpt │ └── 006.phpt ├── add_gz │ └── 001.phpt └── add_bz2 │ └── 001.phpt ├── archive.php ├── config.m4 ├── archive_util.h ├── archive_writer.h ├── archive_clbk.h ├── archive_reader.h ├── archive_util.c ├── php_archive_entry.h ├── archive_clbk.c ├── API.txt ├── php_archive.h ├── package.xml ├── archive.c ├── archive_entry.c └── archive_writer.c /EXPERIMENTAL: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /CREDITS: -------------------------------------------------------------------------------- 1 | Antony Dovgal 2 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | README for PHP Archive 2 | 3 | API.txt 4 | -------------------------------------------------------------------------------- /tests/_files/gnucpio.cpio: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php/pecl-file_formats-archive/master/tests/_files/gnucpio.cpio -------------------------------------------------------------------------------- /tests/_files/bsdtar.cpio.bz2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php/pecl-file_formats-archive/master/tests/_files/bsdtar.cpio.bz2 -------------------------------------------------------------------------------- /tests/_files/bsdtar.cpio.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php/pecl-file_formats-archive/master/tests/_files/bsdtar.cpio.gz -------------------------------------------------------------------------------- /tests/_files/bsdtar.tar.bz2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php/pecl-file_formats-archive/master/tests/_files/bsdtar.tar.bz2 -------------------------------------------------------------------------------- /tests/_files/bsdtar.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php/pecl-file_formats-archive/master/tests/_files/bsdtar.tar.gz -------------------------------------------------------------------------------- /tests/_files/gnucpio.cpio.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php/pecl-file_formats-archive/master/tests/_files/gnucpio.cpio.gz -------------------------------------------------------------------------------- /tests/_files/gnutar.tar.bz2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php/pecl-file_formats-archive/master/tests/_files/gnutar.tar.bz2 -------------------------------------------------------------------------------- /tests/_files/gnutar.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php/pecl-file_formats-archive/master/tests/_files/gnutar.tar.gz -------------------------------------------------------------------------------- /tests/_files/gnucpio.cpio.bz2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php/pecl-file_formats-archive/master/tests/_files/gnucpio.cpio.bz2 -------------------------------------------------------------------------------- /tests/_files/mkdir-torture.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php/pecl-file_formats-archive/master/tests/_files/mkdir-torture.tar.gz -------------------------------------------------------------------------------- /tests/_files/mkdir-torture.tar.bz2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php/pecl-file_formats-archive/master/tests/_files/mkdir-torture.tar.bz2 -------------------------------------------------------------------------------- /tests/_files/extracting-unwritable-dirs.tar.bz2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php/pecl-file_formats-archive/master/tests/_files/extracting-unwritable-dirs.tar.bz2 -------------------------------------------------------------------------------- /tests/_files/extracting-unwritable-dirs.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php/pecl-file_formats-archive/master/tests/_files/extracting-unwritable-dirs.tar.gz -------------------------------------------------------------------------------- /tests/_files/try-to-extract-with-umask-777.tar.bz2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php/pecl-file_formats-archive/master/tests/_files/try-to-extract-with-umask-777.tar.bz2 -------------------------------------------------------------------------------- /tests/_files/try-to-extract-with-umask-777.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php/pecl-file_formats-archive/master/tests/_files/try-to-extract-with-umask-777.tar.gz -------------------------------------------------------------------------------- /archive.php: -------------------------------------------------------------------------------- 1 | \n"; 8 | foreach($functions as $func) { 9 | echo $func."
\n"; 10 | } 11 | echo "
\n"; 12 | $function = 'confirm_' . $module . '_compiled'; 13 | if (extension_loaded($module)) { 14 | $str = $function($module); 15 | } else { 16 | $str = "Module $module is not compiled into PHP"; 17 | } 18 | echo "$str\n"; 19 | ?> 20 | -------------------------------------------------------------------------------- /tests/unlink_entry.inc: -------------------------------------------------------------------------------- 1 | 32 | -------------------------------------------------------------------------------- /tests/_files/bsdtar.cpio: -------------------------------------------------------------------------------- 1 | 0707070014051120071006640007640007640000010000001017007362500001100000002145test.txt +----------------------------------------------------------------------+ 2 | | PHP Version 5 | 3 | +----------------------------------------------------------------------+ 4 | | Copyright (c) 1997-2004 The PHP Group | 5 | +----------------------------------------------------------------------+ 6 | | This source file is subject to version 3.0 of the PHP license, | 7 | | that is bundled with this package in the file LICENSE, and is | 8 | | available through the world-wide-web at the following url: | 9 | | http://www.php.net/license/3_0.txt. | 10 | | If you did not receive a copy of the PHP license and are unable to | 11 | | obtain it through the world-wide-web, please send a note to | 12 | | license@php.net so we can mail you a copy immediately. | 13 | +----------------------------------------------------------------------+ 14 | | Author: Antony Dovgal | 15 | +----------------------------------------------------------------------+ 16 | 0707070000000000000000000000000000000000010000000000000000000001300000000000TRAILER!!! -------------------------------------------------------------------------------- /tests/add/002.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | adding same file multiple times 3 | --SKIPIF-- 4 | 7 | --FILE-- 8 | addEntry($entry)); 17 | var_dump($writer->addEntry($entry)); 18 | var_dump($writer->addEntry($entry)); 19 | var_dump($writer->addEntry($entry)); 20 | var_dump($writer->addEntry($entry)); 21 | var_dump($writer->addEntry($entry)); 22 | var_dump($writer->finish()); 23 | 24 | $reader = new ArchiveReader($file); 25 | 26 | while ($e = $reader->getNextEntry(false)) { 27 | var_dump($e); 28 | var_dump($e->isDir()); 29 | var_dump($e->isFile()); 30 | var_dump($e->isLink()); 31 | var_dump($e->getPathname()); 32 | var_dump($e->getResolvedPathname()); 33 | var_dump($e->getSize()); 34 | } 35 | 36 | @unlink($file); 37 | 38 | echo "Done\n"; 39 | ?> 40 | --EXPECTF-- 41 | bool(true) 42 | bool(true) 43 | bool(true) 44 | bool(true) 45 | bool(true) 46 | bool(true) 47 | bool(true) 48 | object(ArchiveEntry)#%d (1) { 49 | ["entry"]=> 50 | resource(%d) of type (archive entry descriptor) 51 | } 52 | bool(false) 53 | bool(true) 54 | bool(false) 55 | string(%d) "%sadd/../_files/bsdtar.cpio" 56 | bool(false) 57 | int(1297) 58 | Done 59 | -------------------------------------------------------------------------------- /tests/add/003.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | adding same files before the directory 3 | --SKIPIF-- 4 | 7 | --FILE-- 8 | addEntry($entry)); 16 | 17 | $entry = new ArchiveEntry(dirname(__FILE__)."/../_files/"); 18 | var_dump($writer->addEntry($entry)); 19 | 20 | var_dump($writer->finish()); 21 | 22 | $reader = new ArchiveReader($file); 23 | 24 | while ($e = $reader->getNextEntry(false)) { 25 | var_dump($e); 26 | var_dump($e->isDir()); 27 | var_dump($e->isFile()); 28 | var_dump($e->isLink()); 29 | var_dump($e->getPathname()); 30 | var_dump($e->getResolvedPathname()); 31 | var_dump($e->getSize()); 32 | } 33 | 34 | @unlink($file); 35 | 36 | echo "Done\n"; 37 | ?> 38 | --EXPECTF-- 39 | bool(true) 40 | bool(true) 41 | bool(true) 42 | object(ArchiveEntry)#%d (1) { 43 | ["entry"]=> 44 | resource(%d) of type (archive entry descriptor) 45 | } 46 | bool(true) 47 | bool(false) 48 | bool(false) 49 | string(%d) "%sadd/../_files/" 50 | bool(false) 51 | int(0) 52 | object(ArchiveEntry)#%d (1) { 53 | ["entry"]=> 54 | resource(%d) of type (archive entry descriptor) 55 | } 56 | bool(false) 57 | bool(true) 58 | bool(false) 59 | string(%d) "%sadd/../_files/bsdtar.cpio" 60 | bool(false) 61 | int(1297) 62 | Done 63 | -------------------------------------------------------------------------------- /config.m4: -------------------------------------------------------------------------------- 1 | dnl $Id$ 2 | 3 | PHP_ARG_WITH(archive, for tar/cpio support, 4 | [ --with-archive=[DIR] Include tar/cpio support]) 5 | 6 | if test "$PHP_ARCHIVE" != "no"; then 7 | SEARCH_PATH="/usr/local /usr" 8 | SEARCH_FOR="/include/archive.h" 9 | if test -r $PHP_ARCHIVE/$SEARCH_FOR; then 10 | ARCHIVE_DIR=$PHP_ARCHIVE 11 | else 12 | AC_MSG_CHECKING([for libarchive files in default path]) 13 | for i in $SEARCH_PATH ; do 14 | if test -r $i/$SEARCH_FOR; then 15 | ARCHIVE_DIR=$i 16 | AC_MSG_RESULT(found in $i) 17 | fi 18 | done 19 | fi 20 | 21 | if test -z "$ARCHIVE_DIR"; then 22 | AC_MSG_RESULT([not found]) 23 | AC_MSG_ERROR([Please reinstall the libarchive distribution]) 24 | fi 25 | 26 | PHP_ADD_INCLUDE($ARCHIVE_DIR/include) 27 | 28 | LIBNAME=archive 29 | LIBSYMBOL=archive_read_new 30 | 31 | PHP_CHECK_LIBRARY($LIBNAME,$LIBSYMBOL, 32 | [ 33 | PHP_ADD_LIBRARY_WITH_PATH($LIBNAME, $ARCHIVE_DIR/lib, ARCHIVE_SHARED_LIBADD) 34 | AC_DEFINE(HAVE_ARCHIVELIB,1,[ ]) 35 | ],[ 36 | AC_MSG_ERROR([wrong libarchive version or lib not found]) 37 | ],[ 38 | -L$ARCHIVE_DIR/lib -lm -ldl 39 | ]) 40 | 41 | PHP_SUBST(ARCHIVE_SHARED_LIBADD) 42 | 43 | dnl comment out writer while it's not ready 44 | PHP_NEW_EXTENSION(archive, archive.c archive_reader.c archive_writer.c archive_clbk.c archive_entry.c archive_util.c, $ext_shared) 45 | dnl PHP_NEW_EXTENSION(archive, archive.c archive_reader.c archive_clbk.c archive_entry.c, $ext_shared) 46 | fi 47 | -------------------------------------------------------------------------------- /tests/list/001.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | basic tests 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | close()); 21 | 22 | echo "Done\n"; 23 | 24 | ?> 25 | --EXPECTF-- 26 | object(ArchiveException)#%d (7) { 27 | ["message:protected"]=> 28 | string(88) "ArchiveReader::__construct(nonex.file): failed to open stream: No such file or directory" 29 | ["string:private"]=> 30 | string(0) "" 31 | ["code:protected"]=> 32 | int(0) 33 | ["file:protected"]=> 34 | string(%d) "%s001.php" 35 | ["line:protected"]=> 36 | int(%d) 37 | ["trace:private"]=> 38 | array(1) { 39 | [0]=> 40 | array(6) { 41 | ["file"]=> 42 | string(%d) "%s001.php" 43 | ["line"]=> 44 | int(%d) 45 | ["function"]=> 46 | string(11) "__construct" 47 | ["class"]=> 48 | string(13) "ArchiveReader" 49 | ["type"]=> 50 | string(2) "->" 51 | ["args"]=> 52 | array(1) { 53 | [0]=> 54 | string(10) "nonex.file" 55 | } 56 | } 57 | } 58 | ["severity"]=> 59 | int(2) 60 | } 61 | object(ArchiveReader)#%d (1) { 62 | ["fd"]=> 63 | resource(%d) of type (archive descriptor) 64 | } 65 | bool(true) 66 | Done 67 | -------------------------------------------------------------------------------- /archive_util.h: -------------------------------------------------------------------------------- 1 | /* 2 | +----------------------------------------------------------------------+ 3 | | PHP Version 5 | 4 | +----------------------------------------------------------------------+ 5 | | Copyright (c) 1997-2004 The PHP Group | 6 | +----------------------------------------------------------------------+ 7 | | This source file is subject to version 3.0 of the PHP license, | 8 | | that is bundled with this package in the file LICENSE, and is | 9 | | available through the world-wide-web at the following url: | 10 | | http://www.php.net/license/3_0.txt. | 11 | | If you did not receive a copy of the PHP license and are unable to | 12 | | obtain it through the world-wide-web, please send a note to | 13 | | license@php.net so we can mail you a copy immediately. | 14 | +----------------------------------------------------------------------+ 15 | | Author: Antony Dovgal | 16 | +----------------------------------------------------------------------+ 17 | */ 18 | 19 | /* $Id$ */ 20 | 21 | #ifndef ARCHIVE_UTIL_H 22 | #define ARCHIVE_UTIL_H 23 | 24 | void _archive_normalize_path(char **, int *); 25 | int _archive_pathname_compare(const void *, const void * TSRMLS_DC); 26 | 27 | #endif /* ARCHIVE_UTIL_H */ 28 | 29 | /* 30 | * Local variables: 31 | * tab-width: 4 32 | * c-basic-offset: 4 33 | * End: 34 | * vim600: noet sw=4 ts=4 fdm=marker 35 | * vim<600: noet sw=4 ts=4 36 | */ 37 | -------------------------------------------------------------------------------- /tests/list_bz2/001.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | basic tests 3 | --SKIPIF-- 4 | 8 | --FILE-- 9 | close()); 24 | 25 | echo "Done\n"; 26 | 27 | ?> 28 | --EXPECTF-- 29 | object(ArchiveException)#%d (7) { 30 | ["message:protected"]=> 31 | string(88) "ArchiveReader::__construct(nonex.file): failed to open stream: No such file or directory" 32 | ["string:private"]=> 33 | string(0) "" 34 | ["code:protected"]=> 35 | int(0) 36 | ["file:protected"]=> 37 | string(%d) "%s001.php" 38 | ["line:protected"]=> 39 | int(%d) 40 | ["trace:private"]=> 41 | array(1) { 42 | [0]=> 43 | array(6) { 44 | ["file"]=> 45 | string(%d) "%s001.php" 46 | ["line"]=> 47 | int(%d) 48 | ["function"]=> 49 | string(11) "__construct" 50 | ["class"]=> 51 | string(13) "ArchiveReader" 52 | ["type"]=> 53 | string(2) "->" 54 | ["args"]=> 55 | array(1) { 56 | [0]=> 57 | string(10) "nonex.file" 58 | } 59 | } 60 | } 61 | ["severity"]=> 62 | int(2) 63 | } 64 | object(ArchiveReader)#%d (1) { 65 | ["fd"]=> 66 | resource(%d) of type (archive descriptor) 67 | } 68 | bool(true) 69 | Done 70 | -------------------------------------------------------------------------------- /tests/list_gz/001.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | basic tests 3 | --SKIPIF-- 4 | 8 | --FILE-- 9 | close()); 24 | 25 | echo "Done\n"; 26 | 27 | ?> 28 | --EXPECTF-- 29 | object(ArchiveException)#%d (7) { 30 | ["message:protected"]=> 31 | string(88) "ArchiveReader::__construct(nonex.file): failed to open stream: No such file or directory" 32 | ["string:private"]=> 33 | string(0) "" 34 | ["code:protected"]=> 35 | int(0) 36 | ["file:protected"]=> 37 | string(%d) "%s001.php" 38 | ["line:protected"]=> 39 | int(%d) 40 | ["trace:private"]=> 41 | array(1) { 42 | [0]=> 43 | array(6) { 44 | ["file"]=> 45 | string(%d) "%s001.php" 46 | ["line"]=> 47 | int(%d) 48 | ["function"]=> 49 | string(11) "__construct" 50 | ["class"]=> 51 | string(13) "ArchiveReader" 52 | ["type"]=> 53 | string(2) "->" 54 | ["args"]=> 55 | array(1) { 56 | [0]=> 57 | string(10) "nonex.file" 58 | } 59 | } 60 | } 61 | ["severity"]=> 62 | int(2) 63 | } 64 | object(ArchiveReader)#%d (1) { 65 | ["fd"]=> 66 | resource(%d) of type (archive descriptor) 67 | } 68 | bool(true) 69 | Done 70 | -------------------------------------------------------------------------------- /archive_writer.h: -------------------------------------------------------------------------------- 1 | /* 2 | +----------------------------------------------------------------------+ 3 | | PHP Version 5 | 4 | +----------------------------------------------------------------------+ 5 | | Copyright (c) 1997-2004 The PHP Group | 6 | +----------------------------------------------------------------------+ 7 | | This source file is subject to version 3.0 of the PHP license, | 8 | | that is bundled with this package in the file LICENSE, and is | 9 | | available through the world-wide-web at the following url: | 10 | | http://www.php.net/license/3_0.txt. | 11 | | If you did not receive a copy of the PHP license and are unable to | 12 | | obtain it through the world-wide-web, please send a note to | 13 | | license@php.net so we can mail you a copy immediately. | 14 | +----------------------------------------------------------------------+ 15 | | Author: Antony Dovgal | 16 | +----------------------------------------------------------------------+ 17 | */ 18 | 19 | /* $Id$ */ 20 | 21 | #ifndef ARCHIVE_WRITER_H 22 | #define ARCHIVE_WRITER_H 23 | 24 | PHP_MINIT_FUNCTION(archive_writer); 25 | 26 | ZEND_METHOD(ArchiveWriter, __construct); 27 | ZEND_METHOD(ArchiveWriter, addEntry); 28 | ZEND_METHOD(ArchiveWriter, finish); 29 | 30 | #endif /* ARCHIVE_WRITER_H */ 31 | 32 | /* 33 | * Local variables: 34 | * tab-width: 4 35 | * c-basic-offset: 4 36 | * End: 37 | * vim600: noet sw=4 ts=4 fdm=marker 38 | * vim<600: noet sw=4 ts=4 39 | */ 40 | -------------------------------------------------------------------------------- /tests/add/001.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | basic ArchiveWriter tests 3 | --SKIPIF-- 4 | 7 | --FILE-- 8 | addEntry($entry)); 16 | 17 | $entry = new ArchiveEntry(dirname(__FILE__)."/../_files/"); 18 | var_dump($writer->addEntry($entry)); 19 | 20 | $entry = new ArchiveEntry(dirname(__FILE__)."/../_files/bsdtar.cpio.gz"); 21 | var_dump($writer->addEntry($entry)); 22 | 23 | var_dump($writer->finish()); 24 | 25 | $reader = new ArchiveReader($file); 26 | 27 | 28 | while ($e = $reader->getNextEntry(false)) { 29 | var_dump($e); 30 | var_dump($e->isDir()); 31 | var_dump($e->isFile()); 32 | var_dump($e->isLink()); 33 | var_dump($e->getPathname()); 34 | var_dump($e->getResolvedPathname()); 35 | var_dump($e->getSize()); 36 | } 37 | 38 | @unlink($file); 39 | 40 | echo "Done\n"; 41 | ?> 42 | --EXPECTF-- 43 | bool(true) 44 | bool(true) 45 | bool(true) 46 | bool(true) 47 | object(ArchiveEntry)#%d (1) { 48 | ["entry"]=> 49 | resource(%d) of type (archive entry descriptor) 50 | } 51 | bool(true) 52 | bool(false) 53 | bool(false) 54 | string(%d) "%sadd/../_files/" 55 | bool(false) 56 | int(0) 57 | object(ArchiveEntry)#%d (1) { 58 | ["entry"]=> 59 | resource(%d) of type (archive entry descriptor) 60 | } 61 | bool(false) 62 | bool(true) 63 | bool(false) 64 | string(%d) "%sadd/../_files/bsdtar.cpio" 65 | bool(false) 66 | int(1297) 67 | object(ArchiveEntry)#%d (1) { 68 | ["entry"]=> 69 | resource(%d) of type (archive entry descriptor) 70 | } 71 | bool(false) 72 | bool(true) 73 | bool(false) 74 | string(%d) "%sadd/../_files/bsdtar.cpio.gz" 75 | bool(false) 76 | int(463) 77 | Done 78 | -------------------------------------------------------------------------------- /archive_clbk.h: -------------------------------------------------------------------------------- 1 | /* 2 | +----------------------------------------------------------------------+ 3 | | PHP Version 5 | 4 | +----------------------------------------------------------------------+ 5 | | Copyright (c) 1997-2004 The PHP Group | 6 | +----------------------------------------------------------------------+ 7 | | This source file is subject to version 3.0 of the PHP license, | 8 | | that is bundled with this package in the file LICENSE, and is | 9 | | available through the world-wide-web at the following url: | 10 | | http://www.php.net/license/3_0.txt. | 11 | | If you did not receive a copy of the PHP license and are unable to | 12 | | obtain it through the world-wide-web, please send a note to | 13 | | license@php.net so we can mail you a copy immediately. | 14 | +----------------------------------------------------------------------+ 15 | | Author: Antony Dovgal | 16 | +----------------------------------------------------------------------+ 17 | */ 18 | 19 | /* $Id$ */ 20 | 21 | #ifndef ARCHIVE_CLBK_H 22 | #define ARCHIVE_CLBK_H 23 | 24 | ssize_t _archive_read_clbk(struct archive *, void *, const void **); 25 | int _archive_open_clbk(struct archive *, void *); 26 | int _archive_close_clbk(struct archive *, void *); 27 | off_t _archive_skip_clbk(struct archive *, void *, off_t); 28 | ssize_t _archive_seek_clbk(struct archive *, void *, off_t, int); 29 | ssize_t _archive_write_clbk(struct archive *, void *, const void *, size_t); 30 | 31 | #endif /* ARCHIVE_CLBK_H */ 32 | 33 | /* 34 | * Local variables: 35 | * tab-width: 4 36 | * c-basic-offset: 4 37 | * End: 38 | * vim600: noet sw=4 ts=4 fdm=marker 39 | * vim<600: noet sw=4 ts=4 40 | */ 41 | -------------------------------------------------------------------------------- /tests/add_gz/001.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | basic ArchiveWriter tests 3 | --SKIPIF-- 4 | 8 | --FILE-- 9 | addEntry($entry)); 17 | 18 | $entry = new ArchiveEntry(dirname(__FILE__)."/../_files/"); 19 | var_dump($writer->addEntry($entry)); 20 | 21 | $entry = new ArchiveEntry(dirname(__FILE__)."/../_files/bsdtar.cpio.gz"); 22 | var_dump($writer->addEntry($entry)); 23 | 24 | var_dump($writer->finish()); 25 | 26 | $reader = new ArchiveReader($file); 27 | 28 | 29 | while ($e = $reader->getNextEntry(false)) { 30 | var_dump($e); 31 | var_dump($e->isDir()); 32 | var_dump($e->isFile()); 33 | var_dump($e->isLink()); 34 | var_dump($e->getPathname()); 35 | var_dump($e->getResolvedPathname()); 36 | var_dump($e->getSize()); 37 | } 38 | 39 | @unlink($file); 40 | 41 | echo "Done\n"; 42 | ?> 43 | --EXPECTF-- 44 | bool(true) 45 | bool(true) 46 | bool(true) 47 | bool(true) 48 | object(ArchiveEntry)#%d (1) { 49 | ["entry"]=> 50 | resource(%d) of type (archive entry descriptor) 51 | } 52 | bool(true) 53 | bool(false) 54 | bool(false) 55 | string(%d) "%sadd_gz/../_files/" 56 | bool(false) 57 | int(0) 58 | object(ArchiveEntry)#%d (1) { 59 | ["entry"]=> 60 | resource(%d) of type (archive entry descriptor) 61 | } 62 | bool(false) 63 | bool(true) 64 | bool(false) 65 | string(%d) "%sadd_gz/../_files/bsdtar.cpio" 66 | bool(false) 67 | int(1297) 68 | object(ArchiveEntry)#%d (1) { 69 | ["entry"]=> 70 | resource(%d) of type (archive entry descriptor) 71 | } 72 | bool(false) 73 | bool(true) 74 | bool(false) 75 | string(%d) "%sadd_gz/../_files/bsdtar.cpio.gz" 76 | bool(false) 77 | int(463) 78 | Done 79 | -------------------------------------------------------------------------------- /archive_reader.h: -------------------------------------------------------------------------------- 1 | /* 2 | +----------------------------------------------------------------------+ 3 | | PHP Version 5 | 4 | +----------------------------------------------------------------------+ 5 | | Copyright (c) 1997-2004 The PHP Group | 6 | +----------------------------------------------------------------------+ 7 | | This source file is subject to version 3.0 of the PHP license, | 8 | | that is bundled with this package in the file LICENSE, and is | 9 | | available through the world-wide-web at the following url: | 10 | | http://www.php.net/license/3_0.txt. | 11 | | If you did not receive a copy of the PHP license and are unable to | 12 | | obtain it through the world-wide-web, please send a note to | 13 | | license@php.net so we can mail you a copy immediately. | 14 | +----------------------------------------------------------------------+ 15 | | Author: Antony Dovgal | 16 | +----------------------------------------------------------------------+ 17 | */ 18 | 19 | /* $Id$ */ 20 | 21 | #ifndef ARCHIVE_READER_H 22 | #define ARCHIVE_READER_H 23 | 24 | PHP_MINIT_FUNCTION(archive_reader); 25 | 26 | ZEND_METHOD(ArchiveReader, __construct); 27 | ZEND_METHOD(ArchiveReader, getStream); 28 | ZEND_METHOD(ArchiveReader, getArchiveFormat); 29 | ZEND_METHOD(ArchiveReader, getNextEntry); 30 | ZEND_METHOD(ArchiveReader, getCurrentEntryData); 31 | ZEND_METHOD(ArchiveReader, readCurrentEntryData); 32 | ZEND_METHOD(ArchiveReader, skipCurrentEntryData); 33 | ZEND_METHOD(ArchiveReader, extractCurrentEntry); 34 | ZEND_METHOD(ArchiveReader, close); 35 | 36 | #endif /* ARCHIVE_READER_H */ 37 | 38 | /* 39 | * Local variables: 40 | * tab-width: 4 41 | * c-basic-offset: 4 42 | * End: 43 | * vim600: noet sw=4 ts=4 fdm=marker 44 | * vim<600: noet sw=4 ts=4 45 | */ 46 | -------------------------------------------------------------------------------- /tests/add_bz2/001.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | basic ArchiveWriter tests 3 | --SKIPIF-- 4 | 8 | --FILE-- 9 | addEntry($entry)); 17 | 18 | $entry = new ArchiveEntry(dirname(__FILE__)."/../_files/"); 19 | var_dump($writer->addEntry($entry)); 20 | 21 | $entry = new ArchiveEntry(dirname(__FILE__)."/../_files/bsdtar.cpio.gz"); 22 | var_dump($writer->addEntry($entry)); 23 | 24 | var_dump($writer->finish()); 25 | 26 | $reader = new ArchiveReader($file); 27 | 28 | 29 | while ($e = $reader->getNextEntry(false)) { 30 | var_dump($e); 31 | var_dump($e->isDir()); 32 | var_dump($e->isFile()); 33 | var_dump($e->isLink()); 34 | var_dump($e->getPathname()); 35 | var_dump($e->getResolvedPathname()); 36 | var_dump($e->getSize()); 37 | } 38 | 39 | @unlink($file); 40 | 41 | echo "Done\n"; 42 | ?> 43 | --EXPECTF-- 44 | bool(true) 45 | bool(true) 46 | bool(true) 47 | bool(true) 48 | object(ArchiveEntry)#%d (1) { 49 | ["entry"]=> 50 | resource(%d) of type (archive entry descriptor) 51 | } 52 | bool(true) 53 | bool(false) 54 | bool(false) 55 | string(%d) "%sadd_bz2/../_files/" 56 | bool(false) 57 | int(0) 58 | object(ArchiveEntry)#%d (1) { 59 | ["entry"]=> 60 | resource(%d) of type (archive entry descriptor) 61 | } 62 | bool(false) 63 | bool(true) 64 | bool(false) 65 | string(%d) "%sadd_bz2/../_files/bsdtar.cpio" 66 | bool(false) 67 | int(1297) 68 | object(ArchiveEntry)#%d (1) { 69 | ["entry"]=> 70 | resource(%d) of type (archive entry descriptor) 71 | } 72 | bool(false) 73 | bool(true) 74 | bool(false) 75 | string(%d) "%sadd_bz2/../_files/bsdtar.cpio.gz" 76 | bool(false) 77 | int(463) 78 | Done 79 | -------------------------------------------------------------------------------- /tests/list/004.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | bsdtar.cpio 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | getNextEntry(true)) { 11 | var_dump($e); 12 | var_dump($e->isDir()); 13 | var_dump($e->isFile()); 14 | var_dump($e->isLink()); 15 | var_dump($e->getPathname()); 16 | var_dump($e->getResolvedPathname()); 17 | var_dump($e->getUser()); 18 | var_dump($e->getGroup()); 19 | var_dump($e->getMtime()); 20 | var_dump($e->getSize()); 21 | var_dump($e->getPerms()); 22 | var_dump($e->getData()); 23 | } 24 | 25 | echo "Done\n"; 26 | ?> 27 | --EXPECTF-- 28 | object(ArchiveEntry)#%d (1) { 29 | ["entry"]=> 30 | resource(%d) of type (archive entry descriptor) 31 | } 32 | bool(false) 33 | bool(true) 34 | bool(false) 35 | string(8) "test.txt" 36 | bool(false) 37 | bool(false) 38 | bool(false) 39 | int(1105229717) 40 | int(1125) 41 | int(33204) 42 | string(1125) " +----------------------------------------------------------------------+ 43 | | PHP Version 5 | 44 | +----------------------------------------------------------------------+ 45 | | Copyright (c) 1997-2004 The PHP Group | 46 | +----------------------------------------------------------------------+ 47 | | This source file is subject to version 3.0 of the PHP license, | 48 | | that is bundled with this package in the file LICENSE, and is | 49 | | available through the world-wide-web at the following url: | 50 | | http://www.php.net/license/3_0.txt. | 51 | | If you did not receive a copy of the PHP license and are unable to | 52 | | obtain it through the world-wide-web, please send a note to | 53 | | license@php.net so we can mail you a copy immediately. | 54 | +----------------------------------------------------------------------+ 55 | | Author: Antony Dovgal | 56 | +----------------------------------------------------------------------+ 57 | " 58 | Done 59 | -------------------------------------------------------------------------------- /tests/list/005.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | gnucpio.cpio 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | getNextEntry(true)) { 11 | var_dump($e); 12 | var_dump($e->isDir()); 13 | var_dump($e->isFile()); 14 | var_dump($e->isLink()); 15 | var_dump($e->getPathname()); 16 | var_dump($e->getResolvedPathname()); 17 | var_dump($e->getUser()); 18 | var_dump($e->getGroup()); 19 | var_dump($e->getMtime()); 20 | var_dump($e->getSize()); 21 | var_dump($e->getPerms()); 22 | var_dump($e->getData()); 23 | } 24 | 25 | echo "Done\n"; 26 | ?> 27 | --EXPECTF-- 28 | object(ArchiveEntry)#%d (1) { 29 | ["entry"]=> 30 | resource(%d) of type (archive entry descriptor) 31 | } 32 | bool(false) 33 | bool(true) 34 | bool(false) 35 | string(8) "test.txt" 36 | bool(false) 37 | bool(false) 38 | bool(false) 39 | int(1105229717) 40 | int(1125) 41 | int(33204) 42 | string(1125) " +----------------------------------------------------------------------+ 43 | | PHP Version 5 | 44 | +----------------------------------------------------------------------+ 45 | | Copyright (c) 1997-2004 The PHP Group | 46 | +----------------------------------------------------------------------+ 47 | | This source file is subject to version 3.0 of the PHP license, | 48 | | that is bundled with this package in the file LICENSE, and is | 49 | | available through the world-wide-web at the following url: | 50 | | http://www.php.net/license/3_0.txt. | 51 | | If you did not receive a copy of the PHP license and are unable to | 52 | | obtain it through the world-wide-web, please send a note to | 53 | | license@php.net so we can mail you a copy immediately. | 54 | +----------------------------------------------------------------------+ 55 | | Author: Antony Dovgal | 56 | +----------------------------------------------------------------------+ 57 | " 58 | Done 59 | -------------------------------------------------------------------------------- /tests/list/002.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | bsdtar.tar 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | getNextEntry(true)) { 11 | var_dump($e); 12 | var_dump($e->isDir()); 13 | var_dump($e->isFile()); 14 | var_dump($e->isLink()); 15 | var_dump($e->getPathname()); 16 | var_dump($e->getResolvedPathname()); 17 | var_dump($e->getUser()); 18 | var_dump($e->getGroup()); 19 | var_dump($e->getMtime()); 20 | var_dump($e->getSize()); 21 | var_dump($e->getPerms()); 22 | var_dump($e->getData()); 23 | } 24 | 25 | echo "Done\n"; 26 | ?> 27 | --EXPECTF-- 28 | object(ArchiveEntry)#%d (1) { 29 | ["entry"]=> 30 | resource(%d) of type (archive entry descriptor) 31 | } 32 | bool(false) 33 | bool(true) 34 | bool(false) 35 | string(8) "test.txt" 36 | bool(false) 37 | string(4) "tony" 38 | string(4) "tony" 39 | int(1105229717) 40 | int(1125) 41 | int(33204) 42 | string(1125) " +----------------------------------------------------------------------+ 43 | | PHP Version 5 | 44 | +----------------------------------------------------------------------+ 45 | | Copyright (c) 1997-2004 The PHP Group | 46 | +----------------------------------------------------------------------+ 47 | | This source file is subject to version 3.0 of the PHP license, | 48 | | that is bundled with this package in the file LICENSE, and is | 49 | | available through the world-wide-web at the following url: | 50 | | http://www.php.net/license/3_0.txt. | 51 | | If you did not receive a copy of the PHP license and are unable to | 52 | | obtain it through the world-wide-web, please send a note to | 53 | | license@php.net so we can mail you a copy immediately. | 54 | +----------------------------------------------------------------------+ 55 | | Author: Antony Dovgal | 56 | +----------------------------------------------------------------------+ 57 | " 58 | Done 59 | -------------------------------------------------------------------------------- /tests/list/003.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | gnutar.tar 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | getNextEntry(true)) { 11 | var_dump($e); 12 | var_dump($e->isDir()); 13 | var_dump($e->isFile()); 14 | var_dump($e->isLink()); 15 | var_dump($e->getPathname()); 16 | var_dump($e->getResolvedPathname()); 17 | var_dump($e->getUser()); 18 | var_dump($e->getGroup()); 19 | var_dump($e->getMtime()); 20 | var_dump($e->getSize()); 21 | var_dump($e->getPerms()); 22 | var_dump($e->getData()); 23 | } 24 | 25 | echo "Done\n"; 26 | ?> 27 | --EXPECTF-- 28 | object(ArchiveEntry)#%d (1) { 29 | ["entry"]=> 30 | resource(%d) of type (archive entry descriptor) 31 | } 32 | bool(false) 33 | bool(true) 34 | bool(false) 35 | string(8) "test.txt" 36 | bool(false) 37 | string(4) "tony" 38 | string(4) "tony" 39 | int(1105229717) 40 | int(1125) 41 | int(33204) 42 | string(1125) " +----------------------------------------------------------------------+ 43 | | PHP Version 5 | 44 | +----------------------------------------------------------------------+ 45 | | Copyright (c) 1997-2004 The PHP Group | 46 | +----------------------------------------------------------------------+ 47 | | This source file is subject to version 3.0 of the PHP license, | 48 | | that is bundled with this package in the file LICENSE, and is | 49 | | available through the world-wide-web at the following url: | 50 | | http://www.php.net/license/3_0.txt. | 51 | | If you did not receive a copy of the PHP license and are unable to | 52 | | obtain it through the world-wide-web, please send a note to | 53 | | license@php.net so we can mail you a copy immediately. | 54 | +----------------------------------------------------------------------+ 55 | | Author: Antony Dovgal | 56 | +----------------------------------------------------------------------+ 57 | " 58 | Done 59 | -------------------------------------------------------------------------------- /tests/list_gz/004.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | bsdtar.cpio 3 | --SKIPIF-- 4 | 8 | --FILE-- 9 | getNextEntry(true)) { 14 | var_dump($e); 15 | var_dump($e->isDir()); 16 | var_dump($e->isFile()); 17 | var_dump($e->isLink()); 18 | var_dump($e->getPathname()); 19 | var_dump($e->getResolvedPathname()); 20 | var_dump($e->getUser()); 21 | var_dump($e->getGroup()); 22 | var_dump($e->getMtime()); 23 | var_dump($e->getSize()); 24 | var_dump($e->getPerms()); 25 | var_dump($e->getData()); 26 | } 27 | 28 | echo "Done\n"; 29 | ?> 30 | --EXPECTF-- 31 | object(ArchiveEntry)#%d (1) { 32 | ["entry"]=> 33 | resource(%d) of type (archive entry descriptor) 34 | } 35 | bool(false) 36 | bool(true) 37 | bool(false) 38 | string(8) "test.txt" 39 | bool(false) 40 | bool(false) 41 | bool(false) 42 | int(1105229717) 43 | int(1125) 44 | int(33204) 45 | string(1125) " +----------------------------------------------------------------------+ 46 | | PHP Version 5 | 47 | +----------------------------------------------------------------------+ 48 | | Copyright (c) 1997-2004 The PHP Group | 49 | +----------------------------------------------------------------------+ 50 | | This source file is subject to version 3.0 of the PHP license, | 51 | | that is bundled with this package in the file LICENSE, and is | 52 | | available through the world-wide-web at the following url: | 53 | | http://www.php.net/license/3_0.txt. | 54 | | If you did not receive a copy of the PHP license and are unable to | 55 | | obtain it through the world-wide-web, please send a note to | 56 | | license@php.net so we can mail you a copy immediately. | 57 | +----------------------------------------------------------------------+ 58 | | Author: Antony Dovgal | 59 | +----------------------------------------------------------------------+ 60 | " 61 | Done 62 | -------------------------------------------------------------------------------- /tests/list_bz2/004.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | bsdtar.cpio 3 | --SKIPIF-- 4 | 8 | --FILE-- 9 | getNextEntry(true)) { 14 | var_dump($e); 15 | var_dump($e->isDir()); 16 | var_dump($e->isFile()); 17 | var_dump($e->isLink()); 18 | var_dump($e->getPathname()); 19 | var_dump($e->getResolvedPathname()); 20 | var_dump($e->getUser()); 21 | var_dump($e->getGroup()); 22 | var_dump($e->getMtime()); 23 | var_dump($e->getSize()); 24 | var_dump($e->getPerms()); 25 | var_dump($e->getData()); 26 | } 27 | 28 | echo "Done\n"; 29 | ?> 30 | --EXPECTF-- 31 | object(ArchiveEntry)#%d (1) { 32 | ["entry"]=> 33 | resource(%d) of type (archive entry descriptor) 34 | } 35 | bool(false) 36 | bool(true) 37 | bool(false) 38 | string(8) "test.txt" 39 | bool(false) 40 | bool(false) 41 | bool(false) 42 | int(1105229717) 43 | int(1125) 44 | int(33204) 45 | string(1125) " +----------------------------------------------------------------------+ 46 | | PHP Version 5 | 47 | +----------------------------------------------------------------------+ 48 | | Copyright (c) 1997-2004 The PHP Group | 49 | +----------------------------------------------------------------------+ 50 | | This source file is subject to version 3.0 of the PHP license, | 51 | | that is bundled with this package in the file LICENSE, and is | 52 | | available through the world-wide-web at the following url: | 53 | | http://www.php.net/license/3_0.txt. | 54 | | If you did not receive a copy of the PHP license and are unable to | 55 | | obtain it through the world-wide-web, please send a note to | 56 | | license@php.net so we can mail you a copy immediately. | 57 | +----------------------------------------------------------------------+ 58 | | Author: Antony Dovgal | 59 | +----------------------------------------------------------------------+ 60 | " 61 | Done 62 | -------------------------------------------------------------------------------- /tests/list_bz2/005.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | gnucpio.cpio 3 | --SKIPIF-- 4 | 8 | --FILE-- 9 | getNextEntry(true)) { 14 | var_dump($e); 15 | var_dump($e->isDir()); 16 | var_dump($e->isFile()); 17 | var_dump($e->isLink()); 18 | var_dump($e->getPathname()); 19 | var_dump($e->getResolvedPathname()); 20 | var_dump($e->getUser()); 21 | var_dump($e->getGroup()); 22 | var_dump($e->getMtime()); 23 | var_dump($e->getSize()); 24 | var_dump($e->getPerms()); 25 | var_dump($e->getData()); 26 | } 27 | 28 | echo "Done\n"; 29 | ?> 30 | --EXPECTF-- 31 | object(ArchiveEntry)#%d (1) { 32 | ["entry"]=> 33 | resource(%d) of type (archive entry descriptor) 34 | } 35 | bool(false) 36 | bool(true) 37 | bool(false) 38 | string(8) "test.txt" 39 | bool(false) 40 | bool(false) 41 | bool(false) 42 | int(1105229717) 43 | int(1125) 44 | int(33204) 45 | string(1125) " +----------------------------------------------------------------------+ 46 | | PHP Version 5 | 47 | +----------------------------------------------------------------------+ 48 | | Copyright (c) 1997-2004 The PHP Group | 49 | +----------------------------------------------------------------------+ 50 | | This source file is subject to version 3.0 of the PHP license, | 51 | | that is bundled with this package in the file LICENSE, and is | 52 | | available through the world-wide-web at the following url: | 53 | | http://www.php.net/license/3_0.txt. | 54 | | If you did not receive a copy of the PHP license and are unable to | 55 | | obtain it through the world-wide-web, please send a note to | 56 | | license@php.net so we can mail you a copy immediately. | 57 | +----------------------------------------------------------------------+ 58 | | Author: Antony Dovgal | 59 | +----------------------------------------------------------------------+ 60 | " 61 | Done 62 | -------------------------------------------------------------------------------- /tests/list_gz/005.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | gnucpio.cpio 3 | --SKIPIF-- 4 | 8 | --FILE-- 9 | getNextEntry(true)) { 14 | var_dump($e); 15 | var_dump($e->isDir()); 16 | var_dump($e->isFile()); 17 | var_dump($e->isLink()); 18 | var_dump($e->getPathname()); 19 | var_dump($e->getResolvedPathname()); 20 | var_dump($e->getUser()); 21 | var_dump($e->getGroup()); 22 | var_dump($e->getMtime()); 23 | var_dump($e->getSize()); 24 | var_dump($e->getPerms()); 25 | var_dump($e->getData()); 26 | } 27 | 28 | echo "Done\n"; 29 | ?> 30 | --EXPECTF-- 31 | object(ArchiveEntry)#%d (1) { 32 | ["entry"]=> 33 | resource(%d) of type (archive entry descriptor) 34 | } 35 | bool(false) 36 | bool(true) 37 | bool(false) 38 | string(8) "test.txt" 39 | bool(false) 40 | bool(false) 41 | bool(false) 42 | int(1105229717) 43 | int(1125) 44 | int(33204) 45 | string(1125) " +----------------------------------------------------------------------+ 46 | | PHP Version 5 | 47 | +----------------------------------------------------------------------+ 48 | | Copyright (c) 1997-2004 The PHP Group | 49 | +----------------------------------------------------------------------+ 50 | | This source file is subject to version 3.0 of the PHP license, | 51 | | that is bundled with this package in the file LICENSE, and is | 52 | | available through the world-wide-web at the following url: | 53 | | http://www.php.net/license/3_0.txt. | 54 | | If you did not receive a copy of the PHP license and are unable to | 55 | | obtain it through the world-wide-web, please send a note to | 56 | | license@php.net so we can mail you a copy immediately. | 57 | +----------------------------------------------------------------------+ 58 | | Author: Antony Dovgal | 59 | +----------------------------------------------------------------------+ 60 | " 61 | Done 62 | -------------------------------------------------------------------------------- /tests/list_bz2/002.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | bsdtar.tar 3 | --SKIPIF-- 4 | 8 | --FILE-- 9 | getNextEntry(true)) { 14 | var_dump($e); 15 | var_dump($e->isDir()); 16 | var_dump($e->isFile()); 17 | var_dump($e->isLink()); 18 | var_dump($e->getPathname()); 19 | var_dump($e->getResolvedPathname()); 20 | var_dump($e->getUser()); 21 | var_dump($e->getGroup()); 22 | var_dump($e->getMtime()); 23 | var_dump($e->getSize()); 24 | var_dump($e->getPerms()); 25 | var_dump($e->getData()); 26 | } 27 | 28 | echo "Done\n"; 29 | ?> 30 | --EXPECTF-- 31 | object(ArchiveEntry)#%d (1) { 32 | ["entry"]=> 33 | resource(%d) of type (archive entry descriptor) 34 | } 35 | bool(false) 36 | bool(true) 37 | bool(false) 38 | string(8) "test.txt" 39 | bool(false) 40 | string(4) "tony" 41 | string(4) "tony" 42 | int(1105229717) 43 | int(1125) 44 | int(33204) 45 | string(1125) " +----------------------------------------------------------------------+ 46 | | PHP Version 5 | 47 | +----------------------------------------------------------------------+ 48 | | Copyright (c) 1997-2004 The PHP Group | 49 | +----------------------------------------------------------------------+ 50 | | This source file is subject to version 3.0 of the PHP license, | 51 | | that is bundled with this package in the file LICENSE, and is | 52 | | available through the world-wide-web at the following url: | 53 | | http://www.php.net/license/3_0.txt. | 54 | | If you did not receive a copy of the PHP license and are unable to | 55 | | obtain it through the world-wide-web, please send a note to | 56 | | license@php.net so we can mail you a copy immediately. | 57 | +----------------------------------------------------------------------+ 58 | | Author: Antony Dovgal | 59 | +----------------------------------------------------------------------+ 60 | " 61 | Done 62 | -------------------------------------------------------------------------------- /tests/list_bz2/003.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | gnutar.tar 3 | --SKIPIF-- 4 | 8 | --FILE-- 9 | getNextEntry(true)) { 14 | var_dump($e); 15 | var_dump($e->isDir()); 16 | var_dump($e->isFile()); 17 | var_dump($e->isLink()); 18 | var_dump($e->getPathname()); 19 | var_dump($e->getResolvedPathname()); 20 | var_dump($e->getUser()); 21 | var_dump($e->getGroup()); 22 | var_dump($e->getMtime()); 23 | var_dump($e->getSize()); 24 | var_dump($e->getPerms()); 25 | var_dump($e->getData()); 26 | } 27 | 28 | echo "Done\n"; 29 | ?> 30 | --EXPECTF-- 31 | object(ArchiveEntry)#%d (1) { 32 | ["entry"]=> 33 | resource(%d) of type (archive entry descriptor) 34 | } 35 | bool(false) 36 | bool(true) 37 | bool(false) 38 | string(8) "test.txt" 39 | bool(false) 40 | string(4) "tony" 41 | string(4) "tony" 42 | int(1105229717) 43 | int(1125) 44 | int(33204) 45 | string(1125) " +----------------------------------------------------------------------+ 46 | | PHP Version 5 | 47 | +----------------------------------------------------------------------+ 48 | | Copyright (c) 1997-2004 The PHP Group | 49 | +----------------------------------------------------------------------+ 50 | | This source file is subject to version 3.0 of the PHP license, | 51 | | that is bundled with this package in the file LICENSE, and is | 52 | | available through the world-wide-web at the following url: | 53 | | http://www.php.net/license/3_0.txt. | 54 | | If you did not receive a copy of the PHP license and are unable to | 55 | | obtain it through the world-wide-web, please send a note to | 56 | | license@php.net so we can mail you a copy immediately. | 57 | +----------------------------------------------------------------------+ 58 | | Author: Antony Dovgal | 59 | +----------------------------------------------------------------------+ 60 | " 61 | Done 62 | -------------------------------------------------------------------------------- /tests/list_gz/002.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | bsdtar.tar 3 | --SKIPIF-- 4 | 8 | --FILE-- 9 | getNextEntry(true)) { 14 | var_dump($e); 15 | var_dump($e->isDir()); 16 | var_dump($e->isFile()); 17 | var_dump($e->isLink()); 18 | var_dump($e->getPathname()); 19 | var_dump($e->getResolvedPathname()); 20 | var_dump($e->getUser()); 21 | var_dump($e->getGroup()); 22 | var_dump($e->getMtime()); 23 | var_dump($e->getSize()); 24 | var_dump($e->getPerms()); 25 | var_dump($e->getData()); 26 | } 27 | 28 | echo "Done\n"; 29 | ?> 30 | --EXPECTF-- 31 | object(ArchiveEntry)#%d (1) { 32 | ["entry"]=> 33 | resource(%d) of type (archive entry descriptor) 34 | } 35 | bool(false) 36 | bool(true) 37 | bool(false) 38 | string(8) "test.txt" 39 | bool(false) 40 | string(4) "tony" 41 | string(4) "tony" 42 | int(1105229717) 43 | int(1125) 44 | int(33204) 45 | string(1125) " +----------------------------------------------------------------------+ 46 | | PHP Version 5 | 47 | +----------------------------------------------------------------------+ 48 | | Copyright (c) 1997-2004 The PHP Group | 49 | +----------------------------------------------------------------------+ 50 | | This source file is subject to version 3.0 of the PHP license, | 51 | | that is bundled with this package in the file LICENSE, and is | 52 | | available through the world-wide-web at the following url: | 53 | | http://www.php.net/license/3_0.txt. | 54 | | If you did not receive a copy of the PHP license and are unable to | 55 | | obtain it through the world-wide-web, please send a note to | 56 | | license@php.net so we can mail you a copy immediately. | 57 | +----------------------------------------------------------------------+ 58 | | Author: Antony Dovgal | 59 | +----------------------------------------------------------------------+ 60 | " 61 | Done 62 | -------------------------------------------------------------------------------- /tests/list_gz/003.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | gnutar.tar 3 | --SKIPIF-- 4 | 8 | --FILE-- 9 | getNextEntry(true)) { 14 | var_dump($e); 15 | var_dump($e->isDir()); 16 | var_dump($e->isFile()); 17 | var_dump($e->isLink()); 18 | var_dump($e->getPathname()); 19 | var_dump($e->getResolvedPathname()); 20 | var_dump($e->getUser()); 21 | var_dump($e->getGroup()); 22 | var_dump($e->getMtime()); 23 | var_dump($e->getSize()); 24 | var_dump($e->getPerms()); 25 | var_dump($e->getData()); 26 | } 27 | 28 | echo "Done\n"; 29 | ?> 30 | --EXPECTF-- 31 | object(ArchiveEntry)#%d (1) { 32 | ["entry"]=> 33 | resource(%d) of type (archive entry descriptor) 34 | } 35 | bool(false) 36 | bool(true) 37 | bool(false) 38 | string(8) "test.txt" 39 | bool(false) 40 | string(4) "tony" 41 | string(4) "tony" 42 | int(1105229717) 43 | int(1125) 44 | int(33204) 45 | string(1125) " +----------------------------------------------------------------------+ 46 | | PHP Version 5 | 47 | +----------------------------------------------------------------------+ 48 | | Copyright (c) 1997-2004 The PHP Group | 49 | +----------------------------------------------------------------------+ 50 | | This source file is subject to version 3.0 of the PHP license, | 51 | | that is bundled with this package in the file LICENSE, and is | 52 | | available through the world-wide-web at the following url: | 53 | | http://www.php.net/license/3_0.txt. | 54 | | If you did not receive a copy of the PHP license and are unable to | 55 | | obtain it through the world-wide-web, please send a note to | 56 | | license@php.net so we can mail you a copy immediately. | 57 | +----------------------------------------------------------------------+ 58 | | Author: Antony Dovgal | 59 | +----------------------------------------------------------------------+ 60 | " 61 | Done 62 | -------------------------------------------------------------------------------- /archive_util.c: -------------------------------------------------------------------------------- 1 | /* 2 | +----------------------------------------------------------------------+ 3 | | PHP Version 5 | 4 | +----------------------------------------------------------------------+ 5 | | Copyright (c) 1997-2004 The PHP Group | 6 | +----------------------------------------------------------------------+ 7 | | This source file is subject to version 3.0 of the PHP license, | 8 | | that is bundled with this package in the file LICENSE, and is | 9 | | available through the world-wide-web at the following url: | 10 | | http://www.php.net/license/3_0.txt. | 11 | | If you did not receive a copy of the PHP license and are unable to | 12 | | obtain it through the world-wide-web, please send a note to | 13 | | license@php.net so we can mail you a copy immediately. | 14 | +----------------------------------------------------------------------+ 15 | | Author: Antony Dovgal | 16 | +----------------------------------------------------------------------+ 17 | */ 18 | 19 | /* $Id$ */ 20 | 21 | #ifdef HAVE_CONFIG_H 22 | #include "config.h" 23 | #endif 24 | 25 | #include "php.h" 26 | #include "php_archive.h" 27 | #include "archive_util.h" 28 | 29 | /* {{{ _archive_normalize_path 30 | */ 31 | void _archive_normalize_path(char **pathname, int *pathname_len) 32 | { 33 | while (*pathname_len && (*pathname[0] == '.' || *pathname[0] == '/')) { 34 | (*pathname)++; 35 | (*pathname_len)--; 36 | } 37 | } 38 | /* }}} */ 39 | 40 | /* {{{ _archive_pathname_compare 41 | */ 42 | int _archive_pathname_compare(const void *a, const void *b TSRMLS_DC) 43 | { 44 | Bucket *f, *s; 45 | zval result, first, second; 46 | 47 | f = *((Bucket **) a); 48 | s = *((Bucket **) b); 49 | 50 | Z_TYPE(first) = IS_STRING; 51 | Z_STRVAL(first) = (char *)f->arKey; 52 | Z_STRLEN(first) = f->nKeyLength-1; 53 | 54 | Z_TYPE(second) = IS_STRING; 55 | Z_STRVAL(second) = (char *)s->arKey; 56 | Z_STRLEN(second) = s->nKeyLength-1; 57 | 58 | if (string_compare_function(&result, &first, &second TSRMLS_CC) != SUCCESS) { 59 | return 0; 60 | } 61 | return (Z_LVAL(result) < 0 ? -1 : (Z_LVAL(result) > 0 ? 1 : 0)); 62 | } 63 | /* }}} */ 64 | 65 | 66 | /* 67 | * Local variables: 68 | * tab-width: 4 69 | * c-basic-offset: 4 70 | * End: 71 | * vim600: noet sw=4 ts=4 fdm=marker 72 | * vim<600: noet sw=4 ts=4 73 | */ 74 | -------------------------------------------------------------------------------- /php_archive_entry.h: -------------------------------------------------------------------------------- 1 | /* 2 | +----------------------------------------------------------------------+ 3 | | PHP Version 5 | 4 | +----------------------------------------------------------------------+ 5 | | Copyright (c) 1997-2004 The PHP Group | 6 | +----------------------------------------------------------------------+ 7 | | This source file is subject to version 3.0 of the PHP license, | 8 | | that is bundled with this package in the file LICENSE, and is | 9 | | available through the world-wide-web at the following url: | 10 | | http://www.php.net/license/3_0.txt. | 11 | | If you did not receive a copy of the PHP license and are unable to | 12 | | obtain it through the world-wide-web, please send a note to | 13 | | license@php.net so we can mail you a copy immediately. | 14 | +----------------------------------------------------------------------+ 15 | | Author: Antony Dovgal | 16 | +----------------------------------------------------------------------+ 17 | */ 18 | 19 | /* $Id$ */ 20 | 21 | #ifndef PHP_ARCHIVE_ENTRY_H 22 | #define PHP_ARCHIVE_ENTRY_H 23 | 24 | #ifndef S_ISDIR 25 | #define S_ISDIR(mode) (((mode)&S_IFMT) == S_IFDIR) 26 | #endif 27 | #ifndef S_ISREG 28 | #define S_ISREG(mode) (((mode)&S_IFMT) == S_IFREG) 29 | #endif 30 | #ifndef S_ISLNK 31 | #define S_ISLNK(mode) (((mode)&S_IFMT) == S_IFLNK) 32 | #endif 33 | 34 | zend_class_entry *ce_ArchiveEntry; 35 | 36 | ZEND_METHOD(ArchiveEntry, __construct); 37 | ZEND_METHOD(ArchiveEntry, isDir); 38 | ZEND_METHOD(ArchiveEntry, isFile); 39 | ZEND_METHOD(ArchiveEntry, isLink); 40 | ZEND_METHOD(ArchiveEntry, getPathname); 41 | ZEND_METHOD(ArchiveEntry, getResolvedPathname); 42 | ZEND_METHOD(ArchiveEntry, getUser); 43 | ZEND_METHOD(ArchiveEntry, getGroup); 44 | ZEND_METHOD(ArchiveEntry, getMtime); 45 | ZEND_METHOD(ArchiveEntry, getSize); 46 | ZEND_METHOD(ArchiveEntry, getPerms); 47 | ZEND_METHOD(ArchiveEntry, getData); 48 | 49 | PHP_MINIT_FUNCTION(archive_entry); 50 | 51 | int le_archive_entry; 52 | 53 | int _archive_get_entry_rsrc_id(zval * TSRMLS_DC); 54 | int _archive_get_entry_struct(zval *, archive_entry_t ** TSRMLS_DC); 55 | void _archive_entry_free(archive_entry_t * TSRMLS_DC); 56 | 57 | #endif /* PHP_ARCHIVE_ENTRY_H */ 58 | 59 | /* 60 | * Local variables: 61 | * tab-width: 4 62 | * c-basic-offset: 4 63 | * End: 64 | * vim600: noet sw=4 ts=4 fdm=marker 65 | * vim<600: noet sw=4 ts=4 66 | */ 67 | -------------------------------------------------------------------------------- /tests/_files/bsdtar.tar: -------------------------------------------------------------------------------- 1 | test.txt000664 000764 000764 00000002145 10170073625 012637 0ustar00tonytony000000 000000 +----------------------------------------------------------------------+ 2 | | PHP Version 5 | 3 | +----------------------------------------------------------------------+ 4 | | Copyright (c) 1997-2004 The PHP Group | 5 | +----------------------------------------------------------------------+ 6 | | This source file is subject to version 3.0 of the PHP license, | 7 | | that is bundled with this package in the file LICENSE, and is | 8 | | available through the world-wide-web at the following url: | 9 | | http://www.php.net/license/3_0.txt. | 10 | | If you did not receive a copy of the PHP license and are unable to | 11 | | obtain it through the world-wide-web, please send a note to | 12 | | license@php.net so we can mail you a copy immediately. | 13 | +----------------------------------------------------------------------+ 14 | | Author: Antony Dovgal | 15 | +----------------------------------------------------------------------+ 16 | -------------------------------------------------------------------------------- /tests/_files/gnutar.tar: -------------------------------------------------------------------------------- 1 | test.txt0100664000076400007640000000214510170073625011360 0ustar tonytony +----------------------------------------------------------------------+ 2 | | PHP Version 5 | 3 | +----------------------------------------------------------------------+ 4 | | Copyright (c) 1997-2004 The PHP Group | 5 | +----------------------------------------------------------------------+ 6 | | This source file is subject to version 3.0 of the PHP license, | 7 | | that is bundled with this package in the file LICENSE, and is | 8 | | available through the world-wide-web at the following url: | 9 | | http://www.php.net/license/3_0.txt. | 10 | | If you did not receive a copy of the PHP license and are unable to | 11 | | obtain it through the world-wide-web, please send a note to | 12 | | license@php.net so we can mail you a copy immediately. | 13 | +----------------------------------------------------------------------+ 14 | | Author: Antony Dovgal | 15 | +----------------------------------------------------------------------+ 16 | -------------------------------------------------------------------------------- /archive_clbk.c: -------------------------------------------------------------------------------- 1 | /* 2 | +----------------------------------------------------------------------+ 3 | | PHP Version 5 | 4 | +----------------------------------------------------------------------+ 5 | | Copyright (c) 1997-2004 The PHP Group | 6 | +----------------------------------------------------------------------+ 7 | | This source file is subject to version 3.0 of the PHP license, | 8 | | that is bundled with this package in the file LICENSE, and is | 9 | | available through the world-wide-web at the following url: | 10 | | http://www.php.net/license/3_0.txt. | 11 | | If you did not receive a copy of the PHP license and are unable to | 12 | | obtain it through the world-wide-web, please send a note to | 13 | | license@php.net so we can mail you a copy immediately. | 14 | +----------------------------------------------------------------------+ 15 | | Author: Antony Dovgal | 16 | +----------------------------------------------------------------------+ 17 | */ 18 | 19 | /* $Id$ */ 20 | 21 | #ifdef HAVE_CONFIG_H 22 | #include "config.h" 23 | #endif 24 | 25 | #include "php.h" 26 | #include "php_archive.h" 27 | #include "archive_clbk.h" 28 | 29 | /* {{{ _archive_read_clbk 30 | */ 31 | ssize_t _archive_read_clbk(struct archive *a, void *client_data, const void **buff) 32 | { 33 | archive_file_t *arch = (archive_file_t *)client_data; 34 | ssize_t len = 0; 35 | TSRMLS_FETCH(); 36 | 37 | if (arch->stream == NULL) { 38 | return 0; 39 | } 40 | 41 | *buff = arch->buf; 42 | if ((len = php_stream_read(arch->stream, arch->buf, arch->block_size))) { 43 | return len; 44 | } 45 | return 0; 46 | } 47 | /* }}} */ 48 | 49 | /* {{{ _archive_write_clbk 50 | */ 51 | ssize_t _archive_write_clbk(struct archive *a, void *client_data, const void *buff, size_t buf_len) 52 | { 53 | archive_file_t *arch = (archive_file_t *)client_data; 54 | ssize_t len; 55 | TSRMLS_FETCH(); 56 | 57 | if (arch->stream == NULL) { 58 | return 0; 59 | } 60 | 61 | if ((len = php_stream_write(arch->stream, (char *)buff, buf_len))) { 62 | return len; 63 | } 64 | return 0; 65 | } 66 | /* }}} */ 67 | 68 | /* {{{ _archive_skip_clbk 69 | * */ 70 | off_t _archive_skip_clbk(struct archive *a, void *client_data, off_t request) 71 | { 72 | archive_file_t *arch = (archive_file_t *)client_data; 73 | off_t size; 74 | int r; 75 | TSRMLS_FETCH(); 76 | 77 | if(request == 0) { 78 | return 0; 79 | } 80 | 81 | if(arch->stream){ 82 | size = (request/arch->block_size) * arch->block_size; 83 | if(size == 0){ /*do not break a block*/ 84 | return 0; 85 | } 86 | /*TODO maybe lasy seek is a better idea for performance 87 | * refer: libarchive archive_read_open_filename.c file_skip_lseek 88 | * */ 89 | r = php_stream_seek(arch->stream, size, SEEK_CUR); 90 | if(r < 0){ 91 | return 0; 92 | } 93 | return size; 94 | } 95 | return 0; 96 | } 97 | /*}}}*/ 98 | 99 | /* {{{ _archive_seek_clbk 100 | * */ 101 | ssize_t _archive_seek_clbk(struct archive *a, void *client_data, off_t offset, int whence) 102 | { 103 | int r; 104 | archive_file_t *arch = (archive_file_t *)client_data; 105 | TSRMLS_FETCH(); 106 | 107 | r = php_stream_seek(arch->stream, offset, whence); 108 | if(r == 0){ 109 | return php_stream_tell(arch->stream); 110 | } 111 | return r; 112 | }/*}}}*/ 113 | 114 | /* {{{ _archive_open_clbk 115 | */ 116 | int _archive_open_clbk(struct archive *a, void *client_data) 117 | { 118 | archive_file_t *arch = (archive_file_t *)client_data; 119 | TSRMLS_FETCH(); 120 | 121 | if (arch->mode == PHP_ARCHIVE_WRITE_MODE) { 122 | arch->stream = php_stream_open_wrapper_ex(arch->filename, "w", ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL, NULL); 123 | if (arch->stream) { 124 | return 0; 125 | } 126 | } else if (arch->mode == PHP_ARCHIVE_READ_MODE) { 127 | arch->stream = php_stream_open_wrapper_ex(arch->filename, "r", ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL, NULL); 128 | if (arch->stream) { 129 | /* Use libarchive to manage buffer 130 | * here we set non-buffer of php stream 131 | * */ 132 | arch->stream->flags |= PHP_STREAM_FLAG_NO_BUFFER; 133 | if((arch->stream->flags & PHP_STREAM_FLAG_NO_SEEK) == 0){ 134 | archive_read_set_skip_callback(arch->arch, _archive_skip_clbk); 135 | archive_read_set_seek_callback(arch->arch, _archive_seek_clbk); 136 | } 137 | return 0; 138 | } 139 | } 140 | 141 | return 1; 142 | } 143 | /* }}} */ 144 | 145 | /* {{{ _archive_close_clbk 146 | */ 147 | int _archive_close_clbk(struct archive *a, void *client_data) 148 | { 149 | archive_file_t *arch = (archive_file_t *)client_data; 150 | TSRMLS_FETCH(); 151 | 152 | if (arch->stream) { 153 | php_stream_close(arch->stream); 154 | } 155 | arch->stream = NULL; 156 | return 0; 157 | } 158 | /* }}} */ 159 | 160 | /* 161 | * Local variables: 162 | * tab-width: 4 163 | * c-basic-offset: 4 164 | * End: 165 | * vim600: noet sw=4 ts=4 fdm=marker 166 | * vim<600: noet sw=4 ts=4 167 | */ 168 | -------------------------------------------------------------------------------- /API.txt: -------------------------------------------------------------------------------- 1 | 2 | ############################## 3 | # W A R N I N G ! # 4 | ############################## 5 | 6 | Please make sure that your libarchive WAS NOT 7 | compiled with flag -D_FILE_OFFSET_BITS=64, as 8 | this flag changes struct stat size and as the 9 | result you'll get wierd/broken archives. 10 | 11 | ############################## 12 | 13 | 14 | 15 | Archive extension API 16 | 17 | Constants: 18 | ARCH_FORMAT_TAR 19 | ARCH_FORMAT_CPIO 20 | ARCH_FORMAT_PAX 21 | ARCH_FORMAT_PAX_RESTRICTED 22 | ARCH_FORMAT_SHAR 23 | ARCH_FORMAT_USTAR 24 | 25 | ARCH_COMPRESSION_GZIP (defined only if PHP was compiled --with--zlib) 26 | ARCH_COMPRESSION_BZIP2 (defined only if PHP was compiled --with--bz2) 27 | ARCH_COMPRESSION_COMPRESS 28 | ARCH_COMPRESSION_NONE 29 | 30 | Classes: 31 | 32 | class ArchiveReader { 33 | /** 34 | * ArchiveReader __construct (string filename[, int format[, int 35 | * compression [, int block_size]]]) 36 | * 37 | * You need to specify format & compression params *only* if you need 38 | * to support only these particular formats/compressions. 39 | * Use ARCH_COMPRESSION_GZIP | ARCH_COMPRESSION_BZIP2 to support bz2 & gz and 40 | * ARCH_FORMAT_TAR | ARCH_FORMAT_CPIO to support standard tar & cpio. 41 | * All possible formats and compressions are supported by default. 42 | * You'll need libbz2 or libz linked, though, to support BZIP2 or GZIP 43 | * appropriately. 44 | */ 45 | public function __construct($filename, $format, $compression); 46 | 47 | /** 48 | * ArchiveEntry getNextEntry ([bool fetch_entry_data]) 49 | * 50 | * Fetch next ArchiveEntry from the archive. 51 | * 52 | * Parameter fetch_entry_data is used to specify explicitly 53 | * that you need to fetch entry's data. 54 | * 55 | * There is pretty annoying libarchive limitation: 56 | * you can't fetch entry's data twice, so call to extractCurrentEntry() 57 | * after getNextEntry(true) will return false, as there is no data available. 58 | * 59 | * You can also get entry's data with ArchiveEntry->getData() if 60 | * fetch_entry_data was TRUE. 61 | */ 62 | 63 | public function getNextEntry($fetch_entry_data); 64 | 65 | /** 66 | * PHP_STREAM getStream() 67 | * 68 | * Get the PHP Stream object 69 | * 70 | * You can use fread/ftell just like file handles 71 | */ 72 | public function getStream() 73 | 74 | /** 75 | * string getCurrentEntryData(void) 76 | * 77 | * Fetches current entry's data. 78 | * 79 | * You can also get it with ArchiveEntry->getData() after that. 80 | */ 81 | public function getCurrentEntryData(); 82 | 83 | /** 84 | * string readCurrentEntryData(count) 85 | * 86 | * Just the same as getCurrentEntryData expect return *count* bytes. 87 | * 88 | * You can call this method multipule times until return an empty string 89 | * which indicates an EOF 90 | */ 91 | public function readCurrentEntryData(count); 92 | 93 | /** 94 | * skipCurrentEntryData() 95 | * 96 | * Skip current entry explicitly, this is useful when you need to get the 97 | * position of next header 98 | * 99 | */ 100 | public function skipCurrentEntryData(); 101 | 102 | /** 103 | * bool extractCurrentEntry(void) 104 | * 105 | * Recreate entry on your local disk. 106 | * The path is RELATIVE to current script. 107 | */ 108 | public function extractCurrentEntry(); 109 | 110 | /** 111 | * bool close(void) 112 | * 113 | * Close handle. 114 | */ 115 | public function close(); 116 | } 117 | 118 | class ArchiveEntry { 119 | /** 120 | * ArchiveEntry __construct(string filename) 121 | * 122 | * Should be probably disabled while ArchiveWriter is not ready 123 | */ 124 | public function __construct(); 125 | 126 | /** 127 | * bool isDir(void) 128 | */ 129 | public function isDir(); 130 | 131 | /** 132 | * bool isFile(void) 133 | */ 134 | public function isFile(); 135 | 136 | /** 137 | * bool isLink(void) 138 | */ 139 | public function isLink(); 140 | 141 | /** 142 | * string getPathname(void) 143 | * 144 | * Return full entry name. 145 | */ 146 | public function getPathname(); 147 | 148 | /** 149 | * string getResolvedPathname(void) 150 | * 151 | * Return full resolved name of a symlink. 152 | */ 153 | public function getResolvedPathname(); 154 | 155 | /** 156 | * string getUser(void) 157 | * 158 | * Entry's owner name. 159 | * (not supported in CPIO archives) 160 | */ 161 | public function getUser(); 162 | 163 | /** 164 | * string getGroup(void) 165 | * 166 | * Entry's owner group name. 167 | * (not supported in CPIO archives) 168 | */ 169 | public function getGroup(); 170 | 171 | /** 172 | * int getMtime(void) 173 | * 174 | * Entry's last modification time. 175 | * atime & ctime are not supported by libarchive. 176 | */ 177 | public function getMtime(); 178 | 179 | /** 180 | * int getSize(void) 181 | * 182 | * Return entry's size in bytes. 183 | */ 184 | public function getSize(); 185 | 186 | /** 187 | * int getPerms(void) 188 | * 189 | * Similar to fileperms(). 190 | */ 191 | public function getPerms(); 192 | 193 | /** 194 | * string getData(void) 195 | * 196 | * Return entry's data (*only* if it was fetched before by 197 | * getNextEntry(true) or getCurrentEntryData() !) 198 | */ 199 | public function getData(); 200 | } 201 | 202 | class ArchiveException extends Exception { 203 | /* methods inherited from Exception */ 204 | } 205 | 206 | /* tell me why would someone need it */ 207 | interface ArchiveReader { 208 | public function __construct($filename, $format, $compression); 209 | public function getNextEntry($fetch_entry_data); 210 | public function getCurrentEntryData(); 211 | public function extractCurrentEntry(); 212 | public function close(); 213 | } 214 | 215 | -------------------------------------------------------------------------------- /php_archive.h: -------------------------------------------------------------------------------- 1 | /* 2 | +----------------------------------------------------------------------+ 3 | | PHP Version 5 | 4 | +----------------------------------------------------------------------+ 5 | | Copyright (c) 1997-2004 The PHP Group | 6 | +----------------------------------------------------------------------+ 7 | | This source file is subject to version 3.0 of the PHP license, | 8 | | that is bundled with this package in the file LICENSE, and is | 9 | | available through the world-wide-web at the following url: | 10 | | http://www.php.net/license/3_0.txt. | 11 | | If you did not receive a copy of the PHP license and are unable to | 12 | | obtain it through the world-wide-web, please send a note to | 13 | | license@php.net so we can mail you a copy immediately. | 14 | +----------------------------------------------------------------------+ 15 | | Author: Antony Dovgal | 16 | +----------------------------------------------------------------------+ 17 | */ 18 | 19 | /* $Id$ */ 20 | 21 | #ifndef PHP_ARCHIVE_H 22 | #define PHP_ARCHIVE_H 23 | 24 | #include 25 | #include 26 | 27 | #define PHP_ARCHIVE_VERSION "0.4.1-dev" 28 | 29 | #define PHP_ARCHIVE_FORMAT_NONE (0) 30 | #define PHP_ARCHIVE_FORMAT_TAR ARCHIVE_FORMAT_TAR 31 | #define PHP_ARCHIVE_FORMAT_CPIO ARCHIVE_FORMAT_CPIO 32 | #define PHP_ARCHIVE_FORMAT_PAX ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE 33 | #define PHP_ARCHIVE_FORMAT_PAX_RESTRICTED ARCHIVE_FORMAT_TAR_PAX_RESTRICTED 34 | #define PHP_ARCHIVE_FORMAT_SHAR ARCHIVE_FORMAT_SHAR 35 | #define PHP_ARCHIVE_FORMAT_USTAR ARCHIVE_FORMAT_TAR_USTAR 36 | #define PHP_ARCHIVE_FORMAT_RAR ARCHIVE_FORMAT_RAR 37 | #define PHP_ARCHIVE_FORMAT_ZIP ARCHIVE_FORMAT_ZIP 38 | #define PHP_ARCHIVE_FORMAT_7ZIP ARCHIVE_FORMAT_7ZIP 39 | 40 | enum { 41 | PHP_ARCHIVE_READ_MODE, 42 | PHP_ARCHIVE_WRITE_MODE 43 | }; 44 | 45 | #define PHP_ARCHIVE_COMPRESSION_GZIP (1<<0) 46 | #define PHP_ARCHIVE_COMPRESSION_BZIP2 (1<<1) 47 | #define PHP_ARCHIVE_COMPRESSION_COMPRESS (1<<2) 48 | #define PHP_ARCHIVE_COMPRESSION_NONE (1<<3) 49 | 50 | typedef struct php_archive_entry { 51 | struct archive_entry *entry; 52 | char *data; 53 | int data_len; 54 | char *filename; /* used only for writing */ 55 | char *resolved_filename; /* used only for writing */ 56 | } archive_entry_t; 57 | 58 | typedef struct archive_file { 59 | int mode; 60 | php_stream *stream; 61 | struct archive *arch; 62 | archive_entry_t *current_entry; 63 | char *filename; 64 | char *buf; 65 | int struct_state; 66 | int block_size; 67 | HashTable *entries; 68 | } archive_file_t; 69 | 70 | #define PHP_ARCHIVE_BUF_LEN 8196 71 | 72 | #if ARCHIVE_VERSION_NUMBER < 3000000 73 | #define archive_read_free archive_read_finish 74 | #define archive_write_free archive_write_finish 75 | 76 | #define archive_read_support_filter_all archive_read_support_compression_all 77 | #define archive_read_support_filter_bzip2 archive_read_support_compression_bzip2 78 | #define archive_read_support_filter_compress archive_read_support_compression_compress 79 | #define archive_read_support_filter_gzip archive_read_support_compression_gzip 80 | #define archive_read_support_filter_lzip archive_read_support_compression_lzip 81 | #define archive_read_support_filter_lzma archive_read_support_compression_lzma 82 | #define archive_read_support_filter_none archive_read_support_compression_none 83 | #define archive_read_support_filter_program archive_read_support_compression_program 84 | #define archive_read_support_filter_program_signature archive_read_support_compression_program_signature 85 | #define archive_read_support_filter_rpm archive_read_support_compression_rpm 86 | #define archive_read_support_filter_uu archive_read_support_compression_uu 87 | #define archive_read_support_filter_xz archive_read_support_compression_xz 88 | 89 | #define archive_write_add_filter_bzip2 archive_write_set_compression_bzip2 90 | #define archive_write_add_filter_compress archive_write_set_compression_compress 91 | #define archive_write_add_filter_gzip archive_write_set_compression_gzip 92 | #define archive_write_add_filter_lzip archive_write_set_compression_lzip 93 | #define archive_write_add_filter_lzma archive_write_set_compression_lzma 94 | #define archive_write_add_filter_none archive_write_set_compression_none 95 | #define archive_write_add_filter_program archive_write_set_compression_program 96 | #define archive_write_add_filter_xz archive_write_set_compression_xz 97 | #endif 98 | 99 | #if ZEND_MODULE_API_NO < 20090626 100 | typedef int zend_error_handling; 101 | #define zend_replace_error_handling(type, exception, current) php_set_error_handling((type), (exception) TSRMLS_CC) 102 | #define zend_restore_error_handling(exception) php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC) 103 | #endif 104 | 105 | PHPAPI zend_class_entry *ce_ArchiveException; 106 | int le_archive; 107 | 108 | extern zend_module_entry archive_module_entry; 109 | #define phpext_archive_ptr &archive_module_entry 110 | 111 | #ifdef PHP_WIN32 112 | #define PHP_ARCHIVE_API __declspec(dllexport) 113 | #else 114 | #define PHP_ARCHIVE_API 115 | #endif 116 | 117 | #ifdef ZTS 118 | #include "TSRM.h" 119 | #endif 120 | 121 | int _archive_get_rsrc_id(zval * TSRMLS_DC); 122 | int _archive_get_fd(zval *, archive_file_t ** TSRMLS_DC); 123 | void _archive_entries_hash_dtor(void *data); 124 | 125 | PHP_MINIT_FUNCTION(archive); 126 | PHP_MINFO_FUNCTION(archive); 127 | 128 | #ifdef ZTS 129 | #define ARCHIVE_G(v) TSRMG(archive_globals_id, zend_archive_globals *, v) 130 | #else 131 | #define ARCHIVE_G(v) (archive_globals.v) 132 | #endif 133 | 134 | #endif /* PHP_ARCHIVE_H */ 135 | 136 | 137 | /* 138 | * Local variables: 139 | * tab-width: 4 140 | * c-basic-offset: 4 141 | * End: 142 | * vim600: noet sw=4 ts=4 fdm=marker 143 | * vim<600: noet sw=4 ts=4 144 | */ 145 | -------------------------------------------------------------------------------- /package.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | archive 7 | pecl.php.net 8 | archive extension 9 | archive extension allows to read and write 10 | tar and cpio archives using libarchive (http://people.freebsd.org/~kientzle/libarchive/). 11 | 12 | 13 | Antony Dovgal 14 | tony2001 15 | antony@zend.com 16 | yes 17 | 18 | 2009-11-05 19 | 20 | 21 | 0.2 22 | 0.2 23 | 24 | 25 | beta 26 | beta 27 | 28 | PHP License 29 | 30 | - Reimplemented and turned on by default ArchiveWriter. 31 | - Fixed some typobugs and made the code cleaner. 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 5.0.0 141 | 142 | 143 | 1.4.0b1 144 | 145 | 146 | 147 | archive 148 | 149 | 150 | 151 | 152 | 0.1 153 | 0.1 154 | 155 | 156 | alpha 157 | alpha 158 | 159 | 2005-01-26 160 | PHP License 161 | 162 | Initial release. 163 | 164 | 165 | 166 | 167 | -------------------------------------------------------------------------------- /archive.c: -------------------------------------------------------------------------------- 1 | /* 2 | +----------------------------------------------------------------------+ 3 | | PHP Version 5 | 4 | +----------------------------------------------------------------------+ 5 | | Copyright (c) 1997-2004 The PHP Group | 6 | +----------------------------------------------------------------------+ 7 | | This source file is subject to version 3.0 of the PHP license, | 8 | | that is bundled with this package in the file LICENSE, and is | 9 | | available through the world-wide-web at the following url: | 10 | | http://www.php.net/license/3_0.txt. | 11 | | If you did not receive a copy of the PHP license and are unable to | 12 | | obtain it through the world-wide-web, please send a note to | 13 | | license@php.net so we can mail you a copy immediately. | 14 | +----------------------------------------------------------------------+ 15 | | Author: Antony Dovgal | 16 | +----------------------------------------------------------------------+ 17 | */ 18 | 19 | /* $Id$ */ 20 | 21 | #ifdef HAVE_CONFIG_H 22 | #include "config.h" 23 | #endif 24 | 25 | #include "php.h" 26 | #include "php_ini.h" 27 | #include "ext/standard/info.h" 28 | #include "zend_exceptions.h" 29 | #include "php_archive.h" 30 | #include "archive_reader.h" 31 | #include "archive_writer.h" 32 | #include "archive_util.h" 33 | #include "archive_clbk.h" 34 | #include "php_archive_entry.h" 35 | 36 | #if (PHP_MAJOR_VERSION == 5) && (PHP_MINOR_VERSION < 2) 37 | #define archive_ce_Exception zend_exception_get_default() 38 | #else 39 | #define archive_ce_Exception zend_exception_get_default(TSRMLS_C) 40 | #endif 41 | 42 | /* {{{ archive_functions[] 43 | */ 44 | zend_function_entry archive_functions[] = { 45 | {NULL, NULL, NULL} 46 | }; 47 | /* }}} */ 48 | 49 | /* {{{ archive_module_entry 50 | */ 51 | zend_module_entry archive_module_entry = { 52 | #if ZEND_MODULE_API_NO >= 20010901 53 | STANDARD_MODULE_HEADER, 54 | #endif 55 | "archive", 56 | archive_functions, 57 | PHP_MINIT(archive), 58 | NULL, /* nothing */ 59 | NULL, /* to do */ 60 | NULL, /* here */ 61 | PHP_MINFO(archive), 62 | #if ZEND_MODULE_API_NO >= 20010901 63 | PHP_ARCHIVE_VERSION, 64 | #endif 65 | STANDARD_MODULE_PROPERTIES 66 | }; 67 | /* }}} */ 68 | 69 | #ifdef COMPILE_DL_ARCHIVE 70 | ZEND_GET_MODULE(archive) 71 | #endif 72 | 73 | static void _archive_desc_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC); 74 | 75 | /* {{{ _archive_entries_hash_dtor 76 | */ 77 | void _archive_entries_hash_dtor(void *data) 78 | { 79 | archive_entry_t *entry = *(archive_entry_t **)data; 80 | TSRMLS_FETCH(); 81 | 82 | _archive_entry_free(entry TSRMLS_CC); 83 | } 84 | /* }}} */ 85 | 86 | /* {{{ _archive_desc_dtor 87 | */ 88 | static void _archive_desc_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC) 89 | { 90 | archive_file_t *arch = (archive_file_t *)rsrc->ptr; 91 | 92 | if (arch->mode == PHP_ARCHIVE_READ_MODE) { 93 | archive_read_close(arch->arch); 94 | archive_read_free(arch->arch); 95 | } 96 | else if (arch->mode == PHP_ARCHIVE_WRITE_MODE) { 97 | archive_write_close(arch->arch); 98 | archive_write_free(arch->arch); 99 | } 100 | 101 | if (arch->stream) { 102 | php_stream_close(arch->stream); 103 | } 104 | 105 | if (arch->filename) { 106 | efree(arch->filename); 107 | } 108 | 109 | if (arch->entries) { 110 | zend_hash_destroy(arch->entries); 111 | efree(arch->entries); 112 | } 113 | 114 | efree(arch->buf); 115 | efree(arch); 116 | } 117 | /* }}} */ 118 | 119 | /* {{{ _archive_get_rsrc_id 120 | */ 121 | int _archive_get_rsrc_id(zval *this TSRMLS_DC) 122 | { 123 | zval **prop; 124 | 125 | if (zend_hash_find(Z_OBJPROP_P(this), "fd", sizeof("fd"), (void **)&prop) == FAILURE) { 126 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find archive file descriptor"); 127 | return 0; 128 | } 129 | 130 | return Z_LVAL_PP(prop); 131 | } 132 | /* }}} */ 133 | 134 | /* {{{ _archive_get_fd 135 | */ 136 | int _archive_get_fd(zval *this, archive_file_t **arch TSRMLS_DC) 137 | { 138 | int resource_id, type; 139 | 140 | 141 | if ((resource_id = _archive_get_rsrc_id(this TSRMLS_CC))) { 142 | *arch = (archive_file_t *) zend_list_find(resource_id, &type); 143 | if (*arch && type==le_archive) { 144 | return 1; 145 | } 146 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find archive file descriptor #%d", resource_id); 147 | } 148 | return 0; 149 | } 150 | /* }}} */ 151 | 152 | /* {{{ PHP_MINIT_FUNCTION 153 | */ 154 | PHP_MINIT_FUNCTION(archive) 155 | { 156 | zend_class_entry tmp_ce_ArchiveException; 157 | 158 | le_archive = zend_register_list_destructors_ex(_archive_desc_dtor, NULL, "archive descriptor", module_number); 159 | 160 | INIT_CLASS_ENTRY(tmp_ce_ArchiveException, "ArchiveException", NULL); 161 | ce_ArchiveException = zend_register_internal_class_ex(&tmp_ce_ArchiveException, archive_ce_Exception, NULL TSRMLS_CC); 162 | 163 | PHP_MINIT(archive_entry)(INIT_FUNC_ARGS_PASSTHRU); 164 | PHP_MINIT(archive_reader)(INIT_FUNC_ARGS_PASSTHRU); 165 | 166 | PHP_MINIT(archive_writer)(INIT_FUNC_ARGS_PASSTHRU); 167 | 168 | REGISTER_LONG_CONSTANT("ARCH_FORMAT_TAR", PHP_ARCHIVE_FORMAT_TAR, CONST_CS | CONST_PERSISTENT); 169 | REGISTER_LONG_CONSTANT("ARCH_FORMAT_CPIO", PHP_ARCHIVE_FORMAT_CPIO, CONST_CS | CONST_PERSISTENT); 170 | REGISTER_LONG_CONSTANT("ARCH_FORMAT_PAX", PHP_ARCHIVE_FORMAT_PAX, CONST_CS | CONST_PERSISTENT); 171 | REGISTER_LONG_CONSTANT("ARCH_FORMAT_PAX_RESTRICTED", PHP_ARCHIVE_FORMAT_PAX_RESTRICTED, CONST_CS | CONST_PERSISTENT); 172 | REGISTER_LONG_CONSTANT("ARCH_FORMAT_SHAR", PHP_ARCHIVE_FORMAT_SHAR, CONST_CS | CONST_PERSISTENT); 173 | REGISTER_LONG_CONSTANT("ARCH_FORMAT_USTAR", PHP_ARCHIVE_FORMAT_USTAR, CONST_CS | CONST_PERSISTENT); 174 | REGISTER_LONG_CONSTANT("ARCH_FORMAT_RAR", PHP_ARCHIVE_FORMAT_RAR, CONST_CS | CONST_PERSISTENT); 175 | REGISTER_LONG_CONSTANT("ARCH_FORMAT_ZIP", PHP_ARCHIVE_FORMAT_ZIP, CONST_CS | CONST_PERSISTENT); 176 | REGISTER_LONG_CONSTANT("ARCH_FORMAT_7ZIP", PHP_ARCHIVE_FORMAT_7ZIP, CONST_CS | CONST_PERSISTENT); 177 | REGISTER_LONG_CONSTANT("ARCH_FORMAT_NONE", PHP_ARCHIVE_FORMAT_NONE, CONST_CS | CONST_PERSISTENT); 178 | REGISTER_LONG_CONSTANT("ARCH_COMPRESSION_GZIP", PHP_ARCHIVE_COMPRESSION_GZIP, CONST_CS | CONST_PERSISTENT); 179 | REGISTER_LONG_CONSTANT("ARCH_COMPRESSION_BZIP2", PHP_ARCHIVE_COMPRESSION_BZIP2, CONST_CS | CONST_PERSISTENT); 180 | REGISTER_LONG_CONSTANT("ARCH_COMPRESSION_COMPRESS", PHP_ARCHIVE_COMPRESSION_COMPRESS, CONST_CS | CONST_PERSISTENT); 181 | REGISTER_LONG_CONSTANT("ARCH_COMPRESSION_NONE", PHP_ARCHIVE_COMPRESSION_NONE, CONST_CS | CONST_PERSISTENT); 182 | 183 | return SUCCESS; 184 | } 185 | /* }}} */ 186 | 187 | /* {{{ PHP_MINFO_FUNCTION 188 | */ 189 | PHP_MINFO_FUNCTION(archive) 190 | { 191 | php_info_print_table_start(); 192 | php_info_print_table_header(2, "archive support", "enabled"); 193 | php_info_print_table_row(2, "extension version", PHP_ARCHIVE_VERSION); 194 | php_info_print_table_row(2, "libarchive version", archive_version_string()); 195 | php_info_print_table_end(); 196 | } 197 | /* }}} */ 198 | 199 | /* 200 | * Local variables: 201 | * tab-width: 4 202 | * c-basic-offset: 4 203 | * End: 204 | * vim600: noet sw=4 ts=4 fdm=marker 205 | * vim<600: noet sw=4 ts=4 206 | */ 207 | -------------------------------------------------------------------------------- /archive_entry.c: -------------------------------------------------------------------------------- 1 | /* 2 | +----------------------------------------------------------------------+ 3 | | PHP Version 5 | 4 | +----------------------------------------------------------------------+ 5 | | Copyright (c) 1997-2004 The PHP Group | 6 | +----------------------------------------------------------------------+ 7 | | This source file is subject to version 3.0 of the PHP license, | 8 | | that is bundled with this package in the file LICENSE, and is | 9 | | available through the world-wide-web at the following url: | 10 | | http://www.php.net/license/3_0.txt. | 11 | | If you did not receive a copy of the PHP license and are unable to | 12 | | obtain it through the world-wide-web, please send a note to | 13 | | license@php.net so we can mail you a copy immediately. | 14 | +----------------------------------------------------------------------+ 15 | | Author: Antony Dovgal | 16 | +----------------------------------------------------------------------+ 17 | */ 18 | 19 | /* $Id$ */ 20 | 21 | #ifdef HAVE_CONFIG_H 22 | #include "config.h" 23 | #endif 24 | 25 | #include 26 | 27 | #include "php.h" 28 | #include "zend_exceptions.h" 29 | #include "php_archive.h" 30 | #include "php_archive_entry.h" 31 | 32 | /* zend_function_entry funcs_ArchiveEntry {{{ */ 33 | zend_function_entry funcs_ArchiveEntry[] = { 34 | ZEND_ME(ArchiveEntry, __construct, NULL, 0) 35 | ZEND_ME(ArchiveEntry, isDir, NULL, 0) 36 | ZEND_ME(ArchiveEntry, isFile, NULL, 0) 37 | ZEND_ME(ArchiveEntry, isLink, NULL, 0) 38 | ZEND_ME(ArchiveEntry, getPathname, NULL, 0) 39 | ZEND_ME(ArchiveEntry, getResolvedPathname, NULL, 0) 40 | ZEND_ME(ArchiveEntry, getUser, NULL, 0) 41 | ZEND_ME(ArchiveEntry, getGroup, NULL, 0) 42 | ZEND_ME(ArchiveEntry, getMtime, NULL, 0) 43 | ZEND_ME(ArchiveEntry, getSize, NULL, 0) 44 | ZEND_ME(ArchiveEntry, getPerms, NULL, 0) 45 | ZEND_ME(ArchiveEntry, getData, NULL, 0) 46 | {NULL, NULL, NULL} 47 | }; 48 | /* }}} */ 49 | 50 | static void _archive_entry_desc_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC); 51 | 52 | #define PHP_ENTRY_GET_STRUCT \ 53 | zend_error_handling error_handling; \ 54 | zend_replace_error_handling(EH_THROW, ce_ArchiveException, &error_handling TSRMLS_CC); \ 55 | if(!_archive_get_entry_struct(this, &entry TSRMLS_CC)) { \ 56 | zend_restore_error_handling(&error_handling TSRMLS_CC); \ 57 | return; \ 58 | } \ 59 | zend_restore_error_handling(&error_handling TSRMLS_CC); 60 | 61 | /* {{{ _archive_entry_desc_dtor 62 | */ 63 | static void _archive_entry_desc_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC) 64 | { 65 | archive_entry_t *entry = (archive_entry_t *)rsrc->ptr; 66 | _archive_entry_free(entry TSRMLS_CC); 67 | } 68 | /* }}} */ 69 | 70 | /* {{{ _archive_entry_free 71 | */ 72 | void _archive_entry_free(archive_entry_t *entry TSRMLS_DC) 73 | { 74 | if (entry->data) { 75 | efree(entry->data); 76 | } 77 | 78 | if (entry->filename) { 79 | efree(entry->filename); 80 | } 81 | 82 | if (entry->resolved_filename) { 83 | efree(entry->resolved_filename); 84 | } 85 | 86 | /* 87 | if (entry->entry) { 88 | archive_entry_free(entry->entry); 89 | } 90 | */ 91 | 92 | efree(entry); 93 | } 94 | /* }}} */ 95 | 96 | /* {{{ _archive_get_entry_rsrc_id 97 | */ 98 | int _archive_get_entry_rsrc_id(zval *this TSRMLS_DC) 99 | { 100 | zval **prop; 101 | 102 | if (zend_hash_find(Z_OBJPROP_P(this), "entry", sizeof("entry"), (void **)&prop) == FAILURE) { 103 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find entry descriptor"); 104 | return 0; 105 | } 106 | 107 | return Z_LVAL_PP(prop); 108 | } 109 | /* }}} */ 110 | 111 | /* {{{ _archive_get_entry_struct 112 | */ 113 | int _archive_get_entry_struct(zval *this, archive_entry_t **entry TSRMLS_DC) 114 | { 115 | int resource_id, type; 116 | 117 | if ((resource_id = _archive_get_entry_rsrc_id(this TSRMLS_CC))) { 118 | *entry = (archive_entry_t *) zend_list_find(resource_id, &type); 119 | if (*entry && type==le_archive_entry) { 120 | return 1; 121 | } 122 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find entry descriptor #%d", resource_id); 123 | } 124 | return 0; 125 | } 126 | /* }}} */ 127 | 128 | /* {{{ PHP_MINIT_FUNCTION 129 | */ 130 | PHP_MINIT_FUNCTION(archive_entry) { 131 | zend_class_entry ce; 132 | 133 | le_archive_entry = zend_register_list_destructors_ex(_archive_entry_desc_dtor, NULL, "archive entry descriptor", module_number); 134 | 135 | INIT_CLASS_ENTRY(ce, "ArchiveEntry", funcs_ArchiveEntry); 136 | ce_ArchiveEntry = zend_register_internal_class_ex(&ce, ce_ArchiveEntry, NULL TSRMLS_CC); 137 | 138 | return SUCCESS; 139 | } 140 | /* }}} */ 141 | 142 | /* ArchiveEntry::__construct {{{ 143 | * 144 | */ 145 | ZEND_METHOD(ArchiveEntry, __construct) 146 | { 147 | zval *this = getThis(); 148 | char *filename; 149 | int filename_len, resource_id; 150 | archive_entry_t *entry; 151 | struct stat *stat_sb; 152 | php_stream_statbuf ssb; 153 | zend_error_handling error_handling; 154 | 155 | zend_replace_error_handling(EH_THROW, ce_ArchiveException, &error_handling TSRMLS_CC); 156 | 157 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &filename, &filename_len) == FAILURE) { 158 | zend_restore_error_handling(&error_handling TSRMLS_CC); 159 | return; 160 | } 161 | 162 | #if PHP_API_VERSION < 20100412 163 | if (PG(safe_mode) && (!php_checkuid(filename, NULL, CHECKUID_CHECK_FILE_AND_DIR))) { 164 | zend_restore_error_handling(&error_handling TSRMLS_CC); 165 | return; 166 | } 167 | #endif 168 | 169 | if (php_check_open_basedir(filename TSRMLS_CC)) { 170 | zend_restore_error_handling(&error_handling TSRMLS_CC); 171 | return; 172 | } 173 | 174 | if (php_stream_stat_path_ex((char *)filename, PHP_STREAM_URL_STAT_LINK, &ssb, NULL)) { 175 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "stat failed for %s", filename); 176 | zend_restore_error_handling(&error_handling TSRMLS_CC); 177 | return; 178 | } 179 | 180 | stat_sb = &ssb.sb; 181 | 182 | entry = (archive_entry_t *) emalloc(sizeof(archive_entry_t)); 183 | entry->resolved_filename = NULL; 184 | 185 | #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS) 186 | if (S_ISLNK(stat_sb->st_mode)) { 187 | char resolved_path_buff[MAXPATHLEN]; 188 | 189 | if (VCWD_REALPATH(filename, resolved_path_buff)) { 190 | /* TODO figure out if we need this check */ 191 | #if 0 && defined(ZTS) 192 | if (VCWD_ACCESS(resolved_path_buff, F_OK)) { 193 | efree(entry); 194 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "stat failed for %s", filename); 195 | zend_restore_error_handling(&error_handling TSRMLS_CC); 196 | return; 197 | } 198 | #endif 199 | entry->resolved_filename = estrdup(resolved_path_buff); 200 | } 201 | } 202 | #endif 203 | 204 | if (!S_ISREG(stat_sb->st_mode)) { 205 | stat_sb->st_size = 0; 206 | } 207 | 208 | entry->entry = archive_entry_new(); 209 | entry->data = NULL; 210 | entry->data_len = 0; 211 | entry->filename = estrndup(filename, filename_len); 212 | 213 | archive_entry_copy_stat(entry->entry, &ssb.sb); 214 | 215 | resource_id = zend_list_insert(entry,le_archive_entry); 216 | add_property_resource(this, "entry", resource_id); 217 | 218 | zend_restore_error_handling(&error_handling TSRMLS_CC); 219 | return; 220 | } 221 | /* }}} */ 222 | 223 | /* ArchiveEntry::isDir {{{ 224 | * 225 | */ 226 | ZEND_METHOD(ArchiveEntry, isDir) 227 | { 228 | zval *this = getThis(); 229 | archive_entry_t *entry; 230 | mode_t mode; 231 | 232 | PHP_ENTRY_GET_STRUCT; 233 | 234 | mode = archive_entry_mode(entry->entry); 235 | 236 | RETURN_BOOL(S_ISDIR(mode)); 237 | } 238 | /* }}} */ 239 | 240 | /* ArchiveEntry::isFile {{{ 241 | * 242 | */ 243 | ZEND_METHOD(ArchiveEntry, isFile) 244 | { 245 | zval *this = getThis(); 246 | archive_entry_t *entry; 247 | mode_t mode; 248 | 249 | PHP_ENTRY_GET_STRUCT; 250 | 251 | mode = archive_entry_mode(entry->entry); 252 | 253 | RETURN_BOOL(S_ISREG(mode)); 254 | } 255 | /* }}} */ 256 | 257 | /* ArchiveEntry::isLink {{{ 258 | * 259 | */ 260 | ZEND_METHOD(ArchiveEntry, isLink) 261 | { 262 | zval *this = getThis(); 263 | archive_entry_t *entry; 264 | mode_t mode; 265 | 266 | PHP_ENTRY_GET_STRUCT; 267 | 268 | mode = archive_entry_mode(entry->entry); 269 | 270 | RETURN_BOOL(S_ISLNK(mode)); 271 | } 272 | /* }}} */ 273 | 274 | /* ArchiveEntry::getPathname {{{ 275 | * 276 | */ 277 | ZEND_METHOD(ArchiveEntry, getPathname) 278 | { 279 | zval *this = getThis(); 280 | archive_entry_t *entry; 281 | const char *pathname; 282 | 283 | PHP_ENTRY_GET_STRUCT; 284 | 285 | if (entry->filename) { 286 | RETURN_STRING(entry->filename, 1); 287 | } 288 | 289 | if ((pathname = archive_entry_pathname(entry->entry))) { 290 | RETURN_STRING((char *)pathname, 1); 291 | } 292 | RETURN_FALSE; 293 | } 294 | /* }}} */ 295 | 296 | /* ArchiveEntry::getResolvedPathname {{{ 297 | * 298 | */ 299 | ZEND_METHOD(ArchiveEntry, getResolvedPathname) 300 | { 301 | zval *this = getThis(); 302 | archive_entry_t *entry; 303 | const char *pathname; 304 | 305 | PHP_ENTRY_GET_STRUCT; 306 | 307 | if (entry->resolved_filename) { 308 | RETURN_STRING(entry->resolved_filename, 1); 309 | } 310 | 311 | if ((pathname = archive_entry_symlink(entry->entry))) { 312 | RETURN_STRING((char *)pathname, 1); 313 | } 314 | 315 | RETURN_FALSE; 316 | } 317 | /* }}} */ 318 | 319 | /* ArchiveEntry::getUser {{{ 320 | * 321 | */ 322 | ZEND_METHOD(ArchiveEntry, getUser) 323 | { 324 | zval *this = getThis(); 325 | archive_entry_t *entry; 326 | const char *uname; 327 | 328 | PHP_ENTRY_GET_STRUCT; 329 | 330 | if ((uname = archive_entry_uname(entry->entry))) { 331 | RETURN_STRING((char *)uname, 1); 332 | } 333 | RETURN_FALSE; 334 | } 335 | /* }}} */ 336 | 337 | /* ArchiveEntry::getGroup {{{ 338 | * 339 | */ 340 | ZEND_METHOD(ArchiveEntry, getGroup) 341 | { 342 | zval *this = getThis(); 343 | archive_entry_t *entry; 344 | const char *gname; 345 | 346 | PHP_ENTRY_GET_STRUCT; 347 | 348 | if ((gname = archive_entry_gname(entry->entry))) { 349 | RETURN_STRING((char *)gname, 1); 350 | } 351 | RETURN_FALSE; 352 | } 353 | /* }}} */ 354 | 355 | /* ArchiveEntry::getMtime {{{ 356 | * 357 | */ 358 | ZEND_METHOD(ArchiveEntry, getMtime) 359 | { 360 | zval *this = getThis(); 361 | archive_entry_t *entry; 362 | time_t mtime; 363 | 364 | PHP_ENTRY_GET_STRUCT; 365 | 366 | mtime = archive_entry_mtime(entry->entry); 367 | 368 | RETURN_LONG(mtime); 369 | } 370 | /* }}} */ 371 | 372 | /* ArchiveEntry::getSize {{{ 373 | * 374 | */ 375 | ZEND_METHOD(ArchiveEntry, getSize) 376 | { 377 | zval *this = getThis(); 378 | archive_entry_t *entry; 379 | off_t size; 380 | 381 | PHP_ENTRY_GET_STRUCT; 382 | 383 | size = archive_entry_size(entry->entry); 384 | 385 | RETURN_LONG(size); 386 | } 387 | /* }}} */ 388 | 389 | /* ArchiveEntry::getPerms {{{ 390 | * 391 | */ 392 | ZEND_METHOD(ArchiveEntry, getPerms) 393 | { 394 | zval *this = getThis(); 395 | archive_entry_t *entry; 396 | mode_t mode; 397 | 398 | PHP_ENTRY_GET_STRUCT; 399 | 400 | mode = archive_entry_mode(entry->entry); 401 | 402 | RETURN_LONG(mode); 403 | } 404 | /* }}} */ 405 | 406 | /* ArchiveEntry::getData {{{ 407 | * 408 | */ 409 | ZEND_METHOD(ArchiveEntry, getData) 410 | { 411 | zval *this = getThis(); 412 | archive_entry_t *entry; 413 | 414 | PHP_ENTRY_GET_STRUCT; 415 | 416 | if (entry->data) { 417 | RETURN_STRINGL(entry->data, entry->data_len, 1); 418 | } 419 | RETURN_FALSE; 420 | } 421 | /* }}} */ 422 | 423 | /* 424 | * Local variables: 425 | * tab-width: 4 426 | * c-basic-offset: 4 427 | * End: 428 | * vim600: noet sw=4 ts=4 fdm=marker 429 | * vim<600: noet sw=4 ts=4 430 | */ 431 | -------------------------------------------------------------------------------- /tests/list/008.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | try-to-extract-with-umask-777.tar 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | getNextEntry(true)) { 11 | var_dump($e); 12 | var_dump($e->isDir()); 13 | var_dump($e->isFile()); 14 | var_dump($e->isLink()); 15 | var_dump($e->getPathname()); 16 | var_dump($e->getResolvedPathname()); 17 | var_dump($e->getUser()); 18 | var_dump($e->getGroup()); 19 | var_dump($e->getMtime()); 20 | var_dump($e->getSize()); 21 | var_dump($e->getPerms()); 22 | var_dump($e->getData()); 23 | } 24 | 25 | echo "Done\n"; 26 | ?> 27 | --EXPECTF-- 28 | object(ArchiveEntry)#%d (1) { 29 | ["entry"]=> 30 | resource(%d) of type (archive entry descriptor) 31 | } 32 | bool(false) 33 | bool(true) 34 | bool(false) 35 | string(59) "usr/local/share/doc/ghostscript/7.06/pcl3/how-to-report.txt" 36 | bool(false) 37 | string(3) "tim" 38 | string(3) "tim" 39 | int(1053769444) 40 | int(12890) 41 | int(32768) 42 | string(12890) "" 43 | Done 44 | -------------------------------------------------------------------------------- /archive_writer.c: -------------------------------------------------------------------------------- 1 | /* 2 | +----------------------------------------------------------------------+ 3 | | PHP Version 5 | 4 | +----------------------------------------------------------------------+ 5 | | Copyright (c) 1997-2004 The PHP Group | 6 | +----------------------------------------------------------------------+ 7 | | This source file is subject to version 3.0 of the PHP license, | 8 | | that is bundled with this package in the file LICENSE, and is | 9 | | available through the world-wide-web at the following url: | 10 | | http://www.php.net/license/3_0.txt. | 11 | | If you did not receive a copy of the PHP license and are unable to | 12 | | obtain it through the world-wide-web, please send a note to | 13 | | license@php.net so we can mail you a copy immediately. | 14 | +----------------------------------------------------------------------+ 15 | | Author: Antony Dovgal | 16 | +----------------------------------------------------------------------+ 17 | */ 18 | 19 | /* $Id$ */ 20 | 21 | #ifdef HAVE_CONFIG_H 22 | #include "config.h" 23 | #endif 24 | 25 | #include "php.h" 26 | #include "zend_exceptions.h" 27 | #include "php_archive.h" 28 | #include "archive_clbk.h" 29 | #include "archive_writer.h" 30 | #include "archive_util.h" 31 | #include "php_archive_entry.h" 32 | 33 | #define DEFAULT_BYTES_PER_BLOCK 8192 34 | 35 | zend_class_entry *ce_ArchiveWriter; 36 | zend_class_entry *ce_ArchiveWriterInterface; 37 | 38 | /* zend_function_entry funcs_ArchiveWriterInterface {{{ */ 39 | zend_function_entry funcs_ArchiveWriterInterface[] = { 40 | ZEND_ABSTRACT_ME(ArchiveWriter, __construct, NULL) 41 | ZEND_ABSTRACT_ME(ArchiveWriter, addEntry, NULL) 42 | ZEND_ABSTRACT_ME(ArchiveWriter, finish, NULL) 43 | {NULL, NULL, NULL} 44 | }; 45 | /* }}} */ 46 | 47 | /* zend_function_entry funcs_ArchiveWriter {{{ */ 48 | zend_function_entry funcs_ArchiveWriter[] = { 49 | ZEND_ME(ArchiveWriter, __construct, NULL, 0) 50 | ZEND_ME(ArchiveWriter, addEntry, NULL, 0) 51 | ZEND_ME(ArchiveWriter, finish, NULL, 0) 52 | {NULL, NULL, NULL} 53 | }; 54 | /* }}} */ 55 | 56 | /* {{{ PHP_MINIT_FUNCTION 57 | */ 58 | PHP_MINIT_FUNCTION(archive_writer) 59 | { 60 | zend_class_entry tmp_ce_ArchiveWriter, tmp_ce_ArchiveWriterInterface; 61 | 62 | INIT_CLASS_ENTRY(tmp_ce_ArchiveWriterInterface, "ArchiveWriterInterface", funcs_ArchiveWriterInterface); 63 | ce_ArchiveWriterInterface = zend_register_internal_class(&tmp_ce_ArchiveWriterInterface TSRMLS_CC); 64 | ce_ArchiveWriterInterface->ce_flags = ZEND_ACC_INTERFACE; 65 | 66 | INIT_CLASS_ENTRY(tmp_ce_ArchiveWriter, "ArchiveWriter", funcs_ArchiveWriter); 67 | ce_ArchiveWriter = zend_register_internal_class(&tmp_ce_ArchiveWriter TSRMLS_CC); 68 | 69 | zend_class_implements(ce_ArchiveWriter TSRMLS_CC, 1, ce_ArchiveWriterInterface); 70 | 71 | return SUCCESS; 72 | } 73 | /* }}} */ 74 | 75 | /* ArchiveWriter::__construct {{{ 76 | * 77 | */ 78 | ZEND_METHOD(ArchiveWriter, __construct) 79 | { 80 | archive_file_t *arch = NULL; 81 | int resource_id; 82 | zval *this = getThis(); 83 | const char *error_string = NULL; 84 | char *filename; 85 | long error_num, filename_len, result, format=0, compression=0; 86 | zend_error_handling error_handling; 87 | 88 | zend_replace_error_handling(EH_THROW, ce_ArchiveException, &error_handling TSRMLS_CC); 89 | 90 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|ll", &filename, &filename_len, &format, &compression) == FAILURE) { 91 | zend_restore_error_handling(&error_handling TSRMLS_CC); 92 | return; 93 | } 94 | 95 | #if PHP_API_VERSION < 20100412 96 | if (PG(safe_mode) && (!php_checkuid(filename, NULL, CHECKUID_CHECK_FILE_AND_DIR))) { 97 | zend_restore_error_handling(&error_handling TSRMLS_CC); 98 | return; 99 | } 100 | #endif 101 | 102 | if (php_check_open_basedir(filename TSRMLS_CC)) { 103 | zend_restore_error_handling(&error_handling TSRMLS_CC); 104 | return; 105 | } 106 | 107 | arch = (archive_file_t *) emalloc(sizeof(archive_file_t)); 108 | 109 | arch->stream = NULL; 110 | 111 | ALLOC_HASHTABLE(arch->entries); 112 | zend_hash_init(arch->entries, 10, NULL, _archive_entries_hash_dtor, 0); 113 | 114 | arch->mode = PHP_ARCHIVE_WRITE_MODE; 115 | arch->buf = emalloc(PHP_ARCHIVE_BUF_LEN + 1); 116 | arch->filename = estrndup(filename, filename_len); 117 | arch->arch = archive_write_new(); 118 | 119 | switch (compression) { 120 | case PHP_ARCHIVE_COMPRESSION_GZIP: 121 | if (archive_write_add_filter_gzip(arch->arch) != ARCHIVE_OK) { 122 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Gzip compression is not supported in this build"); 123 | zend_restore_error_handling(&error_handling TSRMLS_CC); 124 | return; 125 | } 126 | break; 127 | 128 | case PHP_ARCHIVE_COMPRESSION_BZIP2: 129 | if (archive_write_add_filter_bzip2(arch->arch) != ARCHIVE_OK) { 130 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Bzip2 compression is not supported in this build"); 131 | zend_restore_error_handling(&error_handling TSRMLS_CC); 132 | return; 133 | } 134 | break; 135 | case 0: /* default value */ 136 | case PHP_ARCHIVE_COMPRESSION_NONE: 137 | /* always supported */ 138 | break; 139 | default: 140 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unsupported compression type %ld", compression); 141 | zend_restore_error_handling(&error_handling TSRMLS_CC); 142 | return; 143 | break; 144 | } 145 | 146 | switch (format) { 147 | case 0: /* default value */ 148 | case PHP_ARCHIVE_FORMAT_TAR: 149 | case PHP_ARCHIVE_FORMAT_PAX_RESTRICTED: 150 | archive_write_set_format_pax_restricted(arch->arch); 151 | break; 152 | case PHP_ARCHIVE_FORMAT_PAX: 153 | archive_write_set_format_pax(arch->arch); 154 | break; 155 | case PHP_ARCHIVE_FORMAT_CPIO: 156 | archive_write_set_format_cpio(arch->arch); 157 | break; 158 | case PHP_ARCHIVE_FORMAT_SHAR: 159 | archive_write_set_format_shar(arch->arch); 160 | break; 161 | case PHP_ARCHIVE_FORMAT_USTAR: 162 | archive_write_set_format_ustar(arch->arch); 163 | break; 164 | default: 165 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unsupported archive format: %ld", format); 166 | zend_restore_error_handling(&error_handling TSRMLS_CC); 167 | return; 168 | break; 169 | } 170 | 171 | archive_write_set_bytes_per_block(arch->arch, DEFAULT_BYTES_PER_BLOCK); 172 | result = archive_write_open(arch->arch, arch, _archive_open_clbk, _archive_write_clbk, _archive_close_clbk); 173 | /* do not pad the last block */ 174 | archive_write_set_bytes_in_last_block(arch->arch, 1); 175 | 176 | if (result) { 177 | error_num = archive_errno(arch->arch); 178 | error_string = archive_error_string(arch->arch); 179 | efree(arch->filename); 180 | efree(arch->buf); 181 | efree(arch); 182 | if (error_num && error_string) { 183 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to open file %s for writing: error #%ld, %s", filename, error_num, error_string); 184 | } 185 | else { 186 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to open file %s for writing: unknown error %ld", filename, result); 187 | } 188 | zend_restore_error_handling(&error_handling TSRMLS_CC); 189 | return; 190 | } 191 | 192 | resource_id = zend_list_insert(arch,le_archive); 193 | add_property_resource(this, "fd", resource_id); 194 | 195 | zend_restore_error_handling(&error_handling TSRMLS_CC); 196 | return; 197 | } 198 | /* }}} */ 199 | 200 | /* ArchiveWriter::addEntry {{{ 201 | * 202 | */ 203 | ZEND_METHOD(ArchiveWriter, addEntry) 204 | { 205 | zval *this = getThis(); 206 | zval *entry_obj; 207 | archive_file_t *arch; 208 | archive_entry_t *entry, *entry_copy; 209 | char *pathname; 210 | int pathname_len; 211 | const struct stat *stat_sb; 212 | zend_error_handling error_handling; 213 | 214 | zend_replace_error_handling(EH_THROW, ce_ArchiveException, &error_handling TSRMLS_CC); 215 | 216 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &entry_obj) == FAILURE) { 217 | zend_restore_error_handling(&error_handling TSRMLS_CC); 218 | return; 219 | } 220 | 221 | if (!_archive_get_fd(this, &arch TSRMLS_CC)) { 222 | zend_restore_error_handling(&error_handling TSRMLS_CC); 223 | return; 224 | } 225 | 226 | if (!instanceof_function(Z_OBJCE_P(entry_obj), ce_ArchiveEntry TSRMLS_CC)) { 227 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "An instance of ArchiveEntry is required"); 228 | zend_restore_error_handling(&error_handling TSRMLS_CC); 229 | return; 230 | } 231 | 232 | if (!_archive_get_entry_struct(entry_obj, &entry TSRMLS_CC)) { 233 | zend_restore_error_handling(&error_handling TSRMLS_CC); 234 | return; 235 | } 236 | 237 | pathname = entry->filename; 238 | pathname_len = strlen(pathname); 239 | 240 | _archive_normalize_path(&pathname, &pathname_len); 241 | 242 | if (pathname_len == 0 || pathname[0] == '\0') { 243 | /* user is probably trying to add "./", "/", ".." or ".", ignoring it silently */ 244 | zend_restore_error_handling(&error_handling TSRMLS_CC); 245 | RETURN_TRUE; 246 | } 247 | 248 | /* copy entry.. */ 249 | entry_copy = emalloc(sizeof(archive_entry_t)); 250 | memcpy(entry_copy, entry, sizeof(archive_entry_t)); 251 | entry_copy->entry = archive_entry_new(); 252 | entry_copy->filename = estrdup(entry->filename); 253 | 254 | entry_copy->data = NULL; 255 | entry_copy->data_len = 0; 256 | 257 | archive_entry_copy_pathname(entry_copy->entry, pathname); 258 | stat_sb = archive_entry_stat(entry->entry); 259 | archive_entry_copy_stat(entry_copy->entry, stat_sb); 260 | 261 | /* ..and add it to the hash */ 262 | zend_hash_update(arch->entries, pathname, pathname_len + 1, &entry_copy, sizeof(archive_entry_t), NULL); 263 | zend_restore_error_handling(&error_handling TSRMLS_CC); 264 | RETURN_TRUE; 265 | } 266 | /* }}} */ 267 | 268 | /* ArchiveWriter::finish {{{ 269 | * 270 | */ 271 | ZEND_METHOD(ArchiveWriter, finish) 272 | { 273 | zval *this = getThis(); 274 | int resource_id; 275 | HashPosition pos; 276 | archive_file_t *arch; 277 | archive_entry_t **entry; 278 | int result, error_num; 279 | const char *error_string; 280 | mode_t mode; 281 | php_stream *stream; 282 | zend_error_handling error_handling; 283 | 284 | zend_replace_error_handling(EH_THROW, ce_ArchiveException, &error_handling TSRMLS_CC); 285 | 286 | if (!_archive_get_fd(this, &arch TSRMLS_CC)) { 287 | zend_restore_error_handling(&error_handling TSRMLS_CC); 288 | return; 289 | } 290 | 291 | if (zend_hash_sort(arch->entries, zend_qsort, _archive_pathname_compare, 0 TSRMLS_CC) == FAILURE) { 292 | RETURN_FALSE; 293 | } 294 | 295 | zend_hash_internal_pointer_reset_ex(arch->entries, &pos); 296 | while (zend_hash_get_current_data_ex(arch->entries, (void **)&entry, &pos) == SUCCESS) { 297 | 298 | mode = archive_entry_mode((*entry)->entry); 299 | 300 | if (S_ISREG(mode) && archive_entry_size((*entry)->entry) > 0) { 301 | if ((stream = php_stream_open_wrapper_ex((*entry)->filename, "r", ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL, NULL))) { 302 | char buf[PHP_ARCHIVE_BUF_LEN]; 303 | int header_written=0; 304 | int read_bytes; 305 | 306 | while ((read_bytes = php_stream_read(stream, buf, PHP_ARCHIVE_BUF_LEN))) { 307 | if (!header_written) { 308 | /* write header only after the first successful read */ 309 | result = archive_write_header(arch->arch, (*entry)->entry); 310 | if (result == ARCHIVE_FATAL) { 311 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to write entry header for file %s: fatal error", (*entry)->filename); 312 | zend_restore_error_handling(&error_handling TSRMLS_CC); 313 | return; 314 | } 315 | header_written = 1; 316 | } 317 | result = archive_write_data(arch->arch, buf, read_bytes); 318 | 319 | if (result <= 0) { 320 | error_num = archive_errno(arch->arch); 321 | error_string = archive_error_string(arch->arch); 322 | 323 | if (error_num && error_string) { 324 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to write file %s to archive: error #%d, %s", (*entry)->filename, error_num, error_string); 325 | } 326 | else { 327 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to write file %s: unknown error %d", (*entry)->filename, result); 328 | } 329 | php_stream_close(stream); 330 | zend_restore_error_handling(&error_handling TSRMLS_CC); 331 | return; 332 | } 333 | } 334 | php_stream_close(stream); 335 | } 336 | } 337 | else { 338 | result = archive_write_header(arch->arch, (*entry)->entry); 339 | if (result == ARCHIVE_FATAL) { 340 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to write entry header for file %s: fatal error", (*entry)->filename); 341 | zend_restore_error_handling(&error_handling TSRMLS_CC); 342 | return; 343 | } 344 | } 345 | zend_hash_move_forward_ex(arch->entries, &pos); 346 | } 347 | 348 | if ((resource_id = _archive_get_rsrc_id(this TSRMLS_CC))) { 349 | add_property_resource(this, "fd", 0); 350 | zend_list_delete(resource_id); 351 | zend_restore_error_handling(&error_handling TSRMLS_CC); 352 | RETURN_TRUE; 353 | } 354 | 355 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to finish writing of archive file"); 356 | zend_restore_error_handling(&error_handling TSRMLS_CC); 357 | } 358 | /* }}} */ 359 | 360 | /* 361 | * Local variables: 362 | * tab-width: 4 363 | * c-basic-offset: 4 364 | * End: 365 | * vim600: noet sw=4 ts=4 fdm=marker 366 | * vim<600: noet sw=4 ts=4 367 | */ 368 | -------------------------------------------------------------------------------- /tests/list_gz/008.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | try-to-extract-with-umask-777.tar 3 | --SKIPIF-- 4 | 8 | --FILE-- 9 | getNextEntry(true)) { 14 | var_dump($e); 15 | var_dump($e->isDir()); 16 | var_dump($e->isFile()); 17 | var_dump($e->isLink()); 18 | var_dump($e->getPathname()); 19 | var_dump($e->getResolvedPathname()); 20 | var_dump($e->getUser()); 21 | var_dump($e->getGroup()); 22 | var_dump($e->getMtime()); 23 | var_dump($e->getSize()); 24 | var_dump($e->getPerms()); 25 | var_dump($e->getData()); 26 | } 27 | 28 | echo "Done\n"; 29 | ?> 30 | --EXPECTF-- 31 | object(ArchiveEntry)#%d (1) { 32 | ["entry"]=> 33 | resource(%d) of type (archive entry descriptor) 34 | } 35 | bool(false) 36 | bool(true) 37 | bool(false) 38 | string(59) "usr/local/share/doc/ghostscript/7.06/pcl3/how-to-report.txt" 39 | bool(false) 40 | string(3) "tim" 41 | string(3) "tim" 42 | int(1053769444) 43 | int(12890) 44 | int(32768) 45 | string(12890) "" 46 | Done 47 | -------------------------------------------------------------------------------- /tests/list_bz2/008.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | try-to-extract-with-umask-777.tar 3 | --SKIPIF-- 4 | 8 | --FILE-- 9 | getNextEntry(true)) { 14 | var_dump($e); 15 | var_dump($e->isDir()); 16 | var_dump($e->isFile()); 17 | var_dump($e->isLink()); 18 | var_dump($e->getPathname()); 19 | var_dump($e->getResolvedPathname()); 20 | var_dump($e->getUser()); 21 | var_dump($e->getGroup()); 22 | var_dump($e->getMtime()); 23 | var_dump($e->getSize()); 24 | var_dump($e->getPerms()); 25 | var_dump($e->getData()); 26 | } 27 | 28 | echo "Done\n"; 29 | ?> 30 | --EXPECTF-- 31 | object(ArchiveEntry)#%d (1) { 32 | ["entry"]=> 33 | resource(%d) of type (archive entry descriptor) 34 | } 35 | bool(false) 36 | bool(true) 37 | bool(false) 38 | string(59) "usr/local/share/doc/ghostscript/7.06/pcl3/how-to-report.txt" 39 | bool(false) 40 | string(3) "tim" 41 | string(3) "tim" 42 | int(1053769444) 43 | int(12890) 44 | int(32768) 45 | string(12890) "" 46 | Done 47 | -------------------------------------------------------------------------------- /tests/_files/try-to-extract-with-umask-777.tar: -------------------------------------------------------------------------------- 1 | usr/local/share/doc/ghostscript/7.06/pcl3/how-to-report.txt000000 001750 001750 00000031132 07663637344 023353 0ustar00timtim000000 000000 -------------------------------------------------------------------------------- /tests/list/006.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | mkdir-torture.tar 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | getNextEntry(true)) { 11 | var_dump($e); 12 | var_dump($e->isDir()); 13 | var_dump($e->isFile()); 14 | var_dump($e->isLink()); 15 | var_dump($e->getPathname()); 16 | var_dump($e->getResolvedPathname()); 17 | var_dump($e->getUser()); 18 | var_dump($e->getGroup()); 19 | var_dump($e->getMtime()); 20 | var_dump($e->getSize()); 21 | var_dump($e->getPerms()); 22 | var_dump($e->getData()); 23 | } 24 | 25 | echo "Done\n"; 26 | ?> 27 | --EXPECTF-- 28 | object(ArchiveEntry)#%d (1) { 29 | ["entry"]=> 30 | resource(%d) of type (archive entry descriptor) 31 | } 32 | bool(false) 33 | bool(true) 34 | bool(false) 35 | string(97) "usr/./local/lib/../share/./ImageMagick/.././doc/ghostscript/7.06/./../7.06/pcl3/how-to-report.txt" 36 | bool(false) 37 | string(4) "root" 38 | string(5) "wheel" 39 | int(1053769444) 40 | int(12890) 41 | int(33060) 42 | string(12890) "******************************************************************************* 43 | File: @(#)%s 44 | Contents: How to report bugs and hardware compatibility for pcl3 45 | Author: Martin Lottermoser, Greifswaldstrasse 28, 38124 Braunschweig, 46 | Germany. E-mail: Martin.Lottermoser@t-online.de. 47 | 48 | ******************************************************************************* 49 | * * 50 | * Copyright (C) 2000, 2001 by Martin Lottermoser * 51 | * All rights reserved * 52 | * * 53 | ******************************************************************************* 54 | 55 | 56 | Bugs and Failures 57 | ***************** 58 | This document distinguishes between "bugs" and "failures". A bug is incorrect 59 | behaviour on the part of pcl3, a failure is described by a set of 60 | hardware-relevant parameter values which are not accepted by a particular 61 | printer. Most often a failure is due to hardware limitations in the printer, 62 | not to a problem in pcl3, although it might be difficult to find out which is 63 | the case. For the user, this distinction is fortunately irrelevant. 64 | 65 | 66 | Bugs 67 | **** 68 | The basic rule is that it's a bug if there is disagreement between the 69 | behaviour and the documentation (the bug might be in the documentation, though). 70 | For example, if the documentation states that pcl3 produces a core dump under 71 | certain circumstances, this is by definition not a bug, which means that you 72 | should not report it (I'll have to fix it nevertheless, of course). 73 | 74 | If your printer has a specific subdevice in pcl3 (e.g., if you have a 75 | Hewlett-Packard DeskJet 540, this is the "hpdj540" subdevice) and the result 76 | when using this subdevice is not accepted by the printer or there is printer 77 | functionality you cannot access through this subdevice, this is a bug. 78 | 79 | If you find a bug in pcl3, please report it. The format of your message is 80 | irrelevant, but the content should be sufficiently detailed that I can 81 | reproduce the behaviour. You should always specify the versions of gs and pcl3 82 | you used. Please make sure that the behaviour is due to pcl3 and not to other 83 | causes. In particular, if nothing seems to work and you are on a UNIX system, 84 | do the following: 85 | 86 | - Generate the PCL file by calling gs yourself, and print through a 87 | "raw"/"transparent" queue which does not modify the file. 88 | - If spooled printing fails, log in as root and try to send the file 89 | directly to the device file. If it works, the problem is in the spooler. 90 | - If even that fails, send a line of text (still as superuser) directly 91 | to the device, followed by a form feed: 92 | 93 | printf 'Hello!\r\n\f' > /dev/... 94 | 95 | If this also does not work, you very likely have a kernel or hardware 96 | problem. 97 | 98 | I am writing this because there have been cases where people complained that my 99 | driver wasn't working at all and where the cause turned out to be, e.g., a 100 | misconfiguration of the spooler. Please don't bother me with problems of this 101 | kind; I have enough to do correcting my own mistakes. However, I only demand 102 | that you take reasonable steps to ensure that it isn't you who has created the 103 | problem. If you can't decide which component is at fault, by all means contact 104 | me -- just don't expect a quick answer and don't start by telling me that my 105 | driver doesn't work :-). 106 | 107 | 108 | 109 | Hardware compatibility reports 110 | ****************************** 111 | The pcl3 driver is intended to support a large number of printers. Because the 112 | PCL-3 documentation supplied by Hewlett-Packard is incomplete and occasionally 113 | wrong (sometimes obviously so because of inconsistencies), tests must be made 114 | on various printers in order to discover whether the driver can really be used 115 | for a particular printer model and which parameter values one should specify. 116 | As I do not have access to a complete range of PCL-3 printers, I must rely on 117 | others to do this for me. 118 | 119 | If you have a PCL-3 printer and are using pcl3, please check the file 120 | reports.txt whether there is already an entry for your printer or not. If there 121 | is none or if the hardware-relevant parameters listed are different from the 122 | ones you used, please compose a report in the format described below and send 123 | it to me. You need not cover all possible combinations; in fact, this might be 124 | too confusing for others anyway. Even a single success report, however, can 125 | help someone else with less knowledge or experience to get started. This is a 126 | service *you* can provide to the community of pcl3 users. 127 | 128 | 129 | 130 | Guidelines for testing 131 | ====================== 132 | - Read the documentation. Please. :-) 133 | 134 | - As test files, use publicly available PostScript files, preferably those 135 | included in the ghostscript or pcl3 distributions. The file levels-test.ps in 136 | the latter is a good starting point. 137 | 138 | - Keep in mind that some environment variables influence ghostscript's 139 | behaviour and make sure their values are as intended. 140 | 141 | - If you have access to a manufacturer-endorsed driver for your printer, use 142 | it to generate some test files with various settings, analyse them with 143 | pcl3opts, and try the suggested option combinations first. 144 | 145 | - The basic hardware parameters to test are colour model, resolution, and the 146 | number of intensity levels. 147 | 148 | - Colour model: The interesting models are Gray, CMY, and CMY+K/CMYK, 149 | depending on your printer. You need not bother with CMY for a CMY+K or 150 | CMYK printer unless you discover that the CMY cartridge supports a 151 | higher resolution than the black cartridge. 152 | 153 | - Resolution: Check your printer's documentation first. It should at least 154 | list the highest supported resolution, possibly separately for black and 155 | colour printing. If you don't have access to the documentation, a good 156 | set to test with is {300, 600x300, 600, 1200}. Smaller resolutions 157 | ({75, 100, 150}) are sometimes also supported but they are uninteresting 158 | for serious printing. 159 | 160 | Resolution tests are best made with a file where only the top left corner 161 | of the sheet is used. It should contain some structure of known extension. 162 | If a resolution is not accepted, the printer usually prints the picture 163 | anyway, but at a supported resolution, leading to magnified or reduced 164 | output. 165 | 166 | - Intensity levels: Test this only if your printer's documentation claims 167 | that some kind of Resolution Enhancement (e.g., C-REt) is supported or 168 | pcl3opts tells you that an official driver generates files with this 169 | property. Unless pcl3opts tells you differently, start with 300 ppi and 170 | 4 levels for all colorants used. 171 | 172 | Whether a particular value for a parameter is supported often depends on 173 | the values for other parameters. In some cases, even the print quality is 174 | important. If in doubt, test with "presentation". 175 | 176 | - If your printer has special hardware functionality, tests for that are 177 | also interesting (duplex printing, banner printing, different input or 178 | output trays). If you are using "unspec" or "unspecold", you should also 179 | always try compression method 9 unless the pcl3 documentation states that it 180 | is not supported by your printer. 181 | 182 | 183 | 184 | General rules for reports 185 | ========================= 186 | - You can use all characters in ISO 8859-1, plus HT and NL/LF. 187 | - Please keep to the following syntactic rules which simplify converting the 188 | information into other formats: 189 | - The report consists of a sequence of fields, each occupying an integral 190 | number of lines. 191 | - Each field begins with a field name, starting in column 1 and ending with 192 | the first following colon (':') in the same line. 193 | - The content of a field may be continued over several lines provided all 194 | continuation lines are either empty or indented with blanks (SP or HT). 195 | Trailing empty lines are ignored. 196 | - With the exception of "Success" and "Failure", every field may appear at 197 | most once in a report. If it appears a second time in a file, a new report 198 | is assumed to start at this point. 199 | - Make your report sufficiently detailed to be reproducible but don't tell us 200 | your life story. 201 | 202 | 203 | 204 | Special remarks for individual fields 205 | ===================================== 206 | 207 | - "Name": Supply your full name here. I don't accept anonymous or obviously 208 | nickname-signed reports. 209 | 210 | - "E-mail address" (optional): choose a stable one, your information might be 211 | used for several years. Omit this field if you do not wish your e-mail 212 | address to be disclosed to other users of pcl3. 213 | 214 | - "Date": I prefer the internationally standardized notation, YYYY-MM-DD. 215 | 216 | - "Printer": Be as precise as possible in identifying the printer. Ideally, 217 | I should like to have the following kind of information (as an example 218 | I'm giving some values for a DJ 850C): 219 | - printer name ("HP DeskJet 850C") 220 | - manufacturer's model identification ("C2145A") 221 | - firmware revision ("9.20 02/14/95") 222 | At least some of Hewlett-Packard's printers issue this information when you 223 | print a diagnostic or self test. If your printer's manual doesn't tell you 224 | how to generate such a test, try sending the command "ESC z" to the printer 225 | (on a UNIX system, you can use "printf '\x1bz'" to generate it). 226 | 227 | - pcl3opts (optional): Use this field to describe pcl3opts's output if you ran 228 | pcl3opts on files generated by manufacturer-endorsed drivers and you have 229 | obtained interesting information. You should always describe the driver you 230 | used. 231 | 232 | Interesting information is for example that the official driver generated 233 | files with certain settings for which pcl3opts did not give a warning but 234 | nevertheless you were not able to print such a file with pcl3. Expect me to 235 | ask you for a copy of such a file. 236 | 237 | - "Media configuration file" (optional): If you used a media configuration file 238 | and its content was relevant for the test or you wish to make the file 239 | available to other users, include it or a reference to it here. You must 240 | state where the information came from, so it can be verified in case of 241 | discrepancies. 242 | 243 | - "Remarks" (optional): Use this, if needed, for global information applying 244 | to a number of tests (perhaps a summary) or any other relevant information. 245 | 246 | - "Success:" and "Failure": These are intended for describing the result of 247 | using a single option combination and may be repeated any number of times 248 | (including zero). Each report should be independent of the others so they can 249 | be sorted differently if needed. 250 | 251 | Keep in mind that the key purpose of a report is to find out which hardware 252 | parameters work and which don't. It is therefore a success if the driver is 253 | at least able to correctly tell the printer how to paint shapes at the level 254 | of the printer's hardware capabilities (resolution, colorants and 255 | intensities). A good test file is levels-test.ps which has been designed for 256 | this purpose. I don't count it a failure when the result of printing a 257 | photograph or a similarly demanding document is not as aesthetically pleasing 258 | as it should be or when a problem is due to a bug in ghostscript. Use 259 | comments for such statements if desired. However, the decision whether an 260 | entry is a success or a failure remains yours to make, not mine. 261 | 262 | These fields should start with the list of options given to ghostscript via 263 | the command line, including the "-sDEVICE" option. You should omit options 264 | which are obviously irrelevant for the outcome of the test (like "-dNOPAUSE" 265 | or "-sOutputFile"), but otherwise the option list must be complete. If you 266 | wish to add a comment (and for a failure you must always do that), terminate 267 | this list with a period followed by a newline and add the comment after that. 268 | Here's an example: 269 | 270 | Failure: -sDEVICE=pcl3 -r1200 -sColourModel=CMYK 271 | -sPrintQuality=best -sMedium=transparency. 272 | Printed at twice the size intended. 273 | 274 | The option list terminates immediately after "transparency" in this case. 275 | Note that you don't need backslashes here if you break the command line 276 | into several text lines. 277 | 278 | If you did something interesting in the PostScript file (like setting page 279 | device parameters to unusual values), append the PostScript code in the 280 | comment part or in the "Remarks" field. 281 | 282 | ****************************************************** 283 | 284 | Name: [your full name] 285 | E-mail address: [optional] 286 | Date: [YYYY-MM-DD] 287 | Printer: [at least manufacturer and model] 288 | Ghostscript version: [GNU or AFPL, version number] 289 | pcl3 version: [version number] 290 | pcl3opts: [optional; information on printer capabilities obtained by running 291 | pcl3opts on other drivers' output files] 292 | Media configuration file: [optional] 293 | Remarks: [optional; use, e.g., for global comments or a summary] 294 | Success: [options used, repeat any number of times] 295 | Failure: [options used, repeat any number of times. Don't forget to give your 296 | reason for classifying this as a failure (after terminating the options with 297 | a period followed by a newline).] 298 | " 299 | Done 300 | -------------------------------------------------------------------------------- /tests/list_gz/006.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | mkdir-torture.tar 3 | --SKIPIF-- 4 | 8 | --FILE-- 9 | getNextEntry(true)) { 14 | var_dump($e); 15 | var_dump($e->isDir()); 16 | var_dump($e->isFile()); 17 | var_dump($e->isLink()); 18 | var_dump($e->getPathname()); 19 | var_dump($e->getResolvedPathname()); 20 | var_dump($e->getUser()); 21 | var_dump($e->getGroup()); 22 | var_dump($e->getMtime()); 23 | var_dump($e->getSize()); 24 | var_dump($e->getPerms()); 25 | var_dump($e->getData()); 26 | } 27 | 28 | echo "Done\n"; 29 | ?> 30 | --EXPECTF-- 31 | object(ArchiveEntry)#%d (1) { 32 | ["entry"]=> 33 | resource(%d) of type (archive entry descriptor) 34 | } 35 | bool(false) 36 | bool(true) 37 | bool(false) 38 | string(97) "usr/./local/lib/../share/./ImageMagick/.././doc/ghostscript/7.06/./../7.06/pcl3/how-to-report.txt" 39 | bool(false) 40 | string(4) "root" 41 | string(5) "wheel" 42 | int(1053769444) 43 | int(12890) 44 | int(33060) 45 | string(12890) "******************************************************************************* 46 | File: @(#)%s 47 | Contents: How to report bugs and hardware compatibility for pcl3 48 | Author: Martin Lottermoser, Greifswaldstrasse 28, 38124 Braunschweig, 49 | Germany. E-mail: Martin.Lottermoser@t-online.de. 50 | 51 | ******************************************************************************* 52 | * * 53 | * Copyright (C) 2000, 2001 by Martin Lottermoser * 54 | * All rights reserved * 55 | * * 56 | ******************************************************************************* 57 | 58 | 59 | Bugs and Failures 60 | ***************** 61 | This document distinguishes between "bugs" and "failures". A bug is incorrect 62 | behaviour on the part of pcl3, a failure is described by a set of 63 | hardware-relevant parameter values which are not accepted by a particular 64 | printer. Most often a failure is due to hardware limitations in the printer, 65 | not to a problem in pcl3, although it might be difficult to find out which is 66 | the case. For the user, this distinction is fortunately irrelevant. 67 | 68 | 69 | Bugs 70 | **** 71 | The basic rule is that it's a bug if there is disagreement between the 72 | behaviour and the documentation (the bug might be in the documentation, though). 73 | For example, if the documentation states that pcl3 produces a core dump under 74 | certain circumstances, this is by definition not a bug, which means that you 75 | should not report it (I'll have to fix it nevertheless, of course). 76 | 77 | If your printer has a specific subdevice in pcl3 (e.g., if you have a 78 | Hewlett-Packard DeskJet 540, this is the "hpdj540" subdevice) and the result 79 | when using this subdevice is not accepted by the printer or there is printer 80 | functionality you cannot access through this subdevice, this is a bug. 81 | 82 | If you find a bug in pcl3, please report it. The format of your message is 83 | irrelevant, but the content should be sufficiently detailed that I can 84 | reproduce the behaviour. You should always specify the versions of gs and pcl3 85 | you used. Please make sure that the behaviour is due to pcl3 and not to other 86 | causes. In particular, if nothing seems to work and you are on a UNIX system, 87 | do the following: 88 | 89 | - Generate the PCL file by calling gs yourself, and print through a 90 | "raw"/"transparent" queue which does not modify the file. 91 | - If spooled printing fails, log in as root and try to send the file 92 | directly to the device file. If it works, the problem is in the spooler. 93 | - If even that fails, send a line of text (still as superuser) directly 94 | to the device, followed by a form feed: 95 | 96 | printf 'Hello!\r\n\f' > /dev/... 97 | 98 | If this also does not work, you very likely have a kernel or hardware 99 | problem. 100 | 101 | I am writing this because there have been cases where people complained that my 102 | driver wasn't working at all and where the cause turned out to be, e.g., a 103 | misconfiguration of the spooler. Please don't bother me with problems of this 104 | kind; I have enough to do correcting my own mistakes. However, I only demand 105 | that you take reasonable steps to ensure that it isn't you who has created the 106 | problem. If you can't decide which component is at fault, by all means contact 107 | me -- just don't expect a quick answer and don't start by telling me that my 108 | driver doesn't work :-). 109 | 110 | 111 | 112 | Hardware compatibility reports 113 | ****************************** 114 | The pcl3 driver is intended to support a large number of printers. Because the 115 | PCL-3 documentation supplied by Hewlett-Packard is incomplete and occasionally 116 | wrong (sometimes obviously so because of inconsistencies), tests must be made 117 | on various printers in order to discover whether the driver can really be used 118 | for a particular printer model and which parameter values one should specify. 119 | As I do not have access to a complete range of PCL-3 printers, I must rely on 120 | others to do this for me. 121 | 122 | If you have a PCL-3 printer and are using pcl3, please check the file 123 | reports.txt whether there is already an entry for your printer or not. If there 124 | is none or if the hardware-relevant parameters listed are different from the 125 | ones you used, please compose a report in the format described below and send 126 | it to me. You need not cover all possible combinations; in fact, this might be 127 | too confusing for others anyway. Even a single success report, however, can 128 | help someone else with less knowledge or experience to get started. This is a 129 | service *you* can provide to the community of pcl3 users. 130 | 131 | 132 | 133 | Guidelines for testing 134 | ====================== 135 | - Read the documentation. Please. :-) 136 | 137 | - As test files, use publicly available PostScript files, preferably those 138 | included in the ghostscript or pcl3 distributions. The file levels-test.ps in 139 | the latter is a good starting point. 140 | 141 | - Keep in mind that some environment variables influence ghostscript's 142 | behaviour and make sure their values are as intended. 143 | 144 | - If you have access to a manufacturer-endorsed driver for your printer, use 145 | it to generate some test files with various settings, analyse them with 146 | pcl3opts, and try the suggested option combinations first. 147 | 148 | - The basic hardware parameters to test are colour model, resolution, and the 149 | number of intensity levels. 150 | 151 | - Colour model: The interesting models are Gray, CMY, and CMY+K/CMYK, 152 | depending on your printer. You need not bother with CMY for a CMY+K or 153 | CMYK printer unless you discover that the CMY cartridge supports a 154 | higher resolution than the black cartridge. 155 | 156 | - Resolution: Check your printer's documentation first. It should at least 157 | list the highest supported resolution, possibly separately for black and 158 | colour printing. If you don't have access to the documentation, a good 159 | set to test with is {300, 600x300, 600, 1200}. Smaller resolutions 160 | ({75, 100, 150}) are sometimes also supported but they are uninteresting 161 | for serious printing. 162 | 163 | Resolution tests are best made with a file where only the top left corner 164 | of the sheet is used. It should contain some structure of known extension. 165 | If a resolution is not accepted, the printer usually prints the picture 166 | anyway, but at a supported resolution, leading to magnified or reduced 167 | output. 168 | 169 | - Intensity levels: Test this only if your printer's documentation claims 170 | that some kind of Resolution Enhancement (e.g., C-REt) is supported or 171 | pcl3opts tells you that an official driver generates files with this 172 | property. Unless pcl3opts tells you differently, start with 300 ppi and 173 | 4 levels for all colorants used. 174 | 175 | Whether a particular value for a parameter is supported often depends on 176 | the values for other parameters. In some cases, even the print quality is 177 | important. If in doubt, test with "presentation". 178 | 179 | - If your printer has special hardware functionality, tests for that are 180 | also interesting (duplex printing, banner printing, different input or 181 | output trays). If you are using "unspec" or "unspecold", you should also 182 | always try compression method 9 unless the pcl3 documentation states that it 183 | is not supported by your printer. 184 | 185 | 186 | 187 | General rules for reports 188 | ========================= 189 | - You can use all characters in ISO 8859-1, plus HT and NL/LF. 190 | - Please keep to the following syntactic rules which simplify converting the 191 | information into other formats: 192 | - The report consists of a sequence of fields, each occupying an integral 193 | number of lines. 194 | - Each field begins with a field name, starting in column 1 and ending with 195 | the first following colon (':') in the same line. 196 | - The content of a field may be continued over several lines provided all 197 | continuation lines are either empty or indented with blanks (SP or HT). 198 | Trailing empty lines are ignored. 199 | - With the exception of "Success" and "Failure", every field may appear at 200 | most once in a report. If it appears a second time in a file, a new report 201 | is assumed to start at this point. 202 | - Make your report sufficiently detailed to be reproducible but don't tell us 203 | your life story. 204 | 205 | 206 | 207 | Special remarks for individual fields 208 | ===================================== 209 | 210 | - "Name": Supply your full name here. I don't accept anonymous or obviously 211 | nickname-signed reports. 212 | 213 | - "E-mail address" (optional): choose a stable one, your information might be 214 | used for several years. Omit this field if you do not wish your e-mail 215 | address to be disclosed to other users of pcl3. 216 | 217 | - "Date": I prefer the internationally standardized notation, YYYY-MM-DD. 218 | 219 | - "Printer": Be as precise as possible in identifying the printer. Ideally, 220 | I should like to have the following kind of information (as an example 221 | I'm giving some values for a DJ 850C): 222 | - printer name ("HP DeskJet 850C") 223 | - manufacturer's model identification ("C2145A") 224 | - firmware revision ("9.20 02/14/95") 225 | At least some of Hewlett-Packard's printers issue this information when you 226 | print a diagnostic or self test. If your printer's manual doesn't tell you 227 | how to generate such a test, try sending the command "ESC z" to the printer 228 | (on a UNIX system, you can use "printf '\x1bz'" to generate it). 229 | 230 | - pcl3opts (optional): Use this field to describe pcl3opts's output if you ran 231 | pcl3opts on files generated by manufacturer-endorsed drivers and you have 232 | obtained interesting information. You should always describe the driver you 233 | used. 234 | 235 | Interesting information is for example that the official driver generated 236 | files with certain settings for which pcl3opts did not give a warning but 237 | nevertheless you were not able to print such a file with pcl3. Expect me to 238 | ask you for a copy of such a file. 239 | 240 | - "Media configuration file" (optional): If you used a media configuration file 241 | and its content was relevant for the test or you wish to make the file 242 | available to other users, include it or a reference to it here. You must 243 | state where the information came from, so it can be verified in case of 244 | discrepancies. 245 | 246 | - "Remarks" (optional): Use this, if needed, for global information applying 247 | to a number of tests (perhaps a summary) or any other relevant information. 248 | 249 | - "Success:" and "Failure": These are intended for describing the result of 250 | using a single option combination and may be repeated any number of times 251 | (including zero). Each report should be independent of the others so they can 252 | be sorted differently if needed. 253 | 254 | Keep in mind that the key purpose of a report is to find out which hardware 255 | parameters work and which don't. It is therefore a success if the driver is 256 | at least able to correctly tell the printer how to paint shapes at the level 257 | of the printer's hardware capabilities (resolution, colorants and 258 | intensities). A good test file is levels-test.ps which has been designed for 259 | this purpose. I don't count it a failure when the result of printing a 260 | photograph or a similarly demanding document is not as aesthetically pleasing 261 | as it should be or when a problem is due to a bug in ghostscript. Use 262 | comments for such statements if desired. However, the decision whether an 263 | entry is a success or a failure remains yours to make, not mine. 264 | 265 | These fields should start with the list of options given to ghostscript via 266 | the command line, including the "-sDEVICE" option. You should omit options 267 | which are obviously irrelevant for the outcome of the test (like "-dNOPAUSE" 268 | or "-sOutputFile"), but otherwise the option list must be complete. If you 269 | wish to add a comment (and for a failure you must always do that), terminate 270 | this list with a period followed by a newline and add the comment after that. 271 | Here's an example: 272 | 273 | Failure: -sDEVICE=pcl3 -r1200 -sColourModel=CMYK 274 | -sPrintQuality=best -sMedium=transparency. 275 | Printed at twice the size intended. 276 | 277 | The option list terminates immediately after "transparency" in this case. 278 | Note that you don't need backslashes here if you break the command line 279 | into several text lines. 280 | 281 | If you did something interesting in the PostScript file (like setting page 282 | device parameters to unusual values), append the PostScript code in the 283 | comment part or in the "Remarks" field. 284 | 285 | ****************************************************** 286 | 287 | Name: [your full name] 288 | E-mail address: [optional] 289 | Date: [YYYY-MM-DD] 290 | Printer: [at least manufacturer and model] 291 | Ghostscript version: [GNU or AFPL, version number] 292 | pcl3 version: [version number] 293 | pcl3opts: [optional; information on printer capabilities obtained by running 294 | pcl3opts on other drivers' output files] 295 | Media configuration file: [optional] 296 | Remarks: [optional; use, e.g., for global comments or a summary] 297 | Success: [options used, repeat any number of times] 298 | Failure: [options used, repeat any number of times. Don't forget to give your 299 | reason for classifying this as a failure (after terminating the options with 300 | a period followed by a newline).] 301 | " 302 | Done 303 | -------------------------------------------------------------------------------- /tests/list_bz2/006.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | mkdir-torture.tar 3 | --SKIPIF-- 4 | 8 | --FILE-- 9 | getNextEntry(true)) { 14 | var_dump($e); 15 | var_dump($e->isDir()); 16 | var_dump($e->isFile()); 17 | var_dump($e->isLink()); 18 | var_dump($e->getPathname()); 19 | var_dump($e->getResolvedPathname()); 20 | var_dump($e->getUser()); 21 | var_dump($e->getGroup()); 22 | var_dump($e->getMtime()); 23 | var_dump($e->getSize()); 24 | var_dump($e->getPerms()); 25 | var_dump($e->getData()); 26 | } 27 | 28 | echo "Done\n"; 29 | ?> 30 | --EXPECTF-- 31 | object(ArchiveEntry)#%d (1) { 32 | ["entry"]=> 33 | resource(%d) of type (archive entry descriptor) 34 | } 35 | bool(false) 36 | bool(true) 37 | bool(false) 38 | string(97) "usr/./local/lib/../share/./ImageMagick/.././doc/ghostscript/7.06/./../7.06/pcl3/how-to-report.txt" 39 | bool(false) 40 | string(4) "root" 41 | string(5) "wheel" 42 | int(1053769444) 43 | int(12890) 44 | int(33060) 45 | string(12890) "******************************************************************************* 46 | File: @(#)%s 47 | Contents: How to report bugs and hardware compatibility for pcl3 48 | Author: Martin Lottermoser, Greifswaldstrasse 28, 38124 Braunschweig, 49 | Germany. E-mail: Martin.Lottermoser@t-online.de. 50 | 51 | ******************************************************************************* 52 | * * 53 | * Copyright (C) 2000, 2001 by Martin Lottermoser * 54 | * All rights reserved * 55 | * * 56 | ******************************************************************************* 57 | 58 | 59 | Bugs and Failures 60 | ***************** 61 | This document distinguishes between "bugs" and "failures". A bug is incorrect 62 | behaviour on the part of pcl3, a failure is described by a set of 63 | hardware-relevant parameter values which are not accepted by a particular 64 | printer. Most often a failure is due to hardware limitations in the printer, 65 | not to a problem in pcl3, although it might be difficult to find out which is 66 | the case. For the user, this distinction is fortunately irrelevant. 67 | 68 | 69 | Bugs 70 | **** 71 | The basic rule is that it's a bug if there is disagreement between the 72 | behaviour and the documentation (the bug might be in the documentation, though). 73 | For example, if the documentation states that pcl3 produces a core dump under 74 | certain circumstances, this is by definition not a bug, which means that you 75 | should not report it (I'll have to fix it nevertheless, of course). 76 | 77 | If your printer has a specific subdevice in pcl3 (e.g., if you have a 78 | Hewlett-Packard DeskJet 540, this is the "hpdj540" subdevice) and the result 79 | when using this subdevice is not accepted by the printer or there is printer 80 | functionality you cannot access through this subdevice, this is a bug. 81 | 82 | If you find a bug in pcl3, please report it. The format of your message is 83 | irrelevant, but the content should be sufficiently detailed that I can 84 | reproduce the behaviour. You should always specify the versions of gs and pcl3 85 | you used. Please make sure that the behaviour is due to pcl3 and not to other 86 | causes. In particular, if nothing seems to work and you are on a UNIX system, 87 | do the following: 88 | 89 | - Generate the PCL file by calling gs yourself, and print through a 90 | "raw"/"transparent" queue which does not modify the file. 91 | - If spooled printing fails, log in as root and try to send the file 92 | directly to the device file. If it works, the problem is in the spooler. 93 | - If even that fails, send a line of text (still as superuser) directly 94 | to the device, followed by a form feed: 95 | 96 | printf 'Hello!\r\n\f' > /dev/... 97 | 98 | If this also does not work, you very likely have a kernel or hardware 99 | problem. 100 | 101 | I am writing this because there have been cases where people complained that my 102 | driver wasn't working at all and where the cause turned out to be, e.g., a 103 | misconfiguration of the spooler. Please don't bother me with problems of this 104 | kind; I have enough to do correcting my own mistakes. However, I only demand 105 | that you take reasonable steps to ensure that it isn't you who has created the 106 | problem. If you can't decide which component is at fault, by all means contact 107 | me -- just don't expect a quick answer and don't start by telling me that my 108 | driver doesn't work :-). 109 | 110 | 111 | 112 | Hardware compatibility reports 113 | ****************************** 114 | The pcl3 driver is intended to support a large number of printers. Because the 115 | PCL-3 documentation supplied by Hewlett-Packard is incomplete and occasionally 116 | wrong (sometimes obviously so because of inconsistencies), tests must be made 117 | on various printers in order to discover whether the driver can really be used 118 | for a particular printer model and which parameter values one should specify. 119 | As I do not have access to a complete range of PCL-3 printers, I must rely on 120 | others to do this for me. 121 | 122 | If you have a PCL-3 printer and are using pcl3, please check the file 123 | reports.txt whether there is already an entry for your printer or not. If there 124 | is none or if the hardware-relevant parameters listed are different from the 125 | ones you used, please compose a report in the format described below and send 126 | it to me. You need not cover all possible combinations; in fact, this might be 127 | too confusing for others anyway. Even a single success report, however, can 128 | help someone else with less knowledge or experience to get started. This is a 129 | service *you* can provide to the community of pcl3 users. 130 | 131 | 132 | 133 | Guidelines for testing 134 | ====================== 135 | - Read the documentation. Please. :-) 136 | 137 | - As test files, use publicly available PostScript files, preferably those 138 | included in the ghostscript or pcl3 distributions. The file levels-test.ps in 139 | the latter is a good starting point. 140 | 141 | - Keep in mind that some environment variables influence ghostscript's 142 | behaviour and make sure their values are as intended. 143 | 144 | - If you have access to a manufacturer-endorsed driver for your printer, use 145 | it to generate some test files with various settings, analyse them with 146 | pcl3opts, and try the suggested option combinations first. 147 | 148 | - The basic hardware parameters to test are colour model, resolution, and the 149 | number of intensity levels. 150 | 151 | - Colour model: The interesting models are Gray, CMY, and CMY+K/CMYK, 152 | depending on your printer. You need not bother with CMY for a CMY+K or 153 | CMYK printer unless you discover that the CMY cartridge supports a 154 | higher resolution than the black cartridge. 155 | 156 | - Resolution: Check your printer's documentation first. It should at least 157 | list the highest supported resolution, possibly separately for black and 158 | colour printing. If you don't have access to the documentation, a good 159 | set to test with is {300, 600x300, 600, 1200}. Smaller resolutions 160 | ({75, 100, 150}) are sometimes also supported but they are uninteresting 161 | for serious printing. 162 | 163 | Resolution tests are best made with a file where only the top left corner 164 | of the sheet is used. It should contain some structure of known extension. 165 | If a resolution is not accepted, the printer usually prints the picture 166 | anyway, but at a supported resolution, leading to magnified or reduced 167 | output. 168 | 169 | - Intensity levels: Test this only if your printer's documentation claims 170 | that some kind of Resolution Enhancement (e.g., C-REt) is supported or 171 | pcl3opts tells you that an official driver generates files with this 172 | property. Unless pcl3opts tells you differently, start with 300 ppi and 173 | 4 levels for all colorants used. 174 | 175 | Whether a particular value for a parameter is supported often depends on 176 | the values for other parameters. In some cases, even the print quality is 177 | important. If in doubt, test with "presentation". 178 | 179 | - If your printer has special hardware functionality, tests for that are 180 | also interesting (duplex printing, banner printing, different input or 181 | output trays). If you are using "unspec" or "unspecold", you should also 182 | always try compression method 9 unless the pcl3 documentation states that it 183 | is not supported by your printer. 184 | 185 | 186 | 187 | General rules for reports 188 | ========================= 189 | - You can use all characters in ISO 8859-1, plus HT and NL/LF. 190 | - Please keep to the following syntactic rules which simplify converting the 191 | information into other formats: 192 | - The report consists of a sequence of fields, each occupying an integral 193 | number of lines. 194 | - Each field begins with a field name, starting in column 1 and ending with 195 | the first following colon (':') in the same line. 196 | - The content of a field may be continued over several lines provided all 197 | continuation lines are either empty or indented with blanks (SP or HT). 198 | Trailing empty lines are ignored. 199 | - With the exception of "Success" and "Failure", every field may appear at 200 | most once in a report. If it appears a second time in a file, a new report 201 | is assumed to start at this point. 202 | - Make your report sufficiently detailed to be reproducible but don't tell us 203 | your life story. 204 | 205 | 206 | 207 | Special remarks for individual fields 208 | ===================================== 209 | 210 | - "Name": Supply your full name here. I don't accept anonymous or obviously 211 | nickname-signed reports. 212 | 213 | - "E-mail address" (optional): choose a stable one, your information might be 214 | used for several years. Omit this field if you do not wish your e-mail 215 | address to be disclosed to other users of pcl3. 216 | 217 | - "Date": I prefer the internationally standardized notation, YYYY-MM-DD. 218 | 219 | - "Printer": Be as precise as possible in identifying the printer. Ideally, 220 | I should like to have the following kind of information (as an example 221 | I'm giving some values for a DJ 850C): 222 | - printer name ("HP DeskJet 850C") 223 | - manufacturer's model identification ("C2145A") 224 | - firmware revision ("9.20 02/14/95") 225 | At least some of Hewlett-Packard's printers issue this information when you 226 | print a diagnostic or self test. If your printer's manual doesn't tell you 227 | how to generate such a test, try sending the command "ESC z" to the printer 228 | (on a UNIX system, you can use "printf '\x1bz'" to generate it). 229 | 230 | - pcl3opts (optional): Use this field to describe pcl3opts's output if you ran 231 | pcl3opts on files generated by manufacturer-endorsed drivers and you have 232 | obtained interesting information. You should always describe the driver you 233 | used. 234 | 235 | Interesting information is for example that the official driver generated 236 | files with certain settings for which pcl3opts did not give a warning but 237 | nevertheless you were not able to print such a file with pcl3. Expect me to 238 | ask you for a copy of such a file. 239 | 240 | - "Media configuration file" (optional): If you used a media configuration file 241 | and its content was relevant for the test or you wish to make the file 242 | available to other users, include it or a reference to it here. You must 243 | state where the information came from, so it can be verified in case of 244 | discrepancies. 245 | 246 | - "Remarks" (optional): Use this, if needed, for global information applying 247 | to a number of tests (perhaps a summary) or any other relevant information. 248 | 249 | - "Success:" and "Failure": These are intended for describing the result of 250 | using a single option combination and may be repeated any number of times 251 | (including zero). Each report should be independent of the others so they can 252 | be sorted differently if needed. 253 | 254 | Keep in mind that the key purpose of a report is to find out which hardware 255 | parameters work and which don't. It is therefore a success if the driver is 256 | at least able to correctly tell the printer how to paint shapes at the level 257 | of the printer's hardware capabilities (resolution, colorants and 258 | intensities). A good test file is levels-test.ps which has been designed for 259 | this purpose. I don't count it a failure when the result of printing a 260 | photograph or a similarly demanding document is not as aesthetically pleasing 261 | as it should be or when a problem is due to a bug in ghostscript. Use 262 | comments for such statements if desired. However, the decision whether an 263 | entry is a success or a failure remains yours to make, not mine. 264 | 265 | These fields should start with the list of options given to ghostscript via 266 | the command line, including the "-sDEVICE" option. You should omit options 267 | which are obviously irrelevant for the outcome of the test (like "-dNOPAUSE" 268 | or "-sOutputFile"), but otherwise the option list must be complete. If you 269 | wish to add a comment (and for a failure you must always do that), terminate 270 | this list with a period followed by a newline and add the comment after that. 271 | Here's an example: 272 | 273 | Failure: -sDEVICE=pcl3 -r1200 -sColourModel=CMYK 274 | -sPrintQuality=best -sMedium=transparency. 275 | Printed at twice the size intended. 276 | 277 | The option list terminates immediately after "transparency" in this case. 278 | Note that you don't need backslashes here if you break the command line 279 | into several text lines. 280 | 281 | If you did something interesting in the PostScript file (like setting page 282 | device parameters to unusual values), append the PostScript code in the 283 | comment part or in the "Remarks" field. 284 | 285 | ****************************************************** 286 | 287 | Name: [your full name] 288 | E-mail address: [optional] 289 | Date: [YYYY-MM-DD] 290 | Printer: [at least manufacturer and model] 291 | Ghostscript version: [GNU or AFPL, version number] 292 | pcl3 version: [version number] 293 | pcl3opts: [optional; information on printer capabilities obtained by running 294 | pcl3opts on other drivers' output files] 295 | Media configuration file: [optional] 296 | Remarks: [optional; use, e.g., for global comments or a summary] 297 | Success: [options used, repeat any number of times] 298 | Failure: [options used, repeat any number of times. Don't forget to give your 299 | reason for classifying this as a failure (after terminating the options with 300 | a period followed by a newline).] 301 | " 302 | Done 303 | --------------------------------------------------------------------------------