Beispiel #1
0
static TACommandVerdict get_crc_table_cmd(TAThread thread,TAInputStream stream)
{
    const uLongf* res;

    START_TARGET_OPERATION(thread);

    res = get_crc_table();

    END_TARGET_OPERATION(thread);

    // Response
    writeULongList(thread, res, 256);

    sendResponse(thread);

    return taDefaultVerdict;
}
Beispiel #2
0
ZIP_EXTERN struct zip_source *
zip_source_pkware(struct zip *za, struct zip_source *src,
		  zip_uint16_t em, int flags, const char *password)
{
    struct trad_pkware *ctx;
    struct zip_source *s2;

    if (password == NULL || src == NULL || em != ZIP_EM_TRAD_PKWARE) {
	_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
	return NULL;
    }
    if (flags & ZIP_CODEC_ENCODE) {
	_zip_error_set(&za->error, ZIP_ER_ENCRNOTSUPP, 0);
	return NULL;
    }

    if (crc == NULL)
	crc = get_crc_table();

    if ((ctx=(struct trad_pkware *)malloc(sizeof(*ctx))) == NULL) {
	_zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
	return NULL;
    }

    ctx->e[0] = ctx->e[1] = 0;

    ctx->key[0] = KEY0;
    ctx->key[1] = KEY1;
    ctx->key[2] = KEY2;
    decrypt(ctx, NULL, (const zip_uint8_t *)password, strlen(password), 1);

    if ((s2=zip_source_layered(za, src, pkware_decrypt, ctx)) == NULL) {
	pkware_free(ctx);
	return NULL;
    }

    return s2;
}
Beispiel #3
0
extern MINIZIP_EXPORT int zipOpenNewFileInZip3 (zipFile file,const char* filename,const zip_fileinfo* zipfi,
                                                const void* extrafield_local,uInt size_extrafield_local,
                                                const void* extrafield_global,uInt size_extrafield_global,
                                                const char* comment,int method,int level,int raw,
                                                int windowBits,int memLevel,int strategy,
                                                const char* password,uLong crcForCrypting)

