btrfs: Attempt to fix GCC2 build.
[haiku.git] / src / bin / unzip / list.c
blobda6d06aba3a9690cb86b62aa9cec7467068e4e29
1 /*
2 Copyright (c) 1990-2001 Info-ZIP. All rights reserved.
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 /*---------------------------------------------------------------------------
11 list.c
13 This file contains the non-ZipInfo-specific listing routines for UnZip.
15 Contains: list_files()
16 get_time_stamp() [optional feature]
17 ratio()
18 fnprint()
20 ---------------------------------------------------------------------------*/
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
34 #ifdef TIMESTAMP
35 static int fn_is_dir OF((__GPRO));
36 #endif
38 #ifndef WINDLL
39 static ZCONST char Far CompFactorStr[] = "%c%d%%";
40 static ZCONST char Far CompFactor100[] = "100%%";
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
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} };
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 */
87 /*************************/
88 /* Function list_files() */
89 /*************************/
91 int list_files(__G) /* return PK-type error code */
92 __GDEF
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:###"};
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.
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:
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 ---------------------------------------------------------------------------*/
138 G.pInfo = &info;
139 date_format = DATE_FORMAT;
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])));
152 #endif /* !WINDLL */
154 for (j = 1L;;j++) {
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
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 */
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 */
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.
189 if ((error = do_string(__G__ G.crec.filename_length, DS_FN)) !=
190 PK_COOL) /* ^--(uses pInfo->lcflag) */
192 error_in_archive = error;
193 if (error > PK_WARN) /* fatal: can't continue */
194 return error;
196 if (G.extra_field != (uch *)NULL) {
197 free(G.extra_field);
198 G.extra_field = (uch *)NULL;
200 if ((error = do_string(__G__ G.crec.extra_field_length, EXTRA_FIELD))
201 != 0)
203 error_in_archive = error;
204 if (error > PK_WARN) /* fatal */
205 return error;
207 if (!G.process_all_files) { /* check if specified on command line */
208 unsigned i;
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 */
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;
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.
230 if (G.process_all_files || do_this_file) {
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
243 uch *ef_ptr = G.extra_field;
244 int ef_size, ef_len = G.crec.extra_field_length;
245 ea_size = acl_size = 0;
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;
257 ef_ptr += (ef_size + EB_HEADSIZE);
258 ef_len -= (ef_size + EB_HEADSIZE);
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))
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 */
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);
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;
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;
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);
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 */
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 */
363 if ((error = do_string(__G__ G.crec.file_comment_length,
364 QCOND? DISPL_8 : SKIP)) != 0)
366 error_in_archive = error; /* might be just warning */
367 if (error > PK_WARN) /* fatal */
368 return error;
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;
378 if (acl_size) {
379 tot_aclsize += acl_size;
380 ++tot_aclfiles;
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)
389 } /* end for-loop (j: files in central directory) */
391 /*---------------------------------------------------------------------------
392 Print footer line and totals (compressed size, uncompressed size, number
393 of members in zipfile).
394 ---------------------------------------------------------------------------*/
396 if (uO.qflag < 2
397 #ifdef OS2DLL
398 && !G.processExternally
399 #endif
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;
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;
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 */
451 /*---------------------------------------------------------------------------
452 Double check that we're back at the end-of-central-directory record.
453 ---------------------------------------------------------------------------*/
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 */
459 if (members == 0L && error_in_archive <= PK_WARN)
460 error_in_archive = PK_FIND;
462 return error_in_archive;
464 } /* end function list_files() */
470 #ifdef TIMESTAMP
472 /************************/
473 /* Function fn_is_dir() */
474 /************************/
476 static int fn_is_dir(__G) /* returns TRUE if G.filename is directory */
477 __GDEF
479 extent fn_len = strlen(G.filename);
480 register char endc;
482 return fn_len > 0 &&
483 ((endc = lastchar(G.filename, fn_len)) == '/' ||
484 (G.pInfo->hostnum == FS_FAT_ && !MBSCHR(G.filename, '/') &&
485 endc == '\\'));
492 /*****************************/
493 /* Function get_time_stamp() */
494 /*****************************/
496 int get_time_stamp(__G__ last_modtime, nmember) /* return PK-type error code */
497 __GDEF
498 time_t *last_modtime;
499 ulg *nmember;
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;
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 ---------------------------------------------------------------------------*/
516 *last_modtime = 0L; /* assuming no zipfile data older than 1970 */
517 *nmember = 0L;
518 G.pInfo = &info;
520 for (j = 1L;; j++) {
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
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 */
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;
549 if (G.extra_field != (uch *)NULL) {
550 free(G.extra_field);
551 G.extra_field = (uch *)NULL;
553 if ((error = do_string(__G__ G.crec.extra_field_length, EXTRA_FIELD))
554 != 0)
556 error_in_archive = error;
557 if (error > PK_WARN) /* fatal */
558 return error;
560 if (!G.process_all_files) { /* check if specified on command line */
561 unsigned i;
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 */
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;
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.
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))
594 if (*last_modtime < z_utime.mtime)
595 *last_modtime = z_utime.mtime;
596 } else
597 #endif /* USE_EF_UT_TIME */
599 time_t modtime = dos_to_unix_time(G.crec.last_mod_dos_datetime);
601 if (*last_modtime < modtime)
602 *last_modtime = modtime;
604 ++*nmember;
606 SKIP_(G.crec.file_comment_length)
608 } /* end for-loop (j: files in central directory) */
610 /*---------------------------------------------------------------------------
611 Double check that we're back at the end-of-central-directory record.
612 ---------------------------------------------------------------------------*/
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;
618 if (*nmember == 0L && error_in_archive <= PK_WARN)
619 error_in_archive = PK_FIND;
621 return error_in_archive;
623 } /* end function get_time_stamp() */
625 #endif /* TIMESTAMP */
631 /********************/
632 /* Function ratio() */ /* also used by ZipInfo routines */
633 /********************/
635 int ratio(uc, c)
636 ulg uc, c;
638 ulg denom;
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 */
659 /************************/
660 /* Function fnprint() */ /* also used by ZipInfo routines */
661 /************************/
663 void fnprint(__G) /* print filename (after filtering) and newline */
664 __GDEF
666 char *name = fnfilter(G.filename, slide);
668 (*G.message)((zvoid *)&G, (uch *)name, (ulg)strlen(name), 0);
669 (*G.message)((zvoid *)&G, (uch *)"\n", 1L, 0);
671 } /* end function fnprint() */