Blame | Letzte Änderung | Log anzeigen | RSS feed
<?php/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: *//*** Write the files as a TAR archive** PHP versions 4 and 5** This library is free software; you can redistribute it and/or* modify it under the terms of the GNU Lesser General Public* License as published by the Free Software Foundation; either* version 2.1 of the License, or (at your option) any later version.** This library is distributed in the hope that it will be useful,* but WITHOUT ANY WARRANTY; without even the implied warranty of* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU* Lesser General Public License for more details.** You should have received a copy of the GNU Lesser General Public* License along with this library; if not, write to the Free Software* Foundation, Inc., 59 Temple Place, Suite 330,Boston,MA 02111-1307 USA** @category File Formats* @package File_Archive* @author Vincent Lascaux <vincentlascaux@php.net>* @copyright 1997-2005 The PHP Group* @license http://www.gnu.org/copyleft/lesser.html LGPL* @version CVS: $Id: Tar.php,v 1.20 2008/06/05 21:30:47 cbrunet Exp $* @link http://pear.php.net/package/File_Archive*/require_once "File/Archive/Writer/Archive.php";/*** Write the files as a TAR archive*/class File_Archive_Writer_Tar extends File_Archive_Writer_Archive{var $buffer;var $useBuffer;var $filename = null;var $stats = null;/*** Creates the TAR header for a file** @param string $filename name of the file* @param array $stat statistics of the file* @return string A 512 byte header for the file* @access private*/function tarHeader($filename, $stat){$mode = isset($stat[2]) ? $stat[2] : 0x8000;$uid = isset($stat[4]) ? $stat[4] : 0;$gid = isset($stat[5]) ? $stat[5] : 0;$size = $stat[7];$time = isset($stat[9]) ? $stat[9] : time();$link = "";if ($mode & 0x4000) {$type = 5; // Directory} else if ($mode & 0x8000) {$type = 0; // Regular} else if ($mode & 0xA000) {$type = 1; // Link$link = @readlink($current);} else {$type = 9; // Unknown}$filePrefix = '';if (strlen($filename) > 255) {return PEAR::raiseError("$filename is too long to be put in a tar archive");} else if (strlen($filename) > 100) {// need a path component of max 155 bytes$pos = strrpos(substr($filename, 0, 155), '/');if(strlen($filename) - $pos > 100) {// filename-component may not exceed 100 bytesreturn PEAR::raiseError("$filename is too long to be put in a tar archive");}$filePrefix = substr($filename, 0, $pos);$filename = substr($filename, $pos+1);}$blockbeg = pack("a100a8a8a8a12a12",$filename,decoct($mode),sprintf("%6s ",decoct($uid)),sprintf("%6s ",decoct($gid)),sprintf("%11s ",decoct($size)),sprintf("%11s ",decoct($time)));$blockend = pack("a1a100a6a2a32a32a8a8a155a12",$type,$link,"ustar","00","Unknown","Unknown","","",$filePrefix,"");$checksum = 8*ord(" ");for ($i = 0; $i < 148; $i++) {$checksum += ord($blockbeg{$i});}for ($i = 0; $i < 356; $i++) {$checksum += ord($blockend{$i});}$checksum = pack("a8",sprintf("%6s ",decoct($checksum)));return $blockbeg . $checksum . $blockend;}/*** Creates the TAR footer for a file** @param int $size the size of the data that has been written to the TAR* @return string A string made of less than 512 characteres to fill the* last 512 byte long block* @access private*/function tarFooter($size){if ($size % 512 > 0) {return pack("a".(512 - $size%512), "");} else {return "";}}function flush(){if ($this->filename !== null) {if ($this->useBuffer) {$this->stats[7] = strlen($this->buffer);$header = $this->tarHeader($this->filename, $this->stats);if (PEAR::isError($header)) {return $header;}$this->innerWriter->writeData($header);$this->innerWriter->writeData($this->buffer);}$this->innerWriter->writeData($this->tarFooter($this->stats[7]));}$this->buffer = "";}function _newFile($filename, $stats = array(),$mime = "application/octet-stream"){$err = $this->flush();if (PEAR::isError($err)) {return $err;}$this->useBuffer = !isset($stats[7]);$this->filename = $filename;$this->stats = $stats;if (!$this->useBuffer) {$header = $this->tarHeader($filename, $stats);if (PEAR::isError($header)) {return $header;}return $this->innerWriter->writeData($header);}}/*** @see File_Archive_Writer::close()*/function close(){$err = $this->flush();if (PEAR::isError($err)) {return $err;}$this->innerWriter->writeData(pack("a1024", ""));parent::close();}/*** @see File_Archive_Writer::writeData()*/function writeData($data){if ($this->useBuffer) {$this->buffer .= $data;} else {$this->innerWriter->writeData($data);}}/*** @see File_Archive_Writer::writeFile()*/function writeFile($filename){if ($this->useBuffer) {if (!file_exists($filename)) {return PEAR::raiseError("File not found: $filename.");}$this->buffer .= file_get_contents($filename);} else {$this->innerWriter->writeFile($filename);}}/*** @see File_Archive_Writer::getMime()*/function getMime() { return "application/x-tar"; }}/*** A tar archive cannot contain files with name of folders longer than 255 chars* This filter removes them** @see File_Archive_Predicate, File_Archive_Reader_Filter*/require_once "File/Archive/Predicate.php";class File_Archive_Predicate_TARCompatible extends File_Archive_Predicate{function isTrue($source){return strlen($source->getFilename()) <= 255;}}?>