~ubuntu-branches/ubuntu/precise/boinc/precise

« back to all changes in this revision

Viewing changes to zip/unzip/list.c

Tags: 6.12.8+dfsg-1
* New upstream release.
* Simplified debian/rules

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
  Copyright (c) 1990-2001 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
 
  list.c
12
 
 
13
 
  This file contains the non-ZipInfo-specific listing routines for UnZip.
14
 
 
15
 
  Contains:  list_files()
16
 
             get_time_stamp()   [optional feature]
17
 
             ratio()
18
 
             fnprint()
19
 
 
20
 
  ---------------------------------------------------------------------------*/
21
 
 
22
 
 
23
 
#define UNZIP_INTERNAL
24
 
#include "unzip.h"
25
 
#ifdef WINDLL
26
 
#  ifdef POCKET_UNZIP
27
 
#    include "wince/intrface.h"
28
 
#  else
29
 
#    include "windll/windll.h"
30
 
#  endif
31
 
#endif
32
 
 
33
 
 
34
 
#ifdef TIMESTAMP
35
 
   static int  fn_is_dir   OF((__GPRO));
36
 
#endif
37
 
 
38
 
#ifndef WINDLL
39
 
   static ZCONST char Far CompFactorStr[] = "%c%d%%";
40
 
   static ZCONST char Far CompFactor100[] = "100%%";
41
 
 
42
 
#ifdef OS2_EAS
43
 
   static ZCONST char Far HeadersS[]  =
44
 
     "  Length     EAs   ACLs    Date   Time    Name";
45
 
   static ZCONST char Far HeadersS1[] =
46
 
     " --------    ---   ----    ----   ----    ----";
47
 
#else
48
 
   static ZCONST char Far HeadersS[]  = "  Length     Date   Time    Name";
49
 
   static ZCONST char Far HeadersS1[] = " --------    ----   ----    ----";
50
 
#endif
51
 
 
52
 
   static ZCONST char Far HeadersL[]  =
53
 
     " Length   Method    Size  Ratio   Date   Time   CRC-32    Name";
54
 
   static ZCONST char Far HeadersL1[] =
55
 
     "--------  ------  ------- -----   ----   ----   ------    ----";
56
 
   static ZCONST char Far *Headers[][2] =
57
 
     { {HeadersS, HeadersS1}, {HeadersL, HeadersL1} };
58
 
 
59
 
   static ZCONST char Far CaseConversion[] =
60
 
     "%s (\"^\" ==> case\n%s   conversion)\n";
61
 
   static ZCONST char Far LongHdrStats[] =
62
 
     "%8lu  %-7s%8lu %4s  %02u-%02u-%02u %02u:%02u  %08lx %c";
63
 
   static ZCONST char Far LongFileTrailer[] =
64
 
     "--------          -------  ---                       \
65
 
     -------\n%8lu         %8lu %4s                            %lu file%s\n";
66
 
#ifdef OS2_EAS
67
 
   static ZCONST char Far ShortHdrStats[] =
68
 
     "%9lu %6lu %6lu  %02u-%02u-%02u %02u:%02u  %c";
69
 
   static ZCONST char Far ShortFileTrailer[] = " --------  -----  -----       \
70
 
            -------\n%9lu %6lu %6lu                   %lu file%s\n";
71
 
   static ZCONST char Far OS2ExtAttrTrailer[] =
72
 
     "%lu file%s %lu bytes of OS/2 extended attributes attached.\n";
73
 
   static ZCONST char Far OS2ACLTrailer[] =
74
 
     "%lu file%s %lu bytes of access control lists attached.\n";
75
 
#else
76
 
   static ZCONST char Far ShortHdrStats[] =
77
 
     "%9lu  %02u-%02u-%02u %02u:%02u  %c";
78
 
   static ZCONST char Far ShortFileTrailer[] = " --------       \
79
 
            -------\n%9lu                   %lu file%s\n";
80
 
#endif /* ?OS2_EAS */
81
 
#endif /* !WINDLL */
82
 
 
83
 
 
84
 
 
85
 
 
86
 
 
87
 
