123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734 |
- /*
- Copyright (c) 1990-2009 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 2009-Jan-02 or later
- (the contents of which are also included in unzip.h) for terms of use.
- If, for some reason, all these files are missing, the Info-ZIP license
- also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
- */
- /*---------------------------------------------------------------------------
- list.c
- This file contains the non-ZipInfo-specific listing routines for UnZip.
- Contains: list_files()
- get_time_stamp() [optional feature]
- ratio()
- fnprint()
- ---------------------------------------------------------------------------*/
- #define UNZIP_INTERNAL
- #include "unzip.h"
- #ifdef WINDLL
- # ifdef POCKET_UNZIP
- # include "wince/intrface.h"
- # else
- # include "windll/windll.h"
- # endif
- #endif
- #ifdef TIMESTAMP
- static int fn_is_dir OF((__GPRO));
- #endif
- #ifndef WINDLL
- static ZCONST char Far CompFactorStr[] = "%c%d%%";
- static ZCONST char Far CompFactor100[] = "100%%";
- #ifdef OS2_EAS
- static ZCONST char Far HeadersS[] =
- " Length EAs ACLs Date Time Name";
- static ZCONST char Far HeadersS1[] =
- "--------- --- ---- ---------- ----- ----";
- #else
- static ZCONST char Far HeadersS[] =
- " Length Date Time Name";
- static ZCONST char Far HeadersS1[] =
- "--------- ---------- ----- ----";
- #endif
- static ZCONST char Far HeadersL[] =
- " Length Method Size Cmpr Date Time CRC-32 Name";
- static ZCONST char Far HeadersL1[] =
- "-------- ------ ------- ---- ---------- ----- -------- ----";
- static ZCONST char Far *Headers[][2] =
- { {HeadersS, HeadersS1}, {HeadersL, HeadersL1} };
- static ZCONST char Far CaseConversion[] =
- "%s (\"^\" ==> case\n%s conversion)\n";
- static ZCONST char Far LongHdrStats[] =
- "%s %-7s%s %4s %02u%c%02u%c%02u %02u:%02u %08lx %c";
- static ZCONST char Far LongFileTrailer[] =
- "-------- ------- --- \
- -------\n%s %s %4s %lu file%s\n";
- #ifdef OS2_EAS
- static ZCONST char Far ShortHdrStats[] =
- "%s %6lu %6lu %02u%c%02u%c%02u %02u:%02u %c";
- static ZCONST char Far ShortFileTrailer[] =
- "--------- ----- ----- \
- -------\n%s %6lu %6lu %lu file%s\n";
- static ZCONST char Far OS2ExtAttrTrailer[] =
- "%lu file%s %lu bytes of OS/2 extended attributes attached.\n";
- static ZCONST char Far OS2ACLTrailer[] =
- "%lu file%s %lu bytes of access control lists attached.\n";
- #else
- static ZCONST char Far ShortHdrStats[] =
- "%s %02u%c%02u%c%02u %02u:%02u %c";
- static ZCONST char Far ShortFileTrailer[] =
- "--------- -------\n%s\
- %lu file%s\n";
- #endif /* ?OS2_EAS */
- #endif /* !WINDLL */
- /*************************/
- /* Function list_files() */
- /*************************/
- int list_files(__G) /* return PK-type error code */
- __GDEF
- {
- int do_this_file=FALSE, cfactor, error, error_in_archive=PK_COOL;
- #ifndef WINDLL
- char sgn, cfactorstr[10];
- int longhdr=(uO.vflag>1);
- #endif
- int date_format;
- char dt_sepchar;
- ulg members=0L;
- zusz_t j;
- unsigned methnum;
- #ifdef USE_EF_UT_TIME
- iztimes z_utime;
- struct tm *t;
- #endif
- unsigned yr, mo, dy, hh, mm;
- zusz_t csiz, tot_csize=0L, tot_ucsize=0L;
- #ifdef OS2_EAS
- ulg ea_size, tot_easize=0L, tot_eafiles=0L;
- ulg acl_size, tot_aclsize=0L, tot_aclfiles=0L;
- #endif
- min_info info;
- char methbuf[8];
- static ZCONST char dtype[]="NXFS"; /* see zi_short() */
- static ZCONST char Far method[NUM_METHODS+1][8] =
- {"Stored", "Shrunk", "Reduce1", "Reduce2", "Reduce3", "Reduce4",
- "Implode", "Token", "Defl:#", "Def64#", "ImplDCL", "BZip2",
- "LZMA", "Terse", "IBMLZ77", "WavPack", "PPMd", "Unk:###"};
- /*---------------------------------------------------------------------------
- Unlike extract_or_test_files(), this routine confines itself to the cen-
- tral directory. Thus its structure is somewhat simpler, since we can do
- just a single loop through the entire directory, listing files as we go.
- So to start off, print the heading line and then begin main loop through
- the central directory. The results will look vaguely like the following:
- Length Method Size Ratio Date Time CRC-32 Name ("^" ==> case
- -------- ------ ------- ----- ---- ---- ------ ---- conversion)
- 44004 Implode 13041 71% 11-02-89 19:34 8b4207f7 Makefile.UNIX
- 3438 Shrunk 2209 36% 09-15-90 14:07 a2394fd8 ^dos-file.ext
- 16717 Defl:X 5252 69% 11-03-97 06:40 1ce0f189 WHERE
- -------- ------- --- -------
- 64159 20502 68% 3 files
- ---------------------------------------------------------------------------*/
- G.pInfo = &info;
- date_format = DATE_FORMAT;
- dt_sepchar = DATE_SEPCHAR;
- #ifndef WINDLL
- if (uO.qflag < 2) {
- if (uO.L_flag)
- Info(slide, 0, ((char *)slide, LoadFarString(CaseConversion),
- LoadFarStringSmall(Headers[longhdr][0]),
- LoadFarStringSmall2(Headers[longhdr][1])));
- else
- Info(slide, 0, ((char *)slide, "%s\n%s\n",
- LoadFarString(Headers[longhdr][0]),
- LoadFarStringSmall(Headers[longhdr][1])));
- }
- #endif /* !WINDLL */
- for (j = 1L;;j++) {
- if (readbuf(__G__ G.sig, 4) == 0)
- return PK_EOF;
- if (memcmp(G.sig, central_hdr_sig, 4)) { /* is it a CentDir entry? */
- /* no new central directory entry
- * -> is the number of processed entries compatible with the
- * number of entries as stored in the end_central record?
- */
- if (((j - 1) &
- (ulg)(G.ecrec.have_ecr64 ? MASK_ZUCN64 : MASK_ZUCN16))
- == (ulg)G.ecrec.total_entries_central_dir)
- {
- /* "j modulus 4T/64k" matches the reported 64/16-bit-unsigned
- * number of directory entries -> probably, the regular
- * end of the central directory has been reached
- */
- break;
- } else {
- Info(slide, 0x401,
- ((char *)slide, LoadFarString(CentSigMsg), j));
- Info(slide, 0x401,
- ((char *)slide, LoadFarString(ReportMsg)));
- return PK_BADERR; /* sig not found */
- }
- }
- /* process_cdir_file_hdr() sets pInfo->hostnum, pInfo->lcflag, ...: */
- if ((error = process_cdir_file_hdr(__G)) != PK_COOL)
- return error; /* only PK_EOF defined */
- /*
- * We could DISPLAY the filename instead of storing (and possibly trun-
- * cating, in the case of a very long name) and printing it, but that
- * has the disadvantage of not allowing case conversion--and it's nice
- * to be able to see in the listing precisely how you have to type each
- * filename in order for unzip to consider it a match. Speaking of
- * which, if member names were specified on the command line, check in
- * with match() to see if the current file is one of them, and make a
- * note of it if it is.
- */
- if ((error = do_string(__G__ G.crec.filename_length, DS_FN)) !=
- PK_COOL) /* ^--(uses pInfo->lcflag) */
- {
- error_in_archive = error;
- if (error > PK_WARN) /* fatal: can't continue */
- return error;
- }
- if (G.extra_field != (uch *)NULL) {
- free(G.extra_field);
- G.extra_field = (uch *)NULL;
- }
- if ((error = do_string(__G__ G.crec.extra_field_length, EXTRA_FIELD))
- != 0)
- {
- error_in_archive = error;
- if (error > PK_WARN) /* fatal */
- return error;
- }
- if (!G.process_all_files) { /* check if specified on command line */
- unsigned i;
- if (G.filespecs == 0)
- do_this_file = TRUE;
- else { /* check if this entry matches an `include' argument */
- do_this_file = FALSE;
- for (i = 0; i < G.filespecs; i++)
- if (match(G.filename, G.pfnames[i], uO.C_flag WISEP)) {
- do_this_file = TRUE;
- break; /* found match, so stop looping */
- }
- }
- if (do_this_file) { /* check if this is an excluded file */
- for (i = 0; i < G.xfilespecs; i++)
- if (match(G.filename, G.pxnames[i], uO.C_flag WISEP)) {
- do_this_file = FALSE; /* ^-- ignore case in match */
- break;
- }
- }
- }
- /*
- * If current file was specified on command line, or if no names were
- * specified, do the listing for this file. Otherwise, get rid of the
- * file comment and go back for the next file.
- */
- if (G.process_all_files || do_this_file) {
- #ifdef OS2DLL
- /* this is used by UzpFileTree() to allow easy processing of lists
- * of zip directory contents */
- if (G.processExternally) {
- if ((G.processExternally)(G.filename, &G.crec))
- break;
- ++members;
- } else {
- #endif
- #ifdef OS2_EAS
- {
- uch *ef_ptr = G.extra_field;
- int ef_size, ef_len = G.crec.extra_field_length;
- ea_size = acl_size = 0;
- while (ef_len >= EB_HEADSIZE) {
- ef_size = makeword(&ef_ptr[EB_LEN]);
- switch (makeword(&ef_ptr[EB_ID])) {
- case EF_OS2:
- ea_size = makelong(&ef_ptr[EB_HEADSIZE]);
- break;
- case EF_ACL:
- acl_size = makelong(&ef_ptr[EB_HEADSIZE]);
- break;
- }
- ef_ptr += (ef_size + EB_HEADSIZE);
- ef_len -= (ef_size + EB_HEADSIZE);
- }
- }
- #endif
- #ifdef USE_EF_UT_TIME
- if (G.extra_field &&
- #ifdef IZ_CHECK_TZ
- G.tz_is_valid &&
- #endif
- (ef_scan_for_izux(G.extra_field, G.crec.extra_field_length, 1,
- G.crec.last_mod_dos_datetime, &z_utime, NULL)
- & EB_UT_FL_MTIME))
- {
- TIMET_TO_NATIVE(z_utime.mtime) /* NOP unless MSC 7.0, Mac */
- t = localtime(&(z_utime.mtime));
- } else
- t = (struct tm *)NULL;
- if (t != (struct tm *)NULL) {
- mo = (unsigned)(t->tm_mon + 1);
- dy = (unsigned)(t->tm_mday);
- yr = (unsigned)(t->tm_year + 1900);
- hh = (unsigned)(t->tm_hour);
- mm = (unsigned)(t->tm_min);
- } else
- #endif /* USE_EF_UT_TIME */
- {
- yr = ((((unsigned)(G.crec.last_mod_dos_datetime >> 25) & 0x7f)
- + 1980));
- mo = ((unsigned)(G.crec.last_mod_dos_datetime >> 21) & 0x0f);
- dy = ((unsigned)(G.crec.last_mod_dos_datetime >> 16) & 0x1f);
- hh = (((unsigned)G.crec.last_mod_dos_datetime >> 11) & 0x1f);
- mm = (((unsigned)G.crec.last_mod_dos_datetime >> 5) & 0x3f);
- }
- /* permute date so it displays according to nat'l convention
- * ('methnum' is not yet set, it is used as temporary buffer) */
- switch (date_format) {
- case DF_YMD:
- methnum = mo;
- mo = yr; yr = dy; dy = methnum;
- break;
- case DF_DMY:
- methnum = mo;
- mo = dy; dy = methnum;
- }
- csiz = G.crec.csize;
- if (G.crec.general_purpose_bit_flag & 1)
- csiz -= 12; /* if encrypted, don't count encryption header */
- if ((cfactor = ratio(G.crec.ucsize, csiz)) < 0) {
- #ifndef WINDLL
- sgn = '-';
- #endif
- cfactor = (-cfactor + 5) / 10;
- } else {
- #ifndef WINDLL
- sgn = ' ';
- #endif
- cfactor = (cfactor + 5) / 10;
- }
- methnum = find_compr_idx(G.crec.compression_method);
- zfstrcpy(methbuf, method[methnum]);
- if (G.crec.compression_method == DEFLATED ||
- G.crec.compression_method == ENHDEFLATED) {
- methbuf[5] = dtype[(G.crec.general_purpose_bit_flag>>1) & 3];
- } else if (methnum >= NUM_METHODS) {
- sprintf(&methbuf[4], "%03u", G.crec.compression_method);
- }
- #if 0 /* GRR/Euro: add this? */
- #if defined(DOS_FLX_NLM_OS2_W32) || defined(THEOS) || defined(UNIX)
- for (p = G.filename; *p; ++p)
- if (!isprint(*p))
- *p = '?'; /* change non-printable chars to '?' */
- #endif /* DOS_FLX_NLM_OS2_W32 || THEOS || UNIX */
- #endif /* 0 */
- #ifdef WINDLL
- /* send data to application for formatting and printing */
- if (G.lpUserFunctions->SendApplicationMessage != NULL)
- (*G.lpUserFunctions->SendApplicationMessage)(G.crec.ucsize,
- csiz, (unsigned)cfactor, mo, dy, yr, hh, mm,
- (char)(G.pInfo->lcflag ? '^' : ' '),
- (LPCSTR)fnfilter(G.filename, slide, (WSIZE>>1)),
- (LPCSTR)methbuf, G.crec.crc32,
- (char)((G.crec.general_purpose_bit_flag & 1) ? 'E' : ' '));
- else if (G.lpUserFunctions->SendApplicationMessage_i32 != NULL) {
- unsigned long ucsize_lo, csiz_lo;
- unsigned long ucsize_hi=0L, csiz_hi=0L;
- ucsize_lo = (unsigned long)(G.crec.ucsize);
- csiz_lo = (unsigned long)(csiz);
- #ifdef ZIP64_SUPPORT
- ucsize_hi = (unsigned long)(G.crec.ucsize >> 32);
- csiz_hi = (unsigned long)(csiz >> 32);
- #endif /* ZIP64_SUPPORT */
- (*G.lpUserFunctions->SendApplicationMessage_i32)(ucsize_lo,
- ucsize_hi, csiz_lo, csiz_hi, (unsigned)cfactor,
- mo, dy, yr, hh, mm,
- (char)(G.pInfo->lcflag ? '^' : ' '),
- (LPCSTR)fnfilter(G.filename, slide, (WSIZE>>1)),
- (LPCSTR)methbuf, G.crec.crc32,
- (char)((G.crec.general_purpose_bit_flag & 1) ? 'E' : ' '));
- }
- #else /* !WINDLL */
- if (cfactor == 100)
- sprintf(cfactorstr, LoadFarString(CompFactor100));
- else
- sprintf(cfactorstr, LoadFarString(CompFactorStr), sgn, cfactor);
- if (longhdr)
- Info(slide, 0, ((char *)slide, LoadFarString(LongHdrStats),
- FmZofft(G.crec.ucsize, "8", "u"), methbuf,
- FmZofft(csiz, "8", "u"), cfactorstr,
- mo, dt_sepchar, dy, dt_sepchar, yr, hh, mm,
- G.crec.crc32, (G.pInfo->lcflag? '^':' ')));
- else
- #ifdef OS2_EAS
- Info(slide, 0, ((char *)slide, LoadFarString(ShortHdrStats),
- FmZofft(G.crec.ucsize, "9", "u"), ea_size, acl_size,
- mo, dt_sepchar, dy, dt_sepchar, yr, hh, mm,
- (G.pInfo->lcflag? '^':' ')));
- #else
- Info(slide, 0, ((char *)slide, LoadFarString(ShortHdrStats),
- FmZofft(G.crec.ucsize, "9", "u"),
- mo, dt_sepchar, dy, dt_sepchar, yr, hh, mm,
- (G.pInfo->lcflag? '^':' ')));
- #endif
- fnprint(__G);
- #endif /* ?WINDLL */
- if ((error = do_string(__G__ G.crec.file_comment_length,
- QCOND? DISPL_8 : SKIP)) != 0)
- {
- error_in_archive = error; /* might be just warning */
- if (error > PK_WARN) /* fatal */
- return error;
- }
- tot_ucsize += G.crec.ucsize;
- tot_csize += csiz;
- ++members;
- #ifdef OS2_EAS
- if (ea_size) {
- tot_easize += ea_size;
- ++tot_eafiles;
- }
- if (acl_size) {
- tot_aclsize += acl_size;
- ++tot_aclfiles;
- }
- #endif
- #ifdef OS2DLL
- } /* end of "if (G.processExternally) {...} else {..." */
- #endif
- } else { /* not listing this file */
- SKIP_(G.crec.file_comment_length)
- }
- } /* end for-loop (j: files in central directory) */
- /*---------------------------------------------------------------------------
- Print footer line and totals (compressed size, uncompressed size, number
- of members in zipfile).
- ---------------------------------------------------------------------------*/
- if (uO.qflag < 2
- #ifdef OS2DLL
- && !G.processExternally
- #endif
- ) {
- if ((cfactor = ratio(tot_ucsize, tot_csize)) < 0) {
- #ifndef WINDLL
- sgn = '-';
- #endif
- cfactor = (-cfactor + 5) / 10;
- } else {
- #ifndef WINDLL
- sgn = ' ';
- #endif
- cfactor = (cfactor + 5) / 10;
- }
- #ifdef WINDLL
- /* pass the totals back to the calling application */
- G.lpUserFunctions->TotalSizeComp = tot_csize;
- G.lpUserFunctions->TotalSize = tot_ucsize;
- G.lpUserFunctions->CompFactor = (ulg)cfactor;
- G.lpUserFunctions->NumMembers = members;
- #else /* !WINDLL */
- if (cfactor == 100)
- sprintf(cfactorstr, LoadFarString(CompFactor100));
- else
- sprintf(cfactorstr, LoadFarString(CompFactorStr), sgn, cfactor);
- if (longhdr) {
- Info(slide, 0, ((char *)slide, LoadFarString(LongFileTrailer),
- FmZofft(tot_ucsize, "8", "u"), FmZofft(tot_csize, "8", "u"),
- cfactorstr, members, members==1? "":"s"));
- #ifdef OS2_EAS
- if (tot_easize || tot_aclsize)
- Info(slide, 0, ((char *)slide, "\n"));
- if (tot_eafiles && tot_easize)
- Info(slide, 0, ((char *)slide, LoadFarString(OS2ExtAttrTrailer),
- tot_eafiles, tot_eafiles == 1? " has" : "s have a total of",
- tot_easize));
- if (tot_aclfiles && tot_aclsize)
- Info(slide, 0, ((char *)slide, LoadFarString(OS2ACLTrailer),
- tot_aclfiles,
- tot_aclfiles == 1 ? " has" : "s have a total of",
- tot_aclsize));
- #endif /* OS2_EAS */
- } else
- #ifdef OS2_EAS
- Info(slide, 0, ((char *)slide, LoadFarString(ShortFileTrailer),
- FmZofft(tot_ucsize, "9", "u"), tot_easize, tot_aclsize,
- members, members == 1 ? "" : "s"));
- #else
- Info(slide, 0, ((char *)slide, LoadFarString(ShortFileTrailer),
- FmZofft(tot_ucsize, "9", "u"),
- members, members == 1 ? "" : "s"));
- #endif /* OS2_EAS */
- #endif /* ?WINDLL */
- }
- /* Skip the following checks in case of a premature listing break. */
- if (error_in_archive <= PK_WARN) {
- /*---------------------------------------------------------------------------
- Double check that we're back at the end-of-central-directory record.
- ---------------------------------------------------------------------------*/
- if ( (memcmp(G.sig,
- (G.ecrec.have_ecr64 ?
- end_central64_sig : end_central_sig),
- 4) != 0)
- && (!G.ecrec.is_zip64_archive)
- && (memcmp(G.sig, end_central_sig, 4) != 0)
- ) { /* just to make sure again */
- Info(slide, 0x401, ((char *)slide, LoadFarString(EndSigMsg)));
- error_in_archive = PK_WARN; /* didn't find sig */
- }
- /* Set specific return code when no files have been found. */
- if (members == 0L && error_in_archive <= PK_WARN)
- error_in_archive = PK_FIND;
- }
- return error_in_archive;
- } /* end function list_files() */
- #ifdef TIMESTAMP
- /************************/
- /* Function fn_is_dir() */
- /************************/
- static int fn_is_dir(__G) /* returns TRUE if G.filename is directory */
- __GDEF
- {
- extent fn_len = strlen(G.filename);
- register char endc;
- return fn_len > 0 &&
- ((endc = lastchar(G.filename, fn_len)) == '/' ||
- (G.pInfo->hostnum == FS_FAT_ && !MBSCHR(G.filename, '/') &&
- endc == '\\'));
- }
- /*****************************/
- /* Function get_time_stamp() */
- /*****************************/
- int get_time_stamp(__G__ last_modtime, nmember) /* return PK-type error code */
- __GDEF
- time_t *last_modtime;
- ulg *nmember;
- {
- int do_this_file=FALSE, error, error_in_archive=PK_COOL;
- ulg j;
- #ifdef USE_EF_UT_TIME
- iztimes z_utime;
- #endif
- min_info info;
- /*---------------------------------------------------------------------------
- Unlike extract_or_test_files() but like list_files(), this function works
- on information in the central directory alone. Thus we have a single,
- large loop through the entire directory, searching for the latest time
- stamp.
- ---------------------------------------------------------------------------*/
- *last_modtime = 0L; /* assuming no zipfile data older than 1970 */
- *nmember = 0L;
- G.pInfo = &info;
- for (j = 1L;; j++) {
- if (readbuf(__G__ G.sig, 4) == 0)
- return PK_EOF;
- if (memcmp(G.sig, central_hdr_sig, 4)) { /* is it a CentDir entry? */
- if (((unsigned)(j - 1) & (unsigned)0xFFFF) ==
- (unsigned)G.ecrec.total_entries_central_dir) {
- /* "j modulus 64k" matches the reported 16-bit-unsigned
- * number of directory entries -> probably, the regular
- * end of the central directory has been reached
- */
- break;
- } else {
- Info(slide, 0x401,
- ((char *)slide, LoadFarString(CentSigMsg), j));
- Info(slide, 0x401,
- ((char *)slide, LoadFarString(ReportMsg)));
- return PK_BADERR; /* sig not found */
- }
- }
- /* process_cdir_file_hdr() sets pInfo->lcflag: */
- if ((error = process_cdir_file_hdr(__G)) != PK_COOL)
- return error; /* only PK_EOF defined */
- if ((error = do_string(__G__ G.crec.filename_length, DS_FN)) != PK_OK)
- { /* ^-- (uses pInfo->lcflag) */
- error_in_archive = error;
- if (error > PK_WARN) /* fatal: can't continue */
- return error;
- }
- if (G.extra_field != (uch *)NULL) {
- free(G.extra_field);
- G.extra_field = (uch *)NULL;
- }
- if ((error = do_string(__G__ G.crec.extra_field_length, EXTRA_FIELD))
- != 0)
- {
- error_in_archive = error;
- if (error > PK_WARN) /* fatal */
- return error;
- }
- if (!G.process_all_files) { /* check if specified on command line */
- unsigned i;
- if (G.filespecs == 0)
- do_this_file = TRUE;
- else { /* check if this entry matches an `include' argument */
- do_this_file = FALSE;
- for (i = 0; i < G.filespecs; i++)
- if (match(G.filename, G.pfnames[i], uO.C_flag WISEP)) {
- do_this_file = TRUE;
- break; /* found match, so stop looping */
- }
- }
- if (do_this_file) { /* check if this is an excluded file */
- for (i = 0; i < G.xfilespecs; i++)
- if (match(G.filename, G.pxnames[i], uO.C_flag WISEP)) {
- do_this_file = FALSE; /* ^-- ignore case in match */
- break;
- }
- }
- }
- /* If current file was specified on command line, or if no names were
- * specified, check the time for this file. Either way, get rid of the
- * file comment and go back for the next file.
- * Directory entries are always ignored, to stay compatible with both
- * Zip and PKZIP.
- */
- if ((G.process_all_files || do_this_file) && !fn_is_dir(__G)) {
- #ifdef USE_EF_UT_TIME
- if (G.extra_field &&
- #ifdef IZ_CHECK_TZ
- G.tz_is_valid &&
- #endif
- (ef_scan_for_izux(G.extra_field, G.crec.extra_field_length, 1,
- G.crec.last_mod_dos_datetime, &z_utime, NULL)
- & EB_UT_FL_MTIME))
- {
- if (*last_modtime < z_utime.mtime)
- *last_modtime = z_utime.mtime;
- } else
- #endif /* USE_EF_UT_TIME */
- {
- time_t modtime = dos_to_unix_time(G.crec.last_mod_dos_datetime);
- if (*last_modtime < modtime)
- *last_modtime = modtime;
- }
- ++*nmember;
- }
- SKIP_(G.crec.file_comment_length)
- } /* end for-loop (j: files in central directory) */
- /*---------------------------------------------------------------------------
- Double check that we're back at the end-of-central-directory record.
- ---------------------------------------------------------------------------*/
- if (memcmp(G.sig, end_central_sig, 4)) { /* just to make sure again */
- Info(slide, 0x401, ((char *)slide, LoadFarString(EndSigMsg)));
- error_in_archive = PK_WARN;
- }
- if (*nmember == 0L && error_in_archive <= PK_WARN)
- error_in_archive = PK_FIND;
- return error_in_archive;
- } /* end function get_time_stamp() */
- #endif /* TIMESTAMP */
- /********************/
- /* Function ratio() */ /* also used by ZipInfo routines */
- /********************/
- int ratio(uc, c)
- zusz_t uc, c;
- {
- zusz_t denom;
- if (uc == 0)
- return 0;
- if (uc > 2000000L) { /* risk signed overflow if multiply numerator */
- denom = uc / 1000L;
- return ((uc >= c) ?
- (int) ((uc-c + (denom>>1)) / denom) :
- -((int) ((c-uc + (denom>>1)) / denom)));
- } else { /* ^^^^^^^^ rounding */
- denom = uc;
- return ((uc >= c) ?
- (int) ((1000L*(uc-c) + (denom>>1)) / denom) :
- -((int) ((1000L*(c-uc) + (denom>>1)) / denom)));
- } /* ^^^^^^^^ rounding */
- }
- /************************/
- /* Function fnprint() */ /* also used by ZipInfo routines */
- /************************/
- void fnprint(__G) /* print filename (after filtering) and newline */
- __GDEF
- {
- char *name = fnfilter(G.filename, slide, (extent)(WSIZE>>1));
- (*G.message)((zvoid *)&G, (uch *)name, (ulg)strlen(name), 0);
- (*G.message)((zvoid *)&G, (uch *)"\n", 1L, 0);
- } /* end function fnprint() */
|