Back to index

php5  5.3.10
tarmaker.php.inc
Go to the documentation of this file.
00001 <?php
00002 // stolen from PEAR2_Pyrus_Developer_Creator_Tar by Greg Beaver, the original author, for use in unit tests
00003 class tarmaker
00004 {
00010     protected $archive;
00016     protected $tmp;
00017     protected $path;
00018     protected $compress;
00019     function __construct($path, $compress = 'zlib')
00020     {
00021         $this->compress = $compress;
00022         if ($compress === 'bz2' && !function_exists('bzopen')) {
00023             throw new PEAR2_Pyrus_Developer_Creator_Exception(
00024                 'bzip2 extension not available');
00025         }
00026         if ($compress === 'zlib' && !function_exists('gzopen')) {
00027             throw new PEAR2_Pyrus_Developer_Creator_Exception(
00028                 'zlib extension not available');
00029         }
00030         $this->path = $path;
00031     }
00032 
00041     function addFile($path, $fileOrStream, $stat = null)
00042     {
00043         clearstatcache();
00044         if ($stat === null) {
00045             if (is_resource($fileOrStream)) {
00046                 $stat = fstat($fileOrStream);
00047             } else {
00048                 $stat = array(
00049                     'mode' => 0x8000 + 0644,
00050                     'uid' => 0,
00051                     'gid' => 0,
00052                     'size' => strlen($fileOrStream),
00053                     'mtime' => time(),
00054                 );
00055             }
00056         }
00057 
00058         $link = null;
00059         if ($stat['mode'] & 0x4000) {
00060             $type = 5;        // Directory
00061         } else if ($stat['mode'] & 0x8000) {
00062             $type = 0;        // Regular
00063         } else if ($stat['mode'] & 0xA000) {
00064             $type = 1;        // Link
00065             $link = @readlink($current);
00066         } else {
00067             $type = 9;        // Unknown
00068         }
00069 
00070         $filePrefix = '';
00071         if (strlen($path) > 255) {
00072             throw new Exception(
00073                 "$path is too long, must be 255 characters or less"
00074             );
00075         } else if (strlen($path) > 100) {
00076             $filePrefix = substr($path, 0, strlen($path)-100);
00077             $path = substr($path, -100);
00078         }
00079 
00080         $block = pack('a100a8a8a8a12A12',
00081                 $path,
00082                 decoct($stat['mode']),
00083                 sprintf('%6s ',decoct($stat['uid'])),
00084                 sprintf('%6s ',decoct($stat['gid'])),
00085                 sprintf('%11s ',decoct($stat['size'])),
00086                 sprintf('%11s ',decoct($stat['mtime']))
00087             );
00088 
00089         $blockend = pack('a1a100a6a2a32a32a8a8a155a12',
00090             $type,
00091             $link,
00092             'ustar',
00093             '00',
00094             'Pyrus',
00095             'Pyrus',
00096             '',
00097             '',
00098             $filePrefix,
00099             '');
00100 
00101         $checkheader = array_merge(str_split($block), str_split($blockend));
00102         if (!function_exists('_pear2tarchecksum')) {
00103             function _pear2tarchecksum($a, $b) {return $a + ord($b);}
00104         }
00105         $checksum = 256; // 8 * ord(' ');
00106         $checksum += array_reduce($checkheader, '_pear2tarchecksum');
00107 
00108         $checksum = pack('a8', sprintf('%6s ', decoct($checksum)));
00109 
00110         fwrite($this->tmp, (binary)$block . $checksum . $blockend, 512);
00111         if (is_resource($fileOrStream)) {
00112             stream_copy_to_stream($fileOrStream, $this->tmp);
00113             if ($stat['size'] % 512) {
00114                 fwrite($this->tmp, (binary)str_repeat("\0", 512 - $stat['size'] % 512));
00115             }
00116         } else {
00117             fwrite($this->tmp, (binary)$fileOrStream);
00118             if (strlen($fileOrStream) % 512) {
00119                 fwrite($this->tmp, (binary)str_repeat("\0", 512 - strlen($fileOrStream) % 512));
00120             }
00121         }
00122     }
00123 
00127     function init()
00128     {
00129         switch ($this->compress) {
00130             case 'zlib' :
00131                 $this->tmp = gzopen($this->path, 'wb');
00132                 break;
00133             case 'bz2' :
00134                 $this->tmp = bzopen($this->path, 'w');
00135                 break;
00136             case 'none' :
00137                 $this->tmp = fopen($this->path, 'wb');
00138                 break;
00139             default :
00140                 throw new Exception(
00141                     'unknown compression type ' . $this->compress);
00142         }
00143     }
00144 
00150     function mkdir($dir)
00151     {
00152         $this->addFile($dir, "", array(
00153                     'mode' => 0x4000 + 0644,
00154                     'uid' => 0,
00155                     'gid' => 0,
00156                     'size' => 0,
00157                     'mtime' => time(),
00158                 ));
00159     }
00160 
00164     function close()
00165     {
00166         fwrite($this->tmp, pack('a1024', ''));
00167         fclose($this->tmp);
00168     }
00169 }