summaryrefslogtreecommitdiff
path: root/Build/source/extra/unzip/list.c
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/extra/unzip/list.c')
-rw-r--r--Build/source/extra/unzip/list.c644
1 files changed, 644 insertions, 0 deletions
diff --git a/Build/source/extra/unzip/list.c b/Build/source/extra/unzip/list.c
new file mode 100644
index 00000000000..0dc1e8a1286
--- /dev/null
+++ b/Build/source/extra/unzip/list.c
@@ -0,0 +1,644 @@
+/*---------------------------------------------------------------------------
+
+ 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 Ratio 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[] =
+ "%8lu %-7s%8lu %4s %02u-%02u-%02u %02u:%02u %08lx %c";
+ static ZCONST char Far LongFileTrailer[] =
+ "-------- ------- --- \
+ -------\n%8lu %8lu %4s %u file%s\n";
+#ifdef OS2_EAS
+ static ZCONST char Far ShortHdrStats[] =
+ "%9lu %6lu %6lu %02u-%02u-%02u %02u:%02u %c";
+ static ZCONST char Far ShortFileTrailer[] = " -------- ----- ----- \
+ -------\n%9lu %6lu %6lu %u file%s\n";
+ static ZCONST char Far OS2ExtAttrTrailer[] =
+ "%ld file%s %ld bytes of OS/2 extended attributes attached.\n";
+ static ZCONST char Far OS2ACLTrailer[] =
+ "%ld file%s %ld bytes of access control lists attached.\n";
+#else
+ static ZCONST char Far ShortHdrStats[] =
+ "%9lu %02u-%02u-%02u %02u:%02u %c";
+ static ZCONST char Far ShortFileTrailer[] =
+ " -------- -------\n%9lu %u 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;
+ unsigned j, methnum, members=0;
+#ifdef USE_EF_UT_TIME
+ iztimes z_utime;
+ struct tm *t;
+#endif
+ unsigned yr, mo, dy, hh, mm;
+ ulg 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:#", "EnhDefl", "ImplDCL", "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;
+
+#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 = 0; j++ < (unsigned)G.ecrec.total_entries_central_dir;) {
+
+ if (readbuf(__G__ G.sig, 4) == 0)
+ return PK_EOF;
+ if (strncmp(G.sig, central_hdr_sig, 4)) { /* just to make sure */
+ 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;
+
+ do_this_file = FALSE;
+ for (i = 0; i < G.filespecs; i++)
+ if (match(G.filename, G.pfnames[i], uO.C_flag)) {
+ 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)) {
+ 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 % 100);
+ 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)
+ + 80) % (unsigned)100);
+ 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 = (unsigned)mo;
+ mo = yr; yr = dy; dy = (ush)methnum;
+ break;
+ case DF_DMY:
+ methnum = (unsigned)mo;
+ mo = dy; dy = (ush)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 = MIN(G.crec.compression_method, NUM_METHODS);
+ zfstrcpy(methbuf, method[methnum]);
+ if (methnum == DEFLATED) {
+ 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_OS2_W32) || defined(UNIX)
+ for (p = G.filename; *p; ++p)
+ if (!isprint(*p))
+ *p = '?'; /* change non-printable chars to '?' */
+#endif /* DOS_FLX_OS2_W32 || UNIX */
+#endif /* 0 */
+
+#ifdef WINDLL
+ /* send data to application for formatting and printing */
+ (*G.lpUserFunctions->SendApplicationMessage)(G.crec.ucsize, csiz,
+ (ush)cfactor, mo, dy, yr, hh, mm,
+ (char)(G.pInfo->lcflag ? '^' : ' '),
+ (LPSTR)fnfilter(G.filename, slide), (LPSTR)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),
+ G.crec.ucsize, methbuf, csiz, cfactorstr, mo, dy,
+ yr, hh, mm, G.crec.crc32, (G.pInfo->lcflag? '^':' ')));
+ else
+#ifdef OS2_EAS
+ Info(slide, 0, ((char *)slide, LoadFarString(ShortHdrStats),
+ G.crec.ucsize, ea_size, acl_size,
+ mo, dy, yr, hh, mm, (G.pInfo->lcflag? '^':' ')));
+#else
+ Info(slide, 0, ((char *)slide, LoadFarString(ShortHdrStats),
+ G.crec.ucsize,
+ mo, dy, 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 = 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),
+ tot_ucsize, tot_csize, 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),
+ tot_ucsize, tot_easize, tot_aclsize, members, members == 1?
+ "" : "s"));
+#else
+ Info(slide, 0, ((char *)slide, LoadFarString(ShortFileTrailer),
+ tot_ucsize, members, members == 1? "" : "s"));
+#endif /* OS2_EAS */
+#endif /* ?WINDLL */
+ }
+
+/*---------------------------------------------------------------------------
+ Double check that we're back at the end-of-central-directory record.
+ ---------------------------------------------------------------------------*/
+
+ if (readbuf(__G__ G.sig, 4) == 0) /* disk error? */
+ return PK_EOF;
+ if (strncmp(G.sig, end_central_sig, 4)) { /* just to make sure again */
+ Info(slide, 0x401, ((char *)slide, LoadFarString(EndSigMsg)));
+ error_in_archive = PK_WARN; /* didn't find sig */
+ }
+ if (members == 0 && 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 = G.filename[fn_len-1]) == '/' ||
+ (G.pInfo->hostnum == FS_FAT_ && !strchr(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;
+ unsigned *nmember;
+{
+ int do_this_file=FALSE, error, error_in_archive=PK_COOL;
+ unsigned 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 = 0;
+ G.pInfo = &info;
+
+ for (j = 0; j++ < (unsigned)G.ecrec.total_entries_central_dir;) {
+
+ if (readbuf(__G__ G.sig, 4) == 0)
+ return PK_EOF;
+ if (strncmp(G.sig, central_hdr_sig, 4)) { /* just to make sure */
+ Info(slide, 0x401, ((char *)slide, LoadFarString(CentSigMsg), j));
+ Info(slide, 0x401, ((char *)slide, LoadFarString(ReportMsg)));
+ return PK_BADERR;
+ }
+ /* 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;
+
+ do_this_file = FALSE;
+ for (i = 0; i < G.filespecs; i++)
+ if (match(G.filename, G.pfnames[i], uO.C_flag)) {
+ 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)) {
+ 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 (readbuf(__G__ G.sig, 4) == 0)
+ return PK_EOF;
+ if (strncmp(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 == 0 && 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)
+ ulg uc, c;
+{
+ ulg 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);
+
+ (*G.message)((zvoid *)&G, (uch *)name, (ulg)strlen(name), 0);
+ (*G.message)((zvoid *)&G, (uch *)"\n", 1L, 0);
+
+} /* end function fnprint() */