Back to index

php5  5.3.10
corrupt_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 corrupt_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, $corrupt = 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'] & 0xA000 && $corrupt === 'symlink') {
00060             $type = 2;        // Symbolic Link
00061             $link = $fileOrStream;
00062             $stat['size'] = 0;
00063             $fileOrStream = '';
00064         } else if ($stat['mode'] & 0xA000) {
00065             $type = 1;        // Link
00066             $link = $fileOrStream;
00067             $stat['size'] = 0;
00068             $fileOrStream = '';
00069         } else if ($stat['mode'] & 0x4000) {
00070             $type = 5;        // Directory
00071         } else if ($stat['mode'] & 0x8000) {
00072             $type = 0;        // Regular
00073         } else {
00074             $type = 9;        // Unknown
00075         }
00076 
00077         $filePrefix = '';
00078         if (strlen($path) > 255) {
00079             throw new Exception(
00080                 "$path is too long, must be 255 characters or less"
00081             );
00082         } else if (strlen($path) > 100) {
00083             $filePrefix = substr($path, 0, strlen($path)-100);
00084             $path = substr($path, -100);
00085         }
00086 
00087         $block = pack('a100a8a8a8a12A12',
00088                 $path,
00089                 decoct($stat['mode']),
00090                 sprintf('%6s ',decoct($stat['uid'])),
00091                 sprintf('%6s ',decoct($stat['gid'])),
00092                 sprintf('%11s ',decoct($stat['size'])),
00093                 sprintf('%11s ',decoct($stat['mtime']))
00094             );
00095 
00096         $blockend = pack('a1a100a6a2a32a32a8a8a155a12',
00097             $type,
00098             $link,
00099             'ustar',
00100             '00',
00101             'Pyrus',
00102             'Pyrus',
00103             '',
00104             '',
00105             $filePrefix,
00106             '');
00107 
00108         $checkheader = array_merge(str_split($block), str_split($blockend));
00109         if (!function_exists('_pear2tarchecksum')) {
00110             function _pear2tarchecksum($a, $b) {return $a + ord($b);}
00111         }
00112         $checksum = 256; // 8 * ord(' ');
00113         $checksum += array_reduce($checkheader, '_pear2tarchecksum');
00114 
00115        if ($corrupt === 'checksum') $checksum++;
00116         $checksum = pack('a8', sprintf('%6s ', decoct($checksum)));
00117 
00118         fwrite($this->tmp, $block . $checksum . $blockend, 512);
00119         if (is_resource($fileOrStream)) {
00120             stream_copy_to_stream($fileOrStream, $this->tmp);
00121             if ($stat['size'] % 512) {
00122                 fwrite($this->tmp, str_repeat("\0", 512 - $stat['size'] % 512));
00123             }
00124         } else {
00125             fwrite($this->tmp, $fileOrStream);
00126             if (strlen($fileOrStream) && !isset($link) && strlen($fileOrStream) % 512) {
00127                 fwrite($this->tmp, str_repeat("\0", 512 - strlen($fileOrStream) % 512));
00128             }
00129         }
00130     }
00131 
00135     function init()
00136     {
00137         switch ($this->compress) {
00138             case 'zlib' :
00139                 $this->tmp = gzopen($this->path, 'wb');
00140                 break;
00141             case 'bz2' :
00142                 $this->tmp = bzopen($this->path, 'w');
00143                 break;
00144             case 'none' :
00145                 $this->tmp = fopen($this->path, 'wb');
00146                 break;
00147             default :
00148                 throw new Exception(
00149                     'unknown compression type ' . $this->compress);
00150         }
00151     }
00152 
00158     function mkdir($dir)
00159     {
00160         $this->addFile($dir, "", array(
00161                     'mode' => 0x4000 + 0644,
00162                     'uid' => 0,
00163                     'gid' => 0,
00164                     'size' => 0,
00165                     'mtime' => time(),
00166                 ));
00167     }
00168 
00172     function close()
00173     {
00174         fwrite($this->tmp, pack('a1024', ''));
00175         fclose($this->tmp);
00176     }
00177 }