/*************************/
88
 
/* Function list_files() */
89
 
/*************************/
90
 
 
91
 
int list_files(__G)    /* return PK-type error code */
92
 
    __GDEF
93
 
{
94
 
    int do_this_file=FALSE, cfactor, error, error_in_archive=PK_COOL;
95
 
#ifndef WINDLL
96
 
    char sgn, cfactorstr[10];
97
 
    int longhdr=(uO.vflag>1);
98
 
#endif
99
 
    int date_format;
100
 
    ulg j, members=0L;
101
 
    unsigned methnum;
102
 
#ifdef USE_EF_UT_TIME
103
 
    iztimes z_utime;
104
 
    struct tm *t;
105
 
#endif
106
 
    unsigned yr, mo, dy, hh, mm;
107
 
    ulg csiz, tot_csize=0L, tot_ucsize=0L;
108
 
#ifdef OS2_EAS
109
 
    ulg ea_size, tot_easize=0L, tot_eafiles=0L;
110
 
    ulg acl_size, tot_aclsize=0L, tot_aclfiles=0L;
111
 
#endif
112
 
    min_info info;
113
 
    char methbuf[8];
114
 
    static ZCONST char dtype[]="NXFS";  /* see zi_short() */
115
 
    static ZCONST char Far method[NUM_METHODS+1][8] =
116
 
        {"Stored", "Shrunk", "Reduce1", "Reduce2", "Reduce3", "Reduce4",
117
 
         "Implode", "Token", "Defl:#", "Def64#", "ImplDCL", "Unk:###"};
118
 
 
119
 
 
120
 
 
121
 
/*---------------------------------------------------------------------------
122
 
    Unlike extract_or_test_files(), this routine confines itself to the cen-
123
 
    tral directory.  Thus its structure is somewhat simpler, since we can do
124
 
    just a single loop through the entire directory, listing files as we go.
125
 
 
126
 
    So to start off, print the heading line and then begin main loop through
127
 
    the central directory.  The results will look vaguely like the following:
128
 
 
129
 
 Length   Method    Size  Ratio   Date   Time   CRC-32    Name ("^" ==> case
130
 
--------  ------  ------- -----   ----   ----   ------    ----   conversion)
131
 
   44004  Implode   13041  71%  11-02-89 19:34  8b4207f7  Makefile.UNIX
132
 
    3438  Shrunk     2209  36%  09-15-90 14:07  a2394fd8 ^dos-file.ext
133
 
   16717  Defl:X     5252  69%  11-03-97 06:40  1ce0f189  WHERE
134
 
--------          -------  ---                            -------
135
 
   64159            20502  68%                            3 files
136
 
  ---------------------------------------------------------------------------*/
137
 
 
138
 
    G.pInfo = &info;
139
 
    date_format = DATE_FORMAT;
140
 
 
141
 
#ifndef WINDLL
142
 
    if (uO.qflag < 2) {
143
 
        if (uO.L_flag)
144
 
            Info(slide, 0, ((char *)slide, LoadFarString(CaseConversion),
145
 
              LoadFarStringSmall(Headers[longhdr][0]),
146
 
              LoadFarStringSmall2(Headers[longhdr][1])));
147
 
        else
148
 
            Info(slide, 0, ((char *)slide, "%s\n%s\n",
149
 
               LoadFarString(Headers[longhdr][0]),
150
 
               LoadFarStringSmall(Headers[longhdr][1])));
151
 
    }
152
 
#endif /* !WINDLL */
153
 
 
154
 
    for (j = 1L;;j++) {
155
 
 
156
 
        if (readbuf(__G__ G.sig, 4) == 0)
157
 
            return PK_EOF;
158
 
        if (strncmp(G.sig, central_hdr_sig, 4)) {  /* is it a CentDir entry? */
159
 
            if (((unsigned)(j - 1) & (unsigned)0xFFFF) ==
160
 
                (unsigned)G.ecrec.total_entries_central_dir) {
161
 
                /* "j modulus 64k" matches the reported 16-bit-unsigned
162
 
                 * number of directory entries -> probably, the regular
163
 
                 * end of the central directory has been reached
164
 
                 */
165
 
                break;
166
 
            } else {
167
 
                Info(slide, 0x401,
168
 
                     ((char *)slide, LoadFarString(CentSigMsg), j));
169
 
                Info(slide, 0x401,
170
 
                     ((char *)slide, LoadFarString(ReportMsg)));
171
 
                return PK_BADERR;   /* sig not found */
172
 
            }
173
 
        }
174
 
        /* process_cdir_file_hdr() sets pInfo->hostnum, pInfo->lcflag, ...: */
175
 
        if ((error = process_cdir_file_hdr(__G)) != PK_COOL)
176
 
            return error;       /* only PK_EOF defined */
177
 
 
178
 
        /*
179
 
         * We could DISPLAY the filename instead of storing (and possibly trun-
180
 
         * cating, in the case of a very long name) and printing it, but that
181
 
         * has the disadvantage of not allowing case conversion--and it's nice
182
 
         * to be able to see in the listing precisely how you have to type each
183
 
         * filename in order for unzip to consider it a match.  Speaking of
184
 
         * which, if member names were specified on the command line, check in
185
 
         * with match() to see if the current file is one of them, and make a
186
 
         * note of it if it is.
187
 
         */
188
 
 
189
 
        if ((error = do_string(__G__ G.crec.filename_length, DS_FN)) !=
190
 
             PK_COOL)   /*  ^--(uses pInfo->lcflag) */
191
 
        {
192
 
            error_in_archive = error;
193
 
            if (error > PK_WARN)   /* fatal:  can't continue */
194
 
                return error;
195
 
        }
196
 
        if (G.extra_field != (uch *)NULL) {
197
 
            free(G.extra_field);
198
 
            G.extra_field = (uch *)NULL;
199
 
        }
200
 
        if ((error = do_string(__G__ G.crec.extra_field_length, EXTRA_FIELD))
201
 
            != 0)
202
 
        {
203
 
            error_in_archive = error;
204
 
            if (error > PK_WARN)      /* fatal */
205
 
                return error;
206
 
        }
207
 
        if (!G.process_all_files) {   /* check if specified on command line */
208
 
            unsigned i;
209
 
 
210
 
            do_this_file = FALSE;
211
 
            for (i = 0; i < G.filespecs; i++)
212
 
                if (match(G.filename, G.pfnames[i], uO.C_flag)) {
213
 
                    do_this_file = TRUE;
214
 
                    break;       /* found match, so stop looping */
215
 
                }
216
 
            if (do_this_file) {  /* check if this is an excluded file */
217
 
                for (i = 0; i < G.xfilespecs; i++)
218
 
                    if (match(G.filename, G.pxnames[i], uO.C_flag)) {
219
 
                        do_this_file = FALSE;  /* ^-- ignore case in match */
220
 
                        break;
221
 
                    }
222
 
            }
223
 
        }
224
 
        /*
225
 
         * If current file was specified on command line, or if no names were
226
 
         * specified, do the listing for this file.  Otherwise, get rid of the
227
 
         * file comment and go back for the next file.
228
 
         */
229
 
 
230
 
        if (G.process_all_files || do_this_file) {
231
 
 
232
 
#ifdef OS2DLL
233
 
            /* this is used by UzpFileTree() to allow easy processing of lists
234
 
             * of zip directory contents */
235
 
            if (G.processExternally) {
236
 
                if ((G.processExternally)(G.filename, &G.crec))
237
 
                    break;
238
 
                ++members;
239
 
            } else {
240
 
#endif
241
 
#ifdef OS2_EAS
242
 
            {
243
 
                uch *ef_ptr = G.extra_field;
244
 
                int ef_size, ef_len = G.crec.extra_field_length;
245
 
                ea_size = acl_size = 0;
246
 
 
247
 
                while (ef_len >= EB_HEADSIZE) {
248
 
                    ef_size = makeword(&ef_ptr[EB_LEN]);
249
 
                    switch (makeword(&ef_ptr[EB_ID])) {
250
 
                        case EF_OS2:
251
 
                            ea_size = makelong(&ef_ptr[EB_HEADSIZE]);
252
 
                            break;
253
 
                        case EF_ACL:
254
 
                            acl_size = makelong(&ef_ptr[EB_HEADSIZE]);
255
 
                            break;
256
 
                    }
257
 
                    ef_ptr += (ef_size + EB_HEADSIZE);
258
 
                    ef_len -= (ef_size + EB_HEADSIZE);
259
 
                }
260
 
            }
261
 
#endif
262
 
#ifdef USE_EF_UT_TIME
263
 
            if (G.extra_field &&
264
 
#ifdef IZ_CHECK_TZ
265
 
                G.tz_is_valid &&
266
 
#endif
267
 
                (ef_scan_for_izux(G.extra_field, G.crec.extra_field_length, 1,
268
 
                                  G.crec.last_mod_dos_datetime, &z_utime, NULL)
269
 
                 & EB_UT_FL_MTIME))
270
 
            {
271
 
                TIMET_TO_NATIVE(z_utime.mtime)   /* NOP unless MSC 7.0, Mac */
272
 
                t = localtime(&(z_utime.mtime));
273
 
            } else
274
 
                t = (struct tm *)NULL;
275
 
            if (t != (struct tm *)NULL) {
276
 
                mo = (unsigned)(t->tm_mon + 1);
277
 
                dy = (unsigned)(t->tm_mday);
278
 
                yr = (unsigned)(t->tm_year % 100);
279
 
                hh = (unsigned)(t->tm_hour);
280
 
                mm = (unsigned)(t->tm_min);
281
 
            } else
282
 
#endif /* USE_EF_UT_TIME */
283
 
            {
284
 
                yr = ((((unsigned)(G.crec.last_mod_dos_datetime >> 25) & 0x7f)
285
 
                       + 80) % (unsigned)100);
286
 
                mo = ((unsigned)(G.crec.last_mod_dos_datetime >> 21) & 0x0f);
287
 
                dy = ((unsigned)(G.crec.last_mod_dos_datetime >> 16) & 0x1f);
288
 
                hh = (((unsigned)G.crec.last_mod_dos_datetime >> 11) & 0x1f);
289
 
                mm = (((unsigned)G.crec.last_mod_dos_datetime >> 5) & 0x3f);
290
 
            }
291
 
            /* permute date so it displays according to nat'l convention
292
 
             * ('methnum' is not yet set, it is used as temporary buffer) */
293
 
            switch (date_format) {
294
 
                case DF_YMD:
295
 
                    methnum = mo;
296
 
                    mo = yr; yr = dy; dy = methnum;
297
 
                    break;
298
 
                case DF_DMY:
299
 
                    methnum = mo;
300
 
                    mo = dy; dy = methnum;
301
 
            }
302
 
 
303
 
            csiz = G.crec.csize;
304
 
            if (G.crec.general_purpose_bit_flag & 1)
305
 
                csiz -= 12;   /* if encrypted, don't count encryption header */
306
 
            if ((cfactor = ratio(G.crec.ucsize, csiz)) < 0) {
307
 
#ifndef WINDLL
308
 
                sgn = '-';
309
 
#endif
310
 
                cfactor = (-cfactor + 5) / 10;
311
 
            } else {
312
 
#ifndef WINDLL
313
 
                sgn = ' ';
314
 
#endif
315
 
                cfactor = (cfactor + 5) / 10;
316
 
            }
317
 
 
318
 
            methnum = MIN(G.crec.compression_method, NUM_METHODS);
319
 
            zfstrcpy(methbuf, method[methnum]);
320
 
            if (methnum == DEFLATED || methnum == ENHDEFLATED) {
321
 
                methbuf[5] = dtype[(G.crec.general_purpose_bit_flag>>1) & 3];
322
 
            } else if (methnum >= NUM_METHODS) {
323
 
                sprintf(&methbuf[4], "%03u", G.crec.compression_method);
324
 
            }
325
 
 
326
 
#if 0       /* GRR/Euro:  add this? */
327
 
#if defined(DOS_FLX_NLM_OS2_W32) || defined(THEOS) || defined(UNIX)
328
 
            for (p = G.filename;  *p;  ++p)
329
 
                if (!isprint(*p))
330
 
                    *p = '?';  /* change non-printable chars to '?' */
331
 
#endif /* DOS_FLX_NLM_OS2_W32 || THEOS || UNIX */
332
 
#endif /* 0 */
333
 
 
334
 
#ifdef WINDLL
335
 
            /* send data to application for formatting and printing */
336
 
            (*G.lpUserFunctions->SendApplicationMessage)(G.crec.ucsize, csiz,
337
 
              (unsigned)cfactor, mo, dy, yr, hh, mm,
338
 
              (char)(G.pInfo->lcflag ? '^' : ' '),
339
 
              (LPSTR)fnfilter(G.filename, slide), (LPSTR)methbuf, G.crec.crc32,
340
 
              (char)((G.crec.general_purpose_bit_flag & 1) ? 'E' : ' '));
341
 
#else /* !WINDLL */
342
 
            if (cfactor == 100)
343
 
                sprintf(cfactorstr, LoadFarString(CompFactor100));
344
 
            else
345
 
                sprintf(cfactorstr, LoadFarString(CompFactorStr), sgn, cfactor);
346
 
            if (longhdr)
347
 
                Info(slide, 0, ((char *)slide, LoadFarString(LongHdrStats),
348
 
                  G.crec.ucsize, methbuf, csiz, cfactorstr, mo, dy,
349
 
                  yr, hh, mm, G.crec.crc32, (G.pInfo->lcflag? '^':' ')));
350
 
            else
351
 
#ifdef OS2_EAS
352
 
                Info(slide, 0, ((char *)slide, LoadFarString(ShortHdrStats),
353
 
                  G.crec.ucsize, ea_size, acl_size,
354
 
                  mo, dy, yr, hh, mm, (G.pInfo->lcflag? '^':' ')));
355
 
#else
356
 
                Info(slide, 0, ((char *)slide, LoadFarString(ShortHdrStats),
357
 
                  G.crec.ucsize,
358
 
                  mo, dy, yr, hh, mm, (G.pInfo->lcflag? '^':' ')));
359
 
#endif
360
 
            fnprint(__G);
361
 
#endif /* ?WINDLL */
362
 
 
363
 
            if ((error = do_string(__G__ G.crec.file_comment_length,
364
 
                                   QCOND? DISPL_8 : SKIP)) != 0)
365
 
            {
366
 
                error_in_archive = error;  /* might be just warning */
367
 
                if (error > PK_WARN)       /* fatal */
368
 
                    return error;
369
 
            }
370
 
            tot_ucsize += G.crec.ucsize;
371
 
            tot_csize += csiz;
372
 
            ++members;
373
 
#ifdef OS2_EAS
374
 
            if (ea_size) {
375
 
                tot_easize += ea_size;
376
 
                ++tot_eafiles;
377
 
            }
378
 
            if (acl_size) {
379
 
                tot_aclsize += acl_size;
380
 
                ++tot_aclfiles;
381
 
            }
382
 
#endif
383
 
#ifdef OS2DLL
384
 
            } /* end of "if (G.processExternally) {...} else {..." */
385
 
#endif
386
 
        } else {        /* not listing this file */
387
 
            SKIP_(G.crec.file_comment_length)
388
 
        }
389
 
    } /* end for-loop (j: files in central directory) */
390
 
 
391
 
/*---------------------------------------------------------------------------
392
 
    Print footer line and totals (compressed size, uncompressed size, number
393
 
    of members in zipfile).
394
 
  ---------------------------------------------------------------------------*/
395
 
 
396
 
    if (uO.qflag < 2
397
 
#ifdef OS2DLL
398
 
                     && !G.processExternally
399
 
#endif
400
 
                                            ) {
401
 
        if ((cfactor = ratio(tot_ucsize, tot_csize)) < 0) {
402
 
#ifndef WINDLL
403
 
            sgn = '-';
404
 
#endif
405
 
            cfactor = (-cfactor + 5) / 10;
406
 
        } else {
407
 
#ifndef WINDLL
408
 
            sgn = ' ';
409
 
#endif
410
 
            cfactor = (cfactor + 5) / 10;
411
 
        }
412
 
#ifdef WINDLL
413
 
        /* pass the totals back to the calling application */
414
 
        G.lpUserFunctions->TotalSizeComp = tot_csize;
415
 
        G.lpUserFunctions->TotalSize = tot_ucsize;
416
 
        G.lpUserFunctions->CompFactor = (ulg)cfactor;
417
 
        G.lpUserFunctions->NumMembers = members;
418
 
 
419
 
#else /* !WINDLL */
420
 
        if (cfactor == 100)
421
 
            sprintf(cfactorstr, LoadFarString(CompFactor100));
422
 
        else
423
 
            sprintf(cfactorstr, LoadFarString(CompFactorStr), sgn, cfactor);
424
 
        if (longhdr) {
425
 
            Info(slide, 0, ((char *)slide, LoadFarString(LongFileTrailer),
426
 
              tot_ucsize, tot_csize, cfactorstr, members, members==1? "":"s"));
427
 
#ifdef OS2_EAS
428
 
            if (tot_easize || tot_aclsize)
429
 
                Info(slide, 0, ((char *)slide, "\n"));
430
 
            if (tot_eafiles && tot_easize)
431
 
                Info(slide, 0, ((char *)slide, LoadFarString(OS2ExtAttrTrailer),
432
 
                  tot_eafiles, tot_eafiles == 1? " has" : "s have a total of",
433
 
                  tot_easize));
434
 
            if (tot_aclfiles && tot_aclsize)
435
 
                Info(slide, 0, ((char *)slide, LoadFarString(OS2ACLTrailer),
436
 
                  tot_aclfiles, tot_aclfiles == 1? " has" : "s have a total of",
437
 
                  tot_aclsize));
438
 
#endif /* OS2_EAS */
439
 
        } else
440
 
#ifdef OS2_EAS
441
 
            Info(slide, 0, ((char *)slide, LoadFarString(ShortFileTrailer),
442
 
              tot_ucsize, tot_easize, tot_aclsize, members, members == 1?
443
 
              "" : "s"));
444
 
#else
445
 
            Info(slide, 0, ((char *)slide, LoadFarString(ShortFileTrailer),
446
 
              tot_ucsize, members, members == 1? "" : "s"));
447
 
#endif /* OS2_EAS */
448
 
#endif /* ?WINDLL */
449
 
    }
450
 
 
451
 
/*---------------------------------------------------------------------------
452
 
    Double check that we're back at the end-of-central-directory record.
453
 
  ---------------------------------------------------------------------------*/
454
 
 
455
 
    if (strncmp(G.sig, end_central_sig, 4)) {   /* just to make sure again */
456
 
        Info(slide, 0x401, ((char *)slide, LoadFarString(EndSigMsg)));
457
 
        error_in_archive = PK_WARN;   /* didn't find sig */
458
 
    }
459
 
    if (members == 0L && error_in_archive <= PK_WARN)
460
 
        error_in_archive = PK_FIND;
461
 
 
462
 
    return error_in_archive;
463
 
 
464
 
} /* end function list_files() */
465
 
 
466
 
 
467
 
 
468
 
 
469
 
 
470
 
