2 Copyright (c) 1990-2001 Info-ZIP. All rights reserved.
4 See the accompanying file LICENSE, version 2000-Apr-09 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__ ulg
*pEndprev
));
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 LongHeader
[] = "Archive: %s %ld bytes %u file%s\n";
139 static ZCONST
char Far ShortHeader
[] = "Archive: %s %ld %u\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 ActOffsetCentDir
[] = "\
143 Actual offset of end-of-central-dir record: %9ld (%.8lXh)\n\
144 Expected offset of end-of-central-dir record: %9ld (%.8lXh)\n\
145 (based on the length of the central directory and its expected offset)\n\n";
146 static ZCONST
char Far SinglePartArchive1
[] = "\
147 This zipfile constitutes the sole disk of a single-part archive; its\n\
148 central directory contains %u %s. The central directory is %lu\n\
149 (%.8lXh) bytes long, and its (expected) offset in bytes from the\n";
150 static ZCONST
char Far SinglePartArchive2
[] = "\
151 beginning of the zipfile is %lu (%.8lXh).\n\n";
152 static ZCONST
char Far MultiPartArchive1
[] = "\
153 This zipfile constitutes disk %u of a multi-part archive. The central\n\
154 directory starts on disk %u; %u of its entries %s contained within\n";
155 static ZCONST
char Far MultiPartArchive2
[] = "\
156 this zipfile, out of a total of %u %s. The entire central\n\
157 directory is %lu (%.8lXh) bytes long, and its offset in bytes from\n";
158 static ZCONST
char Far MultiPartArchive3
[] = "\
159 the beginning of the zipfile in which it begins is %lu (%.8lXh).\n\n";
160 static ZCONST
char Far NoZipfileComment
[] = " There is no zipfile comment.\n";
161 static ZCONST
char Far ZipfileCommentDesc
[] =
162 " The zipfile comment is %u bytes long and contains the following text:\n\n";
163 static ZCONST
char Far ZipfileCommBegin
[] =
164 "======================== zipfile comment begins ==========================\n";
165 static ZCONST
char Far ZipfileCommEnd
[] =
166 "========================= zipfile comment ends ===========================\n";
167 static ZCONST
char Far ZipfileCommTrunc2
[] =
168 "\n The zipfile comment is truncated.\n";
169 static ZCONST
char Far ZipfileCommTruncMsg
[] =
170 "\ncaution: zipfile comment truncated\n";
172 static ZCONST
char Far CentralDirEntry
[] =
173 "\nCentral directory entry #%lu:\n---------------------------\n\n";
174 static ZCONST
char Far ZipfileStats
[] =
175 "%lu file%s, %lu bytes uncompressed, %lu bytes compressed: %s%d.%d%%\n";
177 /* zi_long() strings */
178 static ZCONST
char Far OS_FAT
[] = "MS-DOS, OS/2 or NT FAT";
179 static ZCONST
char Far OS_Amiga
[] = "Amiga";
180 static ZCONST
char Far OS_VMS
[] = "VMS";
181 static ZCONST
char Far OS_Unix
[] = "Unix";
182 static ZCONST
char Far OS_VMCMS
[] = "VM/CMS";
183 static ZCONST
char Far OS_AtariST
[] = "Atari ST";
184 static ZCONST
char Far OS_HPFS
[] = "OS/2 or NT HPFS";
185 static ZCONST
char Far OS_Macintosh
[] = "Macintosh HFS";
186 static ZCONST
char Far OS_ZSystem
[] = "Z-System";
187 static ZCONST
char Far OS_CPM
[] = "CP/M";
188 static ZCONST
char Far OS_TOPS20
[] = "TOPS-20";
189 static ZCONST
char Far OS_NTFS
[] = "NTFS";
190 static ZCONST
char Far OS_QDOS
[] = "SMS/QDOS";
191 static ZCONST
char Far OS_Acorn
[] = "Acorn RISC OS";
192 static ZCONST
char Far OS_MVS
[] = "MVS";
193 static ZCONST
char Far OS_VFAT
[] = "Win32 VFAT";
194 static ZCONST
char Far OS_BeOS
[] = "BeOS";
195 static ZCONST
char Far OS_Tandem
[] = "Tandem NSK";
196 static ZCONST
char Far OS_Theos
[] = "Theos";
197 #ifdef OLD_THEOS_EXTRA
198 static ZCONST
char Far OS_TheosOld
[] = "Theos (Old)";
199 #endif /* OLD_THEOS_EXTRA */
201 static ZCONST
char Far MthdNone
[] = "none (stored)";
202 static ZCONST
char Far MthdShrunk
[] = "shrunk";
203 static ZCONST
char Far MthdRedF1
[] = "reduced (factor 1)";
204 static ZCONST
char Far MthdRedF2
[] = "reduced (factor 2)";
205 static ZCONST
char Far MthdRedF3
[] = "reduced (factor 3)";
206 static ZCONST
char Far MthdRedF4
[] = "reduced (factor 4)";
207 static ZCONST
char Far MthdImplode
[] = "imploded";
208 static ZCONST
char Far MthdToken
[] = "tokenized";
209 static ZCONST
char Far MthdDeflate
[] = "deflated";
210 static ZCONST
char Far MthdDeflat64
[] = "deflated (enhanced-64k)";
211 static ZCONST
char Far MthdDCLImplode
[] = "imploded (PK DCL)";
213 static ZCONST
char Far DeflNorm
[] = "normal";
214 static ZCONST
char Far DeflMax
[] = "maximum";
215 static ZCONST
char Far DeflFast
[] = "fast";
216 static ZCONST
char Far DeflSFast
[] = "superfast";
218 static ZCONST
char Far ExtraBytesPreceding
[] =
219 " There are an extra %ld bytes preceding this file.\n\n";
221 static ZCONST
char Far UnknownNo
[] = "unknown (%d)";
223 static ZCONST
char Far LocalHeaderOffset
[] =
224 "\n offset of local header from start of archive: %lu (%.8lXh) bytes\n";
225 static ZCONST
char Far HostOS
[] =
226 " file system or operating system of origin: %s\n";
227 static ZCONST
char Far EncodeSWVer
[] =
228 " version of encoding software: %u.%u\n";
229 static ZCONST
char Far MinOSCompReq
[] =
230 " minimum file system compatibility required: %s\n";
231 static ZCONST
char Far MinSWVerReq
[] =
232 " minimum software version required to extract: %u.%u\n";
233 static ZCONST
char Far CompressMethod
[] =
234 " compression method: %s\n";
235 static ZCONST
char Far SlideWindowSizeImplode
[] =
236 " size of sliding dictionary (implosion): %cK\n";
237 static ZCONST
char Far ShannonFanoTrees
[] =
238 " number of Shannon-Fano trees (implosion): %c\n";
239 static ZCONST
char Far CompressSubtype
[] =
240 " compression sub-type (deflation): %s\n";
241 static ZCONST
char Far FileSecurity
[] =
242 " file security status: %sencrypted\n";
243 static ZCONST
char Far ExtendedLocalHdr
[] =
244 " extended local header: %s\n";
245 static ZCONST
char Far FileModDate
[] =
246 " file last modified on (DOS date/time): %s\n";
247 #ifdef USE_EF_UT_TIME
248 static ZCONST
char Far UT_FileModDate
[] =
249 " file last modified on (UT extra field modtime): %s %s\n";
250 static ZCONST
char Far LocalTime
[] = "local";
252 static ZCONST
char Far GMTime
[] = "UTC";
254 #endif /* USE_EF_UT_TIME */
255 static ZCONST
char Far CRC32Value
[] =
256 " 32-bit CRC value (hex): %.8lx\n";
257 static ZCONST
char Far CompressedFileSize
[] =
258 " compressed size: %lu bytes\n";
259 static ZCONST
char Far UncompressedFileSize
[] =
260 " uncompressed size: %lu bytes\n";
261 static ZCONST
char Far FilenameLength
[] =
262 " length of filename: %u characters\n";
263 static ZCONST
char Far ExtraFieldLength
[] =
264 " length of extra field: %u bytes\n";
265 static ZCONST
char Far FileCommentLength
[] =
266 " length of file comment: %u characters\n";
267 static ZCONST
char Far FileDiskNum
[] =
268 " disk number on which file begins: disk %u\n";
269 static ZCONST
char Far ApparentFileType
[] =
270 " apparent file type: %s\n";
271 static ZCONST
char Far VMSFileAttributes
[] =
272 " VMS file attributes (%06o octal): %s\n";
273 static ZCONST
char Far AmigaFileAttributes
[] =
274 " Amiga file attributes (%06o octal): %s\n";
275 static ZCONST
char Far UnixFileAttributes
[] =
276 " Unix file attributes (%06o octal): %s\n";
277 static ZCONST
char Far NonMSDOSFileAttributes
[] =
278 " non-MSDOS external file attributes: %06lX hex\n";
279 static ZCONST
char Far MSDOSFileAttributes
[] =
280 " MS-DOS file attributes (%02X hex): none\n";
281 static ZCONST
char Far MSDOSFileAttributesRO
[] =
282 " MS-DOS file attributes (%02X hex): read-only\n";
283 static ZCONST
char Far MSDOSFileAttributesAlpha
[] =
284 " MS-DOS file attributes (%02X hex): %s%s%s%s%s%s%s%s\n";
285 static ZCONST
char Far TheosFileAttributes
[] =
286 " Theos file attributes (%04X hex): %s\n";
288 static ZCONST
char Far TheosFTypLib
[] = "Library ";
289 static ZCONST
char Far TheosFTypDir
[] = "Directory ";
290 static ZCONST
char Far TheosFTypReg
[] = "Sequential ";
291 static ZCONST
char Far TheosFTypRel
[] = "Direct ";
292 static ZCONST
char Far TheosFTypKey
[] = "Keyed ";
293 static ZCONST
char Far TheosFTypInd
[] = "Indexed ";
294 static ZCONST
char Far TheosFTypR16
[] = " 86 program ";
295 static ZCONST
char Far TheosFTypP16
[] = "286 program ";
296 static ZCONST
char Far TheosFTypP32
[] = "386 program ";
297 static ZCONST
char Far TheosFTypUkn
[] = "??? ";
299 static ZCONST
char Far ExtraFieldTrunc
[] = "\n\
300 error: EF data block (type 0x%04x) size %u exceeds remaining extra field\n\
301 space %u; block length has been truncated.\n";
302 static ZCONST
char Far ExtraFields
[] = "\n\
303 The central-directory extra field contains:";
304 static ZCONST
char Far ExtraFieldType
[] = "\n\
305 - A subfield with ID 0x%04x (%s) and %u data bytes";
306 static ZCONST
char Far efPKSZ64
[] = "PKWARE 64-bit sizes";
307 static ZCONST
char Far efAV
[] = "PKWARE AV";
308 static ZCONST
char Far efOS2
[] = "OS/2";
309 static ZCONST
char Far efPKVMS
[] = "PKWARE VMS";
310 static ZCONST
char Far efPKWin32
[] = "PKWARE Win32";
311 static ZCONST
char Far efPKUnix
[] = "PKWARE Unix";
312 static ZCONST
char Far efIZVMS
[] = "Info-ZIP VMS";
313 static ZCONST
char Far efIZUnix
[] = "old Info-ZIP Unix/OS2/NT";
314 static ZCONST
char Far efIZUnix2
[] = "Unix UID/GID";
315 static ZCONST
char Far efTime
[] = "universal time";
316 static ZCONST
char Far efJLMac
[] = "old Info-ZIP Macintosh";
317 static ZCONST
char Far efMac3
[] = "new Info-ZIP Macintosh";
318 static ZCONST
char Far efZipIt
[] = "ZipIt Macintosh";
319 static ZCONST
char Far efSmartZip
[] = "SmartZip Macintosh";
320 static ZCONST
char Far efZipIt2
[] = "ZipIt Macintosh (short)";
321 static ZCONST
char Far efVMCMS
[] = "VM/CMS";
322 static ZCONST
char Far efMVS
[] = "MVS";
323 static ZCONST
char Far efACL
[] = "OS/2 ACL";
324 static ZCONST
char Far efNTSD
[] = "Security Descriptor";
325 static ZCONST
char Far efBeOS
[] = "BeOS";
326 static ZCONST
char Far efQDOS
[] = "SMS/QDOS";
327 static ZCONST
char Far efAOSVS
[] = "AOS/VS";
328 static ZCONST
char Far efSpark
[] = "Acorn SparkFS";
329 static ZCONST
char Far efMD5
[] = "Fred Kantor MD5";
330 static ZCONST
char Far efASiUnix
[] = "ASi Unix";
331 static ZCONST
char Far efTandem
[] = "Tandem NSK";
332 static ZCONST
char Far efTheos
[] = "Theos";
333 static ZCONST
char Far efUnknown
[] = "unknown";
335 static ZCONST
char Far OS2EAs
[] = ".\n\
336 The local extra field has %lu bytes of OS/2 extended attributes.\n\
337 (May not match OS/2 \"dir\" amount due to storage method)";
338 static ZCONST
char Far izVMSdata
[] = ". The extra\n\
339 field is %s and has %u bytes of VMS %s information%s";
340 static ZCONST
char Far izVMSstored
[] = "stored";
341 static ZCONST
char Far izVMSrleenc
[] = "run-length encoded";
342 static ZCONST
char Far izVMSdeflat
[] = "deflated";
343 static ZCONST
char Far izVMScunknw
[] = "compressed(?)";
344 static ZCONST
char Far
*izVMScomp
[4] =
345 {izVMSstored
, izVMSrleenc
, izVMSdeflat
, izVMScunknw
};
346 static ZCONST
char Far ACLdata
[] = ".\n\
347 The local extra field has %lu bytes of access control list information";
348 static ZCONST
char Far NTSDData
[] = ".\n\
349 The local extra field has %lu bytes of NT security descriptor data";
350 static ZCONST
char Far UTdata
[] = ".\n\
351 The local extra field has UTC/GMT %s time%s";
352 static ZCONST
char Far UTmodification
[] = "modification";
353 static ZCONST
char Far UTaccess
[] = "access";
354 static ZCONST
char Far UTcreation
[] = "creation";
355 static ZCONST
char Far ZipItFname
[] = ".\n\
356 The Mac long filename is %s";
357 static ZCONST
char Far Mac3data
[] = ".\n\
358 The local extra field has %lu bytes of %scompressed Macintosh\n\
360 /* MacOSdata[] is used by EF_MAC3, EF_ZIPIT, EF_ZIPIT2 and EF_JLEE e. f. */
361 static ZCONST
char Far MacOSdata
[] = ".\n\
362 The associated file has type code `%c%c%c%c' and creator code `%c%c%c%c'";
363 static ZCONST
char Far MacOSdata1
[] = ".\n\
364 The associated file has type code `0x%lx' and creator code `0x%lx'";
365 static ZCONST
char Far MacOSJLEEflags
[] = ".\n File is marked as %s";
366 static ZCONST
char Far MacOS_RF
[] = "Resource-fork";
367 static ZCONST
char Far MacOS_DF
[] = "Data-fork";
368 static ZCONST
char Far MacOSMAC3flags
[] = ".\n\
369 File is marked as %s, File Dates are in %d Bit";
370 static ZCONST
char Far BeOSdata
[] = ".\n\
371 The local extra field has %lu bytes of %scompressed BeOS file attributes";
372 /* The associated file has type code `%c%c%c%c' and creator code `%c%c%c%c'" */
373 static ZCONST
char Far QDOSdata
[] = ".\n\
374 The QDOS extra field subtype is `%c%c%c%c'";
375 static ZCONST
char Far AOSVSdata
[] = ".\n\
376 The AOS/VS extra field revision is %d.%d";
377 static ZCONST
char Far TandemUnstr
[] = "Unstructured";
378 static ZCONST
char Far TandemRel
[] = "Relative";
379 static ZCONST
char Far TandemEntry
[] = "Entry Sequenced";
380 static ZCONST
char Far TandemKey
[] = "Key Sequenced";
381 static ZCONST
char Far TandemEdit
[] = "Edit";
382 static ZCONST
char Far TandemObj
[] = "Object";
383 static ZCONST
char Far
*TandemFileformat
[6] =
384 {TandemUnstr
, TandemRel
, TandemEntry
, TandemKey
, TandemEdit
, TandemObj
};
385 static ZCONST
char Far Tandemdata
[] = ".\n\
386 The file was originally a Tandem %s file, with file code %u";
387 static ZCONST
char Far MD5data
[] = ".\n\
388 The 128-bit MD5 signature is %s";
390 static ZCONST
char Far VmMvsExtraField
[] = ".\n\
391 The stored file open mode (FLDATA TYPE) is \"%s\"";
392 static ZCONST
char Far VmMvsInvalid
[] = "[invalid]";
395 static ZCONST
char Far First20
[] = ". The first\n 20 are: ";
396 static ZCONST
char Far ColonIndent
[] = ":\n ";
397 static ZCONST
char Far efFormat
[] = " %02x";
399 static ZCONST
char Far lExtraFieldType
[] = "\n\
400 There %s a local extra field with ID 0x%04x (%s) and\n\
401 %u data bytes (%s).\n";
402 static ZCONST
char Far efIZuid
[] =
403 "GMT modification/access times and Unix UID/GID";
404 static ZCONST
char Far efIZnouid
[] = "GMT modification/access times only";
407 static ZCONST
char Far NoFileComment
[] = "\n There is no file comment.\n";
408 static ZCONST
char Far FileCommBegin
[] = "\n\
409 ------------------------- file comment begins ----------------------------\n";
410 static ZCONST
char Far FileCommEnd
[] = "\
411 -------------------------- file comment ends -----------------------------\n";
413 /* zi_time() strings */
414 static ZCONST
char Far BogusFmt
[] = "%03d";
415 static ZCONST
char Far DMYHMTime
[] = "%2u-%s-%02u %02u:%02u";
416 static ZCONST
char Far YMDHMSTime
[] = "%u %s %u %02u:%02u:%02u";
417 static ZCONST
char Far DecimalTime
[] = "%04u%02u%02u.%02u%02u%02u";
418 #ifdef USE_EF_UT_TIME
419 static ZCONST
char Far YMDHMSTimeError
[] = "???? ??? ?? ??:??:??";
428 /************************/
429 /* Function zi_opts() */
430 /************************/
432 int zi_opts(__G__ pargc
, pargv
)
438 int argc
, c
, error
=FALSE
, negative
=0;
439 int hflag_slmv
=TRUE
, hflag_2
=FALSE
; /* diff options => diff defaults */
440 int tflag_slm
=TRUE
, tflag_2v
=FALSE
;
441 int explicit_h
=FALSE
, explicit_t
=FALSE
;
445 uO
.lflag
= LFLAG
; /* reset default on each call */
447 G
.extract_flag
= FALSE
; /* zipinfo does not extract to disk */
451 while (--argc
> 0 && (*++argv
)[0] == '-') {
453 while ((c
= *s
++) != 0) { /* "!= 0": prevent Turbo C warning */
458 case '1': /* shortest listing: JUST filenames */
460 uO
.lflag
= -2, negative
= 0;
464 case '2': /* just filenames, plus headers if specified */
466 uO
.lflag
= -2, negative
= 0;
471 case ('C'): /* -C: match filenames case-insensitively */
473 uO
.C_flag
= FALSE
, negative
= 0;
477 #endif /* !CMS_MVS */
478 case 'h': /* header line */
480 hflag_2
= hflag_slmv
= FALSE
, negative
= 0;
482 hflag_2
= hflag_slmv
= explicit_h
= TRUE
;
487 case 'l': /* longer form of "ls -l" type listing */
489 uO
.lflag
= -2, negative
= 0;
493 case 'm': /* medium form of "ls -l" type listing */
495 uO
.lflag
= -2, negative
= 0;
500 case 'M': /* send output through built-in "more" */
502 G
.M_flag
= FALSE
, negative
= 0;
507 case 's': /* default: shorter "ls -l" type listing */
509 uO
.lflag
= -2, negative
= 0;
513 case 't': /* totals line */
515 tflag_2v
= tflag_slm
= FALSE
, negative
= 0;
517 tflag_2v
= tflag_slm
= explicit_t
= TRUE
;
522 case ('T'): /* use (sortable) decimal time format */
524 uO
.T_flag
= FALSE
, negative
= 0;
528 case 'v': /* turbo-verbose listing */
530 uO
.lflag
= -2, negative
= 0;
534 case 'z': /* print zipfile comment */
536 uO
.zflag
= negative
= 0;
540 case 'Z': /* ZipInfo mode: ignore */
548 if ((argc
-- == 0) || error
) {
555 if (G
.M_flag
&& !isatty(1)) /* stdout redirected: "more" func useless */
559 /* if no listing options given (or all negated), or if only -h/-t given
560 * with individual files specified, use default listing format */
561 if ((uO
.lflag
< 0) || ((argc
> 0) && (uO
.lflag
== 0)))
564 /* set header and totals flags to default or specified values */
566 case 0: /* 0: can only occur if either -t or -h explicitly given; */
567 case 2: /* therefore set both flags equal to normally false value */
571 case 1: /* only filenames, *always* */
579 uO
.hflag
= ((argc
> 0) && !explicit_h
)? FALSE
: hflag_slmv
;
580 uO
.tflag
= ((argc
> 0) && !explicit_t
)? FALSE
: tflag_slm
;
583 uO
.hflag
= hflag_slmv
;
592 } /* end function zi_opts() */
600 /*******************************/
601 /* Function zi_end_central() */
602 /*******************************/
604 int zi_end_central(__G
) /* return PK-type error code */
610 /*---------------------------------------------------------------------------
611 Print out various interesting things about the zipfile.
612 ---------------------------------------------------------------------------*/
614 /* header fits on one line, for anything up to 10GB and 10000 files: */
616 Info(slide
, 0, ((char *)slide
, ((int)strlen(G
.zipfn
) < 39)?
617 LoadFarString(LongHeader
) : LoadFarString(ShortHeader
), G
.zipfn
,
618 (long)G
.ziplen
, G
.ecrec
.total_entries_central_dir
,
619 (G
.ecrec
.total_entries_central_dir
==1)?
620 nullStr
: PlurSufx
));
624 Info(slide
, 0, ((char *)slide
, LoadFarString(EndCentDirRec
)));
625 Info(slide
, 0, ((char *)slide
, LoadFarString(LineSeparators
)));
627 Info(slide
, 0, ((char *)slide
, LoadFarString(ActOffsetCentDir
),
628 (long)G
.real_ecrec_offset
, (long)G
.real_ecrec_offset
,
629 (long)G
.expect_ecrec_offset
, (long)G
.expect_ecrec_offset
));
631 if (G
.ecrec
.number_this_disk
== 0) {
632 Info(slide
, 0, ((char *)slide
, LoadFarString(SinglePartArchive1
),
633 G
.ecrec
.total_entries_central_dir
,
634 (G
.ecrec
.total_entries_central_dir
== 1)? "entry" : "entries",
635 G
.ecrec
.size_central_directory
,
636 G
.ecrec
.size_central_directory
));
637 Info(slide
, 0, ((char *)slide
, LoadFarString(SinglePartArchive2
),
638 G
.ecrec
.offset_start_central_directory
,
639 G
.ecrec
.offset_start_central_directory
));
641 Info(slide
, 0, ((char *)slide
, LoadFarString(MultiPartArchive1
),
642 G
.ecrec
.number_this_disk
+ 1,
643 G
.ecrec
.num_disk_start_cdir
+ 1,
644 G
.ecrec
.num_entries_centrl_dir_ths_disk
,
645 (G
.ecrec
.num_entries_centrl_dir_ths_disk
== 1)? "is" : "are"));
646 Info(slide
, 0, ((char *)slide
, LoadFarString(MultiPartArchive2
),
647 G
.ecrec
.total_entries_central_dir
,
648 (G
.ecrec
.total_entries_central_dir
== 1) ? "entry" : "entries",
649 G
.ecrec
.size_central_directory
,
650 G
.ecrec
.size_central_directory
));
651 Info(slide
, 0, ((char *)slide
, LoadFarString(MultiPartArchive3
),
652 G
.ecrec
.offset_start_central_directory
,
653 G
.ecrec
.offset_start_central_directory
));
656 /*-----------------------------------------------------------------------
657 Get the zipfile comment, if any, and print it out. (Comment may be
658 up to 64KB long. May the fleas of a thousand camels infest the arm-
659 pits of anyone who actually takes advantage of this fact.)
660 -----------------------------------------------------------------------*/
662 if (!G
.ecrec
.zipfile_comment_length
)
663 Info(slide
, 0, ((char *)slide
, LoadFarString(NoZipfileComment
)));
665 Info(slide
, 0, ((char *)slide
, LoadFarString(ZipfileCommentDesc
),
666 G
.ecrec
.zipfile_comment_length
));
667 Info(slide
, 0, ((char *)slide
, LoadFarString(ZipfileCommBegin
)));
668 if (do_string(__G__ G
.ecrec
.zipfile_comment_length
, DISPLAY
))
670 Info(slide
, 0, ((char *)slide
, LoadFarString(ZipfileCommEnd
)));
672 Info(slide
, 0, ((char *)slide
,
673 LoadFarString(ZipfileCommTrunc2
)));
674 } /* endif (comment exists) */
676 /* non-verbose mode: print zipfile comment only if requested */
677 } else if (uO
.zflag
&& G
.ecrec
.zipfile_comment_length
) {
678 if (do_string(__G__ G
.ecrec
.zipfile_comment_length
, DISPLAY
)) {
679 Info(slide
, 0x401, ((char *)slide
,
680 LoadFarString(ZipfileCommTruncMsg
)));
683 } /* endif (verbose) */
687 } /* end function zi_end_central() */
693 /************************/
694 /* Function zipinfo() */
695 /************************/
697 int zipinfo(__G
) /* return PK-type error code */
700 int do_this_file
=FALSE
, error
, error_in_archive
=PK_COOL
;
701 int *fn_matched
=NULL
, *xn_matched
=NULL
;
703 ulg tot_csize
=0L, tot_ucsize
=0L;
704 ulg endprev
; /* buffers end of previous entry for zi_long()'s check
708 /*---------------------------------------------------------------------------
709 Malloc space for check on unmatched filespecs (no big deal if one or both
711 ---------------------------------------------------------------------------*/
713 if (G
.filespecs
> 0 &&
714 (fn_matched
=(int *)malloc(G
.filespecs
*sizeof(int))) != NULL
)
715 for (j
= 0; j
< G
.filespecs
; ++j
)
716 fn_matched
[j
] = FALSE
;
718 if (G
.xfilespecs
> 0 &&
719 (xn_matched
=(int *)malloc(G
.xfilespecs
*sizeof(int))) != NULL
)
720 for (j
= 0; j
< G
.xfilespecs
; ++j
)
721 xn_matched
[j
] = FALSE
;
723 /*---------------------------------------------------------------------------
724 Set file pointer to start of central directory, then loop through cen-
725 tral directory entries. Check that directory-entry signature bytes are
726 actually there (just a precaution), then process the entry. We know
727 the entire central directory is on this disk: we wouldn't have any of
728 this information unless the end-of-central-directory record was on this
729 disk, and we wouldn't have gotten to this routine unless this is also
730 the disk on which the central directory starts. In practice, this had
731 better be the *only* disk in the archive, but maybe someday we'll add
733 ---------------------------------------------------------------------------*/
735 uO
.L_flag
= FALSE
; /* zipinfo mode: never convert name to lowercase */
736 G
.pInfo
= G
.info
; /* (re-)initialize, (just to make sure) */
737 G
.pInfo
->textmode
= 0; /* so one can read on screen (is this ever used?) */
739 /* reset endprev for new zipfile; account for multi-part archives (?) */
740 endprev
= (G
.crec
.relative_offset_local_header
== 4L)? 4L : 0L;
744 if (readbuf(__G__ G
.sig
, 4) == 0)
746 if (strncmp(G
.sig
, central_hdr_sig
, 4)) { /* is it a CentDir entry? */
747 if (((unsigned)(j
- 1) & (unsigned)0xFFFF) ==
748 (unsigned)G
.ecrec
.total_entries_central_dir
) {
749 /* "j modulus 64k" matches the reported 16-bit-unsigned
750 * number of directory entries -> probably, the regular
751 * end of the central directory has been reached
756 ((char *)slide
, LoadFarString(CentSigMsg
), j
));
758 ((char *)slide
, LoadFarString(ReportMsg
)));
759 return PK_BADERR
; /* sig not found */
762 /* process_cdir_file_hdr() sets pInfo->hostnum, pInfo->lcflag, ...: */
763 if ((error
= process_cdir_file_hdr(__G
)) != PK_COOL
)
764 return error
; /* only PK_EOF defined */
766 if ((error
= do_string(__G__ G
.crec
.filename_length
, DS_FN
)) !=
769 error_in_archive
= error
; /* might be warning */
770 if (error
> PK_WARN
) /* fatal */
774 if (!G
.process_all_files
) { /* check if specified on command line */
777 do_this_file
= FALSE
;
778 for (i
= 0; i
< G
.filespecs
; i
++)
779 if (match(G
.filename
, G
.pfnames
[i
], uO
.C_flag
)) {
782 fn_matched
[i
] = TRUE
;
783 break; /* found match, so stop looping */
785 if (do_this_file
) { /* check if this is an excluded file */
786 for (i
= 0; i
< G
.xfilespecs
; i
++)
787 if (match(G
.filename
, G
.pxnames
[i
], uO
.C_flag
)) {
788 do_this_file
= FALSE
; /* ^-- ignore case in match */
790 xn_matched
[i
] = TRUE
;
796 /*-----------------------------------------------------------------------
797 If current file was specified on command line, or if no names were
798 specified, do the listing for this file. Otherwise, get rid of the
799 file comment and go back for the next file.
800 -----------------------------------------------------------------------*/
802 if (G
.process_all_files
|| do_this_file
) {
808 SKIP_(G
.crec
.extra_field_length
)
809 SKIP_(G
.crec
.file_comment_length
)
815 if ((error
= zi_short(__G
)) != PK_COOL
) {
816 error_in_archive
= error
; /* might be warning */
817 if (error
> PK_WARN
) /* fatal */
823 Info(slide
, 0, ((char *)slide
,
824 LoadFarString(CentralDirEntry
), j
));
825 if ((error
= zi_long(__G__
&endprev
)) != PK_COOL
) {
826 error_in_archive
= error
; /* might be warning */
827 if (error
> PK_WARN
) /* fatal */
833 SKIP_(G
.crec
.extra_field_length
)
834 SKIP_(G
.crec
.file_comment_length
)
837 } /* end switch (lflag) */
839 tot_csize
+= G
.crec
.csize
;
840 tot_ucsize
+= G
.crec
.ucsize
;
841 if (G
.crec
.general_purpose_bit_flag
& 1)
842 tot_csize
-= 12; /* don't count encryption header */
846 if ((G
.statreportcb
!= NULL
) &&
847 (*G
.statreportcb
)(__G__ UZ_ST_FINISH_MEMBER
, G
.zipfn
,
848 G
.filename
, (zvoid
*)&G
.crec
.ucsize
)) {
850 free((zvoid
*)fn_matched
);
852 free((zvoid
*)xn_matched
);
853 return IZ_CTRLC
; /* cancel operation by user request */
856 #ifdef MACOS /* MacOS is no preemptive OS, thus call event-handling by hand */
860 } else { /* not listing this file */
861 SKIP_(G
.crec
.extra_field_length
)
862 SKIP_(G
.crec
.file_comment_length
)
864 } /* end if (list member?) */
866 } /* end for-loop (j: member files) */
868 /*---------------------------------------------------------------------------
869 Check that we actually found requested files; if so, print totals.
870 ---------------------------------------------------------------------------*/
874 int cfactor
= ratio(tot_ucsize
, tot_csize
);
880 Info(slide
, 0, ((char *)slide
, LoadFarString(ZipfileStats
),
881 members
, (members
==1L)? nullStr
:PlurSufx
, tot_ucsize
,
882 tot_csize
, sgn
, cfactor
/10, cfactor
%10));
885 /*---------------------------------------------------------------------------
886 Check for unmatched filespecs on command line and print warning if any
888 ---------------------------------------------------------------------------*/
891 for (j
= 0; j
< G
.filespecs
; ++j
)
893 Info(slide
, 0x401, ((char *)slide
,
894 LoadFarString(FilenameNotMatched
), G
.pfnames
[j
]));
895 free((zvoid
*)fn_matched
);
898 for (j
= 0; j
< G
.xfilespecs
; ++j
)
900 Info(slide
, 0x401, ((char *)slide
,
901 LoadFarString(ExclFilenameNotMatched
), G
.pxnames
[j
]));
902 free((zvoid
*)xn_matched
);
905 /*---------------------------------------------------------------------------
906 Double check that we're back at the end-of-central-directory record.
907 ---------------------------------------------------------------------------*/
909 if (strncmp(G
.sig
, end_central_sig
, 4)) { /* just to make sure again */
910 Info(slide
, 0x401, ((char *)slide
, LoadFarString(EndSigMsg
)));
911 error_in_archive
= PK_WARN
; /* didn't find sig */
913 if (members
== 0 && error_in_archive
<= PK_WARN
)
914 error_in_archive
= PK_FIND
;
917 (*G
.message
)((zvoid
*)&G
, (uch
*)"\n", 1L, 0);
919 return error_in_archive
;
921 } /* end function zipinfo() */
927 /************************/
928 /* Function zi_long() */
929 /************************/
931 static int zi_long(__G__ pEndprev
) /* return PK-type error code */
933 ulg
*pEndprev
; /* for zi_long() check of extra bytes */
935 #ifdef USE_EF_UT_TIME
938 int error
, error_in_archive
=PK_COOL
;
939 unsigned hostnum
, hostver
, extnum
, extver
, methnum
, xattr
;
940 char workspace
[12], attribs
[22];
941 ZCONST
char *varmsg_str
;
943 static ZCONST
char Far
*os
[NUM_HOSTS
] = {
944 OS_FAT
, OS_Amiga
, OS_VMS
, OS_Unix
, OS_VMCMS
, OS_AtariST
, OS_HPFS
,
945 OS_Macintosh
, OS_ZSystem
, OS_CPM
, OS_TOPS20
, OS_NTFS
, OS_QDOS
,
946 OS_Acorn
, OS_VFAT
, OS_MVS
, OS_BeOS
, OS_Tandem
, OS_Theos
948 static ZCONST
char Far
*method
[NUM_METHODS
] = {
949 MthdNone
, MthdShrunk
, MthdRedF1
, MthdRedF2
, MthdRedF3
, MthdRedF4
,
950 MthdImplode
, MthdToken
, MthdDeflate
, MthdDeflat64
, MthdDCLImplode
952 static ZCONST
char Far
*dtypelng
[4] = {
953 DeflNorm
, DeflMax
, DeflFast
, DeflSFast
957 /*---------------------------------------------------------------------------
958 Check whether there's any extra space inside the zipfile. If *pEndprev is
959 zero, it's probably a signal that OS/2 extra fields are involved (with
960 unknown compressed size). We won't worry about prepended junk here...
961 ---------------------------------------------------------------------------*/
963 if (G
.crec
.relative_offset_local_header
!= *pEndprev
&& *pEndprev
> 0L) {
965 Info(slide, 0, ((char *)slide,
966 " [crec.relative_offset_local_header = %lu, endprev = %lu]\n",
967 G.crec.relative_offset_local_header, *pEndprev));
969 Info(slide
, 0, ((char *)slide
, LoadFarString(ExtraBytesPreceding
),
970 (long)G
.crec
.relative_offset_local_header
- (long)(*pEndprev
)));
973 /* calculate endprev for next time around (problem: extra fields may
974 * differ in length between local and central-directory records) */
975 *pEndprev
= G
.crec
.relative_offset_local_header
+ (4L + LREC_SIZE
) +
976 G
.crec
.filename_length
+ G
.crec
.extra_field_length
+ G
.crec
.csize
;
978 /*---------------------------------------------------------------------------
979 Read the extra field, if any. It may be used to get UNIX style modtime.
980 ---------------------------------------------------------------------------*/
982 if ((error
= do_string(__G__ G
.crec
.extra_field_length
, EXTRA_FIELD
)) != 0)
984 if (G
.extra_field
!= NULL
) {
986 G
.extra_field
= NULL
;
988 error_in_archive
= error
;
989 /* The premature return in case of a "fatal" error (PK_EOF) is
990 * delayed until we analyze the extra field contents.
991 * This allows us to display all the other info that has been
992 * successfully read in.
996 /*---------------------------------------------------------------------------
997 Print out various interesting things about the compressed file.
998 ---------------------------------------------------------------------------*/
1000 hostnum
= (unsigned)(G
.pInfo
->hostnum
);
1001 hostver
= (unsigned)(G
.pInfo
->hostver
);
1002 extnum
= (unsigned)MIN(G
.crec
.version_needed_to_extract
[1], NUM_HOSTS
);
1003 extver
= (unsigned)G
.crec
.version_needed_to_extract
[0];
1004 methnum
= (unsigned)MIN(G
.crec
.compression_method
, NUM_METHODS
);
1006 (*G
.message
)((zvoid
*)&G
, (uch
*)" ", 2L, 0); fnprint(__G
);
1008 Info(slide
, 0, ((char *)slide
, LoadFarString(LocalHeaderOffset
),
1009 G
.crec
.relative_offset_local_header
,
1010 G
.crec
.relative_offset_local_header
));
1012 if (hostnum
>= NUM_HOSTS
) {
1013 sprintf(unkn
, LoadFarString(UnknownNo
),
1014 (int)G
.crec
.version_made_by
[1]);
1017 varmsg_str
= LoadFarStringSmall(os
[hostnum
]);
1018 #ifdef OLD_THEOS_EXTRA
1019 if (hostnum
== FS_VFAT_
&& hostver
== 20) {
1020 /* entry made by old non-official THEOS port zip archive */
1021 varmsg_str
= LoadFarStringSmall(OS_TheosOld
);
1023 #endif /* OLD_THEOS_EXTRA */
1025 Info(slide
, 0, ((char *)slide
, LoadFarString(HostOS
), varmsg_str
));
1026 Info(slide
, 0, ((char *)slide
, LoadFarString(EncodeSWVer
), hostver
/10,
1029 if (extnum
>= NUM_HOSTS
) {
1030 sprintf(unkn
, LoadFarString(UnknownNo
),
1031 (int)G
.crec
.version_needed_to_extract
[1]);
1034 varmsg_str
= LoadFarStringSmall(os
[extnum
]);
1036 Info(slide
, 0, ((char *)slide
, LoadFarString(MinOSCompReq
), varmsg_str
));
1037 Info(slide
, 0, ((char *)slide
, LoadFarString(MinSWVerReq
), extver
/10,
1040 if (methnum
>= NUM_METHODS
) {
1041 sprintf(unkn
, LoadFarString(UnknownNo
), G
.crec
.compression_method
);
1044 varmsg_str
= LoadFarStringSmall(method
[methnum
]);
1046 Info(slide
, 0, ((char *)slide
, LoadFarString(CompressMethod
), varmsg_str
));
1047 if (methnum
== IMPLODED
) {
1048 Info(slide
, 0, ((char *)slide
, LoadFarString(SlideWindowSizeImplode
),
1049 (G
.crec
.general_purpose_bit_flag
& 2)? '8' : '4'));
1050 Info(slide
, 0, ((char *)slide
, LoadFarString(ShannonFanoTrees
),
1051 (G
.crec
.general_purpose_bit_flag
& 4)? '3' : '2'));
1052 } else if (methnum
== DEFLATED
|| methnum
== ENHDEFLATED
) {
1053 ush dnum
=(ush
)((G
.crec
.general_purpose_bit_flag
>>1) & 3);
1055 Info(slide
, 0, ((char *)slide
, LoadFarString(CompressSubtype
),
1056 LoadFarStringSmall(dtypelng
[dnum
])));
1059 Info(slide
, 0, ((char *)slide
, LoadFarString(FileSecurity
),
1060 (G
.crec
.general_purpose_bit_flag
& 1) ? nullStr
: "not "));
1061 Info(slide
, 0, ((char *)slide
, LoadFarString(ExtendedLocalHdr
),
1062 (G
.crec
.general_purpose_bit_flag
& 8) ? "yes" : "no"));
1063 /* print upper 3 bits for amusement? */
1065 /* For printing of date & time, a "char d_t_buf[21]" is required.
1066 * To save stack space, we reuse the "char attribs[22]" buffer which
1069 # define d_t_buf attribs
1071 zi_time(__G__
&G
.crec
.last_mod_dos_datetime
, NULL
, d_t_buf
);
1072 Info(slide
, 0, ((char *)slide
, LoadFarString(FileModDate
), d_t_buf
));
1073 #ifdef USE_EF_UT_TIME
1074 if (G
.extra_field
&&
1078 (ef_scan_for_izux(G
.extra_field
, G
.crec
.extra_field_length
, 1,
1079 G
.crec
.last_mod_dos_datetime
, &z_utime
, NULL
)
1082 TIMET_TO_NATIVE(z_utime
.mtime
) /* NOP unless MSC 7.0 or Macintosh */
1083 d_t_buf
[0] = (char)0; /* signal "show local time" */
1084 zi_time(__G__
&G
.crec
.last_mod_dos_datetime
, &(z_utime
.mtime
), d_t_buf
);
1085 Info(slide
, 0, ((char *)slide
, LoadFarString(UT_FileModDate
),
1086 d_t_buf
, LoadFarStringSmall(LocalTime
)));
1088 d_t_buf
[0] = (char)1; /* signal "show UTC (GMT) time" */
1089 zi_time(__G__
&G
.crec
.last_mod_dos_datetime
, &(z_utime
.mtime
), d_t_buf
);
1090 Info(slide
, 0, ((char *)slide
, LoadFarString(UT_FileModDate
),
1091 d_t_buf
, LoadFarStringSmall(GMTime
)));
1092 #endif /* !NO_GMTIME */
1094 #endif /* USE_EF_UT_TIME */
1096 Info(slide
, 0, ((char *)slide
, LoadFarString(CRC32Value
), G
.crec
.crc32
));
1097 Info(slide
, 0, ((char *)slide
, LoadFarString(CompressedFileSize
),
1099 Info(slide
, 0, ((char *)slide
, LoadFarString(UncompressedFileSize
),
1101 Info(slide
, 0, ((char *)slide
, LoadFarString(FilenameLength
),
1102 G
.crec
.filename_length
));
1103 Info(slide
, 0, ((char *)slide
, LoadFarString(ExtraFieldLength
),
1104 G
.crec
.extra_field_length
));
1105 Info(slide
, 0, ((char *)slide
, LoadFarString(FileCommentLength
),
1106 G
.crec
.file_comment_length
));
1107 Info(slide
, 0, ((char *)slide
, LoadFarString(FileDiskNum
),
1108 G
.crec
.disk_number_start
+ 1));
1109 Info(slide
, 0, ((char *)slide
, LoadFarString(ApparentFileType
),
1110 (G
.crec
.internal_file_attributes
& 1)? "text"
1111 : (G
.crec
.internal_file_attributes
& 2)? "ebcdic"
1112 : "binary")); /* changed to accept EBCDIC */
1114 printf(" external file attributes (hex): %.8lx\n",
1115 G
.crec
.external_file_attributes
);
1117 xattr
= (unsigned)((G
.crec
.external_file_attributes
>> 16) & 0xFFFF);
1118 if (hostnum
== VMS_
) {
1119 char *p
=attribs
, *q
=attribs
+1;
1122 for (k
= 0; k
< 12; ++k
)
1124 if (xattr
& VMS_IRUSR
)
1126 if (xattr
& VMS_IWUSR
) {
1130 if (xattr
& VMS_IXUSR
)
1132 if (xattr
& VMS_IRGRP
)
1134 if (xattr
& VMS_IWGRP
) {
1138 if (xattr
& VMS_IXGRP
)
1140 if (xattr
& VMS_IROTH
)
1142 if (xattr
& VMS_IWOTH
) {
1144 workspace
[11] = 'D';
1146 if (xattr
& VMS_IXOTH
)
1147 workspace
[10] = 'E';
1150 for (k
= j
= 0; j
< 3; ++j
) { /* loop over groups of permissions */
1151 for (i
= 0; i
< 4; ++i
, ++k
) /* loop over perms within a group */
1153 *p
++ = workspace
[k
];
1154 *p
++ = ','; /* group separator */
1156 while ((*p
++ = *q
++) != ',')
1157 ; /* system, owner perms are same */
1160 *p
= ')'; /* overwrite last comma */
1161 Info(slide
, 0, ((char *)slide
, LoadFarString(VMSFileAttributes
), xattr
,
1164 } else if (hostnum
== AMIGA_
) {
1165 switch (xattr
& AMI_IFMT
) {
1166 case AMI_IFDIR
: attribs
[0] = 'd'; break;
1167 case AMI_IFREG
: attribs
[0] = '-'; break;
1168 default: attribs
[0] = '?'; break;
1170 attribs
[1] = (xattr
& AMI_IHIDDEN
)? 'h' : '-';
1171 attribs
[2] = (xattr
& AMI_ISCRIPT
)? 's' : '-';
1172 attribs
[3] = (xattr
& AMI_IPURE
)? 'p' : '-';
1173 attribs
[4] = (xattr
& AMI_IARCHIVE
)? 'a' : '-';
1174 attribs
[5] = (xattr
& AMI_IREAD
)? 'r' : '-';
1175 attribs
[6] = (xattr
& AMI_IWRITE
)? 'w' : '-';
1176 attribs
[7] = (xattr
& AMI_IEXECUTE
)? 'e' : '-';
1177 attribs
[8] = (xattr
& AMI_IDELETE
)? 'd' : '-';
1178 attribs
[9] = 0; /* better dlm the string */
1179 Info(slide
, 0, ((char *)slide
, LoadFarString(AmigaFileAttributes
),
1182 } else if (hostnum
== THEOS_
) {
1183 ZCONST
char Far
*fpFtyp
;
1185 switch (xattr
& THS_IFMT
) {
1186 case THS_IFLIB
: fpFtyp
= TheosFTypLib
; break;
1187 case THS_IFDIR
: fpFtyp
= TheosFTypDir
; break;
1188 case THS_IFREG
: fpFtyp
= TheosFTypReg
; break;
1189 case THS_IFREL
: fpFtyp
= TheosFTypRel
; break;
1190 case THS_IFKEY
: fpFtyp
= TheosFTypKey
; break;
1191 case THS_IFIND
: fpFtyp
= TheosFTypInd
; break;
1192 case THS_IFR16
: fpFtyp
= TheosFTypR16
; break;
1193 case THS_IFP16
: fpFtyp
= TheosFTypP16
; break;
1194 case THS_IFP32
: fpFtyp
= TheosFTypP32
; break;
1195 default: fpFtyp
= TheosFTypUkn
; break;
1197 strcpy(attribs
, LoadFarStringSmall(fpFtyp
));
1198 attribs
[12] = (xattr
& THS_INHID
) ? '.' : 'H';
1199 attribs
[13] = (xattr
& THS_IMODF
) ? '.' : 'M';
1200 attribs
[14] = (xattr
& THS_IWOTH
) ? '.' : 'W';
1201 attribs
[15] = (xattr
& THS_IROTH
) ? '.' : 'R';
1202 attribs
[16] = (xattr
& THS_IEUSR
) ? '.' : 'E';
1203 attribs
[17] = (xattr
& THS_IXUSR
) ? '.' : 'X';
1204 attribs
[18] = (xattr
& THS_IWUSR
) ? '.' : 'W';
1205 attribs
[19] = (xattr
& THS_IRUSR
) ? '.' : 'R';
1207 Info(slide
, 0, ((char *)slide
, LoadFarString(TheosFileAttributes
),
1210 #ifdef OLD_THEOS_EXTRA
1211 } else if (hostnum
== FS_VFAT_
&& hostver
== 20) {
1212 /* process old non-official THEOS port zip archive */
1213 ZCONST
char Far
*fpFtyp
;
1215 switch (xattr
& _THS_IFMT
) {
1216 case _THS_IFLIB
: fpFtyp
= TheosFTypLib
; break;
1217 case _THS_IFDIR
: fpFtyp
= TheosFTypDir
; break;
1218 case _THS_IFREG
: fpFtyp
= TheosFTypReg
; break;
1219 case _THS_IODRC
: fpFtyp
= TheosFTypRel
; break;
1220 case _THS_IOKEY
: fpFtyp
= TheosFTypKey
; break;
1221 case _THS_IOIND
: fpFtyp
= TheosFTypInd
; break;
1222 case _THS_IOPRG
: fpFtyp
= TheosFTypR16
; break;
1223 case _THS_IO286
: fpFtyp
= TheosFTypP16
; break;
1224 case _THS_IO386
: fpFtyp
= TheosFTypP32
; break;
1225 default: fpFtyp
= TheosFTypUkn
; break;
1227 strcpy(attribs
, LoadFarStringSmall(fpFtyp
));
1228 attribs
[12] = (xattr
& _THS_HIDDN
) ? 'H' : '.';
1229 attribs
[13] = (xattr
& _THS_IXOTH
) ? '.' : 'X';
1230 attribs
[14] = (xattr
& _THS_IWOTH
) ? '.' : 'W';
1231 attribs
[15] = (xattr
& _THS_IROTH
) ? '.' : 'R';
1232 attribs
[16] = (xattr
& _THS_IEUSR
) ? '.' : 'E';
1233 attribs
[17] = (xattr
& _THS_IXUSR
) ? '.' : 'X';
1234 attribs
[18] = (xattr
& _THS_IWUSR
) ? '.' : 'W';
1235 attribs
[19] = (xattr
& _THS_IRUSR
) ? '.' : 'R';
1237 Info(slide
, 0, ((char *)slide
, LoadFarString(TheosFileAttributes
),
1239 #endif /* OLD_THEOS_EXTRA */
1241 } else if ((hostnum
!= FS_FAT_
) && (hostnum
!= FS_HPFS_
) &&
1242 (hostnum
!= FS_NTFS_
) && (hostnum
!= FS_VFAT_
) &&
1243 (hostnum
!= ACORN_
) &&
1244 (hostnum
!= VM_CMS_
) && (hostnum
!= MVS_
))
1245 { /* assume Unix-like */
1246 switch ((unsigned)(xattr
& UNX_IFMT
)) {
1247 case (unsigned)UNX_IFDIR
: attribs
[0] = 'd'; break;
1248 case (unsigned)UNX_IFREG
: attribs
[0] = '-'; break;
1249 case (unsigned)UNX_IFLNK
: attribs
[0] = 'l'; break;
1250 case (unsigned)UNX_IFBLK
: attribs
[0] = 'b'; break;
1251 case (unsigned)UNX_IFCHR
: attribs
[0] = 'c'; break;
1252 case (unsigned)UNX_IFIFO
: attribs
[0] = 'p'; break;
1253 case (unsigned)UNX_IFSOCK
: attribs
[0] = 's'; break;
1254 default: attribs
[0] = '?'; break;
1256 attribs
[1] = (xattr
& UNX_IRUSR
)? 'r' : '-';
1257 attribs
[4] = (xattr
& UNX_IRGRP
)? 'r' : '-';
1258 attribs
[7] = (xattr
& UNX_IROTH
)? 'r' : '-';
1260 attribs
[2] = (xattr
& UNX_IWUSR
)? 'w' : '-';
1261 attribs
[5] = (xattr
& UNX_IWGRP
)? 'w' : '-';
1262 attribs
[8] = (xattr
& UNX_IWOTH
)? 'w' : '-';
1264 if (xattr
& UNX_IXUSR
)
1265 attribs
[3] = (xattr
& UNX_ISUID
)? 's' : 'x';
1267 attribs
[3] = (xattr
& UNX_ISUID
)? 'S' : '-'; /* S = undefined */
1268 if (xattr
& UNX_IXGRP
)
1269 attribs
[6] = (xattr
& UNX_ISGID
)? 's' : 'x'; /* == UNX_ENFMT */
1271 attribs
[6] = (xattr
& UNX_ISGID
)? 'l' : '-';
1272 if (xattr
& UNX_IXOTH
)
1273 attribs
[9] = (xattr
& UNX_ISVTX
)? 't' : 'x'; /* "sticky bit" */
1275 attribs
[9] = (xattr
& UNX_ISVTX
)? 'T' : '-'; /* T = undefined */
1278 Info(slide
, 0, ((char *)slide
, LoadFarString(UnixFileAttributes
), xattr
,
1282 Info(slide
, 0, ((char *)slide
, LoadFarString(NonMSDOSFileAttributes
),
1283 G
.crec
.external_file_attributes
>> 8));
1285 } /* endif (hostnum: external attributes format) */
1287 if ((xattr
=(unsigned)(G
.crec
.external_file_attributes
& 0xFF)) == 0)
1288 Info(slide
, 0, ((char *)slide
, LoadFarString(MSDOSFileAttributes
),
1290 else if (xattr
== 1)
1291 Info(slide
, 0, ((char *)slide
, LoadFarString(MSDOSFileAttributesRO
),
1294 Info(slide
, 0, ((char *)slide
, LoadFarString(MSDOSFileAttributesAlpha
),
1295 xattr
, (xattr
&1)? "rdo " : nullStr
,
1296 (xattr
&2)? "hid " : nullStr
,
1297 (xattr
&4)? "sys " : nullStr
,
1298 (xattr
&8)? "lab " : nullStr
,
1299 (xattr
&16)? "dir " : nullStr
,
1300 (xattr
&32)? "arc " : nullStr
,
1301 (xattr
&64)? "lnk " : nullStr
,
1302 (xattr
&128)? "exe" : nullStr
));
1304 /*---------------------------------------------------------------------------
1305 Analyze the extra field, if any, and print the file comment, if any (the
1306 filename has already been printed, above). That finishes up this file
1308 ---------------------------------------------------------------------------*/
1310 if (G
.crec
.extra_field_length
> 0) {
1311 uch
*ef_ptr
= G
.extra_field
;
1312 ush ef_len
= G
.crec
.extra_field_length
;
1313 ush eb_id
, eb_datalen
;
1314 ZCONST
char Far
*ef_fieldname
;
1316 if (error_in_archive
> PK_WARN
) /* fatal: can't continue */
1317 /* delayed "fatal error" return from extra field reading */
1319 if (G
.extra_field
== (uch
*)NULL
)
1320 return PK_ERR
; /* not consistent with crec length */
1322 Info(slide
, 0, ((char *)slide
, LoadFarString(ExtraFields
)));
1324 while (ef_len
>= EB_HEADSIZE
) {
1325 eb_id
= makeword(&ef_ptr
[EB_ID
]);
1326 eb_datalen
= makeword(&ef_ptr
[EB_LEN
]);
1327 ef_ptr
+= EB_HEADSIZE
;
1328 ef_len
-= EB_HEADSIZE
;
1330 if (eb_datalen
> (ush
)ef_len
) {
1331 Info(slide
, 0x421, ((char *)slide
,
1332 LoadFarString(ExtraFieldTrunc
), eb_id
, eb_datalen
, ef_len
));
1333 eb_datalen
= ef_len
;
1338 ef_fieldname
= efPKSZ64
;
1341 ef_fieldname
= efAV
;
1344 ef_fieldname
= efOS2
;
1347 ef_fieldname
= efACL
;
1350 ef_fieldname
= efNTSD
;
1353 ef_fieldname
= efPKVMS
;
1356 ef_fieldname
= efIZVMS
;
1359 ef_fieldname
= efPKWin32
;
1362 ef_fieldname
= efPKUnix
;
1365 ef_fieldname
= efIZUnix
;
1366 if (hostnum
== UNIX_
&& *pEndprev
> 0L)
1367 *pEndprev
+= 4L; /* also have UID/GID in local copy */
1370 ef_fieldname
= efIZUnix2
;
1372 *pEndprev
+= 4L; /* 4 byte UID/GID in local copy */
1375 ef_fieldname
= efTime
;
1378 ef_fieldname
= efMac3
;
1381 ef_fieldname
= efJLMac
;
1384 ef_fieldname
= efZipIt
;
1387 ef_fieldname
= efZipIt2
;
1390 ef_fieldname
= efVMCMS
;
1393 ef_fieldname
= efMVS
;
1396 ef_fieldname
= efBeOS
;
1399 ef_fieldname
= efQDOS
;
1402 ef_fieldname
= efAOSVS
;
1404 case EF_SPARK
: /* from RISC OS */
1405 ef_fieldname
= efSpark
;
1408 ef_fieldname
= efMD5
;
1411 ef_fieldname
= efASiUnix
;
1414 ef_fieldname
= efTandem
;
1417 ef_fieldname
= efSmartZip
;
1420 #ifdef OLD_THEOS_EXTRA
1423 ef_fieldname
= efTheos
;
1426 ef_fieldname
= efUnknown
;
1429 Info(slide
, 0, ((char *)slide
, LoadFarString(ExtraFieldType
),
1430 eb_id
, LoadFarStringSmall(ef_fieldname
), eb_datalen
));
1432 /* additional, field-specific information: */
1436 if (eb_datalen
>= EB_OS2_HLEN
) {
1437 if (eb_id
== EF_OS2
)
1438 ef_fieldname
= OS2EAs
;
1440 ef_fieldname
= ACLdata
;
1441 Info(slide
, 0, ((char *)slide
,
1442 LoadFarString(ef_fieldname
), makelong(ef_ptr
)));
1443 *pEndprev
= 0L; /* no clue about csize of local */
1447 if (eb_datalen
>= EB_NTSD_C_LEN
) {
1448 Info(slide
, 0, ((char *)slide
, LoadFarString(NTSDData
),
1450 *pEndprev
= 0L; /* no clue about csize of local */
1454 if (eb_datalen
>= 8) {
1456 unsigned compr
= makeword(ef_ptr
+EB_IZVMS_FLGS
)
1462 if (strncmp((char *)ef_ptr
, "VFAB", 4) == 0)
1464 else if (strncmp((char *)ef_ptr
, "VALL", 4) == 0)
1466 else if (strncmp((char *)ef_ptr
, "VFHC", 4) == 0)
1468 else if (strncmp((char *)ef_ptr
, "VDAT", 4) == 0)
1470 else if (strncmp((char *)ef_ptr
, "VRDT", 4) == 0)
1472 else if (strncmp((char *)ef_ptr
, "VPRO", 4) == 0)
1474 else if (strncmp((char *)ef_ptr
, "VKEY", 4) == 0)
1476 else if (strncmp((char *)ef_ptr
, "VMSV", 4) == 0) {
1478 if (eb_datalen
>= 16) {
1481 strncpy(q
+2, (char *)ef_ptr
+EB_IZVMS_HLEN
, 4);
1487 Info(slide
, 0, ((char *)slide
,
1488 LoadFarString(izVMSdata
),
1489 LoadFarStringSmall(izVMScomp
[compr
]),
1490 makeword(ef_ptr
+EB_IZVMS_UCSIZ
), p
, q
));
1494 if (eb_datalen
>= 1) {
1500 strcpy(types
, LoadFarString(UTmodification
));
1504 len
= strlen(types
);
1507 strcpy(types
+len
, LoadFarString(UTaccess
));
1513 len
= strlen(types
);
1516 strcpy(types
+len
, LoadFarString(UTcreation
));
1522 Info(slide
, 0, ((char *)slide
,
1523 LoadFarString(UTdata
), types
,
1524 num
== 1? nullStr
: PlurSufx
));
1528 if (eb_datalen
>= EB_MAC3_HLEN
) {
1529 ulg eb_uc
= makelong(ef_ptr
);
1530 unsigned mac3_flgs
= makeword(ef_ptr
+EB_FLGS_OFFS
);
1531 unsigned eb_is_uc
= mac3_flgs
& EB_M3_FL_UNCMPR
;
1533 Info(slide
, 0, ((char *)slide
, LoadFarString(Mac3data
),
1534 eb_uc
, eb_is_uc
? "un" : nullStr
));
1537 *pEndprev
+= makelong(ef_ptr
);
1539 *pEndprev
= 0L; /* no clue about csize of local */
1542 Info(slide
, 0, ((char *)slide
,
1543 LoadFarString(MacOSMAC3flags
),
1544 LoadFarStringSmall(mac3_flgs
& EB_M3_FL_DATFRK
?
1545 MacOS_DF
: MacOS_RF
),
1546 (mac3_flgs
& EB_M3_FL_TIME64
? 64 : 32)));
1547 zi_showMacTypeCreator(__G__
&ef_ptr
[6]);
1551 if (eb_datalen
>= 5 &&
1552 strncmp((char *)ef_ptr
, "ZPIT", 4) == 0) {
1554 if (eb_datalen
>= 12) {
1555 zi_showMacTypeCreator(__G__
&ef_ptr
[4]);
1560 if (eb_datalen
>= 5 &&
1561 strncmp((char *)ef_ptr
, "ZPIT", 4) == 0) {
1562 unsigned fnlen
= ef_ptr
[4];
1564 if ((unsigned)eb_datalen
>= fnlen
+ (5 + 8)) {
1565 uch nullchar
= ef_ptr
[fnlen
+5];
1567 ef_ptr
[fnlen
+5] = '\0'; /* terminate filename */
1568 Info(slide
, 0, ((char *)slide
,
1569 LoadFarString(ZipItFname
), (char *)ef_ptr
+5));
1570 ef_ptr
[fnlen
+5] = nullchar
;
1571 zi_showMacTypeCreator(__G__
&ef_ptr
[fnlen
+5]);
1576 if (eb_datalen
>= 40 &&
1577 strncmp((char *)ef_ptr
, "JLEE", 4) == 0)
1579 zi_showMacTypeCreator(__G__
&ef_ptr
[4]);
1581 Info(slide
, 0, ((char *)slide
,
1582 LoadFarString(MacOSJLEEflags
),
1583 LoadFarStringSmall(ef_ptr
[31] & 1 ?
1584 MacOS_DF
: MacOS_RF
)));
1588 if ((eb_datalen
== EB_SMARTZIP_HLEN
) &&
1589 strncmp((char *)ef_ptr
, "dZip", 4) == 0) {
1590 char filenameBuf
[32];
1591 zi_showMacTypeCreator(__G__
&ef_ptr
[4]);
1592 memcpy(filenameBuf
, &ef_ptr
[33], 31);
1593 filenameBuf
[ef_ptr
[32]] = '\0';
1594 Info(slide
, 0, ((char *)slide
,
1595 LoadFarString(ZipItFname
), filenameBuf
));
1604 Info(slide
, 0, ((char *)slide
,
1605 LoadFarString(VmMvsExtraField
),
1606 (getVMMVSexfield(type
, ef_ptr
-EB_HEADSIZE
,
1607 (unsigned)eb_datalen
) > 0)?
1608 type
: LoadFarStringSmall(VmMvsInvalid
)));
1611 #endif /* CMS_MVS */
1613 if (eb_datalen
>= EB_BEOS_HLEN
) {
1614 ulg eb_uc
= makelong(ef_ptr
);
1616 *(ef_ptr
+EB_FLGS_OFFS
) & EB_BE_FL_UNCMPR
;
1618 Info(slide
, 0, ((char *)slide
, LoadFarString(BeOSdata
),
1619 eb_uc
, eb_is_uc
? "un" : nullStr
));
1622 *pEndprev
+= makelong(ef_ptr
);
1624 *pEndprev
= 0L; /* no clue about csize of local */
1629 if (eb_datalen
>= 4) {
1630 Info(slide
, 0, ((char *)slide
, LoadFarString(QDOSdata
),
1631 ef_ptr
[0], ef_ptr
[1], ef_ptr
[2], ef_ptr
[3]));
1635 if (eb_datalen
>= 5) {
1636 Info(slide
, 0, ((char *)slide
, LoadFarString(AOSVSdata
),
1637 ((int)(uch
)ef_ptr
[4])/10, ((int)(uch
)ef_ptr
[4])%10));
1641 if (eb_datalen
== 20) {
1642 unsigned type
, code
;
1644 type
= (ef_ptr
[18] & 0x60) >> 5;
1645 code
= makeword(ef_ptr
);
1646 /* Arrg..., Tandem e.f. uses BigEndian byte-order */
1647 code
= ((code
<< 8) & 0xff00) | ((code
>> 8) & 0x00ff);
1648 if (type
== NSK_UNSTRUCTURED
) {
1649 if (code
== NSK_EDITFILECODE
)
1651 else if (code
== NSK_OBJECTFILECODE
)
1654 Info(slide
, 0, ((char *)slide
,
1655 LoadFarString(Tandemdata
),
1656 LoadFarStringSmall(TandemFileformat
[type
]),
1661 if (eb_datalen
>= 19) {
1665 for (i
= 0; i
< 16; ++i
)
1666 sprintf(&md5
[i
<<1], "%02x", ef_ptr
[15-i
]);
1668 Info(slide
, 0, ((char *)slide
, LoadFarString(MD5data
),
1671 } /* else: fall through !! */
1673 if (eb_datalen
> 0) {
1676 if (eb_datalen
<= 24) {
1677 Info(slide
, 0, ((char *)slide
,
1678 LoadFarString(ColonIndent
)));
1681 Info(slide
, 0, ((char *)slide
,
1682 LoadFarString(First20
)));
1685 for (i
= 0; i
< n
; ++i
)
1686 Info(slide
, 0, ((char *)slide
,
1687 LoadFarString(efFormat
), ef_ptr
[i
]));
1691 (*G
.message
)((zvoid
*)&G
, (uch
*)".", 1L, 0);
1693 ef_ptr
+= eb_datalen
;
1694 ef_len
-= eb_datalen
;
1696 (*G
.message
)((zvoid
*)&G
, (uch
*)"\n", 1L, 0);
1699 /* high bit == Unix/OS2/NT GMT times (mtime, atime); next bit == UID/GID */
1700 if ((xattr
= (unsigned)((G
.crec
.external_file_attributes
& 0xC000) >> 12))
1703 if (hostnum
== UNIX_
|| hostnum
== FS_HPFS_
|| hostnum
== FS_NTFS_
)
1705 Info(slide
, 0, ((char *)slide
, LoadFarString(lExtraFieldType
),
1706 "is", EF_IZUNIX
, LoadFarStringSmall(efIZUnix
),
1707 (unsigned)(xattr
&12), (xattr
&4)? efIZuid
: efIZnouid
));
1709 *pEndprev
+= (ulg
)(xattr
&12);
1711 else if (hostnum
== FS_FAT_
&& !(xattr
&4))
1712 Info(slide
, 0, ((char *)slide
, LoadFarString(lExtraFieldType
),
1713 "may be", EF_IZUNIX
, LoadFarStringSmall(efIZUnix
), 8,
1717 if (!G
.crec
.file_comment_length
)
1718 Info(slide
, 0, ((char *)slide
, LoadFarString(NoFileComment
)));
1720 Info(slide
, 0, ((char *)slide
, LoadFarString(FileCommBegin
)));
1721 if ((error
= do_string(__G__ G
.crec
.file_comment_length
, DISPL_8
)) !=
1724 error_in_archive
= error
; /* might be warning */
1725 if (error
> PK_WARN
) /* fatal */
1728 Info(slide
, 0, ((char *)slide
, LoadFarString(FileCommEnd
)));
1731 return error_in_archive
;
1733 } /* end function zi_long() */
1739 /*************************/
1740 /* Function zi_short() */
1741 /*************************/
1743 static int zi_short(__G
) /* return PK-type error code */
1746 #ifdef USE_EF_UT_TIME
1750 int k
, error
, error_in_archive
=PK_COOL
;
1751 unsigned hostnum
, hostver
, methnum
, xattr
;
1752 char *p
, workspace
[12], attribs
[16];
1754 static ZCONST
char dtype
[5]="NXFS"; /* normal, maximum, fast, superfast */
1755 static ZCONST
char Far os
[NUM_HOSTS
+1][4] = {
1756 "fat", "ami", "vms", "unx", "cms", "atr", "hpf", "mac", "zzz",
1757 "cpm", "t20", "ntf", "qds", "aco", "vft", "mvs", "be ", "nsk",
1760 #ifdef OLD_THEOS_EXTRA
1761 static ZCONST
char Far os_TheosOld
[] = "tho";
1763 static ZCONST
char Far method
[NUM_METHODS
+1][5] = {
1764 "stor", "shrk", "re:1", "re:2", "re:3", "re:4", "i#:#", "tokn",
1765 "def#", "d64#", "dcli", "u###"
1769 /*---------------------------------------------------------------------------
1770 Print out various interesting things about the compressed file.
1771 ---------------------------------------------------------------------------*/
1773 methnum
= (unsigned)MIN(G
.crec
.compression_method
, NUM_METHODS
);
1774 hostnum
= (unsigned)(G
.pInfo
->hostnum
);
1775 hostver
= (unsigned)(G
.pInfo
->hostver
);
1777 extnum = (unsigned)MIN(G.crec.version_needed_to_extract[1], NUM_HOSTS);
1778 extver = (unsigned)G.crec.version_needed_to_extract[0];
1781 zfstrcpy(methbuf
, method
[methnum
]);
1782 if (methnum
== IMPLODED
) {
1783 methbuf
[1] = (char)((G
.crec
.general_purpose_bit_flag
& 2)? '8' : '4');
1784 methbuf
[3] = (char)((G
.crec
.general_purpose_bit_flag
& 4)? '3' : '2');
1785 } else if (methnum
== DEFLATED
|| methnum
== ENHDEFLATED
) {
1786 ush dnum
=(ush
)((G
.crec
.general_purpose_bit_flag
>>1) & 3);
1787 methbuf
[3] = dtype
[dnum
];
1788 } else if (methnum
>= NUM_METHODS
) { /* unknown */
1789 sprintf(&methbuf
[1], "%03u", G
.crec
.compression_method
);
1792 for (k
= 0; k
< 15; ++k
)
1796 xattr
= (unsigned)((G
.crec
.external_file_attributes
>> 16) & 0xFFFF);
1801 for (k
= 0; k
< 12; ++k
)
1803 if (xattr
& VMS_IRUSR
)
1805 if (xattr
& VMS_IWUSR
) {
1809 if (xattr
& VMS_IXUSR
)
1811 if (xattr
& VMS_IRGRP
)
1813 if (xattr
& VMS_IWGRP
) {
1817 if (xattr
& VMS_IXGRP
)
1819 if (xattr
& VMS_IROTH
)
1821 if (xattr
& VMS_IWOTH
) {
1823 workspace
[11] = 'D';
1825 if (xattr
& VMS_IXOTH
)
1826 workspace
[10] = 'E';
1829 for (k
= j
= 0; j
< 3; ++j
) { /* groups of permissions */
1830 for (i
= 0; i
< 4; ++i
, ++k
) /* perms within a group */
1832 *p
++ = workspace
[k
];
1833 *p
++ = ','; /* group separator */
1835 *--p
= ' '; /* overwrite last comma */
1836 if ((p
- attribs
) < 12)
1837 sprintf(&attribs
[12], "%u.%u", hostver
/10, hostver
%10);
1842 switch (xattr
& AMI_IFMT
) {
1843 case AMI_IFDIR
: attribs
[0] = 'd'; break;
1844 case AMI_IFREG
: attribs
[0] = '-'; break;
1845 default: attribs
[0] = '?'; break;
1847 attribs
[1] = (xattr
& AMI_IHIDDEN
)? 'h' : '-';
1848 attribs
[2] = (xattr
& AMI_ISCRIPT
)? 's' : '-';
1849 attribs
[3] = (xattr
& AMI_IPURE
)? 'p' : '-';
1850 attribs
[4] = (xattr
& AMI_IARCHIVE
)? 'a' : '-';
1851 attribs
[5] = (xattr
& AMI_IREAD
)? 'r' : '-';
1852 attribs
[6] = (xattr
& AMI_IWRITE
)? 'w' : '-';
1853 attribs
[7] = (xattr
& AMI_IEXECUTE
)? 'e' : '-';
1854 attribs
[8] = (xattr
& AMI_IDELETE
)? 'd' : '-';
1855 sprintf(&attribs
[12], "%u.%u", hostver
/10, hostver
%10);
1859 switch (xattr
& THS_IFMT
) {
1860 case THS_IFLIB
: *attribs
= 'L'; break;
1861 case THS_IFDIR
: *attribs
= 'D'; break;
1862 case THS_IFCHR
: *attribs
= 'C'; break;
1863 case THS_IFREG
: *attribs
= 'S'; break;
1864 case THS_IFREL
: *attribs
= 'R'; break;
1865 case THS_IFKEY
: *attribs
= 'K'; break;
1866 case THS_IFIND
: *attribs
= 'I'; break;
1867 case THS_IFR16
: *attribs
= 'P'; break;
1868 case THS_IFP16
: *attribs
= '2'; break;
1869 case THS_IFP32
: *attribs
= '3'; break;
1870 default: *attribs
= '?'; break;
1872 attribs
[1] = (xattr
& THS_INHID
) ? '.' : 'H';
1873 attribs
[2] = (xattr
& THS_IMODF
) ? '.' : 'M';
1874 attribs
[3] = (xattr
& THS_IWOTH
) ? '.' : 'W';
1875 attribs
[4] = (xattr
& THS_IROTH
) ? '.' : 'R';
1876 attribs
[5] = (xattr
& THS_IEUSR
) ? '.' : 'E';
1877 attribs
[6] = (xattr
& THS_IXUSR
) ? '.' : 'X';
1878 attribs
[7] = (xattr
& THS_IWUSR
) ? '.' : 'W';
1879 attribs
[8] = (xattr
& THS_IRUSR
) ? '.' : 'R';
1880 sprintf(&attribs
[12], "%u.%u", hostver
/10, hostver
%10);
1884 #ifdef OLD_THEOS_EXTRA
1885 if (hostver
== 20) {
1886 switch (xattr
& _THS_IFMT
) {
1887 case _THS_IFLIB
: *attribs
= 'L'; break;
1888 case _THS_IFDIR
: *attribs
= 'd'; break;
1889 case _THS_IFCHR
: *attribs
= 'c'; break;
1890 case _THS_IFREG
: *attribs
= 'S'; break;
1891 case _THS_IODRC
: *attribs
= 'D'; break;
1892 case _THS_IOKEY
: *attribs
= 'K'; break;
1893 case _THS_IOIND
: *attribs
= 'I'; break;
1894 case _THS_IOPRG
: *attribs
= 'P'; break;
1895 case _THS_IO286
: *attribs
= '2'; break;
1896 case _THS_IO386
: *attribs
= '3'; break;
1897 default: *attribs
= '?'; break;
1899 attribs
[1] = (xattr
& _THS_HIDDN
) ? 'H' : '.';
1900 attribs
[2] = (xattr
& _THS_IXOTH
) ? '.' : 'X';
1901 attribs
[3] = (xattr
& _THS_IWOTH
) ? '.' : 'W';
1902 attribs
[4] = (xattr
& _THS_IROTH
) ? '.' : 'R';
1903 attribs
[5] = (xattr
& _THS_IEUSR
) ? '.' : 'E';
1904 attribs
[6] = (xattr
& _THS_IXUSR
) ? '.' : 'X';
1905 attribs
[7] = (xattr
& _THS_IWUSR
) ? '.' : 'W';
1906 attribs
[8] = (xattr
& _THS_IRUSR
) ? '.' : 'R';
1907 sprintf(&attribs
[12], "%u.%u", hostver
/10, hostver
%10);
1909 } /* else: fall through! */
1910 #endif /* OLD_THEOS_EXTRA */
1918 if (hostnum
!= FS_FAT_
||
1919 (unsigned)(xattr
& 0700) !=
1921 ((unsigned)!(G
.crec
.external_file_attributes
& 1) << 7) |
1922 ((unsigned)(G
.crec
.external_file_attributes
& 0x10) << 2))
1925 xattr
= (unsigned)(G
.crec
.external_file_attributes
& 0xFF);
1926 sprintf(attribs
, ".r.-... %u.%u", hostver
/10, hostver
%10);
1927 attribs
[2] = (xattr
& 0x01)? '-' : 'w';
1928 attribs
[5] = (xattr
& 0x02)? 'h' : '-';
1929 attribs
[6] = (xattr
& 0x04)? 's' : '-';
1930 attribs
[4] = (xattr
& 0x20)? 'a' : '-';
1936 if (IS_VOLID(xattr
))
1938 else if ((p
= MBSRCHR(G
.filename
, '.')) != (char *)NULL
) {
1940 if (STRNICMP(p
, "com", 3) == 0 ||
1941 STRNICMP(p
, "exe", 3) == 0 ||
1942 STRNICMP(p
, "btm", 3) == 0 ||
1943 STRNICMP(p
, "cmd", 3) == 0 ||
1944 STRNICMP(p
, "bat", 3) == 0)
1948 } /* else: fall through! */
1950 default: /* assume Unix-like */
1951 switch ((unsigned)(xattr
& UNX_IFMT
)) {
1952 case (unsigned)UNX_IFDIR
: attribs
[0] = 'd'; break;
1953 case (unsigned)UNX_IFREG
: attribs
[0] = '-'; break;
1954 case (unsigned)UNX_IFLNK
: attribs
[0] = 'l'; break;
1955 case (unsigned)UNX_IFBLK
: attribs
[0] = 'b'; break;
1956 case (unsigned)UNX_IFCHR
: attribs
[0] = 'c'; break;
1957 case (unsigned)UNX_IFIFO
: attribs
[0] = 'p'; break;
1958 case (unsigned)UNX_IFSOCK
: attribs
[0] = 's'; break;
1959 default: attribs
[0] = '?'; break;
1961 attribs
[1] = (xattr
& UNX_IRUSR
)? 'r' : '-';
1962 attribs
[4] = (xattr
& UNX_IRGRP
)? 'r' : '-';
1963 attribs
[7] = (xattr
& UNX_IROTH
)? 'r' : '-';
1964 attribs
[2] = (xattr
& UNX_IWUSR
)? 'w' : '-';
1965 attribs
[5] = (xattr
& UNX_IWGRP
)? 'w' : '-';
1966 attribs
[8] = (xattr
& UNX_IWOTH
)? 'w' : '-';
1968 if (xattr
& UNX_IXUSR
)
1969 attribs
[3] = (xattr
& UNX_ISUID
)? 's' : 'x';
1971 attribs
[3] = (xattr
& UNX_ISUID
)? 'S' : '-'; /* S==undefined */
1972 if (xattr
& UNX_IXGRP
)
1973 attribs
[6] = (xattr
& UNX_ISGID
)? 's' : 'x'; /* == UNX_ENFMT */
1975 /* attribs[6] = (xattr & UNX_ISGID)? 'l' : '-'; real 4.3BSD */
1976 attribs
[6] = (xattr
& UNX_ISGID
)? 'S' : '-'; /* SunOS 4.1.x */
1977 if (xattr
& UNX_IXOTH
)
1978 attribs
[9] = (xattr
& UNX_ISVTX
)? 't' : 'x'; /* "sticky bit" */
1980 attribs
[9] = (xattr
& UNX_ISVTX
)? 'T' : '-'; /* T==undefined */
1982 sprintf(&attribs
[12], "%u.%u", hostver
/10, hostver
%10);
1985 } /* end switch (hostnum: external attributes format) */
1987 #ifdef OLD_THEOS_EXTRA
1988 Info(slide
, 0, ((char *)slide
, "%s %s %8lu ", attribs
,
1989 LoadFarStringSmall(((hostnum
== FS_VFAT_
&& hostver
== 20) ?
1994 Info(slide
, 0, ((char *)slide
, "%s %s %8lu ", attribs
,
1995 LoadFarStringSmall(os
[hostnum
]),
1998 Info(slide
, 0, ((char *)slide
, "%c",
1999 (G
.crec
.general_purpose_bit_flag
& 1)?
2000 ((G
.crec
.internal_file_attributes
& 1)? 'T' : 'B') : /* encrypted */
2001 ((G
.crec
.internal_file_attributes
& 1)? 't' : 'b'))); /* plaintext */
2002 k
= (G
.crec
.extra_field_length
||
2003 /* a local-only "UX" (old Unix/OS2/NT GMT times "IZUNIX") e.f.? */
2004 ((G
.crec
.external_file_attributes
& 0x8000) &&
2005 (hostnum
== UNIX_
|| hostnum
== FS_HPFS_
|| hostnum
== FS_NTFS_
)));
2006 Info(slide
, 0, ((char *)slide
, "%c", k
?
2007 ((G
.crec
.general_purpose_bit_flag
& 8)? 'X' : 'x') : /* extra field */
2008 ((G
.crec
.general_purpose_bit_flag
& 8)? 'l' : '-'))); /* no extra field */
2009 /* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ extended local header or not */
2011 if (uO
.lflag
== 4) {
2012 ulg csiz
= G
.crec
.csize
;
2014 if (G
.crec
.general_purpose_bit_flag
& 1)
2015 csiz
-= 12; /* if encrypted, don't count encryption header */
2016 Info(slide
, 0, ((char *)slide
, "%3d%%",
2017 (ratio(G
.crec
.ucsize
,csiz
)+5)/10));
2018 } else if (uO
.lflag
== 5)
2019 Info(slide
, 0, ((char *)slide
, " %8lu", G
.crec
.csize
));
2021 /* Read the extra field, if any. The extra field info may be used
2022 * in the file modification time section, below.
2024 if ((error
= do_string(__G__ G
.crec
.extra_field_length
, EXTRA_FIELD
)) != 0)
2026 if (G
.extra_field
!= NULL
) {
2027 free(G
.extra_field
);
2028 G
.extra_field
= NULL
;
2030 error_in_archive
= error
;
2031 /* We do not return prematurely in case of a "fatal" error (PK_EOF).
2032 * This does not hurt here, because we do not need to read from the
2033 * zipfile again before the end of this function.
2037 /* For printing of date & time, a "char d_t_buf[16]" is required.
2038 * To save stack space, we reuse the "char attribs[16]" buffer whose
2039 * content is no longer needed.
2041 # define d_t_buf attribs
2042 #ifdef USE_EF_UT_TIME
2043 z_modtim
= G
.extra_field
&&
2047 (ef_scan_for_izux(G
.extra_field
, G
.crec
.extra_field_length
, 1,
2048 G
.crec
.last_mod_dos_datetime
, &z_utime
, NULL
)
2050 ? &z_utime
.mtime
: NULL
;
2051 TIMET_TO_NATIVE(z_utime
.mtime
) /* NOP unless MSC 7.0 or Macintosh */
2052 d_t_buf
[0] = (char)0; /* signal "show local time" */
2054 # define z_modtim NULL
2056 Info(slide
, 0, ((char *)slide
, " %s %s ", methbuf
,
2057 zi_time(__G__
&G
.crec
.last_mod_dos_datetime
, z_modtim
, d_t_buf
)));
2060 /*---------------------------------------------------------------------------
2061 Skip the file comment, if any (the filename has already been printed,
2062 above). That finishes up this file entry...
2063 ---------------------------------------------------------------------------*/
2065 SKIP_(G
.crec
.file_comment_length
)
2067 return error_in_archive
;
2069 } /* end function zi_short() */
2075 /**************************************/
2076 /* Function zi_showMacTypeCreator() */
2077 /**************************************/
2079 static void zi_showMacTypeCreator(__G__ ebfield
)
2083 /* not every Type / Creator character is printable */
2084 if (isprint(ebfield
[0]) && isprint(ebfield
[1]) &&
2085 isprint(ebfield
[2]) && isprint(ebfield
[3]) &&
2086 isprint(ebfield
[4]) && isprint(ebfield
[5]) &&
2087 isprint(ebfield
[6]) && isprint(ebfield
[7])) {
2088 Info(slide
, 0, ((char *)slide
, LoadFarString(MacOSdata
),
2089 ebfield
[0], ebfield
[1], ebfield
[2], ebfield
[3],
2090 ebfield
[4], ebfield
[5], ebfield
[6], ebfield
[7]));
2092 Info(slide
, 0, ((char *)slide
, LoadFarString(MacOSdata1
),
2093 (((ulg
)ebfield
[0]) << 24) +
2094 (((ulg
)ebfield
[1]) << 16) +
2095 (((ulg
)ebfield
[2]) << 8) +
2097 (((ulg
)ebfield
[4]) << 24) +
2098 (((ulg
)ebfield
[5]) << 16) +
2099 (((ulg
)ebfield
[6]) << 8) +
2100 ((ulg
)ebfield
[7])));
2102 } /* end function zi_showMacTypeCreator() */
2108 /************************/
2109 /* Function zi_time() */
2110 /************************/
2112 static char *zi_time(__G__ datetimez
, modtimez
, d_t_str
)
2114 ZCONST ulg
*datetimez
;
2115 ZCONST
time_t *modtimez
;
2118 unsigned yr
, mo
, dy
, hh
, mm
, ss
;
2120 ZCONST
char *monthstr
;
2121 static ZCONST
char Far month
[12][4] = {
2122 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
2123 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
2125 #ifdef USE_EF_UT_TIME
2131 /*---------------------------------------------------------------------------
2132 Convert the file-modification date and time info to a string of the form
2133 "1991 Feb 23 17:15:00", "23-Feb-91 17:15" or "19910223.171500", depending
2134 on values of lflag and T_flag. If using Unix-time extra fields, convert
2135 to local time or not, depending on value of first character in d_t_str[].
2136 ---------------------------------------------------------------------------*/
2138 #ifdef USE_EF_UT_TIME
2139 if (modtimez
!= NULL
) {
2141 /* check for our secret message from above... */
2142 t
= (d_t_str
[0] == (char)1)? gmtime(modtimez
) : localtime(modtimez
);
2144 t
= localtime(modtimez
);
2146 if (uO
.lflag
> 9 && t
== (struct tm
*)NULL
)
2147 /* time conversion error in verbose listing format,
2148 * return string with '?' instead of data
2150 return (strcpy(d_t_str
, LoadFarString(YMDHMSTimeError
)));
2152 t
= (struct tm
*)NULL
;
2153 if (t
!= (struct tm
*)NULL
) {
2154 mo
= (unsigned)(t
->tm_mon
+ 1);
2155 dy
= (unsigned)(t
->tm_mday
);
2156 yr
= (unsigned)(t
->tm_year
);
2158 hh
= (unsigned)(t
->tm_hour
);
2159 mm
= (unsigned)(t
->tm_min
);
2160 ss
= (unsigned)(t
->tm_sec
);
2162 #endif /* USE_EF_UT_TIME */
2164 yr
= ((unsigned)(*datetimez
>> 25) & 0x7f) + 80;
2165 mo
= ((unsigned)(*datetimez
>> 21) & 0x0f);
2166 dy
= ((unsigned)(*datetimez
>> 16) & 0x1f);
2168 hh
= (((unsigned)*datetimez
>> 11) & 0x1f);
2169 mm
= (((unsigned)*datetimez
>> 5) & 0x3f);
2170 ss
= (((unsigned)*datetimez
<< 1) & 0x3e);
2173 if (mo
== 0 || mo
> 12) {
2174 sprintf(monthbuf
, LoadFarString(BogusFmt
), mo
);
2175 monthstr
= monthbuf
;
2177 monthstr
= LoadFarStringSmall(month
[mo
-1]);
2179 if (uO
.lflag
> 9) /* verbose listing format */
2180 sprintf(d_t_str
, LoadFarString(YMDHMSTime
), yr
+1900, monthstr
, dy
, hh
,
2183 sprintf(d_t_str
, LoadFarString(DecimalTime
), yr
+1900, mo
, dy
, hh
, mm
,
2185 else /* was: if ((uO.lflag >= 3) && (uO.lflag <= 5)) */
2186 sprintf(d_t_str
, LoadFarString(DMYHMTime
), dy
, monthstr
, yr
%100, hh
,
2191 } /* end function zi_time() */
2193 #endif /* !NO_ZIPINFO */