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++; }
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); }
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++; }