Login   Register  
PHP Classes
elePHPant
Icontem

File: EasyTar.class

Recommend this page to a friend!
Stumble It! Stumble It! Bookmark in del.icio.us Bookmark in del.icio.us
  Classes of alban.lopez  >  Easy Archives  >  EasyTar.class  >  Download  
File: EasyTar.class
Role: Class source
Content type: text/plain
Description: manage TAR archives
Class: Easy Archives
Manage tar, gzip, bzip2 and zip archives
Author: By
Last change: Bug correction
Date: 2008-04-27 03:45
Size: 7,581 bytes
 

Contents

Class file image Download
<?
/**-------------------------------------------------
 | EasyTar.class V0.8 -  by Alban LOPEZ
 | Copyright (c) 2007 Alban LOPEZ
 | Email bugs/suggestions to alban.lopez+easytar@gmail.com
 +--------------------------------------------------
 | This file is part of EasyArchive.class V0.9.
 | EasyArchive is free software: you can redistribute it and/or modify
 | it under the terms of the GNU General Public License as published by
 | the Free Software Foundation, either version 3 of the License, or
 | (at your option) any later version.
 | EasyArchive 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 General Public License for more details on http://www.gnu.org/licenses/
 +--------------------------------------------------
 http://www.phpclasses.org/browse/package/4239.html **/
class tar
/* http://www.mkssoftware.com/docs/man4/tar.4.asp */
/**
// You can use this class like that.
$test = new tar;
$test->makeTar('./','./toto.Tar');
var_export($test->infosTar('./toto.Tar'));
$test->extractTar('./toto.Tar', './new/');
**/
    
function infosTar ($src$data=true)
    {
        if (
$this->is_tar($src))
        {
            
file_put_contents ($tmp='~tmp('.microtime().').tar'$src);
            
$src $tmp;
        }
        
$ptr fopen($src'r');
        while (!
feof($ptr))
        {
            
$infos $this->readTarHeader ($ptr);
            if (
$infos['name'])
            {
                if (!
$data) unset($infos['data']);
                
$result[$infos['name']]=$infos;
            }
        }
        if (
is_file($tmp)) unlink($tmp);
        return 
$result;
    }
    function 
makeTar($src$dest=false)
    {
        
$src is_array($src) ? $src : array($src);
        
$src array_map('realpath'$src);
        foreach (
$src as $item)
            
$Tar .= $this->addTarItem($item.((is_dir($item) && substr($item, -1)!='/')?'/':''), dirname($item).'/');
        
        
$Tar str_pad($Tarfloor((strlen($Tar) + 10240 1) / 10240) * 10240"\0");
        if (empty(
$dest)) return $Tar;
        elseif (
file_put_contents($dest$Tar)) return $dest;
        else 
false;
    }
    function 
extractTar ($src$dest)
    {
        if (
$this->is_tar($src))
        {
            
file_put_contents ($tmp='~tmp('.microtime().').tar'$src);
            
$src $tmp;
        }
        
$ptr fopen($src'r');
        while (!
feof($ptr))
        {
            
$infos $this->readTarHeader ($ptr);
            if (
$infos['type']=='5' && @mkdir($dest.$infos['name'], 0775true))
                
$result[]=$dest.$infos['name'];
            elseif ((
$infos['type']=='0' || $infos['type']==chr(0)) && file_put_contents($dest.$infos['name'], $infos['data']))
                
$result[]=$dest.$infos['name'];
            if (
$infos)
                
chmod($dest.$infos['name'], 0775);
//                 chmod(, $infos['mode']);
//                 chgrp(, $infos['uname']);
//                 chown(, $infos['gname']);
        
}
        if (
is_file($tmp)) unlink($tmp);
        return 
$result;
    }
    function 
is_tar($str)
    {
        
$block substr($str,0512);
        if (
strlen($block)!=512) return false;
        
$realchecksum octdec(substr($str,148,8));
        
$checksum 0;
        
$block substr_replace($block'        '1488);
        for (
$i 0$i 512$i++)
            
$checksum += ord(substr($block$i1));
        if (
$realchecksum==$checksum) return true;
        return 
false;
    }
    function 
