filesystem
[ class tree: filesystem ] [ index: filesystem ] [ all elements ]

Source for file TAR.class.php

Documentation is available at TAR.class.php

  1. <?php
  2. /**
  3.  * @package filesystem
  4.  */
  5. if( !defined( "CLASSPATH" ) )
  6. {
  7.   echo "<h3>You have to define the constant CLASSPATH!</h3>\r\n";
  8.   echo "Example: define( 'CLASSPATH', '../path/to/classes/' );\r\n";
  9.   exit();
  10. }
  11.  
  12. /**
  13.  *
  14.  */
  15. require_once( CLASSPATH."communication/FTPHost.class.php" );
  16.  
  17. /**
  18.  *
  19.  */
  20. include_once( CLASSPATH."core/Arrays.class.php" );
  21.  
  22. /**
  23.  * This class reads and writes Tape-Archive (TAR) Files and Gzip
  24.  * compressed TAR files, which are mainly used on UNIX systems.
  25.  * This class works on both windows AND unix systems, and does
  26.  * NOT rely on external applications!! Woohoo!
  27.  *
  28.  * Version History:
  29.  * 1.0    04/10/2002    - InitialRelease
  30.  *
  31.  * 2.0    04/11/2002    - Merged both tarReader and tarWriter classes into one
  32.  *                    - Added support for gzipped tar files
  33.  *                  Remember to name for .tar.gz or .tgz
  34.  *                           if you use gzip compression!
  35.  *                           :: THIS REQUIRES ZLIB EXTENSION ::
  36.  *                    - Added additional comments to functions to help users
  37.  *                    directories from archive
  38.  *
  39.  * 2.1    04/12/2002    - Fixed serious bug in generating tar
  40.  *                    - Created another example file
  41.  *                    - Added check to make sure ZLIB is installed before running
  42.  *                  GZIP compression on TAR
  43.  *
  44.  * 2.2    05/07/2002    - Added automatic detection of Gzipped tar files
  45.  *                  (Thanks go to Jürgen Falch for the idea)
  46.  *                    - Changed "private" functions to have special function names
  47.  *                  beginning with two underscores
  48.  *
  49.  * If you use this script in your application/website, please send me an e-mail
  50.  * letting me know about it :)
  51.  *
  52.  * Bugs:
  53.  * Please report any bugs you might find to my e-mail address at joshb@npt.com.
  54.  * If you have already created a fix/patch for the bug, please do send it to me
  55.  * so I can incorporate it into my release.
  56.  *
  57.  * @package   filesystem
  58.  * @version   0.2.3
  59.  * @author    Josh Barger <joshb@npt.com>
  60.  * @license   http://www.gnu.org/copyleft/lesser.html
  61.  *             GNU Lesser General Public License
  62.  * @copyright Copyright (c) 2002 Josh Barger <joshb@npt.com>
  63.  *
  64.  *  This library is free software; you can redistribute it and/or
  65.  *  modify it under the terms of the GNU Lesser General Public
  66.  *  License as published by the Free Software Foundation; either
  67.  *  version 2.1 of the License.
  68.  *
  69.  *  This library is distributed in the hope that it will be useful,
  70.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  71.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  72.  *  GNU Lesser General Public License for more details.
  73.  *
  74.  *  You should have received a copy of the GNU Lesser General
  75.  *  Public License along with this library; if not, write to the
  76.  *  Free Software Foundation, Inc., 59 Temple Place, Suite 330,
  77.  *  Boston, MA 02111-1307 USA
  78.  */
  79. class TAR
  80. {
  81.   // Unprocessed Archive Information
  82.   /**
  83.    * @var    string 
  84.    * @access public
  85.    */
  86.   var $filename;
  87.   /**
  88.    * @var    boolean 
  89.    * @access public
  90.    */
  91.   var $isGzipped = false;
  92.   /**
  93.    * The data content of the archive will be stored in ths variable.
  94.    * 
  95.    * @var    string 
  96.    * @access public
  97.    */
  98.   var $tar_file = "";
  99.   /**
  100.    * This reference of a FTP object is for the use of the filesystem on the
  101.    * server via FTP, cause of SAFE MODE restriction.
  102.    *
  103.    * @access private
  104.    * @var    FTPHost $ftp 
  105.    */
  106.   var $ftp = null;
  107.  
  108.  
  109.   // Processed Archive Information
  110.   /**
  111.    * @var    array 
  112.    * @access public
  113.    */
  114.   var $files;
  115.   /**
  116.    * @var    array 
  117.    * @access public
  118.    */
  119.   var $directories;
  120.   /**
  121.    * @var    integer 
  122.    * @access private
  123.    */
  124.   var $numFiles;
  125.   /**
  126.    * @var    integer 
  127.    * @access private
  128.    */
  129.   var $numDirectories;
  130.  
  131.  
  132.  
  133.   /**
  134.    * Class Constructor -- Does nothing...
  135.    * Perhaps it sets a reference to an FTPHost-Object.
  136.    *
  137.    * @version 1.0
  138.    * @author  Josh Barger <joshb@npt.com>
  139.    * @access  public
  140.    * @return  tar 
  141.    */
  142.   function TAR( $ftp_host = null )
  143.   { $this->ftp =& $ftp_host; }
  144.  
  145.  
  146.  
  147.   /**
  148.    * Adds ftp data to this object. This can be useful for writing dumps if the
  149.    * sever has SAFE MODE restrictions.
  150.    *
  151.    * @version 1.0
  152.    * @since   0.2.3
  153.    * @author  Daniel Plücken <daniel@debakel.net>
  154.    * @access  public
  155.    * @param   string  $host 
  156.    * @param   string  $user 
  157.    * @param   string  $password 
  158.    * @param   string  $port 
  159.    * @return  void 
  160.    */
  161.   function addFTPData(
  162.                        $host,
  163.                        $user,
  164.                        $password,
  165.                        $port = 21
  166.                      )
  167.   { $this->ftp = new FTPHost( $host, $user, $password, $port ); }
  168.  
  169.  
  170.  
  171.   /**
  172.    * Computes the unsigned Checksum of a file's header to try to ensure valid
  173.    * file.
  174.    *
  175.    * @version 1.0
  176.    * @author  Josh Barger <joshb@npt.com>
  177.    * @access  private
  178.    * @return  string 
  179.    */
  180.   function __computeUnsignedChecksum( $bytestring )
  181.   {
  182.     for ( $i = 0; $i < 512; $i++ )
  183.         $unsigned_chksum += ord( $bytestring[$i] );
  184.     for ( $i = 0; $i < 8; $i++ )
  185.         $unsigned_chksum -= ord( $bytestring[148 + $i] );
  186.     
  187.     $unsigned_chksum += ord(" ") * 8;
  188.     
  189.     return $unsigned_chksum;
  190.   }
  191.  
  192.  
  193.  
  194.   /**
  195.    * Converts a NULL padded string to a non-NULL padded string.
  196.    *
  197.    * @version 1.0
  198.    * @author  Josh Barger <joshb@npt.com>
  199.    * @access  private
  200.    * @return  string 
  201.    */
  202.   function __parseNullPaddedString( $string )
  203.   {
  204.     $position = strpos( $string, chr(0) );
  205.     return substr( $string, 0, $position );
  206.   }
  207.  
  208.  
  209.  
  210.   /**
  211.    * This function parses the current TAR file.
  212.    *
  213.    * @version 1.0
  214.    * @author  Josh Barger <joshb@npt.com>
  215.    * @access  private
  216.    * @return  boolean 
  217.    */
  218.   function __parseTar()
  219.   {
  220.     // Read Files from archive
  221.     $tar_length  = strlen( $this->tar_file );
  222.     $main_offset = 0;
  223.     while( $main_offset < $tar_length )
  224.     {
  225.        // If we read a block of 512 nulls, we are at the end of the archive
  226.        if(
  227.            substr(
  228.                    $this->tar_file,
  229.                    $main_offset, 512
  230.                  ) == str_repeat( chr(0), 512 )
  231.          )
  232.          break;
  233.       
  234.       
  235.    
  236.       // Parse file name
  237.       $file_name = $this->__parseNullPaddedString(
  238.                                                 substr(
  239.                                           $this->tar_file,
  240.                                           $main_offset, 100
  241.                                                       )
  242.                                                  );
  243.       // Parse the file mode
  244.       $file_mode  = substr( $this->tar_file, $main_offset + 100, 8 );
  245.       // Parse the file user ID
  246.       $file_uid   = octdec( substr( $this->tar_file, $main_offset + 108, 8 ) );
  247.       // Parse the file group ID
  248.       $file_gid      = octdec( substr( $this->tar_file, $main_offset + 116, 8 ) );
  249.       // Parse the file size
  250.       $file_size  = octdec( substr( $this->tar_file, $main_offset + 124, 12 ) );
  251.       // Parse the file update time - unix timestamp format
  252.       $file_time  = octdec( substr( $this->tar_file, $main_offset + 136, 12 ) );
  253.       // Parse Checksum
  254.       $file_chksum = octdec( substr( $this->tar_file, $main_offset + 148, 6 ) );
  255.    
  256.       // Parse user name
  257.       $file_uname = $this->__parseNullPaddedString(
  258.                                                substr(
  259.                                             $this->tar_file,
  260.                                             $main_offset + 265, 32
  261.                                                      )
  262.                                                   );
  263.       // Parse Group name
  264.       $file_gname = $this->__parseNullPaddedString(
  265.                                                 substr(
  266.                                              $this->tar_file,
  267.                                              $main_offset + 297, 32
  268.                                                       )
  269.                                                   );
  270.       // Make sure our file is valid
  271.       if (
  272.            $this->__computeUnsignedChecksum(
  273.                                         substr(
  274.                                        $this->tar_file,
  275.                                        $main_offset, 512
  276.                                               )
  277.                                            ) != $file_chksum 
  278.          )
  279.          return false;
  280.       
  281.       // Parse File Contents
  282.       $file_contents = substr(
  283.                          $this->tar_file,
  284.                          $main_offset + 512,
  285.                          $file_size
  286.                              );
  287.       
  288.       /*    ### Unused Header Information ###
  289.        $activeFile["typeflag"]        = substr($this->tar_file,$main_offset + 156,1);
  290.        $activeFile["linkname"]        = substr($this->tar_file,$main_offset + 157,100);
  291.        $activeFile["magic"]        = substr($this->tar_file,$main_offset + 257,6);
  292.        $activeFile["version"]        = substr($this->tar_file,$main_offset + 263,2);
  293.        $activeFile["devmajor"]        = substr($this->tar_file,$main_offset + 329,8);
  294.        $activeFile["devminor"]        = substr($this->tar_file,$main_offset + 337,8);
  295.        $activeFile["prefix"]        = substr($this->tar_file,$main_offset + 345,155);
  296.        $activeFile["endheader"]    = substr($this->tar_file,$main_offset + 500,12);
  297.       */
  298.       
  299.       if( $file_size > 0 )
  300.       {
  301.         // Increment number of files
  302.         $this->numFiles++;
  303.     
  304.         // Create us a new file in our array
  305.         $activeFile = &$this->files[];
  306.     
  307.         // Asign Values
  308.         $activeFile["name"]             = $file_name;
  309.         $activeFile["mode"]       = $file_mode;
  310.         $activeFile["size"]       = $file_size;
  311.         $activeFile["time"]       = $file_time;
  312.         $activeFile["user_id"]    = $file_uid;
  313.         $activeFile["group_id"]   = $file_gid;
  314.         $activeFile["user_name"]  = $file_uname;
  315.         $activeFile["group_name"] = $file_gname;
  316.         $activeFile["checksum"]   = $file_chksum;
  317.         $activeFile["file"]       = $file_contents;
  318.       }
  319.       else
  320.       {
  321.         // Increment number of directories
  322.         $this->numDirectories++;
  323.     
  324.         // Create a new directory in our array
  325.         $activeDir = &$this->directories[];
  326.     
  327.         // Assign values
  328.         $activeDir["name"]       = $file_name;
  329.         $activeDir["mode"]       = $file_mode;
  330.         $activeDir["time"]       = $file_time;
  331.         $activeDir["user_id"]    = $file_uid;
  332.         $activeDir["group_id"]   = $file_gid;
  333.         $activeDir["user_name"]  = $file_uname;
  334.         $activeDir["group_name"] = $file_gname;
  335.         $activeDir["checksum"]   = $file_chksum;
  336.       }
  337.   
  338.       // Move our offset the number of blocks we have processed
  339.       $main_offset += 512 + ( ceil( $file_size / 512 ) * 512 );
  340.     }
  341.     
  342.     return true;
  343.   }
  344.  
  345.  
  346.  
  347.   /**
  348.    * Read a non gzipped tar file in for processing.
  349.    *
  350.    * @version 1.0
  351.    * @author  Josh Barger <joshb@npt.com>
  352.    * @access  private
  353.    * @return  string 
  354.    */
  355.   function __readTar( $filename = '' )
  356.   {
  357.     // Set the filename to load
  358.     if ( !$filename )
  359.        $filename = $this->filename;
  360.   
  361.     // Read in the TAR file
  362.     $fp = fopen( $filename, "rb" );
  363.     $this->tar_file = fread( $fp, filesize( $filename ) );
  364.     fclose( $fp );
  365.   
  366.     if(
  367.         $this->tar_file[0] == chr(31)
  368.      && $this->tar_file[1] == chr(139)
  369.      && $this->tar_file[2] == chr(8)
  370.       )
  371.     {
  372.       if( !function_exists( "gzinflate" ) )
  373.         return false;
  374.    
  375.       $this->isGzipped = true;
  376.    
  377.       $this->tar_file = gzinflate( substr( $this->tar_file, 10, -4 ) );
  378.     }
  379.   
  380.     // Parse the TAR file
  381.     $this->__parseTar();
  382.   
  383.     return true;
  384.   }
  385.  
  386.  
  387.  
  388.   /**
  389.    * Generates a TAR file from the processed data.
  390.    *
  391.    * @version 1.0
  392.    * @author  Josh Barger <joshb@npt.com>
  393.    * @access  private
  394.    * @return  boolean 
  395.    */
  396.   function __generateTAR()
  397.   {
  398.     // Clear any data currently in $this->tar_file    
  399.     unset( $this->tar_file );
  400.     
  401.     // Generate Records for each directory, if we have directories
  402.     if ( $this->numDirectories > 0 )
  403.        foreach ( $this->directories as $key => $information )
  404.        {
  405.           // Generate tar header for this directory
  406.           // Filename, Permissions, UID, GID, size, Time, checksum, typeflag,
  407.           // linkname, magic, version, user name, group name, devmajor,
  408.           // devminor, prefix, end
  409.           $header  = str_pad( $information["name"], 100, chr(0) );
  410.           $header .= str_pad(
  411.                          decoct( $information["mode"] ),
  412.                          7, "0", STR_PAD_LEFT
  413.                             ).chr(0);
  414.           $header .= str_pad(
  415.                          decoct( $information["user_id"] ),
  416.                          7, "0", STR_PAD_LEFT
  417.                             ).chr(0);
  418.           $header .= str_pad(
  419.                          decoct( $information["group_id"] ),
  420.                          7, "0", STR_PAD_LEFT
  421.                             ).chr(0);
  422.           $header .= str_pad( decoct(0), 11, "0", STR_PAD_LEFT ).chr(0);
  423.           $header .= str_pad(
  424.                          decoct( $information["time"] ),
  425.                          11, "0", STR_PAD_LEFT
  426.                             ).chr(0);
  427.           $header .= str_repeat( " ", 8 );
  428.           $header .= "5";
  429.           $header .= str_repeat( chr(0), 100 );
  430.           $header .= str_pad( "ustar", 6, chr(32) );
  431.           $header .= chr(32).chr(0);
  432.           $header .= str_pad( "", 32, chr(0) );
  433.           $header .= str_pad( "", 32, chr(0) );
  434.           $header .= str_repeat( chr(0), 8 );
  435.           $header .= str_repeat( chr(0), 8 );
  436.           $header .= str_repeat( chr(0), 155 );
  437.           $header .= str_repeat( chr(0), 12 );
  438.           
  439.           // Compute header checksum
  440.           $checksum = str_pad(
  441.                           decoct( $this->__computeUnsignedChecksum( $header ) ),
  442.                           6, "0", STR_PAD_LEFT
  443.                              );
  444.           for ( $i = 0; $i < 6; $i++ )
  445.               $header[(148+$i)] = substr( $checksum, $i, 1 );
  446.           
  447.           $header[154] = chr(0);
  448.           $header[155] = chr(32);
  449.           
  450.           // Add new tar formatted data to tar file contents
  451.           $this->tar_file .= $header;
  452.        }
  453.        
  454.        // Generate Records for each file, if we have files (We should...)
  455.        if ( $this->numFiles > 0 )
  456.           foreach ( $this->files as $key => $information )
  457.           {
  458.             unset( $header );
  459.             
  460.             // Generate the TAR header for this file
  461.             // Filename, Permissions, UID, GID, size, Time, checksum, typeflag,
  462.             // linkname, magic, version, user name, group name, devmajor,
  463.             // devminor, prefix, end
  464.             $header .= str_pad( $information["name"], 100, chr(0) );
  465.             $header .= str_pad(
  466.                            decoct( $information["mode"] ),
  467.                            7, "0", STR_PAD_LEFT
  468.                               ).chr(0);
  469.             $header .= str_pad(
  470.                            decoct( $information["user_id"] ),
  471.                            7, "0", STR_PAD_LEFT
  472.                               ).chr(0);
  473.             $header .= str_pad(
  474.                            decoct( $information["group_id"] ),
  475.                            7, "0", STR_PAD_LEFT
  476.                               ).chr(0);
  477.             $header .= str_pad(
  478.                            decoct( $information["size"] ),
  479.                            11, "0", STR_PAD_LEFT
  480.                               ).chr(0);
  481.             $header .= str_pad(
  482.                            decoct( $information["time"] ),
  483.                            11, "0", STR_PAD_LEFT
  484.                               ).chr(0);
  485.             $header .= str_repeat( " ", 8 );
  486.             $header .= "0";
  487.             $header .= str_repeat( chr(0), 100 );
  488.             $header .= str_pad( "ustar", 6, chr(32) );
  489.             $header .= chr(32).chr(0);
  490.             // How do I get a file's user name from PHP?
  491.             $header .= str_pad( $information["user_name"], 32, chr(0) );
  492.             // How do I get a file's group name from PHP?
  493.             $header .= str_pad( $information["group_name"], 32, chr(0) );
  494.             $header .= str_repeat( chr(0), 8 );
  495.             $header .= str_repeat( chr(0), 8 );
  496.             $header .= str_repeat( chr(0), 155 );
  497.             $header .= str_repeat( chr(0), 12 );
  498.  
  499.             // Compute header checksum
  500.             $checksum = str_pad(
  501.                    decoct( $this->__computeUnsignedChecksum( $header ) ),
  502.                    6, "0", STR_PAD_LEFT
  503.                                );
  504.             
  505.             for ( $i = 0; $i < 6; $i++ )
  506.                 $header[(148+$i)] = substr( $checksum, $i, 1 );
  507.             
  508.             $header[154] = chr(0);
  509.             $header[155] = chr(32);
  510.             
  511.             // Pad file contents to byte count divisible by 512
  512.             $file_contents = str_pad(
  513.                                   $information["file"],
  514.                                   (ceil($information["size"]/512) * 512),
  515.                                   chr(0)
  516.                                     );
  517.             
  518.             // Add new tar formatted data to tar file contents
  519.             $this->tar_file .= $header.$file_contents;
  520.           }
  521.         
  522.         // Add 512 bytes of NULLs to designate EOF
  523.         $this->tar_file .= str_repeat( chr(0), 512 );
  524.         
  525.         return true;
  526.   }
  527.  
  528.  
  529.  
  530.   /**
  531.    * Computes the unsigned Checksum of a file's header to try to ensure valid
  532.    * file.
  533.    *
  534.    * @version 1.0
  535.    * @author  Josh Barger <joshb@npt.com>
  536.    * @access  public
  537.    * @param   string  $filename 
  538.    * @return  boolean 
  539.    */
  540.   function openTAR( $filename )
  541.   {
  542.     // Clear any values from previous tar archives
  543.     unset( $this->filename );
  544.     unset( $this->isGzipped );
  545.     unset( $this->tar_file );
  546.     unset( $this->files );
  547.     unset( $this->directories );
  548.     unset( $this->numFiles );
  549.     unset( $this->numDirectories );
  550.     
  551.     // If the tar file doesn't exist...
  552.     if ( !file_exists( $filename ) )
  553.        return false;
  554.     
  555.     $this->filename = $filename;
  556.     
  557.     // Parse this file
  558.     $this->__readTar();
  559.     
  560.     return true;
  561.   }
  562.  
  563.  
  564.  
  565.   /**
  566.    * Appends a tar file to the end of the currently opened tar file.
  567.    *
  568.    * @version 1.0
  569.    * @author  Josh Barger <joshb@npt.com>
  570.    * @access  public
  571.    * @param   string  $filename 
  572.    * @return  boolean 
  573.    */
  574.   function appendTar( $filename )
  575.   {
  576.     // If the tar file doesn't exist...
  577.     if( !file_exists( $filename ) )
  578.       return false;
  579.     
  580.     $this->__readTar( $filename );
  581.     
  582.     return true;
  583.   }
  584.  
  585.  
  586.  
  587.   /**
  588.    * Retrieves information about a file in the current tar archive.
  589.    *
  590.    * @version 1.0
  591.    * @author  Josh Barger <joshb@npt.com>
  592.    * @access  public
  593.    * @param   string  $filename 
  594.    * @return  boolean 
  595.    */
  596.   function getFile( $filename )
  597.   {
  598.     if ( $this->numFiles > 0 )
  599.        foreach ( $this->files as $key => $information )
  600.          if ( $information["name"] == $filename )
  601.             return $information;
  602.  
  603.     return false;
  604.   }
  605.  
  606.  
  607.  
  608.   /**
  609.    * Retrieves information about a directory in the current tar archive.
  610.    *
  611.    * @version 1.0
  612.    * @author  Josh Barger <joshb@npt.com>
  613.    * @access  public
  614.    * @param   string  $dirname 
  615.    * @return  boolean 
  616.    */
  617.   function getDirectory( $dirname )
  618.   {
  619.     if ( $this->numDirectories > 0 )
  620.        foreach ( $this->directories as $key => $information )
  621.          if ( $information["name"] == $dirname )
  622.             return $information;
  623.     
  624.       return false;
  625.   }
  626.  
  627.  
  628.  
  629.   /**
  630.    * Check if this tar archive contains a specific file.
  631.    *
  632.    * @version 1.0
  633.    * @author  Josh Barger <joshb@npt.com>
  634.    * @access  public
  635.    * @param   string  $filename 
  636.    * @return  boolean 
  637.    */
  638.   function containsFile( $filename )
  639.   {
  640.     if ( $this->numFiles > 0 )
  641.        foreach ( $this->files as $key => $information ) 
  642.          if ( $information["name"] == $filename )
  643.             return true;
  644.     
  645.     return false;
  646.   }
  647.  
  648.  
  649.  
  650.   /**
  651.    * Check if this tar archive contains a specific directory.
  652.    *
  653.    * @version 1.0
  654.    * @author  Josh Barger <joshb@npt.com>
  655.    * @access  public
  656.    * @param   string  $dirname 
  657.    * @return  boolean 
  658.    */
  659.   function containsDirectory( $dirname )
  660.   {
  661.     if ( $this->numDirectories > 0 )
  662.        foreach ( $this->directories as $key => $information )
  663.          if ( $information["name"] == $dirname )
  664.             return true;
  665.     
  666.     return false;
  667.   }
  668.  
  669.  
  670.  
  671.   /**
  672.    * Check if this tar archive contains a specific directory.
  673.    *
  674.    * @version 1.0
  675.    * @author  Josh Barger <joshb@npt.com>
  676.    * @author  Daniel Plücken <daniel@debakel.net> (only FTP-Functionality)
  677.    * @access  public
  678.    * @param   string  $dirname 
  679.    * @param   boolean $recursive 
  680.    * @return  boolean 
  681.    */
  682.   function addDirectory( $dirname, $recursive = true )
  683.   {
  684.     if (
  685.          !function_exists( "is_a" )
  686.       && get_class( $this->ftp ) == "ftphost"
  687.       || function_exists( "is_a" )
  688.       && is_a( $this->ftp, "FTPHost" )
  689.        )
  690.     {
  691.        $d_mem = $dirname;
  692.        if ( strpos( $dirname, "/" ) === 0 )
  693.           $dirname = substr( $dirname, 1 );
  694.        
  695.        if ( !$this->ftp->is_dir( $dirname, false ) )
  696.        {
  697.           $this->ftp->disconnect();
  698.           return false;
  699.        }
  700.        
  701.        // Add directory to processed data
  702.        $this->numDirectories++;
  703.        $activeDir = &$this->directories[];
  704.        
  705.        $file_information["mode"] = "16895";
  706.        
  707.        if ( $recursive )
  708.        {
  709.           $res_arr = $this->ftp->loadFolderContent(
  710.                                  $d_mem, "", "", false, "name", false
  711.                                                   );
  712.           
  713.           Arrays::sortSecondDimension( $res_arr, "is_dir", "boolcmp_desc" );
  714.           
  715.           foreach ( $res_arr as $tmp )
  716.           {
  717.             // echo $d_mem."/".$tmp["name"]."<br />";
  718.             if ( $this->ftp->is_dir( $d_mem."/".$tmp["name"], false ) )
  719.                $this->addDirectory( $d_mem."/".$tmp["name"] );
  720.             else
  721.             if ( $this->ftp->is_file( $d_mem."/".$tmp["name"], false ) )
  722.                $this->addFile( $d_mem."/".$tmp["name"], false );
  723.           }
  724.        }
  725.     }
  726.     else
  727.     {
  728.        if ( !is_dir( $dirname ) )
  729.           return false;
  730.        
  731.        
  732.        // Add directory to processed data
  733.        $this->numDirectories++;
  734.        $activeDir = &$this->directories[];
  735.        
  736.        // Get directory information
  737.        $file_information = stat( $dirname );
  738.     }
  739.     
  740.     $activeDir["name"]     = $dirname;
  741.     $activeDir["mode"]     = $file_information["mode"];
  742.     $activeDir["time"]     = $file_information["time"];
  743.     $activeDir["user_id"]  = $file_information["uid"];
  744.     $activeDir["group_id"] = $file_information["gid"];
  745.     // $activeDir["checksum"]    = $checksum;
  746.  
  747.     return true;
  748.   }
  749.  
  750.  
  751.  
  752.   /**
  753.    * Add a file to the tar archive.
  754.    *
  755.    * @version 1.0
  756.    * @author  Josh Barger <joshb@npt.com>
  757.    * @access  public
  758.    * @param   string  $dirname 
  759.    * @param   boolean $ftp_disconnect 
  760.    * @return  boolean 
  761.    */
  762.   function addFile( $filename, $ftp_disconnect = true )
  763.   {
  764.     // Make sure there are no other files in the archive that have this same
  765.     // filename
  766.     if ( $this->containsFile( $filename ) )
  767.        return false;
  768.     
  769.     if (
  770.          !function_exists( "is_a" )
  771.       && get_class( $this->ftp ) == "ftphost"
  772.       || function_exists( "is_a" )
  773.       && is_a( $this->ftp, "FTPHost" )
  774.        )
  775.     {
  776.        $f_mem = $filename;
  777.        if ( strpos( $filename, "/" ) === 0 )
  778.           $filename = substr( $filename, 1 );
  779.        
  780.        // Make sure the file we are adding exists!
  781.        if ( !$this->ftp->is_file( $filename, false ) )
  782.        {
  783.           $this->ftp->disconnect();
  784.           return false;
  785.        }
  786.        
  787.        // Read in the file's contents
  788.        $file_contents = $this->ftp->loadFileContent(
  789.                                                 $f_mem,
  790.                                                 $ftp_disconnect
  791.                                                    );
  792.        
  793.        $file_information["mode"] = "33279";
  794.        $file_information["size"] = strlen( $file_contents );
  795.     }
  796.     else
  797.     {
  798.        // Make sure the file we are adding exists!
  799.        if ( !file_exists( $filename ) )
  800.           return false;
  801.        
  802.        // Get file information
  803.        $file_information = stat( $filename );
  804.        
  805.        // Read in the file's contents
  806.        $fp = fopen( $filename, "rb" );
  807.        $file_contents = fread( $fp, filesize( $filename ) );
  808.        fclose( $fp );
  809.     }
  810.     
  811.     // Add file to processed data
  812.     $this->numFiles++;
  813.     $activeFile               = &$this->files[];
  814.     $activeFile["name"]       = $filename;
  815.     $activeFile["mode"]       = $file_information["mode"];
  816.     $activeFile["user_id"]    = $file_information["uid"];
  817.     $activeFile["group_id"]   = $file_information["gid"];
  818.     $activeFile["size"]       = $file_information["size"];
  819.     $activeFile["time"]       = $file_information["mtime"];
  820.     // $activeFile["checksum"]        = $checksum;
  821.     $activeFile["user_name"]  = "";
  822.     $activeFile["group_name"] = "";
  823.     $activeFile["file"]       = $file_contents;
  824.     
  825.     return true;
  826.   }
  827.  
  828.  
  829.  
  830.   /**
  831.    * Remove a file from the tar archive.
  832.    *
  833.    * @version 1.0
  834.    * @author  Josh Barger <joshb@npt.com>
  835.    * @access  public
  836.    * @param   string  $dirname 
  837.    * @return  boolean 
  838.    */
  839.   function removeFile( $filename )
  840.   {
  841.     if ( $this->numFiles > 0 )
  842.        foreach ( $this->files as $key => $information ) 
  843.          if ( $information["name"] == $filename )
  844.          {
  845.             $this->numFiles--;
  846.             unset( $this->files[$key] );
  847.             return true;
  848.          }
  849.     
  850.     return false;
  851.   }
  852.  
  853.  
  854.  
  855.   /**
  856.    * Remove a directory from the tar archive.
  857.    *
  858.    * @version 1.0
  859.    * @author  Josh Barger <joshb@npt.com>
  860.    * @access  public
  861.    * @return  boolean 
  862.    */
  863.   function removeDirectory( $dirname )
  864.   {
  865.     if ( $this->numDirectories > 0 )
  866.        foreach ( $this->directories as $key => $information )
  867.          if ( $information["name"] == $dirname )
  868.          {
  869.             $this->numDirectories--;
  870.             unset($this->directories[$key]);
  871.             return true;
  872.          }
  873.      
  874.     return false;
  875.   }
  876.  
  877.  
  878.  
  879.   /**
  880.    * Write the currently loaded tar archive to disk or to a ftp ressource
  881.    * if the attribute ftp is a FTPHost-Object.
  882.    *
  883.    * @version 1.0
  884.    * @author  Josh Barger <joshb@npt.com>
  885.    * @author  Daniel Plücken <daniel@debakel.net> (only FTP-Functionality)
  886.    * @access  public
  887.    * @return  boolean 
  888.    */
  889.   function saveTar()
  890.   {
  891.     if ( !$this->filename )
  892.       return false;
  893.   
  894.     // Write tar to current file using specified gzip compression
  895.     $this->toTar( $this->filename, $this->isGzipped );
  896.   
  897.     return true;
  898.   }
  899.  
  900.  
  901.  
  902.   /**
  903.    * Saves tar archive to a different file than the current file.
  904.    *
  905.    * @version 1.0
  906.    * @author  Josh Barger <joshb@npt.com>
  907.    * @author  Daniel Plücken <daniel@debakel.net> (only FTP-Functionality)
  908.    * @access  public
  909.    * @param   string  $filename 
  910.    * @param   boolean $useGzip 
  911.    * @return  boolean 
  912.    */
  913.   function toTar( $filename, $useGzip )
  914.   {
  915.     if( !$filename )
  916.       return false;
  917.   
  918.     // Encode processed files into TAR file format
  919.     $this->__generateTar();
  920.     
  921.     // GZ Compress the data if we need to
  922.     if ( !$useGzip )
  923.        $file = $this->tar_file;
  924.     else
  925.     {
  926.        // Make sure we have gzip support
  927.        if ( !function_exists( "gzencode" ) )
  928.           return false;
  929.        
  930.        $file = gzencode( $this->tar_file );
  931.     }
  932.     
  933.     
  934.     if (
  935.          !function_exists( "is_a" )
  936.       && get_class( $this->ftp ) == "ftphost"
  937.       || function_exists( "is_a" )
  938.       && is_a( $this->ftp, "FTPHost" )
  939.        )
  940.        $this->ftp->saveFile( $filename, $file );
  941.     else
  942.     {
  943.        // Write the TAR file
  944.        $fp = fopen( $filename, "wb" );
  945.        fwrite( $fp, $file );
  946.        fclose( $fp );
  947.     }
  948.   
  949.     return true;
  950.   }
  951. }
  952.  
  953. ?>

Documentation generated on Thu, 05 Jun 2008 19:15:26 +0200 by phpDocumentor 1.4.1