~ubuntu-branches/ubuntu/intrepid/unzip/intrepid

« back to all changes in this revision

Viewing changes to zipinfo.c

  • Committer: Bazaar Package Importer
  • Author(s): Santiago Vila
  • Date: 2004-06-06 17:57:46 UTC
  • Revision ID: james.westby@ubuntu.com-20040606175746-nl7p2dgp3aobyc2c
Tags: upstream-5.51
ImportĀ upstreamĀ versionĀ 5.51

Show diffs side-by-side

added added

removed removed

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