sorry, wrong version checked in
[phpmyadmin/arisferyanto.git] / libraries / unzip.lib.php
blobad3096b7436c65c363c1ac08ac8a1019cf5a0c39
1 <?PHP
2 /* $Id$ */
4 /**
5 * ZIP file unpack classes. Contributed to the phpMyAdmin project.
7 * @category phpPublic
8 * @package File-Formats-ZIP
9 * @subpackage Unzip
10 * @filesource unzip.lib.php
11 * @version 1.0.1
13 * @author Holger Boskugel <vbwebprofi@gmx.de>
14 * @copyright Copyright © 2003, Holger Boskugel, Berlin, Germany
15 * @license http://opensource.org/licenses/gpl-license.php GNU Public License
17 * @history
18 * 2003-12-02 - HB : Patched : naming bug : Time/Size of file
19 * Added : ZIP file comment
20 * Added : Check BZIP2 support of PHP
21 * 2003-11-29 - HB * Initial version
24 /**
25 * Unzip class, which retrieves entries from ZIP files.
27 * Supports only the compression modes
28 * - 0 : Stored,
29 * - 8 : Deflated and
30 * - 12 : BZIP2
32 * Based on :<BR>
33 * <BR>
34 * {@link http://www.pkware.com/products/enterprise/white_papers/appnote.html
35 * * Official ZIP file format}<BR>
36 * {@link http://msdn.microsoft.com/library/en-us/w98ddk/hh/w98ddk/storage_5l4m.asp
37 * * Microsoft DOS date/time format}
39 * @category phpPublic
40 * @package File-Formats-ZIP
41 * @subpackage Unzip
42 * @version 1.0.1
43 * @author Holger Boskugel <vbwebprofi@gmx.de>
44 * @uses SimpleUnzipEntry
45 * @example example.unzip.php Two examples
47 class SimpleUnzip {
48 // 2003-12-02 - HB >
49 /**
50 * Array to store file entries
52 * @var string
53 * @access public
54 * @see ReadFile()
55 * @since 1.0.1
57 var $Comment = '';
58 // 2003-12-02 - HB <
60 /**
61 * Array to store file entries
63 * @var array
64 * @access public
65 * @see ReadFile()
66 * @since 1.0
68 var $Entries = array();
70 /**
71 * Name of the ZIP file
73 * @var string
74 * @access public
75 * @see ReadFile()
76 * @since 1.0
78 var $Name = '';
80 /**
81 * Size of the ZIP file
83 * @var integer
84 * @access public
85 * @see ReadFile()
86 * @since 1.0
88 var $Size = 0;
90 /**
91 * Time of the ZIP file (unix timestamp)
93 * @var integer
94 * @access public
95 * @see ReadFile()
96 * @since 1.0
98 var $Time = 0;
101 * Contructor of the class
103 * @param string File name
104 * @return SimpleUnzip Instanced class
105 * @access public
106 * @uses SimpleUnzip::ReadFile() Opens file on new if specified
107 * @since 1.0
109 function SimpleUnzip($in_FileName = '') {
110 if($in_FileName !== '') {
111 SimpleUnzip::ReadFile($in_FileName);
113 } // end of the 'SimpleUnzip' constructor
116 * Counts the entries
118 * @return integer Count of ZIP entries
119 * @access public
120 * @uses $Entries
121 * @since 1.0
123 function Count() {
124 return count($this->Entries);
125 } // end of the 'Count()' method
128 * Gets data of the specified ZIP entry
130 * @param integer Index of the ZIP entry
131 * @return mixed Data for the ZIP entry
132 * @uses SimpleUnzipEntry::$Data
133 * @access public
134 * @since 1.0
136 function GetData($in_Index) {
137 return $this->Entries[$in_Index]->Data;
138 } // end of the 'GetData()' method
141 * Gets an entry of the ZIP file
143 * @param integer Index of the ZIP entry
144 * @return SimpleUnzipEntry Entry of the ZIP file
145 * @uses $Entries
146 * @access public
147 * @since 1.0
149 function GetEntry($in_Index) {
150 return $this->Entries[$in_Index];
151 } // end of the 'GetEntry()' method
154 * Gets error code for the specified ZIP entry
156 * @param integer Index of the ZIP entry
157 * @return integer Error code for the ZIP entry
158 * @uses SimpleUnzipEntry::$Error
159 * @access public
160 * @since 1.0
162 function GetError($in_Index) {
163 return $this->Entries[$in_Index]->Error;
164 } // end of the 'GetError()' method
167 * Gets error message for the specified ZIP entry
169 * @param integer Index of the ZIP entry
170 * @return string Error message for the ZIP entry
171 * @uses SimpleUnzipEntry::$ErrorMsg
172 * @access public
173 * @since 1.0
175 function GetErrorMsg($in_Index) {
176 return $this->Entries[$in_Index]->ErrorMsg;
177 } // end of the 'GetErrorMsg()' method
180 * Gets file name for the specified ZIP entry
182 * @param integer Index of the ZIP entry
183 * @return string File name for the ZIP entry
184 * @uses SimpleUnzipEntry::$Name
185 * @access public
186 * @since 1.0
188 function GetName($in_Index) {
189 return $this->Entries[$in_Index]->Name;
190 } // end of the 'GetName()' method
193 * Gets path of the file for the specified ZIP entry
195 * @param integer Index of the ZIP entry
196 * @return string Path of the file for the ZIP entry
197 * @uses SimpleUnzipEntry::$Path
198 * @access public
199 * @since 1.0
201 function GetPath($in_Index) {
202 return $this->Entries[$in_Index]->Path;
203 } // end of the 'GetPath()' method
206 * Gets file time for the specified ZIP entry
208 * @param integer Index of the ZIP entry
209 * @return integer File time for the ZIP entry (unix timestamp)
210 * @uses SimpleUnzipEntry::$Time
211 * @access public
212 * @since 1.0
214 function GetTime($in_Index) {
215 return $this->Entries[$in_Index]->Time;
216 } // end of the 'GetTime()' method
219 * Reads ZIP file and extracts the entries
221 * @param string File name of the ZIP archive
222 * @return array ZIP entry list (see also class variable {@link $Entries $Entries})
223 * @uses SimpleUnzipEntry For the entries
224 * @access public
225 * @since 1.0
227 function ReadFile($in_FileName) {
228 $this->Entries = array();
230 // Get file parameters
231 $this->Name = $in_FileName;
232 $this->Time = filemtime($in_FileName);
233 $this->Size = filesize($in_FileName);
235 // Read file
236 $oF = fopen($in_FileName, 'rb');
237 $vZ = fread($oF, $this->Size);
238 fclose($oF);
240 // 2003-12-02 - HB >
241 // Cut end of central directory
242 $aE = explode("\x50\x4b\x05\x06", $vZ);
244 // Easiest way, but not sure if format changes
245 //$this->Comment = substr($aE[1], 18);
247 // Normal way
248 $aP = unpack('x16/v1CL', $aE[1]);
249 $this->Comment = substr($aE[1], 18, $aP['CL']);
251 // Translates end of line from other operating systems
252 $this->Comment = strtr($this->Comment, array("\r\n" => "\n",
253 "\r" => "\n"));
254 // 2003-12-02 - HB <
256 // Cut the entries from the central directory
257 $aE = explode("\x50\x4b\x01\x02", $vZ);
258 // Explode to each part
259 $aE = explode("\x50\x4b\x03\x04", $aE[0]);
260 // Shift out spanning signature or empty entry
261 array_shift($aE);
263 // Loop through the entries
264 foreach($aE as $vZ) {
265 $aI = array();
266 $aI['E'] = 0;
267 $aI['EM'] = '';
268 // Retrieving local file header information
269 $aP = unpack('v1VN/v1GPF/v1CM/v1FT/v1FD/V1CRC/V1CS/V1UCS/v1FNL', $vZ);
270 // Check if data is encrypted
271 $bE = ($aP['GPF'] && 0x0001) ? TRUE : FALSE;
272 $nF = $aP['FNL'];
274 // Special case : value block after the compressed data
275 if($aP['GPF'] & 0x0008) {
276 $aP1 = unpack('V1CRC/V1CS/V1UCS', substr($vZ, -12));
278 $aP['CRC'] = $aP1['CRC'];
279 $aP['CS'] = $aP1['CS'];
280 $aP['UCS'] = $aP1['UCS'];
282 $vZ = substr($vZ, 0, -12);
285 // Getting stored filename
286 $aI['N'] = substr($vZ, 26, $nF);
288 if(substr($aI['N'], -1) == '/') {
289 // is a directory entry - will be skipped
290 continue;
293 // Truncate full filename in path and filename
294 $aI['P'] = dirname($aI['N']);
295 $aI['P'] = $aI['P'] == '.' ? '' : $aI['P'];
296 $aI['N'] = basename($aI['N']);
298 $vZ = substr($vZ, 26 + $nF);
300 if(strlen($vZ) != $aP['CS']) {
301 $aI['E'] = 1;
302 $aI['EM'] = 'Compressed size is not equal with the value in header information.';
304 else {
305 if($bE) {
306 $aI['E'] = 5;
307 $aI['EM'] = 'File is encrypted, which is not supported from this class.';
309 else {
310 switch($aP['CM']) {
311 case 0: // Stored
312 // Here is nothing to do, the file ist flat.
313 break;
315 case 8: // Deflated
316 $vZ = gzinflate($vZ);
317 break;
319 case 12: // BZIP2
320 // 2003-12-02 - HB >
321 if(! extension_loaded('bz2')) {
322 if(strtoupper(substr(PHP_OS, 0, 3)) == 'WIN') {
323 @dl('php_bz2.dll');
325 else {
326 @dl('bz2.so');
330 if(extension_loaded('bz2')) {
331 // 2003-12-02 - HB <
332 $vZ = bzdecompress($vZ);
333 // 2003-12-02 - HB >
335 else {
336 $aI['E'] = 7;
337 $aI['EM'] = "PHP BZIP2 extension not available.";
339 // 2003-12-02 - HB <
341 break;
343 default:
344 $aI['E'] = 6;
345 $aI['EM'] = "De-/Compression method {$aP['CM']} is not supported.";
348 // 2003-12-02 - HB >
349 if(! $aI['E']) {
350 // 2003-12-02 - HB <
351 if($vZ === FALSE) {
352 $aI['E'] = 2;
353 $aI['EM'] = 'Decompression of data failed.';
355 else {
356 if(strlen($vZ) != $aP['UCS']) {
357 $aI['E'] = 3;
358 $aI['EM'] = 'Uncompressed size is not equal with the value in header information.';
360 else {
361 if(crc32($vZ) != $aP['CRC']) {
362 $aI['E'] = 4;
363 $aI['EM'] = 'CRC32 checksum is not equal with the value in header information.';
367 // 2003-12-02 - HB >
369 // 2003-12-02 - HB <
373 $aI['D'] = $vZ;
375 // DOS to UNIX timestamp
376 $aI['T'] = mktime(($aP['FT'] & 0xf800) >> 11,
377 ($aP['FT'] & 0x07e0) >> 5,
378 ($aP['FT'] & 0x001f) << 1,
379 ($aP['FD'] & 0x01e0) >> 5,
380 ($aP['FD'] & 0x001f),
381 (($aP['FD'] & 0xfe00) >> 9) + 1980);
383 $this->Entries[] = &new SimpleUnzipEntry($aI);
384 } // end for each entries
386 return $this->Entries;
387 } // end of the 'ReadFile()' method
388 } // end of the 'SimpleUnzip' class
391 * Entry of the ZIP file.
393 * @category phpPublic
394 * @package File-Formats-ZIP
395 * @subpackage Unzip
396 * @version 1.0
397 * @author Holger Boskugel <vbwebprofi@gmx.de>
398 * @example example.unzip.php Two examples
400 class SimpleUnzipEntry {
402 * Data of the file entry
404 * @var mixed
405 * @access public
406 * @see SimpleUnzipEntry()
407 * @since 1.0
409 var $Data = '';
412 * Error of the file entry
414 * - 0 : No error raised.<BR>
415 * - 1 : Compressed size is not equal with the value in header information.<BR>
416 * - 2 : Decompression of data failed.<BR>
417 * - 3 : Uncompressed size is not equal with the value in header information.<BR>
418 * - 4 : CRC32 checksum is not equal with the value in header information.<BR>
419 * - 5 : File is encrypted, which is not supported from this class.<BR>
420 * - 6 : De-/Compression method ... is not supported.<BR>
421 * - 7 : PHP BZIP2 extension not available.
423 * @var integer
424 * @access public
425 * @see SimpleUnzipEntry()
426 * @since 1.0
428 var $Error = 0;
431 * Error message of the file entry
433 * @var string
434 * @access public
435 * @see SimpleUnzipEntry()
436 * @since 1.0
438 var $ErrorMsg = '';
441 * File name of the file entry
443 * @var string
444 * @access public
445 * @see SimpleUnzipEntry()
446 * @since 1.0
448 var $Name = '';
451 * File path of the file entry
453 * @var string
454 * @access public
455 * @see SimpleUnzipEntry()
456 * @since 1.0
458 var $Path = '';
461 * File time of the file entry (unix timestamp)
463 * @var integer
464 * @access public
465 * @see SimpleUnzipEntry()
466 * @since 1.0
468 var $Time = 0;
471 * Contructor of the class
473 * @param array Entry datas
474 * @return SimpleUnzipEntry Instanced class
475 * @access public
476 * @since 1.0
478 function SimpleUnzipEntry($in_Entry) {
479 $this->Data = $in_Entry['D'];
480 $this->Error = $in_Entry['E'];
481 $this->ErrorMsg = $in_Entry['EM'];
482 $this->Name = $in_Entry['N'];
483 $this->Path = $in_Entry['P'];
484 $this->Time = $in_Entry['T'];
485 } // end of the 'SimpleUnzipEntry' constructor
486 } // end of the 'SimpleUnzipEntry' class