📄 process.c
字号:
((error_in_archive = find_ecrec(__G__ MIN(G.ziplen,66000L))) != 0 || (error_in_archive = uz_end_central(__G)) > PK_WARN))) { CLOSE_INFILE();#ifdef SFX ++lastchance; /* avoid picky compiler warnings */ return error_in_archive;#else if (maybe_exe) Info(slide, 0x401, ((char *)slide, LoadFarString(MaybeExe), G.zipfn)); if (lastchance) return error_in_archive; else { G.no_ecrec = TRUE; /* assume we found wrong file: e.g., */ return PK_NOZIP; /* unzip instead of unzip.zip */ }#endif /* ?SFX */ } if ((uO.zflag > 0) && !uO.zipinfo_mode) { /* unzip: zflag = comment ONLY */ CLOSE_INFILE(); 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 = !uO.zipinfo_mode && (G.ecrec.number_this_disk == 1) && (G.ecrec.num_disk_start_cdir == 1);#else error = !uO.zipinfo_mode && (G.ecrec.number_this_disk != 0);#endif#ifndef SFX if (uO.zipinfo_mode && G.ecrec.number_this_disk != G.ecrec.num_disk_start_cdir) { if (G.ecrec.number_this_disk > G.ecrec.num_disk_start_cdir) { Info(slide, 0x401, ((char *)slide, LoadFarString(CentDirNotInZipMsg), G.zipfn, G.ecrec.number_this_disk, G.ecrec.num_disk_start_cdir)); error_in_archive = PK_FIND; too_weird_to_continue = TRUE; } else { Info(slide, 0x401, ((char *)slide, LoadFarString(EndCentDirBogus), G.zipfn, G.ecrec.number_this_disk, G.ecrec.num_disk_start_cdir)); error_in_archive = PK_WARN; }#ifdef NO_MULTIPART /* concatenation of multiple parts works in some cases */ } else if (!uO.zipinfo_mode && !error && G.ecrec.number_this_disk != 0) { Info(slide, 0x401, ((char *)slide, LoadFarString(NoMultiDiskArcSupport), G.zipfn)); error_in_archive = PK_FIND; too_weird_to_continue = TRUE;#endif } if (!too_weird_to_continue) { /* (relatively) normal zipfile: go for it */ if (error) { Info(slide, 0x401, ((char *)slide, LoadFarString(MaybePakBug), G.zipfn)); error_in_archive = PK_WARN; }#endif /* !SFX */ if ((G.extra_bytes = G.real_ecrec_offset-G.expect_ecrec_offset) < (Z_OFF_T)0) { Info(slide, 0x401, ((char *)slide, LoadFarString(MissingBytes), G.zipfn, (long)(-G.extra_bytes))); error_in_archive = PK_ERR; } else if (G.extra_bytes > 0) { if ((G.ecrec.offset_start_central_directory == 0) && (G.ecrec.size_central_directory != 0)) /* zip 1.5 -go bug */ { Info(slide, 0x401, ((char *)slide, LoadFarString(NullCentDirOffset), G.zipfn)); G.ecrec.offset_start_central_directory = G.extra_bytes; G.extra_bytes = 0; error_in_archive = PK_ERR; }#ifndef SFX else { Info(slide, 0x401, ((char *)slide, LoadFarString(ExtraBytesAtStart), G.zipfn, (long)G.extra_bytes, (G.extra_bytes == 1)? "":"s")); error_in_archive = PK_WARN; }#endif /* !SFX */ } /*----------------------------------------------------------------------- Check for empty zipfile and exit now if so. -----------------------------------------------------------------------*/ if (G.expect_ecrec_offset==0L && G.ecrec.size_central_directory==0) { if (uO.zipinfo_mode) Info(slide, 0, ((char *)slide, "%sEmpty zipfile.\n", uO.lflag>9? "\n " : "")); else Info(slide, 0x401, ((char *)slide, LoadFarString(ZipfileEmpty), G.zipfn)); CLOSE_INFILE(); 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). -----------------------------------------------------------------------*/ error = seek_zipf(__G__ G.ecrec.offset_start_central_directory); if (error == PK_BADERR) { CLOSE_INFILE(); return PK_BADERR; }#ifdef OLD_SEEK_TEST if (error != PK_OK || readbuf(__G__ G.sig, 4) == 0) { CLOSE_INFILE(); return PK_ERR; /* file may be locked, or possibly disk error(?) */ } if (strncmp(G.sig, central_hdr_sig, 4))#else if ((error != PK_OK) || (readbuf(__G__ G.sig, 4) == 0) || strncmp(G.sig, central_hdr_sig, 4))#endif {#ifndef SFX long tmp = G.extra_bytes;#endif G.extra_bytes = 0; error = seek_zipf(__G__ G.ecrec.offset_start_central_directory); if ((error != PK_OK) || (readbuf(__G__ G.sig, 4) == 0) || strncmp(G.sig, central_hdr_sig, 4)) { if (error != PK_BADERR) Info(slide, 0x401, ((char *)slide, LoadFarString(CentDirStartNotFound), G.zipfn, LoadFarStringSmall(ReportMsg))); CLOSE_INFILE(); return (error != PK_OK ? error : PK_BADERR); }#ifndef SFX Info(slide, 0x401, ((char *)slide, LoadFarString(CentDirTooLong), G.zipfn, -tmp));#endif 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. -----------------------------------------------------------------------*/ error = seek_zipf(__G__ G.ecrec.offset_start_central_directory); if (error != PK_OK) { CLOSE_INFILE(); return error; } Trace((stderr, "about to extract/list files (error = %d)\n", error_in_archive));#ifdef DLL /* G.fValidate is used only to look at an archive to see if it appears to be a valid archive. There is no interest in what the archive contains, nor in validating that the entries in the archive are in good condition. This is currently used only in the Windows DLLs for purposes of checking archives within an archive to determine whether or not to display the inner archives. */ if (!G.fValidate)#endif {#ifndef NO_ZIPINFO if (uO.zipinfo_mode) error = zipinfo(__G); /* ZIPINFO 'EM */ else#endif#ifndef SFX#ifdef TIMESTAMP if (uO.T_flag) error = get_time_stamp(__G__ &uxstamp, &nmember); else#endif if (uO.vflag && !uO.tflag && !uO.cflag) error = list_files(__G); /* LIST 'EM */ else#endif /* !SFX */ error = extract_or_test_files(__G); /* EXTRACT OR TEST 'EM */ Trace((stderr, "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 */#ifndef SFX } /* end if (!too_weird_to_continue) */#endif CLOSE_INFILE();#ifdef TIMESTAMP if (uO.T_flag && !uO.zipinfo_mode && (nmember > 0L)) {# ifdef WIN32 if (stamp_file(__G__ G.zipfn, uxstamp)) { /* TIME-STAMP 'EM */# else if (stamp_file(G.zipfn, uxstamp)) { /* TIME-STAMP 'EM */# endif if (uO.qflag < 3) Info(slide, 0x201, ((char *)slide, "warning: cannot set time for %s\n", G.zipfn)); if (error_in_archive < PK_WARN) error_in_archive = PK_WARN; } }#endif return error_in_archive;} /* end function do_seekable() *//*************************//* Function find_ecrec() *//*************************/static int find_ecrec(__G__ searchlen) /* return PK-class error */ __GDEF long searchlen;{ int i, numblks, found=FALSE; Z_OFF_T tail_len; ec_byte_rec byterec;/*--------------------------------------------------------------------------- Treat case of short zipfile separately. ---------------------------------------------------------------------------*/ if (G.ziplen <= INBUFSIZ) { lseek(G.zipfd, 0L, SEEK_SET); if ((G.incnt = read(G.zipfd,(char *)G.inbuf,(unsigned int)G.ziplen)) == (int)G.ziplen) /* 'P' must be at least (ECREC_SIZE+4) bytes from end of zipfile */ for (G.inptr = G.inbuf+(int)G.ziplen-(ECREC_SIZE+4); G.inptr >= G.inbuf; --G.inptr) { if ( (*G.inptr == (uch)0x50) && /* ASCII 'P' */ !strncmp((char *)G.inptr, end_central_sig, 4)) { G.incnt -= (int)(G.inptr - G.inbuf); found = TRUE; break; } }/*--------------------------------------------------------------------------- Zipfile is longer than INBUFSIZ: may need to loop. Start with short block at end of zipfile (if not TOO short). ---------------------------------------------------------------------------*/ } else { if ((tail_len = G.ziplen % INBUFSIZ) > ECREC_SIZE) {#ifdef USE_STRM_INPUT fseek((FILE *)G.zipfd, G.ziplen-tail_len, SEEK_SET); G.cur_zipfile_bufstart = ftell((FILE *)G.zipfd);#else /* !USE_STRM_INPUT */ G.cur_zipfile_bufstart = lseek(G.zipfd, G.ziplen-tail_len, SEEK_SET);#endif /* ?USE_STRM_INPUT */ if ((G.incnt = read(G.zipfd, (char *)G.inbuf, (unsigned int)tail_len)) != (int)tail_len) goto fail; /* it's expedient... */ /* 'P' must be at least (ECREC_SIZE+4) bytes from end of zipfile */ for (G.inptr = G.inbuf+(int)tail_len-(ECREC_SIZE+4); G.inptr >= G.inbuf; --G.inptr) { if ( (*G.inptr == (uch)0x50) && /* ASCII 'P' */ !strncmp((char *)G.inptr, end_central_sig, 4)) { G.incnt -= (int)(G.inptr - G.inbuf); found = TRUE; break; } } /* sig may span block boundary: */ memcpy((char *)G.hold, (char *)G.inbuf, 3); } else G.cur_zipfile_bufstart = G.ziplen - tail_len; /*----------------------------------------------------------------------- Loop through blocks of zipfile data, starting at the end and going toward the beginning. In general, need not check whole zipfile for signature, but may want to do so if testing. -----------------------------------------------------------------------*/ numblks = (int)((searchlen - tail_len + (INBUFSIZ-1)) / INBUFSIZ); /* ==amount= ==done== ==rounding== =blksiz= */ for (i = 1; !found && (i <= numblks); ++i) { G.cur_zipfile_bufstart -= INBUFSIZ; lseek(G.zipfd, G.cur_zipfile_bufstart, SEEK_SET); if ((G.incnt = read(G.zipfd,(char *)G.inbuf,INBUFSIZ)) != INBUFSIZ) break; /* fall through and fail */ for (G.inptr = G.inbuf+INBUFSIZ-1; G.inptr >= G.inbuf; --G.inptr) if ((native(*G.inptr) == 'P') && !strncmp((char *)G.inptr, end_central_sig, 4)) { G.incnt -= (int)(G.inptr - G.inbuf); found = TRUE; break; } /* sig may span block boundary: */ memcpy((char *)G.hold, (char *)G.inbuf, 3); } } /* end if (ziplen > INBUFSIZ) *//*--------------------------------------------------------------------------- Searched through whole region where signature should be without finding it. Print informational message and die a horrible death.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -