예제 #1
0
	function addRegularFile($filename, $content, $attrib = false)
	{
		if (!$attrib)
			$attrib = array();

		$size = strlen($content);

		if (function_exists('gzopen')) {
			list($data, $crc32, $os_type) = zip_deflate($content);

			if (strlen($data) < $size) {
				$content = $data;	// Use compressed data.

				$comp_type = ZIP_DEFLATE;
			} else
				unset ($crc32);	// force plain store.
		}

		if (!isset($crc32)) {
			$comp_type = ZIP_STORE;

			$crc32 = zip_crc32($content);
		}

		if (!empty($attrib['write_protected']))
			$atx = (0100444 << 16) | 1; // S_IFREG + read permissions to
		// everybody.
		else
			$atx = (0100644 << 16); // Add owner write perms.

		$ati = $attrib['is_ascii'] ? 1 : 0;

		if (empty($attrib['mtime']))
			$attrib['mtime'] = time();

		list($mod_date, $mod_time) = unixtime2dostime($attrib['mtime']);

		// Construct parts common to "Local file header" and "Central
		// directory file header."
		if (!isset($attrib['extra_field']))
			$attrib['extra_field'] = '';

		if (!isset($attrib['file_comment']))
			$attrib['file_comment'] = '';

		$head = pack(
						"vvvvvVVVvv", 
						20, // Version needed to extract (FIXME: is this right?)
						0, // Gen purp bit flag
						$comp_type, 
						$mod_time, 
						$mod_date, 
						$crc32, 
						strlen($content), 
						$size, 
						strlen($filename), 
						strlen($attrib['extra_field'])
		);

		// Construct the "Local file header"
		$lheader = ZIP_LOCHEAD_MAGIC . $head . $filename . $attrib['extra_field'];

		// Construct the "central directory file header"
		$this->dir .= pack("a4CC", ZIP_CENTHEAD_MAGIC, 23, $os_type);
		$this->dir .= $head;
		$this->dir .= pack(
						"vvvVV", 
						strlen($attrib['file_comment']), 
						0, // Disk number start
						$ati, // Internal file attributes
						$atx, // External file attributes
						$this->offset // Relative offset of local header
		);
		$this->dir .= $filename . $attrib['extra_field'] . $attrib['file_comment'];

		// Output the "Local file header" and file contents.
		echo $lheader;
		echo $content;

		$this->offset += strlen($lheader) + strlen($content);
		$this->nfiles++;
	}
예제 #2
0
 function readFile()
 {
     $head = $this->_read(30);
     // FIXME: This is bad for gzip compressed buffers
     extract(unpack("a4magic/vreq_version/vflags/vcomp_type" . "/vmod_time/vmod_date" . "/Vcrc32/Vcomp_size/Vuncomp_size" . "/vfilename_len/vextrafld_len", $head));
     if ($magic != ZIP_LOCHEAD_MAGIC) {
         // maybe gzip?
         //$x = substr($magic,0,3);
         if (substr($magic, 0, 3) == "‹•") {
             if ($this->fp) {
                 fclose($this->fp);
                 $this->fp = fopen($this->zipfile, "rb");
                 $content = $this->_read(filesize($this->fp));
             } else {
                 $content = $this->buf;
             }
             // TODO...
             $data = zip_deflate($content);
             return array($filename, $data, $attrib);
         }
         if ($magic != ZIP_CENTHEAD_MAGIC) {
             // FIXME: better message?
             ExitWiki(sprintf("Unsupported ZIP header type: %s", $magic));
         }
         return $this->done();
     }
     if (($flags & 0x21) != 0) {
         ExitWiki("Encryption and/or zip patches not supported.");
     }
     if (($flags & 0x8) != 0) {
         // FIXME: better message?
         ExitWiki("Postponed CRC not yet supported.");
     }
     $filename = $this->_read($filename_len);
     //FIXME: we should probably check $req_version.
     $attrib['mtime'] = dostime2unixtime($mod_date, $mod_time);
     if ($extrafld_len != 0) {
         $attrib['extra_field'] = $this->_read($extrafld_len);
     }
     $data = $this->_read($comp_size);
     if ($comp_type == ZIP_DEFLATE) {
         $data = zip_inflate($data, $crc32, $uncomp_size);
     } else {
         if ($comp_type == ZIP_STORE) {
             $crc = zip_crc32($data);
             if ($crc32 != $crc) {
                 ExitWiki(sprintf("CRC mismatch %x != %x", $crc, $crc32));
             }
         } else {
             ExitWiki(sprintf("Compression method %s unsupported", $comp_method));
         }
     }
     if (strlen($data) != $uncomp_size) {
         ExitWiki(sprintf("Uncompressed size mismatch %d != %d", strlen($data), $uncomp_size));
     }
     return array($filename, $data, $attrib);
 }
예제 #3
0
 function addRegularFile($filename, $content, $attrib = false)
 {
     if (!$attrib) {
         $attrib = array();
     }
     $size = strlen($content);
     if (function_exists('gzopen')) {
         list($data, $crc32, $os_type) = zip_deflate($content);
         if (strlen($data) < $size) {
             $content = $data;
             // Use compressed data.
             $comp_type = ZIP_DEFLATE;
         } else {
             unset($crc32);
         }
         // force plain store.
     }
     if (!isset($crc32)) {
         $comp_type = ZIP_STORE;
         $crc32 = zip_crc32($content);
     }
     if (!empty($attrib['write_protected'])) {
         $atx = 0100444 << 16 | 1;
     } else {
         $atx = 0100644 << 16;
     }
     // Add owner write perms.
     $ati = $attrib['is_ascii'] ? 1 : 0;
     if (empty($attrib['mtime'])) {
         $attrib['mtime'] = time();
     }
     list($mod_date, $mod_time) = unixtime2dostime($attrib['mtime']);
     // Construct parts common to "Local file header" and "Central
     // directory file header."
     if (!isset($attrib['extra_field'])) {
         $attrib['extra_field'] = '';
     }
     if (!isset($attrib['file_comment'])) {
         $attrib['file_comment'] = '';
     }
     $head = pack("vvvvvVVVvv", 20, 0, $comp_type, $mod_time, $mod_date, $crc32, strlen($content), $size, strlen($filename), strlen($attrib['extra_field']));
     // Construct the "Local file header"
     $lheader = ZIP_LOCHEAD_MAGIC . $head . $filename . $attrib['extra_field'];
     // Construct the "central directory file header"
     $this->dir .= pack("a4CC", ZIP_CENTHEAD_MAGIC, 23, $os_type);
     $this->dir .= $head;
     $this->dir .= pack("vvvVV", strlen($attrib['file_comment']), 0, $ati, $atx, $this->offset);
     // Relative offset of local header
     $this->dir .= $filename . $attrib['extra_field'] . $attrib['file_comment'];
     // Output the "Local file header" and file contents.
     echo $lheader;
     echo $content;
     $this->offset += strlen($lheader) + strlen($content);
     $this->nfiles++;
 }