2 Copyright (c) 1990-2009 Info-ZIP. All rights reserved.
4 See the accompanying file LICENSE, version 2009-Jan-02 or later
5 (the contents of which are also included in unzip.h) for terms of use.
6 If, for some reason, all these files are missing, the Info-ZIP license
7 also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
9 /*---------------------------------------------------------------------------
11 zipinfo.c Greg Roelofs et al.
13 This file contains all of the ZipInfo-specific listing routines for UnZip.
22 ---------------------------------------------------------------------------*/
25 #define UNZIP_INTERNAL
29 #ifndef NO_ZIPINFO /* strings use up too much space in small-memory systems */
31 /* Define OS-specific attributes for use on ALL platforms--the S_xxxx
32 * versions of these are defined differently (or not defined) by different
33 * compilers and operating systems. */
35 #define UNX_IFMT 0170000 /* Unix file type mask */
36 #define UNX_IFREG 0100000 /* Unix regular file */
37 #define UNX_IFSOCK 0140000 /* Unix socket (BSD, not SysV or Amiga) */
38 #define UNX_IFLNK 0120000 /* Unix symbolic link (not SysV, Amiga) */
39 #define UNX_IFBLK 0060000 /* Unix block special (not Amiga) */
40 #define UNX_IFDIR 0040000 /* Unix directory */
41 #define UNX_IFCHR 0020000 /* Unix character special (not Amiga) */
42 #define UNX_IFIFO 0010000 /* Unix fifo (BCC, not MSC or Amiga) */
43 #define UNX_ISUID 04000 /* Unix set user id on execution */
44 #define UNX_ISGID 02000 /* Unix set group id on execution */
45 #define UNX_ISVTX 01000 /* Unix directory permissions control */
46 #define UNX_ENFMT UNX_ISGID /* Unix record locking enforcement flag */
47 #define UNX_IRWXU 00700 /* Unix read, write, execute: owner */
48 #define UNX_IRUSR 00400 /* Unix read permission: owner */
49 #define UNX_IWUSR 00200 /* Unix write permission: owner */
50 #define UNX_IXUSR 00100 /* Unix execute permission: owner */
51 #define UNX_IRWXG 00070 /* Unix read, write, execute: group */
52 #define UNX_IRGRP 00040 /* Unix read permission: group */
53 #define UNX_IWGRP 00020 /* Unix write permission: group */
54 #define UNX_IXGRP 00010 /* Unix execute permission: group */
55 #define UNX_IRWXO 00007 /* Unix read, write, execute: other */
56 #define UNX_IROTH 00004 /* Unix read permission: other */
57 #define UNX_IWOTH 00002 /* Unix write permission: other */
58 #define UNX_IXOTH 00001 /* Unix execute permission: other */
60 #define VMS_IRUSR UNX_IRUSR /* VMS read/owner */
61 #define VMS_IWUSR UNX_IWUSR /* VMS write/owner */
62 #define VMS_IXUSR UNX_IXUSR /* VMS execute/owner */
63 #define VMS_IRGRP UNX_IRGRP /* VMS read/group */
64 #define VMS_IWGRP UNX_IWGRP /* VMS write/group */
65 #define VMS_IXGRP UNX_IXGRP /* VMS execute/group */
66 #define VMS_IROTH UNX_IROTH /* VMS read/other */
67 #define VMS_IWOTH UNX_IWOTH /* VMS write/other */
68 #define VMS_IXOTH UNX_IXOTH /* VMS execute/other */
70 #define AMI_IFMT 06000 /* Amiga file type mask */
71 #define AMI_IFDIR 04000 /* Amiga directory */
72 #define AMI_IFREG 02000 /* Amiga regular file */
73 #define AMI_IHIDDEN 00200 /* to be supported in AmigaDOS 3.x */
74 #define AMI_ISCRIPT 00100 /* executable script (text command file) */
75 #define AMI_IPURE 00040 /* allow loading into resident memory */
76 #define AMI_IARCHIVE 00020 /* not modified since bit was last set */
77 #define AMI_IREAD 00010 /* can be opened for reading */
78 #define AMI_IWRITE 00004 /* can be opened for writing */
79 #define AMI_IEXECUTE 00002 /* executable image, a loadable runfile */
80 #define AMI_IDELETE 00001 /* can be deleted */
82 #define THS_IFMT 0xF000 /* Theos file type mask */
83 #define THS_IFIFO 0x1000 /* pipe */
84 #define THS_IFCHR 0x2000 /* char device */
85 #define THS_IFSOCK 0x3000 /* socket */
86 #define THS_IFDIR 0x4000 /* directory */
87 #define THS_IFLIB 0x5000 /* library */
88 #define THS_IFBLK 0x6000 /* block device */
89 #define THS_IFREG 0x8000 /* regular file */
90 #define THS_IFREL 0x9000 /* relative (direct) */
91 #define THS_IFKEY 0xA000 /* keyed */
92 #define THS_IFIND 0xB000 /* indexed */
93 #define THS_IFRND 0xC000 /* ???? */
94 #define THS_IFR16 0xD000 /* 16 bit real mode program */
95 #define THS_IFP16 0xE000 /* 16 bit protected mode prog */
96 #define THS_IFP32 0xF000 /* 32 bit protected mode prog */
97 #define THS_IMODF 0x0800 /* modified */
98 #define THS_INHID 0x0400 /* not hidden */
99 #define THS_IEUSR 0x0200 /* erase permission: owner */
100 #define THS_IRUSR 0x0100 /* read permission: owner */
101 #define THS_IWUSR 0x0080 /* write permission: owner */
102 #define THS_IXUSR 0x0040 /* execute permission: owner */
103 #define THS_IROTH 0x0004 /* read permission: other */
104 #define THS_IWOTH 0x0002 /* write permission: other */
105 #define THS_IXOTH 0x0001 /* execute permission: other */
107 #ifdef OLD_THEOS_EXTRA
108 # include "theos/oldstat.h"
111 #ifndef NSK_UNSTRUCTURED
112 # define NSK_UNSTRUCTURED 0
114 #ifndef NSK_OBJECTFILECODE
115 # define NSK_OBJECTFILECODE 100
117 #ifndef NSK_EDITFILECODE
118 # define NSK_EDITFILECODE 101
121 #define LFLAG 3 /* short "ls -l" type listing */
123 static int zi_long
OF((__GPRO__ zusz_t
*pEndprev
, int error_in_archive
));
124 static int zi_short
OF((__GPRO
));
125 static void zi_showMacTypeCreator
126 OF((__GPRO__ uch
*ebfield
));
127 static char *zi_time
OF((__GPRO__ ZCONST ulg
*datetimez
,
128 ZCONST
time_t *modtimez
, char *d_t_str
));
131 /**********************************************/
132 /* Strings used in zipinfo.c (ZipInfo half) */
133 /**********************************************/
135 static ZCONST
char nullStr
[] = "";
136 static ZCONST
char PlurSufx
[] = "s";
138 static ZCONST
char Far ZipInfHeader2
[] =
139 "Zip file size: %s bytes, number of entries: %s\n";
140 static ZCONST
char Far EndCentDirRec
[] = "\nEnd-of-central-directory record:\n";
141 static ZCONST
char Far LineSeparators
[] = "-------------------------------\n\n";
142 static ZCONST
char Far ZipFSizeVerbose
[] = "\
143 Zip archive file size: %s (%sh)\n";
144 static ZCONST
char Far ActOffsetCentDir
[] = "\
145 Actual end-cent-dir record offset: %s (%sh)\n\
146 Expected end-cent-dir record offset: %s (%sh)\n\
147 (based on the length of the central directory and its expected offset)\n\n";
148 static ZCONST
char Far SinglePartArchive1
[] = "\
149 This zipfile constitutes the sole disk of a single-part archive; its\n\
150 central directory contains %s %s.\n\
151 The central directory is %s (%sh) bytes long,\n";
152 static ZCONST
char Far SinglePartArchive2
[] = "\
153 and its (expected) offset in bytes from the beginning of the zipfile\n\
155 static ZCONST
char Far MultiPartArchive1
[] = "\
156 This zipfile constitutes disk %lu of a multi-part archive. The central\n\
157 directory starts on disk %lu at an offset within that archive part\n";
158 static ZCONST
char Far MultiPartArchive2
[] = "\
159 of %s (%sh) bytes. The entire\n\
160 central directory is %s (%sh) bytes long.\n";
161 static ZCONST
char Far MultiPartArchive3
[] = "\
162 %s of the archive entries %s contained within this zipfile volume,\n\
163 out of a total of %s %s.\n\n";
165 static ZCONST
char Far CentralDirEntry
[] =
166 "\nCentral directory entry #%lu:\n---------------------------\n\n";
167 static ZCONST
char Far ZipfileStats
[] =
168 "%lu file%s, %s bytes uncompressed, %s bytes compressed: %s%d.%d%%\n";
170 /* zi_long() strings */
171 static ZCONST
char Far OS_FAT
[] = "MS-DOS, OS/2 or NT FAT";
172 static ZCONST
char Far OS_Amiga
[] = "Amiga";
173 static ZCONST
char Far OS_VMS
[] = "VMS";
174 static ZCONST
char Far OS_Unix
[] = "Unix";
175 static ZCONST
char Far OS_VMCMS
[] = "VM/CMS";
176 static ZCONST
char Far OS_AtariST
[] = "Atari ST";
177 static ZCONST
char Far OS_HPFS
[] = "OS/2 or NT HPFS";
178 static ZCONST
char Far OS_Macintosh
[] = "Macintosh HFS";
179 static ZCONST
char Far OS_ZSystem
[] = "Z-System";
180 static ZCONST
char Far OS_CPM
[] = "CP/M";
181 static ZCONST
char Far OS_TOPS20
[] = "TOPS-20";
182 static ZCONST
char Far OS_NTFS
[] = "NTFS";
183 static ZCONST
char Far OS_QDOS
[] = "SMS/QDOS";
184 static ZCONST
char Far OS_Acorn
[] = "Acorn RISC OS";
185 static ZCONST
char Far OS_MVS
[] = "MVS";
186 static ZCONST
char Far OS_VFAT
[] = "Win32 VFAT";
187 static ZCONST
char Far OS_AtheOS
[] = "AtheOS";
188 static ZCONST
char Far OS_BeOS
[] = "BeOS";
189 static ZCONST
char Far OS_Tandem
[] = "Tandem NSK";
190 static ZCONST
char Far OS_Theos
[] = "Theos";
191 static ZCONST
char Far OS_MacDarwin
[] = "Mac OS/X (Darwin)";
192 #ifdef OLD_THEOS_EXTRA
193 static ZCONST
char Far OS_TheosOld
[] = "Theos (Old)";
194 #endif /* OLD_THEOS_EXTRA */
196 static ZCONST
char Far MthdNone
[] = "none (stored)";
197 static ZCONST
char Far MthdShrunk
[] = "shrunk";
198 static ZCONST
char Far MthdRedF1
[] = "reduced (factor 1)";
199 static ZCONST
char Far MthdRedF2
[] = "reduced (factor 2)";
200 static ZCONST
char Far MthdRedF3
[] = "reduced (factor 3)";
201 static ZCONST
char Far MthdRedF4
[] = "reduced (factor 4)";
202 static ZCONST
char Far MthdImplode
[] = "imploded";
203 static ZCONST
char Far MthdToken
[] = "tokenized";
204 static ZCONST
char Far MthdDeflate
[] = "deflated";
205 static ZCONST
char Far MthdDeflat64
[] = "deflated (enhanced-64k)";
206 static ZCONST
char Far MthdDCLImplode
[] = "imploded (PK DCL)";
207 static ZCONST
char Far MthdBZip2
[] = "bzipped";
208 static ZCONST
char Far MthdLZMA
[] = "LZMA-ed";
209 static ZCONST
char Far MthdTerse
[] = "tersed (IBM)";
210 static ZCONST
char Far MthdLZ77
[] = "LZ77-compressed (IBM)";
211 static ZCONST
char Far MthdWavPack
[] = "WavPacked";
212 static ZCONST
char Far MthdPPMd
[] = "PPMd-ed";
214 static ZCONST
char Far DeflNorm
[] = "normal";
215 static ZCONST
char Far DeflMax
[] = "maximum";
216 static ZCONST
char Far DeflFast
[] = "fast";
217 static ZCONST
char Far DeflSFast
[] = "superfast";
219 static ZCONST
char Far ExtraBytesPreceding
[] =
220 " There are an extra %s bytes preceding this file.\n\n";
222 static ZCONST
char Far UnknownNo
[] = "unknown (%d)";
225 static ZCONST
char Far LocalHeaderOffset
[] =
226 "\n offset of local header from start of archive: %s\n\
229 static ZCONST
char Far LocalHeaderOffset
[] =
230 "\n offset of local header from start of archive: %s (%sh) bytes\n";
232 static ZCONST
char Far HostOS
[] =
233 " file system or operating system of origin: %s\n";
234 static ZCONST
char Far EncodeSWVer
[] =
235 " version of encoding software: %u.%u\n";
236 static ZCONST
char Far MinOSCompReq
[] =
237 " minimum file system compatibility required: %s\n";
238 static ZCONST
char Far MinSWVerReq
[] =
239 " minimum software version required to extract: %u.%u\n";
240 static ZCONST
char Far CompressMethod
[] =
241 " compression method: %s\n";
242 static ZCONST
char Far SlideWindowSizeImplode
[] =
243 " size of sliding dictionary (implosion): %cK\n";
244 static ZCONST
char Far ShannonFanoTrees
[] =
245 " number of Shannon-Fano trees (implosion): %c\n";
246 static ZCONST
char Far CompressSubtype
[] =
247 " compression sub-type (deflation): %s\n";
248 static ZCONST
char Far FileSecurity
[] =
249 " file security status: %sencrypted\n";
250 static ZCONST
char Far ExtendedLocalHdr
[] =
251 " extended local header: %s\n";
252 static ZCONST
char Far FileModDate
[] =
253 " file last modified on (DOS date/time): %s\n";
254 #ifdef USE_EF_UT_TIME
255 static ZCONST
char Far UT_FileModDate
[] =
256 " file last modified on (UT extra field modtime): %s %s\n";
257 static ZCONST
char Far LocalTime
[] = "local";
259 static ZCONST
char Far GMTime
[] = "UTC";
261 #endif /* USE_EF_UT_TIME */
262 static ZCONST
char Far CRC32Value
[] =
263 " 32-bit CRC value (hex): %.8lx\n";
264 static ZCONST
char Far CompressedFileSize
[] =
265 " compressed size: %s bytes\n";
266 static ZCONST
char Far UncompressedFileSize
[] =
267 " uncompressed size: %s bytes\n";
268 static ZCONST
char Far FilenameLength
[] =
269 " length of filename: %u characters\n";
270 static ZCONST
char Far ExtraFieldLength
[] =
271 " length of extra field: %u bytes\n";
272 static ZCONST
char Far FileCommentLength
[] =
273 " length of file comment: %u characters\n";
274 static ZCONST
char Far FileDiskNum
[] =
275 " disk number on which file begins: disk %lu\n";
276 static ZCONST
char Far ApparentFileType
[] =
277 " apparent file type: %s\n";
278 static ZCONST
char Far VMSFileAttributes
[] =
279 " VMS file attributes (%06o octal): %s\n";
280 static ZCONST
char Far AmigaFileAttributes
[] =
281 " Amiga file attributes (%06o octal): %s\n";
282 static ZCONST
char Far UnixFileAttributes
[] =
283 " Unix file attributes (%06o octal): %s\n";
284 static ZCONST
char Far NonMSDOSFileAttributes
[] =
285 " non-MSDOS external file attributes: %06lX hex\n";
286 static ZCONST
char Far MSDOSFileAttributes
[] =
287 " MS-DOS file attributes (%02X hex): none\n";
288 static ZCONST
char Far MSDOSFileAttributesRO
[] =
289 " MS-DOS file attributes (%02X hex): read-only\n";
290 static ZCONST
char Far MSDOSFileAttributesAlpha
[] =
291 " MS-DOS file attributes (%02X hex): %s%s%s%s%s%s%s%s\n";
292 static ZCONST
char Far TheosFileAttributes
[] =
293 " Theos file attributes (%04X hex): %s\n";
295 static ZCONST
char Far TheosFTypLib
[] = "Library ";
296 static ZCONST
char Far TheosFTypDir
[] = "Directory ";
297 static ZCONST
char Far TheosFTypReg
[] = "Sequential ";
298 static ZCONST
char Far TheosFTypRel
[] = "Direct ";
299 static ZCONST
char Far TheosFTypKey
[] = "Keyed ";
300 static ZCONST
char Far TheosFTypInd
[] = "Indexed ";
301 static ZCONST
char Far TheosFTypR16
[] = " 86 program ";
302 static ZCONST
char Far TheosFTypP16
[] = "286 program ";
303 static ZCONST
char Far TheosFTypP32
[] = "386 program ";
304 static ZCONST
char Far TheosFTypUkn
[] = "??? ";
306 static ZCONST
char Far ExtraFieldTrunc
[] = "\n\
307 error: EF data block (type 0x%04x) size %u exceeds remaining extra field\n\
308 space %u; block length has been truncated.\n";
309 static ZCONST
char Far ExtraFields
[] = "\n\
310 The central-directory extra field contains:";
311 static ZCONST
char Far ExtraFieldType
[] = "\n\
312 - A subfield with ID 0x%04x (%s) and %u data bytes";
313 static ZCONST
char Far efPKSZ64
[] = "PKWARE 64-bit sizes";
314 static ZCONST
char Far efAV
[] = "PKWARE AV";
315 static ZCONST
char Far efOS2
[] = "OS/2";
316 static ZCONST
char Far efPKVMS
[] = "PKWARE VMS";
317 static ZCONST
char Far efPKWin32
[] = "PKWARE Win32";
318 static ZCONST
char Far efPKUnix
[] = "PKWARE Unix";
319 static ZCONST
char Far efIZVMS
[] = "Info-ZIP VMS";
320 static ZCONST
char Far efIZUnix
[] = "old Info-ZIP Unix/OS2/NT";
321 static ZCONST
char Far efIZUnix2
[] = "Unix UID/GID (16-bit)";
322 static ZCONST
char Far efIZUnix3
[] = "Unix UID/GID (any size)";
323 static ZCONST
char Far efTime
[] = "universal time";
324 static ZCONST
char Far efU8Path
[] = "UTF8 path name";
325 static ZCONST
char Far efU8Commnt
[] = "UTF8 entry comment";
326 static ZCONST
char Far efJLMac
[] = "old Info-ZIP Macintosh";
327 static ZCONST
char Far efMac3
[] = "new Info-ZIP Macintosh";
328 static ZCONST
char Far efZipIt
[] = "ZipIt Macintosh";
329 static ZCONST
char Far efSmartZip
[] = "SmartZip Macintosh";
330 static ZCONST
char Far efZipIt2
[] = "ZipIt Macintosh (short)";
331 static ZCONST
char Far efVMCMS
[] = "VM/CMS";
332 static ZCONST
char Far efMVS
[] = "MVS";
333 static ZCONST
char Far efACL
[] = "OS/2 ACL";
334 static ZCONST
char Far efNTSD
[] = "Security Descriptor";
335 static ZCONST
char Far efAtheOS
[] = "AtheOS";
336 static ZCONST
char Far efBeOS
[] = "BeOS";
337 static ZCONST
char Far efQDOS
[] = "SMS/QDOS";
338 static ZCONST
char Far efAOSVS
[] = "AOS/VS";
339 static ZCONST
char Far efSpark
[] = "Acorn SparkFS";
340 static ZCONST
char Far efMD5
[] = "Fred Kantor MD5";
341 static ZCONST
char Far efASiUnix
[] = "ASi Unix";
342 static ZCONST
char Far efTandem
[] = "Tandem NSK";
343 static ZCONST
char Far efTheos
[] = "Theos";
344 static ZCONST
char Far efUnknown
[] = "unknown";
346 static ZCONST
char Far OS2EAs
[] = ".\n\
347 The local extra field has %lu bytes of OS/2 extended attributes.\n\
348 (May not match OS/2 \"dir\" amount due to storage method)";
349 static ZCONST
char Far izVMSdata
[] = ". The extra\n\
350 field is %s and has %u bytes of VMS %s information%s";
351 static ZCONST
char Far izVMSstored
[] = "stored";
352 static ZCONST
char Far izVMSrleenc
[] = "run-length encoded";
353 static ZCONST
char Far izVMSdeflat
[] = "deflated";
354 static ZCONST
char Far izVMScunknw
[] = "compressed(?)";
355 static ZCONST
char Far
*izVMScomp
[4] =
356 {izVMSstored
, izVMSrleenc
, izVMSdeflat
, izVMScunknw
};
357 static ZCONST
char Far ACLdata
[] = ".\n\
358 The local extra field has %lu bytes of access control list information";
359 static ZCONST
char Far NTSDData
[] = ".\n\
360 The local extra field has %lu bytes of NT security descriptor data";
361 static ZCONST
char Far UTdata
[] = ".\n\
362 The local extra field has UTC/GMT %s time%s";
363 static ZCONST
char Far UTmodification
[] = "modification";
364 static ZCONST
char Far UTaccess
[] = "access";
365 static ZCONST
char Far UTcreation
[] = "creation";
366 static ZCONST
char Far U8PthCmnComplete
[] = ".\n\
367 The UTF8 data of the extra field (V%u, ASCII name CRC `%.8lx') are:\n ";
368 static ZCONST
char Far U8PthCmnF24
[] = ". The first\n\
369 24 UTF8 bytes in the extra field (V%u, ASCII name CRC `%.8lx') are:\n ";
370 static ZCONST
char Far ZipItFname
[] = ".\n\
371 The Mac long filename is %s";
372 static ZCONST
char Far Mac3data
[] = ".\n\
373 The local extra field has %lu bytes of %scompressed Macintosh\n\
375 /* MacOSdata[] is used by EF_MAC3, EF_ZIPIT, EF_ZIPIT2 and EF_JLEE e. f. */
376 static ZCONST
char Far MacOSdata
[] = ".\n\
377 The associated file has type code `%c%c%c%c' and creator code `%c%c%c%c'";
378 static ZCONST
char Far MacOSdata1
[] = ".\n\
379 The associated file has type code `0x%lx' and creator code `0x%lx'";
380 static ZCONST
char Far MacOSJLEEflags
[] = ".\n File is marked as %s";
381 static ZCONST
char Far MacOS_RF
[] = "Resource-fork";
382 static ZCONST
char Far MacOS_DF
[] = "Data-fork";
383 static ZCONST
char Far MacOSMAC3flags
[] = ".\n\
384 File is marked as %s, File Dates are in %d Bit";
385 static ZCONST
char Far AtheOSdata
[] = ".\n\
386 The local extra field has %lu bytes of %scompressed AtheOS file attributes";
387 static ZCONST
char Far BeOSdata
[] = ".\n\
388 The local extra field has %lu bytes of %scompressed BeOS file attributes";
389 /* The associated file has type code `%c%c%c%c' and creator code `%c%c%c%c'" */
390 static ZCONST
char Far QDOSdata
[] = ".\n\
391 The QDOS extra field subtype is `%c%c%c%c'";
392 static ZCONST
char Far AOSVSdata
[] = ".\n\
393 The AOS/VS extra field revision is %d.%d";
394 static ZCONST
char Far TandemUnstr
[] = "Unstructured";
395 static ZCONST
char Far TandemRel
[] = "Relative";
396 static ZCONST
char Far TandemEntry
[] = "Entry Sequenced";
397 static ZCONST
char Far TandemKey
[] = "Key Sequenced";
398 static ZCONST
char Far TandemEdit
[] = "Edit";
399 static ZCONST
char Far TandemObj
[] = "Object";
400 static ZCONST
char Far
*TandemFileformat
[6] =
401 {TandemUnstr
, TandemRel
, TandemEntry
, TandemKey
, TandemEdit
, TandemObj
};
402 static ZCONST
char Far Tandemdata
[] = ".\n\
403 The file was originally a Tandem %s file, with file code %u";
404 static ZCONST
char Far MD5data
[] = ".\n\
405 The 128-bit MD5 signature is %s";
407 static ZCONST
char Far VmMvsExtraField
[] = ".\n\
408 The stored file open mode (FLDATA TYPE) is \"%s\"";
409 static ZCONST
char Far VmMvsInvalid
[] = "[invalid]";
412 static ZCONST
char Far First20
[] = ". The first\n 20 are: ";
413 static ZCONST
char Far ColonIndent
[] = ":\n ";
414 static ZCONST
char Far efFormat
[] = " %02x";
416 static ZCONST
char Far lExtraFieldType
[] = "\n\
417 There %s a local extra field with ID 0x%04x (%s) and\n\
418 %u data bytes (%s).\n";
419 static ZCONST
char Far efIZuid
[] =
420 "GMT modification/access times and Unix UID/GID";
421 static ZCONST
char Far efIZnouid
[] = "GMT modification/access times only";
424 static ZCONST
char Far NoFileComment
[] = "\n There is no file comment.\n";
425 static ZCONST
char Far FileCommBegin
[] = "\n\
426 ------------------------- file comment begins ----------------------------\n";
427 static ZCONST
char Far FileCommEnd
[] = "\
428 -------------------------- file comment ends -----------------------------\n";
430 /* zi_time() strings */
431 static ZCONST
char Far BogusFmt
[] = "%03d";
432 static ZCONST
char Far shtYMDHMTime
[] = "%02u-%s-%02u %02u:%02u";
433 static ZCONST
char Far lngYMDHMSTime
[] = "%u %s %u %02u:%02u:%02u";
434 static ZCONST
char Far DecimalTime
[] = "%04u%02u%02u.%02u%02u%02u";
435 #ifdef USE_EF_UT_TIME
436 static ZCONST
char Far lngYMDHMSTimeError
[] = "???? ??? ?? ??:??:??";
445 /************************/
446 /* Function zi_opts() */
447 /************************/
449 int zi_opts(__G__ pargc
, pargv
)
455 int argc
, c
, error
=FALSE
, negative
=0;
456 int hflag_slmv
=TRUE
, hflag_2
=FALSE
; /* diff options => diff defaults */
457 int tflag_slm
=TRUE
, tflag_2v
=FALSE
;
458 int explicit_h
=FALSE
, explicit_t
=FALSE
;
462 uO
.lflag
= LFLAG
; /* reset default on each call */
464 G
.extract_flag
= FALSE
; /* zipinfo does not extract to disk */
468 while (--argc
> 0 && (*++argv
)[0] == '-') {
470 while ((c
= *s
++) != 0) { /* "!= 0": prevent Turbo C warning */
475 case '1': /* shortest listing: JUST filenames */
477 uO
.lflag
= -2, negative
= 0;
481 case '2': /* just filenames, plus headers if specified */
483 uO
.lflag
= -2, negative
= 0;
488 case ('C'): /* -C: match filenames case-insensitively */
490 uO
.C_flag
= FALSE
, negative
= 0;
494 #endif /* !CMS_MVS */
495 case 'h': /* header line */
497 hflag_2
= hflag_slmv
= FALSE
, negative
= 0;
499 hflag_2
= hflag_slmv
= explicit_h
= TRUE
;
504 case 'l': /* longer form of "ls -l" type listing */
506 uO
.lflag
= -2, negative
= 0;
510 case 'm': /* medium form of "ls -l" type listing */
512 uO
.lflag
= -2, negative
= 0;
517 case 'M': /* send output through built-in "more" */
519 G
.M_flag
= FALSE
, negative
= 0;
524 case 's': /* default: shorter "ls -l" type listing */
526 uO
.lflag
= -2, negative
= 0;
530 case 't': /* totals line */
532 tflag_2v
= tflag_slm
= FALSE
, negative
= 0;
534 tflag_2v
= tflag_slm
= explicit_t
= TRUE
;
539 case ('T'): /* use (sortable) decimal time format */
541 uO
.T_flag
= FALSE
, negative
= 0;
545 #ifdef UNICODE_SUPPORT
546 case ('U'): /* escape UTF-8, or disable UTF-8 support */
548 uO
.U_flag
= MAX(uO
.U_flag
-negative
,0);
553 #endif /* UNICODE_SUPPORT */
554 case 'v': /* turbo-verbose listing */
556 uO
.lflag
= -2, negative
= 0;
560 #ifdef WILD_STOP_AT_DIR
561 case ('W'): /* Wildcard interpretation (stop at '/'?) */
563 uO
.W_flag
= FALSE
, negative
= 0;
567 #endif /* WILD_STOP_AT_DIR */
568 case 'z': /* print zipfile comment */
570 uO
.zflag
= negative
= 0;
574 case 'Z': /* ZipInfo mode: ignore */
582 if ((argc
-- == 0) || error
) {
589 if (G
.M_flag
&& !isatty(1)) /* stdout redirected: "more" func useless */
593 /* if no listing options given (or all negated), or if only -h/-t given
594 * with individual files specified, use default listing format */
595 if ((uO
.lflag
< 0) || ((argc
> 0) && (uO
.lflag
== 0)))
598 /* set header and totals flags to default or specified values */
600 case 0: /* 0: can only occur if either -t or -h explicitly given; */
601 case 2: /* therefore set both flags equal to normally false value */
605 case 1: /* only filenames, *always* */
613 uO
.hflag
= ((argc
> 0) && !explicit_h
)? FALSE
: hflag_slmv
;
614 uO
.tflag
= ((argc
> 0) && !explicit_t
)? FALSE
: tflag_slm
;
617 uO
.hflag
= hflag_slmv
;
626 } /* end function zi_opts() */
634 /*******************************/
635 /* Function zi_end_central() */
636 /*******************************/
638 void zi_end_central(__G
)
641 /*---------------------------------------------------------------------------
642 Print out various interesting things about the zipfile.
643 ---------------------------------------------------------------------------*/
647 Info(slide
, 0, ((char *)slide
, LoadFarString(EndCentDirRec
)));
648 Info(slide
, 0, ((char *)slide
, LoadFarString(LineSeparators
)));
650 Info(slide
, 0, ((char *)slide
, LoadFarString(ZipFSizeVerbose
),
651 FmZofft(G
.ziplen
, "11", NULL
),
652 FmZofft(G
.ziplen
, FZOFFT_HEX_DOT_WID
, "X")));
653 Info(slide
, 0, ((char *)slide
, LoadFarString(ActOffsetCentDir
),
654 FmZofft(G
.real_ecrec_offset
, "11", "u"),
655 FmZofft(G
.real_ecrec_offset
, FZOFFT_HEX_DOT_WID
, "X"),
656 FmZofft(G
.expect_ecrec_offset
, "11", "u"),
657 FmZofft(G
.expect_ecrec_offset
, FZOFFT_HEX_DOT_WID
, "X")));
659 if (G
.ecrec
.number_this_disk
== 0) {
660 Info(slide
, 0, ((char *)slide
, LoadFarString(SinglePartArchive1
),
661 FmZofft(G
.ecrec
.total_entries_central_dir
, NULL
, "u"),
662 (G
.ecrec
.total_entries_central_dir
== 1)? "entry" : "entries",
663 FmZofft(G
.ecrec
.size_central_directory
, NULL
, "u"),
664 FmZofft(G
.ecrec
.size_central_directory
,
665 FZOFFT_HEX_DOT_WID
, "X")));
666 Info(slide
, 0, ((char *)slide
, LoadFarString(SinglePartArchive2
),
667 FmZofft(G
.ecrec
.offset_start_central_directory
, NULL
, "u"),
668 FmZofft(G
.ecrec
.offset_start_central_directory
,
669 FZOFFT_HEX_DOT_WID
, "X")));
671 Info(slide
, 0, ((char *)slide
, LoadFarString(MultiPartArchive1
),
672 (ulg
)(G
.ecrec
.number_this_disk
+ 1),
673 (ulg
)(G
.ecrec
.num_disk_start_cdir
+ 1)));
674 Info(slide
, 0, ((char *)slide
, LoadFarString(MultiPartArchive2
),
675 FmZofft(G
.ecrec
.offset_start_central_directory
, NULL
, "u"),
676 FmZofft(G
.ecrec
.offset_start_central_directory
,
677 FZOFFT_HEX_DOT_WID
, "X"),
678 FmZofft(G
.ecrec
.size_central_directory
, NULL
, "u"),
679 FmZofft(G
.ecrec
.size_central_directory
,
680 FZOFFT_HEX_DOT_WID
, "X")));
681 Info(slide
, 0, ((char *)slide
, LoadFarString(MultiPartArchive3
),
682 FmZofft(G
.ecrec
.num_entries_centrl_dir_ths_disk
, NULL
, "u"),
683 (G
.ecrec
.num_entries_centrl_dir_ths_disk
== 1)? "is" : "are",
684 FmZofft(G
.ecrec
.total_entries_central_dir
, NULL
, "u"),
685 (G
.ecrec
.total_entries_central_dir
== 1) ? "entry" : "entries"));
689 /* print zip file size and number of contained entries: */
690 Info(slide
, 0, ((char *)slide
, LoadFarString(ZipInfHeader2
),
691 FmZofft(G
.ziplen
, NULL
, NULL
),
692 FmZofft(G
.ecrec
.total_entries_central_dir
, NULL
, "u")));
695 } /* end function zi_end_central() */
701 /************************/
702 /* Function zipinfo() */
703 /************************/
705 int zipinfo(__G
) /* return PK-type error code */
708 int do_this_file
=FALSE
, error
, error_in_archive
=PK_COOL
;
709 int *fn_matched
=NULL
, *xn_matched
=NULL
;
711 zusz_t tot_csize
=0L, tot_ucsize
=0L;
712 zusz_t endprev
; /* buffers end of previous entry for zi_long()'s check
716 /*---------------------------------------------------------------------------
717 Malloc space for check on unmatched filespecs (no big deal if one or both
719 ---------------------------------------------------------------------------*/
721 if (G
.filespecs
> 0 &&
722 (fn_matched
=(int *)malloc(G
.filespecs
*sizeof(int))) != NULL
)
723 for (j
= 0; j
< G
.filespecs
; ++j
)
724 fn_matched
[j
] = FALSE
;
726 if (G
.xfilespecs
> 0 &&
727 (xn_matched
=(int *)malloc(G
.xfilespecs
*sizeof(int))) != NULL
)
728 for (j
= 0; j
< G
.xfilespecs
; ++j
)
729 xn_matched
[j
] = FALSE
;
731 /*---------------------------------------------------------------------------
732 Set file pointer to start of central directory, then loop through cen-
733 tral directory entries. Check that directory-entry signature bytes are
734 actually there (just a precaution), then process the entry. We know
735 the entire central directory is on this disk: we wouldn't have any of
736 this information unless the end-of-central-directory record was on this
737 disk, and we wouldn't have gotten to this routine unless this is also
738 the disk on which the central directory starts. In practice, this had
739 better be the *only* disk in the archive, but maybe someday we'll add
741 ---------------------------------------------------------------------------*/
743 uO
.L_flag
= FALSE
; /* zipinfo mode: never convert name to lowercase */
744 G
.pInfo
= G
.info
; /* (re-)initialize, (just to make sure) */
745 G
.pInfo
->textmode
= 0; /* so one can read on screen (is this ever used?) */
747 /* reset endprev for new zipfile; account for multi-part archives (?) */
748 endprev
= (G
.crec
.relative_offset_local_header
== 4L)? 4L : 0L;
752 if (readbuf(__G__ G
.sig
, 4) == 0) {
753 error_in_archive
= PK_EOF
;
756 if (memcmp(G
.sig
, central_hdr_sig
, 4)) { /* is it a CentDir entry? */
757 /* no new central directory entry
758 * -> is the number of processed entries compatible with the
759 * number of entries as stored in the end_central record?
762 (ulg
)(G
.ecrec
.have_ecr64
? MASK_ZUCN64
: MASK_ZUCN16
))
763 == (ulg
)G
.ecrec
.total_entries_central_dir
)
765 /* "j modulus 4T/64k" matches the reported 64/16-bit-unsigned
766 * number of directory entries -> probably, the regular
767 * end of the central directory has been reached
772 ((char *)slide
, LoadFarString(CentSigMsg
), j
));
774 ((char *)slide
, LoadFarString(ReportMsg
)));
775 error_in_archive
= PK_BADERR
; /* sig not found */
779 /* process_cdir_file_hdr() sets pInfo->hostnum, pInfo->lcflag, ...: */
780 if ((error
= process_cdir_file_hdr(__G
)) != PK_COOL
) {
781 error_in_archive
= error
; /* only PK_EOF defined */
785 if ((error
= do_string(__G__ G
.crec
.filename_length
, DS_FN
)) !=
788 if (error
> error_in_archive
)
789 error_in_archive
= error
;
790 if (error
> PK_WARN
) /* fatal */
794 if (!G
.process_all_files
) { /* check if specified on command line */
797 if (G
.filespecs
== 0)
799 else { /* check if this entry matches an `include' argument */
800 do_this_file
= FALSE
;
801 for (i
= 0; i
< G
.filespecs
; i
++)
802 if (match(G
.filename
, G
.pfnames
[i
], uO
.C_flag WISEP
)) {
805 fn_matched
[i
] = TRUE
;
806 break; /* found match, so stop looping */
809 if (do_this_file
) { /* check if this is an excluded file */
810 for (i
= 0; i
< G
.xfilespecs
; i
++)
811 if (match(G
.filename
, G
.pxnames
[i
], uO
.C_flag WISEP
)) {
812 do_this_file
= FALSE
; /* ^-- ignore case in match */
814 xn_matched
[i
] = TRUE
;
820 /*-----------------------------------------------------------------------
821 If current file was specified on command line, or if no names were
822 specified, do the listing for this file. Otherwise, get rid of the
823 file comment and go back for the next file.
824 -----------------------------------------------------------------------*/
826 if (G
.process_all_files
|| do_this_file
) {
828 /* Read the extra field, if any. The extra field info is required
829 * for resolving the Zip64 sizes/offsets and may be used in more
830 * analysis of the entry below.
832 if ((error
= do_string(__G__ G
.crec
.extra_field_length
,
835 if (G
.extra_field
!= NULL
) {
837 G
.extra_field
= NULL
;
839 error_in_archive
= error
;
840 /* The premature return in case of a "fatal" error (PK_EOF) is
841 * delayed until we analyze the extra field contents.
842 * This allows us to display all the other info that has been
843 * successfully read in.
851 SKIP_(G
.crec
.file_comment_length
)
857 if ((error
= zi_short(__G
)) != PK_COOL
) {
858 error_in_archive
= error
; /* might be warning */
863 Info(slide
, 0, ((char *)slide
,
864 LoadFarString(CentralDirEntry
), j
));
865 if ((error
= zi_long(__G__
&endprev
,
866 error_in_archive
)) != PK_COOL
) {
867 error_in_archive
= error
; /* might be warning */
872 SKIP_(G
.crec
.file_comment_length
)
875 } /* end switch (lflag) */
876 if (error
> PK_WARN
) /* fatal */
879 tot_csize
+= G
.crec
.csize
;
880 tot_ucsize
+= G
.crec
.ucsize
;
881 if (G
.crec
.general_purpose_bit_flag
& 1)
882 tot_csize
-= 12; /* don't count encryption header */
886 if ((G
.statreportcb
!= NULL
) &&
887 (*G
.statreportcb
)(__G__ UZ_ST_FINISH_MEMBER
, G
.zipfn
,
888 G
.filename
, (zvoid
*)&G
.crec
.ucsize
)) {
889 /* cancel operation by user request */
890 error_in_archive
= IZ_CTRLC
;
894 #ifdef MACOS /* MacOS is no preemptive OS, thus call event-handling by hand */
898 } else { /* not listing this file */
899 SKIP_(G
.crec
.extra_field_length
)
900 SKIP_(G
.crec
.file_comment_length
)
901 if (endprev
!= 0) endprev
= 0;
903 } /* end if (list member?) */
905 } /* end for-loop (j: member files) */
907 /*---------------------------------------------------------------------------
908 Check that we actually found requested files; if so, print totals.
909 ---------------------------------------------------------------------------*/
911 if ((error_in_archive
<= PK_WARN
) && uO
.tflag
) {
913 int cfactor
= ratio(tot_ucsize
, tot_csize
);
919 Info(slide
, 0, ((char *)slide
, LoadFarString(ZipfileStats
),
920 members
, (members
==1L)? nullStr
:PlurSufx
,
921 FmZofft(tot_ucsize
, NULL
, "u"),
922 FmZofft(tot_csize
, NULL
, "u"),
923 sgn
, cfactor
/10, cfactor
%10));
926 /*---------------------------------------------------------------------------
927 Check for unmatched filespecs on command line and print warning if any
929 ---------------------------------------------------------------------------*/
932 if (error_in_archive
<= PK_WARN
)
933 for (j
= 0; j
< G
.filespecs
; ++j
)
935 Info(slide
, 0x401, ((char *)slide
,
936 LoadFarString(FilenameNotMatched
), G
.pfnames
[j
]));
937 free((zvoid
*)fn_matched
);
940 if (error_in_archive
<= PK_WARN
)
941 for (j
= 0; j
< G
.xfilespecs
; ++j
)
943 Info(slide
, 0x401, ((char *)slide
,
944 LoadFarString(ExclFilenameNotMatched
), G
.pxnames
[j
]));
945 free((zvoid
*)xn_matched
);
949 /* Skip the following checks in case of a premature listing break. */
950 if (error_in_archive
<= PK_WARN
) {
952 /*---------------------------------------------------------------------------
953 Double check that we're back at the end-of-central-directory record.
954 ---------------------------------------------------------------------------*/
957 (G
.ecrec
.have_ecr64
?
958 end_central64_sig
: end_central_sig
),
960 && (!G
.ecrec
.is_zip64_archive
)
961 && (memcmp(G
.sig
, end_central_sig
, 4) != 0)
962 ) { /* just to make sure again */
963 Info(slide
, 0x401, ((char *)slide
, LoadFarString(EndSigMsg
)));
964 error_in_archive
= PK_WARN
; /* didn't find sig */
967 /* Set specific return code when no files have been found. */
968 if (members
== 0L && error_in_archive
<= PK_WARN
)
969 error_in_archive
= PK_FIND
;
972 (*G
.message
)((zvoid
*)&G
, (uch
*)"\n", 1L, 0);
975 return error_in_archive
;
977 } /* end function zipinfo() */
983 /************************/
984 /* Function zi_long() */
985 /************************/
987 static int zi_long(__G__ pEndprev
, error_in_archive
)
988 /* return PK-type error code */
990 zusz_t
*pEndprev
; /* for zi_long() check of extra bytes */
991 int error_in_archive
; /* may signal premature return */
993 #ifdef USE_EF_UT_TIME
997 unsigned hostnum
, hostver
, extnum
, extver
, methid
, methnum
, xattr
;
998 char workspace
[12], attribs
[22];
999 ZCONST
char *varmsg_str
;
1001 static ZCONST
char Far
*os
[NUM_HOSTS
] = {
1002 OS_FAT
, OS_Amiga
, OS_VMS
, OS_Unix
, OS_VMCMS
, OS_AtariST
, OS_HPFS
,
1003 OS_Macintosh
, OS_ZSystem
, OS_CPM
, OS_TOPS20
, OS_NTFS
, OS_QDOS
,
1004 OS_Acorn
, OS_VFAT
, OS_MVS
, OS_BeOS
, OS_Tandem
, OS_Theos
, OS_MacDarwin
,
1005 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
1008 static ZCONST
char Far
*method
[NUM_METHODS
] = {
1009 MthdNone
, MthdShrunk
, MthdRedF1
, MthdRedF2
, MthdRedF3
, MthdRedF4
,
1010 MthdImplode
, MthdToken
, MthdDeflate
, MthdDeflat64
, MthdDCLImplode
,
1011 MthdBZip2
, MthdLZMA
, MthdTerse
, MthdLZ77
, MthdWavPack
, MthdPPMd
1013 static ZCONST
char Far
*dtypelng
[4] = {
1014 DeflNorm
, DeflMax
, DeflFast
, DeflSFast
1018 /*---------------------------------------------------------------------------
1019 Check whether there's any extra space inside the zipfile. If *pEndprev is
1020 zero, it's probably a signal that OS/2 extra fields are involved (with
1021 unknown compressed size). We won't worry about prepended junk here...
1022 ---------------------------------------------------------------------------*/
1024 if (G
.crec
.relative_offset_local_header
!= *pEndprev
&& *pEndprev
> 0L) {
1026 Info(slide, 0, ((char *)slide,
1027 " [crec.relative_offset_local_header = %lu, endprev = %lu]\n",
1028 G.crec.relative_offset_local_header, *pEndprev));
1030 Info(slide
, 0, ((char *)slide
, LoadFarString(ExtraBytesPreceding
),
1031 FmZofft((G
.crec
.relative_offset_local_header
- (*pEndprev
)),
1035 /* calculate endprev for next time around (problem: extra fields may
1036 * differ in length between local and central-directory records) */
1037 *pEndprev
= G
.crec
.relative_offset_local_header
+ (4L + LREC_SIZE
) +
1038 G
.crec
.filename_length
+ G
.crec
.extra_field_length
+ G
.crec
.csize
;
1040 /*---------------------------------------------------------------------------
1041 Print out various interesting things about the compressed file.
1042 ---------------------------------------------------------------------------*/
1044 hostnum
= (unsigned)(G
.pInfo
->hostnum
);
1045 hostver
= (unsigned)(G
.pInfo
->hostver
);
1046 extnum
= (unsigned)MIN(G
.crec
.version_needed_to_extract
[1], NUM_HOSTS
);
1047 extver
= (unsigned)G
.crec
.version_needed_to_extract
[0];
1048 methid
= (unsigned)G
.crec
.compression_method
;
1049 methnum
= find_compr_idx(G
.crec
.compression_method
);
1051 (*G
.message
)((zvoid
*)&G
, (uch
*)" ", 2L, 0); fnprint(__G
);
1053 Info(slide
, 0, ((char *)slide
, LoadFarString(LocalHeaderOffset
),
1054 FmZofft(G
.crec
.relative_offset_local_header
, NULL
, "u"),
1055 FmZofft(G
.crec
.relative_offset_local_header
, FZOFFT_HEX_DOT_WID
, "X")));
1057 if (hostnum
>= NUM_HOSTS
) {
1058 sprintf(unkn
, LoadFarString(UnknownNo
),
1059 (int)G
.crec
.version_made_by
[1]);
1062 varmsg_str
= LoadFarStringSmall(os
[hostnum
]);
1063 #ifdef OLD_THEOS_EXTRA
1064 if (hostnum
== FS_VFAT_
&& hostver
== 20) {
1065 /* entry made by old non-official THEOS port zip archive */
1066 varmsg_str
= LoadFarStringSmall(OS_TheosOld
);
1068 #endif /* OLD_THEOS_EXTRA */
1070 Info(slide
, 0, ((char *)slide
, LoadFarString(HostOS
), varmsg_str
));
1071 Info(slide
, 0, ((char *)slide
, LoadFarString(EncodeSWVer
), hostver
/10,
1074 if ((extnum
>= NUM_HOSTS
) || (os
[extnum
] == NULL
)) {
1075 sprintf(unkn
, LoadFarString(UnknownNo
),
1076 (int)G
.crec
.version_needed_to_extract
[1]);
1079 varmsg_str
= LoadFarStringSmall(os
[extnum
]);
1081 Info(slide
, 0, ((char *)slide
, LoadFarString(MinOSCompReq
), varmsg_str
));
1082 Info(slide
, 0, ((char *)slide
, LoadFarString(MinSWVerReq
), extver
/10,
1085 if (methnum
>= NUM_METHODS
) {
1086 sprintf(unkn
, LoadFarString(UnknownNo
), G
.crec
.compression_method
);
1089 varmsg_str
= LoadFarStringSmall(method
[methnum
]);
1091 Info(slide
, 0, ((char *)slide
, LoadFarString(CompressMethod
), varmsg_str
));
1092 if (methid
== IMPLODED
) {
1093 Info(slide
, 0, ((char *)slide
, LoadFarString(SlideWindowSizeImplode
),
1094 (G
.crec
.general_purpose_bit_flag
& 2)? '8' : '4'));
1095 Info(slide
, 0, ((char *)slide
, LoadFarString(ShannonFanoTrees
),
1096 (G
.crec
.general_purpose_bit_flag
& 4)? '3' : '2'));
1097 } else if (methid
== DEFLATED
|| methid
== ENHDEFLATED
) {
1098 ush dnum
=(ush
)((G
.crec
.general_purpose_bit_flag
>>1) & 3);
1100 Info(slide
, 0, ((char *)slide
, LoadFarString(CompressSubtype
),
1101 LoadFarStringSmall(dtypelng
[dnum
])));
1104 Info(slide
, 0, ((char *)slide
, LoadFarString(FileSecurity
),
1105 (G
.crec
.general_purpose_bit_flag
& 1) ? nullStr
: "not "));
1106 Info(slide
, 0, ((char *)slide
, LoadFarString(ExtendedLocalHdr
),
1107 (G
.crec
.general_purpose_bit_flag
& 8) ? "yes" : "no"));
1108 /* print upper 3 bits for amusement? */
1110 /* For printing of date & time, a "char d_t_buf[21]" is required.
1111 * To save stack space, we reuse the "char attribs[22]" buffer which
1114 # define d_t_buf attribs
1116 zi_time(__G__
&G
.crec
.last_mod_dos_datetime
, NULL
, d_t_buf
);
1117 Info(slide
, 0, ((char *)slide
, LoadFarString(FileModDate
), d_t_buf
));
1118 #ifdef USE_EF_UT_TIME
1119 if (G
.extra_field
&&
1123 (ef_scan_for_izux(G
.extra_field
, G
.crec
.extra_field_length
, 1,
1124 G
.crec
.last_mod_dos_datetime
, &z_utime
, NULL
)
1127 TIMET_TO_NATIVE(z_utime
.mtime
) /* NOP unless MSC 7.0 or Macintosh */
1128 d_t_buf
[0] = (char)0; /* signal "show local time" */
1129 zi_time(__G__
&G
.crec
.last_mod_dos_datetime
, &(z_utime
.mtime
), d_t_buf
);
1130 Info(slide
, 0, ((char *)slide
, LoadFarString(UT_FileModDate
),
1131 d_t_buf
, LoadFarStringSmall(LocalTime
)));
1133 d_t_buf
[0] = (char)1; /* signal "show UTC (GMT) time" */
1134 zi_time(__G__
&G
.crec
.last_mod_dos_datetime
, &(z_utime
.mtime
), d_t_buf
);
1135 Info(slide
, 0, ((char *)slide
, LoadFarString(UT_FileModDate
),
1136 d_t_buf
, LoadFarStringSmall(GMTime
)));
1137 #endif /* !NO_GMTIME */
1139 #endif /* USE_EF_UT_TIME */
1141 Info(slide
, 0, ((char *)slide
, LoadFarString(CRC32Value
), G
.crec
.crc32
));
1142 Info(slide
, 0, ((char *)slide
, LoadFarString(CompressedFileSize
),
1143 FmZofft(G
.crec
.csize
, NULL
, "u")));
1144 Info(slide
, 0, ((char *)slide
, LoadFarString(UncompressedFileSize
),
1145 FmZofft(G
.crec
.ucsize
, NULL
, "u")));
1146 Info(slide
, 0, ((char *)slide
, LoadFarString(FilenameLength
),
1147 G
.crec
.filename_length
));
1148 Info(slide
, 0, ((char *)slide
, LoadFarString(ExtraFieldLength
),
1149 G
.crec
.extra_field_length
));
1150 Info(slide
, 0, ((char *)slide
, LoadFarString(FileCommentLength
),
1151 G
.crec
.file_comment_length
));
1152 Info(slide
, 0, ((char *)slide
, LoadFarString(FileDiskNum
),
1153 (ulg
)(G
.crec
.disk_number_start
+ 1)));
1154 Info(slide
, 0, ((char *)slide
, LoadFarString(ApparentFileType
),
1155 (G
.crec
.internal_file_attributes
& 1)? "text"
1156 : (G
.crec
.internal_file_attributes
& 2)? "ebcdic"
1157 : "binary")); /* changed to accept EBCDIC */
1159 printf(" external file attributes (hex): %.8lx\n",
1160 G
.crec
.external_file_attributes
);
1162 xattr
= (unsigned)((G
.crec
.external_file_attributes
>> 16) & 0xFFFF);
1163 if (hostnum
== VMS_
) {
1164 char *p
=attribs
, *q
=attribs
+1;
1167 for (k
= 0; k
< 12; ++k
)
1169 if (xattr
& VMS_IRUSR
)
1171 if (xattr
& VMS_IWUSR
) {
1175 if (xattr
& VMS_IXUSR
)
1177 if (xattr
& VMS_IRGRP
)
1179 if (xattr
& VMS_IWGRP
) {
1183 if (xattr
& VMS_IXGRP
)
1185 if (xattr
& VMS_IROTH
)
1187 if (xattr
& VMS_IWOTH
) {
1189 workspace
[11] = 'D';
1191 if (xattr
& VMS_IXOTH
)
1192 workspace
[10] = 'E';
1195 for (k
= j
= 0; j
< 3; ++j
) { /* loop over groups of permissions */
1196 for (i
= 0; i
< 4; ++i
, ++k
) /* loop over perms within a group */
1198 *p
++ = workspace
[k
];
1199 *p
++ = ','; /* group separator */
1201 while ((*p
++ = *q
++) != ',')
1202 ; /* system, owner perms are same */
1205 *p
= ')'; /* overwrite last comma */
1206 Info(slide
, 0, ((char *)slide
, LoadFarString(VMSFileAttributes
), xattr
,
1209 } else if (hostnum
== AMIGA_
) {
1210 switch (xattr
& AMI_IFMT
) {
1211 case AMI_IFDIR
: attribs
[0] = 'd'; break;
1212 case AMI_IFREG
: attribs
[0] = '-'; break;
1213 default: attribs
[0] = '?'; break;
1215 attribs
[1] = (xattr
& AMI_IHIDDEN
)? 'h' : '-';
1216 attribs
[2] = (xattr
& AMI_ISCRIPT
)? 's' : '-';
1217 attribs
[3] = (xattr
& AMI_IPURE
)? 'p' : '-';
1218 attribs
[4] = (xattr
& AMI_IARCHIVE
)? 'a' : '-';
1219 attribs
[5] = (xattr
& AMI_IREAD
)? 'r' : '-';
1220 attribs
[6] = (xattr
& AMI_IWRITE
)? 'w' : '-';
1221 attribs
[7] = (xattr
& AMI_IEXECUTE
)? 'e' : '-';
1222 attribs
[8] = (xattr
& AMI_IDELETE
)? 'd' : '-';
1223 attribs
[9] = 0; /* better dlm the string */
1224 Info(slide
, 0, ((char *)slide
, LoadFarString(AmigaFileAttributes
),
1227 } else if (hostnum
== THEOS_
) {
1228 ZCONST
char Far
*fpFtyp
;
1230 switch (xattr
& THS_IFMT
) {
1231 case THS_IFLIB
: fpFtyp
= TheosFTypLib
; break;
1232 case THS_IFDIR
: fpFtyp
= TheosFTypDir
; break;
1233 case THS_IFREG
: fpFtyp
= TheosFTypReg
; break;
1234 case THS_IFREL
: fpFtyp
= TheosFTypRel
; break;
1235 case THS_IFKEY
: fpFtyp
= TheosFTypKey
; break;
1236 case THS_IFIND
: fpFtyp
= TheosFTypInd
; break;
1237 case THS_IFR16
: fpFtyp
= TheosFTypR16
; break;
1238 case THS_IFP16
: fpFtyp
= TheosFTypP16
; break;
1239 case THS_IFP32
: fpFtyp
= TheosFTypP32
; break;
1240 default: fpFtyp
= TheosFTypUkn
; break;
1242 strcpy(attribs
, LoadFarStringSmall(fpFtyp
));
1243 attribs
[12] = (xattr
& THS_INHID
) ? '.' : 'H';
1244 attribs
[13] = (xattr
& THS_IMODF
) ? '.' : 'M';
1245 attribs
[14] = (xattr
& THS_IWOTH
) ? '.' : 'W';
1246 attribs
[15] = (xattr
& THS_IROTH
) ? '.' : 'R';
1247 attribs
[16] = (xattr
& THS_IEUSR
) ? '.' : 'E';
1248 attribs
[17] = (xattr
& THS_IXUSR
) ? '.' : 'X';
1249 attribs
[18] = (xattr
& THS_IWUSR
) ? '.' : 'W';
1250 attribs
[19] = (xattr
& THS_IRUSR
) ? '.' : 'R';
1252 Info(slide
, 0, ((char *)slide
, LoadFarString(TheosFileAttributes
),
1255 #ifdef OLD_THEOS_EXTRA
1256 } else if (hostnum
== FS_VFAT_
&& hostver
== 20) {
1257 /* process old non-official THEOS port zip archive */
1258 ZCONST
char Far
*fpFtyp
;
1260 switch (xattr
& _THS_IFMT
) {
1261 case _THS_IFLIB
: fpFtyp
= TheosFTypLib
; break;
1262 case _THS_IFDIR
: fpFtyp
= TheosFTypDir
; break;
1263 case _THS_IFREG
: fpFtyp
= TheosFTypReg
; break;
1264 case _THS_IODRC
: fpFtyp
= TheosFTypRel
; break;
1265 case _THS_IOKEY
: fpFtyp
= TheosFTypKey
; break;
1266 case _THS_IOIND
: fpFtyp
= TheosFTypInd
; break;
1267 case _THS_IOPRG
: fpFtyp
= TheosFTypR16
; break;
1268 case _THS_IO286
: fpFtyp
= TheosFTypP16
; break;
1269 case _THS_IO386
: fpFtyp
= TheosFTypP32
; break;
1270 default: fpFtyp
= TheosFTypUkn
; break;
1272 strcpy(attribs
, LoadFarStringSmall(fpFtyp
));
1273 attribs
[12] = (xattr
& _THS_HIDDN
) ? 'H' : '.';
1274 attribs
[13] = (xattr
& _THS_IXOTH
) ? '.' : 'X';
1275 attribs
[14] = (xattr
& _THS_IWOTH
) ? '.' : 'W';
1276 attribs
[15] = (xattr
& _THS_IROTH
) ? '.' : 'R';
1277 attribs
[16] = (xattr
& _THS_IEUSR
) ? '.' : 'E';
1278 attribs
[17] = (xattr
& _THS_IXUSR
) ? '.' : 'X';
1279 attribs
[18] = (xattr
& _THS_IWUSR
) ? '.' : 'W';
1280 attribs
[19] = (xattr
& _THS_IRUSR
) ? '.' : 'R';
1282 Info(slide
, 0, ((char *)slide
, LoadFarString(TheosFileAttributes
),
1284 #endif /* OLD_THEOS_EXTRA */
1286 } else if ((hostnum
!= FS_FAT_
) && (hostnum
!= FS_HPFS_
) &&
1287 (hostnum
!= FS_NTFS_
) && (hostnum
!= FS_VFAT_
) &&
1288 (hostnum
!= ACORN_
) &&
1289 (hostnum
!= VM_CMS_
) && (hostnum
!= MVS_
))
1290 { /* assume Unix-like */
1291 switch ((unsigned)(xattr
& UNX_IFMT
)) {
1292 case (unsigned)UNX_IFDIR
: attribs
[0] = 'd'; break;
1293 case (unsigned)UNX_IFREG
: attribs
[0] = '-'; break;
1294 case (unsigned)UNX_IFLNK
: attribs
[0] = 'l'; break;
1295 case (unsigned)UNX_IFBLK
: attribs
[0] = 'b'; break;
1296 case (unsigned)UNX_IFCHR
: attribs
[0] = 'c'; break;
1297 case (unsigned)UNX_IFIFO
: attribs
[0] = 'p'; break;
1298 case (unsigned)UNX_IFSOCK
: attribs
[0] = 's'; break;
1299 default: attribs
[0] = '?'; break;
1301 attribs
[1] = (xattr
& UNX_IRUSR
)? 'r' : '-';
1302 attribs
[4] = (xattr
& UNX_IRGRP
)? 'r' : '-';
1303 attribs
[7] = (xattr
& UNX_IROTH
)? 'r' : '-';
1305 attribs
[2] = (xattr
& UNX_IWUSR
)? 'w' : '-';
1306 attribs
[5] = (xattr
& UNX_IWGRP
)? 'w' : '-';
1307 attribs
[8] = (xattr
& UNX_IWOTH
)? 'w' : '-';
1309 if (xattr
& UNX_IXUSR
)
1310 attribs
[3] = (xattr
& UNX_ISUID
)? 's' : 'x';
1312 attribs
[3] = (xattr
& UNX_ISUID
)? 'S' : '-'; /* S = undefined */
1313 if (xattr
& UNX_IXGRP
)
1314 attribs
[6] = (xattr
& UNX_ISGID
)? 's' : 'x'; /* == UNX_ENFMT */
1316 attribs
[6] = (xattr
& UNX_ISGID
)? 'l' : '-';
1317 if (xattr
& UNX_IXOTH
)
1318 attribs
[9] = (xattr
& UNX_ISVTX
)? 't' : 'x'; /* "sticky bit" */
1320 attribs
[9] = (xattr
& UNX_ISVTX
)? 'T' : '-'; /* T = undefined */
1323 Info(slide
, 0, ((char *)slide
, LoadFarString(UnixFileAttributes
), xattr
,
1327 Info(slide
, 0, ((char *)slide
, LoadFarString(NonMSDOSFileAttributes
),
1328 G
.crec
.external_file_attributes
>> 8));
1330 } /* endif (hostnum: external attributes format) */
1332 if ((xattr
=(unsigned)(G
.crec
.external_file_attributes
& 0xFF)) == 0)
1333 Info(slide
, 0, ((char *)slide
, LoadFarString(MSDOSFileAttributes
),
1335 else if (xattr
== 1)
1336 Info(slide
, 0, ((char *)slide
, LoadFarString(MSDOSFileAttributesRO
),
1339 Info(slide
, 0, ((char *)slide
, LoadFarString(MSDOSFileAttributesAlpha
),
1340 xattr
, (xattr
&1)? "rdo " : nullStr
,
1341 (xattr
&2)? "hid " : nullStr
,
1342 (xattr
&4)? "sys " : nullStr
,
1343 (xattr
&8)? "lab " : nullStr
,
1344 (xattr
&16)? "dir " : nullStr
,
1345 (xattr
&32)? "arc " : nullStr
,
1346 (xattr
&64)? "lnk " : nullStr
,
1347 (xattr
&128)? "exe" : nullStr
));
1349 /*---------------------------------------------------------------------------
1350 Analyze the extra field, if any, and print the file comment, if any (the
1351 filename has already been printed, above). That finishes up this file
1353 ---------------------------------------------------------------------------*/
1355 if (G
.crec
.extra_field_length
> 0) {
1356 uch
*ef_ptr
= G
.extra_field
;
1357 ush ef_len
= G
.crec
.extra_field_length
;
1358 ush eb_id
, eb_datalen
;
1359 ZCONST
char Far
*ef_fieldname
;
1361 if (error_in_archive
> PK_WARN
) /* fatal: can't continue */
1362 /* delayed "fatal error" return from extra field reading */
1363 return error_in_archive
;
1364 if (G
.extra_field
== (uch
*)NULL
)
1365 return PK_ERR
; /* not consistent with crec length */
1367 Info(slide
, 0, ((char *)slide
, LoadFarString(ExtraFields
)));
1369 while (ef_len
>= EB_HEADSIZE
) {
1370 eb_id
= makeword(&ef_ptr
[EB_ID
]);
1371 eb_datalen
= makeword(&ef_ptr
[EB_LEN
]);
1372 ef_ptr
+= EB_HEADSIZE
;
1373 ef_len
-= EB_HEADSIZE
;
1375 if (eb_datalen
> (ush
)ef_len
) {
1376 Info(slide
, 0x421, ((char *)slide
,
1377 LoadFarString(ExtraFieldTrunc
), eb_id
, eb_datalen
, ef_len
));
1378 eb_datalen
= ef_len
;
1383 ef_fieldname
= efPKSZ64
;
1384 if ((G
.crec
.relative_offset_local_header
1385 & (~(zusz_t
)0xFFFFFFFFL
)) != 0) {
1386 /* Subtract the size of the 64bit local offset from
1387 the local e.f. size, local Z64 e.f. block has no
1388 offset; when only local offset present, the entire
1389 local PKSZ64 block is missing. */
1390 *pEndprev
-= (eb_datalen
== 8 ? 12 : 8);
1394 ef_fieldname
= efAV
;
1397 ef_fieldname
= efOS2
;
1400 ef_fieldname
= efACL
;
1403 ef_fieldname
= efNTSD
;
1406 ef_fieldname
= efPKVMS
;
1409 ef_fieldname
= efIZVMS
;
1412 ef_fieldname
= efPKWin32
;
1415 ef_fieldname
= efPKUnix
;
1418 ef_fieldname
= efIZUnix
;
1419 if (hostnum
== UNIX_
&& *pEndprev
> 0L)
1420 *pEndprev
+= 4L; /* also have UID/GID in local copy */
1423 ef_fieldname
= efIZUnix2
;
1425 *pEndprev
+= 4L; /* 4 byte UID/GID in local copy */
1428 ef_fieldname
= efIZUnix3
;
1431 *pEndprev
+= 4L; /* 4 byte UID/GID in local copy */
1435 ef_fieldname
= efTime
;
1438 ef_fieldname
= efU8Path
;
1441 ef_fieldname
= efU8Commnt
;
1444 ef_fieldname
= efMac3
;
1447 ef_fieldname
= efJLMac
;
1450 ef_fieldname
= efZipIt
;
1453 ef_fieldname
= efZipIt2
;
1456 ef_fieldname
= efVMCMS
;
1459 ef_fieldname
= efMVS
;
1462 ef_fieldname
= efAtheOS
;
1465 ef_fieldname
= efBeOS
;
1468 ef_fieldname
= efQDOS
;
1471 ef_fieldname
= efAOSVS
;
1473 case EF_SPARK
: /* from RISC OS */
1474 ef_fieldname
= efSpark
;
1477 ef_fieldname
= efMD5
;
1480 ef_fieldname
= efASiUnix
;
1483 ef_fieldname
= efTandem
;
1486 ef_fieldname
= efSmartZip
;
1489 #ifdef OLD_THEOS_EXTRA
1492 ef_fieldname
= efTheos
;
1495 ef_fieldname
= efUnknown
;
1498 Info(slide
, 0, ((char *)slide
, LoadFarString(ExtraFieldType
),
1499 eb_id
, LoadFarStringSmall(ef_fieldname
), eb_datalen
));
1501 /* additional, field-specific information: */
1505 if (eb_datalen
>= EB_OS2_HLEN
) {
1506 if (eb_id
== EF_OS2
)
1507 ef_fieldname
= OS2EAs
;
1509 ef_fieldname
= ACLdata
;
1510 Info(slide
, 0, ((char *)slide
,
1511 LoadFarString(ef_fieldname
), makelong(ef_ptr
)));
1512 *pEndprev
= 0L; /* no clue about csize of local */
1514 goto ef_default_display
;
1518 if (eb_datalen
>= EB_NTSD_C_LEN
) {
1519 Info(slide
, 0, ((char *)slide
, LoadFarString(NTSDData
),
1521 *pEndprev
= 0L; /* no clue about csize of local */
1523 goto ef_default_display
;
1527 if (eb_datalen
>= 8) {
1529 unsigned compr
= makeword(ef_ptr
+EB_IZVMS_FLGS
)
1535 switch (makelong(ef_ptr
)) {
1536 case 0x42414656: /* "VFAB" */
1538 case 0x4C4C4156: /* "VALL" */
1539 p
= "XABALL"; break;
1540 case 0x43484656: /* "VFHC" */
1541 p
= "XABFHC"; break;
1542 case 0x54414456: /* "VDAT" */
1543 p
= "XABDAT"; break;
1544 case 0x54445256: /* "VRDT" */
1545 p
= "XABRDT"; break;
1546 case 0x4F525056: /* "VPRO" */
1547 p
= "XABPRO"; break;
1548 case 0x59454B56: /* "VKEY" */
1549 p
= "XABKEY"; break;
1550 case 0x56534D56: /* "VMSV" */
1552 if (eb_datalen
>= 16) {
1553 /* put termitation first, for A_TO_N() */
1558 (char *)ef_ptr
+EB_IZVMS_HLEN
, 4);
1566 Info(slide
, 0, ((char *)slide
,
1567 LoadFarString(izVMSdata
),
1568 LoadFarStringSmall(izVMScomp
[compr
]),
1569 makeword(ef_ptr
+EB_IZVMS_UCSIZ
), p
, q
));
1571 goto ef_default_display
;
1575 if (eb_datalen
> 0) {
1581 strcpy(types
, LoadFarString(UTmodification
));
1585 len
= strlen(types
);
1588 strcpy(types
+len
, LoadFarString(UTaccess
));
1594 len
= strlen(types
);
1597 strcpy(types
+len
, LoadFarString(UTcreation
));
1603 Info(slide
, 0, ((char *)slide
,
1604 LoadFarString(UTdata
), types
,
1605 num
== 1? nullStr
: PlurSufx
));
1610 if (eb_datalen
>= 5) {
1612 ulg name_crc
= makelong(ef_ptr
+1);
1614 if (eb_datalen
<= 29) {
1615 Info(slide
, 0, ((char *)slide
,
1616 LoadFarString(U8PthCmnComplete
),
1617 (unsigned)ef_ptr
[0], name_crc
));
1620 Info(slide
, 0, ((char *)slide
,
1621 LoadFarString(U8PthCmnF24
),
1622 (unsigned)ef_ptr
[0], name_crc
));
1625 for (i
= 5; i
< n
; ++i
)
1626 Info(slide
, 0, ((char *)slide
,
1627 LoadFarString(efFormat
), ef_ptr
[i
]));
1629 goto ef_default_display
;
1633 if (eb_datalen
>= EB_MAC3_HLEN
) {
1634 ulg eb_uc
= makelong(ef_ptr
);
1635 unsigned mac3_flgs
= makeword(ef_ptr
+EB_FLGS_OFFS
);
1636 unsigned eb_is_uc
= mac3_flgs
& EB_M3_FL_UNCMPR
;
1638 Info(slide
, 0, ((char *)slide
, LoadFarString(Mac3data
),
1639 eb_uc
, eb_is_uc
? "un" : nullStr
));
1642 *pEndprev
+= makelong(ef_ptr
);
1644 *pEndprev
= 0L; /* no clue about csize of local */
1647 Info(slide
, 0, ((char *)slide
,
1648 LoadFarString(MacOSMAC3flags
),
1649 LoadFarStringSmall(mac3_flgs
& EB_M3_FL_DATFRK
?
1650 MacOS_DF
: MacOS_RF
),
1651 (mac3_flgs
& EB_M3_FL_TIME64
? 64 : 32)));
1652 zi_showMacTypeCreator(__G__
&ef_ptr
[6]);
1654 goto ef_default_display
;
1658 if (eb_datalen
>= 5 &&
1659 makelong(ef_ptr
) == 0x5449505A /* "ZPIT" */) {
1661 if (eb_datalen
>= 12) {
1662 zi_showMacTypeCreator(__G__
&ef_ptr
[4]);
1665 goto ef_default_display
;
1669 if (eb_datalen
>= 5 &&
1670 makelong(ef_ptr
) == 0x5449505A /* "ZPIT" */) {
1671 unsigned fnlen
= ef_ptr
[4];
1673 if ((unsigned)eb_datalen
>= fnlen
+ (5 + 8)) {
1674 uch nullchar
= ef_ptr
[fnlen
+5];
1676 ef_ptr
[fnlen
+5] = '\0'; /* terminate filename */
1678 Info(slide
, 0, ((char *)slide
,
1679 LoadFarString(ZipItFname
), (char *)ef_ptr
+5));
1680 ef_ptr
[fnlen
+5] = nullchar
;
1681 zi_showMacTypeCreator(__G__
&ef_ptr
[fnlen
+5]);
1684 goto ef_default_display
;
1688 if (eb_datalen
>= 40 &&
1689 makelong(ef_ptr
) == 0x45454C4A /* "JLEE" */)
1691 zi_showMacTypeCreator(__G__
&ef_ptr
[4]);
1693 Info(slide
, 0, ((char *)slide
,
1694 LoadFarString(MacOSJLEEflags
),
1695 LoadFarStringSmall(ef_ptr
[31] & 1 ?
1696 MacOS_DF
: MacOS_RF
)));
1698 goto ef_default_display
;
1702 if ((eb_datalen
== EB_SMARTZIP_HLEN
) &&
1703 makelong(ef_ptr
) == 0x70695A64 /* "dZip" */) {
1704 char filenameBuf
[32];
1705 zi_showMacTypeCreator(__G__
&ef_ptr
[4]);
1706 memcpy(filenameBuf
, &ef_ptr
[33], 31);
1707 filenameBuf
[ef_ptr
[32]] = '\0';
1708 A_TO_N(filenameBuf
);
1709 Info(slide
, 0, ((char *)slide
,
1710 LoadFarString(ZipItFname
), filenameBuf
));
1712 goto ef_default_display
;
1721 Info(slide
, 0, ((char *)slide
,
1722 LoadFarString(VmMvsExtraField
),
1723 (getVMMVSexfield(type
, ef_ptr
-EB_HEADSIZE
,
1724 (unsigned)eb_datalen
) > 0)?
1725 type
: LoadFarStringSmall(VmMvsInvalid
)));
1728 #endif /* CMS_MVS */
1731 if (eb_datalen
>= EB_BEOS_HLEN
) {
1732 ulg eb_uc
= makelong(ef_ptr
);
1734 *(ef_ptr
+EB_FLGS_OFFS
) & EB_BE_FL_UNCMPR
;
1736 if (eb_id
== EF_ATHEOS
)
1737 ef_fieldname
= AtheOSdata
;
1739 ef_fieldname
= BeOSdata
;
1740 Info(slide
, 0, ((char *)slide
,
1741 LoadFarString(ef_fieldname
),
1742 eb_uc
, eb_is_uc
? "un" : nullStr
));
1745 *pEndprev
+= makelong(ef_ptr
);
1747 *pEndprev
= 0L; /* no clue about csize of local */
1750 goto ef_default_display
;
1754 if (eb_datalen
>= 4) {
1755 Info(slide
, 0, ((char *)slide
, LoadFarString(QDOSdata
),
1756 ef_ptr
[0], ef_ptr
[1], ef_ptr
[2], ef_ptr
[3]));
1758 goto ef_default_display
;
1762 if (eb_datalen
>= 5) {
1763 Info(slide
, 0, ((char *)slide
, LoadFarString(AOSVSdata
),
1764 ((int)(uch
)ef_ptr
[4])/10, ((int)(uch
)ef_ptr
[4])%10));
1766 goto ef_default_display
;
1770 if (eb_datalen
== 20) {
1771 unsigned type
, code
;
1773 type
= (ef_ptr
[18] & 0x60) >> 5;
1774 code
= makeword(ef_ptr
);
1775 /* Arrg..., Tandem e.f. uses BigEndian byte-order */
1776 code
= ((code
<< 8) & 0xff00) | ((code
>> 8) & 0x00ff);
1777 if (type
== NSK_UNSTRUCTURED
) {
1778 if (code
== NSK_EDITFILECODE
)
1780 else if (code
== NSK_OBJECTFILECODE
)
1783 Info(slide
, 0, ((char *)slide
,
1784 LoadFarString(Tandemdata
),
1785 LoadFarStringSmall(TandemFileformat
[type
]),
1788 goto ef_default_display
;
1792 if (eb_datalen
>= 19) {
1796 for (i
= 0; i
< 16; ++i
)
1797 sprintf(&md5
[i
<<1], "%02x", ef_ptr
[15-i
]);
1799 Info(slide
, 0, ((char *)slide
, LoadFarString(MD5data
),
1802 } /* else: fall through !! */
1805 if (eb_datalen
> 0) {
1808 if (eb_datalen
<= 24) {
1809 Info(slide
, 0, ((char *)slide
,
1810 LoadFarString(ColonIndent
)));
1813 Info(slide
, 0, ((char *)slide
,
1814 LoadFarString(First20
)));
1817 for (i
= 0; i
< n
; ++i
)
1818 Info(slide
, 0, ((char *)slide
,
1819 LoadFarString(efFormat
), ef_ptr
[i
]));
1823 (*G
.message
)((zvoid
*)&G
, (uch
*)".", 1L, 0);
1825 ef_ptr
+= eb_datalen
;
1826 ef_len
-= eb_datalen
;
1828 (*G
.message
)((zvoid
*)&G
, (uch
*)"\n", 1L, 0);
1831 /* high bit == Unix/OS2/NT GMT times (mtime, atime); next bit == UID/GID */
1832 if ((xattr
= (unsigned)((G
.crec
.external_file_attributes
& 0xC000) >> 12))
1835 if (hostnum
== UNIX_
|| hostnum
== FS_HPFS_
|| hostnum
== FS_NTFS_
)
1837 Info(slide
, 0, ((char *)slide
, LoadFarString(lExtraFieldType
),
1838 "is", EF_IZUNIX
, LoadFarStringSmall(efIZUnix
),
1839 (unsigned)(xattr
&12), (xattr
&4)? efIZuid
: efIZnouid
));
1841 *pEndprev
+= (ulg
)(xattr
&12);
1843 else if (hostnum
== FS_FAT_
&& !(xattr
&4))
1844 Info(slide
, 0, ((char *)slide
, LoadFarString(lExtraFieldType
),
1845 "may be", EF_IZUNIX
, LoadFarStringSmall(efIZUnix
), 8,
1849 if (!G
.crec
.file_comment_length
)
1850 Info(slide
, 0, ((char *)slide
, LoadFarString(NoFileComment
)));
1852 Info(slide
, 0, ((char *)slide
, LoadFarString(FileCommBegin
)));
1853 if ((error
= do_string(__G__ G
.crec
.file_comment_length
, DISPL_8
)) !=
1856 error_in_archive
= error
; /* might be warning */
1857 if (error
> PK_WARN
) /* fatal */
1860 Info(slide
, 0, ((char *)slide
, LoadFarString(FileCommEnd
)));
1863 return error_in_archive
;
1865 } /* end function zi_long() */
1871 /*************************/
1872 /* Function zi_short() */
1873 /*************************/
1875 static int zi_short(__G
) /* return PK-type error code */
1878 #ifdef USE_EF_UT_TIME
1882 int k
, error
, error_in_archive
=PK_COOL
;
1883 unsigned hostnum
, hostver
, methid
, methnum
, xattr
;
1884 char *p
, workspace
[12], attribs
[16];
1886 static ZCONST
char dtype
[5]="NXFS"; /* normal, maximum, fast, superfast */
1887 static ZCONST
char Far os
[NUM_HOSTS
+1][4] = {
1888 "fat", "ami", "vms", "unx", "cms", "atr", "hpf", "mac", "zzz",
1889 "cpm", "t20", "ntf", "qds", "aco", "vft", "mvs", "be ", "nsk",
1890 "ths", "osx", "???", "???", "???", "???", "???", "???", "???",
1891 "???", "???", "???", "ath", "???"
1893 #ifdef OLD_THEOS_EXTRA
1894 static ZCONST
char Far os_TheosOld
[] = "tho";
1896 static ZCONST
char Far method
[NUM_METHODS
+1][5] = {
1897 "stor", "shrk", "re:1", "re:2", "re:3", "re:4", "i#:#", "tokn",
1898 "def#", "d64#", "dcli", "bzp2", "lzma", "ters", "lz77", "wavp",
1903 /*---------------------------------------------------------------------------
1904 Print out various interesting things about the compressed file.
1905 ---------------------------------------------------------------------------*/
1907 methid
= (unsigned)(G
.crec
.compression_method
);
1908 methnum
= find_compr_idx(G
.crec
.compression_method
);
1909 hostnum
= (unsigned)(G
.pInfo
->hostnum
);
1910 hostver
= (unsigned)(G
.pInfo
->hostver
);
1912 extnum = (unsigned)MIN(G.crec.version_needed_to_extract[1], NUM_HOSTS);
1913 extver = (unsigned)G.crec.version_needed_to_extract[0];
1916 zfstrcpy(methbuf
, method
[methnum
]);
1917 if (methid
== IMPLODED
) {
1918 methbuf
[1] = (char)((G
.crec
.general_purpose_bit_flag
& 2)? '8' : '4');
1919 methbuf
[3] = (char)((G
.crec
.general_purpose_bit_flag
& 4)? '3' : '2');
1920 } else if (methid
== DEFLATED
|| methid
== ENHDEFLATED
) {
1921 ush dnum
=(ush
)((G
.crec
.general_purpose_bit_flag
>>1) & 3);
1922 methbuf
[3] = dtype
[dnum
];
1923 } else if (methnum
>= NUM_METHODS
) { /* unknown */
1924 sprintf(&methbuf
[1], "%03u", G
.crec
.compression_method
);
1927 for (k
= 0; k
< 15; ++k
)
1931 xattr
= (unsigned)((G
.crec
.external_file_attributes
>> 16) & 0xFFFF);
1936 for (k
= 0; k
< 12; ++k
)
1938 if (xattr
& VMS_IRUSR
)
1940 if (xattr
& VMS_IWUSR
) {
1944 if (xattr
& VMS_IXUSR
)
1946 if (xattr
& VMS_IRGRP
)
1948 if (xattr
& VMS_IWGRP
) {
1952 if (xattr
& VMS_IXGRP
)
1954 if (xattr
& VMS_IROTH
)
1956 if (xattr
& VMS_IWOTH
) {
1958 workspace
[11] = 'D';
1960 if (xattr
& VMS_IXOTH
)
1961 workspace
[10] = 'E';
1964 for (k
= j
= 0; j
< 3; ++j
) { /* groups of permissions */
1965 for (i
= 0; i
< 4; ++i
, ++k
) /* perms within a group */
1967 *p
++ = workspace
[k
];
1968 *p
++ = ','; /* group separator */
1970 *--p
= ' '; /* overwrite last comma */
1971 if ((p
- attribs
) < 12)
1972 sprintf(&attribs
[12], "%u.%u", hostver
/10, hostver
%10);
1977 switch (xattr
& AMI_IFMT
) {
1978 case AMI_IFDIR
: attribs
[0] = 'd'; break;
1979 case AMI_IFREG
: attribs
[0] = '-'; break;
1980 default: attribs
[0] = '?'; break;
1982 attribs
[1] = (xattr
& AMI_IHIDDEN
)? 'h' : '-';
1983 attribs
[2] = (xattr
& AMI_ISCRIPT
)? 's' : '-';
1984 attribs
[3] = (xattr
& AMI_IPURE
)? 'p' : '-';
1985 attribs
[4] = (xattr
& AMI_IARCHIVE
)? 'a' : '-';
1986 attribs
[5] = (xattr
& AMI_IREAD
)? 'r' : '-';
1987 attribs
[6] = (xattr
& AMI_IWRITE
)? 'w' : '-';
1988 attribs
[7] = (xattr
& AMI_IEXECUTE
)? 'e' : '-';
1989 attribs
[8] = (xattr
& AMI_IDELETE
)? 'd' : '-';
1990 sprintf(&attribs
[12], "%u.%u", hostver
/10, hostver
%10);
1994 switch (xattr
& THS_IFMT
) {
1995 case THS_IFLIB
: *attribs
= 'L'; break;
1996 case THS_IFDIR
: *attribs
= 'D'; break;
1997 case THS_IFCHR
: *attribs
= 'C'; break;
1998 case THS_IFREG
: *attribs
= 'S'; break;
1999 case THS_IFREL
: *attribs
= 'R'; break;
2000 case THS_IFKEY
: *attribs
= 'K'; break;
2001 case THS_IFIND
: *attribs
= 'I'; break;
2002 case THS_IFR16
: *attribs
= 'P'; break;
2003 case THS_IFP16
: *attribs
= '2'; break;
2004 case THS_IFP32
: *attribs
= '3'; break;
2005 default: *attribs
= '?'; break;
2007 attribs
[1] = (xattr
& THS_INHID
) ? '.' : 'H';
2008 attribs
[2] = (xattr
& THS_IMODF
) ? '.' : 'M';
2009 attribs
[3] = (xattr
& THS_IWOTH
) ? '.' : 'W';
2010 attribs
[4] = (xattr
& THS_IROTH
) ? '.' : 'R';
2011 attribs
[5] = (xattr
& THS_IEUSR
) ? '.' : 'E';
2012 attribs
[6] = (xattr
& THS_IXUSR
) ? '.' : 'X';
2013 attribs
[7] = (xattr
& THS_IWUSR
) ? '.' : 'W';
2014 attribs
[8] = (xattr
& THS_IRUSR
) ? '.' : 'R';
2015 sprintf(&attribs
[12], "%u.%u", hostver
/10, hostver
%10);
2019 #ifdef OLD_THEOS_EXTRA
2020 if (hostver
== 20) {
2021 switch (xattr
& _THS_IFMT
) {
2022 case _THS_IFLIB
: *attribs
= 'L'; break;
2023 case _THS_IFDIR
: *attribs
= 'd'; break;
2024 case _THS_IFCHR
: *attribs
= 'c'; break;
2025 case _THS_IFREG
: *attribs
= 'S'; break;
2026 case _THS_IODRC
: *attribs
= 'D'; break;
2027 case _THS_IOKEY
: *attribs
= 'K'; break;
2028 case _THS_IOIND
: *attribs
= 'I'; break;
2029 case _THS_IOPRG
: *attribs
= 'P'; break;
2030 case _THS_IO286
: *attribs
= '2'; break;
2031 case _THS_IO386
: *attribs
= '3'; break;
2032 default: *attribs
= '?'; break;
2034 attribs
[1] = (xattr
& _THS_HIDDN
) ? 'H' : '.';
2035 attribs
[2] = (xattr
& _THS_IXOTH
) ? '.' : 'X';
2036 attribs
[3] = (xattr
& _THS_IWOTH
) ? '.' : 'W';
2037 attribs
[4] = (xattr
& _THS_IROTH
) ? '.' : 'R';
2038 attribs
[5] = (xattr
& _THS_IEUSR
) ? '.' : 'E';
2039 attribs
[6] = (xattr
& _THS_IXUSR
) ? '.' : 'X';
2040 attribs
[7] = (xattr
& _THS_IWUSR
) ? '.' : 'W';
2041 attribs
[8] = (xattr
& _THS_IRUSR
) ? '.' : 'R';
2042 sprintf(&attribs
[12], "%u.%u", hostver
/10, hostver
%10);
2044 } /* else: fall through! */
2045 #endif /* OLD_THEOS_EXTRA */
2053 if (hostnum
!= FS_FAT_
||
2054 (unsigned)(xattr
& 0700) !=
2056 ((unsigned)!(G
.crec
.external_file_attributes
& 1) << 7) |
2057 ((unsigned)(G
.crec
.external_file_attributes
& 0x10) << 2))
2060 xattr
= (unsigned)(G
.crec
.external_file_attributes
& 0xFF);
2061 sprintf(attribs
, ".r.-... %u.%u", hostver
/10, hostver
%10);
2062 attribs
[2] = (xattr
& 0x01)? '-' : 'w';
2063 attribs
[5] = (xattr
& 0x02)? 'h' : '-';
2064 attribs
[6] = (xattr
& 0x04)? 's' : '-';
2065 attribs
[4] = (xattr
& 0x20)? 'a' : '-';
2071 if (IS_VOLID(xattr
))
2073 else if ((p
= MBSRCHR(G
.filename
, '.')) != (char *)NULL
) {
2075 if (STRNICMP(p
, "com", 3) == 0 ||
2076 STRNICMP(p
, "exe", 3) == 0 ||
2077 STRNICMP(p
, "btm", 3) == 0 ||
2078 STRNICMP(p
, "cmd", 3) == 0 ||
2079 STRNICMP(p
, "bat", 3) == 0)
2083 } /* else: fall through! */
2085 default: /* assume Unix-like */
2086 switch ((unsigned)(xattr
& UNX_IFMT
)) {
2087 case (unsigned)UNX_IFDIR
: attribs
[0] = 'd'; break;
2088 case (unsigned)UNX_IFREG
: attribs
[0] = '-'; break;
2089 case (unsigned)UNX_IFLNK
: attribs
[0] = 'l'; break;
2090 case (unsigned)UNX_IFBLK
: attribs
[0] = 'b'; break;
2091 case (unsigned)UNX_IFCHR
: attribs
[0] = 'c'; break;
2092 case (unsigned)UNX_IFIFO
: attribs
[0] = 'p'; break;
2093 case (unsigned)UNX_IFSOCK
: attribs
[0] = 's'; break;
2094 default: attribs
[0] = '?'; break;
2096 attribs
[1] = (xattr
& UNX_IRUSR
)? 'r' : '-';
2097 attribs
[4] = (xattr
& UNX_IRGRP
)? 'r' : '-';
2098 attribs
[7] = (xattr
& UNX_IROTH
)? 'r' : '-';
2099 attribs
[2] = (xattr
& UNX_IWUSR
)? 'w' : '-';
2100 attribs
[5] = (xattr
& UNX_IWGRP
)? 'w' : '-';
2101 attribs
[8] = (xattr
& UNX_IWOTH
)? 'w' : '-';
2103 if (xattr
& UNX_IXUSR
)
2104 attribs
[3] = (xattr
& UNX_ISUID
)? 's' : 'x';
2106 attribs
[3] = (xattr
& UNX_ISUID
)? 'S' : '-'; /* S==undefined */
2107 if (xattr
& UNX_IXGRP
)
2108 attribs
[6] = (xattr
& UNX_ISGID
)? 's' : 'x'; /* == UNX_ENFMT */
2110 /* attribs[6] = (xattr & UNX_ISGID)? 'l' : '-'; real 4.3BSD */
2111 attribs
[6] = (xattr
& UNX_ISGID
)? 'S' : '-'; /* SunOS 4.1.x */
2112 if (xattr
& UNX_IXOTH
)
2113 attribs
[9] = (xattr
& UNX_ISVTX
)? 't' : 'x'; /* "sticky bit" */
2115 attribs
[9] = (xattr
& UNX_ISVTX
)? 'T' : '-'; /* T==undefined */
2117 sprintf(&attribs
[12], "%u.%u", hostver
/10, hostver
%10);
2120 } /* end switch (hostnum: external attributes format) */
2122 #ifdef OLD_THEOS_EXTRA
2123 Info(slide
, 0, ((char *)slide
, "%s %s %s ", attribs
,
2124 LoadFarStringSmall(((hostnum
== FS_VFAT_
&& hostver
== 20) ?
2127 FmZofft(G
.crec
.ucsize
, "8", "u")));
2129 Info(slide
, 0, ((char *)slide
, "%s %s %s ", attribs
,
2130 LoadFarStringSmall(os
[hostnum
]),
2131 FmZofft(G
.crec
.ucsize
, "8", "u")));
2133 Info(slide
, 0, ((char *)slide
, "%c",
2134 (G
.crec
.general_purpose_bit_flag
& 1)?
2135 ((G
.crec
.internal_file_attributes
& 1)? 'T' : 'B') : /* encrypted */
2136 ((G
.crec
.internal_file_attributes
& 1)? 't' : 'b'))); /* plaintext */
2137 k
= (G
.crec
.extra_field_length
||
2138 /* a local-only "UX" (old Unix/OS2/NT GMT times "IZUNIX") e.f.? */
2139 ((G
.crec
.external_file_attributes
& 0x8000) &&
2140 (hostnum
== UNIX_
|| hostnum
== FS_HPFS_
|| hostnum
== FS_NTFS_
)));
2141 Info(slide
, 0, ((char *)slide
, "%c", k
?
2142 ((G
.crec
.general_purpose_bit_flag
& 8)? 'X' : 'x') : /* extra field */
2143 ((G
.crec
.general_purpose_bit_flag
& 8)? 'l' : '-'))); /* no extra field */
2144 /* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ extended local header or not */
2146 if (uO
.lflag
== 4) {
2147 zusz_t csiz
= G
.crec
.csize
;
2149 if (G
.crec
.general_purpose_bit_flag
& 1)
2150 csiz
-= 12; /* if encrypted, don't count encryption header */
2151 Info(slide
, 0, ((char *)slide
, "%3d%%",
2152 (ratio(G
.crec
.ucsize
,csiz
)+5)/10));
2153 } else if (uO
.lflag
== 5)
2154 Info(slide
, 0, ((char *)slide
, " %s",
2155 FmZofft(G
.crec
.csize
, "8", "u")));
2157 /* For printing of date & time, a "char d_t_buf[16]" is required.
2158 * To save stack space, we reuse the "char attribs[16]" buffer whose
2159 * content is no longer needed.
2161 # define d_t_buf attribs
2162 #ifdef USE_EF_UT_TIME
2163 z_modtim
= G
.extra_field
&&
2167 (ef_scan_for_izux(G
.extra_field
, G
.crec
.extra_field_length
, 1,
2168 G
.crec
.last_mod_dos_datetime
, &z_utime
, NULL
)
2170 ? &z_utime
.mtime
: NULL
;
2171 TIMET_TO_NATIVE(z_utime
.mtime
) /* NOP unless MSC 7.0 or Macintosh */
2172 d_t_buf
[0] = (char)0; /* signal "show local time" */
2174 # define z_modtim NULL
2176 Info(slide
, 0, ((char *)slide
, " %s %s ", methbuf
,
2177 zi_time(__G__
&G
.crec
.last_mod_dos_datetime
, z_modtim
, d_t_buf
)));
2180 /*---------------------------------------------------------------------------
2181 Skip the file comment, if any (the filename has already been printed,
2182 above). That finishes up this file entry...
2183 ---------------------------------------------------------------------------*/
2185 SKIP_(G
.crec
.file_comment_length
)
2187 return error_in_archive
;
2189 } /* end function zi_short() */
2195 /**************************************/
2196 /* Function zi_showMacTypeCreator() */
2197 /**************************************/
2199 static void zi_showMacTypeCreator(__G__ ebfield
)
2203 /* not every Type / Creator character is printable */
2204 if (isprint(native(ebfield
[0])) && isprint(native(ebfield
[1])) &&
2205 isprint(native(ebfield
[2])) && isprint(native(ebfield
[3])) &&
2206 isprint(native(ebfield
[4])) && isprint(native(ebfield
[5])) &&
2207 isprint(native(ebfield
[6])) && isprint(native(ebfield
[7]))) {
2208 Info(slide
, 0, ((char *)slide
, LoadFarString(MacOSdata
),
2209 native(ebfield
[0]), native(ebfield
[1]),
2210 native(ebfield
[2]), native(ebfield
[3]),
2211 native(ebfield
[4]), native(ebfield
[5]),
2212 native(ebfield
[6]), native(ebfield
[7])));
2214 Info(slide
, 0, ((char *)slide
, LoadFarString(MacOSdata1
),
2215 (((ulg
)ebfield
[0]) << 24) +
2216 (((ulg
)ebfield
[1]) << 16) +
2217 (((ulg
)ebfield
[2]) << 8) +
2219 (((ulg
)ebfield
[4]) << 24) +
2220 (((ulg
)ebfield
[5]) << 16) +
2221 (((ulg
)ebfield
[6]) << 8) +
2222 ((ulg
)ebfield
[7])));
2224 } /* end function zi_showMacTypeCreator() */
2230 /************************/
2231 /* Function zi_time() */
2232 /************************/
2234 static char *zi_time(__G__ datetimez
, modtimez
, d_t_str
)
2236 ZCONST ulg
*datetimez
;
2237 ZCONST
time_t *modtimez
;
2240 unsigned yr
, mo
, dy
, hh
, mm
, ss
;
2242 ZCONST
char *monthstr
;
2243 static ZCONST
char Far month
[12][4] = {
2244 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
2245 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
2247 #ifdef USE_EF_UT_TIME
2253 /*---------------------------------------------------------------------------
2254 Convert the file-modification date and time info to a string of the form
2255 "1991 Feb 23 17:15:00", "23-Feb-91 17:15" or "19910223.171500", depending
2256 on values of lflag and T_flag. If using Unix-time extra fields, convert
2257 to local time or not, depending on value of first character in d_t_str[].
2258 ---------------------------------------------------------------------------*/
2260 #ifdef USE_EF_UT_TIME
2261 if (modtimez
!= NULL
) {
2263 /* check for our secret message from above... */
2264 t
= (d_t_str
[0] == (char)1)? gmtime(modtimez
) : localtime(modtimez
);
2266 t
= localtime(modtimez
);
2268 if (uO
.lflag
> 9 && t
== (struct tm
*)NULL
)
2269 /* time conversion error in verbose listing format,
2270 * return string with '?' instead of data
2272 return (strcpy(d_t_str
, LoadFarString(lngYMDHMSTimeError
)));
2274 t
= (struct tm
*)NULL
;
2275 if (t
!= (struct tm
*)NULL
) {
2276 mo
= (unsigned)(t
->tm_mon
+ 1);
2277 dy
= (unsigned)(t
->tm_mday
);
2278 yr
= (unsigned)(t
->tm_year
);
2280 hh
= (unsigned)(t
->tm_hour
);
2281 mm
= (unsigned)(t
->tm_min
);
2282 ss
= (unsigned)(t
->tm_sec
);
2284 #endif /* USE_EF_UT_TIME */
2286 yr
= ((unsigned)(*datetimez
>> 25) & 0x7f) + 80;
2287 mo
= ((unsigned)(*datetimez
>> 21) & 0x0f);
2288 dy
= ((unsigned)(*datetimez
>> 16) & 0x1f);
2290 hh
= (((unsigned)*datetimez
>> 11) & 0x1f);
2291 mm
= (((unsigned)*datetimez
>> 5) & 0x3f);
2292 ss
= (((unsigned)*datetimez
<< 1) & 0x3e);
2295 if (mo
== 0 || mo
> 12) {
2296 sprintf(monthbuf
, LoadFarString(BogusFmt
), mo
);
2297 monthstr
= monthbuf
;
2299 monthstr
= LoadFarStringSmall(month
[mo
-1]);
2301 if (uO
.lflag
> 9) /* verbose listing format */
2302 sprintf(d_t_str
, LoadFarString(lngYMDHMSTime
), yr
+1900, monthstr
, dy
,
2305 sprintf(d_t_str
, LoadFarString(DecimalTime
), yr
+1900, mo
, dy
,
2307 else /* was: if ((uO.lflag >= 3) && (uO.lflag <= 5)) */
2308 sprintf(d_t_str
, LoadFarString(shtYMDHMTime
), yr
%100, monthstr
, dy
,
2313 } /* end function zi_time() */
2315 #endif /* !NO_ZIPINFO */