delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/2003/04/26/07:48:20

Date: Sat, 26 Apr 2003 12:18:17 +0100
From: "Richard Dawe" <rich AT phekda DOT freeserve DOT co DOT uk>
Sender: rich AT phekda DOT freeserve DOT co DOT uk
To: djgpp-workers AT delorie DOT com
X-Mailer: Emacs 21.3.50 (via feedmail 8.3.emacs20_6 I) and Blat ver 1.8.6
Subject: djtar and slightly weirdly formatted ZIPs [PATCH]
Message-Id: <E199Nch-0000l9-00@phekda.freeserve.co.uk>
Reply-To: djgpp-workers AT delorie DOT com

Hello.

I noticed the other day that djtar cannot extract the flex 2.54 binary
package from Simtel.NET - v2gnu/flx254b.zip. This is because
it has a slightly weird header. Before the normal ZIP local header
it has the header "PK00". I can't find out what this is for.

InfoZIP's unzip copes fine with this file. It seems to skip over headers
until it finds the first local header.

I've made djtar do this - below is a patch. It differs slightly from
the InfoZIP approach, because it assumes that all ZIP file headers
have a 4-byte identifier before the header data - PK<a><b>, where
a, b identify the header type.

Something else I noticed is that the output for djtar -t is not consistent
between ZIP and tar'd formats. For ZIPs it just lists the filenames.
For tar files it lists attributes, dates and file sizes too.

OK to commit?

Thanks, bye, Rich =]

Index: src/utils/djtar/epunzip.c
===================================================================
RCS file: /cvs/djgpp/djgpp/src/utils/djtar/epunzip.c,v
retrieving revision 1.4
diff -p -u -3 -r1.4 epunzip.c
--- src/utils/djtar/epunzip.c	17 Oct 2002 23:00:26 -0000	1.4
+++ src/utils/djtar/epunzip.c	26 Apr 2003 11:09:47 -0000
@@ -37,6 +37,8 @@ int epcopy(char *, long);
 void
 epunzip_read(char *zipfilename)
 {
+  int at_local_header = 0;
+
   clear_bufs();
   errno = 0;
   ifd = oread_open(zipfilename);
@@ -46,28 +48,70 @@ epunzip_read(char *zipfilename)
       return;
     }
 
+  /* Find the first local header. Ignore all other headers until
+   * we find that. */
   while(1)
     {
-      int buffer, ext_header, timedate, crc, size, length, name_length,
-	extra_length, should_be_written, count, real_file = 0;
-      char filename[2048];
+      int buffer;
+      char c = get_byte();
 
-      ((char *)&buffer)[0] = (char)get_byte();
+      if (c != 'P')
+	{
+	  /* not the start of a header - look further */
+	  continue;
+	}
+
+      ((char *)&buffer)[0] = c;
       ((char *)&buffer)[1] = (char)get_byte();
 
       if(*(short *)&buffer != *(short *)"PK")
-	{
-	  fprintf(log_out, "%s: invalid zip file structure\n", zipfilename);
-	  break;
-	}
+	continue;
 
       ((char *)&buffer)[0] = (char)get_byte();
       ((char *)&buffer)[1] = (char)get_byte();
 
       if(*(short *)&buffer != *(short *)"\3\4")
 	{
-	  /* not a local header - all done */
-	  break;
+	  /* not a local header - look further */
+	  continue;
+	}
+
+      at_local_header = 1;
+      break;
+    }
+
+  if (!at_local_header)
+    fprintf(log_out, "%s: invalid zip file structure\n", zipfilename);
+
+  if (at_local_header) while(1)
+    {
+      int buffer, ext_header, timedate, crc, size, length, name_length,
+	extra_length, should_be_written, count, real_file = 0;
+      char filename[2048];
+
+      if (!at_local_header)
+	{
+	  ((char *)&buffer)[0] = (char)get_byte();
+	  ((char *)&buffer)[1] = (char)get_byte();
+
+	  if(*(short *)&buffer != *(short *)"PK")
+	    {
+	      fprintf(log_out, "%s: invalid zip file structure\n", zipfilename);
+	      break;
+	    }
+
+	  ((char *)&buffer)[0] = (char)get_byte();
+	  ((char *)&buffer)[1] = (char)get_byte();
+
+	  if(*(short *)&buffer != *(short *)"\3\4")
+	    {
+	      /* not a local header - all done */
+	      break;
+	    }
+	}
+      else
+	{
+	  at_local_header = 0;
 	}
 
       /* version info - ignore it */

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019