{
  zip_internal* zi;
  uInt size_filename;
  uInt size_comment;
  uInt i;
  int err = ZIP_OK;

#    ifdef NOCRYPT
  if (password != 0)
    return ZIP_PARAMERROR;
#    endif

  if (file == 0)
    return ZIP_PARAMERROR;
  if ((method!=0) && (method!=Z_DEFLATED))
    return ZIP_PARAMERROR;

  zi = (zip_internal*)file;

  if (zi->in_opened_file_inzip == 1)
    {
      err = zipCloseFileInZip (file);
      if (err != ZIP_OK)
        return err;
    }


  if (filename==0)
    filename="-";

  if (comment==0)
    size_comment = 0;
  else
    size_comment = (uInt)strlen(comment);

  size_filename = (uInt)strlen(filename);

  if (zipfi == 0)
    zi->ci.dosDate = 0;
  else
    {
      if (zipfi->dosDate != 0)
        zi->ci.dosDate = zipfi->dosDate;
      else zi->ci.dosDate = ziplocal_TmzDateToDosDate(&zipfi->tmz_date,zipfi->dosDate);
    }

  zi->ci.flag = 0;
  if ((level==8) || (level==9))
    zi->ci.flag |= 2;
  if ((level==2))
    zi->ci.flag |= 4;
  if ((level==1))
    zi->ci.flag |= 6;
  if (password != 0)
    zi->ci.flag |= 1;

  zi->ci.crc32 = 0;
  zi->ci.method = method;
  zi->ci.encrypt = 0;
  zi->ci.stream_initialised = 0;
  zi->ci.pos_in_buffered_data = 0;
  zi->ci.raw = raw;
  zi->ci.pos_local_header = ZTELL(zi->z_filefunc,zi->filestream) ;
  zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename +
    size_extrafield_global + size_comment;
  zi->ci.central_header = (char*)ALLOC((uInt)zi->ci.size_centralheader);

  ziplocal_putValue_inmemory(zi->ci.central_header,(uLong)CENTRALHEADERMAGIC,4);
  /* version info */
  ziplocal_putValue_inmemory(zi->ci.central_header+4,(uLong)VERSIONMADEBY,2);
  ziplocal_putValue_inmemory(zi->ci.central_header+6,(uLong)20,2);
  ziplocal_putValue_inmemory(zi->ci.central_header+8,(uLong)zi->ci.flag,2);
  ziplocal_putValue_inmemory(zi->ci.central_header+10,(uLong)zi->ci.method,2);
  ziplocal_putValue_inmemory(zi->ci.central_header+12,(uLong)zi->ci.dosDate,4);
  ziplocal_putValue_inmemory(zi->ci.central_header+16,(uLong)0,4); /*crc*/
  ziplocal_putValue_inmemory(zi->ci.central_header+20,(uLong)0,4); /*compr size*/
  ziplocal_putValue_inmemory(zi->ci.central_header+24,(uLong)0,4); /*uncompr size*/
  ziplocal_putValue_inmemory(zi->ci.central_header+28,(uLong)size_filename,2);
  ziplocal_putValue_inmemory(zi->ci.central_header+30,(uLong)size_extrafield_global,2);
  ziplocal_putValue_inmemory(zi->ci.central_header+32,(uLong)size_comment,2);
  ziplocal_putValue_inmemory(zi->ci.central_header+34,(uLong)0,2); /*disk nm start*/

  if (zipfi==0)
    ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)0,2);
  else
    ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)zipfi->internal_fa,2);

  if (zipfi==0)
    ziplocal_putValue_inmemory(zi->ci.central_header+38,(uLong)0,4);
  else
    ziplocal_putValue_inmemory(zi->ci.central_header+38,(uLong)zipfi->external_fa,4);

  ziplocal_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_local_header- zi->add_position_when_writting_offset,4);

  for (i=0;i<size_filename;i++)
    *(zi->ci.central_header+SIZECENTRALHEADER+i) = *(filename+i);

  for (i=0;i<size_extrafield_global;i++)
    *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+i) =
      *(((const char*)extrafield_global)+i);

  for (i=0;i<size_comment;i++)
    *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+
      size_extrafield_global+i) = *(comment+i);
  if (zi->ci.central_header == 0)
    return ZIP_INTERNALERROR;

  /* write the local header */
  err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)LOCALHEADERMAGIC,4);

  if (err==ZIP_OK)
    err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)20,2);/* version needed to extract */
  if (err==ZIP_OK)
    err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.flag,2);

  if (err==ZIP_OK)
    err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.method,2);

  if (err==ZIP_OK)
    err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.dosDate,4);

  if (err==ZIP_OK)
    err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* crc 32, unknown */
  if (err==ZIP_OK)
    err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* compressed size, unknown */
  if (err==ZIP_OK)
    err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* uncompressed size, unknown */

  if (err==ZIP_OK)
    err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_filename,2);

  if (err==ZIP_OK)
    err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_extrafield_local,2);

  if ((err==ZIP_OK) && (size_filename>0))
    if (ZWRITE(zi->z_filefunc,zi->filestream,filename,size_filename)!=size_filename)
      err = ZIP_ERRNO;

  if ((err==ZIP_OK) && (size_extrafield_local>0))
    if (ZWRITE(zi->z_filefunc,zi->filestream,extrafield_local,size_extrafield_local)
        !=size_extrafield_local)
      err = ZIP_ERRNO;

  zi->ci.stream.avail_in = (uInt)0;
  zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
  zi->ci.stream.next_out = zi->ci.buffered_data;
  zi->ci.stream.total_in = 0;
  zi->ci.stream.total_out = 0;

  if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
    {
      zi->ci.stream.zalloc = (alloc_func)0;
      zi->ci.stream.zfree = (free_func)0;
      zi->ci.stream.opaque = (voidpf)0;

      if (windowBits>0)
        windowBits = -windowBits;

      err = deflateInit2(&zi->ci.stream, level,
                         Z_DEFLATED, windowBits, memLevel, strategy);

      if (err==Z_OK)
        zi->ci.stream_initialised = 1;
    }
#    ifndef NOCRYPT
  zi->ci.crypt_header_size = 0;
  if ((err==Z_OK) && (password != 0))
    {
      unsigned char bufHead[RAND_HEAD_LEN];
      unsigned int sizeHead;
      zi->ci.encrypt = 1;
      zi->ci.pcrc_32_tab = get_crc_table();
      /*init_keys(password,zi->ci.keys,zi->ci.pcrc_32_tab);*/

      sizeHead=crypthead(password,bufHead,RAND_HEAD_LEN,zi->ci.keys,zi->ci.pcrc_32_tab,crcForCrypting);
      zi->ci.crypt_header_size = sizeHead;

      if (ZWRITE(zi->z_filefunc,zi->filestream,bufHead,sizeHead) != sizeHead)
        err = ZIP_ERRNO;
    }
#    endif

  if (err==Z_OK)
    zi->in_opened_file_inzip = 1;
  return err;
}
Beispiel #4
0
static blargg_err_t init_zip()
{
	get_crc_table(); // initialize zlib's CRC-32 tables
	return blargg_ok;
}
Beispiel #5
0
static int ZipOpenCurrentFile(Zip* file, const char *password)
{
	int err = _ZIP_OK;
	int store;
	unsigned int isizevar;
	_zip* s;
	zipFileInfoInternal* pfileinzipreadinfo;
	unsigned long localextrafieldoffset;
	unsigned int localextrafieldsize;

	char source[12];

	if(file == NULL)
		return _ZIP_PARAM_ERROR;

	s = (_zip*)file;

	if(!s->currentfileok)
		return _ZIP_PARAM_ERROR;

	if(s->currentzipfileinfo != NULL)
		ZipCloseCurrentFile(file);

	if(ZipCheckCurrentFileCoherencyHeader(s, &isizevar, &localextrafieldoffset, &localextrafieldsize) != _ZIP_OK)
		return _ZIP_BAD_FILE;

	pfileinzipreadinfo = (zipFileInfoInternal*) MallocPatch(sizeof(zipFileInfoInternal));

	if(pfileinzipreadinfo == NULL)
		return _ZIP_INTERNAL_ERROR;

	pfileinzipreadinfo->buffer = (char*)MallocPatch(_ZIP_BUFFER_SIZE);
	pfileinzipreadinfo->localextrafieldoffset = localextrafieldoffset;
	pfileinzipreadinfo->localextrafieldsize = localextrafieldsize;
	pfileinzipreadinfo->localextrafieldpos = 0;

	if(pfileinzipreadinfo->buffer == NULL)
	{
		FreePatch(pfileinzipreadinfo);
		return _ZIP_INTERNAL_ERROR;
	}

	pfileinzipreadinfo->streaminitialised = 0;

	if((s->currentfileinfo.compressionmethod != 0) && (s->currentfileinfo.compressionmethod != Z_DEFLATED))
		err = _ZIP_BAD_FILE;

	store = s->currentfileinfo.compressionmethod == 0;

	pfileinzipreadinfo->crc32wait = s->currentfileinfo.crc;
	pfileinzipreadinfo->crc32 = 0;
	pfileinzipreadinfo->compressionmethod = s->currentfileinfo.compressionmethod;
	pfileinzipreadinfo->file = s->file;
	pfileinzipreadinfo->bytebeforezip = s->bytebeforezip;

	pfileinzipreadinfo->stream.total_out = 0;

	if(!store)
	{
		pfileinzipreadinfo->stream.zalloc = (alloc_func)0;
		pfileinzipreadinfo->stream.zfree = (free_func)0;
		pfileinzipreadinfo->stream.opaque = (voidpf)0;

		err = inflateInit2(&pfileinzipreadinfo->stream, -MAX_WBITS);

		if(err == Z_OK)
			pfileinzipreadinfo->streaminitialised = 1;
	}

	pfileinzipreadinfo->restreadcompressed = s->currentfileinfo.compressedsize;
	pfileinzipreadinfo->restreaduncompressed = s->currentfileinfo.uncompressedsize;

	pfileinzipreadinfo->posinzip = s->currentfileinfointernal.currentfileoffset + _ZIP_LOCALHEADER_SIZE + isizevar;

	pfileinzipreadinfo->stream.avail_in = (unsigned int)0;

	s->currentzipfileinfo = pfileinzipreadinfo;

	if(password != NULL)
	{
		int i;
		s->crc32tab = get_crc_table();
		ZipInitKeys(password, s->keys, s->crc32tab);

		if(fseek(pfileinzipreadinfo->file, s->currentzipfileinfo->posinzip + s->currentzipfileinfo->bytebeforezip, SEEK_SET) != 0)
		{
			FreePatch(pfileinzipreadinfo->buffer);
			FreePatch(pfileinzipreadinfo);

			return _ZIP_INTERNAL_ERROR;
		}

		if(fread(source, 1, 12, pfileinzipreadinfo->file) < 12)
		{
			FreePatch(pfileinzipreadinfo->buffer);
			FreePatch(pfileinzipreadinfo);

			return _ZIP_INTERNAL_ERROR;
		}

		for(i = 0; i < 12; i++)
			zdecode(s->keys, s->crc32tab, source[i]);

		s->currentzipfileinfo->posinzip += 12;
		s->encrypted = 1;
	}

	return _ZIP_OK;
}
Beispiel #6
0
/*
  Open for reading data the current file in the zipfile.
  If there is no error and the file is opened, the return value is UNZ_OK.
*/
int ZEXPORT unzOpenCurrentFile3 (
    unzFile file,
    int* method,
    int* level,
    int raw,
    const char* password)
{
    int err=UNZ_OK;
    uInt iSizeVar;
    unz_s* s;
    file_in_zip_read_info_s* pfile_in_zip_read_info;
    uLong offset_local_extrafield;  /* offset of the local extra field */
    uInt  size_local_extrafield;    /* size of the local extra field */
#    ifndef NOUNCRYPT
    char source[12];
#    else
    if (password != NULL)
        return UNZ_PARAMERROR;
#    endif

    if (file==NULL)
        return UNZ_PARAMERROR;
    s=(unz_s*)file;
    if (!s->current_file_ok)
        return UNZ_PARAMERROR;

    if (s->pfile_in_zip_read != NULL)
        unzCloseCurrentFile(file);

    if (unzlocal_CheckCurrentFileCoherencyHeader(s,&iSizeVar,
                &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK)
        return UNZ_BADZIPFILE;

    pfile_in_zip_read_info = (file_in_zip_read_info_s*)
                                        ALLOC(sizeof(file_in_zip_read_info_s));
    if (pfile_in_zip_read_info==NULL)
        return UNZ_INTERNALERROR;

    pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE);
    pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
    pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
    pfile_in_zip_read_info->pos_local_extrafield=0;
    pfile_in_zip_read_info->raw=raw;

    if (pfile_in_zip_read_info->read_buffer==NULL)
    {
        TRYFREE(pfile_in_zip_read_info);
        return UNZ_INTERNALERROR;
    }

    pfile_in_zip_read_info->stream_initialised=0;

    if (method!=NULL)
        *method = (int)s->cur_file_info.compression_method;

    if (level!=NULL)
    {
        *level = 6;
        switch (s->cur_file_info.flag & 0x06)
        {
          case 6 : *level = 1; break;
          case 4 : *level = 2; break;
          case 2 : *level = 9; break;
        }
    }

    if ((s->cur_file_info.compression_method!=0) &&
        (s->cur_file_info.compression_method!=Z_DEFLATED))
        err=UNZ_BADZIPFILE;

    pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc;
    pfile_in_zip_read_info->crc32=0;
    pfile_in_zip_read_info->compression_method =
            s->cur_file_info.compression_method;
    pfile_in_zip_read_info->filestream=s->filestream;
    pfile_in_zip_read_info->z_filefunc=s->z_filefunc;
    pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile;

    pfile_in_zip_read_info->stream.total_out = 0;

    if ((s->cur_file_info.compression_method==Z_DEFLATED) &&
        (!raw))
    {
      pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
      pfile_in_zip_read_info->stream.zfree = (free_func)0;
      pfile_in_zip_read_info->stream.opaque = (voidpf)0;
      pfile_in_zip_read_info->stream.next_in = (Bytef*)0;
      pfile_in_zip_read_info->stream.avail_in = 0;

      err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS);
      if (err == Z_OK)
        pfile_in_zip_read_info->stream_initialised=1;
      else
      {
        TRYFREE(pfile_in_zip_read_info);
        return err;
      }
        /* windowBits is passed < 0 to tell that there is no zlib header.
         * Note that in this case inflate *requires* an extra "dummy" byte
         * after the compressed stream in order to complete decompression and
         * return Z_STREAM_END.
         * In unzip, i don't wait absolutely Z_STREAM_END because I known the
         * size of both compressed and uncompressed data
         */
    }
    pfile_in_zip_read_info->rest_read_compressed =
            s->cur_file_info.compressed_size ;
    pfile_in_zip_read_info->rest_read_uncompressed =
            s->cur_file_info.uncompressed_size ;


    pfile_in_zip_read_info->pos_in_zipfile =
            s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER +
              iSizeVar;

    pfile_in_zip_read_info->stream.avail_in = (uInt)0;

    s->pfile_in_zip_read = pfile_in_zip_read_info;

