home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume44 / unzip / part04 < prev    next >
Internet Message Format  |  1994-09-19  |  71KB

  1. From: zip-bugs@wkuvx1.wku.edu (Info-ZIP group)
  2. Newsgroups: comp.sources.misc
  3. Subject: v44i069:  unzip - Info-ZIP portable UnZip, version 5.12, Part04/20
  4. Date: 18 Sep 1994 23:14:35 -0500
  5. Organization: Sterling Software
  6. Sender: kent@sparky.sterling.com
  7. Approved: kent@sparky.sterling.com
  8. Message-ID: <35j37b$qmc@sparky.sterling.com>
  9. X-Md4-Signature: 33ef05d4562f4c968484d7930bebbc87
  10.  
  11. Submitted-by: zip-bugs@wkuvx1.wku.edu (Info-ZIP group)
  12. Posting-number: Volume 44, Issue 69
  13. Archive-name: unzip/part04
  14. Environment: UNIX, VMS, OS/2, MS-DOS, MACINTOSH, WIN-NT, LINUX, MINIX, COHERENT, AMIGA?, ATARI TOS, SGI, DEC, Cray, Convex, Amdahl, Sun
  15. Supersedes: unzip50: Volume 31, Issue 104-117
  16.  
  17. #! /bin/sh
  18. # This is a shell archive.  Remove anything before this line, then feed it
  19. # into a shell via "sh file" or similar.  To overwrite existing files,
  20. # type "sh file -c".
  21. # Contents:  unzip-5.12/amiga/makefile.azt unzip-5.12/zipinfo.c
  22. # Wrapped by kent@sparky on Sat Sep 17 23:33:37 1994
  23. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
  24. echo If this archive is complete, you will see the following message:
  25. echo '          "shar: End of archive 4 (of 20)."'
  26. if test -f 'unzip-5.12/amiga/makefile.azt' -a "${1}" != "-c" ; then 
  27.   echo shar: Will not clobber existing file \"'unzip-5.12/amiga/makefile.azt'\"
  28. else
  29.   echo shar: Extracting \"'unzip-5.12/amiga/makefile.azt'\" \(2163 characters\)
  30.   sed "s/^X//" >'unzip-5.12/amiga/makefile.azt' <<'END_OF_FILE'
  31. X# Makefile for UnZip 5.11+ using Manx Aztec C 5.2               10 July 1994
  32. X#
  33. X# You may need to change directory names for stat.c, filedate.c and amiga.c.
  34. X
  35. X
  36. XCC = cc
  37. XCFLAGS = -d AMIGA -ps -sabfmnpu -wcpr0u
  38. X# -ps means short ints, -s... is optimizations, -w... is type checking
  39. XLD = ln
  40. XLDFLAGS = +q -m
  41. XLDLIBS = -lc16
  42. X
  43. XOBJS = unzip.o crypt.o envargs.o explode.o unshrink.o \
  44. X       extract.o zipinfo.o file_io.o inflate.o match.o unreduce.o \
  45. X       amiga/amiga.o amiga/crc_68.o amiga/flate.o
  46. XXOBJS = unzip.xo crypt.o extract.xo file_io.o inflate.o amiga/flate.o \
  47. X        match.o amiga/amiga.xo
  48. XFOBJS = funzip.o crypt.fo inflate.fo amiga/flate.fo
  49. X
  50. X
  51. X.c.o :
  52. X    $(CC) -o $@ $(CFLAGS) $*.c
  53. X
  54. X.c.xo:
  55. X    $(CC) -o $@ -d SFX $(CFLAGS) $*.c
  56. X
  57. X.c.fo:
  58. X    $(CC) -o $@ -d FUNZIP $(CFLAGS) $*.c
  59. X
  60. XUnZip :     $(OBJS)
  61. X    $(LD) $(LDFLAGS) -o $@ $(OBJS) $(LDLIBS)
  62. X
  63. XUnZipSFX :  $(FOBJS)
  64. X    $(LD) $(LDFLAGS) -o $@ $(FOBJS) $(LDLIBS)
  65. X
  66. XfUnZip :    $(FOBJS)
  67. X    $(LD) $(LDFLAGS) -o $@ $(XOBJS) $(LDLIBS)
  68. X
  69. Xf : fUnZip
  70. X
  71. Xall : UnZip UnZipSFX fUnZip
  72. X
  73. Xclean :
  74. X    delete #?.(o|xo|fo) quiet
  75. X
  76. X
  77. X$(OBJS) $(XOBJS) $(FOBJS) : unzip.h amiga/amiga.h amiga/z-stat.h
  78. X
  79. Xcrypt.o crypt.fo : zip.h
  80. X
  81. Xinflate.o inflate.fo : inflate.h
  82. X
  83. Xfile_io.o funzip.o : tables.h
  84. X
  85. Xcrypt.o crypt.fo unzip.o unzip.xo funzip.o file_io.o : crypt.h
  86. Xextract.o extract.xo inflate.o inflate.fo : crypt.h
  87. X
  88. Xunzip.o unzip.xo : version.h
  89. X
  90. Xfile_io.o : file_io.c
  91. X    $(CC) -o file_io.o $(CFLAGS) -d ASM_CRC file_io.c
  92. X
  93. Xinflate.o : inflate.c
  94. X    $(CC) -o inflate.o $(CFLAGS) -d ASM_INFLATECODES inflate.c
  95. X
  96. Xinflate.fo : inflate.c
  97. X    $(CC) -o inflate.fo $(CFLAGS) -d FUNZIP -d ASM_INFLATECODES inflate.c
  98. X
  99. Xamiga/amiga.o : amiga/filedate.c amiga/stat.c amiga/amiga.c
  100. X    $(CC) -o amiga/amiga.o -d __VERSION__=5 -d __REVISION__=2 \
  101. X            $(CFLAGS) amiga/amiga.c
  102. X
  103. Xamiga/amiga.xo : amiga/filedate.c amiga/stat.c amiga/amiga.c
  104. X    $(CC) -o amiga/amiga.xo -d __VERSION__=5 -d __REVISION__=2 -d SFX \
  105. X            $(CFLAGS) amiga/amiga.c
  106. X
  107. Xamiga/crc_68.o : amiga/crc_68.a
  108. X    as -n -o amiga/crc_68.o -eREGARGS amiga/crc_68.a
  109. X
  110. Xamiga/flate.o : amiga/flate.a
  111. X    as -n -o amiga/flate.o amiga/flate.a
  112. X
  113. Xamiga/flate.fo : amiga/flate.a
  114. X    as -n -o amiga/flate.fo -eCRYPT -eFUNZIP amiga/flate.a
  115. END_OF_FILE
  116.   if test 2163 -ne `wc -c <'unzip-5.12/amiga/makefile.azt'`; then
  117.     echo shar: \"'unzip-5.12/amiga/makefile.azt'\" unpacked with wrong size!
  118.   fi
  119.   # end of 'unzip-5.12/amiga/makefile.azt'
  120. fi
  121. if test -f 'unzip-5.12/zipinfo.c' -a "${1}" != "-c" ; then 
  122.   echo shar: Will not clobber existing file \"'unzip-5.12/zipinfo.c'\"
  123. else
  124.   echo shar: Extracting \"'unzip-5.12/zipinfo.c'\" \(64797 characters\)
  125.   sed "s/^X//" >'unzip-5.12/zipinfo.c' <<'END_OF_FILE'
  126. X/*---------------------------------------------------------------------------
  127. X
  128. X  zipinfo.c
  129. X
  130. X  This file contains all of the zipfile-listing routines for UnZip, inclu-
  131. X  ding the bulk of what used to be the separate program ZipInfo.  All of
  132. X  the ZipInfo routines are by Greg Roelofs; list_files is by the usual mish-
  133. X  mash of Info-ZIP contributors (see the listing in CONTRIBS).
  134. X
  135. X  Contains:  zi_opts()
  136. X             zi_end_central()
  137. X             zipinfo()
  138. X             zi_long()
  139. X             zi_short()
  140. X             zi_time()
  141. X             list_files()
  142. X             ratio()
  143. X             fnprint()
  144. X
  145. X  ---------------------------------------------------------------------------*/
  146. X
  147. X
  148. X#include "unzip.h"
  149. X
  150. Xstatic char unkn[16];
  151. X
  152. Xstatic int ratio OF((ulg uc, ulg c));
  153. Xstatic void fnprint OF((void));
  154. X
  155. X
  156. X/********************************************/
  157. X/*  Strings used in zipinfo.c (UnZip half)  */
  158. X/********************************************/
  159. X
  160. X/* also referenced in UpdateListBox() in updatelb.c (Windows version) */
  161. Xchar Far HeadersS[] = " Length    Date    Time    Name";
  162. Xchar Far HeadersS1[] = " ------    ----    ----    ----";
  163. Xchar Far HeadersL[] = " Length  Method   Size  Ratio   Date    Time   CRC-32     Name";
  164. Xchar Far HeadersL1[] = " ------  ------   ----  -----   ----    ----   ------     ----";
  165. Xchar Far *Headers[][2] = { {HeadersS, HeadersS1}, {HeadersL, HeadersL1} };
  166. X
  167. Xstatic char Far CaseConversion[] = "%s (\"^\" ==> case\n%s   conversion)\n";
  168. Xstatic char Far CompFactorStr[] = "%c%d%%";
  169. Xstatic char Far CompMethodUnknown[] = "Unk:%03d";
  170. X#ifdef MSWIN
  171. X   static char Far LongHdrStats[] =
  172. X     "%7lu  %-7s%7lu %4s  %02u-%02u-%02u  %02u:%02u  %08lx  %c%s";
  173. X   static char Far LongFileHeader[] =
  174. X     "%7lu         %7lu %4s                              %-7u";
  175. X   static char Far ShortHdrStats[] = "%7lu  %02u-%02u-%02u  %02u:%02u  %c%s";
  176. X   static char Far ShortFileHeader[] = "%7lu                    %-7u";
  177. X#else /* !MSWIN */
  178. X   static char Far LongHdrStats[] =
  179. X     "%7lu  %-7s%7lu %4s  %02u-%02u-%02u  %02u:%02u  %08lx  %c";
  180. X   static char Far ShortHdrStats[] = "%7lu  %02u-%02u-%02u  %02u:%02u  %c";
  181. X   static char Far LongFileHeader[] =
  182. X     " ------          ------  ---                         \
  183. X     -------\n%7lu         %7lu %4s                              %-7u\n";
  184. X   static char Far ShortFileHeader[] =
  185. X     " ------                    -------\n%7lu                    %-7u\n";
  186. X#endif /* ?MSWIN */
  187. X
  188. X
  189. X
  190. X#ifndef NO_ZIPINFO  /* strings use up too much space in small-memory systems */
  191. X
  192. X/* Define OS-specific attributes for use on ALL platforms--the S_xxxx
  193. X * versions of these are defined differently (or not defined) by different
  194. X * compilers and operating systems. */
  195. X
  196. X#define UNX_IFMT       0170000     /* Unix file type mask */
  197. X#define UNX_IFDIR      0040000     /* Unix directory */
  198. X#define UNX_IFREG      0100000     /* Unix regular file */
  199. X#define UNX_IFSOCK     0140000     /* Unix socket (BSD, not SysV or Amiga) */
  200. X#define UNX_IFLNK      0120000     /* Unix symbolic link (not SysV, Amiga) */
  201. X#define UNX_IFBLK      0060000     /* Unix block special       (not Amiga) */
  202. X#define UNX_IFCHR      0020000     /* Unix character special   (not Amiga) */
  203. X#define UNX_IFIFO      0010000     /* Unix fifo    (BCC, not MSC or Amiga) */
  204. X#define UNX_ISUID      04000       /* Unix set user id on execution */
  205. X#define UNX_ISGID      02000       /* Unix set group id on execution */
  206. X#define UNX_ISVTX      01000       /* Unix directory permissions control */
  207. X#define UNX_ENFMT      UNX_ISGID   /* Unix record locking enforcement flag */
  208. X#define UNX_IRWXU      00700       /* Unix read, write, execute: owner */
  209. X#define UNX_IRUSR      00400       /* Unix read permission: owner */
  210. X#define UNX_IWUSR      00200       /* Unix write permission: owner */
  211. X#define UNX_IXUSR      00100       /* Unix execute permission: owner */
  212. X#define UNX_IRWXG      00070       /* Unix read, write, execute: group */
  213. X#define UNX_IRGRP      00040       /* Unix read permission: group */
  214. X#define UNX_IWGRP      00020       /* Unix write permission: group */
  215. X#define UNX_IXGRP      00010       /* Unix execute permission: group */
  216. X#define UNX_IRWXO      00007       /* Unix read, write, execute: other */
  217. X#define UNX_IROTH      00004       /* Unix read permission: other */
  218. X#define UNX_IWOTH      00002       /* Unix write permission: other */
  219. X#define UNX_IXOTH      00001       /* Unix execute permission: other */
  220. X
  221. X#define VMS_IRUSR      UNX_IRUSR   /* VMS read/owner */
  222. X#define VMS_IWUSR      UNX_IWUSR   /* VMS write/owner */
  223. X#define VMS_IXUSR      UNX_IXUSR   /* VMS execute/owner */
  224. X#define VMS_IRGRP      UNX_IRGRP   /* VMS read/group */
  225. X#define VMS_IWGRP      UNX_IWGRP   /* VMS write/group */
  226. X#define VMS_IXGRP      UNX_IXGRP   /* VMS execute/group */
  227. X#define VMS_IROTH      UNX_IROTH   /* VMS read/other */
  228. X#define VMS_IWOTH      UNX_IWOTH   /* VMS write/other */
  229. X#define VMS_IXOTH      UNX_IXOTH   /* VMS execute/other */
  230. X
  231. X#define AMI_IFMT       06000       /* Amiga file type mask */
  232. X#define AMI_IFDIR      04000       /* Amiga directory */
  233. X#define AMI_IFREG      02000       /* Amiga regular file */
  234. X#define AMI_IHIDDEN    00200       /* to be supported in AmigaDOS 3.x */
  235. X#define AMI_ISCRIPT    00100       /* executable script (text command file) */
  236. X#define AMI_IPURE      00040       /* allow loading into resident memory */
  237. X#define AMI_IARCHIVE   00020       /* not modified since bit was last set */
  238. X#define AMI_IREAD      00010       /* can be opened for reading */
  239. X#define AMI_IWRITE     00004       /* can be opened for writing */
  240. X#define AMI_IEXECUTE   00002       /* executable image, a loadable runfile */
  241. X#define AMI_IDELETE    00001       /* can be deleted */
  242. X
  243. X/* extra-field ID values: */
  244. X#define EF_AV        0x0007   /* PKWARE authenticity verification */
  245. X#define EF_OS2       0x0009   /* OS/2 extended attributes */
  246. X#define EF_PKVMS     0x000c   /* PKWARE's VMS ID */
  247. X#define EF_IZVMS     0x4d49   /* Info-ZIP's VMS ID ("IM") */
  248. X#define EF_ASIUNIX   0x756e   /* ASi/PKWARE's Unix ID ("IM") */
  249. X#define EF_SPARK     0x4341   /* David Pilling's Acorn/SparkFS ID ("AC") */
  250. X
  251. X#define LFLAG  3   /* short "ls -l" type listing */
  252. X
  253. Xstatic int   zi_long   OF((void));
  254. Xstatic int   zi_short  OF((void));
  255. Xstatic char *zi_time   OF((ush *datez, ush *timez));
  256. X
  257. X
  258. X/**********************************************/
  259. X/*  Strings used in zipinfo.c (ZipInfo half)  */
  260. X/**********************************************/
  261. X
  262. Xstatic char Far LongHeader[] = "Archive:  %s   %ld bytes   %d file%s\n";
  263. Xstatic char Far ShortHeader[] = "Archive:  %s   %ld   %d\n";
  264. Xstatic char Far EndCentDirRec[] = "\nEnd-of-central-directory record:\n";
  265. Xstatic char Far LineSeparators[] = "-------------------------------\n\n";
  266. Xstatic char Far ActOffsetCentDir[] = "\
  267. X  Actual offset of end-of-central-dir record:   %9ld (%.8lXh)\n\
  268. X  Expected offset of end-of-central-dir record: %9ld (%.8lXh)\n\
  269. X  (based on the length of the central directory and its expected offset)\n\n";
  270. Xstatic char Far SinglePartArchive[] = "\
  271. X  This zipfile constitutes the sole disk of a single-part archive; its\n\
  272. X  central directory contains %u %s.  The central directory is %lu\n\
  273. X  (%.8lXh) bytes long, and its (expected) offset in bytes from the\n\
  274. X  beginning of the zipfile is %lu (%.8lXh).\n\n";
  275. Xstatic char Far MultiPartArchive[] = "\
  276. X  This zipfile constitutes disk %u of a multi-part archive.  The central\n\
  277. X  directory starts on disk %u; %u of its entries %s contained within\n\
  278. X  this zipfile, out of a total of %u %s.  The entire central\n\
  279. X  directory is %lu (%.8lXh) bytes long, and its offset in bytes from\n\
  280. X  the beginning of the zipfile in which it begins is %lu (%.8lXh).\n\n";
  281. Xstatic char Far NoZipfileComment[] = "  There is no zipfile comment.\n";
  282. Xstatic char Far ZipfileCommentDesc[] =
  283. X  "  The zipfile comment is %u bytes long and contains the following text:\n\n";
  284. Xstatic char Far ZipfileCommBegin[] =
  285. X "======================== zipfile comment begins ==========================\n";
  286. Xstatic char Far ZipfileCommEnd[] =
  287. X "========================= zipfile comment ends ===========================\n";
  288. Xstatic char Far ZipfileCommTrunc2[] = "\n  The zipfile comment is truncated.\n";
  289. Xstatic char Far ZipfileCommTruncMsg[] =
  290. X  "\ncaution:  zipfile comment truncated\n";
  291. X
  292. X#ifdef T20_VMS
  293. X   static char Far CentralDirEntry[] = "\nCentral directory entry #%d:\n";
  294. X#else
  295. X   static char Far CentralDirEntry[] = "%s\nCentral directory entry #%d:\n";
  296. X#endif
  297. X
  298. Xstatic char Far CentralDirLines[] = "---------------------------\n\n";
  299. Xstatic char Far ZipfileStats[] = 
  300. X  "%d file%s, %lu bytes uncompressed, %lu bytes compressed:  %s%d.%d%%\n";
  301. X
  302. X/* zi_long() strings */
  303. Xstatic char Far OS_FAT[] = "MS-DOS, OS/2 or NT FAT";
  304. Xstatic char Far OS_Amiga[] = "Amiga";
  305. Xstatic char Far OS_VAXVMS[] = "VAX VMS";
  306. Xstatic char Far OS_Unix[] = "Unix";
  307. Xstatic char Far OS_VMCMS[] = "VM/CMS";
  308. Xstatic char Far OS_AtariST[] = "Atari ST";
  309. Xstatic char Far OS_HPFS[] = "OS/2 or NT HPFS";
  310. Xstatic char Far OS_Macintosh[] = "Macintosh";
  311. Xstatic char Far OS_ZSystem[] = "Z-System";
  312. Xstatic char Far OS_CPM[] = "CP/M";
  313. Xstatic char Far OS_TOPS20[] = "TOPS-20";
  314. Xstatic char Far OS_NTFS[] = "NT NTFS";
  315. Xstatic char Far OS_QDOS[] = "QDOS (maybe)";
  316. Xstatic char Far OS_Acorn[] = "Acorn RISCOS";
  317. X
  318. Xstatic char Far MthdNone[] = "none (stored)";
  319. Xstatic char Far MthdShrunk[] = "shrunk";
  320. Xstatic char Far MthdRedF1[] = "reduced (factor 1)";
  321. Xstatic char Far MthdRedF2[] = "reduced (factor 2)";
  322. Xstatic char Far MthdRedF3[] = "reduced (factor 3)";
  323. Xstatic char Far MthdRedF4[] = "reduced (factor 4)";
  324. Xstatic char Far MthdImplode[] = "imploded";
  325. Xstatic char Far MthdToken[] = "tokenized";
  326. Xstatic char Far MthdDeflate[] = "deflated";
  327. X
  328. Xstatic char Far ExtraBytesPreceding[] =
  329. X  "  There are an extra %ld bytes preceding this file.\n\n";
  330. X
  331. Xstatic char Far Unknown[] = "unknown (%d)";
  332. X
  333. Xstatic char Far HostOS[] =
  334. X  "\n  host operating system (created on):               %s\n";
  335. Xstatic char Far EncodeSWVer[] =
  336. X  "  version of encoding software:                     %d.%d\n";
  337. Xstatic char Far MinOSCompReq[] =
  338. X  "  minimum operating system compatibility required:  %s\n";
  339. Xstatic char Far MinSWVerReq[] =
  340. X  "  minimum software version required to extract:     %d.%d\n";
  341. Xstatic char Far CompressMethod[] =
  342. X  "  compression method:                               %s\n";
  343. Xstatic char Far SlideWindowSizeImplode[] =
  344. X  "  size of sliding dictionary (implosion):           %cK\n";
  345. Xstatic char Far ShannonFanoTrees[] =
  346. X  "  number of Shannon-Fano trees (implosion):         %c\n";
  347. Xstatic char Far CompressSubtype[] =
  348. X  "  compression sub-type (deflation):                 %s\n";
  349. Xstatic char Far FileSecurity[] =
  350. X  "  file security status:                             %sencrypted\n";
  351. Xstatic char Far ExtendedLocalHdr[] =
  352. X  "  extended local header:                            %s\n";
  353. Xstatic char Far FileModDate[] =
  354. X  "  file last modified on:                            %s\n";
  355. Xstatic char Far CRC32Value[] =
  356. X  "  32-bit CRC value (hex):                           %.8lx\n";
  357. Xstatic char Far CompressedFileSize[] =
  358. X  "  compressed size:                                  %lu bytes\n";
  359. Xstatic char Far UncompressedFileSize[] =
  360. X  "  uncompressed size:                                %lu bytes\n";
  361. Xstatic char Far FilenameLength[] =
  362. X  "  length of filename:                               %u characters\n";
  363. Xstatic char Far ExtraFieldLength[] =
  364. X  "  length of extra field:                            %u bytes\n";
  365. Xstatic char Far FileCommentLength[] =
  366. X  "  length of file comment:                           %u characters\n";
  367. Xstatic char Far FileDiskNum[] =
  368. X  "  disk number on which file begins:                 disk %u\n";
  369. Xstatic char Far ApparentFileType[] =
  370. X  "  apparent file type:                               %s\n";
  371. Xstatic char Far VMSFileAttributes[] =
  372. X  "  VMS file attributes (%06o octal):               %s\n";
  373. Xstatic char Far AmigaFileAttributes[] =
  374. X  "  Amiga file attributes (%06o octal):             %s\n";
  375. Xstatic char Far UnixFileAttributes[] =
  376. X  "  Unix file attributes (%06o octal):              %s\n";
  377. Xstatic char Far NonMSDOSFileAttributes[] =
  378. X  "  non-MSDOS external file attributes:               %06lX hex\n";
  379. Xstatic char Far MSDOSFileAttributes[] =
  380. X  "  MS-DOS file attributes (%02X hex):                  none\n";
  381. Xstatic char Far MSDOSFileAttributesRO[] =
  382. X  "  MS-DOS file attributes (%02X hex):                  read-only\n";
  383. Xstatic char Far MSDOSFileAttributesAlpha[] =
  384. X  "  MS-DOS file attributes (%02X hex):                  %s%s%s%s%s%s\n";
  385. Xstatic char Far LocalHeaderOffset[] =
  386. X  "  offset of local header from start of archive:     %lu (%.8lXh) bytes\n";
  387. Xstatic char Far ExtraFieldType[] = "\n\
  388. X  The central-directory extra field has ID 0x%04x (%s) and has %u\n\
  389. X  data bytes";
  390. Xstatic char Far OS2EAs[] = "\
  391. X.  The local extra field has %lu bytes of OS/2 extended\n\
  392. X  attributes (may not match OS/2 \"dir\" amount due to storage method).";
  393. Xstatic char Far First16[] = ".  The first 16 are%s";
  394. Xstatic char Far ColonIndent[] = ":\n     ";
  395. Xstatic char Far efFormat[] = " %02x";
  396. Xstatic char Far efAV[] = "PKWARE AV";
  397. Xstatic char Far efOS2[] = "OS/2";
  398. Xstatic char Far efPKVMS[] = "PKWARE VMS";
  399. Xstatic char Far efIZVMS[] = "Info-ZIP VMS";
  400. Xstatic char Far efASiUnix[] = "ASi Unix";
  401. X/* static char Far efIZUnix[] = "Info-ZIP Unix"; */
  402. Xstatic char Far efSpark[] = "Acorn SparkFS";
  403. Xstatic char Far efUnknown[] = "unknown";
  404. Xstatic char Far NoFileComment[] = "\n  There is no file comment.\n";
  405. Xstatic char Far FileCommBegin[] = "\n\
  406. X------------------------- file comment begins ----------------------------\n";
  407. Xstatic char Far FileCommEnd[] = "\
  408. X-------------------------- file comment ends -----------------------------\n";
  409. Xstatic char Far JanMonth[] = "Jan";
  410. Xstatic char Far FebMonth[] = "Feb";
  411. Xstatic char Far MarMonth[] = "Mar";
  412. Xstatic char Far AprMonth[] = "Apr";
  413. Xstatic char Far MayMonth[] = "May";
  414. Xstatic char Far JunMonth[] = "Jun";
  415. Xstatic char Far JulMonth[] = "Jul";
  416. Xstatic char Far AugMonth[] = "Aug";
  417. Xstatic char Far SepMonth[] = "Sep";
  418. Xstatic char Far OctMonth[] = "Oct";
  419. Xstatic char Far NovMonth[] = "Nov";
  420. Xstatic char Far DecMonth[] = "Dec";
  421. Xstatic char Far BogusFmt[] = "%03d";
  422. Xstatic char Far DMYHMTime[] = "%2u-%s-%02u %02u:%02u";
  423. Xstatic char Far YMDHMSTime[] = "%u %s %u %02u:%02u:%02u";
  424. Xstatic char Far DecimalTime[] = "%02u%02u%02u.%02u%02u%02u";
  425. X
  426. X
  427. X
  428. X
  429. X
  430. X/************************/
  431. X/*  Function zi_opts()  */
  432. X/************************/
  433. X
  434. Xint zi_opts(pargc, pargv)
  435. X    int *pargc;
  436. X    char ***pargv;
  437. X{
  438. X    char   **argv, *s;
  439. X    int    argc, c, error=FALSE, negative=0;
  440. X    int    hflag_slmv=TRUE, hflag_2=FALSE;  /* diff options => diff defaults */
  441. X    int    tflag_slm=TRUE, tflag_2v=FALSE;
  442. X    int    explicit_h=FALSE, explicit_t=FALSE;
  443. X
  444. X
  445. X#ifdef MACOS
  446. X    lflag = LFLAG;   /* reset default on each call */
  447. X#endif
  448. X    argc = *pargc;
  449. X    argv = *pargv;
  450. X
  451. X    while (--argc > 0 && (*++argv)[0] == '-') {
  452. X        s = argv[0] + 1;
  453. X        while ((c = *s++) != 0) {    /* "!= 0":  prevent Turbo C warning */
  454. X            switch (c) {
  455. X                case '-':
  456. X                    ++negative;
  457. X                    break;
  458. X                case '1':      /* shortest listing:  JUST filenames */
  459. X                    if (negative)
  460. X                        lflag = -2, negative = 0;
  461. X                    else
  462. X                        lflag = 1;
  463. X                    break;
  464. X                case '2':      /* just filenames, plus headers if specified */
  465. X                    if (negative)
  466. X                        lflag = -2, negative = 0;
  467. X                    else
  468. X                        lflag = 2;
  469. X                    break;
  470. X                case 'h':      /* header line */
  471. X                    if (negative)
  472. X                        hflag_2 = hflag_slmv = FALSE, negative = 0;
  473. X                    else {
  474. X                        hflag_2 = hflag_slmv = explicit_h = TRUE;
  475. X                        if (lflag == -1)
  476. X                            lflag = 0;
  477. X                    }
  478. X                    break;
  479. X                case 'l':      /* longer form of "ls -l" type listing */
  480. X                    if (negative)
  481. X                        lflag = -2, negative = 0;
  482. X                    else
  483. X                        lflag = 5;
  484. X                    break;
  485. X                case 'm':      /* medium form of "ls -l" type listing */
  486. X                    if (negative)
  487. X                        lflag = -2, negative = 0;
  488. X                    else
  489. X                        lflag = 4;
  490. X                    break;
  491. X                case 's':      /* default:  shorter "ls -l" type listing */
  492. X                    if (negative)
  493. X                        lflag = -2, negative = 0;
  494. X                    else
  495. X                        lflag = 3;
  496. X                    break;
  497. X                case 't':      /* totals line */
  498. X                    if (negative)
  499. X                        tflag_2v = tflag_slm = FALSE, negative = 0;
  500. X                    else {
  501. X                        tflag_2v = tflag_slm = explicit_t = TRUE;
  502. X                        if (lflag == -1)
  503. X                            lflag = 0;
  504. X                    }
  505. X                    break;
  506. X                case ('T'):    /* use (sortable) decimal time format */
  507. X                    if (negative)
  508. X                        T_flag = FALSE, negative = 0;
  509. X                    else
  510. X                        T_flag = TRUE;
  511. X                    break;
  512. X                case 'v':      /* turbo-verbose listing */
  513. X                    if (negative)
  514. X                        lflag = -2, negative = 0;
  515. X                    else
  516. X                        lflag = 10;
  517. X                    break;
  518. X                case 'z':      /* print zipfile comment */
  519. X                    if (negative)
  520. X                        zflag = negative = 0;
  521. X                    else
  522. X                        zflag = 1;
  523. X                    break;
  524. X                case 'Z':      /* ZipInfo mode:  ignore */
  525. X                    break;
  526. X                default:
  527. X                    error = TRUE;
  528. X                    break;
  529. X            }
  530. X        }
  531. X    }
  532. X    if ((argc-- == 0) || error) {
  533. X        *pargc = argc;
  534. X        *pargv = argv;
  535. X        return usage(error);
  536. X    }
  537. X
  538. X    /* if no listing options given (or all negated), or if only -h/-t given
  539. X     * with individual files specified, use default listing format */
  540. X    if ((lflag < 0) || ((argc > 0) && (lflag == 0)))
  541. X        lflag = LFLAG;
  542. X
  543. X    /* set header and totals flags to default or specified values */
  544. X    switch (lflag) {
  545. X        case 0:   /* 0:  can only occur if either -t or -h explicitly given; */
  546. X        case 2:   /*  therefore set both flags equal to normally false value */
  547. X            hflag = hflag_2;
  548. X            tflag = tflag_2v;
  549. X            break;
  550. X        case 1:   /* only filenames, *always* */
  551. X            hflag = FALSE;
  552. X            tflag = FALSE;
  553. X            zflag = FALSE;
  554. X            break;
  555. X        case 3:
  556. X        case 4:
  557. X        case 5:
  558. X            hflag = ((argc > 0) && !explicit_h)? FALSE : hflag_slmv;
  559. X            tflag = ((argc > 0) && !explicit_t)? FALSE : tflag_slm;
  560. X            break;
  561. X        case 10:
  562. X            hflag = hflag_slmv;
  563. X            tflag = tflag_2v;
  564. X            break;
  565. X    }
  566. X
  567. X    *pargc = argc;
  568. X    *pargv = argv;
  569. X    return 0;
  570. X
  571. X} /* end function zi_opts() */
  572. X
  573. X
  574. X
  575. X
  576. X
  577. X/*******************************/
  578. X/*  Function zi_end_central()  */
  579. X/*******************************/
  580. X
  581. Xint zi_end_central()   /* return PK-type error code */
  582. X{
  583. X    int  error = PK_COOL;
  584. X
  585. X
  586. X/*---------------------------------------------------------------------------
  587. X    Print out various interesting things about the zipfile.
  588. X  ---------------------------------------------------------------------------*/
  589. X
  590. X    /* header fits on one line, for anything up to 10GB and 10000 files: */
  591. X    if (hflag)
  592. X        PRINTF(((int)strlen(zipfn) < 39)?
  593. X          LoadFarString(LongHeader) :
  594. X          LoadFarString(ShortHeader), zipfn, (long)ziplen,
  595. X          ecrec.total_entries_central_dir,
  596. X          (ecrec.total_entries_central_dir==1)? "":"s");
  597. X
  598. X    /* verbose format */
  599. X    if (lflag > 9) {
  600. X        PRINTF(LoadFarString(EndCentDirRec));
  601. X        PRINTF(LoadFarString(LineSeparators));
  602. X
  603. X        PRINTF(LoadFarString(ActOffsetCentDir),
  604. X          (long)real_ecrec_offset, (long)real_ecrec_offset,
  605. X          (long)expect_ecrec_offset, (long)expect_ecrec_offset);
  606. X
  607. X        if (ecrec.number_this_disk == 0) {
  608. X            PRINTF(LoadFarString(SinglePartArchive),
  609. X              ecrec.total_entries_central_dir,
  610. X              (ecrec.total_entries_central_dir == 1)? "entry" : "entries",
  611. X              ecrec.size_central_directory, ecrec.size_central_directory,
  612. X              ecrec.offset_start_central_directory,
  613. X              ecrec.offset_start_central_directory);
  614. X        } else {
  615. X            PRINTF(LoadFarString(MultiPartArchive),
  616. X              ecrec.number_this_disk,
  617. X              ecrec.num_disk_with_start_central_dir,
  618. X              ecrec.num_entries_centrl_dir_ths_disk,
  619. X              (ecrec.num_entries_centrl_dir_ths_disk == 1)? "is" : "are",
  620. X              ecrec.total_entries_central_dir,
  621. X              (ecrec.total_entries_central_dir == 1) ? "entry" : "entries",
  622. X              ecrec.size_central_directory, ecrec.size_central_directory,
  623. X              ecrec.offset_start_central_directory,
  624. X              ecrec.offset_start_central_directory);
  625. X        }
  626. X
  627. X    /*-----------------------------------------------------------------------
  628. X        Get the zipfile comment, if any, and print it out.  (Comment may be
  629. X        up to 64KB long.  May the fleas of a thousand camels infest the arm-
  630. X        pits of anyone who actually takes advantage of this fact.)
  631. X      -----------------------------------------------------------------------*/
  632. X
  633. X        if (!ecrec.zipfile_comment_length)
  634. X            PRINTF(LoadFarString(NoZipfileComment));
  635. X        else {
  636. X            PRINTF(LoadFarString(ZipfileCommentDesc),
  637. X              ecrec.zipfile_comment_length );
  638. X            PRINTF(LoadFarString(ZipfileCommBegin));
  639. X            if (do_string(ecrec.zipfile_comment_length, DISPLAY))
  640. X                error = PK_WARN;
  641. X            PRINTF(LoadFarString(ZipfileCommEnd));
  642. X            if (error)
  643. X                PRINTF(LoadFarString(ZipfileCommTrunc2));
  644. X        } /* endif (comment exists) */
  645. X
  646. X    /* non-verbose mode:  print zipfile comment only if requested */
  647. X    } else if (zflag && ecrec.zipfile_comment_length) {
  648. X        if (do_string(ecrec.zipfile_comment_length,DISPLAY)) {
  649. X            FPRINTF(stderr, LoadFarString(ZipfileCommTruncMsg));
  650. X            error = PK_WARN;
  651. X        }
  652. X    } /* endif (verbose) */
  653. X
  654. X    return error;
  655. X
  656. X} /* end function zi_end_central() */
  657. X
  658. X
  659. X
  660. X
  661. X
  662. X/************************/
  663. X/*  Function zipinfo()  */
  664. X/************************/
  665. X
  666. Xint zipinfo()   /* return PK-type error code */
  667. X{
  668. X    int   j, do_this_file=FALSE, error, error_in_archive=PK_COOL;
  669. X    int   *fn_matched=NULL, *xn_matched=NULL;
  670. X    ush   members=0;
  671. X    ulg   tot_csize=0L, tot_ucsize=0L;
  672. X
  673. X
  674. X/*---------------------------------------------------------------------------
  675. X    Malloc space for check on unmatched filespecs (no big deal if one or both
  676. X    are NULL).
  677. X  ---------------------------------------------------------------------------*/
  678. X
  679. X    if (filespecs > 0  &&
  680. X        (fn_matched=(int *)malloc(filespecs*sizeof(int))) != NULL)
  681. X        for (j = 0;  j < filespecs;  ++j)
  682. X            fn_matched[j] = FALSE;
  683. X
  684. X    if (xfilespecs > 0  &&
  685. X        (xn_matched=(int *)malloc(xfilespecs*sizeof(int))) != NULL)
  686. X        for (j = 0;  j < xfilespecs;  ++j)
  687. X            xn_matched[j] = FALSE;
  688. X
  689. X/*---------------------------------------------------------------------------
  690. X    Set file pointer to start of central directory, then loop through cen-
  691. X    tral directory entries.  Check that directory-entry signature bytes are
  692. X    actually there (just a precaution), then process the entry.  We know
  693. X    the entire central directory is on this disk:  we wouldn't have any of
  694. X    this information unless the end-of-central-directory record was on this
  695. X    disk, and we wouldn't have gotten to this routine unless this is also
  696. X    the disk on which the central directory starts.  In practice, this had
  697. X    better be the *only* disk in the archive, but maybe someday we'll add
  698. X    multi-disk support.
  699. X  ---------------------------------------------------------------------------*/
  700. X
  701. X    pInfo->lcflag = 0;    /* used in do_string():  never TRUE in zipinfo mode */
  702. X    pInfo->textmode = 0;  /* so one can read on screen (but is it ever used?) */
  703. X    newzip = TRUE;        /* for zi_long() check of extra bytes */
  704. X
  705. X    for (j = 0;  j < (int)ecrec.total_entries_central_dir;  ++j) {
  706. X        if (readbuf(sig, 4) == 0)
  707. X            return PK_EOF;
  708. X        if (strncmp(sig, central_hdr_sig, 4)) {  /* just to make sure */
  709. X            FPRINTF(stderr, LoadFarString(CentSigMsg), j);  /* sig not found */
  710. X            return PK_BADERR;
  711. X        }
  712. X        if ((error = get_cdir_ent()) != PK_COOL)
  713. X            return error;       /* only PK_EOF defined */
  714. X
  715. X        /* do Amigas (AMIGA_) also have volume labels? */
  716. X        if (IS_VOLID(crec.external_file_attributes) &&
  717. X            (pInfo->hostnum == FS_FAT_ || pInfo->hostnum == FS_HPFS_ ||
  718. X             pInfo->hostnum == FS_NTFS_ || pInfo->hostnum == ATARI_))
  719. X            pInfo->vollabel = TRUE;
  720. X        else
  721. X            pInfo->vollabel = FALSE;
  722. X
  723. X        if ((error = do_string(crec.filename_length, FILENAME)) != PK_COOL) {
  724. X          error_in_archive = error;   /* might be warning */
  725. X          if (error > PK_WARN)        /* fatal */
  726. X              return error;
  727. X        }
  728. X
  729. X        if (!process_all_files) {    /* check if specified on command line */
  730. X            char  **pfn = pfnames-1;
  731. X
  732. X            do_this_file = FALSE;
  733. X            while (*++pfn)
  734. X                if (match(filename, *pfn, 0)) {
  735. X                    do_this_file = TRUE;
  736. X                    if (fn_matched)
  737. X                        fn_matched[pfn-pfnames] = TRUE;
  738. X                    break;       /* found match, so stop looping */
  739. X                }
  740. X            if (do_this_file) {  /* check if this is an excluded file */
  741. X                char  **pxn = pxnames-1;
  742. X
  743. X                while (*++pxn)
  744. X                    if (match(filename, *pxn, 0)) {
  745. X                        do_this_file = FALSE;
  746. X                        if (xn_matched)
  747. X                            xn_matched[pxn-pxnames] = TRUE;
  748. X                        break;
  749. X                    }
  750. X            }
  751. X        }
  752. X
  753. X    /*-----------------------------------------------------------------------
  754. X        If current file was specified on command line, or if no names were
  755. X        specified, do the listing for this file.  Otherwise, get rid of the
  756. X        file comment and go back for the next file.
  757. X      -----------------------------------------------------------------------*/
  758. X
  759. X        if (process_all_files || do_this_file) {
  760. X
  761. X            switch (lflag) {
  762. X                case 1:
  763. X                case 2:
  764. X                    fnprint();
  765. X                    SKIP_(crec.extra_field_length)
  766. X                    SKIP_(crec.file_comment_length)
  767. X                    break;
  768. X
  769. X                case 3:
  770. X                case 4:
  771. X                case 5:
  772. X                    if ((error = zi_short()) != PK_COOL) {
  773. X                        error_in_archive = error;   /* might be warning */
  774. X                        if (error > PK_WARN)        /* fatal */
  775. X                            return error;
  776. X                    }
  777. X                    break;
  778. X
  779. X                case 10:
  780. X#ifdef T20_VMS  /* GRR:  add cbreak-style "more" */
  781. X                    PRINTF(LoadFarString(CentralDirEntry), j);
  782. X#else
  783. X                    /* formfeed/CR for piping to "more": */
  784. X                    PRINTF(LoadFarString(CentralDirEntry), "\014", j);
  785. X#endif
  786. X                    PRINTF(LoadFarString(CentralDirLines));
  787. X
  788. X                    if ((error = zi_long()) != PK_COOL) {
  789. X                        error_in_archive = error;   /* might be warning */
  790. X                        if (error > PK_WARN)        /* fatal */
  791. X                            return error;
  792. X                    }
  793. X                    break;
  794. X
  795. X                default:
  796. X                    SKIP_(crec.extra_field_length)
  797. X                    SKIP_(crec.file_comment_length)
  798. X                    break;
  799. X
  800. X            } /* end switch (lflag) */
  801. X
  802. X            tot_csize += crec.csize;
  803. X            tot_ucsize += crec.ucsize;
  804. X            if (crec.general_purpose_bit_flag & 1)
  805. X                tot_csize -= 12;   /* don't count encryption header */
  806. X            ++members;
  807. X
  808. X        } else {   /* not listing */
  809. X            SKIP_(crec.extra_field_length)
  810. X            SKIP_(crec.file_comment_length)
  811. X
  812. X        } /* end if (list member?) */
  813. X
  814. X    } /* end for-loop (j: member files) */
  815. X
  816. X/*---------------------------------------------------------------------------
  817. X    Double check that we're back at the end-of-central-directory record.
  818. X  ---------------------------------------------------------------------------*/
  819. X
  820. X    if (readbuf(sig, 4) == 0)  /* disk error? */
  821. X        return PK_EOF;
  822. X    if (strncmp(sig, end_central_sig, 4)) {     /* just to make sure again */
  823. X        FPRINTF(stderr, LoadFarString(EndSigMsg));  /* didn't find sig */
  824. X        error_in_archive = PK_WARN;
  825. X    }
  826. X
  827. X/*---------------------------------------------------------------------------
  828. X    Check that we actually found requested files; if so, print totals.
  829. X  ---------------------------------------------------------------------------*/
  830. X
  831. X    if (tflag) {
  832. X        char *sgn = "";
  833. X        int cfactor = ratio(tot_ucsize, tot_csize);
  834. X
  835. X        if (cfactor < 0) {
  836. X            sgn = "-";
  837. X            cfactor = -cfactor;
  838. X        }
  839. X        PRINTF(LoadFarString(ZipfileStats),
  840. X          members, (members==1)? "":"s", tot_ucsize, tot_csize, sgn, cfactor/10,
  841. X          cfactor%10);
  842. X    }
  843. X
  844. X/*---------------------------------------------------------------------------
  845. X    Check for unmatched filespecs on command line and print warning if any
  846. X    found.
  847. X  ---------------------------------------------------------------------------*/
  848. X
  849. X    if (fn_matched) {
  850. X        for (j = 0;  j < filespecs;  ++j)
  851. X            if (!fn_matched[j])
  852. X                FPRINTF(stderr, LoadFarString(FilenameNotMatched),
  853. X                  pfnames[j]);
  854. X        free(fn_matched);
  855. X    }
  856. X    if (xn_matched) {
  857. X        for (j = 0;  j < xfilespecs;  ++j)
  858. X            if (!xn_matched[j])
  859. X                FPRINTF(stderr, LoadFarString(ExclFilenameNotMatched),
  860. X                  pxnames[j]);
  861. X        free(xn_matched);
  862. X    }
  863. X    if (members == 0 && error_in_archive <= PK_WARN)
  864. X        error_in_archive = PK_FIND;
  865. X
  866. X    return error_in_archive;
  867. X
  868. X} /* end function zipinfo() */
  869. X
  870. X
  871. X
  872. X
  873. X
  874. X#define OS_unkn unkn
  875. X
  876. X/************************/
  877. X/*  Function zi_long()  */
  878. X/************************/
  879. X
  880. Xstatic int zi_long()   /* return PK-type error code */
  881. X{
  882. X    int  error, error_in_archive=PK_COOL;
  883. X    ush  hostnum, hostver, extnum, extver, methnum, xattr;
  884. X    char workspace[12], attribs[22];
  885. X    static char meth_unkn[16];
  886. X    static char Far *os[NUM_HOSTS+1] = {
  887. X        OS_FAT, OS_Amiga, OS_VAXVMS, OS_Unix, OS_VMCMS, OS_AtariST, OS_HPFS,
  888. X        OS_Macintosh, OS_ZSystem, OS_CPM, OS_TOPS20, OS_NTFS, OS_QDOS,
  889. X        OS_Acorn, OS_unkn
  890. X    };
  891. X    static char Far *method[NUM_METHODS+1] = {
  892. X        MthdNone, MthdShrunk, MthdRedF1, MthdRedF2, MthdRedF3, MthdRedF4,
  893. X        MthdImplode, MthdToken, MthdDeflate, meth_unkn
  894. X    };
  895. X    static char *dtype[4] = {"normal", "maximum", "fast", "superfast"};
  896. X    static ulg endprev;
  897. X
  898. X
  899. X/*---------------------------------------------------------------------------
  900. X    Check whether there's any extra space inside the zipfile.
  901. X  ---------------------------------------------------------------------------*/
  902. X
  903. X    if (newzip) {   /* reset if new zipfile; account for multi-part archives */
  904. X        endprev = (crec.relative_offset_local_header == 4L)? 4L : 0L;
  905. X        newzip = FALSE;
  906. X    }
  907. X
  908. X    if (crec.relative_offset_local_header != endprev)
  909. X        PRINTF(LoadFarString(ExtraBytesPreceding),
  910. X          (long)crec.relative_offset_local_header - (long)endprev);
  911. X
  912. X    /* calculate endprev for next time around */
  913. X    endprev = crec.relative_offset_local_header + 4L + LREC_SIZE +
  914. X      crec.filename_length + crec.extra_field_length + crec.file_comment_length
  915. X      + crec.csize;
  916. X
  917. X/*---------------------------------------------------------------------------
  918. X    Print out various interesting things about the compressed file.
  919. X  ---------------------------------------------------------------------------*/
  920. X
  921. X    hostnum = MIN(crec.version_made_by[1], NUM_HOSTS);
  922. X    hostver = crec.version_made_by[0];
  923. X    extnum = MIN(crec.version_needed_to_extract[1], NUM_HOSTS);
  924. X    extver = crec.version_needed_to_extract[0];
  925. X    methnum = MIN(crec.compression_method, NUM_METHODS);
  926. X
  927. X    if (hostnum == NUM_HOSTS)
  928. X        sprintf(OS_unkn, LoadFarString(Unknown), (int)crec.version_made_by[1]);
  929. X    if (methnum == NUM_METHODS)
  930. X        sprintf(meth_unkn, LoadFarString(Unknown), crec.compression_method);
  931. X
  932. X    PRINTF("  ");  fnprint();
  933. X
  934. X    PRINTF(LoadFarString(HostOS), LoadFarStringSmall(os[hostnum]));
  935. X    PRINTF(LoadFarString(EncodeSWVer), hostver/10, hostver%10);
  936. X    PRINTF(LoadFarString(MinOSCompReq), LoadFarStringSmall(os[extnum]));
  937. X    PRINTF(LoadFarString(MinSWVerReq), extver/10, extver%10);
  938. X    PRINTF(LoadFarString(CompressMethod), LoadFarStringSmall(method[methnum]));
  939. X    if (methnum == IMPLODED) {
  940. X        PRINTF(LoadFarString(SlideWindowSizeImplode),
  941. X          (crec.general_purpose_bit_flag & 2)? '8' : '4');
  942. X        PRINTF(LoadFarString(ShannonFanoTrees),
  943. X          (crec.general_purpose_bit_flag & 4)? '3' : '2');
  944. X    } else if (methnum == DEFLATED) {
  945. X        ush  dnum=(crec.general_purpose_bit_flag>>1) & 3;
  946. X        PRINTF(LoadFarString(CompressSubtype), dtype[dnum]);
  947. X    }
  948. X    PRINTF(LoadFarString(FileSecurity),
  949. X      (crec.general_purpose_bit_flag & 1)? "" : "not ");
  950. X    PRINTF(LoadFarString(ExtendedLocalHdr),
  951. X      (crec.general_purpose_bit_flag & 8)? "yes" : "no");
  952. X    /* print upper 3 bits for amusement? */
  953. X    PRINTF(LoadFarString(FileModDate),
  954. X      zi_time(&crec.last_mod_file_date, &crec.last_mod_file_time));
  955. X    PRINTF(LoadFarString(CRC32Value), crec.crc32);
  956. X    PRINTF(LoadFarString(CompressedFileSize), crec.csize);
  957. X    PRINTF(LoadFarString(UncompressedFileSize), crec.ucsize);
  958. X    PRINTF(LoadFarString(FilenameLength), crec.filename_length);
  959. X    PRINTF(LoadFarString(ExtraFieldLength), crec.extra_field_length);
  960. X    PRINTF(LoadFarString(FileCommentLength), crec.file_comment_length);
  961. X    PRINTF(LoadFarString(FileDiskNum), crec.disk_number_start);
  962. X    PRINTF(LoadFarString(ApparentFileType),
  963. X      (crec.internal_file_attributes & 1)? "text" : "binary");
  964. X/*
  965. X    PRINTF("  external file attributes (hex):                   %.8lx\n",
  966. X      crec.external_file_attributes);
  967. X */
  968. X    xattr = (ush)((crec.external_file_attributes >> 16) & 0xFFFF);
  969. X    if (hostnum == VMS_) {
  970. X        char   *p=attribs, *q=attribs+1;
  971. X        int    i, j, k;
  972. X
  973. X        for (k = 0;  k < 12;  ++k)
  974. X            workspace[k] = 0;
  975. X        if (xattr & VMS_IRUSR)
  976. X            workspace[0] = 'R';
  977. X        if (xattr & VMS_IWUSR) {
  978. X            workspace[1] = 'W';
  979. X            workspace[3] = 'D';
  980. X        }
  981. X        if (xattr & VMS_IXUSR)
  982. X            workspace[2] = 'E';
  983. X        if (xattr & VMS_IRGRP)
  984. X            workspace[4] = 'R';
  985. X        if (xattr & VMS_IWGRP) {
  986. X            workspace[5] = 'W';
  987. X            workspace[7] = 'D';
  988. X        }
  989. X        if (xattr & VMS_IXGRP)
  990. X            workspace[6] = 'E';
  991. X        if (xattr & VMS_IROTH)
  992. X            workspace[8] = 'R';
  993. X        if (xattr & VMS_IWOTH) {
  994. X            workspace[9] = 'W';
  995. X            workspace[11] = 'D';
  996. X        }
  997. X        if (xattr & VMS_IXOTH)
  998. X            workspace[10] = 'E';
  999. X
  1000. X        *p++ = '(';
  1001. X        for (k = j = 0;  j < 3;  ++j) {    /* loop over groups of permissions */
  1002. X            for (i = 0;  i < 4;  ++i, ++k)  /* loop over perms within a group */
  1003. X                if (workspace[k])
  1004. X                    *p++ = workspace[k];
  1005. X            *p++ = ',';                       /* group separator */
  1006. X            if (j == 0)
  1007. X                while ((*p++ = *q++) != ','); /* system, owner perms are same */
  1008. X        }
  1009. X        *p-- = 0;
  1010. X        *p = ')';   /* overwrite last comma */
  1011. X        PRINTF(LoadFarString(VMSFileAttributes), xattr, attribs);
  1012. X
  1013. X    } else if (hostnum == AMIGA_) {
  1014. X        switch (xattr & AMI_IFMT) {
  1015. X            case AMI_IFDIR:  attribs[0] = 'd';  break;
  1016. X            case AMI_IFREG:  attribs[0] = '-';  break;
  1017. X            default:         attribs[0] = '?';  break;
  1018. X        }
  1019. X        attribs[1] = (xattr & AMI_IHIDDEN)?   'h' : '-';
  1020. X        attribs[2] = (xattr & AMI_ISCRIPT)?   's' : '-';
  1021. X        attribs[3] = (xattr & AMI_IPURE)?     'p' : '-';
  1022. X        attribs[4] = (xattr & AMI_IARCHIVE)?  'a' : '-';
  1023. X        attribs[5] = (xattr & AMI_IREAD)?     'r' : '-';
  1024. X        attribs[6] = (xattr & AMI_IWRITE)?    'w' : '-';
  1025. X        attribs[7] = (xattr & AMI_IEXECUTE)?  'e' : '-';
  1026. X        attribs[8] = (xattr & AMI_IDELETE)?   'd' : '-';
  1027. X        attribs[9] = 0;   /* better dlm the string */
  1028. X        PRINTF(LoadFarString(AmigaFileAttributes), xattr, attribs);
  1029. X
  1030. X    } else if ((hostnum != FS_FAT_) && (hostnum != FS_HPFS_) &&
  1031. X               (hostnum != FS_NTFS_) && (hostnum != ATARI_) &&
  1032. X               (hostnum != ACORN_))
  1033. X    {                                 /* assume Unix-like */
  1034. X        switch (xattr & UNX_IFMT) {
  1035. X            case UNX_IFDIR:   attribs[0] = 'd';  break;
  1036. X            case UNX_IFREG:   attribs[0] = '-';  break;
  1037. X            case UNX_IFLNK:   attribs[0] = 'l';  break;
  1038. X            case UNX_IFBLK:   attribs[0] = 'b';  break;
  1039. X            case UNX_IFCHR:   attribs[0] = 'c';  break;
  1040. X            case UNX_IFIFO:   attribs[0] = 'p';  break;
  1041. X            case UNX_IFSOCK:  attribs[0] = 's';  break;
  1042. X            default:          attribs[0] = '?';  break;
  1043. X        }
  1044. X        attribs[1] = (xattr & UNX_IRUSR)? 'r' : '-';
  1045. X        attribs[4] = (xattr & UNX_IRGRP)? 'r' : '-';
  1046. X        attribs[7] = (xattr & UNX_IROTH)? 'r' : '-';
  1047. X
  1048. X        attribs[2] = (xattr & UNX_IWUSR)? 'w' : '-';
  1049. X        attribs[5] = (xattr & UNX_IWGRP)? 'w' : '-';
  1050. X        attribs[8] = (xattr & UNX_IWOTH)? 'w' : '-';
  1051. X
  1052. X        if (xattr & UNX_IXUSR)
  1053. X            attribs[3] = (xattr & UNX_ISUID)? 's' : 'x';
  1054. X        else
  1055. X            attribs[3] = (xattr & UNX_ISUID)? 'S' : '-';   /* S = undefined */
  1056. X        if (xattr & UNX_IXGRP)
  1057. X            attribs[6] = (xattr & UNX_ISGID)? 's' : 'x';   /* == UNX_ENFMT */
  1058. X        else
  1059. X            attribs[6] = (xattr & UNX_ISGID)? 'l' : '-';
  1060. X        if (xattr & UNX_IXOTH)
  1061. X            attribs[9] = (xattr & UNX_ISVTX)? 't' : 'x';   /* "sticky bit" */
  1062. X        else
  1063. X            attribs[9] = (xattr & UNX_ISVTX)? 'T' : '-';   /* T = undefined */
  1064. X        attribs[10] = 0;
  1065. X
  1066. X        PRINTF(LoadFarString(UnixFileAttributes), xattr, attribs);
  1067. X
  1068. X    } else {
  1069. X        PRINTF(LoadFarString(NonMSDOSFileAttributes),
  1070. X            crec.external_file_attributes >> 8);
  1071. X
  1072. X    } /* endif (hostnum: external attributes format) */
  1073. X
  1074. X    if ((xattr=(ush)(crec.external_file_attributes & 0xFF)) == 0)
  1075. X        PRINTF(LoadFarString(MSDOSFileAttributes), xattr);
  1076. X    else if (xattr == 1)
  1077. X        PRINTF(LoadFarString(MSDOSFileAttributesRO), xattr);
  1078. X    else
  1079. X        PRINTF(LoadFarString(MSDOSFileAttributesAlpha),
  1080. X          xattr, (xattr&1)?"rdo ":"", (xattr&2)?"hid ":"", (xattr&4)?"sys ":"",
  1081. X          (xattr&8)?"lab ":"", (xattr&16)?"dir ":"", (xattr&32)?"arc":"");
  1082. X    PRINTF(LoadFarString(LocalHeaderOffset),
  1083. X      crec.relative_offset_local_header, crec.relative_offset_local_header);
  1084. X
  1085. X/*---------------------------------------------------------------------------
  1086. X    Skip the extra field, if any, and print the file comment, if any (the
  1087. X    filename has already been printed, above).  That finishes up this file
  1088. X    entry...
  1089. X  ---------------------------------------------------------------------------*/
  1090. X
  1091. X    if (crec.extra_field_length > 0) {
  1092. X        ush ef_id, ef_datalen;
  1093. X
  1094. X        if ((error = do_string(crec.extra_field_length, EXTRA_FIELD)) != 0) {
  1095. X            error_in_archive = error;
  1096. X            if (error > PK_WARN)   /* fatal:  can't continue */
  1097. X                return error;
  1098. X        }
  1099. X        if (extra_field == (uch *)NULL)
  1100. X            return PK_ERR;   /* not consistent with crec length */
  1101. X        ef_id = makeword(extra_field);
  1102. X        ef_datalen = makeword(&extra_field[2]);
  1103. X        switch (ef_id) {
  1104. X            case EF_AV:
  1105. X                PRINTF(LoadFarString(ExtraFieldType), ef_id,
  1106. X                  LoadFarStringSmall(efAV), ef_datalen);
  1107. X                break;
  1108. X            case EF_OS2:
  1109. X                PRINTF(LoadFarString(ExtraFieldType), ef_id,
  1110. X                  LoadFarStringSmall(efOS2), ef_datalen);
  1111. X/* GRR:  should check that ef_datalen really 4 and not 2 before doing this: */
  1112. X                PRINTF(LoadFarString(OS2EAs), makelong(&extra_field[4]));
  1113. X                break;
  1114. X            case EF_PKVMS:
  1115. X                PRINTF(LoadFarString(ExtraFieldType), ef_id,
  1116. X                  LoadFarStringSmall(efPKVMS), ef_datalen);
  1117. X                break;
  1118. X            case EF_IZVMS:
  1119. X                PRINTF(LoadFarString(ExtraFieldType), ef_id,
  1120. X                  LoadFarStringSmall(efIZVMS), ef_datalen);
  1121. X                break;
  1122. X            case EF_ASIUNIX:
  1123. X                PRINTF(LoadFarString(ExtraFieldType), ef_id,
  1124. X                  LoadFarStringSmall(efASiUnix), ef_datalen);
  1125. X                break;
  1126. X            case EF_SPARK:
  1127. X                PRINTF(LoadFarString(ExtraFieldType), ef_id,
  1128. X                  LoadFarStringSmall(efSpark), ef_datalen);
  1129. X                break;
  1130. X            default:
  1131. X                PRINTF(LoadFarString(ExtraFieldType), ef_id,
  1132. X                  LoadFarStringSmall(efUnknown), ef_datalen);
  1133. X                break;
  1134. X        }
  1135. X        if (ef_id != EF_OS2) {
  1136. X            ush i, n;
  1137. X
  1138. X            if (ef_datalen <= 16) {
  1139. X                PRINTF(LoadFarString(ColonIndent));
  1140. X/* GRR:  should double-check that datalen <= crec.extra_field_length - 4 */
  1141. X                n = ef_datalen;
  1142. X            } else {
  1143. X                PRINTF(LoadFarString(First16),
  1144. X                  LoadFarStringSmall(ColonIndent));
  1145. X                n = 16;
  1146. X            }
  1147. X            for (i = 0;  i < n;  ++i)
  1148. X                PRINTF(LoadFarString(efFormat), extra_field[i+4]);
  1149. X        }
  1150. X        PRINTF("\n");
  1151. X    }
  1152. X
  1153. X    if (!crec.file_comment_length)
  1154. X        PRINTF(LoadFarString(NoFileComment));
  1155. X    else {
  1156. X        PRINTF(LoadFarString(FileCommBegin));
  1157. X        if ((error = do_string(crec.file_comment_length, DISPLAY)) != PK_COOL) {
  1158. X          error_in_archive = error;   /* might be warning */
  1159. X          if (error > PK_WARN)   /* fatal */
  1160. X              return error;
  1161. X        }
  1162. X        PRINTF(LoadFarString(FileCommEnd));
  1163. X    }
  1164. X
  1165. X    return error_in_archive;
  1166. X
  1167. X} /* end function zi_long() */
  1168. X
  1169. X
  1170. X
  1171. X
  1172. X
  1173. X/*************************/
  1174. X/*  Function zi_short()  */
  1175. X/*************************/
  1176. X
  1177. Xstatic int zi_short()   /* return PK-type error code */
  1178. X{
  1179. X    int         k, error, error_in_archive=PK_COOL;
  1180. X    ush         methnum, hostnum, hostver, xattr;
  1181. X    char        *p, workspace[12], attribs[16];
  1182. X    static char impl[5]="i#:#", defl[5]="def#";
  1183. X    static char dtype[5]="NXFS";  /* normal, maximum, fast, superfast */
  1184. X    static char *os[NUM_HOSTS+1] = {
  1185. X        "fat", "ami", "vms", "unx", "cms", "atr", "hpf", "mac", "zzz",
  1186. X        "cpm", "t20", "ntf", "qds", "aco", "???"
  1187. X    };
  1188. X    static char *method[NUM_METHODS+1] = {
  1189. X        "stor", "shrk", "re:1", "re:2", "re:3", "re:4", impl, "tokn",
  1190. X        defl, unkn
  1191. X    };
  1192. X
  1193. X
  1194. X/*---------------------------------------------------------------------------
  1195. X    Print out various interesting things about the compressed file.
  1196. X  ---------------------------------------------------------------------------*/
  1197. X
  1198. X    methnum = MIN(crec.compression_method, NUM_METHODS);
  1199. X    hostnum = MIN(crec.version_made_by[1], NUM_HOSTS);
  1200. X    hostver = crec.version_made_by[0];
  1201. X/*
  1202. X    extnum = MIN(crec.version_needed_to_extract[1], NUM_HOSTS);
  1203. X    extver = crec.version_needed_to_extract[0];
  1204. X */
  1205. X
  1206. X    if (methnum == IMPLODED) {
  1207. X        impl[1] = (char) ((crec.general_purpose_bit_flag & 2)? '8' : '4');
  1208. X        impl[3] = (char) ((crec.general_purpose_bit_flag & 4)? '3' : '2');
  1209. X    } else if (methnum == DEFLATED) {
  1210. X        ush  dnum=(crec.general_purpose_bit_flag>>1) & 3;
  1211. X        defl[3] = dtype[dnum];
  1212. X    } else if (methnum == NUM_METHODS) {   /* unknown */
  1213. X        sprintf(unkn, "u%03d", crec.compression_method);
  1214. X    }
  1215. X
  1216. X    for (k = 0;  k < 15;  ++k)
  1217. X        attribs[k] = ' ';
  1218. X    attribs[15] = 0;
  1219. X
  1220. X    xattr = (ush)((crec.external_file_attributes >> 16) & 0xFFFF);
  1221. X    switch (hostnum) {
  1222. X        case VMS_:
  1223. X            {   int    i, j;
  1224. X
  1225. X                for (k = 0;  k < 12;  ++k)
  1226. X                    workspace[k] = 0;
  1227. X                if (xattr & VMS_IRUSR)
  1228. X                    workspace[0] = 'R';
  1229. X                if (xattr & VMS_IWUSR) {
  1230. X                    workspace[1] = 'W';
  1231. X                    workspace[3] = 'D';
  1232. X                }
  1233. X                if (xattr & VMS_IXUSR)
  1234. X                    workspace[2] = 'E';
  1235. X                if (xattr & VMS_IRGRP)
  1236. X                    workspace[4] = 'R';
  1237. X                if (xattr & VMS_IWGRP) {
  1238. X                    workspace[5] = 'W';
  1239. X                    workspace[7] = 'D';
  1240. X                }
  1241. X                if (xattr & VMS_IXGRP)
  1242. X                  workspace[6] = 'E';
  1243. X                if (xattr & VMS_IROTH)
  1244. X                    workspace[8] = 'R';
  1245. X                if (xattr & VMS_IWOTH) {
  1246. X                    workspace[9] = 'W';
  1247. X                    workspace[11] = 'D';
  1248. X                }
  1249. X                if (xattr & VMS_IXOTH)
  1250. X                    workspace[10] = 'E';
  1251. X
  1252. X                p = attribs;
  1253. X                for (k = j = 0;  j < 3;  ++j) {     /* groups of permissions */
  1254. X                    for (i = 0;  i < 4;  ++i, ++k)  /* perms within a group */
  1255. X                        if (workspace[k])
  1256. X                            *p++ = workspace[k];
  1257. X                    *p++ = ',';                     /* group separator */
  1258. X                }
  1259. X                *--p = ' ';   /* overwrite last comma */
  1260. X                if ((p - attribs) < 12)
  1261. X                    sprintf(&attribs[12], "%d.%d", hostver/10, hostver%10);
  1262. X            }
  1263. X            break;
  1264. X
  1265. X        case FS_FAT_:
  1266. X        case FS_HPFS_:
  1267. X        case FS_NTFS_:
  1268. X        case ATARI_:
  1269. X        case ACORN_:
  1270. X            xattr = (ush)(crec.external_file_attributes & 0xFF);
  1271. X            sprintf(attribs, ".r.-...     %d.%d", hostver/10, hostver%10);
  1272. X            attribs[2] = (xattr & 0x01)? '-' : 'w';
  1273. X            attribs[5] = (xattr & 0x02)? 'h' : '-';
  1274. X            attribs[6] = (xattr & 0x04)? 's' : '-';
  1275. X            attribs[4] = (xattr & 0x20)? 'a' : '-';
  1276. X            if (xattr & 0x10) {
  1277. X                attribs[0] = 'd';
  1278. X                attribs[3] = 'x';
  1279. X            } else
  1280. X                attribs[0] = '-';
  1281. X            if (IS_VOLID(xattr))
  1282. X                attribs[0] = 'V';
  1283. X            else if ((p = strrchr(filename, '.')) != (char *)NULL) {
  1284. X                ++p;
  1285. X                if (STRNICMP(p, "com", 3) == 0 || STRNICMP(p, "exe", 3) == 0 ||
  1286. X                    STRNICMP(p, "btm", 3) == 0 || STRNICMP(p, "cmd", 3) == 0 ||
  1287. X                    STRNICMP(p, "bat", 3) == 0)
  1288. X                    attribs[3] = 'x';
  1289. X            }
  1290. X            break;
  1291. X
  1292. X        case AMIGA_:
  1293. X            switch (xattr & AMI_IFMT) {
  1294. X                case AMI_IFDIR:  attribs[0] = 'd';  break;
  1295. X                case AMI_IFREG:  attribs[0] = '-';  break;
  1296. X                default:         attribs[0] = '?';  break;
  1297. X            }
  1298. X            attribs[1] = (xattr & AMI_IHIDDEN)?   'h' : '-';
  1299. X            attribs[2] = (xattr & AMI_ISCRIPT)?   's' : '-';
  1300. X            attribs[3] = (xattr & AMI_IPURE)?     'p' : '-';
  1301. X            attribs[4] = (xattr & AMI_IARCHIVE)?  'a' : '-';
  1302. X            attribs[5] = (xattr & AMI_IREAD)?     'r' : '-';
  1303. X            attribs[6] = (xattr & AMI_IWRITE)?    'w' : '-';
  1304. X            attribs[7] = (xattr & AMI_IEXECUTE)?  'e' : '-';
  1305. X            attribs[8] = (xattr & AMI_IDELETE)?   'd' : '-';
  1306. X            sprintf(&attribs[12], "%d.%d", hostver/10, hostver%10);
  1307. X            break;
  1308. X
  1309. X        default:   /* assume Unix-like */
  1310. X            switch (xattr & UNX_IFMT) {
  1311. X                case UNX_IFDIR:   attribs[0] = 'd';  break;
  1312. X                case UNX_IFREG:   attribs[0] = '-';  break;
  1313. X                case UNX_IFLNK:   attribs[0] = 'l';  break;
  1314. X                case UNX_IFBLK:   attribs[0] = 'b';  break;
  1315. X                case UNX_IFCHR:   attribs[0] = 'c';  break;
  1316. X                case UNX_IFIFO:   attribs[0] = 'p';  break;
  1317. X                case UNX_IFSOCK:  attribs[0] = 's';  break;
  1318. X                default:          attribs[0] = '?';  break;
  1319. X            }
  1320. X            attribs[1] = (xattr & UNX_IRUSR)? 'r' : '-';
  1321. X            attribs[4] = (xattr & UNX_IRGRP)? 'r' : '-';
  1322. X            attribs[7] = (xattr & UNX_IROTH)? 'r' : '-';
  1323. X            attribs[2] = (xattr & UNX_IWUSR)? 'w' : '-';
  1324. X            attribs[5] = (xattr & UNX_IWGRP)? 'w' : '-';
  1325. X            attribs[8] = (xattr & UNX_IWOTH)? 'w' : '-';
  1326. X
  1327. X            if (xattr & UNX_IXUSR)
  1328. X                attribs[3] = (xattr & UNX_ISUID)? 's' : 'x';
  1329. X            else
  1330. X                attribs[3] = (xattr & UNX_ISUID)? 'S' : '-';  /* S==undefined */
  1331. X            if (xattr & UNX_IXGRP)
  1332. X                attribs[6] = (xattr & UNX_ISGID)? 's' : 'x';  /* == UNX_ENFMT */
  1333. X            else
  1334. X                /* attribs[6] = (xattr & UNX_ISGID)? 'l' : '-';  real 4.3BSD */
  1335. X                attribs[6] = (xattr & UNX_ISGID)? 'S' : '-';  /* SunOS 4.1.x */
  1336. X            if (xattr & UNX_IXOTH)
  1337. X                attribs[9] = (xattr & UNX_ISVTX)? 't' : 'x';  /* "sticky bit" */
  1338. X            else
  1339. X                attribs[9] = (xattr & UNX_ISVTX)? 'T' : '-';  /* T==undefined */
  1340. X
  1341. X            sprintf(&attribs[12], "%d.%d", hostver/10, hostver%10);
  1342. X            break;
  1343. X
  1344. X    } /* end switch (hostnum: external attributes format) */
  1345. X
  1346. X    PRINTF("%s %s %7lu %c%c", attribs, os[hostnum], crec.ucsize,
  1347. X      (crec.general_purpose_bit_flag & 1)?
  1348. X      ((crec.internal_file_attributes & 1)? 'T' : 'B') :   /* encrypted */
  1349. X      ((crec.internal_file_attributes & 1)? 't' : 'b'),    /* plaintext */
  1350. X      (crec.general_purpose_bit_flag & 8)? (crec.extra_field_length? 'X' : 'l')
  1351. X                                        : (crec.extra_field_length? 'x' : '-'));
  1352. X    if (lflag == 4) {
  1353. X        ulg csiz = crec.csize;
  1354. X
  1355. X        if (crec.general_purpose_bit_flag & 1)
  1356. X            csiz -= 12;    /* if encrypted, don't count encryption header */
  1357. X        PRINTF("%3d%%", (ratio(crec.ucsize,csiz) + 5)/10);
  1358. X    } else if (lflag == 5)
  1359. X        PRINTF(" %7lu", crec.csize);
  1360. X
  1361. X    PRINTF(" %s %s ", method[methnum],
  1362. X      zi_time(&crec.last_mod_file_date, &crec.last_mod_file_time));
  1363. X    fnprint();
  1364. X
  1365. X/*---------------------------------------------------------------------------
  1366. X    Skip the extra field and/or the file comment, if any (the filename has
  1367. X    already been printed, above).  That finishes up this file entry...
  1368. X  ---------------------------------------------------------------------------*/
  1369. X
  1370. X    SKIP_(crec.extra_field_length)
  1371. X    SKIP_(crec.file_comment_length)
  1372. X
  1373. X    return error_in_archive;
  1374. X
  1375. X} /* end function zi_short() */
  1376. X
  1377. X
  1378. X
  1379. X
  1380. X
  1381. X/************************/
  1382. X/*  Function zi_time()  */
  1383. X/************************/
  1384. X
  1385. Xstatic char *zi_time(datez, timez)
  1386. X    ush *datez, *timez;
  1387. X{
  1388. X    ush yr, mo, dy, hh, mm, ss;
  1389. X    static char d_t_str[21], bogus[4];
  1390. X    static char Far *month[13] = {
  1391. X        bogus, JanMonth, FebMonth, MarMonth, AprMonth, MayMonth, JunMonth,
  1392. X        JulMonth, AugMonth, SepMonth, OctMonth, NovMonth, DecMonth
  1393. X    };
  1394. X
  1395. X
  1396. X
  1397. X/*---------------------------------------------------------------------------
  1398. X    Convert the file-modification date and time info to a string of the form
  1399. X    "1991 Feb 23 17:15:00" or "23-Feb-91 17:15," depending on value of lflag.
  1400. X  ---------------------------------------------------------------------------*/
  1401. X
  1402. X    yr = ((*datez >> 9) & 0x7f) + 80;
  1403. X    mo = ((*datez >> 5) & 0x0f);
  1404. X    dy = *datez & 0x1f;
  1405. X
  1406. X    hh = (*timez >> 11) & 0x1f;
  1407. X    mm = (*timez >> 5) & 0x3f;
  1408. X    ss = (*timez & 0x1f) * 2;
  1409. X
  1410. X    if (mo == 0 || mo > 12) {
  1411. X        sprintf(bogus, LoadFarString(BogusFmt), mo);
  1412. X        mo = 0;
  1413. X    }
  1414. X
  1415. X    if (lflag > 9)  /* verbose listing format */
  1416. X        sprintf(d_t_str, LoadFarString(YMDHMSTime), yr+1900,
  1417. X            LoadFarStringSmall(month[mo]), dy, hh, mm, ss);
  1418. X    else if (T_flag)
  1419. X        sprintf(d_t_str, LoadFarString(DecimalTime), yr%100, mo, dy, hh, mm,
  1420. X          ss);
  1421. X    else   /* was:  if ((lflag >= 3) && (lflag <= 5)) */
  1422. X        sprintf(d_t_str, LoadFarString(DMYHMTime), dy,
  1423. X            LoadFarStringSmall(month[mo]), yr%100, hh, mm);
  1424. X
  1425. X    return d_t_str;
  1426. X
  1427. X} /* end function zi_time() */
  1428. X
  1429. X#endif /* !NO_ZIPINFO */
  1430. X
  1431. X
  1432. X
  1433. X
  1434. X
  1435. X/*************************/
  1436. X/* Function list_files() */
  1437. X/*************************/
  1438. X
  1439. Xint list_files()    /* return PK-type error code */
  1440. X{
  1441. X    char sgn, cfactorstr[10];
  1442. X    int do_this_file=FALSE, cfactor, error, error_in_archive=PK_COOL;
  1443. X    int longhdr=(vflag>1), date_format, methnum;
  1444. X    ush j, yr, mo, dy, hh, mm, members=0;
  1445. X    ulg csiz, tot_csize=0L, tot_ucsize=0L;
  1446. X#ifdef OS2
  1447. X    ulg ea_size, tot_easize=0L, tot_eafiles=0L;
  1448. X#endif
  1449. X#ifdef MSWIN
  1450. X    PSTR psLBEntry;  /* list box entry */
  1451. X#endif
  1452. X    min_info info;
  1453. X    static char defl[]="Defl:#", dtype[]="NXFS";   /* see zi_short() */
  1454. X    static char *method[NUM_METHODS+1] =
  1455. X        {"Stored", "Shrunk", "Reduce1", "Reduce2", "Reduce3", "Reduce4",
  1456. X         "Implode", "Token", defl, unkn};
  1457. X
  1458. X
  1459. X
  1460. X/*---------------------------------------------------------------------------
  1461. X    Unlike extract_or_test_files(), this routine confines itself to the cen-
  1462. X    tral directory.  Thus its structure is somewhat simpler, since we can do
  1463. X    just a single loop through the entire directory, listing files as we go.
  1464. X
  1465. X    So to start off, print the heading line and then begin main loop through
  1466. X    the central directory.  The results will look vaguely like the following:
  1467. X
  1468. X  Length  Method   Size  Ratio   Date    Time   CRC-32     Name ("^" ==> case
  1469. X  ------  ------   ----  -----   ----    ----   ------     ----   conversion)
  1470. X   44004  Implode  13041  71%  11-02-89  19:34  8b4207f7   Makefile.UNIX
  1471. X    3438  Shrunk    2209  36%  09-15-90  14:07  a2394fd8  ^dos-file.ext
  1472. X  ---------------------------------------------------------------------------*/
  1473. X
  1474. X    pInfo = &info;
  1475. X    date_format = DATE_FORMAT;
  1476. X
  1477. X#ifndef MSWIN
  1478. X    if (qflag < 2)
  1479. X        if (L_flag)
  1480. X            PRINTF(LoadFarString(CaseConversion),
  1481. X              LoadFarStringSmall(Headers[longhdr][0]),
  1482. X              LoadFarStringSmall2(Headers[longhdr][1]));
  1483. X        else
  1484. X            PRINTF("%s\n%s\n", LoadFarString(Headers[longhdr][0]),
  1485. X                   LoadFarStringSmall(Headers[longhdr][1]));
  1486. X#endif /* !MSWIN */
  1487. X
  1488. X    for (j = 0; j < ecrec.total_entries_central_dir; ++j) {
  1489. X
  1490. X        if (readbuf(sig, 4) == 0)
  1491. X            return PK_EOF;
  1492. X        if (strncmp(sig, central_hdr_sig, 4)) {  /* just to make sure */
  1493. X            FPRINTF(stderr, LoadFarString(CentSigMsg), j);   /* sig not found */
  1494. X            FPRINTF(stderr, LoadFarString(ReportMsg));  /* check binary xfers */
  1495. X            return PK_BADERR;
  1496. X        }
  1497. X        /* process_cdir_file_hdr() sets pInfo->lcflag: */
  1498. X        if ((error = process_cdir_file_hdr()) != PK_COOL)
  1499. X            return error;       /* only PK_EOF defined */
  1500. X
  1501. X        /*
  1502. X         * We could DISPLAY the filename instead of storing (and possibly trun-
  1503. X         * cating, in the case of a very long name) and printing it, but that
  1504. X         * has the disadvantage of not allowing case conversion--and it's nice
  1505. X         * to be able to see in the listing precisely how you have to type each
  1506. X         * filename in order for unzip to consider it a match.  Speaking of
  1507. X         * which, if member names were specified on the command line, check in
  1508. X         * with match() to see if the current file is one of them, and make a
  1509. X         * note of it if it is.
  1510. X         */
  1511. X
  1512. X        if ((error = do_string(crec.filename_length, FILENAME)) != PK_COOL) {
  1513. X            error_in_archive = error;             /*  ^--(uses pInfo->lcflag) */
  1514. X            if (error > PK_WARN)   /* fatal:  can't continue */
  1515. X                return error;
  1516. X        }
  1517. X        if (extra_field != (uch *)NULL) {
  1518. X            free(extra_field);
  1519. X            extra_field = (uch *)NULL;
  1520. X        }
  1521. X        if ((error = do_string(crec.extra_field_length, EXTRA_FIELD)) != 0) {
  1522. X            error_in_archive = error;  
  1523. X            if (error > PK_WARN)      /* fatal */
  1524. X                return error;
  1525. X        }
  1526. X        if (!process_all_files) {   /* check if specified on command line */
  1527. X            char **pfn = pfnames-1;
  1528. X
  1529. X            do_this_file = FALSE;
  1530. X            while (*++pfn)
  1531. X                if (match(filename, *pfn, C_flag)) {
  1532. X                    do_this_file = TRUE;
  1533. X                    break;       /* found match, so stop looping */
  1534. X                }
  1535. X            if (do_this_file) {  /* check if this is an excluded file */
  1536. X                char **pxn = pxnames-1;
  1537. X
  1538. X                while (*++pxn)
  1539. X                    if (match(filename, *pxn, C_flag)) {
  1540. X                        do_this_file = FALSE;  /* ^-- ignore case in match */
  1541. X                        break;
  1542. X                    }
  1543. X            }
  1544. X        }
  1545. X        /*
  1546. X         * If current file was specified on command line, or if no names were
  1547. X         * specified, do the listing for this file.  Otherwise, get rid of the
  1548. X         * file comment and go back for the next file.
  1549. X         */
  1550. X
  1551. X        if (process_all_files || do_this_file) {
  1552. X
  1553. X            yr = (((crec.last_mod_file_date >> 9) & 0x7f) + 80) % (unsigned)100;
  1554. X            mo = (crec.last_mod_file_date >> 5) & 0x0f;
  1555. X            dy = crec.last_mod_file_date & 0x1f;
  1556. X
  1557. X            /* permute date so it displays according to national convention */
  1558. X            switch (date_format) {
  1559. X                case DF_YMD:
  1560. X                    hh = mo; mo = yr; yr = dy; dy = hh;
  1561. X                    break;
  1562. X                case DF_DMY:
  1563. X                    hh = mo; mo = dy; dy = hh;
  1564. X            }
  1565. X            hh = (crec.last_mod_file_time >> 11) & 0x1f;
  1566. X            mm = (crec.last_mod_file_time >> 5) & 0x3f;
  1567. X
  1568. X            csiz = crec.csize;
  1569. X            if (crec.general_purpose_bit_flag & 1)
  1570. X                csiz -= 12;   /* if encrypted, don't count encryption header */
  1571. X            if ((cfactor = ratio(crec.ucsize, csiz)) < 0) {
  1572. X                sgn = '-';
  1573. X                cfactor = (-cfactor + 5) / 10;
  1574. X            } else {
  1575. X                sgn = ' ';
  1576. X                cfactor = (cfactor + 5) / 10;
  1577. X            }
  1578. X            sprintf(cfactorstr, LoadFarString(CompFactorStr), sgn, cfactor);
  1579. X
  1580. X            methnum = MIN(crec.compression_method, NUM_METHODS);
  1581. X            if (methnum == DEFLATED)
  1582. X                defl[5] = dtype[(crec.general_purpose_bit_flag>>1) & 3];
  1583. X            else if (methnum == NUM_METHODS)
  1584. X                sprintf(unkn, LoadFarString(CompMethodUnknown),
  1585. X                    crec.compression_method);
  1586. X
  1587. X#if 0       /* GRR/Euro:  add this? */
  1588. X#if defined(DOS_NT_OS2) || defined(UNIX)
  1589. X            for (p = filename;  *p;  ++p)
  1590. X                if (!isprint(*p))
  1591. X                    *p = '?';  /* change non-printable chars to '?' */
  1592. X#endif /* DOS_NT_OS2 || UNIX */
  1593. X#endif /* 0 */
  1594. X
  1595. X#ifdef MSWIN
  1596. X#ifdef NEED_EARLY_REDRAW
  1597. X            /* turn on listbox redrawing just before adding last line */
  1598. X            if (j == (ecrec.total_entries_central_dir-1))
  1599. X                (void)SendMessage(hWndList, WM_SETREDRAW, TRUE, 0L);
  1600. X#endif /* NEED_EARLY_REDRAW */
  1601. X            psLBEntry =
  1602. X              (PSTR)LocalAlloc(LMEM_FIXED, FILNAMSIZ+LONG_FORM_FNAME_INX);
  1603. X            /* GRR:  does OemToAnsi filter out escape and CR characters? */
  1604. X            OemToAnsi(filename, filename);  /* translate to ANSI */
  1605. X            if (longhdr) {
  1606. X                wsprintf(psLBEntry, LoadFarString(LongHdrStats),
  1607. X                  crec.ucsize, (LPSTR)method[methnum], csiz, cfactorstr,
  1608. X                  mo, dy, yr, hh, mm, crec.crc32, (pInfo->lcflag?'^':' '),
  1609. X                  (LPSTR)filename);
  1610. X                SendMessage(hWndList, LB_ADDSTRING, 0,
  1611. X                  (LONG)(LPSTR)psLBEntry);
  1612. X            } else {
  1613. X                wsprintf(psLBEntry, LoadFarString(ShortHdrStats),
  1614. X                  crec.ucsize, mo, dy, yr, hh, mm, (pInfo->lcflag?'^':' '),
  1615. X                  (LPSTR)filename);
  1616. X                SendMessage(hWndList, LB_ADDSTRING, 0,
  1617. X                  (LONG)(LPSTR)psLBEntry);
  1618. X            }
  1619. X            LocalFree((HANDLE)psLBEntry);
  1620. X#else /* !MSWIN */
  1621. X            if (longhdr)
  1622. X                PRINTF(LoadFarString(LongHdrStats),
  1623. X                  crec.ucsize, method[methnum], csiz, cfactorstr, mo, dy, yr,
  1624. X                  hh, mm, crec.crc32, (pInfo->lcflag?'^':' '));
  1625. X            else
  1626. X                PRINTF(LoadFarString(ShortHdrStats), crec.ucsize,
  1627. X                  mo, dy, yr, hh, mm, (pInfo->lcflag?'^':' '));
  1628. X            fnprint();
  1629. X#endif /* ?MSWIN */
  1630. X
  1631. X            error = do_string(crec.file_comment_length, QCOND? DISPLAY : SKIP);
  1632. X            if (error) {
  1633. X                error_in_archive = error;  /* might be just warning */
  1634. X                if (error > PK_WARN)       /* fatal */
  1635. X                    return error;
  1636. X            }
  1637. X            tot_ucsize += crec.ucsize;
  1638. X            tot_csize += csiz;
  1639. X            ++members;
  1640. X#ifdef OS2
  1641. X            if ((ea_size = SizeOfEAs(extra_field)) != 0) {
  1642. X                tot_easize += ea_size;
  1643. X                tot_eafiles++;
  1644. X            }
  1645. X#endif
  1646. X        } else {        /* not listing this file */
  1647. X            SKIP_(crec.file_comment_length)
  1648. X        }
  1649. X    } /* end for-loop (j: files in central directory) */
  1650. X
  1651. X/*---------------------------------------------------------------------------
  1652. X    Print footer line and totals (compressed size, uncompressed size, number
  1653. X    of members in zipfile).
  1654. X  ---------------------------------------------------------------------------*/
  1655. X
  1656. X    if (qflag < 2) {
  1657. X        if ((cfactor = ratio(tot_ucsize, tot_csize)) < 0) {
  1658. X            sgn = '-';
  1659. X            cfactor = (-cfactor + 5) / 10;
  1660. X        } else {
  1661. X            sgn = ' ';
  1662. X            cfactor = (cfactor + 5) / 10;
  1663. X        }
  1664. X        sprintf(cfactorstr, LoadFarString(CompFactorStr), sgn, cfactor);
  1665. X#ifdef MSWIN
  1666. X        /* Display just the totals since the dashed lines get displayed
  1667. X         * in UpdateListBox(). Get just enough space to display total. */
  1668. X        if (longhdr)
  1669. X            wsprintf(lpumb->szTotalsLine,LoadFarString(LongFileHeader), 
  1670. X              tot_ucsize, tot_csize, cfactorstr, members);
  1671. X        else
  1672. X            wsprintf(lpumb->szTotalsLine, LoadFarString(ShortFileHeader), 
  1673. X              tot_ucsize, members);
  1674. X#else /* !MSWIN */
  1675. X        if (longhdr)
  1676. X            PRINTF(LoadFarString(LongFileHeader), tot_ucsize, tot_csize, cfactorstr, members);
  1677. X        else
  1678. X            PRINTF(LoadFarString(ShortFileHeader), tot_ucsize, members);
  1679. X#endif /* ?MSWIN */
  1680. X#ifdef OS2
  1681. X        if (tot_eafiles && tot_easize)
  1682. X            PRINTF("\n%ld file%s %ld bytes of EA's attached.\n", tot_eafiles, 
  1683. X              tot_eafiles == 1 ? " has" : "s have a total of", tot_easize);
  1684. X#endif
  1685. X    }
  1686. X/*---------------------------------------------------------------------------
  1687. X    Double check that we're back at the end-of-central-directory record.
  1688. X  ---------------------------------------------------------------------------*/
  1689. X
  1690. X    if (readbuf(sig, 4) == 0)
  1691. X        return PK_EOF;
  1692. X    if (strncmp(sig, end_central_sig, 4)) {     /* just to make sure again */
  1693. X        FPRINTF(stderr, LoadFarString(EndSigMsg));  /* didn't find sig */
  1694. X        error_in_archive = PK_WARN;
  1695. X    }
  1696. X    if (members == 0 && error_in_archive <= PK_WARN)
  1697. X        error_in_archive = PK_FIND;
  1698. X
  1699. X    return error_in_archive;
  1700. X
  1701. X} /* end function list_files() */
  1702. X
  1703. X
  1704. X
  1705. X
  1706. X
  1707. X/********************/
  1708. X/* Function ratio() */
  1709. X/********************/
  1710. X
  1711. Xstatic int ratio(uc, c)
  1712. X    ulg uc, c;
  1713. X{
  1714. X    ulg denom;
  1715. X
  1716. X    if (uc == 0)
  1717. X        return 0;
  1718. X    if (uc > 2000000L) {    /* risk signed overflow if multiply numerator */
  1719. X        denom = uc / 1000L;
  1720. X        return ((uc >= c) ?
  1721. X            (int) ((uc-c + (denom>>1)) / denom) :
  1722. X          -((int) ((c-uc + (denom>>1)) / denom)));
  1723. X    } else {             /* ^^^^^^^^ rounding */
  1724. X        denom = uc;
  1725. X        return ((uc >= c) ?
  1726. X            (int) ((1000L*(uc-c) + (denom>>1)) / denom) :
  1727. X          -((int) ((1000L*(c-uc) + (denom>>1)) / denom)));
  1728. X    }                            /* ^^^^^^^^ rounding */
  1729. X}
  1730. X
  1731. X
  1732. X
  1733. X
  1734. X
  1735. X/************************/
  1736. X/*  Function fnprint()  */
  1737. X/************************/
  1738. X
  1739. Xstatic void fnprint()    /* print filename (after filtering) and newline */
  1740. X{
  1741. X    register uch *p = (uch *)filename-1;
  1742. X    register uch *q = (uch *)slide;
  1743. X
  1744. X#ifdef NATIVE
  1745. X    PRINTF("%s", filename);   /* GRR:  can ANSI be used with EBCDIC? */
  1746. X#else /* ASCII */
  1747. X    while (*++p) {
  1748. X        if (*p < 32) {        /* ASCII control character */
  1749. X            *q++ = '^';
  1750. X            *q++ = *p + 64;
  1751. X        } else
  1752. X            *q++ = *p;
  1753. X    }                    /* filename better not be longer than slide[] ... */
  1754. X    *q = '\0';
  1755. X    PRINTF("%s\n", slide);
  1756. X#endif /* ?NATIVE */
  1757. X
  1758. X} /* end function fnprint() */
  1759. END_OF_FILE
  1760.   if test 64797 -ne `wc -c <'unzip-5.12/zipinfo.c'`; then
  1761.     echo shar: \"'unzip-5.12/zipinfo.c'\" unpacked with wrong size!
  1762.   fi
  1763.   # end of 'unzip-5.12/zipinfo.c'
  1764. fi
  1765. echo shar: End of archive 4 \(of 20\).
  1766. cp /dev/null ark4isdone
  1767. MISSING=""
  1768. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ; do
  1769.     if test ! -f ark${I}isdone ; then
  1770.     MISSING="${MISSING} ${I}"
  1771.     fi
  1772. done
  1773. if test "${MISSING}" = "" ; then
  1774.     echo You have unpacked all 20 archives.
  1775.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1776. else
  1777.     echo You still must unpack the following archives:
  1778.     echo "        " ${MISSING}
  1779. fi
  1780. exit 0
  1781. exit 0 # Just in case...
  1782.