ArchiveTar.class.php

gehe zur Dokumentation dieser Datei
00001 <?php
00002 /*
00003 =======================================================================
00004 Name:
00005      tar Class
00006 
00007 Author:
00008      Josh Barger <joshb@npt.com>
00009 
00010 Description:
00011      This class reads and writes Tape-Archive (TAR) Files and Gzip
00012      compressed TAR files, which are mainly used on UNIX systems.
00013      This class works on both windows AND unix systems, and does
00014      NOT rely on external applications!! Woohoo!
00015 
00016 Usage:
00017      Copyright (C) 2002  Josh Barger
00018 
00019      This library is free software; you can redistribute it and/or
00020      modify it under the terms of the GNU Lesser General Public
00021      License as published by the Free Software Foundation; either
00022      version 2.1 of the License, or (at your option) any later version.
00023 
00024      This library is distributed in the hope that it will be useful,
00025      but WITHOUT ANY WARRANTY; without even the implied warranty of
00026      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00027      Lesser General Public License for more details at:
00028           http://www.gnu.org/copyleft/lesser.html
00029 
00030      If you use this script in your application/website, please
00031      send me an e-mail letting me know about it :)
00032 
00033 Bugs:
00034      Please report any bugs you might find to my e-mail address
00035      at joshb@npt.com.  If you have already created a fix/patch
00036      for the bug, please do send it to me so I can incorporate it into my release.
00037 
00038 Version History:
00039      1.0  04/10/2002     - InitialRelease
00040 
00041      2.0  04/11/2002     - Merged both tarReader and tarWriter
00042                       classes into one
00043                     - Added support for gzipped tar files
00044                       Remember to name for .tar.gz or .tgz
00045                       if you use gzip compression!
00046                       :: THIS REQUIRES ZLIB EXTENSION ::
00047                     - Added additional comments to
00048                       functions to help users
00049                     - Added ability to remove files and
00050                       directories from archive
00051      2.1  04/12/2002     - Fixed serious bug in generating tar
00052                     - Created another example file
00053                     - Added check to make sure ZLIB is
00054                       installed before running GZIP
00055                       compression on TAR
00056      2.2  05/07/2002     - Added automatic detection of Gzipped
00057                       tar files (Thanks go to Jürgen Falch
00058                       for the idea)
00059                     - Changed "private" functions to have
00060                       special function names beginning with
00061                       two underscores
00062 =======================================================================
00063 */
00064 
00065 
00066 class ArchiveTar
00067 {
00068      // Unprocessed Archive Information
00069      var $filename;
00070      var $isGzipped;
00071      var $tar_file;
00072 
00073      // Processed Archive Information
00074      var $files;
00075      var $directories;
00076      var $numFiles;
00077      var $numDirectories;
00078 
00079 
00080      // Class Constructor -- Does nothing...
00081      function tar() {
00082           return true;
00083      }
00084 
00085 
00086      // Computes the unsigned Checksum of a file's header
00087      // to try to ensure valid file
00088      // PRIVATE ACCESS FUNCTION
00089      function __computeUnsignedChecksum($bytestring)
00090      {
00091           $unsigned_chksum=0;
00092           for($i=0; $i<512; $i++)
00093                $unsigned_chksum += ord($bytestring[$i]);
00094           for($i=0; $i<8; $i++)
00095                $unsigned_chksum -= ord($bytestring[148 + $i]);
00096           $unsigned_chksum += ord(" ") * 8;
00097 
00098           return $unsigned_chksum;
00099      }
00100 
00101 
00102      // Converts a NULL padded string to a non-NULL padded string
00103      // PRIVATE ACCESS FUNCTION
00104      function __parseNullPaddedString($string)
00105      {
00106           $position = strpos($string,chr(0));
00107           return substr($string,0,$position);
00108      }
00109 
00110 
00111      // This function parses the current TAR file
00112      // PRIVATE ACCESS FUNCTION
00113      function __parseTar()
00114      {
00115           // Read Files from archive
00116           $this->numFiles=0;
00117           $tar_length = strlen($this->tar_file);
00118           $main_offset = 0;
00119           while($main_offset < $tar_length) {
00120                // If we read a block of 512 nulls, we are at the end of the archive
00121                if(substr($this->tar_file,$main_offset,512) == str_repeat(chr(0),512))
00122                     break;
00123 
00124                // Parse file name
00125                $file_name          = $this->__parseNullPaddedString(substr($this->tar_file,$main_offset,100));
00126 
00127                // Parse the file mode
00128                $file_mode          = substr($this->tar_file,$main_offset + 100,8);
00129 
00130                // Parse the file user ID
00131                $file_uid      = octdec(substr($this->tar_file,$main_offset + 108,8));
00132 
00133                // Parse the file group ID
00134                $file_gid      = octdec(substr($this->tar_file,$main_offset + 116,8));
00135 
00136                // Parse the file size
00137                $file_size          = octdec(substr($this->tar_file,$main_offset + 124,12));
00138 
00139                // Parse the file update time - unix timestamp format
00140                $file_time          = octdec(substr($this->tar_file,$main_offset + 136,12));
00141 
00142                // Parse Checksum
00143                $file_chksum        = octdec(substr($this->tar_file,$main_offset + 148,6));
00144 
00145                // Parse user name
00146                $file_uname         = $this->__parseNullPaddedString(substr($this->tar_file,$main_offset + 265,32));
00147 
00148                // Parse Group name
00149                $file_gname         = $this->__parseNullPaddedString(substr($this->tar_file,$main_offset + 297,32));
00150 
00151                // Make sure our file is valid
00152                if($this->__computeUnsignedChecksum(substr($this->tar_file,$main_offset,512)) != $file_chksum)
00153                     return false;
00154 
00155                // Parse File Contents
00156                $file_contents      = substr($this->tar_file,$main_offset + 512,$file_size);
00157 
00158                /*   ### Unused Header Information ###
00159                     $activeFile["typeflag"]       = substr($this->tar_file,$main_offset + 156,1);
00160                     $activeFile["linkname"]       = substr($this->tar_file,$main_offset + 157,100);
00161                     $activeFile["magic"]          = substr($this->tar_file,$main_offset + 257,6);
00162                     $activeFile["version"]        = substr($this->tar_file,$main_offset + 263,2);
00163                     $activeFile["devmajor"]       = substr($this->tar_file,$main_offset + 329,8);
00164                     $activeFile["devminor"]       = substr($this->tar_file,$main_offset + 337,8);
00165                     $activeFile["prefix"]         = substr($this->tar_file,$main_offset + 345,155);
00166                     $activeFile["endheader"] = substr($this->tar_file,$main_offset + 500,12);
00167                */
00168 
00169                if($file_size > 0) {
00170                     // Increment number of files
00171                     $this->numFiles++;
00172 
00173                     // Create us a new file in our array
00174                     $activeFile = &$this->files[];
00175 
00176                     // Asign Values
00177                     $activeFile["name"]      = $file_name;
00178                     $activeFile["mode"]      = $file_mode;
00179                     $activeFile["size"]      = $file_size;
00180                     $activeFile["time"]      = $file_time;
00181                     $activeFile["user_id"]        = $file_uid;
00182                     $activeFile["group_id"]       = $file_gid;
00183                     $activeFile["user_name"] = $file_uname;
00184                     $activeFile["group_name"]     = $file_gname;
00185                     $activeFile["checksum"]       = $file_chksum;
00186                     $activeFile["file"]      = $file_contents;
00187 
00188                } else {
00189                     // Increment number of directories
00190                     $this->numDirectories++;
00191 
00192                     // Create a new directory in our array
00193                     $activeDir = &$this->directories[];
00194 
00195                     // Assign values
00196                     $activeDir["name"]       = $file_name;
00197                     $activeDir["mode"]       = $file_mode;
00198                     $activeDir["time"]       = $file_time;
00199                     $activeDir["user_id"]         = $file_uid;
00200                     $activeDir["group_id"]        = $file_gid;
00201                     $activeDir["user_name"]       = $file_uname;
00202                     $activeDir["group_name"] = $file_gname;
00203                     $activeDir["checksum"]        = $file_chksum;
00204                }
00205 
00206                // Move our offset the number of blocks we have processed
00207                $main_offset += 512 + (ceil($file_size / 512) * 512);
00208           }
00209 
00210           return true;
00211      }
00212 
00213 
00214      // Read a non gzipped tar file in for processing
00215      // PRIVATE ACCESS FUNCTION
00216      function __readTar($filename='')
00217      {
00218           // Set the filename to load
00219           // Read in the TAR file
00220 
00221           if($this->tar_file[0] == chr(31) && $this->tar_file[1] == chr(139) && $this->tar_file[2] == chr(8)) {
00222                if(!function_exists("gzinflate"))
00223                     return false;
00224 
00225                $this->isGzipped = TRUE;
00226 
00227                $this->tar_file = gzinflate(substr($this->tar_file,10,-4));
00228           }
00229 
00230           // Parse the TAR file
00231           $this->__parseTar();
00232 
00233           return true;
00234      }
00235 
00236 
00237      // Generates a TAR file from the processed data
00238      // PRIVATE ACCESS FUNCTION
00239      function __generateTAR()
00240      {
00241           // Clear any data currently in $this->tar_file    
00242           unset($this->tar_file);
00243 
00244           // Generate Records for each directory, if we have directories
00245           if($this->numDirectories > 0) {
00246                foreach($this->directories as $key => $information) {
00247                     unset($header);
00248 
00249                     // Generate tar header for this directory
00250                     // Filename, Permissions, UID, GID, size, Time, checksum, typeflag, linkname, magic, version, user name, group name, devmajor, devminor, prefix, end
00251                     $header .= str_pad($information["name"],100,chr(0));
00252                     $header .= str_pad(decoct($information["mode"]),7,"0",STR_PAD_LEFT) . chr(0);
00253                     $header .= str_pad(decoct($information["user_id"]),7,"0",STR_PAD_LEFT) . chr(0);
00254                     $header .= str_pad(decoct($information["group_id"]),7,"0",STR_PAD_LEFT) . chr(0);
00255                     $header .= str_pad(decoct(0),11,"0",STR_PAD_LEFT) . chr(0);
00256                     $header .= str_pad(decoct($information["time"]),11,"0",STR_PAD_LEFT) . chr(0);
00257                     $header .= str_repeat(" ",8);
00258                     $header .= "5";
00259                     $header .= str_repeat(chr(0),100);
00260                     $header .= str_pad("ustar",6,chr(32));
00261                     $header .= chr(32) . chr(0);
00262                     $header .= str_pad("",32,chr(0));
00263                     $header .= str_pad("",32,chr(0));
00264                     $header .= str_repeat(chr(0),8);
00265                     $header .= str_repeat(chr(0),8);
00266                     $header .= str_repeat(chr(0),155);
00267                     $header .= str_repeat(chr(0),12);
00268 
00269                     // Compute header checksum
00270                     $checksum = str_pad(decoct($this->__computeUnsignedChecksum($header)),6,"0",STR_PAD_LEFT);
00271                     for($i=0; $i<6; $i++) {
00272                          $header[(148 + $i)] = substr($checksum,$i,1);
00273                     }
00274                     $header[154] = chr(0);
00275                     $header[155] = chr(32);
00276 
00277                     // Add new tar formatted data to tar file contents
00278                     $this->tar_file .= $header;
00279                }
00280           }
00281 
00282           // Generate Records for each file, if we have files (We should...)
00283           if($this->numFiles > 0)
00284           {
00285                foreach($this->files as $key => $information)
00286                {
00287                     unset($header);
00288 
00289                     // Generate the TAR header for this file
00290                     // Filename, Permissions, UID, GID, size, Time, checksum, typeflag, linkname, magic, version, user name, group name, devmajor, devminor, prefix, end
00291                     $header .= str_pad($information["name"],100,chr(0));
00292                     $header .= str_pad(decoct($information["mode"]),7,"0",STR_PAD_LEFT) . chr(0);
00293                     $header .= str_pad(decoct($information["user_id"]),7,"0",STR_PAD_LEFT) . chr(0);
00294                     $header .= str_pad(decoct($information["group_id"]),7,"0",STR_PAD_LEFT) . chr(0);
00295                     $header .= str_pad(decoct($information["size"]),11,"0",STR_PAD_LEFT) . chr(0);
00296                     $header .= str_pad(decoct($information["time"]),11,"0",STR_PAD_LEFT) . chr(0);
00297                     $header .= str_repeat(" ",8);
00298                     $header .= "0";
00299                     $header .= str_repeat(chr(0),100);
00300                     $header .= str_pad("ustar",6,chr(32));
00301                     $header .= chr(32) . chr(0);
00302                     $header .= str_pad($information["user_name"],32,chr(0));    // How do I get a file's user name from PHP?
00303                     $header .= str_pad($information["group_name"],32,chr(0));   // How do I get a file's group name from PHP?
00304                     $header .= str_repeat(chr(0),8);
00305                     $header .= str_repeat(chr(0),8);
00306                     $header .= str_repeat(chr(0),155);
00307                     $header .= str_repeat(chr(0),12);
00308 
00309                     // Compute header checksum
00310                     $checksum = str_pad(decoct($this->__computeUnsignedChecksum($header)),6,"0",STR_PAD_LEFT);
00311                     for($i=0; $i<6; $i++)
00312                     {
00313                          $header[(148 + $i)] = substr($checksum,$i,1);
00314                     }
00315                     $header[154] = chr(0);
00316                     $header[155] = chr(32);
00317 
00318                     // Pad file contents to byte count divisible by 512
00319                     $file_contents = str_pad($information["file"],(ceil($information["size"] / 512) * 512),chr(0));
00320 
00321                     // Add new tar formatted data to tar file contents
00322                     $this->tar_file .= $header . $file_contents;
00323                }
00324           }
00325 
00326           // Add 512 bytes of NULLs to designate EOF
00327           $this->tar_file .= str_repeat(chr(0),512);
00328 
00329           return true;
00330      }
00331 
00332 
00333      // Open a TAR file
00334      function openTAR($value)
00335      {
00336           // Clear any values from previous tar archives
00337           unset($this->filename);
00338           unset($this->isGzipped);
00339           unset($this->tar_file);
00340           unset($this->files);
00341           unset($this->directories);
00342           unset($this->numFiles);
00343           unset($this->numDirectories);
00344 
00345           $this->filename = 'none';
00346           $this->tar_file = $value;
00347           // Parse this file
00348           $this->__readTar();
00349 
00350           return true;
00351      }
00352 
00353 
00354      // Write the currently loaded tar archive to disk
00355      function saveTar()
00356      {
00357           if(!$this->filename)
00358                return false;
00359 
00360           // Write tar to current file using specified gzip compression
00361           $this->toTar($this->filename,$this->isGzipped);
00362 
00363           return true;
00364      }
00365 
00366 
00367      // Saves tar archive to a different file than the current file
00368      function toTar($filename,$useGzip)
00369      {
00370           if(!$filename)
00371                return false;
00372 
00373           // Encode processed files into TAR file format
00374           $this->__generateTar();
00375 
00376           // GZ Compress the data if we need to
00377           if($useGzip) {
00378                // Make sure we have gzip support
00379                if(!function_exists("gzencode"))
00380                     return false;
00381 
00382                $file = gzencode($this->tar_file);
00383           } else {
00384                $file = $this->tar_file;
00385           }
00386 
00387           // Write the TAR file
00388           $fp = fopen($filename,"wb");
00389           fwrite($fp,$file);
00390           fclose($fp);
00391 
00392           return true;
00393      }
00394 }
00395 
00396 ?>

Erzeugt am Thu May 14 00:55:49 2009 für OpenRat von  doxygen 1.5.8