vfs: check userland buffers before reading them.
[haiku.git] / src / bin / unzip / zipinfo.c
blob2ea5c9dd6a054b32c245952b8b13de784398b7c4
1 /*
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
8 */
9 /*---------------------------------------------------------------------------
11 zipinfo.c Greg Roelofs et al.
13 This file contains all of the ZipInfo-specific listing routines for UnZip.
15 Contains: zi_opts()
16 zi_end_central()
17 zipinfo()
18 zi_long()
19 zi_short()
20 zi_time()
22 ---------------------------------------------------------------------------*/
25 #define UNZIP_INTERNAL
26 #include "unzip.h"
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"
109 #endif
111 #ifndef NSK_UNSTRUCTURED
112 # define NSK_UNSTRUCTURED 0
113 #endif
114 #ifndef NSK_OBJECTFILECODE
115 # define NSK_OBJECTFILECODE 100
116 #endif
117 #ifndef NSK_EDITFILECODE
118 # define NSK_EDITFILECODE 101
119 #endif
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";
251 #ifndef NO_GMTIME
252 static ZCONST char Far GMTime[] = "UTC";
253 #endif
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\
359 finder attributes";
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";
389 #ifdef CMS_MVS
390 static ZCONST char Far VmMvsExtraField[] = ".\n\
391 The stored file open mode (FLDATA TYPE) is \"%s\"";
392 static ZCONST char Far VmMvsInvalid[] = "[invalid]";
393 #endif /* CMS_MVS */
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[] = "???? ??? ?? ??:??:??";
420 #endif
426 #ifndef WINDLL
428 /************************/
429 /* Function zi_opts() */
430 /************************/
432 int zi_opts(__G__ pargc, pargv)
433 int *pargc;
434 char ***pargv;
435 __GDEF
437 char **argv, *s;
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;
444 #ifdef MACOS
445 uO.lflag = LFLAG; /* reset default on each call */
446 #endif
447 G.extract_flag = FALSE; /* zipinfo does not extract to disk */
448 argc = *pargc;
449 argv = *pargv;
451 while (--argc > 0 && (*++argv)[0] == '-') {
452 s = argv[0] + 1;
453 while ((c = *s++) != 0) { /* "!= 0": prevent Turbo C warning */
454 switch (c) {
455 case '-':
456 ++negative;
457 break;
458 case '1': /* shortest listing: JUST filenames */
459 if (negative)
460 uO.lflag = -2, negative = 0;
461 else
462 uO.lflag = 1;
463 break;
464 case '2': /* just filenames, plus headers if specified */
465 if (negative)
466 uO.lflag = -2, negative = 0;
467 else
468 uO.lflag = 2;
469 break;
470 #ifndef CMS_MVS
471 case ('C'): /* -C: match filenames case-insensitively */
472 if (negative)
473 uO.C_flag = FALSE, negative = 0;
474 else
475 uO.C_flag = TRUE;
476 break;
477 #endif /* !CMS_MVS */
478 case 'h': /* header line */
479 if (negative)
480 hflag_2 = hflag_slmv = FALSE, negative = 0;
481 else {
482 hflag_2 = hflag_slmv = explicit_h = TRUE;
483 if (uO.lflag == -1)
484 uO.lflag = 0;
486 break;
487 case 'l': /* longer form of "ls -l" type listing */
488 if (negative)
489 uO.lflag = -2, negative = 0;
490 else
491 uO.lflag = 5;
492 break;
493 case 'm': /* medium form of "ls -l" type listing */
494 if (negative)
495 uO.lflag = -2, negative = 0;
496 else
497 uO.lflag = 4;
498 break;
499 #ifdef MORE
500 case 'M': /* send output through built-in "more" */
501 if (negative)
502 G.M_flag = FALSE, negative = 0;
503 else
504 G.M_flag = TRUE;
505 break;
506 #endif
507 case 's': /* default: shorter "ls -l" type listing */
508 if (negative)
509 uO.lflag = -2, negative = 0;
510 else
511 uO.lflag = 3;
512 break;
513 case 't': /* totals line */
514 if (negative)
515 tflag_2v = tflag_slm = FALSE, negative = 0;
516 else {
517 tflag_2v = tflag_slm = explicit_t = TRUE;
518 if (uO.lflag == -1)
519 uO.lflag = 0;
521 break;
522 case ('T'): /* use (sortable) decimal time format */
523 if (negative)
524 uO.T_flag = FALSE, negative = 0;
525 else
526 uO.T_flag = TRUE;
527 break;
528 case 'v': /* turbo-verbose listing */
529 if (negative)
530 uO.lflag = -2, negative = 0;
531 else
532 uO.lflag = 10;
533 break;
534 case 'z': /* print zipfile comment */
535 if (negative)
536 uO.zflag = negative = 0;
537 else
538 uO.zflag = 1;
539 break;
540 case 'Z': /* ZipInfo mode: ignore */
541 break;
542 default:
543 error = TRUE;
544 break;
548 if ((argc-- == 0) || error) {
549 *pargc = argc;
550 *pargv = argv;
551 return USAGE(error);
554 #ifdef MORE
555 if (G.M_flag && !isatty(1)) /* stdout redirected: "more" func useless */
556 G.M_flag = 0;
557 #endif
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)))
562 uO.lflag = LFLAG;
564 /* set header and totals flags to default or specified values */
565 switch (uO.lflag) {
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 */
568 uO.hflag = hflag_2;
569 uO.tflag = tflag_2v;
570 break;
571 case 1: /* only filenames, *always* */
572 uO.hflag = FALSE;
573 uO.tflag = FALSE;
574 uO.zflag = FALSE;
575 break;
576 case 3:
577 case 4:
578 case 5:
579 uO.hflag = ((argc > 0) && !explicit_h)? FALSE : hflag_slmv;
580 uO.tflag = ((argc > 0) && !explicit_t)? FALSE : tflag_slm;
581 break;
582 case 10:
583 uO.hflag = hflag_slmv;
584 uO.tflag = tflag_2v;
585 break;
588 *pargc = argc;
589 *pargv = argv;
590 return 0;
592 } /* end function zi_opts() */
594 #endif /* !WINDLL */
600 /*******************************/
601 /* Function zi_end_central() */
602 /*******************************/
604 int zi_end_central(__G) /* return PK-type error code */
605 __GDEF
607 int error = PK_COOL;
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: */
615 if (uO.hflag)
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));
622 /* verbose format */
623 if (uO.lflag > 9) {
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));
640 } else {
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)));
664 else {
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))
669 error = PK_WARN;
670 Info(slide, 0, ((char *)slide, LoadFarString(ZipfileCommEnd)));
671 if (error)
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)));
681 error = PK_WARN;
683 } /* endif (verbose) */
685 return error;
687 } /* end function zi_end_central() */
693 /************************/
694 /* Function zipinfo() */
695 /************************/
697 int zipinfo(__G) /* return PK-type error code */
698 __GDEF
700 int do_this_file=FALSE, error, error_in_archive=PK_COOL;
701 int *fn_matched=NULL, *xn_matched=NULL;
702 ulg j, members=0L;
703 ulg tot_csize=0L, tot_ucsize=0L;
704 ulg endprev; /* buffers end of previous entry for zi_long()'s check
705 * of extra bytes */
708 /*---------------------------------------------------------------------------
709 Malloc space for check on unmatched filespecs (no big deal if one or both
710 are NULL).
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
732 multi-disk support.
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;
743 for (j = 1L;; j++) {
744 if (readbuf(__G__ G.sig, 4) == 0)
745 return PK_EOF;
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
753 break;
754 } else {
755 Info(slide, 0x401,
756 ((char *)slide, LoadFarString(CentSigMsg), j));
757 Info(slide, 0x401,
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)) !=
767 PK_COOL)
769 error_in_archive = error; /* might be warning */
770 if (error > PK_WARN) /* fatal */
771 return error;
774 if (!G.process_all_files) { /* check if specified on command line */
775 unsigned i;
777 do_this_file = FALSE;
778 for (i = 0; i < G.filespecs; i++)
779 if (match(G.filename, G.pfnames[i], uO.C_flag)) {
780 do_this_file = TRUE;
781 if (fn_matched)
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 */
789 if (xn_matched)
790 xn_matched[i] = TRUE;
791 break;
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) {
804 switch (uO.lflag) {
805 case 1:
806 case 2:
807 fnprint(__G);
808 SKIP_(G.crec.extra_field_length)
809 SKIP_(G.crec.file_comment_length)
810 break;
812 case 3:
813 case 4:
814 case 5:
815 if ((error = zi_short(__G)) != PK_COOL) {
816 error_in_archive = error; /* might be warning */
817 if (error > PK_WARN) /* fatal */
818 return error;
820 break;
822 case 10:
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 */
828 return error;
830 break;
832 default:
833 SKIP_(G.crec.extra_field_length)
834 SKIP_(G.crec.file_comment_length)
835 break;
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 */
843 ++members;
845 #ifdef DLL
846 if ((G.statreportcb != NULL) &&
847 (*G.statreportcb)(__G__ UZ_ST_FINISH_MEMBER, G.zipfn,
848 G.filename, (zvoid *)&G.crec.ucsize)) {
849 if (fn_matched)
850 free((zvoid *)fn_matched);
851 if (xn_matched)
852 free((zvoid *)xn_matched);
853 return IZ_CTRLC; /* cancel operation by user request */
855 #endif
856 #ifdef MACOS /* MacOS is no preemptive OS, thus call event-handling by hand */
857 UserStop();
858 #endif
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 ---------------------------------------------------------------------------*/
872 if (uO.tflag) {
873 char *sgn = "";
874 int cfactor = ratio(tot_ucsize, tot_csize);
876 if (cfactor < 0) {
877 sgn = "-";
878 cfactor = -cfactor;
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
887 found.
888 ---------------------------------------------------------------------------*/
890 if (fn_matched) {
891 for (j = 0; j < G.filespecs; ++j)
892 if (!fn_matched[j])
893 Info(slide, 0x401, ((char *)slide,
894 LoadFarString(FilenameNotMatched), G.pfnames[j]));
895 free((zvoid *)fn_matched);
897 if (xn_matched) {
898 for (j = 0; j < G.xfilespecs; ++j)
899 if (!xn_matched[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;
916 if (uO.lflag >= 10)
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 */
932 __GDEF
933 ulg *pEndprev; /* for zi_long() check of extra bytes */
935 #ifdef USE_EF_UT_TIME
936 iztimes z_utime;
937 #endif
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;
942 char unkn[16];
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) {
964 /* GRR DEBUG
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) {
985 free(G.extra_field);
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]);
1015 varmsg_str = unkn;
1016 } else {
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,
1027 hostver%10));
1029 if (extnum >= NUM_HOSTS) {
1030 sprintf(unkn, LoadFarString(UnknownNo),
1031 (int)G.crec.version_needed_to_extract[1]);
1032 varmsg_str = unkn;
1033 } else {
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,
1038 extver%10));
1040 if (methnum >= NUM_METHODS) {
1041 sprintf(unkn, LoadFarString(UnknownNo), G.crec.compression_method);
1042 varmsg_str = unkn;
1043 } else {
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
1067 * is not used yet.
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 &&
1075 #ifdef IZ_CHECK_TZ
1076 G.tz_is_valid &&
1077 #endif
1078 (ef_scan_for_izux(G.extra_field, G.crec.extra_field_length, 1,
1079 G.crec.last_mod_dos_datetime, &z_utime, NULL)
1080 & EB_UT_FL_MTIME))
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)));
1087 #ifndef NO_GMTIME
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),
1098 G.crec.csize));
1099 Info(slide, 0, ((char *)slide, LoadFarString(UncompressedFileSize),
1100 G.crec.ucsize));
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 */
1113 #ifdef ATARI
1114 printf(" external file attributes (hex): %.8lx\n",
1115 G.crec.external_file_attributes);
1116 #endif
1117 xattr = (unsigned)((G.crec.external_file_attributes >> 16) & 0xFFFF);
1118 if (hostnum == VMS_) {
1119 char *p=attribs, *q=attribs+1;
1120 int i, j, k;
1122 for (k = 0; k < 12; ++k)
1123 workspace[k] = 0;
1124 if (xattr & VMS_IRUSR)
1125 workspace[0] = 'R';
1126 if (xattr & VMS_IWUSR) {
1127 workspace[1] = 'W';
1128 workspace[3] = 'D';
1130 if (xattr & VMS_IXUSR)
1131 workspace[2] = 'E';
1132 if (xattr & VMS_IRGRP)
1133 workspace[4] = 'R';
1134 if (xattr & VMS_IWGRP) {
1135 workspace[5] = 'W';
1136 workspace[7] = 'D';
1138 if (xattr & VMS_IXGRP)
1139 workspace[6] = 'E';
1140 if (xattr & VMS_IROTH)
1141 workspace[8] = 'R';
1142 if (xattr & VMS_IWOTH) {
1143 workspace[9] = 'W';
1144 workspace[11] = 'D';
1146 if (xattr & VMS_IXOTH)
1147 workspace[10] = 'E';
1149 *p++ = '(';
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 */
1152 if (workspace[k])
1153 *p++ = workspace[k];
1154 *p++ = ','; /* group separator */
1155 if (j == 0)
1156 while ((*p++ = *q++) != ',')
1157 ; /* system, owner perms are same */
1159 *p-- = '\0';
1160 *p = ')'; /* overwrite last comma */
1161 Info(slide, 0, ((char *)slide, LoadFarString(VMSFileAttributes), xattr,
1162 attribs));
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),
1180 xattr, attribs));
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';
1206 attribs[20] = 0;
1207 Info(slide, 0, ((char *)slide, LoadFarString(TheosFileAttributes),
1208 xattr, attribs));
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';
1236 attribs[20] = 0;
1237 Info(slide, 0, ((char *)slide, LoadFarString(TheosFileAttributes),
1238 xattr, attribs));
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';
1266 else
1267 attribs[3] = (xattr & UNX_ISUID)? 'S' : '-'; /* S = undefined */
1268 if (xattr & UNX_IXGRP)
1269 attribs[6] = (xattr & UNX_ISGID)? 's' : 'x'; /* == UNX_ENFMT */
1270 else
1271 attribs[6] = (xattr & UNX_ISGID)? 'l' : '-';
1272 if (xattr & UNX_IXOTH)
1273 attribs[9] = (xattr & UNX_ISVTX)? 't' : 'x'; /* "sticky bit" */
1274 else
1275 attribs[9] = (xattr & UNX_ISVTX)? 'T' : '-'; /* T = undefined */
1276 attribs[10] = 0;
1278 Info(slide, 0, ((char *)slide, LoadFarString(UnixFileAttributes), xattr,
1279 attribs));
1281 } else {
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),
1289 xattr));
1290 else if (xattr == 1)
1291 Info(slide, 0, ((char *)slide, LoadFarString(MSDOSFileAttributesRO),
1292 xattr));
1293 else
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
1307 entry...
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 */
1318 return error;
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;
1336 switch (eb_id) {
1337 case EF_PKSZ64:
1338 ef_fieldname = efPKSZ64;
1339 break;
1340 case EF_AV:
1341 ef_fieldname = efAV;
1342 break;
1343 case EF_OS2:
1344 ef_fieldname = efOS2;
1345 break;
1346 case EF_ACL:
1347 ef_fieldname = efACL;
1348 break;
1349 case EF_NTSD:
1350 ef_fieldname = efNTSD;
1351 break;
1352 case EF_PKVMS:
1353 ef_fieldname = efPKVMS;
1354 break;
1355 case EF_IZVMS:
1356 ef_fieldname = efIZVMS;
1357 break;
1358 case EF_PKW32:
1359 ef_fieldname = efPKWin32;
1360 break;
1361 case EF_PKUNIX:
1362 ef_fieldname = efPKUnix;
1363 break;
1364 case EF_IZUNIX:
1365 ef_fieldname = efIZUnix;
1366 if (hostnum == UNIX_ && *pEndprev > 0L)
1367 *pEndprev += 4L; /* also have UID/GID in local copy */
1368 break;
1369 case EF_IZUNIX2:
1370 ef_fieldname = efIZUnix2;
1371 if (*pEndprev > 0L)
1372 *pEndprev += 4L; /* 4 byte UID/GID in local copy */
1373 break;
1374 case EF_TIME:
1375 ef_fieldname = efTime;
1376 break;
1377 case EF_MAC3:
1378 ef_fieldname = efMac3;
1379 break;
1380 case EF_JLMAC:
1381 ef_fieldname = efJLMac;
1382 break;
1383 case EF_ZIPIT:
1384 ef_fieldname = efZipIt;
1385 break;
1386 case EF_ZIPIT2:
1387 ef_fieldname = efZipIt2;
1388 break;
1389 case EF_VMCMS:
1390 ef_fieldname = efVMCMS;
1391 break;
1392 case EF_MVS:
1393 ef_fieldname = efMVS;
1394 break;
1395 case EF_BEOS:
1396 ef_fieldname = efBeOS;
1397 break;
1398 case EF_QDOS:
1399 ef_fieldname = efQDOS;
1400 break;
1401 case EF_AOSVS:
1402 ef_fieldname = efAOSVS;
1403 break;
1404 case EF_SPARK: /* from RISC OS */
1405 ef_fieldname = efSpark;
1406 break;
1407 case EF_MD5:
1408 ef_fieldname = efMD5;
1409 break;
1410 case EF_ASIUNIX:
1411 ef_fieldname = efASiUnix;
1412 break;
1413 case EF_TANDEM:
1414 ef_fieldname = efTandem;
1415 break;
1416 case EF_SMARTZIP:
1417 ef_fieldname = efSmartZip;
1418 break;
1419 case EF_THEOS:
1420 #ifdef OLD_THEOS_EXTRA
1421 case EF_THEOSO:
1422 #endif
1423 ef_fieldname = efTheos;
1424 break;
1425 default:
1426 ef_fieldname = efUnknown;
1427 break;
1429 Info(slide, 0, ((char *)slide, LoadFarString(ExtraFieldType),
1430 eb_id, LoadFarStringSmall(ef_fieldname), eb_datalen));
1432 /* additional, field-specific information: */
1433 switch (eb_id) {
1434 case EF_OS2:
1435 case EF_ACL:
1436 if (eb_datalen >= EB_OS2_HLEN) {
1437 if (eb_id == EF_OS2)
1438 ef_fieldname = OS2EAs;
1439 else
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 */
1445 break;
1446 case EF_NTSD:
1447 if (eb_datalen >= EB_NTSD_C_LEN) {
1448 Info(slide, 0, ((char *)slide, LoadFarString(NTSDData),
1449 makelong(ef_ptr)));
1450 *pEndprev = 0L; /* no clue about csize of local */
1452 break;
1453 case EF_IZVMS:
1454 if (eb_datalen >= 8) {
1455 char *p, q[8];
1456 unsigned compr = makeword(ef_ptr+EB_IZVMS_FLGS)
1457 & EB_IZVMS_BCMASK;
1459 *q = '\0';
1460 if (compr > 3)
1461 compr = 3;
1462 if (strncmp((char *)ef_ptr, "VFAB", 4) == 0)
1463 p = "FAB";
1464 else if (strncmp((char *)ef_ptr, "VALL", 4) == 0)
1465 p = "XABALL";
1466 else if (strncmp((char *)ef_ptr, "VFHC", 4) == 0)
1467 p = "XABFHC";
1468 else if (strncmp((char *)ef_ptr, "VDAT", 4) == 0)
1469 p = "XABDAT";
1470 else if (strncmp((char *)ef_ptr, "VRDT", 4) == 0)
1471 p = "XABRDT";
1472 else if (strncmp((char *)ef_ptr, "VPRO", 4) == 0)
1473 p = "XABPRO";
1474 else if (strncmp((char *)ef_ptr, "VKEY", 4) == 0)
1475 p = "XABKEY";
1476 else if (strncmp((char *)ef_ptr, "VMSV", 4) == 0) {
1477 p = "version";
1478 if (eb_datalen >= 16) {
1479 q[0] = ' ';
1480 q[1] = '(';
1481 strncpy(q+2, (char *)ef_ptr+EB_IZVMS_HLEN, 4);
1482 q[6] = ')';
1483 q[7] = '\0';
1485 } else
1486 p = "unknown";
1487 Info(slide, 0, ((char *)slide,
1488 LoadFarString(izVMSdata),
1489 LoadFarStringSmall(izVMScomp[compr]),
1490 makeword(ef_ptr+EB_IZVMS_UCSIZ), p, q));
1492 break;
1493 case EF_TIME:
1494 if (eb_datalen >= 1) {
1495 char types[80];
1496 int num = 0, len;
1498 *types = '\0';
1499 if (*ef_ptr & 1) {
1500 strcpy(types, LoadFarString(UTmodification));
1501 ++num;
1503 if (*ef_ptr & 2) {
1504 len = strlen(types);
1505 if (num)
1506 types[len++] = '/';
1507 strcpy(types+len, LoadFarString(UTaccess));
1508 ++num;
1509 if (*pEndprev > 0L)
1510 *pEndprev += 4L;
1512 if (*ef_ptr & 4) {
1513 len = strlen(types);
1514 if (num)
1515 types[len++] = '/';
1516 strcpy(types+len, LoadFarString(UTcreation));
1517 ++num;
1518 if (*pEndprev > 0L)
1519 *pEndprev += 4L;
1521 if (num > 0)
1522 Info(slide, 0, ((char *)slide,
1523 LoadFarString(UTdata), types,
1524 num == 1? nullStr : PlurSufx));
1526 break;
1527 case EF_MAC3:
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));
1535 if (eb_is_uc) {
1536 if (*pEndprev > 0L)
1537 *pEndprev += makelong(ef_ptr);
1538 } else {
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]);
1549 break;
1550 case EF_ZIPIT2:
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]);
1558 break;
1559 case EF_ZIPIT:
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]);
1574 break;
1575 case EF_JLMAC:
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)));
1586 break;
1587 case EF_SMARTZIP:
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));
1597 break;
1598 #ifdef CMS_MVS
1599 case EF_VMCMS:
1600 case EF_MVS:
1602 char type[100];
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)));
1610 break;
1611 #endif /* CMS_MVS */
1612 case EF_BEOS:
1613 if (eb_datalen >= EB_BEOS_HLEN) {
1614 ulg eb_uc = makelong(ef_ptr);
1615 unsigned eb_is_uc =
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));
1620 if (eb_is_uc) {
1621 if (*pEndprev > 0L)
1622 *pEndprev += makelong(ef_ptr);
1623 } else {
1624 *pEndprev = 0L; /* no clue about csize of local */
1627 break;
1628 case EF_QDOS:
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]));
1633 break;
1634 case EF_AOSVS:
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));
1639 break;
1640 case EF_TANDEM:
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)
1650 type = 4;
1651 else if (code == NSK_OBJECTFILECODE)
1652 type = 5;
1654 Info(slide, 0, ((char *)slide,
1655 LoadFarString(Tandemdata),
1656 LoadFarStringSmall(TandemFileformat[type]),
1657 code));
1659 break;
1660 case EF_MD5:
1661 if (eb_datalen >= 19) {
1662 char md5[33];
1663 int i;
1665 for (i = 0; i < 16; ++i)
1666 sprintf(&md5[i<<1], "%02x", ef_ptr[15-i]);
1667 md5[32] = '\0';
1668 Info(slide, 0, ((char *)slide, LoadFarString(MD5data),
1669 md5));
1670 break;
1671 } /* else: fall through !! */
1672 default:
1673 if (eb_datalen > 0) {
1674 ush i, n;
1676 if (eb_datalen <= 24) {
1677 Info(slide, 0, ((char *)slide,
1678 LoadFarString(ColonIndent)));
1679 n = eb_datalen;
1680 } else {
1681 Info(slide, 0, ((char *)slide,
1682 LoadFarString(First20)));
1683 n = 20;
1685 for (i = 0; i < n; ++i)
1686 Info(slide, 0, ((char *)slide,
1687 LoadFarString(efFormat), ef_ptr[i]));
1689 break;
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))
1701 & 8)
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));
1708 if (*pEndprev > 0L)
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,
1714 efIZnouid));
1717 if (!G.crec.file_comment_length)
1718 Info(slide, 0, ((char *)slide, LoadFarString(NoFileComment)));
1719 else {
1720 Info(slide, 0, ((char *)slide, LoadFarString(FileCommBegin)));
1721 if ((error = do_string(__G__ G.crec.file_comment_length, DISPL_8)) !=
1722 PK_COOL)
1724 error_in_archive = error; /* might be warning */
1725 if (error > PK_WARN) /* fatal */
1726 return error;
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 */
1744 __GDEF
1746 #ifdef USE_EF_UT_TIME
1747 iztimes z_utime;
1748 time_t *z_modtim;
1749 #endif
1750 int k, error, error_in_archive=PK_COOL;
1751 unsigned hostnum, hostver, methnum, xattr;
1752 char *p, workspace[12], attribs[16];
1753 char methbuf[5];
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",
1758 "ths", "???"
1760 #ifdef OLD_THEOS_EXTRA
1761 static ZCONST char Far os_TheosOld[] = "tho";
1762 #endif
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)
1793 attribs[k] = ' ';
1794 attribs[15] = 0;
1796 xattr = (unsigned)((G.crec.external_file_attributes >> 16) & 0xFFFF);
1797 switch (hostnum) {
1798 case VMS_:
1799 { int i, j;
1801 for (k = 0; k < 12; ++k)
1802 workspace[k] = 0;
1803 if (xattr & VMS_IRUSR)
1804 workspace[0] = 'R';
1805 if (xattr & VMS_IWUSR) {
1806 workspace[1] = 'W';
1807 workspace[3] = 'D';
1809 if (xattr & VMS_IXUSR)
1810 workspace[2] = 'E';
1811 if (xattr & VMS_IRGRP)
1812 workspace[4] = 'R';
1813 if (xattr & VMS_IWGRP) {
1814 workspace[5] = 'W';
1815 workspace[7] = 'D';
1817 if (xattr & VMS_IXGRP)
1818 workspace[6] = 'E';
1819 if (xattr & VMS_IROTH)
1820 workspace[8] = 'R';
1821 if (xattr & VMS_IWOTH) {
1822 workspace[9] = 'W';
1823 workspace[11] = 'D';
1825 if (xattr & VMS_IXOTH)
1826 workspace[10] = 'E';
1828 p = attribs;
1829 for (k = j = 0; j < 3; ++j) { /* groups of permissions */
1830 for (i = 0; i < 4; ++i, ++k) /* perms within a group */
1831 if (workspace[k])
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);
1839 break;
1841 case AMIGA_:
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);
1856 break;
1858 case THEOS_:
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);
1881 break;
1883 case FS_VFAT_:
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);
1908 break;
1909 } /* else: fall through! */
1910 #endif /* OLD_THEOS_EXTRA */
1912 case FS_FAT_:
1913 case FS_HPFS_:
1914 case FS_NTFS_:
1915 case VM_CMS_:
1916 case MVS_:
1917 case ACORN_:
1918 if (hostnum != FS_FAT_ ||
1919 (unsigned)(xattr & 0700) !=
1920 ((unsigned)0400 |
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' : '-';
1931 if (xattr & 0x10) {
1932 attribs[0] = 'd';
1933 attribs[3] = 'x';
1934 } else
1935 attribs[0] = '-';
1936 if (IS_VOLID(xattr))
1937 attribs[0] = 'V';
1938 else if ((p = MBSRCHR(G.filename, '.')) != (char *)NULL) {
1939 ++p;
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)
1945 attribs[3] = 'x';
1947 break;
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';
1970 else
1971 attribs[3] = (xattr & UNX_ISUID)? 'S' : '-'; /* S==undefined */
1972 if (xattr & UNX_IXGRP)
1973 attribs[6] = (xattr & UNX_ISGID)? 's' : 'x'; /* == UNX_ENFMT */
1974 else
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" */
1979 else
1980 attribs[9] = (xattr & UNX_ISVTX)? 'T' : '-'; /* T==undefined */
1982 sprintf(&attribs[12], "%u.%u", hostver/10, hostver%10);
1983 break;
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) ?
1990 os_TheosOld :
1991 os[hostnum])),
1992 G.crec.ucsize));
1993 #else
1994 Info(slide, 0, ((char *)slide, "%s %s %8lu ", attribs,
1995 LoadFarStringSmall(os[hostnum]),
1996 G.crec.ucsize));
1997 #endif
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 &&
2044 #ifdef IZ_CHECK_TZ
2045 G.tz_is_valid &&
2046 #endif
2047 (ef_scan_for_izux(G.extra_field, G.crec.extra_field_length, 1,
2048 G.crec.last_mod_dos_datetime, &z_utime, NULL)
2049 & EB_UT_FL_MTIME)
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" */
2053 #else
2054 # define z_modtim NULL
2055 #endif
2056 Info(slide, 0, ((char *)slide, " %s %s ", methbuf,
2057 zi_time(__G__ &G.crec.last_mod_dos_datetime, z_modtim, d_t_buf)));
2058 fnprint(__G);
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)
2080 __GDEF
2081 uch *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]));
2091 } else {
2092 Info(slide, 0, ((char *)slide, LoadFarString(MacOSdata1),
2093 (((ulg)ebfield[0]) << 24) +
2094 (((ulg)ebfield[1]) << 16) +
2095 (((ulg)ebfield[2]) << 8) +
2096 ((ulg)ebfield[3]),
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)
2113 __GDEF
2114 ZCONST ulg *datetimez;
2115 ZCONST time_t *modtimez;
2116 char *d_t_str;
2118 unsigned yr, mo, dy, hh, mm, ss;
2119 char monthbuf[4];
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
2126 struct tm *t;
2127 #endif
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) {
2140 #ifndef NO_GMTIME
2141 /* check for our secret message from above... */
2142 t = (d_t_str[0] == (char)1)? gmtime(modtimez) : localtime(modtimez);
2143 #else
2144 t = localtime(modtimez);
2145 #endif
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)));
2151 } else
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);
2161 } else
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;
2176 } else
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,
2181 mm, ss);
2182 else if (uO.T_flag)
2183 sprintf(d_t_str, LoadFarString(DecimalTime), yr+1900, mo, dy, hh, mm,
2184 ss);
2185 else /* was: if ((uO.lflag >= 3) && (uO.lflag <= 5)) */
2186 sprintf(d_t_str, LoadFarString(DMYHMTime), dy, monthstr, yr%100, hh,
2187 mm);
2189 return d_t_str;
2191 } /* end function zi_time() */
2193 #endif /* !NO_ZIPINFO */