#ifdef TIMESTAMP
471
 
 
472
 
/************************/
473
 
/* Function fn_is_dir() */
474
 
/************************/
475
 
 
476
 
static int fn_is_dir(__G)    /* returns TRUE if G.filename is directory */
477
 
    __GDEF
478
 
{
479
 
    extent fn_len = strlen(G.filename);
480
 
    register char   endc;
481
 
 
482
 
    return  fn_len > 0 &&
483
 
            ((endc = lastchar(G.filename, fn_len)) == '/' ||
484
 
             (G.pInfo->hostnum == FS_FAT_ && !MBSCHR(G.filename, '/') &&
485
 
              endc == '\\'));
486
 
}
487
 
 
488
 
 
489
 
 
490
 
 
491
 
 
492
 
/*****************************/
493
 
/* Function get_time_stamp() */
494
 
/*****************************/
495
 
 
496
 
int get_time_stamp(__G__ last_modtime, nmember)  /* return PK-type error code */
497
 
    __GDEF
498
 
    time_t *last_modtime;
499
 
    ulg *nmember;
500
 
{
501
 
    int do_this_file=FALSE, error, error_in_archive=PK_COOL;
502
 
    ulg j;
503
 
#ifdef USE_EF_UT_TIME
504
 
    iztimes z_utime;
505
 
#endif
506
 
    min_info info;
507
 
 
508
 
 
509
 
/*---------------------------------------------------------------------------
510
 
    Unlike extract_or_test_files() but like list_files(), this function works
511
 
    on information in the central directory alone.  Thus we have a single,
512
 
    large loop through the entire directory, searching for the latest time
513
 
    stamp.
514
 
  ---------------------------------------------------------------------------*/
515
 
 
516
 
    *last_modtime = 0L;         /* assuming no zipfile data older than 1970 */
517
 
    *nmember = 0L;
518
 
    G.pInfo = &info;
519
 
 
520
 
    for (j = 1L;; j++) {
521
 
 
522
 
        if (readbuf(__G__ G.sig, 4) == 0)
523
 
            return PK_EOF;
524
 
        if (strncmp(G.sig, central_hdr_sig, 4)) {  /* is it a CentDir entry? */
525
 
            if (((unsigned)(j - 1) & (unsigned)0xFFFF) ==
526
 
                (unsigned)G.ecrec.total_entries_central_dir) {
527
 
                /* "j modulus 64k" matches the reported 16-bit-unsigned
528
 
                 * number of directory entries -> probably, the regular
529
 
                 * end of the central directory has been reached
530
 
                 */
531
 
                break;
532
 
            } else {
533
 
                Info(slide, 0x401,
534
 
                     ((char *)slide, LoadFarString(CentSigMsg), j));
535
 
                Info(slide, 0x401,
536
 
                     ((char *)slide, LoadFarString(ReportMsg)));
537
 
                return PK_BADERR;   /* sig not found */
538
 
            }
539
 
        }
540
 
        /* process_cdir_file_hdr() sets pInfo->lcflag: */
541
 
        if ((error = process_cdir_file_hdr(__G)) != PK_COOL)
542
 
            return error;       /* only PK_EOF defined */
543
 
        if ((error = do_string(__G__ G.crec.filename_length, DS_FN)) != PK_OK)
544
 
        {        /*  ^-- (uses pInfo->lcflag) */
545
 
            error_in_archive = error;
546
 
            if (error > PK_WARN)   /* fatal:  can't continue */
547
 
                return error;
548
 
        }
549
 
        if (G.extra_field != (uch *)NULL) {
550
 
            free(G.extra_field);
551
 
            G.extra_field = (uch *)NULL;
552
 
        }
553
 
        if ((error = do_string(__G__ G.crec.extra_field_length, EXTRA_FIELD))
554
 
            != 0)
555
 
        {
556
 
            error_in_archive = error;
557
 
            if (error > PK_WARN)      /* fatal */
558
 
                return error;
559
 
        }
560
 
        if (!G.process_all_files) {   /* check if specified on command line */
561
 
            unsigned i;
562
 
 
563
 
            do_this_file = FALSE;
564
 
            for (i = 0; i < G.filespecs; i++)
565
 
                if (match(G.filename, G.pfnames[i], uO.C_flag)) {
566
 
                    do_this_file = TRUE;
567
 
                    break;       /* found match, so stop looping */
568
 
                }
569
 
            if (do_this_file) {  /* check if this is an excluded file */
570
 
                for (i = 0; i < G.xfilespecs; i++)
571
 
                    if (match(G.filename, G.pxnames[i], uO.C_flag)) {
572
 
                        do_this_file = FALSE;  /* ^-- ignore case in match */
573
 
                        break;
574
 
                    }
575
 
            }
576
 
        }
577
 
 
578
 
        /* If current file was specified on command line, or if no names were
579
 
         * specified, check the time for this file.  Either way, get rid of the
580
 
         * file comment and go back for the next file.
581
 
         * Directory entries are always ignored, to stay compatible with both
582
 
         * Zip and PKZIP.
583
 
         */
584
 
        if ((G.process_all_files || do_this_file) && !fn_is_dir(__G)) {
585
 
#ifdef USE_EF_UT_TIME
586
 
            if (G.extra_field &&
587
 
#ifdef IZ_CHECK_TZ
588
 
                G.tz_is_valid &&
589
 
#endif
590
 
                (ef_scan_for_izux(G.extra_field, G.crec.extra_field_length, 1,
591
 
                                  G.crec.last_mod_dos_datetime, &z_utime, NULL)
592
 
                 & EB_UT_FL_MTIME))
593
 
            {
594
 
                if (*last_modtime < z_utime.mtime)
595
 
                    *last_modtime = z_utime.mtime;
596
 
            } else
597
 
#endif /* USE_EF_UT_TIME */
598
 
            {
599
 
                time_t modtime = dos_to_unix_time(G.crec.last_mod_dos_datetime);
600
 
 
601
 
                if (*last_modtime < modtime)
602
 
                    *last_modtime = modtime;
603
 
            }
604
 
            ++*nmember;
605
 
        }
606
 
        SKIP_(G.crec.file_comment_length)
607
 
 
608
 
    } /* end for-loop (j: files in central directory) */
609
 
 
610
 
/*---------------------------------------------------------------------------
611
 
    Double check that we're back at the end-of-central-directory record.
612
 
  ---------------------------------------------------------------------------*/
613
 
 
614
 
    if (strncmp(G.sig, end_central_sig, 4)) {   /* just to make sure again */
615
 
        Info(slide, 0x401, ((char *)slide, LoadFarString(EndSigMsg)));
616
 
        error_in_archive = PK_WARN;
617
 
    }
618
 
    if (*nmember == 0L && error_in_archive <= PK_WARN)
619
 
        error_in_archive = PK_FIND;
620
 
 
621
 
    return error_in_archive;
622
 
 
623
 
} /* end function get_time_stamp() */
624
 
 
625
 
