📄 unzip.c
字号:
#ifdef DEBUG_STRUC printf("local_file_hdr size: %X\n", sizeof(local_file_hdr)); printf("local_byte_hdr size: %X\n", sizeof(local_byte_hdr)); printf("actual size of local headers: %X\n", LREC_SIZE); printf("central directory header size: %X\n", sizeof(cdir_file_hdr)); printf("central directory byte header size: %X\n", sizeof(cdir_byte_hdr)); printf("actual size of central dir headers: %X\n", CREC_SIZE); printf("end central dir record size: %X\n", sizeof(ecdir_rec)); printf("end central dir byte record size: %X\n", sizeof(ec_byte_rec)); printf("actual size of end-central-dir record: %X\n", ECREC_SIZE);#endif /* DEBUG_STRUC *//*--------------------------------------------------------------------------- Rip through any command-line options lurking about... ---------------------------------------------------------------------------*/ while (--argc > 0 && (*++argv)[0] == '-') { s = argv[0] + 1; while ((c = *s++) != 0) { /* "!= 0": prevent Turbo C warning */ switch (c) { case ('a'): ++aflag; break;#if 0 case ('s'): ++sflag; break;#endif case ('c'): ++cflag;#ifdef NATIVE ++aflag; /* this is so you can read it on the screen */#endif break; case ('d'): /* re-create directory structure (now by default) */ break; case ('e'): /* just ignore -e, -x options (extract) */ break; case ('f'): /* "freshen" (extract only newer files) */ ++fflag; ++uflag; break; case ('j'): /* junk pathnames/directory structure */ ++jflag; break; /* case ('l') is below, after fall-through for 'v' */ case ('n'): /* don't overwrite any files */ overwrite_none = TRUE; break; case ('o'): /* OK to overwrite files without prompting */ overwrite_all = TRUE; force_flag = TRUE; /* (share -o for now): force to continue */ break; case ('p'): ++cflag;#if defined(NATIVE) && !defined(DOS_OS2) ++aflag;#endif quietflg += 99; break; case ('q'): ++quietflg; break;#ifdef DOS_OS2 case ('s'): ++sflag; break;#endif case ('t'): ++tflag; break; case ('U'): /* Uppercase flag (i.e., don't convert to lower) */ ++U_flag; break; case ('u'): /* "update" (extract only new and newer files) */ ++uflag; break; case ('V'): /* Version flag: retain VMS/DEC-20 file versions */ ++V_flag; break; case ('v'): ++vflag; /* fall thru */ case ('l'): ++vflag; break;#ifdef VMS case ('X'): /* restore owner/protection info (may need privs) */ secinf = TRUE; break;#endif /* VMS */ case ('x'): /* extract: default */ break; case ('z'): /* display only the archive comment */ ++zflag; break; default: error = TRUE; break; } } }/*--------------------------------------------------------------------------- Make sure we aren't trying to do too many things here. [This seems like kind of a brute-force way to do things; but aside from that, isn't the -a option useful when listing the directory (i.e., for reading zipfile comments)? It's a modifier, not an action in and of itself, so perhaps it should not be included in the test--certainly, in the case of zipfile testing, it can just be ignored.] ---------------------------------------------------------------------------*/ if ((aflag && tflag) || (aflag && vflag) || (cflag && tflag) || (cflag && uflag) || (cflag && vflag) || (tflag && uflag) || (tflag && vflag) || (uflag && vflag) || (fflag && overwrite_none)) { fprintf(stderr, "error:\ -at, -av, -ct, -cu, -cv, -fn, -tu, -tv, -uv combinations not allowed\n"); error = TRUE; } if (quietflg && zflag) quietflg = 0; if (overwrite_all && overwrite_none) { fprintf(stderr, "caution: both -n and -o specified; ignoring -o\n"); overwrite_all = FALSE; } if ((argc-- == 0) || error) RETURN(usage(error));/*--------------------------------------------------------------------------- Now get the zipfile name from the command line and see if it exists as a regular (non-directory) file. If not, append the ".zip" suffix. We don't immediately check to see if this results in a good name, but we will do so later. In the meantime, see if there are any member filespecs on the com- mand line, and if so, set the filename pointer to point at them. ---------------------------------------------------------------------------*/ strcpy(zipfn, *argv++); if (stat(zipfn, &statbuf) || (statbuf.st_mode & S_IFMT) == S_IFDIR) strcat(zipfn, ZSUFX);#if defined(UNIX) && !defined(VMS) /* Unix executables have no extension-- */ else if (statbuf.st_mode & S_IEXEC) /* might find zip, not zip.zip; etc */ fprintf(stderr, "\nnote: file [ %s ] may be an executable\n\n", zipfn);#endif /* UNIX && !VMS */ if (stat(zipfn, &statbuf)) {/* try again */ fprintf(stderr, "error: can't find zipfile [ %s ]\n", zipfn); RETURN(9); /* 9: file not found */ } else ziplen = statbuf.st_size; if (argc != 0) { fnv = argv; process_all_files = FALSE; } else process_all_files = TRUE; /* for speed *//*--------------------------------------------------------------------------- Okey dokey, we have everything we need to get started. Let's roll. ---------------------------------------------------------------------------*/ inbuf = (byte *) malloc(INBUFSIZ + 4); /* 4 extra for hold[] (below) */ outbuf = (byte *) malloc(OUTBUFSIZ + 1); /* 1 extra for string termin. */#ifndef DOS_OS2 if (aflag) /* if need an ascebc scratch, */ outout = (byte *) malloc(OUTBUFSIZ); else /* allocate it... */#endif /* !DOS_OS2 */ outout = outbuf; /* else just point to outbuf */ if ((inbuf == NULL) || (outbuf == NULL) || (outout == NULL)) { fprintf(stderr, "error: can't allocate unzip buffers\n"); RETURN(4); /* 4-8: insufficient memory */ } hold = &inbuf[INBUFSIZ]; /* to check for boundary-spanning signatures */#ifdef THINK_C if (!process_zipfile()) goto start;#else RETURN(process_zipfile()); /* keep passing errors back... */#endif} /* end main() *//**********************//* Function usage() *//**********************/int usage(error) /* return PK-type error code */ int error;{#ifdef NATIVE#ifdef EBCDIC char *astring = "-a convert ASCII to EBCDIC";#else /* !EBCDIC */ char *astring = "-a convert ASCII to native chars";#endif /* ?EBCDIC *?/* char *astring = "-a convert ASCII to " NATIVE; (ANSI C concatenation) */ char *loc_str = "";#else /* !NATIVE */#ifdef DOS_OS2 char *astring = "-a convert text (LF => CR LF)"; char *loc_str = "-s allow spaces in filenames";#else /* !DOS_OS2 */#ifdef MACOS char *astring = "-a convert text (CR LF => CR)"; char *loc_str = "";#else /* !MACOS: UNIX, VMS */ char *astring = "-a convert text (CR LF => LF)";#ifdef VMS char *loc_str = "-X restore owner/protection info";#else /* !VMS */ char *loc_str = "";#endif /* ?VMS */#endif /* ?MACOS */#endif /* ?DOS_OS2 */#endif /* ?NATIVE */ FILE *usagefp;/*--------------------------------------------------------------------------- If user requested usage, send it to stdout; else send to stderr. ---------------------------------------------------------------------------*/ if (error) usagefp = (FILE *) stderr; else usagefp = (FILE *) stdout; fprintf(usagefp, "\UnZip: Zipfile Extract %s; (c) 1989 S.H.Smith and others\n\Versions 3.0 and later by Info-ZIP. Bug reports ONLY to zip-bugs@cs.ucla.edu\\n\n", VERSION); fprintf(usagefp, "\Usage: unzip [ -options[modifiers] ] file[.zip] [filespec...]\n\ -x extract files (default) -l list files (short format)\n\ -c extract files to stdout/screen (CRT) -v list files (verbose format)\n\ -f freshen existing files, create none -p extract to pipe, no messages\n\ -u update files, create if necessary -t test archive integrity\n\ -z display archive comment\n\modifiers:\n\ -n never overwrite existing files %s\n", loc_str); fprintf(usagefp, "\ -o overwrite files WITHOUT prompting %s\n\ -j junk paths (don't make directories) -U don't make names lowercase\n\ -q quiet mode (-qq => quieter) -V retain VMS version numbers\\n\n\Examples: (See manual for more information)\n\ unzip data1 Readme => extracts file Readme from zipfile data1.zip\n\ unzip -p foo | more => send contents of foo.zip via pipe into program more\n\ unzip -fo foo => quietly replace existing files if archive files newer\\n", astring);#ifdef VMS fprintf(usagefp, "\ unzip \"-V\" foo \"Bar\" => must quote uppercase options and filenames in VMS\\n");#endif if (error) return 10; /* 10: bad or illegal parameters specified */ else return 0; /* just wanted usage screen: no error */} /* end function usage() *//********************************//* Function process_zipfile() *//********************************/int process_zipfile() /* return PK-type error code */{ int error=0, error_in_archive; longint real_ecrec_offset, expect_ecrec_offset;/*--------------------------------------------------------------------------- Open the zipfile for reading and in BINARY mode to prevent CR/LF trans- lation, which would corrupt the bitstreams. ---------------------------------------------------------------------------*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -