⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 extract.c

📁 zip压缩
💻 C
📖 第 1 页 / 共 5 页
字号:
/*  Copyright (c) 1990-2002 Info-ZIP.  All rights reserved.  See the accompanying file LICENSE, version 2000-Apr-09 or later  (the contents of which are also included in unzip.h) for terms of use.  If, for some reason, all these files are missing, the Info-ZIP license  also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html*//*---------------------------------------------------------------------------  extract.c  This file contains the high-level routines ("driver routines") for extrac-  ting and testing zipfile members.  It calls the low-level routines in files  explode.c, inflate.c, unreduce.c and unshrink.c.  Contains:  extract_or_test_files()             store_info()             extract_or_test_entrylist()             extract_or_test_member()             TestExtraField()             test_compr_eb()             memextract()             memflush()             extract_izvms_block()    (VMS or VMS_TEXT_CONV)             fnfilter()  ---------------------------------------------------------------------------*/#define __EXTRACT_C     /* identifies this source module */#define UNZIP_INTERNAL#include "unzip.h"#ifdef WINDLL#  ifdef POCKET_UNZIP#    include "wince/intrface.h"#  else#    include "windll/windll.h"#  endif#endif#include "crypt.h"#define GRRDUMP(buf,len) { \    int i, j; \ \    for (j = 0;  j < (len)/16;  ++j) { \        printf("        "); \        for (i = 0;  i < 16;  ++i) \            printf("%02x ", (uch)(buf)[i+(j<<4)]); \        printf("\n        "); \        for (i = 0;  i < 16;  ++i) { \            char c = (char)(buf)[i+(j<<4)]; \ \            if (c == '\n') \                printf("\\n "); \            else if (c == '\r') \                printf("\\r "); \            else \                printf(" %c ", c); \        } \        printf("\n"); \    } \    if ((len) % 16) { \        printf("        "); \        for (i = j<<4;  i < (len);  ++i) \            printf("%02x ", (uch)(buf)[i]); \        printf("\n        "); \        for (i = j<<4;  i < (len);  ++i) { \            char c = (char)(buf)[i]; \ \            if (c == '\n') \                printf("\\n "); \            else if (c == '\r') \                printf("\\r "); \            else \                printf(" %c ", c); \        } \        printf("\n"); \    } \}static int store_info OF((__GPRO));#ifdef SET_DIR_ATTRIBstatic int extract_or_test_entrylist OF((__GPRO__ unsigned numchunk,                ulg *pfilnum, ulg *pnum_bad_pwd, LONGINT *pold_extra_bytes,                unsigned *pnum_dirs, dirtime **pdirlist,                int error_in_archive));#elsestatic int extract_or_test_entrylist OF((__GPRO__ unsigned numchunk,                ulg *pfilnum, ulg *pnum_bad_pwd, LONGINT *pold_extra_bytes,                int error_in_archive));#endifstatic int extract_or_test_member OF((__GPRO));#ifndef SFX   static int TestExtraField OF((__GPRO__ uch *ef, unsigned ef_len));   static int test_compr_eb OF((__GPRO__ uch *eb, unsigned eb_size,        unsigned compr_offset,        int (*test_uc_ebdata)(__GPRO__ uch *eb, unsigned eb_size,                              uch *eb_ucptr, ulg eb_ucsize)));#endif#if (defined(VMS) || defined(VMS_TEXT_CONV))   static void decompress_bits OF((uch *outptr, unsigned needlen,                                   ZCONST uch *bitptr));#endif#ifdef SET_DIR_ATTRIB   static int dircomp OF((ZCONST zvoid *a, ZCONST zvoid *b));#endif/*******************************//*  Strings used in extract.c  *//*******************************/static ZCONST char Far VersionMsg[] =  "   skipping: %-22s  need %s compat. v%u.%u (can do v%u.%u)\n";static ZCONST char Far ComprMsgNum[] =  "   skipping: %-22s  unsupported compression method %u\n";#ifndef SFX   static ZCONST char Far ComprMsgName[] =     "   skipping: %-22s  `%s' method not supported\n";   static ZCONST char Far CmprNone[]       = "store";   static ZCONST char Far CmprShrink[]     = "shrink";   static ZCONST char Far CmprReduce[]     = "reduce";   static ZCONST char Far CmprImplode[]    = "implode";   static ZCONST char Far CmprTokenize[]   = "tokenize";   static ZCONST char Far CmprDeflate[]    = "deflate";   static ZCONST char Far CmprDeflat64[]   = "deflate64";   static ZCONST char Far CmprDCLImplode[] = "DCL implode";   static ZCONST char Far *ComprNames[NUM_METHODS] = {     CmprNone, CmprShrink, CmprReduce, CmprReduce, CmprReduce, CmprReduce,     CmprImplode, CmprTokenize, CmprDeflate, CmprDeflat64, CmprDCLImplode   };#endif /* !SFX */static ZCONST char Far FilNamMsg[] =  "%s:  bad filename length (%s)\n";static ZCONST char Far ExtFieldMsg[] =  "%s:  bad extra field length (%s)\n";static ZCONST char Far OffsetMsg[] =  "file #%lu:  bad zipfile offset (%s):  %ld\n";static ZCONST char Far ExtractMsg[] =  "%8sing: %-22s  %s%s";#ifndef SFX   static ZCONST char Far LengthMsg[] =     "%s  %s:  %ld bytes required to uncompress to %lu bytes;\n    %s\      supposed to require %lu bytes%s%s%s\n";#endifstatic ZCONST char Far BadFileCommLength[] = "%s:  bad file comment length\n";static ZCONST char Far LocalHdrSig[] = "local header sig";static ZCONST char Far BadLocalHdr[] = "file #%lu:  bad local header\n";static ZCONST char Far AttemptRecompensate[] =  "  (attempting to re-compensate)\n";#ifndef SFX   static ZCONST char Far BackslashPathSep[] =     "warning:  %s appears to use backslashes as path separators\n";#endifstatic ZCONST char Far AbsolutePathWarning[] =  "warning:  stripped absolute path spec from %s\n";static ZCONST char Far SkipVolumeLabel[] =  "   skipping: %-22s  %svolume label\n";#ifdef SET_DIR_ATTRIB  /* messages of code for setting directory attributes */   static ZCONST char Far DirlistEntryNoMem[] =     "warning:  cannot alloc memory for dir times/permissions/UID/GID\n";   static ZCONST char Far DirlistSortNoMem[] =     "warning:  cannot alloc memory to sort dir times/perms/etc.\n";   static ZCONST char Far DirlistSetAttrFailed[] =     "warning:  set times/attribs failed for %s\n";#endif#ifndef WINDLL   static ZCONST char Far ReplaceQuery[] =     "replace %s? [y]es, [n]o, [A]ll, [N]one, [r]ename: ";   static ZCONST char Far AssumeNone[] = " NULL\n(assuming [N]one)\n";   static ZCONST char Far NewNameQuery[] = "new name: ";   static ZCONST char Far InvalidResponse[] = "error:  invalid response [%c]\n";#endif /* !WINDLL */static ZCONST char Far ErrorInArchive[] =  "At least one %serror was detected in %s.\n";static ZCONST char Far ZeroFilesTested[] =  "Caution:  zero files tested in %s.\n";#ifndef VMS   static ZCONST char Far VMSFormatQuery[] =     "\n%s:  stored in VMS format.  Extract anyway? (y/n) ";#endif#if CRYPT   static ZCONST char Far SkipCannotGetPasswd[] =     "   skipping: %-22s  unable to get password\n";   static ZCONST char Far SkipIncorrectPasswd[] =     "   skipping: %-22s  incorrect password\n";   static ZCONST char Far FilesSkipBadPasswd[] =     "%lu file%s skipped because of incorrect password.\n";   static ZCONST char Far MaybeBadPasswd[] =     "    (may instead be incorrect password)\n";#else   static ZCONST char Far SkipEncrypted[] =     "   skipping: %-22s  encrypted (not supported)\n";#endifstatic ZCONST char Far NoErrInCompData[] =  "No errors detected in compressed data of %s.\n";static ZCONST char Far NoErrInTestedFiles[] =  "No errors detected in %s for the %lu file%s tested.\n";static ZCONST char Far FilesSkipped[] =  "%lu file%s skipped because of unsupported compression or encoding.\n";static ZCONST char Far ErrUnzipFile[] = "  error:  %s%s %s\n";static ZCONST char Far ErrUnzipNoFile[] = "\n  error:  %s%s\n";static ZCONST char Far NotEnoughMem[] = "not enough memory to ";static ZCONST char Far InvalidComprData[] = "invalid compressed data to ";static ZCONST char Far Inflate[] = "inflate";#ifndef SFX   static ZCONST char Far Explode[] = "explode";#ifndef LZW_CLEAN   static ZCONST char Far Unshrink[] = "unshrink";#endif#endif#if (!defined(DELETE_IF_FULL) || !defined(HAVE_UNLINK))   static ZCONST char Far FileTruncated[] =     "warning:  %s is probably truncated\n";#endifstatic ZCONST char Far FileUnknownCompMethod[] =  "%s:  unknown compression method\n";static ZCONST char Far BadCRC[] = " bad CRC %08lx  (should be %08lx)\n";      /* TruncEAs[] also used in OS/2 mapname(), close_outfile() */char ZCONST Far TruncEAs[] = " compressed EA data missing (%d bytes)%s";char ZCONST Far TruncNTSD[] =  " compressed WinNT security data missing (%d bytes)%s";#ifndef SFX   static ZCONST char Far InconsistEFlength[] = "bad extra-field entry:\n \     EF block length (%u bytes) exceeds remaining EF data (%u bytes)\n";   static ZCONST char Far InvalidComprDataEAs[] =     " invalid compressed data for EAs\n";#  if (defined(WIN32) && defined(NTSD_EAS))     static ZCONST char Far InvalidSecurityEAs[] =       " EAs fail security check\n";#  endif   static ZCONST char Far UnsuppNTSDVersEAs[] =     " unsupported NTSD EAs version %d\n";   static ZCONST char Far BadCRC_EAs[] = " bad CRC for extended attributes\n";   static ZCONST char Far UnknComprMethodEAs[] =     " unknown compression method for EAs (%u)\n";   static ZCONST char Far NotEnoughMemEAs[] =     " out of memory while inflating EAs\n";   static ZCONST char Far UnknErrorEAs[] =     " unknown error on extended attributes\n";#endif /* !SFX */static ZCONST char Far UnsupportedExtraField[] =  "\nerror:  unsupported extra-field compression type (%u)--skipping\n";static ZCONST char Far BadExtraFieldCRC[] =  "error [%s]:  bad extra-field CRC %08lx (should be %08lx)\n";/**************************************//*  Function extract_or_test_files()  *//**************************************/int extract_or_test_files(__G)    /* return PK-type error code */     __GDEF{    unsigned i, j;    long cd_bufstart;    uch *cd_inptr;    int cd_incnt;    ulg filnum=0L, blknum=0L;    int reached_end, no_endsig_found;    int error, error_in_archive=PK_COOL;    int *fn_matched=NULL, *xn_matched=NULL;    unsigned members_processed;    ulg num_skipped=0L, num_bad_pwd=0L;    LONGINT old_extra_bytes = 0L;#ifdef SET_DIR_ATTRIB    unsigned num_dirs=0;    dirtime *dirlist=(dirtime *)NULL, **sorted_dirlist=(dirtime **)NULL;#endif/*---------------------------------------------------------------------------    The basic idea of this function is as follows.  Since the central di-    rectory lies at the end of the zipfile and the member files lie at the    beginning or middle or wherever, it is not very desirable to simply    read a central directory entry, jump to the member and extract it, and    then jump back to the central directory.  In the case of a large zipfile    this would lead to a whole lot of disk-grinding, especially if each mem-    ber file is small.  Instead, we read from the central directory the per-    tinent information for a block of files, then go extract/test the whole    block.  Thus this routine contains two small(er) loops within a very    large outer loop:  the first of the small ones reads a block of files    from the central directory; the second extracts or tests each file; and    the outer one loops over blocks.  There's some file-pointer positioning    stuff in between, but that's about it.  Btw, it's because of this jump-    ing around that we can afford to be lenient if an error occurs in one of    the member files:  we should still be able to go find the other members,    since we know the offset of each from the beginning of the zipfile.  ---------------------------------------------------------------------------*/    G.pInfo = G.info;#if CRYPT    G.newzip = TRUE;#endif#ifndef SFX    G.reported_backslash = FALSE;#endif    /* malloc space for check on unmatched filespecs (OK if one or both NULL) */    if (G.filespecs > 0  &&        (fn_matched=(int *)malloc(G.filespecs*sizeof(int))) != (int *)NULL)        for (i = 0;  i < G.filespecs;  ++i)            fn_matched[i] = FALSE;    if (G.xfilespecs > 0  &&        (xn_matched=(int *)malloc(G.xfilespecs*sizeof(int))) != (int *)NULL)        for (i = 0;  i < G.xfilespecs;  ++i)            xn_matched[i] = FALSE;/*---------------------------------------------------------------------------    Begin main loop over blocks of member files.  We know the entire central    directory is on this disk:  we would not have any of this information un-    less the end-of-central-directory record was on this disk, and we would

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -