[ Index ] |
|
Code source de XOOPS 2.0.17.1 |
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 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Sun Nov 25 11:44:32 2007 | par Balluche grâce à PHPXref 0.7 |
![]() |