| [ Index ] |
|
Code source de DokuWiki 2006-11-06 |
1 <?php 2 3 /** 4 * @author bouchon 5 * @link http://dev.maxg.info 6 * @link http://forum.maxg.info 7 * 8 * Modified for Dokuwiki 9 * @author Christopher Smith <chris@jalakai.co.uk> 10 */ 11 12 class zip 13 { 14 15 var $datasec, $ctrl_dir = array(); 16 var $eof_ctrl_dir = "\x50\x4b\x05\x06\x00\x00\x00\x00"; 17 var $old_offset = 0; var $dirs = Array("."); 18 19 function get_List($zip_name) 20 { 21 $zip = @fopen($zip_name, 'rb'); 22 if(!$zip) return(0); 23 $centd = $this->ReadCentralDir($zip,$zip_name); 24 25 @rewind($zip); 26 @fseek($zip, $centd['offset']); 27 28 for ($i=0; $i<$centd['entries']; $i++) 29 { 30 $header = $this->ReadCentralFileHeaders($zip); 31 $header['index'] = $i;$info['filename'] = $header['filename']; 32 $info['stored_filename'] = $header['stored_filename']; 33 $info['size'] = $header['size'];$info['compressed_size']=$header['compressed_size']; 34 $info['crc'] = strtoupper(dechex( $header['crc'] )); 35 $info['mtime'] = $header['mtime']; $info['comment'] = $header['comment']; 36 $info['folder'] = ($header['external']==0x41FF0010||$header['external']==16)?1:0; 37 $info['index'] = $header['index'];$info['status'] = $header['status']; 38 $ret[]=$info; unset($header); 39 } 40 return $ret; 41 } 42 43 function Add($files,$compact) 44 { 45 if(!is_array($files[0])) $files=Array($files); 46 47 for($i=0;$files[$i];$i++){ 48 $fn = $files[$i]; 49 if(!in_Array(dirname($fn[0]),$this->dirs)) 50 $this->add_Dir(dirname($fn[0])); 51 if(basename($fn[0])) 52 $ret[basename($fn[0])]=$this->add_File($fn[1],$fn[0],$compact); 53 } 54 return $ret; 55 } 56 57 function get_file() 58 { 59 $data = implode('', $this -> datasec); 60 $ctrldir = implode('', $this -> ctrl_dir); 61 62 return $data . $ctrldir . $this -> eof_ctrl_dir . 63 pack('v', sizeof($this -> ctrl_dir)).pack('v', sizeof($this -> ctrl_dir)). 64 pack('V', strlen($ctrldir)) . pack('V', strlen($data)) . "\x00\x00"; 65 } 66 67 function add_dir($name) 68 { 69 $name = str_replace("\\", "/", $name); 70 $fr = "\x50\x4b\x03\x04\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00"; 71 72 $fr .= pack("V",0).pack("V",0).pack("V",0).pack("v", strlen($name) ); 73 $fr .= pack("v", 0 ).$name.pack("V", 0).pack("V", 0).pack("V", 0); 74 $this -> datasec[] = $fr; 75 76 $new_offset = strlen(implode("", $this->datasec)); 77 78 $cdrec = "\x50\x4b\x01\x02\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00"; 79 $cdrec .= pack("V",0).pack("V",0).pack("V",0).pack("v", strlen($name) ); 80 $cdrec .= pack("v", 0 ).pack("v", 0 ).pack("v", 0 ).pack("v", 0 ); 81 $ext = "\xff\xff\xff\xff"; 82 $cdrec .= pack("V", 16 ).pack("V", $this -> old_offset ).$name; 83 84 $this -> ctrl_dir[] = $cdrec; 85 $this -> old_offset = $new_offset; 86 $this -> dirs[] = $name; 87 } 88 89 function add_File($data, $name, $compact = 1) 90 { 91 $name = str_replace('\\', '/', $name); 92 $dtime = dechex($this->DosTime()); 93 94 $hexdtime = '\x' . $dtime[6] . $dtime[7].'\x'.$dtime[4] . $dtime[5] 95 . '\x' . $dtime[2] . $dtime[3].'\x'.$dtime[0].$dtime[1]; 96 eval('$hexdtime = "' . $hexdtime . '";'); 97 98 if($compact) 99 $fr = "\x50\x4b\x03\x04\x14\x00\x00\x00\x08\x00".$hexdtime; 100 else $fr = "\x50\x4b\x03\x04\x0a\x00\x00\x00\x00\x00".$hexdtime; 101 $unc_len = strlen($data); $crc = crc32($data); 102 103 if($compact){ 104 $zdata = gzcompress($data); $c_len = strlen($zdata); 105 $zdata = substr(substr($zdata, 0, strlen($zdata) - 4), 2); 106 }else{ 107 $zdata = $data; 108 } 109 $c_len=strlen($zdata); 110 $fr .= pack('V', $crc).pack('V', $c_len).pack('V', $unc_len); 111 $fr .= pack('v', strlen($name)).pack('v', 0).$name.$zdata; 112 113 $fr .= pack('V', $crc).pack('V', $c_len).pack('V', $unc_len); 114 115 $this -> datasec[] = $fr; 116 $new_offset = strlen(implode('', $this->datasec)); 117 if($compact) 118 $cdrec = "\x50\x4b\x01\x02\x00\x00\x14\x00\x00\x00\x08\x00"; 119 else $cdrec = "\x50\x4b\x01\x02\x14\x00\x0a\x00\x00\x00\x00\x00"; 120 $cdrec .= $hexdtime.pack('V', $crc).pack('V', $c_len).pack('V', $unc_len); 121 $cdrec .= pack('v', strlen($name) ).pack('v', 0 ).pack('v', 0 ); 122 $cdrec .= pack('v', 0 ).pack('v', 0 ).pack('V', 32 ); 123 $cdrec .= pack('V', $this -> old_offset ); 124 125 $this -> old_offset = $new_offset; 126 $cdrec .= $name; 127 $this -> ctrl_dir[] = $cdrec; 128 return true; 129 } 130 131 function DosTime() { 132 $timearray = getdate(); 133 if ($timearray['year'] < 1980) { 134 $timearray['year'] = 1980; $timearray['mon'] = 1; 135 $timearray['mday'] = 1; $timearray['hours'] = 0; 136 $timearray['minutes'] = 0; $timearray['seconds'] = 0; 137 } 138 return (($timearray['year'] - 1980) << 25) | ($timearray['mon'] << 21) | ($timearray['mday'] << 16) | ($timearray['hours'] << 11) | 139 ($timearray['minutes'] << 5) | ($timearray['seconds'] >> 1); 140 } 141 142 function Extract ( $zn, $to, $index = Array(-1) ) 143 { 144 if(!@is_dir($to)) @mkdir($to,0777); 145 $ok = 0; $zip = @fopen($zn,'rb'); 146 if(!$zip) return(-1); 147 $cdir = $this->ReadCentralDir($zip,$zn); 148 $pos_entry = $cdir['offset']; 149 150 if(!is_array($index)){ $index = array($index); } 151 for($i=0; $index[$i];$i++){ 152 if(intval($index[$i])!=$index[$i]||$index[$i]>$cdir['entries']) 153 return(-1); 154 } 155 156 for ($i=0; $i<$cdir['entries']; $i++) 157 { 158 @fseek($zip, $pos_entry); 159 $header = $this->ReadCentralFileHeaders($zip); 160 $header['index'] = $i; $pos_entry = ftell($zip); 161 @rewind($zip); fseek($zip, $header['offset']); 162 if(in_array("-1",$index)||in_array($i,$index)) 163 $stat[$header['filename']]=$this->ExtractFile($header, $to, $zip); 164 165 } 166 fclose($zip); 167 return $stat; 168 } 169 170 function ReadFileHeader($zip) 171 { 172 $binary_data = fread($zip, 30); 173 $data = unpack('vchk/vid/vversion/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len', $binary_data); 174 175 $header['filename'] = fread($zip, $data['filename_len']); 176 if ($data['extra_len'] != 0) { 177 $header['extra'] = fread($zip, $data['extra_len']); 178 } else { $header['extra'] = ''; } 179 180 $header['compression'] = $data['compression'];$header['size'] = $data['size']; 181 $header['compressed_size'] = $data['compressed_size']; 182 $header['crc'] = $data['crc']; $header['flag'] = $data['flag']; 183 $header['mdate'] = $data['mdate'];$header['mtime'] = $data['mtime']; 184 185 if ($header['mdate'] && $header['mtime']){ 186 $hour=($header['mtime']&0xF800)>>11;$minute=($header['mtime']&0x07E0)>>5; 187 $seconde=($header['mtime']&0x001F)*2;$year=(($header['mdate']&0xFE00)>>9)+1980; 188 $month=($header['mdate']&0x01E0)>>5;$day=$header['mdate']&0x001F; 189 $header['mtime'] = mktime($hour, $minute, $seconde, $month, $day, $year); 190 }else{$header['mtime'] = time();} 191 192 $header['stored_filename'] = $header['filename']; 193 $header['status'] = "ok"; 194 return $header; 195 } 196 197 function ReadCentralFileHeaders($zip){ 198 $binary_data = fread($zip, 46); 199 $header = unpack('vchkid/vid/vversion/vversion_extracted/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len/vcomment_len/vdisk/vinternal/Vexternal/Voffset', $binary_data); 200 201 if ($header['filename_len'] != 0) 202 $header['filename'] = fread($zip,$header['filename_len']); 203 else $header['filename'] = ''; 204 205 if ($header['extra_len'] != 0) 206 $header['extra'] = fread($zip, $header['extra_len']); 207 else $header['extra'] = ''; 208 209 if ($header['comment_len'] != 0) 210 $header['comment'] = fread($zip, $header['comment_len']); 211 else $header['comment'] = ''; 212 213 if ($header['mdate'] && $header['mtime']) 214 { 215 $hour = ($header['mtime'] & 0xF800) >> 11; 216 $minute = ($header['mtime'] & 0x07E0) >> 5; 217 $seconde = ($header['mtime'] & 0x001F)*2; 218 $year = (($header['mdate'] & 0xFE00) >> 9) + 1980; 219 $month = ($header['mdate'] & 0x01E0) >> 5; 220 $day = $header['mdate'] & 0x001F; 221 $header['mtime'] = mktime($hour, $minute, $seconde, $month, $day, $year); 222 } else { 223 $header['mtime'] = time(); 224 } 225 $header['stored_filename'] = $header['filename']; 226 $header['status'] = 'ok'; 227 if (substr($header['filename'], -1) == '/') 228 $header['external'] = 0x41FF0010; 229 return $header; 230 } 231 232 function ReadCentralDir($zip,$zip_name) 233 { 234 $size = filesize($zip_name); 235 if ($size < 277) $maximum_size = $size; 236 else $maximum_size=277; 237 238 @fseek($zip, $size-$maximum_size); 239 $pos = ftell($zip); $bytes = 0x00000000; 240 241 while ($pos < $size) 242 { 243 $byte = @fread($zip, 1); $bytes=($bytes << 8) | Ord($byte); 244 if ($bytes == 0x504b0506){ $pos++; break; } $pos++; 245 } 246 247 $data=unpack('vdisk/vdisk_start/vdisk_entries/ventries/Vsize/Voffset/vcomment_size', 248 fread($zip, 18)); 249 250 if ($data['comment_size'] != 0) 251 $centd['comment'] = fread($zip, $data['comment_size']); 252 else $centd['comment'] = ''; $centd['entries'] = $data['entries']; 253 $centd['disk_entries'] = $data['disk_entries']; 254 $centd['offset'] = $data['offset'];$centd['disk_start'] = $data['disk_start']; 255 $centd['size'] = $data['size']; $centd['disk'] = $data['disk']; 256 return $centd; 257 } 258 259 function ExtractFile($header,$to,$zip) 260 { 261 $header = $this->readfileheader($zip); 262 263 if(substr($to,-1)!="/") $to.="/"; 264 if(substr($header['filename'],-1)=="/") 265 { 266 // @mkdir($to.$header['filename']); --CS 267 $this->_mkdir($to.$header['filename']); //-- CS 268 return +2; 269 } 270 271 // $pth = explode("/",dirname($header['filename'])); 272 // for($i=0,$tmp="";isset($pth[$i]);$i++){ 273 // if(!$pth[$i]) continue; 274 // if(!is_dir($to.$tmp.$pth[$i])) @mkdir($to.$pth[$i],0777); 275 // $tmp.=$pth[$i]."/"; 276 // } 277 if (!$this->_mkdir($to.dirname($header['filename']))) return (-1); //--CS 278 279 if (!($header['external']==0x41FF0010)&&!($header['external']==16)) 280 { 281 if ($header['compression']==0) 282 { 283 $fp = @fopen($to.$header['filename'], 'wb'); 284 if(!$fp) return(-1); 285 $size = $header['compressed_size']; 286 287 while ($size != 0) 288 { 289 $read_size = ($size < 2048 ? $size : 2048); 290 $buffer = fread($zip, $read_size); 291 $binary_data = pack('a'.$read_size, $buffer); 292 @fwrite($fp, $binary_data, $read_size); 293 $size -= $read_size; 294 } 295 fclose($fp); 296 touch($to.$header['filename'], $header['mtime']); 297 298 }else{ 299 if (!is_dir(dirname($to.$header['filename']))) $this->_mkdir(dirname($to.$header['filename'])); //-CS 300 $fp = fopen($to.$header['filename'].'.gz','wb'); 301 if(!$fp) return(-1); 302 $binary_data = pack('va1a1Va1a1', 0x8b1f, Chr($header['compression']), 303 Chr(0x00), time(), Chr(0x00), Chr(3)); 304 305 fwrite($fp, $binary_data, 10); 306 $size = $header['compressed_size']; 307 308 while ($size != 0) 309 { 310 $read_size = ($size < 1024 ? $size : 1024); 311 $buffer = fread($zip, $read_size); 312 $binary_data = pack('a'.$read_size, $buffer); 313 @fwrite($fp, $binary_data, $read_size); 314 $size -= $read_size; 315 } 316 317 $binary_data = pack('VV', $header['crc'], $header['size']); 318 fwrite($fp, $binary_data,8); fclose($fp); 319 320 $gzp = @gzopen($to.$header['filename'].'.gz','rb'); 321 if(!$gzp){ 322 @gzclose($gzp); @unlink($to.$header['filename']); 323 die("Archive is compressed whereas ZLIB is not enabled."); 324 } 325 $fp = @fopen($to.$header['filename'],'wb'); 326 if(!$fp) return(-1); 327 $size = $header['size']; 328 329 while ($size != 0) 330 { 331 $read_size = ($size < 2048 ? $size : 2048); 332 $buffer = gzread($gzp, $read_size); 333 $binary_data = pack('a'.$read_size, $buffer); 334 @fwrite($fp, $binary_data, $read_size); 335 $size -= $read_size; 336 } 337 fclose($fp); gzclose($gzp); 338 339 touch($to.$header['filename'], $header['mtime']); 340 @unlink($to.$header['filename'].'.gz'); 341 342 }} 343 return true; 344 } 345 346 //--CS start 347 // centralize mkdir calls and use dokuwiki io functions 348 function _mkdir($d) { 349 return ap_mkdir($d); 350 } 351 //--CS end 352 } 353
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
| Généré le : Tue Apr 3 20:47:31 2007 | par Balluche grâce à PHPXref 0.7 |