tarHeader512($infos)
    { 
/* http://www.mkssoftware.com/docs/man4/tar.4.asp */
        
$bigheader $header '';
        if (
strlen($infos['name100'])>100)
        {
            
$bigheader pack("a100a8a8a8a12a12a8a1a100a6a2a32a32a8a8a155a12",
                
'././@LongLink','0000000','0000000','0000000',
                
sprintf("%011o"strlen($infos['name100'])),'00000000000',
                
'        ''L''''ustar ''0',
                
$infos['userName32'],
                
$infos['groupName32'],'','','','');

            
$bigheader .= str_pad($infos['name100'], floor((strlen($infos['name100']) + 512 1) / 512) * 512"\0");

            
$checksum 0;
            for (
$i 0$i 512$i++)
                
$checksum += ord(substr($bigheader$i1));
            
$bigheader substr_replace($bigheadersprintf("%06o"$checksum)."\0 "1488);
        }
        
$header pack("a100a8a8a8a12a12a8a1a100a6a2a32a32a8a8a155a12"// book the memorie area
            
substr($infos['name100'],0,100),        //  0     100     File name
            
str_pad(substr(sprintf("%07o",$infos['mode8']),-4), 7'0'STR_PAD_LEFT),        // 100     8         File mode
            
sprintf("%07o"$infos['uid8']),        // 108     8         Owner user ID
            
sprintf("%07o"$infos['gid8']),        // 116     8         Group user ID
            
sprintf("%011o"$infos['size12']),        // 124     12         File size in bytes
            
sprintf("%011o"$infos['mtime12']),    // 136     12         Last modification time
            
'        ',                                // 148     8         Check sum for header block
            
$infos['link1'],                        // 156     1         Link indicator / ustar Type flag
            
$infos['link100'],                        // 157     100     Name of linked file
            
'ustar ',                                // 257     6         USTAR indicator "ustar"
            
' ',                                    // 263     2         USTAR version "00"
            
$infos['userName32'],                // 265     32         Owner user name
            
$infos['groupName32'],                // 297     32         Owner group name
            
'',                                    // 329     8         Device major number
            
'',                                    // 337     8         Device minor number
            
$infos['prefix155'],                    // 345     155     Filename prefix
            
'');                                    // 500     12         ??

        
$checksum 0;
        for (
$i 0$i 512$i++)
            
$checksum += ord(substr($header$i1));
        
$header substr_replace($headersprintf("%06o"$checksum)."\0 "1488);

        return 
$bigheader.$header;
    }
    function 
addTarItem ($item$racine)
    {
        
$infos['name100'] = str_replace($racine''$item);
        list (, , 
$infos['mode8'], , $infos['uid8'], $infos['gid8'], , , , $infos['mtime12'] ) = stat($item);
        
$infos['size12'] = is_dir($item) ? filesize($item);
        
$infos['link1'] = is_link($item) ? is_dir ($item) ? 0;
        
$infos['link100'] == readlink($item) : "";

            
$a=function_exists('posix_getpwuid')?posix_getpwuid (fileowner($item)):array('name'=>'Unknown');
        
$infos['userName32'] = $a['name'];

            
$a=function_exists('posix_getgrgid')?posix_getgrgid (filegroup($item)):array('name'=>'Unknown');
        
$infos['groupName32'] = $a['name'];
        
$infos['prefix155'] = '';

        
$header $this->tarHeader512($infos);
        
$data str_pad(file_get_contents($item), floor(($infos['size12'] + 512 1) / 512) * 512"\0");
        if (
is_dir($item))
        {
            
$lst scandir($item);
            
array_shift($lst); // remove  ./  of $lst
            
array_shift($lst); // remove ../  of $lst
            
foreach ($lst as $subitem)
                
$sub .= $this->addTarItem($item.$subitem.(is_dir($item.$subitem)?'/':''), $racine);
        }
        return 
$header.$data.$sub;
    }
    function 
readTarHeader ($ptr)
    {
        
$block fread($ptr512);
        if (
strlen($block)!=512) return false;
        
$hdr unpack ("a100name/a8mode/a8uid/a8gid/a12size/a12mtime/a8checksum/a1type/a100symlink/a6magic/a2version/a32uname/a32gname/a8devmajor/a8devminor/a155prefix/a12temp"$block);
            
$hdr['mode']=$hdr['mode']+0;
            
$hdr['uid']=octdec($hdr['uid']);
            
$hdr['gid']=octdec($hdr['gid']);
            
$hdr['size']=octdec($hdr['size']);
            
$hdr['mtime']=octdec($hdr['mtime']);
            
$hdr['checksum']=octdec($hdr['checksum']);
        
$checksum 0;
        
$block substr_replace($block'        '1488);
        for (
$i 0$i 512$i++)
            
$checksum += ord(substr($block$i1));
        if (isset(
$hdr['name']) && $hdr['checksum']==$checksum)
        {
            if (
$hdr['name']=='././@LongLink' && $hdr['type']=='L')
            {
                
$realName substr(fread($ptrfloor(($hdr['size'] + 512 1) / 512) * 512), 0$hdr['size']-1);
                
$hdr2 $this->readTarHeader ($ptr);
                
$hdr2['name'] = $realName;
                return 
$hdr2;
            }
            elseif (
strtolower(substr($hdr['magic'], 05) == 'ustar'))
            {
                if (
$hdr['size']>0)
                    
$hdr['data'] = substr(fread($ptrfloor(($hdr['size'] + 512 1) / 512) * 512), 0$hdr['size']);
                else 
$hdr['data'] = '';
                return 
$hdr;
            }
            else return 
false;
        }
        else return 
false;
    }
}
?>