#endif /* TIMESTAMP */
626
 
 
627
 
 
628
 
 
629
 
 
630
 
 
631
 
/********************/
632
 
/* Function ratio() */    /* also used by ZipInfo routines */
633
 
/********************/
634
 
 
635
 
int ratio(uc, c)
636
 
    ulg uc, c;
637
 
{
638
 
    ulg denom;
639
 
 
640
 
    if (uc == 0)
641
 
        return 0;
642
 
    if (uc > 2000000L) {    /* risk signed overflow if multiply numerator */
643
 
        denom = uc / 1000L;
644
 
        return ((uc >= c) ?
645
 
            (int) ((uc-c + (denom>>1)) / denom) :
646
 
          -((int) ((c-uc + (denom>>1)) / denom)));
647
 
    } else {             /* ^^^^^^^^ rounding */
648
 
        denom = uc;
649
 
        return ((uc >= c) ?
650
 
            (int) ((1000L*(uc-c) + (denom>>1)) / denom) :
651
 
          -((int) ((1000L*(c-uc) + (denom>>1)) / denom)));
652
 
    }                            /* ^^^^^^^^ rounding */
653
 
}
654
 
 
655
 
 
656
 
 
657
 
 
658
 
 
659
 
/************************/
660
 
/*  Function fnprint()  */    /* also used by ZipInfo routines */
661
 
/************************/
662
 
 
663
 
void fnprint(__G)    /* print filename (after filtering) and newline */
664
 
    __GDEF
665
 
{
666
 
    char *name = fnfilter(G.filename, slide);
667
 
 
668
 
    (*G.message)((zvoid *)&G, (uch *)name, (ulg)strlen(name), 0);
669
 
    (*G.message)((zvoid *)&G, (uch *)"\n", 1L, 0);
670
 
 
671
 
} /* end function fnprint() */
672
 
 
673
 
const char *BOINC_RCSID_670c4eb825 = "$Id: list.c 4979 2005-01-02 18:29:53Z ballen $";