[Distutils] bdist_wininst creates corrupt installation

Thomas Heller thomas.heller@ion-tof.com
Mon Oct 9 12:20:15 2000


This is a multi-part message in MIME format.

------=_NextPart_000_0141_01C0321D.61154C40
Content-Type: text/plain;
	charset="iso-8859-1"
Content-Transfer-Encoding: 7bit

[Martin von Loewis]
> I've created a PyXML distribution with recent distutils (0.93 and
> 1.0). When installing these distributions, the installer creates empty
> files only, see 
> 
> http://download.sourceforge.net/pyxml/PyXML-0.6.0.win32.exe
> 
> for an example.
> 
> I've tracked this down to usage of the zipfile module. If it does not
> find an external zip program (which I did not have), it then tries to
> use the zipfile module. Somehow, the installation program later cannot
> process the files created with that module.
> 
> The problem is probably in the installer, since Winzip 7 is capable of
> reading the package, and extracts the files properly.
> 
> I have solved the problem by installing infozip on my
> machine. However, I'd appreciate if somebody could look into the
> problem and let me know what the cause is. If you cannot reproduce the
> problem, please let me know as well.
> 
The problem was that the windows installer was using zipfile datastructures
which are not always set.
The following patch fixes this problem.
Since currently I cannot check in these changes, I'm posting them here
so they do not get lost.
Note that wininst.exe must be recompiled and bdist_wininst.py
must be regenerated to complete the fix.

Thomas

------=_NextPart_000_0141_01C0321D.61154C40
Content-Type: text/plain;
	name="diff.txt"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
	filename="diff.txt"

Index: misc/archive.h
===================================================================
RCS file: /cvsroot/python/distutils/misc/archive.h,v
retrieving revision 1.2
diff -c -r1.2 archive.h
*** misc/archive.h	2000/09/07 07:36:40	1.2
--- misc/archive.h	2000/10/09 16:14:42
***************
*** 59,70 ****
  
  typedef int (*NOTIFYPROC)(int code, LPSTR text, ...);
  
! extern BOOL extract_file (char *dst, struct fhdr *phdr, char *src,
! 			  NOTIFYPROC callback);
  extern BOOL unzip_archive (char *dirname, char *data, DWORD size,
  			   NOTIFYPROC callback);
  extern char *map_new_file (DWORD flags, char *filename, char
! 			   *pathname_part, struct fhdr *pfhdr,
  			   NOTIFYPROC callback);
  extern BOOL ensure_directory (char *pathname, char *new_part,
  			      NOTIFYPROC callback);
--- 59,71 ----
  
  typedef int (*NOTIFYPROC)(int code, LPSTR text, ...);
  
! extern BOOL extract_file (char *dst, char *src, int method, int comp_size,
! 			  int uncomp_size, NOTIFYPROC notify);
  extern BOOL unzip_archive (char *dirname, char *data, DWORD size,
  			   NOTIFYPROC callback);
  extern char *map_new_file (DWORD flags, char *filename, char
! 			   *pathname_part, int size,
! 			   WORD wFatDate, WORD wFatTime,
  			   NOTIFYPROC callback);
  extern BOOL ensure_directory (char *pathname, char *new_part,
  			      NOTIFYPROC callback);
