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 + -
显示快捷键?