diff --git a/htdocs/sql/libraries/unzip.lib.php b/htdocs/sql/libraries/unzip.lib.php new file mode 100755 --- /dev/null +++ b/htdocs/sql/libraries/unzip.lib.php @@ -0,0 +1,493 @@ + + * @copyright Copyright © 2003, Holger Boskugel, Berlin, Germany + * @license http://opensource.org/licenses/gpl-license.php GNU Public License + * + * @history + * 2003-12-02 - HB : Patched : naming bug : Time/Size of file + * Added : ZIP file comment + * Added : Check BZIP2 support of PHP + * 2003-11-29 - HB * Initial version + */ + + /** + * Unzip class, which retrieves entries from ZIP files. + * + * Supports only the compression modes + * - 0 : Stored, + * - 8 : Deflated and + * - 12 : BZIP2 + * + * Based on :
+ *
+ * {@link http://www.pkware.com/products/enterprise/white_papers/appnote.html + * * Official ZIP file format}
+ * {@link http://msdn.microsoft.com/library/en-us/w98ddk/hh/w98ddk/storage_5l4m.asp + * * Microsoft DOS date/time format} + * + * @category phpPublic + * @package File-Formats-ZIP + * @subpackage Unzip + * @version 1.0.1 + * @author Holger Boskugel + * @uses SimpleUnzipEntry + * @example example.unzip.php Two examples + */ + class SimpleUnzip { +// 2003-12-02 - HB > + /** + * Array to store file entries + * + * @var string + * @access public + * @see ReadFile() + * @since 1.0.1 + */ + var $Comment = ''; +// 2003-12-02 - HB < + + /** + * Array to store file entries + * + * @var array + * @access public + * @see ReadFile() + * @since 1.0 + */ + var $Entries = array(); + + /** + * Name of the ZIP file + * + * @var string + * @access public + * @see ReadFile() + * @since 1.0 + */ + var $Name = ''; + + /** + * Size of the ZIP file + * + * @var integer + * @access public + * @see ReadFile() + * @since 1.0 + */ + var $Size = 0; + + /** + * Time of the ZIP file (unix timestamp) + * + * @var integer + * @access public + * @see ReadFile() + * @since 1.0 + */ + var $Time = 0; + + /** + * Contructor of the class + * + * @param string File name + * @return SimpleUnzip Instanced class + * @access public + * @uses SimpleUnzip::ReadFile() Opens file on new if specified + * @since 1.0 + */ + function SimpleUnzip($in_FileName = '') + { + if ($in_FileName !== '') { + SimpleUnzip::ReadFile($in_FileName); + } + } // end of the 'SimpleUnzip' constructor + + /** + * Counts the entries + * + * @return integer Count of ZIP entries + * @access public + * @uses $Entries + * @since 1.0 + */ + function Count() + { + return count($this->Entries); + } // end of the 'Count()' method + + /** + * Gets data of the specified ZIP entry + * + * @param integer Index of the ZIP entry + * @return mixed Data for the ZIP entry + * @uses SimpleUnzipEntry::$Data + * @access public + * @since 1.0 + */ + function GetData($in_Index) + { + return $this->Entries[$in_Index]->Data; + } // end of the 'GetData()' method + + /** + * Gets an entry of the ZIP file + * + * @param integer Index of the ZIP entry + * @return SimpleUnzipEntry Entry of the ZIP file + * @uses $Entries + * @access public + * @since 1.0 + */ + function GetEntry($in_Index) + { + return $this->Entries[$in_Index]; + } // end of the 'GetEntry()' method + + /** + * Gets error code for the specified ZIP entry + * + * @param integer Index of the ZIP entry + * @return integer Error code for the ZIP entry + * @uses SimpleUnzipEntry::$Error + * @access public + * @since 1.0 + */ + function GetError($in_Index) + { + return $this->Entries[$in_Index]->Error; + } // end of the 'GetError()' method + + /** + * Gets error message for the specified ZIP entry + * + * @param integer Index of the ZIP entry + * @return string Error message for the ZIP entry + * @uses SimpleUnzipEntry::$ErrorMsg + * @access public + * @since 1.0 + */ + function GetErrorMsg($in_Index) + { + return $this->Entries[$in_Index]->ErrorMsg; + } // end of the 'GetErrorMsg()' method + + /** + * Gets file name for the specified ZIP entry + * + * @param integer Index of the ZIP entry + * @return string File name for the ZIP entry + * @uses SimpleUnzipEntry::$Name + * @access public + * @since 1.0 + */ + function GetName($in_Index) + { + return $this->Entries[$in_Index]->Name; + } // end of the 'GetName()' method + + /** + * Gets path of the file for the specified ZIP entry + * + * @param integer Index of the ZIP entry + * @return string Path of the file for the ZIP entry + * @uses SimpleUnzipEntry::$Path + * @access public + * @since 1.0 + */ + function GetPath($in_Index) + { + return $this->Entries[$in_Index]->Path; + } // end of the 'GetPath()' method + + /** + * Gets file time for the specified ZIP entry + * + * @param integer Index of the ZIP entry + * @return integer File time for the ZIP entry (unix timestamp) + * @uses SimpleUnzipEntry::$Time + * @access public + * @since 1.0 + */ + function GetTime($in_Index) + { + return $this->Entries[$in_Index]->Time; + } // end of the 'GetTime()' method + + /** + * Reads ZIP file and extracts the entries + * + * @param string File name of the ZIP archive + * @return array ZIP entry list (see also class variable {@link $Entries $Entries}) + * @uses SimpleUnzipEntry For the entries + * @access public + * @since 1.0 + */ + function ReadFile($in_FileName) + { + $this->Entries = array(); + + // Get file parameters + $this->Name = $in_FileName; + $this->Time = filemtime($in_FileName); + $this->Size = filesize($in_FileName); + + // Read file + $oF = fopen($in_FileName, 'rb'); + $vZ = fread($oF, $this->Size); + fclose($oF); + +// 2003-12-02 - HB > + // Cut end of central directory + $aE = explode("\x50\x4b\x05\x06", $vZ); + + // Easiest way, but not sure if format changes + //$this->Comment = substr($aE[1], 18); + + // Normal way + $aP = unpack('x16/v1CL', $aE[1]); + $this->Comment = substr($aE[1], 18, $aP['CL']); + + // Translates end of line from other operating systems + $this->Comment = strtr($this->Comment, array("\r\n" => "\n", + "\r" => "\n")); +// 2003-12-02 - HB < + + // Cut the entries from the central directory + $aE = explode("\x50\x4b\x01\x02", $vZ); + // Explode to each part + $aE = explode("\x50\x4b\x03\x04", $aE[0]); + // Shift out spanning signature or empty entry + array_shift($aE); + + // Loop through the entries + foreach ($aE as $vZ) { + $aI = array(); + $aI['E'] = 0; + $aI['EM'] = ''; + // Retrieving local file header information + $aP = unpack('v1VN/v1GPF/v1CM/v1FT/v1FD/V1CRC/V1CS/V1UCS/v1FNL', $vZ); + // Check if data is encrypted + $bE = ($aP['GPF'] & 0x0001) ? TRUE : FALSE; + $nF = $aP['FNL']; + + // Special case : value block after the compressed data + if ($aP['GPF'] & 0x0008) { + $aP1 = unpack('V1CRC/V1CS/V1UCS', substr($vZ, -12)); + + $aP['CRC'] = $aP1['CRC']; + $aP['CS'] = $aP1['CS']; + $aP['UCS'] = $aP1['UCS']; + + $vZ = substr($vZ, 0, -12); + } + + // Getting stored filename + $aI['N'] = substr($vZ, 26, $nF); + + if (substr($aI['N'], -1) == '/') { + // is a directory entry - will be skipped + continue; + } + + // Truncate full filename in path and filename + $aI['P'] = dirname($aI['N']); + $aI['P'] = $aI['P'] == '.' ? '' : $aI['P']; + $aI['N'] = basename($aI['N']); + + $vZ = substr($vZ, 26 + $nF); + + if (strlen($vZ) != $aP['CS']) { + $aI['E'] = 1; + $aI['EM'] = 'Compressed size is not equal with the value in header information.'; + } else { + if ($bE) { + $aI['E'] = 5; + $aI['EM'] = 'File is encrypted, which is not supported from this class.'; + } else { + switch($aP['CM']) { + case 0: // Stored + // Here is nothing to do, the file ist flat. + break; + + case 8: // Deflated + $vZ = gzinflate($vZ); + break; + + case 12: // BZIP2 +// 2003-12-02 - HB > + if (! extension_loaded('bz2')) { + if (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN') { + @dl('php_bz2.dll'); + } else { + @dl('bz2.so'); + } + } + + if (extension_loaded('bz2')) { +// 2003-12-02 - HB < + $vZ = bzdecompress($vZ); +// 2003-12-02 - HB > + } else { + $aI['E'] = 7; + $aI['EM'] = "PHP BZIP2 extension not available."; + } +// 2003-12-02 - HB < + + break; + + default: + $aI['E'] = 6; + $aI['EM'] = "De-/Compression method {$aP['CM']} is not supported."; + } + +// 2003-12-02 - HB > + if (! $aI['E']) { +// 2003-12-02 - HB < + if ($vZ === FALSE) { + $aI['E'] = 2; + $aI['EM'] = 'Decompression of data failed.'; + } else { + if (strlen($vZ) != $aP['UCS']) { + $aI['E'] = 3; + $aI['EM'] = 'Uncompressed size is not equal with the value in header information.'; + } else { + if (crc32($vZ) != $aP['CRC']) { + $aI['E'] = 4; + $aI['EM'] = 'CRC32 checksum is not equal with the value in header information.'; + } + } + } +// 2003-12-02 - HB > + } +// 2003-12-02 - HB < + } + } + + $aI['D'] = $vZ; + + // DOS to UNIX timestamp + $aI['T'] = mktime(($aP['FT'] & 0xf800) >> 11, + ($aP['FT'] & 0x07e0) >> 5, + ($aP['FT'] & 0x001f) << 1, + ($aP['FD'] & 0x01e0) >> 5, + ($aP['FD'] & 0x001f), + (($aP['FD'] & 0xfe00) >> 9) + 1980); + + $this->Entries[] = &new SimpleUnzipEntry($aI); + } // end for each entries + + return $this->Entries; + } // end of the 'ReadFile()' method + } // end of the 'SimpleUnzip' class + + /** + * Entry of the ZIP file. + * + * @category phpPublic + * @package File-Formats-ZIP + * @subpackage Unzip + * @version 1.0 + * @author Holger Boskugel + * @example example.unzip.php Two examples + */ + class SimpleUnzipEntry { + /** + * Data of the file entry + * + * @var mixed + * @access public + * @see SimpleUnzipEntry() + * @since 1.0 + */ + var $Data = ''; + + /** + * Error of the file entry + * + * - 0 : No error raised.
+ * - 1 : Compressed size is not equal with the value in header information.
+ * - 2 : Decompression of data failed.
+ * - 3 : Uncompressed size is not equal with the value in header information.
+ * - 4 : CRC32 checksum is not equal with the value in header information.
+ * - 5 : File is encrypted, which is not supported from this class.
+ * - 6 : De-/Compression method ... is not supported.
+ * - 7 : PHP BZIP2 extension not available. + * + * @var integer + * @access public + * @see SimpleUnzipEntry() + * @since 1.0 + */ + var $Error = 0; + + /** + * Error message of the file entry + * + * @var string + * @access public + * @see SimpleUnzipEntry() + * @since 1.0 + */ + var $ErrorMsg = ''; + + /** + * File name of the file entry + * + * @var string + * @access public + * @see SimpleUnzipEntry() + * @since 1.0 + */ + var $Name = ''; + + /** + * File path of the file entry + * + * @var string + * @access public + * @see SimpleUnzipEntry() + * @since 1.0 + */ + var $Path = ''; + + /** + * File time of the file entry (unix timestamp) + * + * @var integer + * @access public + * @see SimpleUnzipEntry() + * @since 1.0 + */ + var $Time = 0; + + /** + * Contructor of the class + * + * @param array Entry datas + * @return SimpleUnzipEntry Instanced class + * @access public + * @since 1.0 + */ + function SimpleUnzipEntry($in_Entry) + { + $this->Data = $in_Entry['D']; + $this->Error = $in_Entry['E']; + $this->ErrorMsg = $in_Entry['EM']; + $this->Name = $in_Entry['N']; + $this->Path = $in_Entry['P']; + $this->Time = $in_Entry['T']; + } // end of the 'SimpleUnzipEntry' constructor + } // end of the 'SimpleUnzipEntry' class +?>