Index: misc/extract.c
===================================================================
RCS file: /cvsroot/python/distutils/misc/extract.c,v
retrieving revision 1.3
diff -c -r1.3 extract.c
*** misc/extract.c	2000/09/29 11:20:55	1.3
--- misc/extract.c	2000/10/09 16:14:42
***************
*** 46,57 ****
   * uncomp_size and file_times instead of pfhdr!
   */
  char *map_new_file (DWORD flags, char *filename,
! 		    char *pathname_part, struct fhdr *pfhdr,
  		    NOTIFYPROC notify)
  {
      HANDLE hFile, hFileMapping;
      char *dst;
-     int size = pfhdr->uncomp_size;
      FILETIME ft;
  
    try_again:
--- 46,57 ----
   * uncomp_size and file_times instead of pfhdr!
   */
  char *map_new_file (DWORD flags, char *filename,
! 		    char *pathname_part, int size,
! 		    WORD wFatDate, WORD wFatTime,
  		    NOTIFYPROC notify)
  {
      HANDLE hFile, hFileMapping;
      char *dst;
      FILETIME ft;
  
    try_again:
***************
*** 98,105 ****
      if (notify)
  	notify (FILE_CREATED, filename);
  
!     DosDateTimeToFileTime (pfhdr->last_mod_file_date,
! 			   pfhdr->last_mod_file_time, &ft);
      SetFileTime (hFile, &ft, &ft, &ft);
  
  
--- 98,104 ----
      if (notify)
  	notify (FILE_CREATED, filename);
  
!     DosDateTimeToFileTime (wFatDate, wFatTime, &ft);
      SetFileTime (hFile, &ft, &ft, &ft);
  
  
***************
*** 136,153 ****
  
  
  BOOL
! extract_file (char *dst, struct fhdr *phdr, char *src, NOTIFYPROC notify)
  {
      z_stream zstream;
      int result;
  
!     if (phdr->method == Z_DEFLATED) {
  	int x;
          memset (&zstream, 0, sizeof (zstream));
          zstream.next_in = src;
!         zstream.avail_in = phdr->comp_size+1;
  	zstream.next_out = dst;
!         zstream.avail_out = phdr->uncomp_size;
  
  /* Apparently an undocumented feature of zlib: Set windowsize
   to negative values to supress the gzip header and be compatible with
--- 135,153 ----
  
  
  BOOL
! extract_file (char *dst, char *src, int method, int comp_size,
! 	      int uncomp_size, NOTIFYPROC notify)
  {
      z_stream zstream;
      int result;
  
!     if (method == Z_DEFLATED) {
  	int x;
          memset (&zstream, 0, sizeof (zstream));
          zstream.next_in = src;
!         zstream.avail_in = comp_size+1;
  	zstream.next_out = dst;
!         zstream.avail_out = uncomp_size;
  
  /* Apparently an undocumented feature of zlib: Set windowsize
   to negative values to supress the gzip header and be compatible with
***************
*** 170,177 ****
  		notify (ZLIB_ERROR, "inflateEnd returns %d", x);
  	    result = FALSE;
  	}
!     } else if (phdr->method == 0) {
! 	memcpy(dst, src, phdr->uncomp_size);
  	result = TRUE;
      } else
  	result = FALSE;
--- 170,177 ----
  		notify (ZLIB_ERROR, "inflateEnd returns %d", x);
  	    result = FALSE;
  	}
!     } else if (method == 0) {
! 	memcpy(dst, src, uncomp_size);
  	result = TRUE;
      } else
  	result = FALSE;
***************
*** 233,241 ****
  	strncat (pathname, fname, pfhdr->fname_length);
  	fixpath (pathname);
  	if (pathname[strlen(pathname)-1] != '\\') {
! 	    dst = map_new_file (0, pathname, new_part, pfhdr, notify);
  	    if (dst) {
! 		if (!extract_file (dst, pfhdr, pcomp, notify))
  		    return FALSE;
  	    } /* else ??? */
  	}
--- 233,253 ----
  	strncat (pathname, fname, pfhdr->fname_length);
  	fixpath (pathname);
  	if (pathname[strlen(pathname)-1] != '\\') {
! 	    /*
! 	     * The local file header (pfhdr) does not always contain
! 	     * the compressed and uncompressed sizes of the data
! 	     * depending on bit 3 of the flags field.
! 	     * So it seems better to use the data from the
! 	     * central directory (pcdir).
! 	     */
! 	    dst = map_new_file (0, pathname, new_part,
! 				pcdir->uncomp_size,
! 				pcdir->last_mod_file_date,
! 				pcdir->last_mod_file_time, notify);
  	    if (dst) {
! 		if (!extract_file (dst, pcomp, pfhdr->method,
! 				   pcdir->comp_size, pcdir->uncomp_size,
! 				   notify))
  		    return FALSE;
  	    } /* else ??? */
  	}
Index: misc/install.c
===================================================================
RCS file: /cvsroot/python/distutils/misc/install.c,v
retrieving revision 1.7
diff -c -r1.7 install.c
*** misc/install.c	2000/09/29 11:28:41	1.7
--- misc/install.c	2000/10/09 16:14:43
***************
*** 356,362 ****
  
      /* read meta_data info */
      struct meta_data_hdr *pmd = (struct meta_data_hdr *)&data[ofs];
-     struct fhdr fhdr;
      char *src, *dst;
      char *ini_file;
      char tempdir[MAX_PATH];
--- 356,361 ----
***************
*** 381,388 ****
  	return NULL;
      }
      
!     fhdr.uncomp_size = pmd->uncomp_size;
!     dst = map_new_file (CREATE_ALWAYS, ini_file, NULL, &fhdr, notify);
      if (!dst)
  	return NULL;
      memcpy (dst, src, pmd->uncomp_size);
--- 380,387 ----
  	return NULL;
      }
      
!     dst = map_new_file (CREATE_ALWAYS, ini_file, NULL, pmd->uncomp_size,
! 			0, 0, notify);
      if (!dst)
  	return NULL;
      memcpy (dst, src, pmd->uncomp_size);

------=_NextPart_000_0141_01C0321D.61154C40--