Файл: core/cuctema/tar.php
Строк: 564
<?
define ('ARCHIVE_TAR_ATT_SEPARATOR', 90001);
define ('ARCHIVE_TAR_END_BLOCK', pack('a512', ''));
class Archive_Tar extends PEAR
{
var $_tarname='';
var $_compress=false;
var $_compress_type='none';
var $_separator=' ';
var $_file=0;
var $_temp_tarname='';
function Archive_Tar($p_tarname, $p_compress = null)
{
$this->PEAR();
$this->_compress = false;
$this->_compress_type = 'none';
if (($p_compress === null) || ($p_compress == '')) {
if (@file_exists($p_tarname)) {
if ($fp = @fopen($p_tarname, "rb")) {
$data = fread($fp, 2);
fclose($fp);
if ($data == "37213") {
$this->_compress = true;
$this->_compress_type = 'gz';
} elseif ($data == "BZ") {
$this->_compress = true;
$this->_compress_type = 'bz2';
}
}
} else {
if (substr($p_tarname, -2) == 'gz') {
$this->_compress = true;
$this->_compress_type = 'gz';
} elseif ((substr($p_tarname, -3) == 'bz2') ||
(substr($p_tarname, -2) == 'bz')) {
$this->_compress = true;
$this->_compress_type = 'bz2';
}
}
} else {
if (($p_compress === true) || ($p_compress == 'gz')) {
$this->_compress = true;
$this->_compress_type = 'gz';
} else if ($p_compress == 'bz2') {
$this->_compress = true;
$this->_compress_type = 'bz2';
} else {
die("Unsupported compression type '$p_compress'n".
"Supported types are 'gz' and 'bz2'.n");
return false;
}
}
$this->_tarname = $p_tarname;
if ($this->_compress) { // assert zlib or bz2 extension support
if ($this->_compress_type == 'gz')
$extname = 'zlib';
else if ($this->_compress_type == 'bz2')
$extname = 'bz2';
if (!extension_loaded($extname)) {
PEAR::loadExtension($extname);
}
if (!extension_loaded($extname)) {
die("The extension '$extname' couldn't be found.n".
"Please make sure your version of PHP was built ".
"with '$extname' support.n");
return false;
}
}
}
// }}}
// {{{ destructor
function _Archive_Tar()
{
$this->_close();
// ----- Look for a local copy to delete
if ($this->_temp_tarname != '')
@unlink($this->_temp_tarname);
$this->_PEAR();
}
function create($p_filelist)
{
return $this->createModify($p_filelist, '', '');
}
function add($p_filelist)
{
return $this->addModify($p_filelist, '', '');
}
// }}}
// {{{ extract()
function extract($p_path='')
{
return $this->extractModify($p_path, '');
}
// }}}
// {{{ listContent()
function listContent()
{
$v_list_detail = array();
if ($this->_openRead()) {
if (!$this->_extractList('', $v_list_detail, "list", '', '')) {
unset($v_list_detail);
$v_list_detail = 0;
}
$this->_close();
}
return $v_list_detail;
}
function createModify($p_filelist, $p_add_dir, $p_remove_dir='')
{
$v_result = true;
if (!$this->_openWrite())
return false;
if ($p_filelist != '') {
if (is_array($p_filelist))
$v_list = $p_filelist;
elseif (is_string($p_filelist))
$v_list = explode($this->_separator, $p_filelist);
else {
$this->_cleanFile();
$this->_error('Invalid file list');
return false;
}
$v_result = $this->_addList($v_list, $p_add_dir, $p_remove_dir);
}
if ($v_result) {
$this->_writeFooter();
$this->_close();
} else
$this->_cleanFile();
return $v_result;
}
function addModify($p_filelist, $p_add_dir, $p_remove_dir='')
{
$v_result = true;
if (!$this->_isArchive())
$v_result = $this->createModify($p_filelist, $p_add_dir,
$p_remove_dir);
else {
if (is_array($p_filelist))
$v_list = $p_filelist;
elseif (is_string($p_filelist))
$v_list = explode($this->_separator, $p_filelist);
else {
$this->_error('Invalid file list');
return false;
}
$v_result = $this->_append($v_list, $p_add_dir, $p_remove_dir);
}
return $v_result;
}
function addString($p_filename, $p_string)
{
$v_result = true;
if (!$this->_isArchive()) {
if (!$this->_openWrite()) {
return false;
}
$this->_close();
}
if (!$this->_openAppend())
return false;
$v_result = $this->_addString($p_filename, $p_string);
$this->_writeFooter();
$this->_close();
return $v_result;
}
function extractModify($p_path, $p_remove_path)
{
$v_result = true;
$v_list_detail = array();
if ($v_result = $this->_openRead()) {
$v_result = $this->_extractList($p_path, $v_list_detail,
"complete", 0, $p_remove_path);
$this->_close();
}
return $v_result;
}
function extractInString($p_filename)
{
if ($this->_openRead()) {
$v_result = $this->_extractInString($p_filename);
$this->_close();
} else {
$v_result = NULL;
}
return $v_result;
}
function extractList($p_filelist, $p_path='', $p_remove_path='')
{
$v_result = true;
$v_list_detail = array();
if (is_array($p_filelist))
$v_list = $p_filelist;
elseif (is_string($p_filelist))
$v_list = explode($this->_separator, $p_filelist);
else {
$this->_error('Invalid string list');
return false;
}
if ($v_result = $this->_openRead()) {
$v_result = $this->_extractList($p_path, $v_list_detail, "partial",
$v_list, $p_remove_path);
$this->_close();
}
return $v_result;
}
function setAttribute()
{
$v_result = true;
if (($v_size = func_num_args()) == 0) {
return true;
}
$v_att_list = &func_get_args();
$i=0;
while ($i<$v_size) {
switch ($v_att_list[$i]) {
case ARCHIVE_TAR_ATT_SEPARATOR :
if (($i+1) >= $v_size) {
$this->_error('Invalid number of parameters for '
.'attribute ARCHIVE_TAR_ATT_SEPARATOR');
return false;
}
// ----- Get the value
$this->_separator = $v_att_list[$i+1];
$i++;
break;
default :
$this->_error('Unknow attribute code '.$v_att_list[$i].'');
return false;
}
// ----- Next attribute
$i++;
}
return $v_result;
}
// }}}
// {{{ _error()
function _error($p_message)
{
// ----- To be completed
$this->raiseError($p_message);
}
// }}}
// {{{ _warning()
function _warning($p_message)
{
// ----- To be completed
$this->raiseError($p_message);
}
// }}}
// {{{ _isArchive()
function _isArchive($p_filename=NULL)
{
if ($p_filename == NULL) {
$p_filename = $this->_tarname;
}
clearstatcache();
return @is_file($p_filename);
}
// }}}
// {{{ _openWrite()
function _openWrite()
{
if ($this->_compress_type == 'gz')
$this->_file = @gzopen($this->_tarname, "wb9");
else if ($this->_compress_type == 'bz2')
$this->_file = @bzopen($this->_tarname, "wb");
else if ($this->_compress_type == 'none')
$this->_file = @fopen($this->_tarname, "wb");
else
$this->_error('Unknown or missing compression type ('
.$this->_compress_type.')');
if ($this->_file == 0) {
$this->_error('Unable to open in write mode ''
.$this->_tarname.''');
return false;
}
return true;
}
// }}}
// {{{ _openRead()
function _openRead()
{
if (strtolower(substr($this->_tarname, 0, 7)) == 'http://') {
// ----- Look if a local copy need to be done
if ($this->_temp_tarname == '') {
$this->_temp_tarname = uniqid('tar').'.tmp';
if (!$v_file_from = @fopen($this->_tarname, 'rb')) {
$this->_error('Unable to open in read mode ''
.$this->_tarname.''');
$this->_temp_tarname = '';
return false;
}
if (!$v_file_to = @fopen($this->_temp_tarname, 'wb')) {
$this->_error('Unable to open in write mode ''
.$this->_temp_tarname.''');
$this->_temp_tarname = '';
return false;
}
while ($v_data = @fread($v_file_from, 1024))
@fwrite($v_file_to, $v_data);
@fclose($v_file_from);
@fclose($v_file_to);
}
// ----- File to open if the local copy
$v_filename = $this->_temp_tarname;
} else
// ----- File to open if the normal Tar file
$v_filename = $this->_tarname;
if ($this->_compress_type == 'gz')
$this->_file = @gzopen($v_filename, "rb");
else if ($this->_compress_type == 'bz2')
$this->_file = @bzopen($v_filename, "rb");
else if ($this->_compress_type == 'none')
$this->_file = @fopen($v_filename, "rb");
else
$this->_error('Unknown or missing compression type ('
.$this->_compress_type.')');
if ($this->_file == 0) {
$this->_error('Unable to open in read mode ''.$v_filename.''');
return false;
}
return true;
}
// }}}
// {{{ _openReadWrite()
function _openReadWrite()
{
if ($this->_compress_type == 'gz')
$this->_file = @gzopen($this->_tarname, "r+b");
else if ($this->_compress_type == 'bz2')
$this->_file = @bzopen($this->_tarname, "r+b");
else if ($this->_compress_type == 'none')
$this->_file = @fopen($this->_tarname, "r+b");
else
$this->_error('Unknown or missing compression type ('
.$this->_compress_type.')');
if ($this->_file == 0) {
$this->_error('Unable to open in read/write mode ''
.$this->_tarname.''');
return false;
}
return true;
}
// }}}
// {{{ _close()
function _close()
{
//if (isset($this->_file)) {
if (is_resource($this->_file)) {
if ($this->_compress_type == 'gz')
@gzclose($this->_file);
else if ($this->_compress_type == 'bz2')
@bzclose($this->_file);
else if ($this->_compress_type == 'none')
@fclose($this->_file);
else
$this->_error('Unknown or missing compression type ('
.$this->_compress_type.')');
$this->_file = 0;
}
// ----- Look if a local copy need to be erase
// Note that it might be interesting to keep the url for a time : ToDo
if ($this->_temp_tarname != '') {
@unlink($this->_temp_tarname);
$this->_temp_tarname = '';
}
return true;
}
// }}}
// {{{ _cleanFile()
function _cleanFile()
{
$this->_close();
// ----- Look for a local copy
if ($this->_temp_tarname != '') {
// ----- Remove the local copy but not the remote tarname
@unlink($this->_temp_tarname);
$this->_temp_tarname = '';
} else {
// ----- Remove the local tarname file
@unlink($this->_tarname);
}
$this->_tarname = '';
return true;
}
// }}}
// {{{ _writeBlock()
function _writeBlock($p_binary_data, $p_len=null)
{
if (is_resource($this->_file)) {
if ($p_len === null) {
if ($this->_compress_type == 'gz')
@gzputs($this->_file, $p_binary_data);
else if ($this->_compress_type == 'bz2')
@bzwrite($this->_file, $p_binary_data);
else if ($this->_compress_type == 'none')
@fputs($this->_file, $p_binary_data);
else
$this->_error('Unknown or missing compression type ('
.$this->_compress_type.')');
} else {
if ($this->_compress_type == 'gz')
@gzputs($this->_file, $p_binary_data, $p_len);
else if ($this->_compress_type == 'bz2')
@bzwrite($this->_file, $p_binary_data, $p_len);
else if ($this->_compress_type == 'none')
@fputs($this->_file, $p_binary_data, $p_len);
else
$this->_error('Unknown or missing compression type ('
.$this->_compress_type.')');
}
}
return true;
}
// }}}
// {{{ _readBlock()
function _readBlock()
{
$v_block = null;
if (is_resource($this->_file)) {
if ($this->_compress_type == 'gz')
$v_block = @gzread($this->_file, 512);
else if ($this->_compress_type == 'bz2')
$v_block = @bzread($this->_file, 512);
else if ($this->_compress_type == 'none')
$v_block = @fread($this->_file, 512);
else
$this->_error('Unknown or missing compression type ('
.$this->_compress_type.')');
}
return $v_block;
}
// }}}
// {{{ _jumpBlock()
function _jumpBlock($p_len=null)
{
if (is_resource($this->_file)) {
if ($p_len === null)
$p_len = 1;
if ($this->_compress_type == 'gz') {
@gzseek($this->_file, gztell($this->_file)+($p_len*512));
}
else if ($this->_compress_type == 'bz2') {
// ----- Replace missing bztell() and bzseek()
for ($i=0; $i<$p_len; $i++)
$this->_readBlock();
} else if ($this->_compress_type == 'none')
@fseek($this->_file, ftell($this->_file)+($p_len*512));
else
$this->_error('Unknown or missing compression type ('
.$this->_compress_type.')');
}
return true;
}
// }}}
// {{{ _writeFooter()
function _writeFooter()
{
if (is_resource($this->_file)) {
// ----- Write the last 0 filled block for end of archive
$v_binary_data = pack('a1024', '');
$this->_writeBlock($v_binary_data);
}
return true;
}
// }}}
// {{{ _addList()
function _addList($p_list, $p_add_dir, $p_remove_dir)
{
$v_result=true;
$v_header = array();
// ----- Remove potential windows directory separator
$p_add_dir = $this->_translateWinPath($p_add_dir);
$p_remove_dir = $this->_translateWinPath($p_remove_dir, false);
if (!$this->_file) {
$this->_error('Invalid file descriptor');
return false;
}
if (sizeof($p_list) == 0)
return true;
foreach ($p_list as $v_filename) {
if (!$v_result) {
break;
}
// ----- Skip the current tar name
if ($v_filename == $this->_tarname)
continue;
if ($v_filename == '')
continue;
if (!file_exists($v_filename)) {
$this->_warning("File '$v_filename' does not exist");
continue;
}
// ----- Add the file or directory header
if (!$this->_addFile($v_filename, $v_header, $p_add_dir, $p_remove_dir))
return false;
if (@is_dir($v_filename)) {
if (!($p_hdir = opendir($v_filename))) {
$this->_warning("Directory '$v_filename' can not be read");
continue;
}
while (false !== ($p_hitem = readdir($p_hdir))) {
if (($p_hitem != '.') && ($p_hitem != '..')) {
if ($v_filename != ".")
$p_temp_list[0] = $v_filename.'/'.$p_hitem;
else
$p_temp_list[0] = $p_hitem;
$v_result = $this->_addList($p_temp_list,
$p_add_dir,
$p_remove_dir);
}
}
unset($p_temp_list);
unset($p_hdir);
unset($p_hitem);
}
}
return $v_result;
}
// }}}
// {{{ _addFile()
function _addFile($p_filename, &$p_header, $p_add_dir, $p_remove_dir)
{
if (!$this->_file) {
$this->_error('Invalid file descriptor');
return false;
}
if ($p_filename == '') {
$this->_error('Invalid file name');
return false;
}
// ----- Calculate the stored filename
$p_filename = $this->_translateWinPath($p_filename, false);;
$v_stored_filename = $p_filename;
if (strcmp($p_filename, $p_remove_dir) == 0) {
return true;
}
if ($p_remove_dir != '') {
if (substr($p_remove_dir, -1) != '/')
$p_remove_dir .= '/';
if (substr($p_filename, 0, strlen($p_remove_dir)) == $p_remove_dir)
$v_stored_filename = substr($p_filename, strlen($p_remove_dir));
}
$v_stored_filename = $this->_translateWinPath($v_stored_filename);
if ($p_add_dir != '') {
if (substr($p_add_dir, -1) == '/')
$v_stored_filename = $p_add_dir.$v_stored_filename;
else
$v_stored_filename = $p_add_dir.'/'.$v_stored_filename;
}
$v_stored_filename = $this->_pathReduction($v_stored_filename);
if ($this->_isArchive($p_filename)) {
if (($v_file = @fopen($p_filename, "rb")) == 0) {
$this->_warning("Unable to open file '".$p_filename
."' in binary read mode");
return true;
}
if (!$this->_writeHeader($p_filename, $v_stored_filename))
return false;
while (($v_buffer = fread($v_file, 512)) != '') {
$v_binary_data = pack("a512", "$v_buffer");
$this->_writeBlock($v_binary_data);
}
fclose($v_file);
} else {
// ----- Only header for dir
if (!$this->_writeHeader($p_filename, $v_stored_filename))
return false;
}
return true;
}
// }}}
// {{{ _addString()
function _addString($p_filename, $p_string)
{
if (!$this->_file) {
$this->_error('Invalid file descriptor');
return false;
}
if ($p_filename == '') {
$this->_error('Invalid file name');
return false;
}
// ----- Calculate the stored filename
$p_filename = $this->_translateWinPath($p_filename, false);;
if (!$this->_writeHeaderBlock($p_filename, strlen($p_string),
time(), 384, "", 0, 0))
return false;
$i=0;
while (($v_buffer = substr($p_string, (($i++)*512), 512)) != '') {
$v_binary_data = pack("a512", $v_buffer);
$this->_writeBlock($v_binary_data);
}
return true;
}
// }}}
// {{{ _writeHeader()
function _writeHeader($p_filename, $p_stored_filename)
{
if ($p_stored_filename == '')
$p_stored_filename = $p_filename;
$v_reduce_filename = $this->_pathReduction($p_stored_filename);
if (strlen($v_reduce_filename) > 99) {
if (!$this->_writeLongHeader($v_reduce_filename))
return false;
}
$v_info = stat($p_filename);
$v_uid = sprintf("%6s ", DecOct($v_info[4]));
$v_gid = sprintf("%6s ", DecOct($v_info[5]));
$v_perms = sprintf("%6s ", DecOct(fileperms($p_filename)));
$v_mtime = sprintf("%11s", DecOct(filemtime($p_filename)));
if (@is_dir($p_filename)) {
$v_typeflag = "5";
$v_size = sprintf("%11s ", DecOct(0));
} else {
$v_typeflag = '';
clearstatcache();
$v_size = sprintf("%11s ", DecOct(filesize($p_filename)));
}
$v_linkname = '';
$v_magic = '';
$v_version = '';
$v_uname = '';
$v_gname = '';
$v_devmajor = '';
$v_devminor = '';
$v_prefix = '';
$v_binary_data_first = pack("a100a8a8a8a12A12",
$v_reduce_filename, $v_perms, $v_uid,
$v_gid, $v_size, $v_mtime);
$v_binary_data_last = pack("a1a100a6a2a32a32a8a8a155a12",
$v_typeflag, $v_linkname, $v_magic,
$v_version, $v_uname, $v_gname,
$v_devmajor, $v_devminor, $v_prefix, '');
// ----- Calculate the checksum
$v_checksum = 0;
// ..... First part of the header
for ($i=0; $i<148; $i++)
$v_checksum += ord(substr($v_binary_data_first,$i,1));
// ..... Ignore the checksum value and replace it by ' ' (space)
for ($i=148; $i<156; $i++)
$v_checksum += ord(' ');
// ..... Last part of the header
for ($i=156, $j=0; $i<512; $i++, $j++)
$v_checksum += ord(substr($v_binary_data_last,$j,1));
// ----- Write the first 148 bytes of the header in the archive
$this->_writeBlock($v_binary_data_first, 148);
// ----- Write the calculated checksum
$v_checksum = sprintf("%6s ", DecOct($v_checksum));
$v_binary_data = pack("a8", $v_checksum);
$this->_writeBlock($v_binary_data, 8);
// ----- Write the last 356 bytes of the header in the archive
$this->_writeBlock($v_binary_data_last, 356);
return true;
}
// }}}
// {{{ _writeHeaderBlock()
function _writeHeaderBlock($p_filename, $p_size, $p_mtime=0, $p_perms=0,
$p_type='', $p_uid=0, $p_gid=0)
{
$p_filename = $this->_pathReduction($p_filename);
if (strlen($p_filename) > 99) {
if (!$this->_writeLongHeader($p_filename))
return false;
}
if ($p_type == "5") {
$v_size = sprintf("%11s ", DecOct(0));
} else {
$v_size = sprintf("%11s ", DecOct($p_size));
}
$v_uid = sprintf("%6s ", DecOct($p_uid));
$v_gid = sprintf("%6s ", DecOct($p_gid));
$v_perms = sprintf("%6s ", DecOct($p_perms));
$v_mtime = sprintf("%11s", DecOct($p_mtime));
$v_linkname = '';
$v_magic = '';
$v_version = '';
$v_uname = '';
$v_gname = '';
$v_devmajor = '';
$v_devminor = '';
$v_prefix = '';
$v