#    ifndef NOUNCRYPT
    if (password != NULL)
    {
        int i;
        s->pcrc_32_tab = get_crc_table();
        init_keys(password,s->keys,s->pcrc_32_tab);
        if (ZSEEK(s->z_filefunc, s->filestream,
                  s->pfile_in_zip_read->pos_in_zipfile +
                     s->pfile_in_zip_read->byte_before_the_zipfile,
                  SEEK_SET)!=0)
            return UNZ_INTERNALERROR;
        if(ZREAD(s->z_filefunc, s->filestream,source, 12)<12)
            return UNZ_INTERNALERROR;

        for (i = 0; i<12; i++)
            zdecode(s->keys,s->pcrc_32_tab,source[i]);

        s->pfile_in_zip_read->pos_in_zipfile+=12;
        s->encrypted=1;
    }
#    endif


    return UNZ_OK;
}
Beispiel #7
0
/* ===========================================================================
 *									Function do_seekable()
 * return PK-type error code
 */
static int do_seekable( struct Globals *pG, int lastchance ) {
	/* static int no_ecrec = FALSE;  SKM: moved to globals.h */
	int maybe_exe = false;
	int too_weird_to_continue = false;
	int error = 0, error_in_archive;

	diag( pG, "starting do_seekable" );
	/*---------------------------------------------------------------------------
	 * Open the zipfile for reading in BINARY mode to prevent CR/LF translation,
	 * which would corrupt the bit streams.
	 *---------------------------------------------------------------------------*/
	if ( stat( pG->zipfn, &pG->statbuf ) || (error = S_ISDIR( pG->statbuf.st_mode )) != 0 ) {
		if ( lastchance )
			if ( pG->no_ecrec )
				printf( "can't find zip file dir" );
			else
				printf( "can't find either zip file" );
		return error ? IZ_DIR : PK_NOZIP;
	}
	pG->ziplen = pG->statbuf.st_size;

	if ( pG->statbuf.st_mode & S_IEXEC )
		maybe_exe = true;           /* might find unzip, not unzip.zip; etc. */

	diag( pG, "do_seekable, loc 2" );
	if ( open_input_file( pG ) )   /* this should never happen, given */
		return PK_NOZIP;            /* the stat() test above, but... */
	diag( pG, "do_seekable, loc 3" );
	/*---------------------------------------------------------------------------
	 * Find and process the end-of-central-directory header.  UnZip need only
	 * check last 65557 bytes of zipfile:  comment may be up to 65535, end-of-
	 * central-directory record is 18 bytes, and signature itself is 4 bytes;
	 * add some to allow for appended garbage.
	 *---------------------------------------------------------------------------*/
	/* initialize the CRC table pointer (once) */
	// EWE: This "get" of CRC table will be done again by crc32.c.
	// I have used a statically allocated table, so it doesn't matter.
	if ( CRC_32_TAB == NULL ) {
		if ( (CRC_32_TAB = (ulg *)get_crc_table()) == NULL ) return PK_MEM2;
	}
	pG->cur_zipfile_bufstart = 0;
	pG->inptr = pG->inbuf;

#ifdef TIMESTAMP
	if ( !pG->qflag && !pG->T_flag && !pG->zipinfo_mode )
#else
	if ( !pG->qflag && !pG->zipinfo_mode )
#endif
		printf( "Archive:  %s", pG->zipfn );

	diag( pG, "do_seekable, loc 4" );
	if ( ( ((error_in_archive = find_ecrec( pG, MIN( pG->ziplen, 66000L ))) != 0 ||
           (error_in_archive = uz_end_central( pG )) > PK_WARN)) ) {
		close( pG->zipfd );
		pG->zipfd = 0;		/* RCV added 29-1-99 */
		if ( maybe_exe ) printf( "maybe an EXE file: %s", pG->zipfn );
		if ( lastchance ) return error_in_archive;
		else {
			pG->no_ecrec = true;    /* assume we found wrong file:  e.g., */
			return PK_NOZIP;        /* unzip instead of unzip.zip         */
		}
	}
	diag( pG, "do_seekable, loc 5" );
	if ( pG->zflag > 0 && !pG->zipinfo_mode ) {  /* unzip: zflag = comment ONLY */
		close( pG->zipfd );
		pG->zipfd = 0;		/* RCV added 29-1-99 */
		return error_in_archive;
	}

	/*---------------------------------------------------------------------------
	 * Test the end-of-central-directory info for incompatibilities (multi-disk
	 * archives) or inconsistencies (missing or extra bytes in zipfile).
	 *---------------------------------------------------------------------------*/
#ifdef NO_MULTIPART
	error = !pG->zipinfo_mode && (pG->ecrec.number_this_disk == 1) &&
			(pG->ecrec.num_disk_start_cdir == 1);
#else
	error = !pG->zipinfo_mode && (pG->ecrec.number_this_disk != 0);
#endif

	if ( pG->zipinfo_mode && pG->ecrec.number_this_disk != pG->ecrec.num_disk_start_cdir ) {
		if ( pG->ecrec.number_this_disk > pG->ecrec.num_disk_start_cdir ) {
			UnzErr( pG, UEN_MISC01 );
			error_in_archive = PK_FIND;
			too_weird_to_continue = true;
		} else {
			printf( "Central dir bogus" );
			error_in_archive = PK_WARN;
		}
#ifdef NO_MULTIPART   /* concatenation of multiple parts works in some cases */
	} else if ( !pG->zipinfo_mode && !error && pG->ecrec.number_this_disk != 0 ) {
		UnzErr( pG, UEN_MISC02 );
		error_in_archive = PK_FIND;
		too_weird_to_continue = true;
#endif
	}

	diag( pG, "do_seekable, loc 6" );
	if ( !too_weird_to_continue ) {  /* (relatively) normal zipfile:  go for it */
		if ( error ) {
			printf( "maybe a pak bug in %s", pG->zipfn );
			error_in_archive = PK_WARN;
		}
		if ( (pG->extra_bytes = pG->real_ecrec_offset - pG->expect_ecrec_offset) < 0L ) {
			printf( "missing bytes in zipfile" );
			error_in_archive = PK_ERR;
		} else if ( pG->extra_bytes > 0 ) {
			if ( (pG->ecrec.offset_start_central_directory == 0) &&
                (pG->ecrec.size_central_directory != 0) ) {  /* zip 1.5 -go bug */
				printf( "NULL central dir" );
				pG->ecrec.offset_start_central_directory = pG->extra_bytes;
				pG->extra_bytes = 0;
				error_in_archive = PK_ERR;
			} else {
				printf( "Warning: extra bytes at start of zipfile" );
				error_in_archive = PK_WARN;
			}
		}

		/*-----------------------------------------------------------------------
		 *       Check for empty zipfile and exit now if so.
		 *-----------------------------------------------------------------------*/
		diag( pG, "do_seekable, loc 7" );
		if ( pG->expect_ecrec_offset == 0L && pG->ecrec.size_central_directory == 0 ) {
			printf( "Empty zipfile" );
			close( pG->zipfd );
			pG->zipfd = 0;		/* RCV added 29-1-99 */
			return (error_in_archive > PK_WARN) ? error_in_archive : PK_WARN;
		}

		/*-----------------------------------------------------------------------
		 * Compensate for missing or extra bytes, and seek to where the start
		 * of central directory should be.  If header not found, uncompensate
		 * and try again (necessary for at least some Atari archives created
		 * with STZip, as well as archives created by J.H. Holm's ZIPSPLIT 1.1).
		 *-----------------------------------------------------------------------*/
		ZLSEEK( pG->ecrec.offset_start_central_directory )
#ifdef OLD_SEEK_TEST
		if ( readbuf( pG->sig, 4 ) == 0 ) {
			close( pG->zipfd );
			pG->zipfd = 0;		/* RCV added 29-1-99 */
			return PK_ERR;		/* file may be locked, or possibly disk error(?) */
		}
		if ( strncmp( pG->sig, pG->central_hdr_sig, 4 ) )
#else
		if ( (readbuf( pG, pG->sig, 4 ) == 0) || strncmp( pG->sig, pG->central_hdr_sig, 4 ) )
#endif
		{
			// long tmp = pG->extra_bytes;

			diag( pG, "central dir found" );
			pG->extra_bytes = 0;
			ZLSEEK( pG->ecrec.offset_start_central_directory )
			if ( (readbuf( pG, pG->sig, 4 ) == 0 ) || strncmp( pG->sig, pG->central_hdr_sig, 4 ) ) {
				UnzErr( pG, UEN_FORM18 );
				close( pG->zipfd );
				pG->zipfd = 0;		/* RCV added 29-1-99 */
				return PK_BADERR;
			}
			printf( "central dir too long" );
			error_in_archive = PK_ERR;
		}
		/*-----------------------------------------------------------------------
		 * Seek to the start of the central directory one last time, since we
		 * have just read the first entry's signature bytes; then list, extract
		 * or test member files as instructed, and close the zipfile.
		 *-----------------------------------------------------------------------*/
		Trace( (pG, "about to extract/list files (error = %d)\n", error_in_archive) );
		ZLSEEK( pG->ecrec.offset_start_central_directory )

#ifdef TIMESTAMP
		// EWE  do some work here???
		// How can you timestamp a file before you extract it?
		//          if ( pG->T_flag )
		//              error = time_stamp( pG );              /* TIME-STAMP 'EM */
		//          else
#endif
		//          if ( pG->vflag && !pG->tflag && !pG->cflag )
		//              error = //list_files( pG );              /* LIST 'EM */
		//          else
		//              GO DO EXTRACT OR TEST
		error = extract_or_test_files( pG );   /* EXTRACT OR TEST 'EM */

		Trace( (pG, "Done with extract/list files (error = %d)\n", error) );
		if ( error > error_in_archive )   /* don't overwrite stronger error */
			error_in_archive = error;   /*  with (for example) a warning */
	} /* end if (!too_weird_to_continue) */