]> git.saurik.com Git - wxWidgets.git/blob - utils/Install/packzip/zipinfo.c
fixed a race condition resulting in returning incorrect thread exit code
[wxWidgets.git] / utils / Install / packzip / zipinfo.c
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 */