📄 zipinfo.c
字号:
/*-------------------------------------------------------------------------- zipinfo.c This program reads all sorts of totally nifty information, including the central directory stuff, from a ZIP archive ("zipfile" for short). It started as just a testbed for fooling with zipfiles, but at this point it's actually a moderately useful utility. It also became the basis for the rewrite of unzip (3.16 -> 4.0), using the central directory for processing rather than the individual (local) file headers. For myself, I find it convenient to define an alias "ii" (under Unix and VMS) or to rename the executable to "ii.exe" (OS/2 and DOS). This nicely complements my Unix long-listing "ll" alias (ls -lF), since zipinfo's de- fault action is to produce a Unix-like listing of the archive's contents. "ii zipfile" is easier to type than "zipinfo zipfile"... Another dandy product from your buddies at Newtware! -------------------------------------------------------------------------- To compile (partial instructions; some of this stuff doesn't exist yet): under Unix (cc): make zipinfo under MS-DOS (TurboC): make -fMKZIPINF.DOS (edit appropriately) under MS-DOS (MSC): make MKZIPINF.DOS (or use Makefile if you have MSC 6.0: "nmake zi_dos") under OS/2 (MSC): make MKZIPINF.DOS (edit appropriately) (or use Makefile if you have MSC 6.0: "nmake zi_os2") under Atari OS: beats me... under VMS: @MAKE_ZIPINFO (see also VMSNOTES) ZIPINFO == $DISKNAME:[DIRECTORY]ZIPINFO.EXE under Macintosh OS: who knows? -------------------------------------------------------------------------- Version: unzip42.zip (.tar.Z, etc.) for Unix, VMS, OS/2 and MS-DOS Source: wuarchive.wustl.edu (128.252.135.4) in /mirrors/misc/unix wsmr-simtel20.army.mil (192.88.110.20) in pd1:[misc.unix] Author: Greg Roelofs, roelofs@amelia.nas.nasa.gov, 23 August 1990 Copyright: none (except that some of the file input/output code comes from unzip, which has its own copyrights, sort of...MY stuff is in the public domain, however) --------------------------------------------------------------------------*/#define ZIPINFO#include "unzip.h"#define VERSION "v0.96k BETA of 20 Mar 92"/**********************//* Global Variables *//**********************/#ifdef EBCDIC int aflag=1; /* this is so you can read it on the screen */#else /* (basically, entire program is "unzip -c") */ int aflag=0;#endifint lflag=2; /* for "ls -l" type listing */byte *inbuf, *inptr; /* input buffer (any size is legal) and pointer */int incnt;int zipfd; /* zipfile file handle */char zipfn[FILNAMSIZ];char local_hdr_sig[5] = "\120"; /* remaining signature bytes come later: */char central_hdr_sig[5] = "\120"; /* must initialize at runtime so zipinfo */char end_central_sig[5] = "\120"; /* executable won't look like a zipfile */cdir_file_hdr crec; /* used in zipinfo.c, misc.c */local_file_hdr lrec;ecdir_rec ecrec;struct stat statbuf; /* used by main() */int process_all_files;longint extra_bytes=0; /* used in zipinfo.c, misc.c */longint cur_zipfile_bufstart; /* find_end_central_dir, readbuf */min_info info, *pInfo=(&info);byte *extra_field = NULL; /* currently used by VMS version only */byte *outbuf; /* buffer for rle look-back, zipfile comment */byte *outout; /* scratch pad for ASCII-native trans */char filename[FILNAMSIZ];char sig[5];char *fnames[2] = {"*", NULL}; /* default filenames vector */char **fnv = fnames;static byte *hold;static longint ziplen;static UWORD hostnum;static UWORD methnum;static UWORD extnum;/* UWORD j, yr, mo, dy, hh, mm, members = 0; ULONG tot_csize = 0L, tot_ucsize = 0L; */char *EndSigMsg = "\nwarning:\ didn't find end-of-central-dir signature at end of central dir.\n";char *CentSigMsg = "error: expected central file header signature not found (file #%u).\n";char *SeekMsg = "error: attempt to seek before beginning of zipfile\n%s";#ifdef VMSchar *ReportMsg = "\ (please check that you have transferred or created the zipfile in the\n\ appropriate BINARY mode--this includes ftp, Kermit, AND unzip'd zipfiles)\n";#else /* !VMS */char *ReportMsg = "\ (please check that you have transferred or created the zipfile in the\n\ appropriate BINARY mode and that you have compiled unzip properly)\n";#endif /* ?VMS *//******************//* Main program *//******************/main(argc, argv) int argc; char *argv[];{ char *s; int c, error=FALSE;/*--------------------------------------------------------------------------- Everybody is now "NOTINT16," but this is a nice little piece of code, so just comment it out for future reference. :-) ---------------------------------------------------------------------------*/#if 0# ifndef KNOW_IT_WORKS /* define this to save space, if things already work */# ifndef DOS_OS2 /* already works (no RISCy OS/2's yet...) */# ifndef NOTINT16 /* whole point is to see if this NEEDS defining */ { int error=0; long testsig; static char *mach_type[3] = {"big-endian", "structure-padding", "big-endian and structure-padding"}; strcpy((char *)&testsig,"012"); if (testsig != 0x00323130) error = 1; if (sizeof(cdir_file_hdr) != CREC_SIZE) error += 2; if (error--) fprintf(stderr, "It appears that your machine is %s. If errors\n\occur, please try recompiling with \"NOTINT16\" defined (read the\n\Makefile, or try \"make zipinfo\").\n\n", mach_type[error]); }# endif /* !NOTINT16 */# endif /* !DOS_OS2 */# endif /* !KNOW_IT_WORKS */#endif /* 0 *//*--------------------------------------------------------------------------- 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 ('1'): /* minimum listing: just names */ lflag = 0; break; case ('l'): /* default: "ls -l" type listing */ lflag = 2; break; case ('v'): /* turbo-verbose listing */ lflag = 10; break; default: error = TRUE; break; } } } 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. */ if (aflag) /* if need an ascebc scratch, */ outout = (byte *) (malloc(OUTBUFSIZ)); else /* allocate it... */ outout = outbuf; /* else just point to outbuf */ if ((inbuf == NULL) || (outbuf == NULL) || (outout == NULL)) { fprintf(stderr, "error: can't allocate zipinfo buffers\n"); RETURN(4); /* 4-8: insufficient memory */ } hold = &inbuf[INBUFSIZ]; /* to check for boundary-spanning signatures */ RETURN(process_zipfile()); /* keep passing errors back... */} /* end main() *//**********************//* Function usage() *//**********************/int usage(error) int error;{ 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, "\ ZipInfo: Zipfile Information Utility %s\n\ (brought to you by Newtware, Inc., and the fine folks at Info-ZIP)\n\n\ Usage: zipinfo [-1lv] file[.zip] [filespec...]\n", VERSION); fprintf(usagefp, "\ -1 list filenames only, one per line (useful for pipes)\n\ -l list files in Unix \"ls -l\" format: default\n\ -v list files in verbose, multi-page format\n");/* -p disable automatic \"more\" function (for pipes) [not implemented]\n"); */#ifdef VMS fprintf(usagefp, "\nRemember that non-lowercase filespecs must be quoted\ in VMS (e.g., \"Makefile\").\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. ---------------------------------------------------------------------------*/#ifdef VMS { int rtype; VMSmunch(zipfn, GET_RTYPE, (char *)&rtype); if (rtype == FAT$C_VARIABLE) { fprintf(stderr, "\n Error: zipfile is in variable-length record format. Please\n\ run \"bilf l %s\" to convert the zipfile to stream-LF\n\ record format. (Both bilf.c and make_bilf.com are included\n\ in the VMS unzip distribution.)\n\n", zipfn); return 2; /* 2: error in zipfile */ } rtype = FAT$C_STREAMLF; /* Unix I/O loves it */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -