]>
Commit | Line | Data |
---|---|---|
1 | /*--------------------------------------------------------------------------- | |
2 | ||
3 | zipinfo.c Greg Roelofs et al. | |
4 | ||
5 | This file contains all of the ZipInfo-specific listing routines for UnZip. | |
6 | ||
7 | Contains: zi_opts() | |
8 | zi_end_central() | |
9 | zipinfo() | |
10 | zi_long() | |
11 | zi_short() | |
12 | zi_time() | |
13 | ||
14 | ---------------------------------------------------------------------------*/ | |
15 | ||
16 | ||
17 | #define UNZIP_INTERNAL | |
18 | #include "unzip.h" | |
19 | ||
20 | ||
21 | #ifndef NO_ZIPINFO /* strings use up too much space in small-memory systems */ | |
22 | ||
23 | /* Define OS-specific attributes for use on ALL platforms--the S_xxxx | |
24 | * versions of these are defined differently (or not defined) by different | |
25 | * compilers and operating systems. */ | |
26 | ||
27 | #define UNX_IFMT 0170000 /* Unix file type mask */ | |
28 | #define UNX_IFDIR 0040000 /* Unix directory */ | |
29 | #define UNX_IFREG 0100000 /* Unix regular file */ | |
30 | #define UNX_IFSOCK 0140000 /* Unix socket (BSD, not SysV or Amiga) */ | |
31 | #define UNX_IFLNK 0120000 /* Unix symbolic link (not SysV, Amiga) */ | |
32 | #define UNX_IFBLK 0060000 /* Unix block special (not Amiga) */ | |
33 | #define UNX_IFCHR 0020000 /* Unix character special (not Amiga) */ | |
34 | #define UNX_IFIFO 0010000 /* Unix fifo (BCC, not MSC or Amiga) */ | |
35 | #define UNX_ISUID 04000 /* Unix set user id on execution */ | |
36 | #define UNX_ISGID 02000 /* Unix set group id on execution */ | |
37 | #define UNX_ISVTX 01000 /* Unix directory permissions control */ | |
38 | #define UNX_ENFMT UNX_ISGID /* Unix record locking enforcement flag */ | |
39 | #define UNX_IRWXU 00700 /* Unix read, write, execute: owner */ | |
40 | #define UNX_IRUSR 00400 /* Unix read permission: owner */ | |
41 | #define UNX_IWUSR 00200 /* Unix write permission: owner */ | |
42 | #define UNX_IXUSR 00100 /* Unix execute permission: owner */ | |
43 | #define UNX_IRWXG 00070 /* Unix read, write, execute: group */ | |
44 | #define UNX_IRGRP 00040 /* Unix read permission: group */ | |
45 | #define UNX_IWGRP 00020 /* Unix write permission: group */ | |
46 | #define UNX_IXGRP 00010 /* Unix execute permission: group */ | |
47 | #define UNX_IRWXO 00007 /* Unix read, write, execute: other */ | |
48 | #define UNX_IROTH 00004 /* Unix read permission: other */ | |
49 | #define UNX_IWOTH 00002 /* Unix write permission: other */ | |
50 | #define UNX_IXOTH 00001 /* Unix execute permission: other */ | |
51 | ||
52 | #define VMS_IRUSR UNX_IRUSR /* VMS read/owner */ | |
53 | #define VMS_IWUSR UNX_IWUSR /* VMS write/owner */ | |
54 | #define VMS_IXUSR UNX_IXUSR /* VMS execute/owner */ | |
55 | #define VMS_IRGRP UNX_IRGRP /* VMS read/group */ | |
56 | #define VMS_IWGRP UNX_IWGRP /* VMS write/group */ | |
57 | #define VMS_IXGRP UNX_IXGRP /* VMS execute/group */ | |
58 | #define VMS_IROTH UNX_IROTH /* VMS read/other */ | |
59 | #define VMS_IWOTH UNX_IWOTH /* VMS write/other */ | |
60 | #define VMS_IXOTH UNX_IXOTH /* VMS execute/other */ | |
61 | ||
62 | #define AMI_IFMT 06000 /* Amiga file type mask */ | |
63 | #define AMI_IFDIR 04000 /* Amiga directory */ | |
64 | #define AMI_IFREG 02000 /* Amiga regular file */ | |
65 | #define AMI_IHIDDEN 00200 /* to be supported in AmigaDOS 3.x */ | |
66 | #define AMI_ISCRIPT 00100 /* executable script (text command file) */ | |
67 | #define AMI_IPURE 00040 /* allow loading into resident memory */ | |
68 | #define AMI_IARCHIVE 00020 /* not modified since bit was last set */ | |
69 | #define AMI_IREAD 00010 /* can be opened for reading */ | |
70 | #define AMI_IWRITE 00004 /* can be opened for writing */ | |
71 | #define AMI_IEXECUTE 00002 /* executable image, a loadable runfile */ | |
72 | #define AMI_IDELETE 00001 /* can be deleted */ | |
73 | ||
74 | #define LFLAG 3 /* short "ls -l" type listing */ | |
75 | ||
76 | static int zi_long OF((__GPRO__ ulg *pEndprev)); | |
77 | static int zi_short OF((__GPRO)); | |
78 | static void zi_showMacTypeCreator | |
79 | OF((__GPRO__ uch *ebfield)); | |
80 | static char *zi_time OF((__GPRO__ ZCONST ulg *datetimez, | |
81 | ZCONST time_t *modtimez, char *d_t_str)); | |
82 | ||
83 | ||
84 | /**********************************************/ | |
85 | /* Strings used in zipinfo.c (ZipInfo half) */ | |
86 | /**********************************************/ | |
87 | ||
88 | static char nullStr[] = ""; | |
89 | ||
90 | static ZCONST char Far LongHeader[] = "Archive: %s %ld bytes %d file%s\n"; | |
91 | static ZCONST char Far ShortHeader[] = "Archive: %s %ld %d\n"; | |
92 | static ZCONST char Far EndCentDirRec[] = "\nEnd-of-central-directory record:\n"; | |
93 | static ZCONST char Far LineSeparators[] = "-------------------------------\n\n"; | |
94 | static ZCONST char Far ActOffsetCentDir[] = "\ | |
95 | Actual offset of end-of-central-dir record: %9ld (%.8lXh)\n\ | |
96 | Expected offset of end-of-central-dir record: %9ld (%.8lXh)\n\ | |
97 | (based on the length of the central directory and its expected offset)\n\n"; | |
98 | static ZCONST char Far SinglePartArchive1[] = "\ | |
99 | This zipfile constitutes the sole disk of a single-part archive; its\n\ | |
100 | central directory contains %u %s. The central directory is %lu\n\ | |
101 | (%.8lXh) bytes long, and its (expected) offset in bytes from the\n"; | |
102 | static ZCONST char Far SinglePartArchive2[] = "\ | |
103 | beginning of the zipfile is %lu (%.8lXh).\n\n"; | |
104 | static ZCONST char Far MultiPartArchive1[] = "\ | |
105 | This zipfile constitutes disk %u of a multi-part archive. The central\n\ | |
106 | directory starts on disk %u; %u of its entries %s contained within\n"; | |
107 | static ZCONST char Far MultiPartArchive2[] = "\ | |
108 | this zipfile, out of a total of %u %s. The entire central\n\ | |
109 | directory is %lu (%.8lXh) bytes long, and its offset in bytes from\n"; | |
110 | static ZCONST char Far MultiPartArchive3[] = "\ | |
111 | the beginning of the zipfile in which it begins is %lu (%.8lXh).\n\n"; | |
112 | static ZCONST char Far NoZipfileComment[] = " There is no zipfile comment.\n"; | |
113 | static ZCONST char Far ZipfileCommentDesc[] = | |
114 | " The zipfile comment is %u bytes long and contains the following text:\n\n"; | |
115 | static ZCONST char Far ZipfileCommBegin[] = | |
116 | "======================== zipfile comment begins ==========================\n"; | |
117 | static ZCONST char Far ZipfileCommEnd[] = | |
118 | "========================= zipfile comment ends ===========================\n"; | |
119 | static ZCONST char Far ZipfileCommTrunc2[] = "\n The zipfile comment is truncated.\n"; | |
120 | static ZCONST char Far ZipfileCommTruncMsg[] = | |
121 | "\ncaution: zipfile comment truncated\n"; | |
122 | ||
123 | static ZCONST char Far CentralDirEntry[] = | |
124 | "\nCentral directory entry #%d:\n---------------------------\n\n"; | |
125 | static ZCONST char Far ZipfileStats[] = | |
126 | "%d file%s, %lu bytes uncompressed, %lu bytes compressed: %s%d.%d%%\n"; | |
127 | ||
128 | /* zi_long() strings */ | |
129 | static ZCONST char Far OS_FAT[] = "MS-DOS, OS/2 or NT FAT"; | |
130 | static ZCONST char Far OS_Amiga[] = "Amiga"; | |
131 | static ZCONST char Far OS_VMS[] = "VMS"; | |
132 | static ZCONST char Far OS_Unix[] = "Unix"; | |
133 | static ZCONST char Far OS_VMCMS[] = "VM/CMS"; | |
134 | static ZCONST char Far OS_AtariST[] = "Atari ST"; | |
135 | static ZCONST char Far OS_HPFS[] = "OS/2 or NT HPFS"; | |
136 | static ZCONST char Far OS_Macintosh[] = "Macintosh HFS"; | |
137 | static ZCONST char Far OS_ZSystem[] = "Z-System"; | |
138 | static ZCONST char Far OS_CPM[] = "CP/M"; | |
139 | static ZCONST char Far OS_TOPS20[] = "TOPS-20"; | |
140 | static ZCONST char Far OS_NTFS[] = "NTFS"; | |
141 | static ZCONST char Far OS_QDOS[] = "SMS/QDOS"; | |
142 | static ZCONST char Far OS_Acorn[] = "Acorn RISC OS"; | |
143 | static ZCONST char Far OS_MVS[] = "MVS"; | |
144 | static ZCONST char Far OS_VFAT[] = "Win32 VFAT"; | |
145 | static ZCONST char Far OS_BeOS[] = "BeOS"; | |
146 | static ZCONST char Far OS_Tandem[] = "Tandem NSK"; | |
147 | ||
148 | static ZCONST char Far MthdNone[] = "none (stored)"; | |
149 | static ZCONST char Far MthdShrunk[] = "shrunk"; | |
150 | static ZCONST char Far MthdRedF1[] = "reduced (factor 1)"; | |
151 | static ZCONST char Far MthdRedF2[] = "reduced (factor 2)"; | |
152 | static ZCONST char Far MthdRedF3[] = "reduced (factor 3)"; | |
153 | static ZCONST char Far MthdRedF4[] = "reduced (factor 4)"; | |
154 | static ZCONST char Far MthdImplode[] = "imploded"; | |
155 | static ZCONST char Far MthdToken[] = "tokenized"; | |
156 | static ZCONST char Far MthdDeflate[] = "deflated"; | |
157 | static ZCONST char Far MthdEnDeflate[] = "deflated (enhanced)"; | |
158 | static ZCONST char Far MthdDCLImplode[] = "imploded (PK DCL)"; | |
159 | ||
160 | static ZCONST char Far DeflNorm[] = "normal"; | |
161 | static ZCONST char Far DeflMax[] = "maximum"; | |
162 | static ZCONST char Far DeflFast[] = "fast"; | |
163 | static ZCONST char Far DeflSFast[] = "superfast"; | |
164 | ||
165 | static ZCONST char Far ExtraBytesPreceding[] = | |
166 | " There are an extra %ld bytes preceding this file.\n\n"; | |
167 | ||
168 | static ZCONST char Far UnknownNo[] = "unknown (%d)"; | |
169 | ||
170 | static ZCONST char Far LocalHeaderOffset[] = | |
171 | "\n offset of local header from start of archive: %lu (%.8lXh) bytes\n"; | |
172 | static ZCONST char Far HostOS[] = | |
173 | " file system or operating system of origin: %s\n"; | |
174 | static ZCONST char Far EncodeSWVer[] = | |
175 | " version of encoding software: %d.%d\n"; | |
176 | static ZCONST char Far MinOSCompReq[] = | |
177 | " minimum file system compatibility required: %s\n"; | |
178 | static ZCONST char Far MinSWVerReq[] = | |
179 | " minimum software version required to extract: %d.%d\n"; | |
180 | static ZCONST char Far CompressMethod[] = | |
181 | " compression method: %s\n"; | |
182 | static ZCONST char Far SlideWindowSizeImplode[] = | |
183 | " size of sliding dictionary (implosion): %cK\n"; | |
184 | static ZCONST char Far ShannonFanoTrees[] = | |
185 | " number of Shannon-Fano trees (implosion): %c\n"; | |
186 | static ZCONST char Far CompressSubtype[] = | |
187 | " compression sub-type (deflation): %s\n"; | |
188 | static ZCONST char Far FileSecurity[] = | |
189 | " file security status: %sencrypted\n"; | |
190 | static ZCONST char Far ExtendedLocalHdr[] = | |
191 | " extended local header: %s\n"; | |
192 | static ZCONST char Far FileModDate[] = | |
193 | " file last modified on (DOS date/time): %s\n"; | |
194 | #ifdef USE_EF_UT_TIME | |
195 | static ZCONST char Far UT_FileModDate[] = | |
196 | " file last modified on (UT extra field modtime): %s %s\n"; | |
197 | static ZCONST char Far LocalTime[] = "local"; | |
198 | #ifndef NO_GMTIME | |
199 | static ZCONST char Far GMTime[] = "UTC"; | |
200 | #endif | |
201 | #endif /* USE_EF_UT_TIME */ | |
202 | static ZCONST char Far CRC32Value[] = | |
203 | " 32-bit CRC value (hex): %.8lx\n"; | |
204 | static ZCONST char Far CompressedFileSize[] = | |
205 | " compressed size: %lu bytes\n"; | |
206 | static ZCONST char Far UncompressedFileSize[] = | |
207 | " uncompressed size: %lu bytes\n"; | |
208 | static ZCONST char Far FilenameLength[] = | |
209 | " length of filename: %u characters\n"; | |
210 | static ZCONST char Far ExtraFieldLength[] = | |
211 | " length of extra field: %u bytes\n"; | |
212 | static ZCONST char Far FileCommentLength[] = | |
213 | " length of file comment: %u characters\n"; | |
214 | static ZCONST char Far FileDiskNum[] = | |
215 | " disk number on which file begins: disk %u\n"; | |
216 | static ZCONST char Far ApparentFileType[] = | |
217 | " apparent file type: %s\n"; | |
218 | static ZCONST char Far VMSFileAttributes[] = | |
219 | " VMS file attributes (%06o octal): %s\n"; | |
220 | static ZCONST char Far AmigaFileAttributes[] = | |
221 | " Amiga file attributes (%06o octal): %s\n"; | |
222 | static ZCONST char Far UnixFileAttributes[] = | |
223 | " Unix file attributes (%06o octal): %s\n"; | |
224 | static ZCONST char Far NonMSDOSFileAttributes[] = | |
225 | " non-MSDOS external file attributes: %06lX hex\n"; | |
226 | static ZCONST char Far MSDOSFileAttributes[] = | |
227 | " MS-DOS file attributes (%02X hex): none\n"; | |
228 | static ZCONST char Far MSDOSFileAttributesRO[] = | |
229 | " MS-DOS file attributes (%02X hex): read-only\n"; | |
230 | static ZCONST char Far MSDOSFileAttributesAlpha[] = | |
231 | " MS-DOS file attributes (%02X hex): %s%s%s%s%s%s\n"; | |
232 | ||
233 | ||
234 | static ZCONST char Far ExtraFieldTrunc[] = "\n\ | |
235 | error: EF data block (type 0x%04x) size %u exceeds remaining extra field\n\ | |
236 | space %u; block length has been truncated.\n"; | |
237 | static ZCONST char Far ExtraFields[] = "\n\ | |
238 | The central-directory extra field contains:"; | |
239 | static ZCONST char Far ExtraFieldType[] = "\n\ | |
240 | - A subfield with ID 0x%04x (%s) and %u data bytes"; | |
241 | static ZCONST char Far efAV[] = "PKWARE AV"; | |
242 | static ZCONST char Far efOS2[] = "OS/2"; | |
243 | static ZCONST char Far efPKVMS[] = "PKWARE VMS"; | |
244 | static ZCONST char Far efPKWin32[] = "PKWARE Win32"; | |
245 | static ZCONST char Far efPKUnix[] = "PKWARE Unix"; | |
246 | static ZCONST char Far efIZVMS[] = "Info-ZIP VMS"; | |
247 | static ZCONST char Far efIZUnix[] = "old Info-ZIP Unix/OS2/NT"; | |
248 | static ZCONST char Far efIZUnix2[] = "Unix UID/GID"; | |
249 | static ZCONST char Far efTime[] = "universal time"; | |
250 | static ZCONST char Far efJLMac[] = "old Info-ZIP Macintosh"; | |
251 | static ZCONST char Far efMac3[] = "new Info-ZIP Macintosh"; | |
252 | static ZCONST char Far efZipIt[] = "ZipIt Macintosh"; | |
253 | static ZCONST char Far efZipIt2[] = "ZipIt Macintosh (short)"; | |
254 | static ZCONST char Far efVMCMS[] = "VM/CMS"; | |
255 | static ZCONST char Far efMVS[] = "MVS"; | |
256 | static ZCONST char Far efACL[] = "OS/2 ACL"; | |
257 | static ZCONST char Far efNTSD[] = "Security Descriptor"; | |
258 | static ZCONST char Far efBeOS[] = "BeOS"; | |
259 | static ZCONST char Far efQDOS[] = "SMS/QDOS"; | |
260 | static ZCONST char Far efAOSVS[] = "AOS/VS"; | |
261 | static ZCONST char Far efSpark[] = "Acorn SparkFS"; | |
262 | static ZCONST char Far efMD5[] = "Fred Kantor MD5"; | |
263 | static ZCONST char Far efASiUnix[] = "ASi Unix"; | |
264 | static ZCONST char Far efUnknown[] = "unknown"; | |
265 | ||
266 | static ZCONST char Far OS2EAs[] = ".\n\ | |
267 | The local extra field has %lu bytes of OS/2 extended attributes.\n\ | |
268 | (May not match OS/2 \"dir\" amount due to storage method)"; | |
269 | static ZCONST char Far izVMSdata[] = ". The extra\n\ | |
270 | field is %s and has %lu bytes of VMS %s information%s"; | |
271 | static ZCONST char Far izVMSstored[] = "stored"; | |
272 | static ZCONST char Far izVMSrleenc[] = "run-length encoded"; | |
273 | static ZCONST char Far izVMSdeflat[] = "deflated"; | |
274 | static ZCONST char Far izVMScunknw[] = "compressed(?)"; | |
275 | static ZCONST char Far *izVMScomp[4] = | |
276 | {izVMSstored, izVMSrleenc, izVMSdeflat, izVMScunknw}; | |
277 | static ZCONST char Far ACLdata[] = ".\n\ | |
278 | The local extra field has %lu bytes of access control list information"; | |
279 | static ZCONST char Far NTSDData[] = ".\n\ | |
280 | The local extra field has %lu bytes of NT security descriptor data"; | |
281 | static ZCONST char Far UTdata[] = ".\n\ | |
282 | The local extra field has UTC/GMT %s time%s"; | |
283 | static ZCONST char Far UTmodification[] = "modification"; | |
284 | static ZCONST char Far UTaccess[] = "access"; | |
285 | static ZCONST char Far UTcreation[] = "creation"; | |
286 | static ZCONST char Far ZipItFname[] = ".\n\ | |
287 | The Mac long filename is %s.\n"; | |
288 | static ZCONST char Far Mac3data[] = ".\n\ | |
289 | The local extra field has %lu bytes of %scompressed Macintosh\n\ | |
290 | finder attributes"; | |
291 | /* MacOSdata[] is used by EF_MAC3, EF_ZIPIT, EF_ZIPIT2 and EF_JLEE e. f. */ | |
292 | static ZCONST char Far MacOSdata[] = ".\n\ | |
293 | The associated file has type code `%c%c%c%c' and creator code `%c%c%c%c'"; | |
294 | static ZCONST char Far MacOSdata1[] = ".\n\ | |
295 | The associated file has type code `0x%lx' and creator code `0x%lx'"; | |
296 | static ZCONST char Far MacOSJLEEflags[] = "\n File is marked as %s"; | |
297 | static ZCONST char Far MacOS_RF[] = "Resource-fork"; | |
298 | static ZCONST char Far MacOS_DF[] = "Data-fork"; | |
299 | static ZCONST char Far MacOSMAC3flags[] = ".\n\ | |
300 | File is marked as %s, File Dates are in %d Bit"; | |
301 | static ZCONST char Far BeOSdata[] = ".\n\ | |
302 | The local extra field has %lu bytes of %scompressed BeOS file attributes"; | |
303 | /* The associated file has type code `%c%c%c%c' and creator code `%c%c%c%c'" */ | |
304 | static ZCONST char Far QDOSdata[] = ".\n\ | |
305 | The QDOS extra field subtype is `%c%c%c%c'"; | |
306 | static ZCONST char Far AOSVSdata[] = ".\n\ | |
307 | The AOS/VS extra field revision is %d.%d"; | |
308 | static ZCONST char Far MD5data[] = ".\n\ | |
309 | The 128-bit MD5 signature is %s"; | |
310 | #ifdef CMS_MVS | |
311 | static ZCONST char Far VmMvsExtraField[] = ".\n\ | |
312 | The stored file open mode (FLDATA TYPE) is \"%s\""; | |
313 | static ZCONST char Far VmMvsInvalid[] = "[invalid]"; | |
314 | #endif /* CMS_MVS */ | |
315 | ||
316 | static ZCONST char Far First20[] = ". The first\n 20 are: "; | |
317 | static ZCONST char Far ColonIndent[] = ":\n "; | |
318 | static ZCONST char Far efFormat[] = " %02x"; | |
319 | ||
320 | static ZCONST char Far lExtraFieldType[] = "\n\ | |
321 | There %s a local extra field with ID 0x%04x (%s) and\n\ | |
322 | %u data bytes (%s).\n"; | |
323 | static ZCONST char Far efIZuid[] = | |
324 | "GMT modification/access times and Unix UID/GID"; | |
325 | static ZCONST char Far efIZnouid[] = "GMT modification/access times only"; | |
326 | ||
327 | ||
328 | static ZCONST char Far NoFileComment[] = "\n There is no file comment.\n"; | |
329 | static ZCONST char Far FileCommBegin[] = "\n\ | |
330 | ------------------------- file comment begins ----------------------------\n"; | |
331 | static ZCONST char Far FileCommEnd[] = "\ | |
332 | -------------------------- file comment ends -----------------------------\n"; | |
333 | ||
334 | /* zi_time() strings */ | |
335 | static ZCONST char Far BogusFmt[] = "%03d"; | |
336 | static ZCONST char Far DMYHMTime[] = "%2u-%s-%02u %02u:%02u"; | |
337 | static ZCONST char Far YMDHMSTime[] = "%u %s %u %02u:%02u:%02u"; | |
338 | static ZCONST char Far DecimalTime[] = "%04u%02u%02u.%02u%02u%02u"; | |
339 | static ZCONST char Far YMDHMSTimeError[] = "???? ??? ?? ??:??:??"; | |
340 | ||
341 | ||
342 | ||
343 | ||
344 | ||
345 | #ifndef WINDLL | |
346 | ||
347 | /************************/ | |
348 | /* Function zi_opts() */ | |
349 | /************************/ | |
350 | ||
351 | int zi_opts(__G__ pargc, pargv) | |
352 | int *pargc; | |
353 | char ***pargv; | |
354 | __GDEF | |
355 | { | |
356 | char **argv, *s; | |
357 | int argc, c, error=FALSE, negative=0; | |
358 | int hflag_slmv=TRUE, hflag_2=FALSE; /* diff options => diff defaults */ | |
359 | int tflag_slm=TRUE, tflag_2v=FALSE; | |
360 | int explicit_h=FALSE, explicit_t=FALSE; | |
361 | ||
362 | ||
363 | #ifdef MACOS | |
364 | uO.lflag = LFLAG; /* reset default on each call */ | |
365 | #endif | |
366 | G.extract_flag = FALSE; /* zipinfo does not extract to disk */ | |
367 | argc = *pargc; | |
368 | argv = *pargv; | |
369 | ||
370 | while (--argc > 0 && (*++argv)[0] == '-') { | |
371 | s = argv[0] + 1; | |
372 | while ((c = *s++) != 0) { /* "!= 0": prevent Turbo C warning */ | |
373 | switch (c) { | |
374 | case '-': | |
375 | ++negative; | |
376 | break; | |
377 | case '1': /* shortest listing: JUST filenames */ | |
378 | if (negative) | |
379 | uO.lflag = -2, negative = 0; | |
380 | else | |
381 | uO.lflag = 1; | |
382 | break; | |
383 | case '2': /* just filenames, plus headers if specified */ | |
384 | if (negative) | |
385 | uO.lflag = -2, negative = 0; | |
386 | else | |
387 | uO.lflag = 2; | |
388 | break; | |
389 | #ifndef CMS_MVS | |
390 | case ('C'): /* -C: match filenames case-insensitively */ | |
391 | if (negative) | |
392 | uO.C_flag = FALSE, negative = 0; | |
393 | else | |
394 | uO.C_flag = TRUE; | |
395 | break; | |
396 | #endif /* !CMS_MVS */ | |
397 | case 'h': /* header line */ | |
398 | if (negative) | |
399 | hflag_2 = hflag_slmv = FALSE, negative = 0; | |
400 | else { | |
401 | hflag_2 = hflag_slmv = explicit_h = TRUE; | |
402 | if (uO.lflag == -1) | |
403 | uO.lflag = 0; | |
404 | } | |
405 | break; | |
406 | case 'l': /* longer form of "ls -l" type listing */ | |
407 | if (negative) | |
408 | uO.lflag = -2, negative = 0; | |
409 | else | |
410 | uO.lflag = 5; | |
411 | break; | |
412 | case 'm': /* medium form of "ls -l" type listing */ | |
413 | if (negative) | |
414 | uO.lflag = -2, negative = 0; | |
415 | else | |
416 | uO.lflag = 4; | |
417 | break; | |
418 | #ifdef MORE | |
419 | case 'M': /* send output through built-in "more" */ | |
420 | if (negative) | |
421 | G.M_flag = FALSE, negative = 0; | |
422 | else | |
423 | G.M_flag = TRUE; | |
424 | break; | |
425 | #endif | |
426 | case 's': /* default: shorter "ls -l" type listing */ | |
427 | if (negative) | |
428 | uO.lflag = -2, negative = 0; | |
429 | else | |
430 | uO.lflag = 3; | |
431 | break; | |
432 | case 't': /* totals line */ | |
433 | if (negative) | |
434 | tflag_2v = tflag_slm = FALSE, negative = 0; | |
435 | else { | |
436 | tflag_2v = tflag_slm = explicit_t = TRUE; | |
437 | if (uO.lflag == -1) | |
438 | uO.lflag = 0; | |
439 | } | |
440 | break; | |
441 | case ('T'): /* use (sortable) decimal time format */ | |
442 | if (negative) | |
443 | uO.T_flag = FALSE, negative = 0; | |
444 | else | |
445 | uO.T_flag = TRUE; | |
446 | break; | |
447 | case 'v': /* turbo-verbose listing */ | |
448 | if (negative) | |
449 | uO.lflag = -2, negative = 0; | |
450 | else | |
451 | uO.lflag = 10; | |
452 | break; | |
453 | case 'z': /* print zipfile comment */ | |
454 | if (negative) | |
455 | uO.zflag = negative = 0; | |
456 | else | |
457 | uO.zflag = 1; | |
458 | break; | |
459 | case 'Z': /* ZipInfo mode: ignore */ | |
460 | break; | |
461 | default: | |
462 | error = TRUE; | |
463 | break; | |
464 | } | |
465 | } | |
466 | } | |
467 | if ((argc-- == 0) || error) { | |
468 | *pargc = argc; | |
469 | *pargv = argv; | |
470 | return USAGE(error); | |
471 | } | |
472 | ||
473 | #ifdef MORE | |
474 | if (G.M_flag && !isatty(1)) /* stdout redirected: "more" func useless */ | |
475 | G.M_flag = 0; | |
476 | #endif | |
477 | ||
478 | /* if no listing options given (or all negated), or if only -h/-t given | |
479 | * with individual files specified, use default listing format */ | |
480 | if ((uO.lflag < 0) || ((argc > 0) && (uO.lflag == 0))) | |
481 | uO.lflag = LFLAG; | |
482 | ||
483 | /* set header and totals flags to default or specified values */ | |
484 | switch (uO.lflag) { | |
485 | case 0: /* 0: can only occur if either -t or -h explicitly given; */ | |
486 | case 2: /* therefore set both flags equal to normally false value */ | |
487 | uO.hflag = hflag_2; | |
488 | uO.tflag = tflag_2v; | |
489 | break; | |
490 | case 1: /* only filenames, *always* */ | |
491 | uO.hflag = FALSE; | |
492 | uO.tflag = FALSE; | |
493 | uO.zflag = FALSE; | |
494 | break; | |
495 | case 3: | |
496 | case 4: | |
497 | case 5: | |
498 | uO.hflag = ((argc > 0) && !explicit_h)? FALSE : hflag_slmv; | |
499 | uO.tflag = ((argc > 0) && !explicit_t)? FALSE : tflag_slm; | |
500 | break; | |
501 | case 10: | |
502 | uO.hflag = hflag_slmv; | |
503 | uO.tflag = tflag_2v; | |
504 | break; | |
505 | } | |
506 | ||
507 | *pargc = argc; | |
508 | *pargv = argv; | |
509 | return 0; | |
510 | ||
511 | } /* end function zi_opts() */ | |
512 | ||
513 | #endif /* !WINDLL */ | |
514 | ||
515 | ||
516 | ||
517 | ||
518 | ||
519 | /*******************************/ | |
520 | /* Function zi_end_central() */ | |
521 | /*******************************/ | |
522 | ||
523 | int zi_end_central(__G) /* return PK-type error code */ | |
524 | __GDEF | |
525 | { | |
526 | int error = PK_COOL; | |
527 | ||
528 | ||
529 | /*--------------------------------------------------------------------------- | |
530 | Print out various interesting things about the zipfile. | |
531 | ---------------------------------------------------------------------------*/ | |
532 | ||
533 | /* header fits on one line, for anything up to 10GB and 10000 files: */ | |
534 | if (uO.hflag) | |
535 | Info(slide, 0, ((char *)slide, ((int)strlen(G.zipfn) < 39)? | |
536 | LoadFarString(LongHeader) : LoadFarString(ShortHeader), G.zipfn, | |
537 | (long)G.ziplen, G.ecrec.total_entries_central_dir, | |
538 | (G.ecrec.total_entries_central_dir==1)? | |
539 | nullStr : "s")); | |
540 | ||
541 | /* verbose format */ | |
542 | if (uO.lflag > 9) { | |
543 | Info(slide, 0, ((char *)slide, LoadFarString(EndCentDirRec))); | |
544 | Info(slide, 0, ((char *)slide, LoadFarString(LineSeparators))); | |
545 | ||
546 | Info(slide, 0, ((char *)slide, LoadFarString(ActOffsetCentDir), | |
547 | (long)G.real_ecrec_offset, (long)G.real_ecrec_offset, | |
548 | (long)G.expect_ecrec_offset, (long)G.expect_ecrec_offset)); | |
549 | ||
550 | if (G.ecrec.number_this_disk == 0) { | |
551 | Info(slide, 0, ((char *)slide, LoadFarString(SinglePartArchive1), | |
552 | G.ecrec.total_entries_central_dir, | |
553 | (G.ecrec.total_entries_central_dir == 1)? "entry" : "entries", | |
554 | G.ecrec.size_central_directory, | |
555 | G.ecrec.size_central_directory)); | |
556 | Info(slide, 0, ((char *)slide, LoadFarString(SinglePartArchive2), | |
557 | G.ecrec.offset_start_central_directory, | |
558 | G.ecrec.offset_start_central_directory)); | |
559 | } else { | |
560 | Info(slide, 0, ((char *)slide, LoadFarString(MultiPartArchive1), | |
561 | G.ecrec.number_this_disk + 1, | |
562 | G.ecrec.num_disk_start_cdir + 1, | |
563 | G.ecrec.num_entries_centrl_dir_ths_disk, | |
564 | (G.ecrec.num_entries_centrl_dir_ths_disk == 1)? "is" : "are")); | |
565 | Info(slide, 0, ((char *)slide, LoadFarString(MultiPartArchive2), | |
566 | G.ecrec.total_entries_central_dir, | |
567 | (G.ecrec.total_entries_central_dir == 1) ? "entry" : "entries", | |
568 | G.ecrec.size_central_directory, | |
569 | G.ecrec.size_central_directory)); | |
570 | Info(slide, 0, ((char *)slide, LoadFarString(MultiPartArchive3), | |
571 | G.ecrec.offset_start_central_directory, | |
572 | G.ecrec.offset_start_central_directory)); | |
573 | } | |
574 | ||
575 | /*----------------------------------------------------------------------- | |
576 | Get the zipfile comment, if any, and print it out. (Comment may be | |
577 | up to 64KB long. May the fleas of a thousand camels infest the arm- | |
578 | pits of anyone who actually takes advantage of this fact.) | |
579 | -----------------------------------------------------------------------*/ | |
580 | ||
581 | if (!G.ecrec.zipfile_comment_length) | |
582 | Info(slide, 0, ((char *)slide, LoadFarString(NoZipfileComment))); | |
583 | else { | |
584 | Info(slide, 0, ((char *)slide, LoadFarString(ZipfileCommentDesc), | |
585 | G.ecrec.zipfile_comment_length)); | |
586 | Info(slide, 0, ((char *)slide, LoadFarString(ZipfileCommBegin))); | |
587 | if (do_string(__G__ G.ecrec.zipfile_comment_length, DISPLAY)) | |
588 | error = PK_WARN; | |
589 | Info(slide, 0, ((char *)slide, LoadFarString(ZipfileCommEnd))); | |
590 | if (error) | |
591 | Info(slide, 0, ((char *)slide, | |
592 | LoadFarString(ZipfileCommTrunc2))); | |
593 | } /* endif (comment exists) */ | |
594 | ||
595 | /* non-verbose mode: print zipfile comment only if requested */ | |
596 | } else if (uO.zflag && G.ecrec.zipfile_comment_length) { | |
597 | if (do_string(__G__ G.ecrec.zipfile_comment_length, DISPLAY)) { | |
598 | Info(slide, 0x401, ((char *)slide, | |
599 | LoadFarString(ZipfileCommTruncMsg))); | |
600 | error = PK_WARN; | |
601 | } | |
602 | } /* endif (verbose) */ | |
603 | ||
604 | return error; | |
605 | ||
606 | } /* end function zi_end_central() */ | |
607 | ||
608 | ||
609 | ||
610 | ||
611 | ||
612 | /************************/ | |
613 | /* Function zipinfo() */ | |
614 | /************************/ | |
615 | ||
616 | int zipinfo(__G) /* return PK-type error code */ | |
617 | __GDEF | |
618 | { | |
619 | int do_this_file=FALSE, error, error_in_archive=PK_COOL; | |
620 | int *fn_matched=NULL, *xn_matched=NULL; | |
621 | unsigned j, members=0; | |
622 | ulg tot_csize=0L, tot_ucsize=0L; | |
623 | ulg endprev; /* buffers end of previous entry for zi_long()'s check | |
624 | * of extra bytes */ | |
625 | ||
626 | ||
627 | /*--------------------------------------------------------------------------- | |
628 | Malloc space for check on unmatched filespecs (no big deal if one or both | |
629 | are NULL). | |
630 | ---------------------------------------------------------------------------*/ | |
631 | ||
632 | if (G.filespecs > 0 && | |
633 | (fn_matched=(int *)malloc(G.filespecs*sizeof(int))) != NULL) | |
634 | for (j = 0; j < G.filespecs; ++j) | |
635 | fn_matched[j] = FALSE; | |
636 | ||
637 | if (G.xfilespecs > 0 && | |
638 | (xn_matched=(int *)malloc(G.xfilespecs*sizeof(int))) != NULL) | |
639 | for (j = 0; j < G.xfilespecs; ++j) | |
640 | xn_matched[j] = FALSE; | |
641 | ||
642 | /*--------------------------------------------------------------------------- | |
643 | Set file pointer to start of central directory, then loop through cen- | |
644 | tral directory entries. Check that directory-entry signature bytes are | |
645 | actually there (just a precaution), then process the entry. We know | |
646 | the entire central directory is on this disk: we wouldn't have any of | |
647 | this information unless the end-of-central-directory record was on this | |
648 | disk, and we wouldn't have gotten to this routine unless this is also | |
649 | the disk on which the central directory starts. In practice, this had | |
650 | better be the *only* disk in the archive, but maybe someday we'll add | |
651 | multi-disk support. | |
652 | ---------------------------------------------------------------------------*/ | |
653 | ||
654 | uO.L_flag = FALSE; /* zipinfo mode: never convert name to lowercase */ | |
655 | G.pInfo = G.info; /* (re-)initialize, (just to make sure) */ | |
656 | G.pInfo->textmode = 0; /* so one can read on screen (is this ever used?) */ | |
657 | ||
658 | /* reset endprev for new zipfile; account for multi-part archives (?) */ | |
659 | endprev = (G.crec.relative_offset_local_header == 4L)? 4L : 0L; | |
660 | ||
661 | ||
662 | for (j = 0; j++ < (unsigned)G.ecrec.total_entries_central_dir;) { | |
663 | if (readbuf(__G__ G.sig, 4) == 0) | |
664 | return PK_EOF; | |
665 | if (strncmp(G.sig, central_hdr_sig, 4)) { /* just to make sure */ | |
666 | Info(slide, 0x401, ((char *)slide, LoadFarString(CentSigMsg), j)); | |
667 | return PK_BADERR; /* sig not found */ | |
668 | } | |
669 | /* process_cdir_file_hdr() sets pInfo->hostnum, pInfo->lcflag, ...: */ | |
670 | if ((error = process_cdir_file_hdr(__G)) != PK_COOL) | |
671 | return error; /* only PK_EOF defined */ | |
672 | ||
673 | if ((error = do_string(__G__ G.crec.filename_length, DS_FN)) != | |
674 | PK_COOL) | |
675 | { | |
676 | error_in_archive = error; /* might be warning */ | |
677 | if (error > PK_WARN) /* fatal */ | |
678 | return error; | |
679 | } | |
680 | ||
681 | if (!G.process_all_files) { /* check if specified on command line */ | |
682 | unsigned i; | |
683 | ||
684 | do_this_file = FALSE; | |
685 | for (i = 0; i < G.filespecs; i++) | |
686 | if (match(G.filename, G.pfnames[i], uO.C_flag)) { | |
687 | do_this_file = TRUE; | |
688 | if (fn_matched) | |
689 | fn_matched[i] = TRUE; | |
690 | break; /* found match, so stop looping */ | |
691 | } | |
692 | if (do_this_file) { /* check if this is an excluded file */ | |
693 | for (i = 0; i < G.xfilespecs; i++) | |
694 | if (match(G.filename, G.pxnames[i], uO.C_flag)) { | |
695 | do_this_file = FALSE; /* ^-- ignore case in match */ | |
696 | if (xn_matched) | |
697 | xn_matched[i] = TRUE; | |
698 | break; | |
699 | } | |
700 | } | |
701 | } | |
702 | ||
703 | /*----------------------------------------------------------------------- | |
704 | If current file was specified on command line, or if no names were | |
705 | specified, do the listing for this file. Otherwise, get rid of the | |
706 | file comment and go back for the next file. | |
707 | -----------------------------------------------------------------------*/ | |
708 | ||
709 | if (G.process_all_files || do_this_file) { | |
710 | ||
711 | switch (uO.lflag) { | |
712 | case 1: | |
713 | case 2: | |
714 | fnprint(__G); | |
715 | SKIP_(G.crec.extra_field_length) | |
716 | SKIP_(G.crec.file_comment_length) | |
717 | break; | |
718 | ||
719 | case 3: | |
720 | case 4: | |
721 | case 5: | |
722 | if ((error = zi_short(__G)) != PK_COOL) { | |
723 | error_in_archive = error; /* might be warning */ | |
724 | if (error > PK_WARN) /* fatal */ | |
725 | return error; | |
726 | } | |
727 | break; | |
728 | ||
729 | case 10: | |
730 | Info(slide, 0, ((char *)slide, | |
731 | LoadFarString(CentralDirEntry), j)); | |
732 | if ((error = zi_long(__G__ &endprev)) != PK_COOL) { | |
733 | error_in_archive = error; /* might be warning */ | |
734 | if (error > PK_WARN) /* fatal */ | |
735 | return error; | |
736 | } | |
737 | break; | |
738 | ||
739 | default: | |
740 | SKIP_(G.crec.extra_field_length) | |
741 | SKIP_(G.crec.file_comment_length) | |
742 | break; | |
743 | ||
744 | } /* end switch (lflag) */ | |
745 | ||
746 | tot_csize += G.crec.csize; | |
747 | tot_ucsize += G.crec.ucsize; | |
748 | if (G.crec.general_purpose_bit_flag & 1) | |
749 | tot_csize -= 12; /* don't count encryption header */ | |
750 | ++members; | |
751 | ||
752 | #ifdef DLL | |
753 | if ((G.statreportcb != NULL) && | |
754 | (*G.statreportcb)(__G__ UZ_ST_FINISH_MEMBER, G.zipfn, | |
755 | G.filename, NULL)) { | |
756 | if (fn_matched) | |
757 | free((zvoid *)fn_matched); | |
758 | if (xn_matched) | |
759 | free((zvoid *)xn_matched); | |
760 | return IZ_CTRLC; /* cancel operation by user request */ | |
761 | } | |
762 | #endif | |
763 | #ifdef MACOS /* MacOS is no preemptive OS, thus call event-handling by hand */ | |
764 | UserStop(); | |
765 | #endif | |
766 | ||
767 | } else { /* not listing this file */ | |
768 | SKIP_(G.crec.extra_field_length) | |
769 | SKIP_(G.crec.file_comment_length) | |
770 | ||
771 | } /* end if (list member?) */ | |
772 | ||
773 | } /* end for-loop (j: member files) */ | |
774 | ||
775 | /*--------------------------------------------------------------------------- | |
776 | Check that we actually found requested files; if so, print totals. | |
777 | ---------------------------------------------------------------------------*/ | |
778 | ||
779 | if (uO.tflag) { | |
780 | char *sgn = ""; | |
781 | int cfactor = ratio(tot_ucsize, tot_csize); | |
782 | ||
783 | if (cfactor < 0) { | |
784 | sgn = "-"; | |
785 | cfactor = -cfactor; | |
786 | } | |
787 | Info(slide, 0, ((char *)slide, LoadFarString(ZipfileStats), | |
788 | members, (members==1)? nullStr:"s", tot_ucsize, | |
789 | tot_csize, sgn, cfactor/10, cfactor%10)); | |
790 | } | |
791 | ||
792 | /*--------------------------------------------------------------------------- | |
793 | Check for unmatched filespecs on command line and print warning if any | |
794 | found. | |
795 | ---------------------------------------------------------------------------*/ | |
796 | ||
797 | if (fn_matched) { | |
798 | for (j = 0; j < G.filespecs; ++j) | |
799 | if (!fn_matched[j]) | |
800 | Info(slide, 0x401, ((char *)slide, | |
801 | LoadFarString(FilenameNotMatched), G.pfnames[j])); | |
802 | free((zvoid *)fn_matched); | |
803 | } | |
804 | if (xn_matched) { | |
805 | for (j = 0; j < G.xfilespecs; ++j) | |
806 | if (!xn_matched[j]) | |
807 | Info(slide, 0x401, ((char *)slide, | |
808 | LoadFarString(ExclFilenameNotMatched), G.pxnames[j])); | |
809 | free((zvoid *)xn_matched); | |
810 | } | |
811 | ||
812 | /*--------------------------------------------------------------------------- | |
813 | Double check that we're back at the end-of-central-directory record. | |
814 | ---------------------------------------------------------------------------*/ | |
815 | ||
816 | if (readbuf(__G__ G.sig, 4) == 0) /* disk error? */ | |
817 | return PK_EOF; | |
818 | if (strncmp(G.sig, end_central_sig, 4)) { /* just to make sure again */ | |
819 | Info(slide, 0x401, ((char *)slide, LoadFarString(EndSigMsg))); | |
820 | error_in_archive = PK_WARN; /* didn't find sig */ | |
821 | } | |
822 | if (members == 0 && error_in_archive <= PK_WARN) | |
823 | error_in_archive = PK_FIND; | |
824 | ||
825 | if (uO.lflag >= 10) | |
826 | (*G.message)((zvoid *)&G, (uch *)"\n", 1L, 0); | |
827 | ||
828 | return error_in_archive; | |
829 | ||
830 | } /* end function zipinfo() */ | |
831 | ||
832 | ||
833 | ||
834 | ||
835 | ||
836 | /************************/ | |
837 | /* Function zi_long() */ | |
838 | /************************/ | |
839 | ||
840 | static int zi_long(__G__ pEndprev) /* return PK-type error code */ | |
841 | __GDEF | |
842 | ulg *pEndprev; /* for zi_long() check of extra bytes */ | |
843 | { | |
844 | #ifdef USE_EF_UT_TIME | |
845 | iztimes z_utime; | |
846 | #endif | |
847 | int error, error_in_archive=PK_COOL; | |
848 | ush hostnum, hostver, extnum, extver, methnum, xattr; | |
849 | char workspace[12], attribs[22]; | |
850 | ZCONST char *varmsg_str; | |
851 | char unkn[16]; | |
852 | static ZCONST char Far *os[NUM_HOSTS] = { | |
853 | OS_FAT, OS_Amiga, OS_VMS, OS_Unix, OS_VMCMS, OS_AtariST, OS_HPFS, | |
854 | OS_Macintosh, OS_ZSystem, OS_CPM, OS_TOPS20, OS_NTFS, OS_QDOS, | |
855 | OS_Acorn, OS_VFAT, OS_MVS, OS_BeOS, OS_Tandem | |
856 | }; | |
857 | static ZCONST char Far *method[NUM_METHODS] = { | |
858 | MthdNone, MthdShrunk, MthdRedF1, MthdRedF2, MthdRedF3, MthdRedF4, | |
859 | MthdImplode, MthdToken, MthdDeflate, MthdEnDeflate, MthdDCLImplode | |
860 | }; | |
861 | static ZCONST char Far *dtypelng[4] = { | |
862 | DeflNorm, DeflMax, DeflFast, DeflSFast | |
863 | }; | |
864 | ||
865 | ||
866 | /*--------------------------------------------------------------------------- | |
867 | Check whether there's any extra space inside the zipfile. If *pEndprev is | |
868 | zero, it's probably a signal that OS/2 extra fields are involved (with | |
869 | unknown compressed size). We won't worry about prepended junk here... | |
870 | ---------------------------------------------------------------------------*/ | |
871 | ||
872 | if (G.crec.relative_offset_local_header != *pEndprev && *pEndprev > 0L) { | |
873 | /* GRR DEBUG | |
874 | Info(slide, 0, ((char *)slide, | |
875 | " [crec.relative_offset_local_header = %lu, endprev = %lu]\n", | |
876 | G.crec.relative_offset_local_header, *pEndprev)); | |
877 | */ | |
878 | Info(slide, 0, ((char *)slide, LoadFarString(ExtraBytesPreceding), | |
879 | (long)G.crec.relative_offset_local_header - (long)(*pEndprev))); | |
880 | } | |
881 | ||
882 | /* calculate endprev for next time around (problem: extra fields may | |
883 | * differ in length between local and central-directory records) */ | |
884 | *pEndprev = G.crec.relative_offset_local_header + 4L + LREC_SIZE + | |
885 | G.crec.filename_length + G.crec.extra_field_length + | |
886 | G.crec.file_comment_length + G.crec.csize; | |
887 | ||
888 | /*--------------------------------------------------------------------------- | |
889 | Read the extra field, if any. It may be used to get UNIX style modtime. | |
890 | ---------------------------------------------------------------------------*/ | |
891 | ||
892 | if ((error = do_string(__G__ G.crec.extra_field_length, EXTRA_FIELD)) != 0) | |
893 | { | |
894 | if (G.extra_field != NULL) { | |
895 | free(G.extra_field); | |
896 | G.extra_field = NULL; | |
897 | } | |
898 | error_in_archive = error; | |
899 | /* The premature return in case of a "fatal" error (PK_EOF) is | |
900 | * delayed until we analyze the extra field contents. | |
901 | * This allows us to display all the other info that has been | |
902 | * successfully read in. | |
903 | */ | |
904 | } | |
905 | ||
906 | /*--------------------------------------------------------------------------- | |
907 | Print out various interesting things about the compressed file. | |
908 | ---------------------------------------------------------------------------*/ | |
909 | ||
910 | hostnum = (ush)(G.pInfo->hostnum); | |
911 | hostver = G.crec.version_made_by[0]; | |
912 | extnum = (ush)MIN(G.crec.version_needed_to_extract[1], NUM_HOSTS); | |
913 | extver = G.crec.version_needed_to_extract[0]; | |
914 | methnum = (ush)MIN(G.crec.compression_method, NUM_METHODS); | |
915 | ||
916 | (*G.message)((zvoid *)&G, (uch *)" ", 2L, 0); fnprint(__G); | |
917 | ||
918 | Info(slide, 0, ((char *)slide, LoadFarString(LocalHeaderOffset), | |
919 | G.crec.relative_offset_local_header, | |
920 | G.crec.relative_offset_local_header)); | |
921 | ||
922 | if (hostnum >= NUM_HOSTS) { | |
923 | sprintf(unkn, LoadFarString(UnknownNo), | |
924 | (int)G.crec.version_made_by[1]); | |
925 | varmsg_str = unkn; | |
926 | } else { | |
927 | varmsg_str = LoadFarStringSmall(os[hostnum]); | |
928 | } | |
929 | Info(slide, 0, ((char *)slide, LoadFarString(HostOS), varmsg_str)); | |
930 | Info(slide, 0, ((char *)slide, LoadFarString(EncodeSWVer), hostver/10, | |
931 | hostver%10)); | |
932 | ||
933 | if (extnum >= NUM_HOSTS) { | |
934 | sprintf(unkn, LoadFarString(UnknownNo), | |
935 | (int)G.crec.version_needed_to_extract[1]); | |
936 | varmsg_str = unkn; | |
937 | } else { | |
938 | varmsg_str = LoadFarStringSmall(os[extnum]); | |
939 | } | |
940 | Info(slide, 0, ((char *)slide, LoadFarString(MinOSCompReq), varmsg_str)); | |
941 | Info(slide, 0, ((char *)slide, LoadFarString(MinSWVerReq), extver/10, | |
942 | extver%10)); | |
943 | ||
944 | if (methnum >= NUM_METHODS) { | |
945 | sprintf(unkn, LoadFarString(UnknownNo), G.crec.compression_method); | |
946 | varmsg_str = unkn; | |
947 | } else { | |
948 | varmsg_str = LoadFarStringSmall(method[methnum]); | |
949 | } | |
950 | Info(slide, 0, ((char *)slide, LoadFarString(CompressMethod), varmsg_str)); | |
951 | if (methnum == IMPLODED) { | |
952 | Info(slide, 0, ((char *)slide, LoadFarString(SlideWindowSizeImplode), | |
953 | (G.crec.general_purpose_bit_flag & 2)? '8' : '4')); | |
954 | Info(slide, 0, ((char *)slide, LoadFarString(ShannonFanoTrees), | |
955 | (G.crec.general_purpose_bit_flag & 4)? '3' : '2')); | |
956 | } else if (methnum == DEFLATED) { | |
957 | ush dnum=(ush)((G.crec.general_purpose_bit_flag>>1) & 3); | |
958 | ||
959 | Info(slide, 0, ((char *)slide, LoadFarString(CompressSubtype), | |
960 | LoadFarStringSmall(dtypelng[dnum]))); | |
961 | } | |
962 | ||
963 | Info(slide, 0, ((char *)slide, LoadFarString(FileSecurity), | |
964 | (G.crec.general_purpose_bit_flag & 1) ? nullStr : "not ")); | |
965 | Info(slide, 0, ((char *)slide, LoadFarString(ExtendedLocalHdr), | |
966 | (G.crec.general_purpose_bit_flag & 8) ? "yes" : "no")); | |
967 | /* print upper 3 bits for amusement? */ | |
968 | ||
969 | /* For printing of date & time, a "char d_t_buf[21]" is required. | |
970 | * To save stack space, we reuse the "char attribs[22]" buffer which | |
971 | * is not used yet. | |
972 | */ | |
973 | # define d_t_buf attribs | |
974 | ||
975 | zi_time(__G__ &G.crec.last_mod_dos_datetime, NULL, d_t_buf); | |
976 | Info(slide, 0, ((char *)slide, LoadFarString(FileModDate), d_t_buf)); | |
977 | #ifdef USE_EF_UT_TIME | |
978 | if (G.extra_field && | |
979 | #ifdef IZ_CHECK_TZ | |
980 | G.tz_is_valid && | |
981 | #endif | |
982 | (ef_scan_for_izux(G.extra_field, G.crec.extra_field_length, 1, | |
983 | G.crec.last_mod_dos_datetime, &z_utime, NULL) | |
984 | & EB_UT_FL_MTIME)) | |
985 | { | |
986 | TIMET_TO_NATIVE(z_utime.mtime) /* NOP unless MSC 7.0 or Macintosh */ | |
987 | d_t_buf[0] = (char)0; /* signal "show local time" */ | |
988 | zi_time(__G__ &G.crec.last_mod_dos_datetime, &(z_utime.mtime), d_t_buf); | |
989 | Info(slide, 0, ((char *)slide, LoadFarString(UT_FileModDate), | |
990 | d_t_buf, LoadFarStringSmall(LocalTime))); | |
991 | #ifndef NO_GMTIME | |
992 | d_t_buf[0] = (char)1; /* signal "show UTC (GMT) time" */ | |
993 | zi_time(__G__ &G.crec.last_mod_dos_datetime, &(z_utime.mtime), d_t_buf); | |
994 | Info(slide, 0, ((char *)slide, LoadFarString(UT_FileModDate), | |
995 | d_t_buf, LoadFarStringSmall(GMTime))); | |
996 | #endif /* !NO_GMTIME */ | |
997 | } | |
998 | #endif /* USE_EF_UT_TIME */ | |
999 | ||
1000 | Info(slide, 0, ((char *)slide, LoadFarString(CRC32Value), G.crec.crc32)); | |
1001 | Info(slide, 0, ((char *)slide, LoadFarString(CompressedFileSize), | |
1002 | G.crec.csize)); | |
1003 | Info(slide, 0, ((char *)slide, LoadFarString(UncompressedFileSize), | |
1004 | G.crec.ucsize)); | |
1005 | Info(slide, 0, ((char *)slide, LoadFarString(FilenameLength), | |
1006 | G.crec.filename_length)); | |
1007 | Info(slide, 0, ((char *)slide, LoadFarString(ExtraFieldLength), | |
1008 | G.crec.extra_field_length)); | |
1009 | Info(slide, 0, ((char *)slide, LoadFarString(FileCommentLength), | |
1010 | G.crec.file_comment_length)); | |
1011 | Info(slide, 0, ((char *)slide, LoadFarString(FileDiskNum), | |
1012 | G.crec.disk_number_start + 1)); | |
1013 | Info(slide, 0, ((char *)slide, LoadFarString(ApparentFileType), | |
1014 | (G.crec.internal_file_attributes & 1)? "text" | |
1015 | : (G.crec.internal_file_attributes & 2)? "ebcdic" | |
1016 | : "binary")); /* changed to accept EBCDIC */ | |
1017 | #ifdef ATARI | |
1018 | printf(" external file attributes (hex): %.8lx\n", | |
1019 | G.crec.external_file_attributes); | |
1020 | #endif | |
1021 | xattr = (ush)((G.crec.external_file_attributes >> 16) & 0xFFFF); | |
1022 | if (hostnum == VMS_) { | |
1023 | char *p=attribs, *q=attribs+1; | |
1024 | int i, j, k; | |
1025 | ||
1026 | for (k = 0; k < 12; ++k) | |
1027 | workspace[k] = 0; | |
1028 | if (xattr & VMS_IRUSR) | |
1029 | workspace[0] = 'R'; | |
1030 | if (xattr & VMS_IWUSR) { | |
1031 | workspace[1] = 'W'; | |
1032 | workspace[3] = 'D'; | |
1033 | } | |
1034 | if (xattr & VMS_IXUSR) | |
1035 | workspace[2] = 'E'; | |
1036 | if (xattr & VMS_IRGRP) | |
1037 | workspace[4] = 'R'; | |
1038 | if (xattr & VMS_IWGRP) { | |
1039 | workspace[5] = 'W'; | |
1040 | workspace[7] = 'D'; | |
1041 | } | |
1042 | if (xattr & VMS_IXGRP) | |
1043 | workspace[6] = 'E'; | |
1044 | if (xattr & VMS_IROTH) | |
1045 | workspace[8] = 'R'; | |
1046 | if (xattr & VMS_IWOTH) { | |
1047 | workspace[9] = 'W'; | |
1048 | workspace[11] = 'D'; | |
1049 | } | |
1050 | if (xattr & VMS_IXOTH) | |
1051 | workspace[10] = 'E'; | |
1052 | ||
1053 | *p++ = '('; | |
1054 | for (k = j = 0; j < 3; ++j) { /* loop over groups of permissions */ | |
1055 | for (i = 0; i < 4; ++i, ++k) /* loop over perms within a group */ | |
1056 | if (workspace[k]) | |
1057 | *p++ = workspace[k]; | |
1058 | *p++ = ','; /* group separator */ | |
1059 | if (j == 0) | |
1060 | while ((*p++ = *q++) != ',') | |
1061 | ; /* system, owner perms are same */ | |
1062 | } | |
1063 | *p-- = 0; | |
1064 | *p = ')'; /* overwrite last comma */ | |
1065 | Info(slide, 0, ((char *)slide, LoadFarString(VMSFileAttributes), xattr, | |
1066 | attribs)); | |
1067 | ||
1068 | } else if (hostnum == AMIGA_) { | |
1069 | switch (xattr & AMI_IFMT) { | |
1070 | case AMI_IFDIR: attribs[0] = 'd'; break; | |
1071 | case AMI_IFREG: attribs[0] = '-'; break; | |
1072 | default: attribs[0] = '?'; break; | |
1073 | } | |
1074 | attribs[1] = (xattr & AMI_IHIDDEN)? 'h' : '-'; | |
1075 | attribs[2] = (xattr & AMI_ISCRIPT)? 's' : '-'; | |
1076 | attribs[3] = (xattr & AMI_IPURE)? 'p' : '-'; | |
1077 | attribs[4] = (xattr & AMI_IARCHIVE)? 'a' : '-'; | |
1078 | attribs[5] = (xattr & AMI_IREAD)? 'r' : '-'; | |
1079 | attribs[6] = (xattr & AMI_IWRITE)? 'w' : '-'; | |
1080 | attribs[7] = (xattr & AMI_IEXECUTE)? 'e' : '-'; | |
1081 | attribs[8] = (xattr & AMI_IDELETE)? 'd' : '-'; | |
1082 | attribs[9] = 0; /* better dlm the string */ | |
1083 | Info(slide, 0, ((char *)slide, LoadFarString(AmigaFileAttributes), | |
1084 | xattr, attribs)); | |
1085 | ||
1086 | } else if ((hostnum != FS_FAT_) && (hostnum != FS_HPFS_) && | |
1087 | (hostnum != FS_NTFS_) && (hostnum != FS_VFAT_) && | |
1088 | (hostnum != ACORN_) && | |
1089 | (hostnum != VM_CMS_) && (hostnum != MVS_)) | |
1090 | { /* assume Unix-like */ | |
1091 | switch ((unsigned)(xattr & UNX_IFMT)) { | |
1092 | case (unsigned)UNX_IFDIR: attribs[0] = 'd'; break; | |
1093 | case (unsigned)UNX_IFREG: attribs[0] = '-'; break; | |
1094 | case (unsigned)UNX_IFLNK: attribs[0] = 'l'; break; | |
1095 | case (unsigned)UNX_IFBLK: attribs[0] = 'b'; break; | |
1096 | case (unsigned)UNX_IFCHR: attribs[0] = 'c'; break; | |
1097 | case (unsigned)UNX_IFIFO: attribs[0] = 'p'; break; | |
1098 | case (unsigned)UNX_IFSOCK: attribs[0] = 's'; break; | |
1099 | default: attribs[0] = '?'; break; | |
1100 | } | |
1101 | attribs[1] = (xattr & UNX_IRUSR)? 'r' : '-'; | |
1102 | attribs[4] = (xattr & UNX_IRGRP)? 'r' : '-'; | |
1103 | attribs[7] = (xattr & UNX_IROTH)? 'r' : '-'; | |
1104 | ||
1105 | attribs[2] = (xattr & UNX_IWUSR)? 'w' : '-'; | |
1106 | attribs[5] = (xattr & UNX_IWGRP)? 'w' : '-'; | |
1107 | attribs[8] = (xattr & UNX_IWOTH)? 'w' : '-'; | |
1108 | ||
1109 | if (xattr & UNX_IXUSR) | |
1110 | attribs[3] = (xattr & UNX_ISUID)? 's' : 'x'; | |
1111 | else | |
1112 | attribs[3] = (xattr & UNX_ISUID)? 'S' : '-'; /* S = undefined */ | |
1113 | if (xattr & UNX_IXGRP) | |
1114 | attribs[6] = (xattr & UNX_ISGID)? 's' : 'x'; /* == UNX_ENFMT */ | |
1115 | else | |
1116 | attribs[6] = (xattr & UNX_ISGID)? 'l' : '-'; | |
1117 | if (xattr & UNX_IXOTH) | |
1118 | attribs[9] = (xattr & UNX_ISVTX)? 't' : 'x'; /* "sticky bit" */ | |
1119 | else | |
1120 | attribs[9] = (xattr & UNX_ISVTX)? 'T' : '-'; /* T = undefined */ | |
1121 | attribs[10] = 0; | |
1122 | ||
1123 | Info(slide, 0, ((char *)slide, LoadFarString(UnixFileAttributes), xattr, | |
1124 | attribs)); | |
1125 | ||
1126 | } else { | |
1127 | Info(slide, 0, ((char *)slide, LoadFarString(NonMSDOSFileAttributes), | |
1128 | G.crec.external_file_attributes >> 8)); | |
1129 | ||
1130 | } /* endif (hostnum: external attributes format) */ | |
1131 | ||
1132 | if ((xattr=(ush)(G.crec.external_file_attributes & 0xFF)) == 0) | |
1133 | Info(slide, 0, ((char *)slide, LoadFarString(MSDOSFileAttributes), | |
1134 | xattr)); | |
1135 | else if (xattr == 1) | |
1136 | Info(slide, 0, ((char *)slide, LoadFarString(MSDOSFileAttributesRO), | |
1137 | xattr)); | |
1138 | else | |
1139 | Info(slide, 0, ((char *)slide, LoadFarString(MSDOSFileAttributesAlpha), | |
1140 | xattr, (xattr&1)? "rdo " : nullStr, | |
1141 | (xattr&2)? "hid " : nullStr, | |
1142 | (xattr&4)? "sys " : nullStr, | |
1143 | (xattr&8)? "lab " : nullStr, | |
1144 | (xattr&16)? "dir " : nullStr, | |
1145 | (xattr&32)? "arc" : nullStr)); | |
1146 | ||
1147 | /*--------------------------------------------------------------------------- | |
1148 | Analyze the extra field, if any, and print the file comment, if any (the | |
1149 | filename has already been printed, above). That finishes up this file | |
1150 | entry... | |
1151 | ---------------------------------------------------------------------------*/ | |
1152 | ||
1153 | if (G.crec.extra_field_length > 0) { | |
1154 | uch *ef_ptr = G.extra_field; | |
1155 | ush ef_len = G.crec.extra_field_length; | |
1156 | ush eb_id, eb_datalen; | |
1157 | ZCONST char Far *ef_fieldname; | |
1158 | ||
1159 | if (error_in_archive > PK_WARN) /* fatal: can't continue */ | |
1160 | /* delayed "fatal error" return from extra field reading */ | |
1161 | return error; | |
1162 | if (G.extra_field == (uch *)NULL) | |
1163 | return PK_ERR; /* not consistent with crec length */ | |
1164 | ||
1165 | Info(slide, 0, ((char *)slide, LoadFarString(ExtraFields))); | |
1166 | ||
1167 | while (ef_len >= EB_HEADSIZE) { | |
1168 | eb_id = makeword(&ef_ptr[EB_ID]); | |
1169 | eb_datalen = makeword(&ef_ptr[EB_LEN]); | |
1170 | ef_ptr += EB_HEADSIZE; | |
1171 | ef_len -= EB_HEADSIZE; | |
1172 | ||
1173 | if (eb_datalen > (ush)ef_len) { | |
1174 | Info(slide, 0x421, ((char *)slide, | |
1175 | LoadFarString(ExtraFieldTrunc), eb_id, eb_datalen, ef_len)); | |
1176 | eb_datalen = ef_len; | |
1177 | } | |
1178 | ||
1179 | switch (eb_id) { | |
1180 | case EF_AV: | |
1181 | ef_fieldname = efAV; | |
1182 | break; | |
1183 | case EF_OS2: | |
1184 | ef_fieldname = efOS2; | |
1185 | break; | |
1186 | case EF_ACL: | |
1187 | ef_fieldname = efACL; | |
1188 | break; | |
1189 | case EF_NTSD: | |
1190 | ef_fieldname = efNTSD; | |
1191 | break; | |
1192 | case EF_PKVMS: | |
1193 | ef_fieldname = efPKVMS; | |
1194 | break; | |
1195 | case EF_IZVMS: | |
1196 | ef_fieldname = efIZVMS; | |
1197 | break; | |
1198 | case EF_PKW32: | |
1199 | ef_fieldname = efPKWin32; | |
1200 | break; | |
1201 | case EF_PKUNIX: | |
1202 | ef_fieldname = efPKUnix; | |
1203 | break; | |
1204 | case EF_IZUNIX: | |
1205 | ef_fieldname = efIZUnix; | |
1206 | if (G.crec.version_made_by[1] == UNIX_ && *pEndprev > 0L) | |
1207 | *pEndprev += 4L; /* also have UID/GID in local copy */ | |
1208 | break; | |
1209 | case EF_IZUNIX2: | |
1210 | ef_fieldname = efIZUnix2; | |
1211 | if (*pEndprev > 0L) | |
1212 | *pEndprev += 4L; /* 4 byte UID/GID in local copy */ | |
1213 | break; | |
1214 | case EF_TIME: | |
1215 | ef_fieldname = efTime; | |
1216 | break; | |
1217 | case EF_MAC3: | |
1218 | ef_fieldname = efMac3; | |
1219 | break; | |
1220 | case EF_JLMAC: | |
1221 | ef_fieldname = efJLMac; | |
1222 | break; | |
1223 | case EF_ZIPIT: | |
1224 | ef_fieldname = efZipIt; | |
1225 | break; | |
1226 | case EF_ZIPIT2: | |
1227 | ef_fieldname = efZipIt2; | |
1228 | break; | |
1229 | case EF_VMCMS: | |
1230 | ef_fieldname = efVMCMS; | |
1231 | break; | |
1232 | case EF_MVS: | |
1233 | ef_fieldname = efMVS; | |
1234 | break; | |
1235 | case EF_BEOS: | |
1236 | ef_fieldname = efBeOS; | |
1237 | break; | |
1238 | case EF_QDOS: | |
1239 | ef_fieldname = efQDOS; | |
1240 | break; | |
1241 | case EF_AOSVS: | |
1242 | ef_fieldname = efAOSVS; | |
1243 | break; | |
1244 | case EF_SPARK: /* from RISC OS */ | |
1245 | ef_fieldname = efSpark; | |
1246 | break; | |
1247 | case EF_MD5: | |
1248 | ef_fieldname = efMD5; | |
1249 | break; | |
1250 | case EF_ASIUNIX: | |
1251 | ef_fieldname = efASiUnix; | |
1252 | break; | |
1253 | default: | |
1254 | ef_fieldname = efUnknown; | |
1255 | break; | |
1256 | } | |
1257 | Info(slide, 0, ((char *)slide, LoadFarString(ExtraFieldType), | |
1258 | eb_id, LoadFarStringSmall(ef_fieldname), eb_datalen)); | |
1259 | ||
1260 | /* additional, field-specific information: */ | |
1261 | switch (eb_id) { | |
1262 | case EF_OS2: | |
1263 | case EF_ACL: | |
1264 | if (eb_datalen >= EB_OS2_HLEN) { | |
1265 | if (eb_id == EF_OS2) | |
1266 | ef_fieldname = OS2EAs; | |
1267 | else | |
1268 | ef_fieldname = ACLdata; | |
1269 | Info(slide, 0, ((char *)slide, | |
1270 | LoadFarString(ef_fieldname), makelong(ef_ptr))); | |
1271 | *pEndprev = 0L; /* no clue about csize of local */ | |
1272 | } | |
1273 | break; | |
1274 | case EF_NTSD: | |
1275 | if (eb_datalen >= EB_NTSD_C_LEN) { | |
1276 | Info(slide, 0, ((char *)slide, LoadFarString(NTSDData), | |
1277 | makelong(ef_ptr))); | |
1278 | *pEndprev = 0L; /* no clue about csize of local */ | |
1279 | } | |
1280 | break; | |
1281 | case EF_IZVMS: | |
1282 | if (eb_datalen >= 8) { | |
1283 | char *p, q[8]; | |
1284 | int compr = makeword(ef_ptr+4) & 7; | |
1285 | ||
1286 | *q = '\0'; | |
1287 | if (compr > 3) | |
1288 | compr = 3; | |
1289 | if (strncmp((char *)ef_ptr, "VFAB", 4) == 0) | |
1290 | p = "FAB"; | |
1291 | else if (strncmp((char *)ef_ptr, "VALL", 4) == 0) | |
1292 | p = "XABALL"; | |
1293 | else if (strncmp((char *)ef_ptr, "VFHC", 4) == 0) | |
1294 | p = "XABFHC"; | |
1295 | else if (strncmp((char *)ef_ptr, "VDAT", 4) == 0) | |
1296 | p = "XABDAT"; | |
1297 | else if (strncmp((char *)ef_ptr, "VRDT", 4) == 0) | |
1298 | p = "XABRDT"; | |
1299 | else if (strncmp((char *)ef_ptr, "VPRO", 4) == 0) | |
1300 | p = "XABPRO"; | |
1301 | else if (strncmp((char *)ef_ptr, "VKEY", 4) == 0) | |
1302 | p = "XABKEY"; | |
1303 | else if (strncmp((char *)ef_ptr, "VMSV", 4) == 0) { | |
1304 | p = "version"; | |
1305 | if (eb_datalen >= 16) { | |
1306 | q[0] = ' '; | |
1307 | q[1] = '('; | |
1308 | strncpy(q+2, (char *)ef_ptr+12, 4); | |
1309 | q[6] = ')'; | |
1310 | q[7] = '\0'; | |
1311 | } | |
1312 | } else | |
1313 | p = "version"; | |
1314 | Info(slide, 0, ((char *)slide, LoadFarString(izVMSdata), | |
1315 | LoadFarStringSmall(izVMScomp[compr]), | |
1316 | makeword(ef_ptr+6), p, q)); | |
1317 | } | |
1318 | break; | |
1319 | case EF_TIME: | |
1320 | if (eb_datalen >= 1) { | |
1321 | char types[80]; | |
1322 | int num = 0, len; | |
1323 | ||
1324 | *types = '\0'; | |
1325 | if (*ef_ptr & 1) { | |
1326 | strcpy(types, LoadFarString(UTmodification)); | |
1327 | ++num; | |
1328 | } | |
1329 | if (*ef_ptr & 2) { | |
1330 | len = strlen(types); | |
1331 | if (num) | |
1332 | types[len++] = '/'; | |
1333 | strcpy(types+len, LoadFarString(UTaccess)); | |
1334 | ++num; | |
1335 | if (*pEndprev > 0L) | |
1336 | *pEndprev += 4L; | |
1337 | } | |
1338 | if (*ef_ptr & 4) { | |
1339 | len = strlen(types); | |
1340 | if (num) | |
1341 | types[len++] = '/'; | |
1342 | strcpy(types+len, LoadFarString(UTcreation)); | |
1343 | ++num; | |
1344 | if (*pEndprev > 0L) | |
1345 | *pEndprev += 4L; | |
1346 | } | |
1347 | if (num > 0) | |
1348 | Info(slide, 0, ((char *)slide, | |
1349 | LoadFarString(UTdata), types, | |
1350 | num == 1? nullStr : "s")); | |
1351 | } | |
1352 | break; | |
1353 | case EF_MAC3: | |
1354 | if (eb_datalen >= EB_MAC3_HLEN) { | |
1355 | ulg eb_uc = makelong(ef_ptr); | |
1356 | unsigned mac3_flgs = makeword(ef_ptr+EB_FLGS_OFFS); | |
1357 | unsigned eb_is_uc = mac3_flgs & EB_M3_FL_UNCMPR; | |
1358 | ||
1359 | Info(slide, 0, ((char *)slide, LoadFarString(Mac3data), | |
1360 | eb_uc, eb_is_uc ? "un" : nullStr)); | |
1361 | if (eb_is_uc) { | |
1362 | if (*pEndprev > 0L) | |
1363 | *pEndprev += makelong(ef_ptr); | |
1364 | } else { | |
1365 | *pEndprev = 0L; /* no clue about csize of local */ | |
1366 | } | |
1367 | ||
1368 | Info(slide, 0, ((char *)slide, | |
1369 | LoadFarString(MacOSMAC3flags), | |
1370 | LoadFarStringSmall(mac3_flgs & EB_M3_FL_DATFRK ? | |
1371 | MacOS_DF : MacOS_RF), | |
1372 | (mac3_flgs & EB_M3_FL_TIME64 ? 64 : 32))); | |
1373 | zi_showMacTypeCreator(__G__ &ef_ptr[6]); | |
1374 | } | |
1375 | break; | |
1376 | case EF_ZIPIT2: | |
1377 | if (eb_datalen >= 5 && | |
1378 | strncmp((char *)ef_ptr, "ZPIT", 4) == 0) { | |
1379 | ||
1380 | if (eb_datalen >= 12) { | |
1381 | zi_showMacTypeCreator(__G__ &ef_ptr[4]); | |
1382 | } | |
1383 | } | |
1384 | ||
1385 | case EF_ZIPIT: | |
1386 | if (eb_datalen >= 5 && | |
1387 | strncmp((char *)ef_ptr, "ZPIT", 4) == 0) { | |
1388 | unsigned fnlen = ef_ptr[4]; | |
1389 | ||
1390 | if (eb_datalen >= fnlen + (5 + 8)) { | |
1391 | uch nullchar = ef_ptr[fnlen+5]; | |
1392 | ||
1393 | ef_ptr[fnlen+5] = '\0'; /* terminate filename */ | |
1394 | Info(slide, 0, ((char *)slide, | |
1395 | LoadFarString(ZipItFname), (char *)ef_ptr+5)); | |
1396 | ef_ptr[fnlen+5] = nullchar; | |
1397 | zi_showMacTypeCreator(__G__ &ef_ptr[fnlen+5]); | |
1398 | } | |
1399 | } | |
1400 | break; | |
1401 | case EF_JLMAC: | |
1402 | if (eb_datalen >= 40 && | |
1403 | strncmp((char *)ef_ptr, "JLEE", 4) == 0) | |
1404 | { | |
1405 | zi_showMacTypeCreator(__G__ &ef_ptr[4]); | |
1406 | ||
1407 | Info(slide, 0, ((char *)slide, | |
1408 | LoadFarString(MacOSJLEEflags), | |
1409 | LoadFarStringSmall(ef_ptr[31] & 1 ? | |
1410 | MacOS_DF : MacOS_RF))); | |
1411 | } | |
1412 | break; | |
1413 | #ifdef CMS_MVS | |
1414 | case EF_VMCMS: | |
1415 | case EF_MVS: | |
1416 | { | |
1417 | char type[100]; | |
1418 | ||
1419 | Info(slide, 0, ((char *)slide, | |
1420 | LoadFarString(VmMvsExtraField), | |
1421 | (getVMMVSexfield(type, ef_ptr-EB_HEADSIZE, | |
1422 | (unsigned)eb_datalen) > 0)? | |
1423 | type : LoadFarStringSmall(VmMvsInvalid))); | |
1424 | } | |
1425 | break; | |
1426 | #endif /* CMS_MVS */ | |
1427 | case EF_BEOS: | |
1428 | if (eb_datalen >= EB_BEOS_HLEN) { | |
1429 | ulg eb_uc = makelong(ef_ptr); | |
1430 | unsigned eb_is_uc = | |
1431 | *(ef_ptr+EB_FLGS_OFFS) & EB_BE_FL_UNCMPR; | |
1432 | ||
1433 | Info(slide, 0, ((char *)slide, LoadFarString(BeOSdata), | |
1434 | eb_uc, eb_is_uc ? "un" : nullStr)); | |
1435 | if (eb_is_uc) { | |
1436 | if (*pEndprev > 0L) | |
1437 | *pEndprev += makelong(ef_ptr); | |
1438 | } else { | |
1439 | *pEndprev = 0L; /* no clue about csize of local */ | |
1440 | } | |
1441 | } | |
1442 | break; | |
1443 | case EF_QDOS: | |
1444 | if (eb_datalen >= 4) { | |
1445 | Info(slide, 0, ((char *)slide, LoadFarString(QDOSdata), | |
1446 | ef_ptr[0], ef_ptr[1], ef_ptr[2], ef_ptr[3])); | |
1447 | } | |
1448 | break; | |
1449 | case EF_AOSVS: | |
1450 | if (eb_datalen >= 5) { | |
1451 | Info(slide, 0, ((char *)slide, LoadFarString(AOSVSdata), | |
1452 | ((int)(uch)ef_ptr[4])/10, ((int)(uch)ef_ptr[4])%10)); | |
1453 | } | |
1454 | break; | |
1455 | case EF_MD5: | |
1456 | if (eb_datalen >= 19) { | |
1457 | char md5[33]; | |
1458 | int i; | |
1459 | ||
1460 | for (i = 0; i < 16; ++i) | |
1461 | sprintf(&md5[i<<1], "%02x", ef_ptr[15-i]); | |
1462 | md5[32] = '\0'; | |
1463 | Info(slide, 0, ((char *)slide, LoadFarString(MD5data), | |
1464 | md5)); | |
1465 | break; | |
1466 | } /* else: fall through !! */ | |
1467 | default: | |
1468 | if (eb_datalen > 0) { | |
1469 | ush i, n; | |
1470 | ||
1471 | if (eb_datalen <= 24) { | |
1472 | Info(slide, 0, ((char *)slide, | |
1473 | LoadFarString(ColonIndent))); | |
1474 | n = eb_datalen; | |
1475 | } else { | |
1476 | Info(slide, 0, ((char *)slide, | |
1477 | LoadFarString(First20))); | |
1478 | n = 20; | |
1479 | } | |
1480 | for (i = 0; i < n; ++i) | |
1481 | Info(slide, 0, ((char *)slide, | |
1482 | LoadFarString(efFormat), ef_ptr[i])); | |
1483 | } | |
1484 | break; | |
1485 | } | |
1486 | (*G.message)((zvoid *)&G, (uch *)".", 1L, 0); | |
1487 | ||
1488 | ef_ptr += eb_datalen; | |
1489 | ef_len -= eb_datalen; | |
1490 | } | |
1491 | (*G.message)((zvoid *)&G, (uch *)"\n", 1L, 0); | |
1492 | } | |
1493 | ||
1494 | /* high bit == Unix/OS2/NT GMT times (mtime, atime); next bit == UID/GID */ | |
1495 | if ((xattr = (ush)((G.crec.external_file_attributes & 0xC000) >> 12)) & 8) | |
1496 | { | |
1497 | if (hostnum == UNIX_ || hostnum == FS_HPFS_ || hostnum == FS_NTFS_) | |
1498 | { | |
1499 | Info(slide, 0, ((char *)slide, LoadFarString(lExtraFieldType), | |
1500 | "is", EF_IZUNIX, LoadFarStringSmall(efIZUnix), | |
1501 | (unsigned)(xattr&12), (xattr&4)? efIZuid : efIZnouid)); | |
1502 | if (*pEndprev > 0L) | |
1503 | *pEndprev += (ulg)(xattr&12); | |
1504 | } | |
1505 | else if (hostnum == FS_FAT_ && !(xattr&4)) | |
1506 | Info(slide, 0, ((char *)slide, LoadFarString(lExtraFieldType), | |
1507 | "may be", EF_IZUNIX, LoadFarStringSmall(efIZUnix), 8, | |
1508 | efIZnouid)); | |
1509 | } | |
1510 | ||
1511 | if (!G.crec.file_comment_length) | |
1512 | Info(slide, 0, ((char *)slide, LoadFarString(NoFileComment))); | |
1513 | else { | |
1514 | Info(slide, 0, ((char *)slide, LoadFarString(FileCommBegin))); | |
1515 | if ((error = do_string(__G__ G.crec.file_comment_length, DISPL_8)) != | |
1516 | PK_COOL) | |
1517 | { | |
1518 | error_in_archive = error; /* might be warning */ | |
1519 | if (error > PK_WARN) /* fatal */ | |
1520 | return error; | |
1521 | } | |
1522 | Info(slide, 0, ((char *)slide, LoadFarString(FileCommEnd))); | |
1523 | } | |
1524 | ||
1525 | return error_in_archive; | |
1526 | ||
1527 | } /* end function zi_long() */ | |
1528 | ||
1529 | ||
1530 | ||
1531 | ||
1532 | ||
1533 | /*************************/ | |
1534 | /* Function zi_short() */ | |
1535 | /*************************/ | |
1536 | ||
1537 | static int zi_short(__G) /* return PK-type error code */ | |
1538 | __GDEF | |
1539 | { | |
1540 | #ifdef USE_EF_UT_TIME | |
1541 | iztimes z_utime; | |
1542 | time_t *z_modtim; | |
1543 | #endif | |
1544 | int k, error, error_in_archive=PK_COOL; | |
1545 | ush methnum, hostnum, hostver, xattr; | |
1546 | char *p, workspace[12], attribs[16]; | |
1547 | char methbuf[5]; | |
1548 | static ZCONST char dtype[5]="NXFS"; /* normal, maximum, fast, superfast */ | |
1549 | static ZCONST char Far os[NUM_HOSTS+1][4] = { | |
1550 | "fat", "ami", "vms", "unx", "cms", "atr", "hpf", "mac", "zzz", | |
1551 | "cpm", "t20", "ntf", "qds", "aco", "vft", "mvs", "be ", "nsk", | |
1552 | "???" | |
1553 | }; | |
1554 | static ZCONST char Far method[NUM_METHODS+1][5] = { | |
1555 | "stor", "shrk", "re:1", "re:2", "re:3", "re:4", "i#:#", "tokn", | |
1556 | "def#", "edef", "dcli", "u###" | |
1557 | }; | |
1558 | ||
1559 | ||
1560 | /*--------------------------------------------------------------------------- | |
1561 | Print out various interesting things about the compressed file. | |
1562 | ---------------------------------------------------------------------------*/ | |
1563 | ||
1564 | methnum = (ush)MIN(G.crec.compression_method, NUM_METHODS); | |
1565 | hostnum = (ush)(G.pInfo->hostnum); | |
1566 | hostver = G.crec.version_made_by[0]; | |
1567 | /* | |
1568 | extnum = MIN(G.crec.version_needed_to_extract[1], NUM_HOSTS); | |
1569 | extver = G.crec.version_needed_to_extract[0]; | |
1570 | */ | |
1571 | ||
1572 | zfstrcpy(methbuf, method[methnum]); | |
1573 | if (methnum == IMPLODED) { | |
1574 | methbuf[1] = (char)((G.crec.general_purpose_bit_flag & 2)? '8' : '4'); | |
1575 | methbuf[3] = (char)((G.crec.general_purpose_bit_flag & 4)? '3' : '2'); | |
1576 | } else if (methnum == DEFLATED) { | |
1577 | ush dnum=(ush)((G.crec.general_purpose_bit_flag>>1) & 3); | |
1578 | methbuf[3] = dtype[dnum]; | |
1579 | } else if (methnum >= NUM_METHODS) { /* unknown */ | |
1580 | sprintf(&methbuf[1], "%03u", G.crec.compression_method); | |
1581 | } | |
1582 | ||
1583 | for (k = 0; k < 15; ++k) | |
1584 | attribs[k] = ' '; | |
1585 | attribs[15] = 0; | |
1586 | ||
1587 | xattr = (ush)((G.crec.external_file_attributes >> 16) & 0xFFFF); | |
1588 | switch (hostnum) { | |
1589 | case VMS_: | |
1590 | { int i, j; | |
1591 | ||
1592 | for (k = 0; k < 12; ++k) | |
1593 | workspace[k] = 0; | |
1594 | if (xattr & VMS_IRUSR) | |
1595 | workspace[0] = 'R'; | |
1596 | if (xattr & VMS_IWUSR) { | |
1597 | workspace[1] = 'W'; | |
1598 | workspace[3] = 'D'; | |
1599 | } | |
1600 | if (xattr & VMS_IXUSR) | |
1601 | workspace[2] = 'E'; | |
1602 | if (xattr & VMS_IRGRP) | |
1603 | workspace[4] = 'R'; | |
1604 | if (xattr & VMS_IWGRP) { | |
1605 | workspace[5] = 'W'; | |
1606 | workspace[7] = 'D'; | |
1607 | } | |
1608 | if (xattr & VMS_IXGRP) | |
1609 | workspace[6] = 'E'; | |
1610 | if (xattr & VMS_IROTH) | |
1611 | workspace[8] = 'R'; | |
1612 | if (xattr & VMS_IWOTH) { | |
1613 | workspace[9] = 'W'; | |
1614 | workspace[11] = 'D'; | |
1615 | } | |
1616 | if (xattr & VMS_IXOTH) | |
1617 | workspace[10] = 'E'; | |
1618 | ||
1619 | p = attribs; | |
1620 | for (k = j = 0; j < 3; ++j) { /* groups of permissions */ | |
1621 | for (i = 0; i < 4; ++i, ++k) /* perms within a group */ | |
1622 | if (workspace[k]) | |
1623 | *p++ = workspace[k]; | |
1624 | *p++ = ','; /* group separator */ | |
1625 | } | |
1626 | *--p = ' '; /* overwrite last comma */ | |
1627 | if ((p - attribs) < 12) | |
1628 | sprintf(&attribs[12], "%d.%d", hostver/10, hostver%10); | |
1629 | } | |
1630 | break; | |
1631 | ||
1632 | case FS_FAT_: | |
1633 | case FS_HPFS_: | |
1634 | case FS_NTFS_: | |
1635 | case VM_CMS_: | |
1636 | case FS_VFAT_: | |
1637 | case MVS_: | |
1638 | case ACORN_: | |
1639 | xattr = (ush)(G.crec.external_file_attributes & 0xFF); | |
1640 | sprintf(attribs, ".r.-... %d.%d", hostver/10, hostver%10); | |
1641 | attribs[2] = (xattr & 0x01)? '-' : 'w'; | |
1642 | attribs[5] = (xattr & 0x02)? 'h' : '-'; | |
1643 | attribs[6] = (xattr & 0x04)? 's' : '-'; | |
1644 | attribs[4] = (xattr & 0x20)? 'a' : '-'; | |
1645 | if (xattr & 0x10) { | |
1646 | attribs[0] = 'd'; | |
1647 | attribs[3] = 'x'; | |
1648 | } else | |
1649 | attribs[0] = '-'; | |
1650 | if (IS_VOLID(xattr)) | |
1651 | attribs[0] = 'V'; | |
1652 | else if ((p = strrchr(G.filename, '.')) != (char *)NULL) { | |
1653 | ++p; | |
1654 | if (STRNICMP(p, "com", 3) == 0 || STRNICMP(p, "exe", 3) == 0 || | |
1655 | STRNICMP(p, "btm", 3) == 0 || STRNICMP(p, "cmd", 3) == 0 || | |
1656 | STRNICMP(p, "bat", 3) == 0) | |
1657 | attribs[3] = 'x'; | |
1658 | } | |
1659 | break; | |
1660 | ||
1661 | case AMIGA_: | |
1662 | switch (xattr & AMI_IFMT) { | |
1663 | case AMI_IFDIR: attribs[0] = 'd'; break; | |
1664 | case AMI_IFREG: attribs[0] = '-'; break; | |
1665 | default: attribs[0] = '?'; break; | |
1666 | } | |
1667 | attribs[1] = (xattr & AMI_IHIDDEN)? 'h' : '-'; | |
1668 | attribs[2] = (xattr & AMI_ISCRIPT)? 's' : '-'; | |
1669 | attribs[3] = (xattr & AMI_IPURE)? 'p' : '-'; | |
1670 | attribs[4] = (xattr & AMI_IARCHIVE)? 'a' : '-'; | |
1671 | attribs[5] = (xattr & AMI_IREAD)? 'r' : '-'; | |
1672 | attribs[6] = (xattr & AMI_IWRITE)? 'w' : '-'; | |
1673 | attribs[7] = (xattr & AMI_IEXECUTE)? 'e' : '-'; | |
1674 | attribs[8] = (xattr & AMI_IDELETE)? 'd' : '-'; | |
1675 | sprintf(&attribs[12], "%d.%d", hostver/10, hostver%10); | |
1676 | break; | |
1677 | ||
1678 | default: /* assume Unix-like */ | |
1679 | switch ((unsigned)(xattr & UNX_IFMT)) { | |
1680 | case (unsigned)UNX_IFDIR: attribs[0] = 'd'; break; | |
1681 | case (unsigned)UNX_IFREG: attribs[0] = '-'; break; | |
1682 | case (unsigned)UNX_IFLNK: attribs[0] = 'l'; break; | |
1683 | case (unsigned)UNX_IFBLK: attribs[0] = 'b'; break; | |
1684 | case (unsigned)UNX_IFCHR: attribs[0] = 'c'; break; | |
1685 | case (unsigned)UNX_IFIFO: attribs[0] = 'p'; break; | |
1686 | case (unsigned)UNX_IFSOCK: attribs[0] = 's'; break; | |
1687 | default: attribs[0] = '?'; break; | |
1688 | } | |
1689 | attribs[1] = (xattr & UNX_IRUSR)? 'r' : '-'; | |
1690 | attribs[4] = (xattr & UNX_IRGRP)? 'r' : '-'; | |
1691 | attribs[7] = (xattr & UNX_IROTH)? 'r' : '-'; | |
1692 | attribs[2] = (xattr & UNX_IWUSR)? 'w' : '-'; | |
1693 | attribs[5] = (xattr & UNX_IWGRP)? 'w' : '-'; | |
1694 | attribs[8] = (xattr & UNX_IWOTH)? 'w' : '-'; | |
1695 | ||
1696 | if (xattr & UNX_IXUSR) | |
1697 | attribs[3] = (xattr & UNX_ISUID)? 's' : 'x'; | |
1698 | else | |
1699 | attribs[3] = (xattr & UNX_ISUID)? 'S' : '-'; /* S==undefined */ | |
1700 | if (xattr & UNX_IXGRP) | |
1701 | attribs[6] = (xattr & UNX_ISGID)? 's' : 'x'; /* == UNX_ENFMT */ | |
1702 | else | |
1703 | /* attribs[6] = (xattr & UNX_ISGID)? 'l' : '-'; real 4.3BSD */ | |
1704 | attribs[6] = (xattr & UNX_ISGID)? 'S' : '-'; /* SunOS 4.1.x */ | |
1705 | if (xattr & UNX_IXOTH) | |
1706 | attribs[9] = (xattr & UNX_ISVTX)? 't' : 'x'; /* "sticky bit" */ | |
1707 | else | |
1708 | attribs[9] = (xattr & UNX_ISVTX)? 'T' : '-'; /* T==undefined */ | |
1709 | ||
1710 | sprintf(&attribs[12], "%d.%d", hostver/10, hostver%10); | |
1711 | break; | |
1712 | ||
1713 | } /* end switch (hostnum: external attributes format) */ | |
1714 | ||
1715 | Info(slide, 0, ((char *)slide, "%s %s %8lu ", attribs, | |
1716 | LoadFarStringSmall(os[hostnum]), G.crec.ucsize)); | |
1717 | Info(slide, 0, ((char *)slide, "%c", | |
1718 | (G.crec.general_purpose_bit_flag & 1)? | |
1719 | ((G.crec.internal_file_attributes & 1)? 'T' : 'B') : /* encrypted */ | |
1720 | ((G.crec.internal_file_attributes & 1)? 't' : 'b'))); /* plaintext */ | |
1721 | k = (G.crec.extra_field_length || | |
1722 | /* a local-only "UX" (old Unix/OS2/NT GMT times "IZUNIX") e.f.? */ | |
1723 | ((G.crec.external_file_attributes & 0x8000) && | |
1724 | (hostnum == UNIX_ || hostnum == FS_HPFS_ || hostnum == FS_NTFS_))); | |
1725 | Info(slide, 0, ((char *)slide, "%c", k? | |
1726 | ((G.crec.general_purpose_bit_flag & 8)? 'X' : 'x') : /* extra field */ | |
1727 | ((G.crec.general_purpose_bit_flag & 8)? 'l' : '-'))); /* no extra field */ | |
1728 | /* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ extended local header or not */ | |
1729 | ||
1730 | if (uO.lflag == 4) { | |
1731 | ulg csiz = G.crec.csize; | |
1732 | ||
1733 | if (G.crec.general_purpose_bit_flag & 1) | |
1734 | csiz -= 12; /* if encrypted, don't count encryption header */ | |
1735 | Info(slide, 0, ((char *)slide, "%3d%%", | |
1736 | (ratio(G.crec.ucsize,csiz)+5)/10)); | |
1737 | } else if (uO.lflag == 5) | |
1738 | Info(slide, 0, ((char *)slide, " %8lu", G.crec.csize)); | |
1739 | ||
1740 | /* Read the extra field, if any. The extra field info may be used | |
1741 | * in the file modification time section, below. | |
1742 | */ | |
1743 | if ((error = do_string(__G__ G.crec.extra_field_length, EXTRA_FIELD)) != 0) | |
1744 | { | |
1745 | if (G.extra_field != NULL) { | |
1746 | free(G.extra_field); | |
1747 | G.extra_field = NULL; | |
1748 | } | |
1749 | error_in_archive = error; | |
1750 | /* We do not return prematurely in case of a "fatal" error (PK_EOF). | |
1751 | * This does not hurt here, because we do not need to read from the | |
1752 | * zipfile again before the end of this function. | |
1753 | */ | |
1754 | } | |
1755 | ||
1756 | /* For printing of date & time, a "char d_t_buf[16]" is required. | |
1757 | * To save stack space, we reuse the "char attribs[16]" buffer whose | |
1758 | * content is no longer needed. | |
1759 | */ | |
1760 | # define d_t_buf attribs | |
1761 | #ifdef USE_EF_UT_TIME | |
1762 | z_modtim = G.extra_field && | |
1763 | #ifdef IZ_CHECK_TZ | |
1764 | G.tz_is_valid && | |
1765 | #endif | |
1766 | (ef_scan_for_izux(G.extra_field, G.crec.extra_field_length, 1, | |
1767 | G.crec.last_mod_dos_datetime, &z_utime, NULL) | |
1768 | & EB_UT_FL_MTIME) | |
1769 | ? &z_utime.mtime : NULL; | |
1770 | TIMET_TO_NATIVE(z_utime.mtime) /* NOP unless MSC 7.0 or Macintosh */ | |
1771 | d_t_buf[0] = (char)0; /* signal "show local time" */ | |
1772 | #else | |
1773 | # define z_modtim NULL | |
1774 | #endif | |
1775 | Info(slide, 0, ((char *)slide, " %s %s ", methbuf, | |
1776 | zi_time(__G__ &G.crec.last_mod_dos_datetime, z_modtim, d_t_buf))); | |
1777 | fnprint(__G); | |
1778 | ||
1779 | /*--------------------------------------------------------------------------- | |
1780 | Skip the file comment, if any (the filename has already been printed, | |
1781 | above). That finishes up this file entry... | |
1782 | ---------------------------------------------------------------------------*/ | |
1783 | ||
1784 | SKIP_(G.crec.file_comment_length) | |
1785 | ||
1786 | return error_in_archive; | |
1787 | ||
1788 | } /* end function zi_short() */ | |
1789 | ||
1790 | ||
1791 | ||
1792 | ||
1793 | ||
1794 | /**************************************/ | |
1795 | /* Function zi_showMacTypeCreator() */ | |
1796 | /**************************************/ | |
1797 | ||
1798 | static void zi_showMacTypeCreator(__G__ ebfield) | |
1799 | __GDEF | |
1800 | uch *ebfield; | |
1801 | { | |
1802 | /* not every Type / Creator character is printable */ | |
1803 | if (isprint(ebfield[0]) && isprint(ebfield[1]) && | |
1804 | isprint(ebfield[2]) && isprint(ebfield[3]) && | |
1805 | isprint(ebfield[4]) && isprint(ebfield[5]) && | |
1806 | isprint(ebfield[6]) && isprint(ebfield[7])) { | |
1807 | Info(slide, 0, ((char *)slide, LoadFarString(MacOSdata), | |
1808 | ebfield[0], ebfield[1], ebfield[2], ebfield[3], | |
1809 | ebfield[4], ebfield[5], ebfield[6], ebfield[7])); | |
1810 | } else { | |
1811 | Info(slide, 0, ((char *)slide, LoadFarString(MacOSdata1), | |
1812 | (((ulg)ebfield[0]) << 24) + | |
1813 | (((ulg)ebfield[1]) << 16) + | |
1814 | (((ulg)ebfield[2]) << 8) + | |
1815 | ((ulg)ebfield[3]), | |
1816 | (((ulg)ebfield[4]) << 24) + | |
1817 | (((ulg)ebfield[5]) << 16) + | |
1818 | (((ulg)ebfield[6]) << 8) + | |
1819 | ((ulg)ebfield[7]))); | |
1820 | } | |
1821 | } /* end function zi_showMacTypeCreator() */ | |
1822 | ||
1823 | ||
1824 | ||
1825 | ||
1826 | ||
1827 | /************************/ | |
1828 | /* Function zi_time() */ | |
1829 | /************************/ | |
1830 | ||
1831 | static char *zi_time(__G__ datetimez, modtimez, d_t_str) | |
1832 | __GDEF | |
1833 | ZCONST ulg *datetimez; | |
1834 | ZCONST time_t *modtimez; | |
1835 | char *d_t_str; | |
1836 | { | |
1837 | unsigned yr, mo, dy, hh, mm, ss; | |
1838 | char monthbuf[4]; | |
1839 | ZCONST char *monthstr; | |
1840 | static ZCONST char Far month[12][4] = { | |
1841 | "Jan", "Feb", "Mar", "Apr", "May", "Jun", | |
1842 | "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" | |
1843 | }; | |
1844 | #ifdef USE_EF_UT_TIME | |
1845 | struct tm *t; | |
1846 | #endif | |
1847 | ||
1848 | ||
1849 | ||
1850 | /*--------------------------------------------------------------------------- | |
1851 | Convert the file-modification date and time info to a string of the form | |
1852 | "1991 Feb 23 17:15:00", "23-Feb-91 17:15" or "19910223.171500", depending | |
1853 | on values of lflag and T_flag. If using Unix-time extra fields, convert | |
1854 | to local time or not, depending on value of first character in d_t_str[]. | |
1855 | ---------------------------------------------------------------------------*/ | |
1856 | ||
1857 | #ifdef USE_EF_UT_TIME | |
1858 | if (modtimez != NULL) { | |
1859 | #ifndef NO_GMTIME | |
1860 | /* check for our secret message from above... */ | |
1861 | t = (d_t_str[0] == (char)1)? gmtime(modtimez) : localtime(modtimez); | |
1862 | #else | |
1863 | t = localtime(modtimez); | |
1864 | #endif | |
1865 | if (uO.lflag > 9 && t == (struct tm *)NULL) | |
1866 | /* time conversion error in verbose listing format, | |
1867 | * return string with '?' instead of data | |
1868 | */ | |
1869 | return (strcpy(d_t_str, LoadFarString(YMDHMSTimeError))); | |
1870 | } else | |
1871 | t = (struct tm *)NULL; | |
1872 | if (t != (struct tm *)NULL) { | |
1873 | mo = (unsigned)(t->tm_mon + 1); | |
1874 | dy = (unsigned)(t->tm_mday); | |
1875 | yr = (unsigned)(t->tm_year); | |
1876 | ||
1877 | hh = (unsigned)(t->tm_hour); | |
1878 | mm = (unsigned)(t->tm_min); | |
1879 | ss = (unsigned)(t->tm_sec); | |
1880 | } else | |
1881 | #endif /* USE_EF_UT_TIME */ | |
1882 | { | |
1883 | yr = ((unsigned)(*datetimez >> 25) & 0x7f) + 80; | |
1884 | mo = ((unsigned)(*datetimez >> 21) & 0x0f); | |
1885 | dy = ((unsigned)(*datetimez >> 16) & 0x1f); | |
1886 | ||
1887 | hh = (((unsigned)*datetimez >> 11) & 0x1f); | |
1888 | mm = (((unsigned)*datetimez >> 5) & 0x3f); | |
1889 | ss = (((unsigned)*datetimez << 1) & 0x3e); | |
1890 | } | |
1891 | ||
1892 | if (mo == 0 || mo > 12) { | |
1893 | sprintf(monthbuf, LoadFarString(BogusFmt), mo); | |
1894 | monthstr = monthbuf; | |
1895 | } else | |
1896 | monthstr = LoadFarStringSmall(month[mo-1]); | |
1897 | ||
1898 | if (uO.lflag > 9) /* verbose listing format */ | |
1899 | sprintf(d_t_str, LoadFarString(YMDHMSTime), yr+1900, monthstr, dy, hh, | |
1900 | mm, ss); | |
1901 | else if (uO.T_flag) | |
1902 | sprintf(d_t_str, LoadFarString(DecimalTime), yr+1900, mo, dy, hh, mm, | |
1903 | ss); | |
1904 | else /* was: if ((uO.lflag >= 3) && (uO.lflag <= 5)) */ | |
1905 | sprintf(d_t_str, LoadFarString(DMYHMTime), dy, monthstr, yr%100, hh, | |
1906 | mm); | |
1907 | ||
1908 | return d_t_str; | |
1909 | ||
1910 | } /* end function zi_time() */ | |
1911 | ||
1912 | #endif /* !NO_ZIPINFO */ |