Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

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