[ Index ]
 

Code source de XOOPS 2.0.17.1

Accédez au Source d'autres logiciels libres

title

Body

[fermer]

/htdocs/class/ -> class.tar.php (source)

   1  <?php
   2  // $Id: class.tar.php 2 2005-11-02 18:23:29Z skalpa $

   3  /*

   4      package::i.tools

   5  

   6      php-downloader    v1.0    -    www.ipunkt.biz

   7  

   8      (c)    2002 - www.ipunkt.biz (rok)

   9  */
  10  
  11  /*

  12  =======================================================================

  13  Name:

  14      tar Class

  15  

  16  Author:

  17      Josh Barger <joshb@npt.com>

  18  

  19  Description:

  20      This class reads and writes Tape-Archive (TAR) Files and Gzip

  21      compressed TAR files, which are mainly used on UNIX systems.

  22      This class works on both windows AND unix systems, and does

  23      NOT rely on external applications!! Woohoo!

  24  

  25  Usage:

  26      Copyright (C) 2002  Josh Barger

  27  

  28      This library is free software; you can redistribute it and/or

  29      modify it under the terms of the GNU Lesser General Public

  30      License as published by the Free Software Foundation; either

  31      version 2.1 of the License, or (at your option) any later version.

  32  

  33      This library is distributed in the hope that it will be useful,

  34      but WITHOUT ANY WARRANTY; without even the implied warranty of

  35      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU

  36      Lesser General Public License for more details at:

  37          http://www.gnu.org/copyleft/lesser.html

  38  

  39      If you use this script in your application/website, please

  40      send me an e-mail letting me know about it :)

  41  

  42  Bugs:

  43      Please report any bugs you might find to my e-mail address

  44      at joshb@npt.com.  If you have already created a fix/patch

  45      for the bug, please do send it to me so I can incorporate it into my release.

  46  

  47  Version History:

  48      1.0    04/10/2002    - InitialRelease

  49  

  50      2.0    04/11/2002    - Merged both tarReader and tarWriter

  51                    classes into one

  52                  - Added support for gzipped tar files

  53                    Remember to name for .tar.gz or .tgz

  54                    if you use gzip compression!

  55                    :: THIS REQUIRES ZLIB EXTENSION ::

  56                  - Added additional comments to

  57                    functions to help users

  58                  - Added ability to remove files and

  59                    directories from archive

  60      2.1    04/12/2002    - Fixed serious bug in generating tar

  61                  - Created another example file

  62                  - Added check to make sure ZLIB is

  63                    installed before running GZIP

  64                    compression on TAR

  65      2.2    05/07/2002    - Added automatic detection of Gzipped

  66                    tar files (Thanks go to Jidgen Falch

  67                    for the idea)

  68                  - Changed "private" functions to have

  69                    special function names beginning with

  70                    two underscores

  71  =======================================================================

  72  XOOPS changes onokazu <webmaster@xoops.org>

  73  

  74      12/25/2002 - Added flag to addFile() function for binary files

  75  

  76  =======================================================================

  77  */
  78  
  79  /**

  80   * tar Class

  81   * 

  82   * This class reads and writes Tape-Archive (TAR) Files and Gzip

  83   * compressed TAR files, which are mainly used on UNIX systems.

  84   * This class works on both windows AND unix systems, and does

  85   * NOT rely on external applications!! Woohoo!

  86   * 

  87   * @author    Josh Barger <joshb@npt.com>

  88   * @copyright    Copyright (C) 2002  Josh Barger

  89   * 

  90   * @package     kernel

  91   * @subpackage  core

  92   */
  93  class tar
  94  {
  95      /**#@+

  96       * Unprocessed Archive Information

  97       */
  98      var $filename;
  99      var $isGzipped;
 100      var $tar_file;
 101      /**#@-*/

 102  
 103      /**#@+

 104       * Processed Archive Information

 105       */
 106      var $files;
 107      var $directories;
 108      var $numFiles;
 109      var $numDirectories;
 110      /**#@-*/

 111  
 112  
 113      /**

 114       * Class Constructor -- Does nothing...

 115       */
 116  	function tar()
 117      {
 118          return true;
 119      }
 120  
 121      /**

 122       * Computes the unsigned Checksum of a file's header

 123       * to try to ensure valid file

 124       * 

 125       * @param    string  $bytestring

 126       * 

 127       * @access    private

 128       */
 129  	function __computeUnsignedChecksum($bytestring)
 130      {
 131          $unsigned_chksum = '';
 132          for($i=0; $i<512; $i++)
 133              $unsigned_chksum += ord($bytestring[$i]);
 134          for($i=0; $i<8; $i++)
 135              $unsigned_chksum -= ord($bytestring[148 + $i]);
 136          $unsigned_chksum += ord(" ") * 8;
 137  
 138          return $unsigned_chksum;
 139      }
 140  
 141  
 142      /**

 143       * Converts a NULL padded string to a non-NULL padded string

 144       * 

 145       * @param   string  $string

 146       * 

 147       * @return  string 

 148       * 

 149       * @access    private

 150       **/
 151  	function __parseNullPaddedString($string)
 152      {
 153          $position = strpos($string,chr(0));
 154          return substr($string,0,$position);
 155      }
 156  
 157      /**

 158       * This function parses the current TAR file

 159       * 

 160       * @return  bool    always TRUE

 161       * 

 162       * @access    private

 163       **/
 164  	function __parseTar()
 165      {
 166          // Read Files from archive

 167          $tar_length = strlen($this->tar_file);
 168          $main_offset = 0;
 169          $this->numFiles = 0;
 170          while ( $main_offset < $tar_length ) {
 171              // If we read a block of 512 nulls, we are at the end of the archive

 172              if(substr($this->tar_file,$main_offset,512) == str_repeat(chr(0),512))
 173                  break;
 174  
 175              // Parse file name

 176              $file_name        = $this->__parseNullPaddedString(substr($this->tar_file,$main_offset,100));
 177  
 178              // Parse the file mode

 179              $file_mode        = substr($this->tar_file,$main_offset + 100,8);
 180  
 181              // Parse the file user ID

 182              $file_uid        = octdec(substr($this->tar_file,$main_offset + 108,8));
 183  
 184              // Parse the file group ID

 185              $file_gid        = octdec(substr($this->tar_file,$main_offset + 116,8));
 186  
 187              // Parse the file size

 188              $file_size        = octdec(substr($this->tar_file,$main_offset + 124,12));
 189  
 190              // Parse the file update time - unix timestamp format

 191              $file_time        = octdec(substr($this->tar_file,$main_offset + 136,12));
 192  
 193              // Parse Checksum

 194              $file_chksum        = octdec(substr($this->tar_file,$main_offset + 148,6));
 195  
 196              // Parse user name

 197              $file_uname        = $this->__parseNullPaddedString(substr($this->tar_file,$main_offset + 265,32));
 198  
 199              // Parse Group name

 200              $file_gname        = $this->__parseNullPaddedString(substr($this->tar_file,$main_offset + 297,32));
 201  
 202              // Make sure our file is valid

 203              if($this->__computeUnsignedChecksum(substr($this->tar_file,$main_offset,512)) != $file_chksum)
 204                  return false;
 205  
 206              // Parse File Contents

 207              $file_contents        = substr($this->tar_file,$main_offset + 512,$file_size);
 208  
 209              /*    ### Unused Header Information ###

 210                  $activeFile["typeflag"]        = substr($this->tar_file,$main_offset + 156,1);

 211                  $activeFile["linkname"]        = substr($this->tar_file,$main_offset + 157,100);

 212                  $activeFile["magic"]        = substr($this->tar_file,$main_offset + 257,6);

 213                  $activeFile["version"]        = substr($this->tar_file,$main_offset + 263,2);

 214                  $activeFile["devmajor"]        = substr($this->tar_file,$main_offset + 329,8);

 215                  $activeFile["devminor"]        = substr($this->tar_file,$main_offset + 337,8);

 216                  $activeFile["prefix"]        = substr($this->tar_file,$main_offset + 345,155);

 217                  $activeFile["endheader"]    = substr($this->tar_file,$main_offset + 500,12);

 218              */
 219  
 220              if ( $file_size > 0 ) {
 221                  // Increment number of files

 222                  $this->numFiles++;
 223  
 224                  // Create us a new file in our array

 225                  $activeFile = &$this->files[];
 226  
 227                  // Asign Values

 228                  $activeFile["name"]        = $file_name;
 229                  $activeFile["mode"]        = $file_mode;
 230                  $activeFile["size"]        = $file_size;
 231                  $activeFile["time"]        = $file_time;
 232                  $activeFile["user_id"]        = $file_uid;
 233                  $activeFile["group_id"]        = $file_gid;
 234                  $activeFile["user_name"]    = $file_uname;
 235                  $activeFile["group_name"]    = $file_gname;
 236                  $activeFile["checksum"]        = $file_chksum;
 237                  $activeFile["file"]        = $file_contents;
 238              } else {
 239                  // Increment number of directories

 240                  $this->numDirectories++;
 241  
 242                  // Create a new directory in our array

 243                  $activeDir = &$this->directories[];
 244  
 245                  // Assign values

 246                  $activeDir["name"]        = $file_name;
 247                  $activeDir["mode"]        = $file_mode;
 248                  $activeDir["time"]        = $file_time;
 249                  $activeDir["user_id"]        = $file_uid;
 250                  $activeDir["group_id"]        = $file_gid;
 251                  $activeDir["user_name"]        = $file_uname;
 252                  $activeDir["group_name"]    = $file_gname;
 253                  $activeDir["checksum"]        = $file_chksum;
 254              }
 255  
 256              // Move our offset the number of blocks we have processed

 257              $main_offset += 512 + (ceil($file_size / 512) * 512);
 258          }
 259  
 260          return true;
 261      }
 262  
 263      /**

 264       * Read a non gzipped tar file in for processing.

 265       * 

 266       * @param   string  $filename   full filename

 267       * @return  bool    always TRUE

 268       * 

 269       * @access    private

 270       **/
 271  	function __readTar($filename='')
 272      {
 273          // Set the filename to load

 274          if(!$filename)
 275              $filename = $this->filename;
 276  
 277          // Read in the TAR file

 278          $fp = fopen($filename,"rb");
 279          $this->tar_file = fread($fp,filesize($filename));
 280          fclose($fp);
 281  
 282          if($this->tar_file[0] == chr(31) && $this->tar_file[1] == chr(139) && $this->tar_file[2] == chr(8)) {
 283              if(!function_exists("gzinflate"))
 284                  return false;
 285  
 286              $this->isGzipped = true;
 287  
 288              $this->tar_file = gzinflate(substr($this->tar_file,10,-4));
 289          }
 290  
 291          // Parse the TAR file

 292          $this->__parseTar();
 293  
 294          return true;
 295      }
 296  
 297      /**

 298       * Generates a TAR file from the processed data

 299       * 

 300       * @return  bool    always TRUE

 301       * 

 302       * @access    private

 303       **/
 304  	function __generateTAR()
 305      {
 306          // Clear any data currently in $this->tar_file

 307          unset($this->tar_file);
 308  
 309          // Generate Records for each directory, if we have directories

 310          if($this->numDirectories > 0) {
 311              foreach($this->directories as $key => $information) {
 312                  unset($header);
 313  
 314                  // Generate tar header for this directory

 315                  // Filename, Permissions, UID, GID, size, Time, checksum, typeflag, linkname, magic, version, user name, group name, devmajor, devminor, prefix, end

 316                  $header .= str_pad($information["name"],100,chr(0));
 317                  $header .= str_pad(decoct($information["mode"]),7,"0",STR_PAD_LEFT) . chr(0);
 318                  $header .= str_pad(decoct($information["user_id"]),7,"0",STR_PAD_LEFT) . chr(0);
 319                  $header .= str_pad(decoct($information["group_id"]),7,"0",STR_PAD_LEFT) . chr(0);
 320                  $header .= str_pad(decoct(0),11,"0",STR_PAD_LEFT) . chr(0);
 321                  $header .= str_pad(decoct($information["time"]),11,"0",STR_PAD_LEFT) . chr(0);
 322                  $header .= str_repeat(" ",8);
 323                  $header .= "5";
 324                  $header .= str_repeat(chr(0),100);
 325                  $header .= str_pad("ustar",6,chr(32));
 326                  $header .= chr(32) . chr(0);
 327                  $header .= str_pad("",32,chr(0));
 328                  $header .= str_pad("",32,chr(0));
 329                  $header .= str_repeat(chr(0),8);
 330                  $header .= str_repeat(chr(0),8);
 331                  $header .= str_repeat(chr(0),155);
 332                  $header .= str_repeat(chr(0),12);
 333  
 334                  // Compute header checksum

 335                  $checksum = str_pad(decoct($this->__computeUnsignedChecksum($header)),6,"0",STR_PAD_LEFT);
 336                  for($i=0; $i<6; $i++) {
 337                      $header[(148 + $i)] = substr($checksum,$i,1);
 338                  }
 339                  $header[154] = chr(0);
 340                  $header[155] = chr(32);
 341  
 342                  // Add new tar formatted data to tar file contents

 343                  $this->tar_file .= $header;
 344              }
 345          }
 346  
 347          // Generate Records for each file, if we have files (We should...)

 348          if($this->numFiles > 0) {
 349              $this->tar_file = '';
 350              foreach($this->files as $key => $information) {
 351                  unset($header);
 352  
 353                  // Generate the TAR header for this file

 354                  // Filename, Permissions, UID, GID, size, Time, checksum, typeflag, linkname, magic, version, user name, group name, devmajor, devminor, prefix, end

 355                  $header = str_pad($information["name"],100,chr(0));
 356                  $header .= str_pad(decoct($information["mode"]),7,"0",STR_PAD_LEFT) . chr(0);
 357                  $header .= str_pad(decoct($information["user_id"]),7,"0",STR_PAD_LEFT) . chr(0);
 358                  $header .= str_pad(decoct($information["group_id"]),7,"0",STR_PAD_LEFT) . chr(0);
 359                  $header .= str_pad(decoct($information["size"]),11,"0",STR_PAD_LEFT) . chr(0);
 360                  $header .= str_pad(decoct($information["time"]),11,"0",STR_PAD_LEFT) . chr(0);
 361                  $header .= str_repeat(" ",8);
 362                  $header .= "0";
 363                  $header .= str_repeat(chr(0),100);
 364                  $header .= str_pad("ustar",6,chr(32));
 365                  $header .= chr(32) . chr(0);
 366                  $header .= str_pad($information["user_name"],32,chr(0));    // How do I get a file's user name from PHP?

 367                  $header .= str_pad($information["group_name"],32,chr(0));    // How do I get a file's group name from PHP?

 368                  $header .= str_repeat(chr(0),8);
 369                  $header .= str_repeat(chr(0),8);
 370                  $header .= str_repeat(chr(0),155);
 371                  $header .= str_repeat(chr(0),12);
 372  
 373                  // Compute header checksum

 374                  $checksum = str_pad(decoct($this->__computeUnsignedChecksum($header)),6,"0",STR_PAD_LEFT);
 375                  for($i=0; $i<6; $i++) {
 376                      $header[(148 + $i)] = substr($checksum,$i,1);
 377                  }
 378                  $header[154] = chr(0);
 379                  $header[155] = chr(32);
 380  
 381                  // Pad file contents to byte count divisible by 512

 382                  $file_contents = str_pad($information["file"],(ceil($information["size"] / 512) * 512),chr(0));
 383  
 384                  // Add new tar formatted data to tar file contents

 385                  $this->tar_file .= $header . $file_contents;
 386              }
 387          }
 388  
 389          // Add 512 bytes of NULLs to designate EOF

 390          $this->tar_file .= str_repeat(chr(0),512);
 391  
 392          return true;
 393      }
 394  
 395  
 396      /**

 397       * Open a TAR file

 398       * 

 399       * @param   string  $filename

 400       * @return  bool 

 401       **/
 402  	function openTAR($filename)
 403      {
 404          // Clear any values from previous tar archives

 405          unset($this->filename);
 406          unset($this->isGzipped);
 407          unset($this->tar_file);
 408          unset($this->files);
 409          unset($this->directories);
 410          unset($this->numFiles);
 411          unset($this->numDirectories);
 412  
 413          // If the tar file doesn't exist...

 414          if(!file_exists($filename))
 415              return false;
 416  
 417          $this->filename = $filename;
 418  
 419          // Parse this file

 420          $this->__readTar();
 421  
 422          return true;
 423      }
 424  
 425      /**

 426       * Appends a tar file to the end of the currently opened tar file.

 427       * 

 428       * @param   string  $filename

 429       * @return  bool

 430       **/
 431  	function appendTar($filename)
 432      {
 433          // If the tar file doesn't exist...

 434          if(!file_exists($filename))
 435              return false;
 436  
 437          $this->__readTar($filename);
 438  
 439          return true;
 440      }
 441  
 442      /**

 443       * Retrieves information about a file in the current tar archive

 444       * 

 445       * @param   string  $filename

 446       * @return  string  FALSE on fail

 447       **/
 448  	function getFile($filename)
 449      {
 450          if ( $this->numFiles > 0 ) {
 451              foreach($this->files as $key => $information) {
 452                  if($information["name"] == $filename)
 453                      return $information;
 454              }
 455          }
 456  
 457          return false;
 458      }
 459  
 460      /**

 461       * Retrieves information about a directory in the current tar archive

 462       * 

 463       * @param   string  $dirname

 464       * @return  string  FALSE on fail

 465       **/
 466  	function getDirectory($dirname)
 467      {
 468          if($this->numDirectories > 0) {
 469              foreach($this->directories as $key => $information) {
 470                  if($information["name"] == $dirname)
 471                      return $information;
 472              }
 473          }
 474  
 475          return false;
 476      }
 477  
 478      /**

 479       * Check if this tar archive contains a specific file

 480       * 

 481       * @param   string  $filename

 482       * @return  bool

 483       **/
 484  	function containsFile($filename)
 485      {
 486          if ( $this->numFiles > 0 ) {
 487              foreach($this->files as $key => $information) {
 488                  if($information["name"] == $filename)
 489                      return true;
 490              }
 491          }
 492          return false;
 493      }
 494  
 495      /**

 496       * Check if this tar archive contains a specific directory

 497       * 

 498       * @param   string  $dirname

 499       * @return  bool

 500       **/
 501  	function containsDirectory($dirname)
 502      {
 503          if ( $this->numDirectories > 0 ) {
 504              foreach ( $this->directories as $key => $information ) {
 505                  if ( $information["name"] == $dirname ) {
 506                      return true;
 507                  }
 508              }
 509          }
 510          return false;
 511      }
 512  
 513      /**

 514       * Add a directory to this tar archive

 515       * 

 516       * @param   string  $dirname

 517       * @return  bool

 518       **/
 519  	function addDirectory($dirname)
 520      {
 521          if ( !file_exists($dirname) ) {
 522              return false;
 523          }
 524  
 525          // Get directory information

 526          $file_information = stat($dirname);
 527  
 528          // Add directory to processed data

 529          $this->numDirectories++;
 530          $activeDir        = &$this->directories[];
 531          $activeDir["name"]    = $dirname;
 532          $activeDir["mode"]    = $file_information["mode"];
 533          $activeDir["time"]    = $file_information["time"];
 534          $activeDir["user_id"]    = $file_information["uid"];
 535          $activeDir["group_id"]    = $file_information["gid"];
 536          $activeDir["checksum"]    = $checksum;
 537  
 538          return true;
 539      }
 540  
 541      /**

 542       * Add a file to the tar archive

 543       * 

 544       * @param   string  $filename

 545       * @param   boolean $binary     Binary file?

 546       * @return  bool

 547       **/
 548  	function addFile($filename, $binary = false)
 549      {
 550          // Make sure the file we are adding exists!

 551          if ( !file_exists($filename) ) {
 552              return false;
 553          }
 554  
 555          // Make sure there are no other files in the archive that have this same filename

 556          if ( $this->containsFile($filename) ) {
 557              return false;
 558          }
 559  
 560          // Get file information

 561          $file_information = stat($filename);
 562  
 563          // Read in the file's contents

 564          if (!$binary) {
 565              $fp = fopen($filename, "r");
 566          } else {
 567              $fp = fopen($filename, "rb");
 568          }
 569          $file_contents = fread($fp,filesize($filename));
 570          fclose($fp);
 571  
 572          // Add file to processed data

 573          $this->numFiles++;
 574          $activeFile            = &$this->files[];
 575          $activeFile["name"]        = $filename;
 576          $activeFile["mode"]        = $file_information["mode"];
 577          $activeFile["user_id"]        = $file_information["uid"];
 578          $activeFile["group_id"]        = $file_information["gid"];
 579          $activeFile["size"]        = $file_information["size"];
 580          $activeFile["time"]        = $file_information["mtime"];
 581          $activeFile["checksum"]        = isset($checksum) ? $checksum : '';
 582          $activeFile["user_name"]    = "";
 583          $activeFile["group_name"]    = "";
 584          $activeFile["file"]        = trim($file_contents);
 585  
 586          return true;
 587      }
 588  
 589      /**

 590       * Remove a file from the tar archive

 591       * 

 592       * @param   string  $filename

 593       * @return  bool

 594       **/
 595  	function removeFile($filename)
 596      {
 597          if ( $this->numFiles > 0 ) {
 598              foreach ( $this->files as $key => $information ) {
 599                  if ( $information["name"] == $filename ) {
 600                      $this->numFiles--;
 601                      unset($this->files[$key]);
 602                      return true;
 603                  }
 604              }
 605          }
 606          return false;
 607      }
 608  
 609      /**

 610       * Remove a directory from the tar archive

 611       * 

 612       * @param   string  $dirname

 613       * @return  bool

 614       **/
 615  	function removeDirectory($dirname)
 616      {
 617          if ( $this->numDirectories > 0 ) {
 618              foreach ( $this->directories as $key => $information ) {
 619                  if ( $information["name"] == $dirname ) {
 620                      $this->numDirectories--;
 621                      unset($this->directories[$key]);
 622                      return true;
 623                  }
 624              }
 625          }
 626          return false;
 627      }
 628  
 629      /**

 630       * Write the currently loaded tar archive to disk

 631       * 

 632       * @return  bool 

 633       **/
 634  	function saveTar()
 635      {
 636          if ( !$this->filename ) {
 637              return false;
 638          }
 639  
 640          // Write tar to current file using specified gzip compression

 641          $this->toTar($this->filename,$this->isGzipped);
 642  
 643          return true;
 644      }
 645  
 646      /**

 647       * Saves tar archive to a different file than the current file

 648       * 

 649       * @param   string  $filename

 650       * @param   bool    $useGzip    Use GZ compression?

 651       * @return  bool

 652       **/
 653  	function toTar($filename,$useGzip)
 654      {
 655          if ( !$filename ) {
 656              return false;
 657          }
 658  
 659          // Encode processed files into TAR file format

 660          $this->__generateTar();
 661  
 662          // GZ Compress the data if we need to

 663          if ( $useGzip ) {
 664              // Make sure we have gzip support

 665              if ( !function_exists("gzencode") ) {
 666                  return false;
 667              }
 668  
 669              $file = gzencode($this->tar_file);
 670          } else {
 671              $file = $this->tar_file;
 672          }
 673  
 674          // Write the TAR file

 675          $fp = fopen($filename,"wb");
 676          fwrite($fp,$file);
 677          fclose($fp);
 678  
 679          return true;
 680      }
 681  
 682      /**

 683       * Sends tar archive to stdout

 684       * 

 685       * @param   string  $filename

 686       * @param   bool    $useGzip    Use GZ compression?

 687       * @return  string

 688       **/
 689  	function toTarOutput($filename,$useGzip)
 690      {
 691          if ( !$filename ) {
 692              return false;
 693          }
 694  
 695          // Encode processed files into TAR file format

 696          $this->__generateTar();
 697  
 698          // GZ Compress the data if we need to

 699          if ( $useGzip ) {
 700              // Make sure we have gzip support

 701              if ( !function_exists("gzencode") ) {
 702                  return false;
 703              }
 704  
 705              $file = gzencode($this->tar_file);
 706          } else {
 707              $file = $this->tar_file;
 708          }
 709  
 710          return $file;
 711      }
 712  }
 713  
 714  ?>


Généré le : Sun Nov 25 11:44:32 2007 par Balluche grâce à PHPXref 0.7
  Clicky Web Analytics