extract.c

来自「zip压缩」· C语言 代码 · 共 1,655 行 · 第 1/5 页

C
1,655
字号
    not have gotten to this routine unless this is also the disk on which    the central directory starts.  In practice, this had better be the ONLY    disk in the archive, but we'll add multi-disk support soon.  ---------------------------------------------------------------------------*/    members_processed = 0;    no_endsig_found = FALSE;    reached_end = FALSE;    while (!reached_end) {        j = 0;#ifdef AMIGA        memzero(G.filenotes, DIR_BLKSIZ * sizeof(char *));#endif        /*         * Loop through files in central directory, storing offsets, file         * attributes, case-conversion and text-conversion flags until block         * size is reached.         */        while ((j < DIR_BLKSIZ)) {            G.pInfo = &G.info[j];            if (readbuf(__G__ G.sig, 4) == 0) {                error_in_archive = PK_EOF;                reached_end = TRUE;     /* ...so no more left to do */                break;            }            if (strncmp(G.sig, central_hdr_sig, 4)) {  /* is it a new entry? */                /* no new central directory entry                 * -> is the number of processed entries compatible with the                 *    number of entries as stored in the end_central record?                 */                if ((members_processed & (unsigned)0xFFFF) ==                    (unsigned)G.ecrec.total_entries_central_dir) {                    /* yes, so look if we ARE back at the end_central record                     */                    no_endsig_found =                      (strncmp(G.sig, end_central_sig, 4) != 0);                } else {                    /* no; we have found an error in the central directory                     * -> report it and stop searching for more Zip entries                     */                    Info(slide, 0x401, ((char *)slide,                      LoadFarString(CentSigMsg), j + blknum*DIR_BLKSIZ + 1));                    Info(slide, 0x401, ((char *)slide,                      LoadFarString(ReportMsg)));                    error_in_archive = PK_BADERR;                }                reached_end = TRUE;     /* ...so no more left to do */                break;            }            /* process_cdir_file_hdr() sets pInfo->hostnum, pInfo->lcflag */            if ((error = process_cdir_file_hdr(__G)) != PK_COOL) {                error_in_archive = error;   /* only PK_EOF defined */                reached_end = TRUE;     /* ...so no more left to do */                break;            }            if ((error = do_string(__G__ G.crec.filename_length, DS_FN)) !=                 PK_COOL)            {                if (error > error_in_archive)                    error_in_archive = error;                if (error > PK_WARN) {  /* fatal:  no more left to do */                    Info(slide, 0x401, ((char *)slide, LoadFarString(FilNamMsg),                      FnFilter1(G.filename), "central"));                    reached_end = TRUE;                    break;                }            }            if ((error = do_string(__G__ G.crec.extra_field_length,                EXTRA_FIELD)) != 0)            {                if (error > error_in_archive)                    error_in_archive = error;                if (error > PK_WARN) {  /* fatal */                    Info(slide, 0x401, ((char *)slide,                      LoadFarString(ExtFieldMsg),                      FnFilter1(G.filename), "central"));                    reached_end = TRUE;                    break;                }            }#ifdef AMIGA            G.filenote_slot = j;            if ((error = do_string(__G__ G.crec.file_comment_length,                                   uO.N_flag ? FILENOTE : SKIP)) != PK_COOL)#else            if ((error = do_string(__G__ G.crec.file_comment_length, SKIP))                != PK_COOL)#endif            {                if (error > error_in_archive)                    error_in_archive = error;                if (error > PK_WARN) {  /* fatal */                    Info(slide, 0x421, ((char *)slide,                      LoadFarString(BadFileCommLength),                      FnFilter1(G.filename)));                    reached_end = TRUE;                    break;                }            }            if (G.process_all_files) {                if (store_info(__G))                    ++j;  /* file is OK; info[] stored; continue with next */                else                    ++num_skipped;            } else {                int   do_this_file;                if (G.filespecs == 0)                    do_this_file = TRUE;                else {  /* check if this entry matches an `include' argument */                    do_this_file = FALSE;                    for (i = 0; i < G.filespecs; i++)                        if (match(G.filename, G.pfnames[i], uO.C_flag)) {                            do_this_file = TRUE;  /* ^-- ignore case or not? */                            if (fn_matched)                                fn_matched[i] = TRUE;                            break;       /* found match, so stop looping */                        }                }                if (do_this_file) {  /* check if this is an excluded file */                    for (i = 0; i < G.xfilespecs; i++)                        if (match(G.filename, G.pxnames[i], uO.C_flag)) {                            do_this_file = FALSE; /* ^-- ignore case or not? */                            if (xn_matched)                                xn_matched[i] = TRUE;                            break;                        }                }                if (do_this_file) {                    if (store_info(__G))                        ++j;            /* file is OK */                    else                        ++num_skipped;  /* unsupp. compression or encryption */                }            } /* end if (process_all_files) */            members_processed++;        } /* end while-loop (adding files to current block) */        /* save position in central directory so can come back later */        cd_bufstart = G.cur_zipfile_bufstart;        cd_inptr = G.inptr;        cd_incnt = G.incnt;    /*-----------------------------------------------------------------------        Second loop:  process files in current block, extracting or testing        each one.      -----------------------------------------------------------------------*/        error = extract_or_test_entrylist(__G__ j,                        &filnum, &num_bad_pwd, &old_extra_bytes,#ifdef SET_DIR_ATTRIB                        &num_dirs, &dirlist,#endif                        error_in_archive);        if (error != PK_COOL) {            if (error > error_in_archive)                error_in_archive = error;       /* ...and keep going */            if (G.disk_full > 1 || error_in_archive == IZ_CTRLC) {                if (fn_matched)                    free((zvoid *)fn_matched);                if (xn_matched)                    free((zvoid *)xn_matched);                return error_in_archive;        /* (unless disk full) */            }        }        /*         * Jump back to where we were in the central directory, then go and do         * the next batch of files.         */#ifdef USE_STRM_INPUT        fseek((FILE *)G.zipfd, (LONGINT)cd_bufstart, SEEK_SET);        G.cur_zipfile_bufstart = ftell((FILE *)G.zipfd);#else /* !USE_STRM_INPUT */        G.cur_zipfile_bufstart =          lseek(G.zipfd, (LONGINT)cd_bufstart, SEEK_SET);#endif /* ?USE_STRM_INPUT */        read(G.zipfd, (char *)G.inbuf, INBUFSIZ);  /* been here before... */        G.inptr = cd_inptr;        G.incnt = cd_incnt;        ++blknum;#ifdef TEST        printf("\ncd_bufstart = %ld (%.8lXh)\n", cd_bufstart, cd_bufstart);        printf("cur_zipfile_bufstart = %ld (%.8lXh)\n", cur_zipfile_bufstart,          cur_zipfile_bufstart);        printf("inptr-inbuf = %d\n", G.inptr-G.inbuf);        printf("incnt = %d\n\n", G.incnt);#endif    } /* end while-loop (blocks of files in central directory) *//*---------------------------------------------------------------------------    Go back through saved list of directories, sort and set times/perms/UIDs    and GIDs from the deepest level on up.  ---------------------------------------------------------------------------*/#ifdef SET_DIR_ATTRIB    if (num_dirs > 0) {        sorted_dirlist = (dirtime **)malloc(num_dirs*sizeof(dirtime *));        if (sorted_dirlist == (dirtime **)NULL) {            Info(slide, 0x401, ((char *)slide,              LoadFarString(DirlistSortNoMem)));            while (dirlist != (dirtime *)NULL) {                dirtime *d = dirlist;                dirlist = dirlist->next;                free(d);            }        } else {            if (num_dirs == 1)                sorted_dirlist[0] = dirlist;            else {                for (i = 0;  i < num_dirs;  ++i) {                    sorted_dirlist[i] = dirlist;                    dirlist = dirlist->next;                }                qsort((char *)sorted_dirlist, num_dirs, sizeof(dirtime *),                  dircomp);            }            Trace((stderr, "setting directory times/perms/attributes\n"));            for (i = 0;  i < num_dirs;  ++i) {                dirtime *d = sorted_dirlist[i];                Trace((stderr, "dir = %s\n", d->fn));                if ((error = set_direc_attribs(__G__ d)) != PK_OK) {                    Info(slide, 0x201, ((char *)slide,                      LoadFarString(DirlistSetAttrFailed), d->fn));                    if (!error_in_archive)                        error_in_archive = error;                }                free(d->fn);                free(d);            }            free(sorted_dirlist);        }    }#endif /* SET_DIR_ATTRIB */#if (defined(WIN32) && defined(NTSD_EAS))    process_defer_NT(__G);  /* process any deferred items for this .zip file */#endif/*---------------------------------------------------------------------------    Check for unmatched filespecs on command line and print warning if any    found.  Free allocated memory.  ---------------------------------------------------------------------------*/    if (fn_matched) {        for (i = 0;  i < G.filespecs;  ++i)            if (!fn_matched[i]) {#ifdef DLL                if (!G.redirect_data && !G.redirect_text)                    Info(slide, 0x401, ((char *)slide,                      LoadFarString(FilenameNotMatched), G.pfnames[i]));                else                    setFileNotFound(__G);#else                Info(slide, 1, ((char *)slide,                  LoadFarString(FilenameNotMatched), G.pfnames[i]));#endif                if (error_in_archive <= PK_WARN)                    error_in_archive = PK_FIND;   /* some files not found */            }        free((zvoid *)fn_matched);    }    if (xn_matched) {        for (i = 0;  i < G.xfilespecs;  ++i)            if (!xn_matched[i])                Info(slide, 0x401, ((char *)slide,                  LoadFarString(ExclFilenameNotMatched), G.pxnames[i]));        free((zvoid *)xn_matched);    }/*---------------------------------------------------------------------------    Double-check that we're back at the end-of-central-directory record, and    print quick summary of results, if we were just testing the archive.  We    send the summary to stdout so that people doing the testing in the back-    ground and redirecting to a file can just do a "tail" on the output file.  ---------------------------------------------------------------------------*/#ifndef SFX    if (no_endsig_found) {                      /* just to make sure */        Info(slide, 0x401, ((char *)slide, LoadFarString(EndSigMsg)));        Info(slide, 0x401, ((char *)slide, LoadFarString(ReportMsg)));        if (!error_in_archive)       /* don't overwrite stronger error */            error_in_archive = PK_WARN;    }#endif /* !SFX */    if (uO.tflag) {        ulg num = filnum - num_bad_pwd;        if (uO.qflag < 2) {        /* GRR 930710:  was (uO.qflag == 1) */            if (error_in_archive)                Info(slide, 0, ((char *)slide, LoadFarString(ErrorInArchive),                  (error_in_archive == PK_WARN)? "warning-" : "", G.zipfn));            else if (num == 0L)                Info(slide, 0, ((char *)slide, LoadFarString(ZeroFilesTested),                  G.zipfn));            else if (G.process_all_files && (num_skipped+num_bad_pwd == 0L))                Info(slide, 0, ((char *)slide, LoadFarString(NoErrInCompData),                  G.zipfn));            else                Info(slide, 0, ((char *)slide, LoadFarString(NoErrInTestedFiles)                  , G.zipfn, num, (num==1L)? "":"s"));            if (num_skipped > 0L)                Info(slide, 0, ((char *)slide, LoadFarString(FilesSkipped),                  num_skipped, (num_skipped==1L)? "":"s"));#if CRYPT            if (num_bad_pwd > 0L)                Info(slide, 0, ((char *)slide, LoadFarString(FilesSkipBadPasswd)                  , num_bad_pwd, (num_bad_pwd==1L)? "":"s"));#endif /* CRYPT */        } else if ((uO.qflag == 0) && !error_in_archive && (num == 0))            Info(slide, 0, ((char *)slide, LoadFarString(ZeroFilesTested),              G.zipfn));    }    /* give warning if files not tested or extracted (first condition can still     * happen if zipfile is empty and no files specified on command line) */    if ((filnum == 0) && error_in_archive <= PK_WARN) {        if (num_skipped > 0L)

⌨️ 快捷键说明

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