📄 extract.c
字号:
#ifndef VMS /* VMS creates higher version number instead of overwriting * (will have to modify for VMS-style names with specific * version numbers: just check V_flag? don't use stat?) */ if (query) { fprintf(stderr, "replace %s? [y]es, [n]o, [A]ll, [N]one, [r]ename: ", filename); FFLUSH /* for Amiga and Mac MPW */ fgets(answerbuf, 9, stdin); switch (*answerbuf) { case 'A': /* dangerous option: force caps */ overwrite_all = TRUE; overwrite_none = FALSE; /* just to make sure */ break; case 'r': case 'R': do { fprintf(stderr, "new name: "); FFLUSH /* for AMIGA and Mac MPW */ fgets(filename, FILNAMSIZ, stdin); /* usually get \n here: better check for it */ len = strlen(filename); if (filename[len-1] == '\n') filename[--len] = 0; } while (len == 0); renamed = TRUE; goto startover; /* sorry for a goto */ /* break; (never reached--dpk) */ case 'y': case 'Y': break; case 'N': overwrite_none = TRUE; overwrite_all = FALSE; /* make sure */ force_flag = FALSE; /* ditto */ /* FALL THROUGH, skip */ case 'n': default: continue; /* skip file */ } /* end switch (*answerbuf) */ } /* end if (query) */#endif /* !VMS */ } /* end if (extracting to disk) */#ifdef CRYPT if (pInfo->encrypted && ((error = decrypt_member()) != 0)) { fprintf(stderr, " skipping: %-22s incorrect password\n", filename); ++num_bad_pwd; /* if (error > error_in_archive) >>until fix up error return<< error_in_archive = error; unable to test file... */ continue; /* go on to next file */ /* GRR: add loop here (2 or 3 times) for bad passwords */ }#endif /* CRYPT */ disk_full = 0; if ((error = extract_or_test_member()) != 0) { if (error > error_in_archive) error_in_archive = error; /* ...and keep going */ if (disk_full > 1) return error_in_archive; /* (unless disk full) */ } } /* end for-loop (i: files in current block) */ /* * Jump back to where we were in the central directory, then go and do * the next batch of files. */ cur_zipfile_bufstart = lseek(zipfd, cd_bufstart, SEEK_SET); read(zipfd, (char *)inbuf, INBUFSIZ); /* were there b4 ==> no error */ inptr = cd_inptr; 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", inptr-inbuf); printf("incnt = %d\n\n", incnt);#endif } /* end while-loop (blocks of files in central directory) *//*--------------------------------------------------------------------------- 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. ---------------------------------------------------------------------------*/ readbuf(sig, 4); if (strncmp(sig, end_central_sig, 4)) { /* just to make sure again */ fprintf(stderr, EndSigMsg); /* didn't find end-of-central-dir sig */ fprintf(stderr, ReportMsg); /* check binary transfers */ if (!error_in_archive) /* don't overwrite stronger error */ error_in_archive = 1; /* 1: warning error */ } if (tflag && (quietflg == 1)) { int num=filnum+1 - num_bad_pwd; if (error_in_archive) printf("At least one error was detected in %s.\n", zipfn); else if (num == 0) printf("Caution: zero files tested in %s.\n", zipfn); else if (process_all_files && (num_skipped+num_bad_pwd == 0)) printf("No errors detected in %s.\n", zipfn); else printf("No errors detected in %s for the %d file%s tested.\n", zipfn, num, (num==1)? "":"s"); if (num_skipped > 0) printf("%d file%s skipped because of unsupported compression or\ encoding.\n", num_skipped, (num_skipped==1)? "":"s");#ifdef CRYPT if (num_bad_pwd > 0) printf("%d file%s skipped because of incorrect password.\n", num_bad_pwd, (num_bad_pwd==1)? "":"s");#endif /* CRYPT */ } if ((num_skipped > 0) && !error_in_archive) /* files not tested or */ error_in_archive = 1; /* extracted: warning */#ifdef CRYPT if ((num_bad_pwd > 0) && !error_in_archive) /* files not tested or */ error_in_archive = 1; /* extracted: warning */#endif /* CRYPT */ return (error_in_archive);} /* end function extract_or_test_files() *//***************************//* Function store_info() *//***************************/static int store_info() /* return 1 if skipping, 0 if OK */{ ULONG tmp;#ifdef INFLATE# define UNKN_COMPR \ (crec.compression_method>IMPLODED && crec.compression_method!=DEFLATED)#else# define UNKN_COMPR (crec.compression_method>IMPLODED)#endif/*--------------------------------------------------------------------------- Check central directory info for version/compatibility requirements. ---------------------------------------------------------------------------*/ pInfo->encrypted = crec.general_purpose_bit_flag & 1; /* bit field */ pInfo->ExtLocHdr = (crec.general_purpose_bit_flag & 8) == 8; /* bit */ pInfo->text = crec.internal_file_attributes & 1; /* bit field *//* pInfo->crc = crec.crc32; (no longer used) */ if (crec.version_needed_to_extract[1] == VMS_) { if (crec.version_needed_to_extract[0] > VMS_VERSION) { fprintf(stderr, VersionMsg, filename, "VMS", crec.version_needed_to_extract[0] / 10, crec.version_needed_to_extract[0] % 10, VMS_VERSION / 10, VMS_VERSION % 10); return 1; }#ifndef VMS /* won't be able to use extra field, but still have data */ else if (!tflag && !force_flag) { /* if forcing, extract regardless */ fprintf(stderr, "\n%s: stored in VMS format. Extract anyway? (y/n) ", filename); FFLUSH /* for Amiga and Mac MPW */ fgets(answerbuf, 9, stdin); if ((*answerbuf != 'y') && (*answerbuf != 'Y')) return 1; }#endif /* !VMS */ /* usual file type: don't need VMS to extract */ } else if (crec.version_needed_to_extract[0] > UNZIP_VERSION) { fprintf(stderr, VersionMsg, filename, "PK", crec.version_needed_to_extract[0] / 10, crec.version_needed_to_extract[0] % 10, UNZIP_VERSION / 10, UNZIP_VERSION % 10); return 1; } if UNKN_COMPR { fprintf(stderr, ComprMsg, filename, crec.compression_method); return 1; }#ifndef CRYPT if (pInfo->encrypted) { fprintf(stderr, " skipping: %-22s encrypted (not supported)\n", filename); return 1; }#endif /* !CRYPT *//*--------------------------------------------------------------------------- Store some central-directory information (encryption, file attributes, offsets) for later use. ---------------------------------------------------------------------------*/ tmp = crec.external_file_attributes; pInfo->dos_attr = 32; /* set archive bit: file is not backed up */ switch (pInfo->hostnum) { case UNIX_: case VMS_: pInfo->unix_attr = tmp >> 16; break; case DOS_OS2_FAT_: case OS2_HPFS_: pInfo->dos_attr = (unsigned) tmp; tmp = (!(tmp & 1)) << 1; /* read-only bit */ pInfo->unix_attr = 0444 | (tmp<<6) | (tmp<<3) | tmp;#ifdef UNIX umask( (int)(tmp=umask(0)) ); pInfo->unix_attr &= ~tmp;#endif break; case MAC_: tmp &= 1; /* read-only bit */ pInfo->unix_attr = tmp; break; default: pInfo->unix_attr = 0666; break; } /* end switch (host-OS-created-by) */ pInfo->offset = (longint) crec.relative_offset_local_header; return 0;} /* end function store_info() *//***************************************//* Function extract_or_test_member() *//***************************************/static int extract_or_test_member() /* return PK-type error code */{#ifdef S_IFLNK int symlnk=FALSE;#endif /* S_IFLNK */ int error=0; UWORD b;/*--------------------------------------------------------------------------- Initialize variables, buffers, etc. ---------------------------------------------------------------------------*/ bits_left = 0; bitbuf = 0L; outpos = 0L; outcnt = 0; outptr = outbuf; zipeof = 0; crc32val = 0xFFFFFFFFL;#ifdef S_IFLNK if ((pInfo->unix_attr & S_IFMT) == S_IFLNK && (pInfo->hostnum == UNIX_) && !tflag && !cflag) symlnk = TRUE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -