PHP Classes

Zip file elements need timestamps

Recommend this page to a friend!

      Create ZIP File  >  All threads  >  Zip file elements need timestamps  >  (Un) Subscribe thread alerts  
Subject:Zip file elements need timestamps
Summary:I'm providing a patch to enable creation of timestamped elements
Messages:3
Author:Daniel Kahn Gillmor
Date:2009-03-22 23:17:12
Update:2009-05-30 20:10:22
 

  1. Zip file elements need timestamps   Reply   Report abuse  
Picture of Daniel Kahn Gillmor Daniel Kahn Gillmor - 2009-03-22 23:17:13
The current CreateZipFile code creates zip files with the elements set with a bizarre timestamp (in 2038).

You should be able to indicate the timestamp intended for each element within a zip file, and if the timestamp is not provided, it should default to the current time.

I'm providing a patch which enables this functionality, which i've posted online:

lair.fifthhorseman.net/~dkg/src/php ...

Anyone is free to use my patch for any purpose. Feel free to incorporate it into CreateZipFile.php, if you like.

The diff itself is (i have no idea if this will transmit cleanly in this webforum; you're probably better off downloading it from the link above):

diff --git a/CreateZipFile.php b/CreateZipFile.php
index cdf58de..0ac67bd 100644
--- a/CreateZipFile.php
+++ b/CreateZipFile.php
@@ -4,6 +4,11 @@
* Class to dynamically create a zip file (archive)
*
* @author Rochak Chauhan
+
+ * Modification to enable timestamps by Daniel Kahn Gillmor (dkg).
+ *
+ * dkg's modifications are freely available to anyone for any use for
+ * any purpose.
*/

class createZip {
@@ -13,21 +18,54 @@ class createZip {
public $endOfCentralDirectory = "\x50\x4b\x05\x06\x00\x00\x00\x00"; //end of Central directory record
public $oldOffset = 0;

+
+ /**
+ * Function to generate the funky MS-DOS style timestamps that
+ * PKZIP likes to use for native date/time formats.
+ *
+ * @param $timestamp integer UNIX-style timestamp
+ *
+ */
+ private function createMSDOSDateStamp($timestamp) {
+ /* why are we doing this insanity? because
+ http://www.pkware.com/documents/casestudies/APPNOTE.TXT suggests that
+ the time stamps are using MSDOS formats, which i found documented
+ here (bytes 0x0e through 0x11 of the directory table entries):
+ http://en.wikipedia.org/wiki/FAT32#Directory_table
+ */
+ $x = getdate($timestamp);
+ $ret = 0;
+
+ $ret = ((($x['year'] - 1980) & 0x7f) << 25) +
+ ((($x['mon']) & 0x0f) << 21) +
+ ((($x['mday']) & 0x1f) << 16) +
+ ((($x['hours']) & 0x1f) << 11) +
+ ((($x['minutes']) & 0x3f) << 5) +
+ ((($x['seconds']/2) & 0x1f));
+
+ return pack('V', $ret);
+ }
+
+
/**
* Function to create the directory where the file(s) will be unzipped
*
* @param $directoryName string
+ * @param $timestamp UNIX timestamp for the directory (defaults to time())
*
*/

- public function addDirectory($directoryName) {
+ public function addDirectory($directoryName, $timestamp = NULL) {
$directoryName = str_replace("\\", "/", $directoryName);
+ if (is_null($timestamp))
+ $timestamp = time();
+ $ms = $this->createMSDOSDateStamp($timestamp);

$feedArrayRow = "\x50\x4b\x03\x04";
$feedArrayRow .= "\x0a\x00";
$feedArrayRow .= "\x00\x00";
$feedArrayRow .= "\x00\x00";
- $feedArrayRow .= "\x00\x00\x00\x00";
+ $feedArrayRow .= $ms;

$feedArrayRow .= pack("V",0);
$feedArrayRow .= pack("V",0);
@@ -49,7 +87,7 @@ class createZip {
$addCentralRecord .="\x0a\x00";
$addCentralRecord .="\x00\x00";
$addCentralRecord .="\x00\x00";
- $addCentralRecord .="\x00\x00\x00\x00";
+ $addCentralRecord .= $ms;
$addCentralRecord .= pack("V",0);
$addCentralRecord .= pack("V",0);
$addCentralRecord .= pack("V",0);
@@ -74,18 +112,22 @@ class createZip {
* Function to add file(s) to the specified directory in the archive
*
* @param $directoryName string
+ * @param $timestamp UNIX timestamp for the file (defaults to time())
*
*/

- public function addFile($data, $directoryName) {
+ public function addFile($data, $directoryName, $timestamp = NULL) {

$directoryName = str_replace("\\", "/", $directoryName);
+ if (is_null($timestamp))
+ $timestamp = time();
+ $ms = $this->createMSDOSDateStamp($timestamp);

$feedArrayRow = "\x50\x4b\x03\x04";
$feedArrayRow .= "\x14\x00";
$feedArrayRow .= "\x00\x00";
$feedArrayRow .= "\x08\x00";
- $feedArrayRow .= "\x00\x00\x00\x00";
+ $feedArrayRow .= $ms;

$uncompressedLength = strlen($data);
$compression = crc32($data);
@@ -114,7 +156,7 @@ class createZip {
$addCentralRecord .="\x14\x00";
$addCentralRecord .="\x00\x00";
$addCentralRecord .="\x08\x00";
- $addCentralRecord .="\x00\x00\x00\x00";
+ $addCentralRecord .= $ms;
$addCentralRecord .= pack("V",$compression);
$addCentralRecord .= pack("V",$compressedLength);
$addCentralRecord .= pack("V",$uncompressedLength);

  2. Re: Zip file elements need timestamps   Reply   Report abuse  
Picture of mat test mat test - 2009-05-29 14:07:55 - In reply to message 1 from Daniel Kahn Gillmor
Hello,

I have implemented the patch of you on the create zip file of Rochak Chauhan.
This seems to work, but somehow I get now the message:"the local header signature not found".

How should this be solved, because every time I open the zip file I get this annoying message, and I am not be able to open this zip file.

Sincerely,

Marcel

  3. Re: Zip file elements need timestamps   Reply   Report abuse  
Picture of Daniel Kahn Gillmor Daniel Kahn Gillmor - 2009-05-30 20:10:22 - In reply to message 2 from mat test
hi mat test. I don't know what program you're using that generates that error message. perhaps Rochak Chauhan can comment on it?