home *** CD-ROM | disk | FTP | other *** search
/ Hackers Magazine 57 / CdHackersMagazineNr57.iso / Software / Programming / dhtmlxMenu.exe / dhtmlxMenu / libCompiler / ziplib.php < prev   
Encoding:
PHP Script  |  2009-10-13  |  9.9 KB  |  250 lines

  1. <?php
  2. // **************************
  3. // *      Ziplib 0.3.1      *
  4. // *    Created by: Seven   *
  5. // **************************
  6. //
  7. // Simple set of functions to create a zipfile
  8. // according to the PKWare specifications, which
  9. // can be found on:
  10. // http://www.pkware.com/products/enterprise/white_papers/
  11. // ⌐1989-2003, PKWARE Inc.
  12.  
  13. // functions in here start with zl, which comes from ZipLib ;)
  14.  
  15. // requires dostime.php
  16. $settings['offset'] = 1; // Holland ;)
  17.  
  18. class Ziplib {
  19.  
  20. var $archive;
  21. var $archive_fileinfo = array();
  22. var $archive_filecount;
  23. var $compr_lvl_last;
  24.  
  25. private function zl_compress($data,$level = "",$type = "") {
  26.     if($type != "g" && $type != "b" && $type != "n") {
  27.         // Darnit, they forgot to set the type. Assuming gZip if any compression
  28.         if($level >= 1 && $level <= 9) $type = "g";
  29.         elseif($level > 9) die("Compression level set too high");
  30.         else $type = "n";
  31.     }
  32.         
  33.     if($type == "g") {
  34.         $this->compr_lvl_last = 8;
  35.         RETURN gzdeflate($data,$level);
  36.     } elseif($type == "b") {
  37.         $this->compr_lvl_last = 12;
  38.         RETURN bzcompress($data,$level);
  39.     } else {
  40.         $this->compr_lvl_last = 0;
  41.         RETURN $data;
  42.     }
  43. }
  44.  
  45. public function zl_add_file($data,$filename,$comp = "") {
  46.     global $settings;
  47.     // if we already created a file, we'll make sure it'll be there in the coming zipfile ;)
  48.  
  49.     // first, checking some data
  50.     if(strlen($filename) > pow(2,16)-1) die("Filename $filename too long"); // ooh, dirty... dieing, will change later
  51.     if(strlen($data) > pow(2,32)-1) die("File $filename larger then 2GB, cannot continue"); // another one, naughty me ;)
  52.  
  53.     // $comp has a special format. the first character tells me about the compression, the second one represents the level
  54.     if(strlen($comp) == 1) {
  55.         // they still use the old method, assuming gzip
  56.         
  57.         $comp_type = "n";
  58.         $comp_lvl = 0;
  59.         if($comp >= 1 && $comp <= 9) {
  60.             $comp_type = "g";
  61.             $comp_lvl = $comp;
  62.         }
  63.     } else {
  64.         $comp_lvl = 5;
  65.         $comp_type = "n";
  66.         // hmmm, the new method. Is it valid?
  67.         if ($comp[0] == "b" OR $comp[0] == "g" OR $comp[0] == "n") $comp_type = $comp[0];
  68.         if (preg_match("/[0-9]/i",$comp[1])) $comp_lvl = $comp[1];
  69.     }
  70.  
  71.     // ok, let's get this bitch tidy:
  72.     // first adding a file
  73.     $compressed = $this->zl_compress($data,$comp_lvl,$comp_type);
  74.     $uncompressed = strlen($data);
  75.  
  76.     $newfile = "\x50\x4b\x03\x04";                // Header
  77.     $newfile .="\x00\x00";                    // Version needed to extract
  78.     $newfile .="\x00\x00";                    // general purpose bit flag
  79.     $newfile .=pack("v",$this->compr_lvl_last);        // compression method
  80.     $newfile .=pack("v",dostime_get($settings['offset']));            // last mod file time
  81.     $newfile .=pack("v",dosdate_get($settings['offset']));            // last mod file date
  82.     $newfile .=pack("V",crc32($data));            // CRC32
  83.     $newfile .=pack("V",strlen($compressed));        // compressed filesize
  84.     $newfile .=pack("V",$uncompressed);            // uncompressed filesize
  85.     $newfile .=pack("v",strlen($filename));            // length of filename
  86.     $newfile .="\x00\x00";                    // some sort of extra field ;)
  87.     $newfile .=$filename;
  88.     $newfile .=$compressed;
  89.  
  90.     $this->archive .= $newfile;
  91.  
  92.  
  93.     // some 'statistics' for this file ;)
  94.     $this->archive_filecount++;
  95.     $idf = $this->archive_filecount - 1;
  96.     $this->archive_fileinfo[$this->archive_filecount]['comp_type'] = $this->compr_lvl_last;
  97.     $this->archive_fileinfo[$this->archive_filecount]['size'] = strlen($data);
  98.     $this->archive_fileinfo[$this->archive_filecount]['size_comp'] = strlen($compressed);
  99.     $this->archive_fileinfo[$this->archive_filecount]['pkg_size'] = strlen($newfile);
  100.     if(!empty($this->archive_fileinfo[$idf]['local_stats_pointer'])) {
  101.         $this->archive_fileinfo[$this->archive_filecount]['local_stats_pointer'] = 
  102.         $this->archive_fileinfo[$idf]['local_stats_pointer'] +
  103.         $this->archive_fileinfo[$idf]['pkg_size'] + 1; // HACKERDIEHACK! only way to get local_stats_pointer to '0' (for now) in zl_pack
  104.     } else {
  105.         $this->archive_fileinfo[$this->archive_filecount]['local_stats_pointer'] = 1;
  106.     }
  107.     $this->archive_fileinfo[$this->archive_filecount]['name'] = $filename;
  108.     $this->archive_fileinfo[$this->archive_filecount]['crc32'] = crc32($data);
  109.     unset($file,$compressed); // to avoid having data in our memory double ;)
  110.     RETURN TRUE;
  111. }
  112.  
  113. public function zl_pack($comment) {
  114.     global $settings;
  115.     if(strlen($comment) > pow(2,16)-1) die("Comment too long"); // that's 3
  116.  
  117.     // now the central directory structure start
  118.     for($x=1;$x <= $this->archive_filecount;$x++) {
  119.         $file_stats = $this->archive_fileinfo[$x];
  120.         $cdss .= "\x50\x4b\x01\x02";            // Header
  121.         $cdss .="\x00\x00";                // version made by
  122.         $cdss .="\x00\x00";                // version needed to extract
  123.         $cdss .="\x00\x00";                // general purpose bit flag
  124.         $cdss .=pack("v",$file_stats['comp_type']);    // compression method
  125.         $cdss .=pack("v",dostime_get($settings['offset']));        // last mod file time
  126.         $cdss .=pack("v",dosdate_get($settings['offset']));        // last mod file date
  127.         $cdss .=pack("V",$file_stats['crc32']);        // CRC32
  128.         $cdss .=pack("V",$file_stats['size_comp']);    // compressed size
  129.         $cdss .=pack("V",$file_stats['size']);        // uncompressed size
  130.         $cdss .=pack("v",strlen($file_stats['name']));    // file name length
  131.         $cdss .="\x00\x00";                // extra field length
  132.         $cdss .="\x00\x00";                // file comment length
  133.         $cdss .="\x00\x00";                // disk number start
  134.         $cdss .="\x00\x00";                // internal file attributes
  135.         $cdss .="\x00\x00\x00\x00";            // external file attributes
  136.         $cdss .=pack("V",$file_stats['local_stats_pointer']-$x);    // relative offset of local header
  137.                                         // aka: The local_stats_pointer hack: part 2, see above
  138.         $cdss .=$file_stats['name'];
  139.     }
  140.  
  141.     // and final, the ending central directory structure! "WHOO HOOW!" (⌐Blur, 1998)
  142.     $cdse = "\x50\x4b\x05\x06";            // Header
  143.     $cdse .="\x00\x00";                // number of this disk
  144.     $cdse .="\x00\x00";                // number of the disk with the start of the central directory
  145.     $cdse .=pack("v",$this->archive_filecount);    // total number of entries in the central directory on this disk
  146.     $cdse .=pack("v",$this->archive_filecount);    // total number of entries in the central directory
  147.     $cdse .=pack("V",strlen($cdss));        // size of the central directory
  148.     $cdse .=pack("V",strlen($this->archive));    // offset of start of central directory with respect to the starting disk number
  149.     $cdse .=pack("v",strlen($comment));        // .ZIP file comment length
  150.     $cdse .=$comment;
  151.     
  152.     return $this->archive.$cdss.$cdse;
  153. }
  154.  
  155. public function zl_index_file($file) {
  156.     $fp = @fopen($file,"rb");
  157.     // ok, as we don't know what the exact position of everything is, we'll have to "guess" using the default sizes
  158.     //and set values in the zipfile. Basicly this means I have to go through the entire file, could take some time.
  159.     //Let's see if I can create an algorithm powerful enough.
  160.     if(!$fp) die("File empty");
  161.     $continue = 1;
  162.     $file_count = 0;
  163.  
  164.     while($continue) {
  165.         $content = fread($fp,30);
  166.         $id = substr($content,0,4);
  167.         if ($id == "\x50\x4b\x03\x04") {
  168.             // the method used is quite simple, load a file in the memory, and walk through several parts of it using substr
  169.             // As the PKZip format uses mostly fixed sizes for information, this isn't too hard to implement
  170.             // First I want everything tested, before I start giving this function a nice place in the class
  171.             $temp[$file_count]['file-size'] = ascii2dec(substr($content,18,4));
  172.             $temp[$file_count]['filename-size'] = ascii2dec(substr($content,26,2));
  173.             $temp[$file_count]['compression-type'] = ascii2dec(substr($content,8,2));
  174.             $temp[$file_count]['crc'] = ascii2dec(substr($content,14,4));
  175.             $temp[$file_count]['dostime'] = dostime_return(substr($content,10,2));
  176.             $temp[$file_count]['dosdate'] = dosdate_return(substr($content,12,2));
  177.  
  178.             $temp[$file_count]['filename'] = fread($fp,$temp[$file_count]['filename-size']);
  179.  
  180.             // As the Zip format does not include Content type headers, I'll create a nice little array with 
  181.             // extension/content type, and a small function to retreive it
  182.             $temp[$file_count]['file-type'] = ext2cth($temp[$file_count]['filename']);
  183.             $temp[$file_count]['content'] = fread($fp,$temp[$file_count]['file-size']);
  184.  
  185.             if ($temp[$file_count]['compression-type'] != 0 AND $temp[$file_count]['compression-type'] != 8 AND $temp[$file_count]['compression-type'] != 12) {
  186.                 $temp[$file_count]['lasterror'] = "Compression type not supported";
  187.             } else {
  188.                 if($temp[$file_count]['compression-type'] == 8) {
  189.                     $temp[$file_count]['content'] = gzinflate($temp[$file_count]['content']);
  190.                 } elseif ($temp[$file_count]['compression-type'] == 12) {
  191.                     $temp[$file_count]['content'] = bzdecompress($temp[$file_count]['content']);
  192.                 }
  193.                 $verify = crc32($temp[$file_count]['content']);
  194.                 if ($verify != $temp[$file_count]['crc']) {
  195.                     $temp[$file_count]['lasterror'] = "CRC did not match, possibly this zipfile is damaged";
  196.                 }
  197.             }
  198.             $file_count++;
  199.         } else {
  200.             $continue = 0;    
  201.         }
  202.  
  203.     }
  204.     fclose($fp);
  205.     unset($fp,$content,$file_count);
  206.     return $temp;
  207. }
  208. }
  209.  
  210.     function zipImgsFiles($source,$zip)
  211.     { 
  212.         
  213.         $folder = opendir($source==""?"./":$source);
  214.         while($file = readdir($folder))
  215.         {
  216.         if ($file == '.' || $file == '..') {
  217.                    continue;
  218.                }
  219.                
  220.                if(is_dir($source.$file))
  221.                {
  222.                     zipImgsFiles($source.$file."/",$zip);
  223.                }
  224.                else 
  225.                {
  226.                 $zip->zl_add_file(file_get_contents($source.$file),$source.$file,"g0");
  227.                }
  228.         }
  229.         closedir($folder);
  230.         return 1;
  231.     }
  232.  
  233.     function zipFromLocation($location,$name="dhtmlx"){
  234.         //echo $location;
  235.         chdir($location);        
  236.         $zip = new Ziplib;
  237.         $zip->zl_add_file(file_get_contents("dhtmlx.js"),$name.'.js',"g9");
  238.         $zip->zl_add_file(file_get_contents("dhtmlx.css"),$name.'.css',"g9");
  239.         $zip->zl_add_file(file_get_contents("manifest.txt"),'manifest.txt',"g9");
  240.         zipImgsFiles("imgs/",$zip);
  241.         $files = @scandir("./types");
  242.         if (count($files) > 2)
  243.             zipImgsFiles("types/",$zip);
  244.             
  245.         $outZip = $zip->zl_pack("");
  246.         
  247.         return $outZip;
  248.     }    
  249. ?>
  250.