1/* 2 zipup.c - Zip 3 3 4 Copyright (c) 1990-2008 Info-ZIP. All rights reserved. 5 6 See the accompanying file LICENSE, version 2007-Mar-4 or later 7 (the contents of which are also included in zip.h) for terms of use. 8 If, for some reason, all these files are missing, the Info-ZIP license 9 also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html 10*/ 11/* 12 * zipup.c by Mark Adler and Jean-loup Gailly. 13 */ 14#define __ZIPUP_C 15 16/* Found that for at least unix port zip.h has to be first or ctype.h will 17 define off_t and when using 64-bit file environment off_t in other files 18 is 8 bytes while off_t here is 4 bytes, and this makes the zlist struct 19 different sizes and needless to say leads to segmentation faults. Putting 20 zip.h first seems to fix this. 8/14/04 EG */ 21#include "zip.h" 22#include <ctype.h> 23#include <errno.h> 24 25#ifndef UTIL /* This module contains no code for Zip Utilities */ 26 27#include "revision.h" 28#include "crc32.h" 29#include "crypt.h" 30#ifdef USE_ZLIB 31# include "zlib.h" 32#endif 33#ifdef BZIP2_SUPPORT 34# ifdef BZIP2_USEBZIP2DIR 35# include "bzip2/bzlib.h" 36# else 37# include "bzlib.h" 38# endif 39#endif 40 41#ifdef OS2 42# include "os2/os2zip.h" 43#endif 44 45#if defined(MMAP) 46# include <sys/mman.h> 47# ifndef PAGESIZE /* used to be SYSV, what about pagesize on SVR3 ? */ 48# define PAGESIZE getpagesize() 49# endif 50# if defined(NO_VALLOC) && !defined(valloc) 51# define valloc malloc 52# endif 53#endif 54 55/* Use the raw functions for MSDOS and Unix to save on buffer space. 56 They're not used for VMS since it doesn't work (raw is weird on VMS). 57 */ 58 59#ifdef AMIGA 60# include "amiga/zipup.h" 61#endif /* AMIGA */ 62 63#ifdef AOSVS 64# include "aosvs/zipup.h" 65#endif /* AOSVS */ 66 67#ifdef ATARI 68# include "atari/zipup.h" 69#endif 70 71#ifdef __BEOS__ 72# include "beos/zipup.h" 73#endif 74 75#ifdef __ATHEOS__ 76# include "atheos/zipup.h" 77#endif /* __ATHEOS__ */ 78 79#ifdef __human68k__ 80# include "human68k/zipup.h" 81#endif /* __human68k__ */ 82 83#ifdef MACOS 84# include "macos/zipup.h" 85#endif 86 87#ifdef DOS 88# include "msdos/zipup.h" 89#endif /* DOS */ 90 91#ifdef NLM 92# include "novell/zipup.h" 93# include <nwfattr.h> 94#endif 95 96#ifdef OS2 97# include "os2/zipup.h" 98#endif /* OS2 */ 99 100#ifdef RISCOS 101# include "acorn/zipup.h" 102#endif 103 104#ifdef TOPS20 105# include "tops20/zipup.h" 106#endif 107 108#ifdef UNIX 109# include "unix/zipup.h" 110#endif 111 112#ifdef CMS_MVS 113# include "zipup.h" 114#endif /* CMS_MVS */ 115 116#ifdef TANDEM 117# include "zipup.h" 118#endif /* TANDEM */ 119 120#ifdef VMS 121# include "vms/zipup.h" 122#endif /* VMS */ 123 124#ifdef QDOS 125# include "qdos/zipup.h" 126#endif /* QDOS */ 127 128#ifdef WIN32 129# include "win32/zipup.h" 130#endif 131 132#ifdef THEOS 133# include "theos/zipup.h" 134#endif 135 136/* Local functions */ 137#ifndef RISCOS 138 local int suffixes OF((char *, char *)); 139#else 140 local int filetypes OF((char *, char *)); 141#endif 142local unsigned file_read OF((char *buf, unsigned size)); 143#ifdef USE_ZLIB 144 local int zl_deflate_init OF((int pack_level)); 145#else /* !USE_ZLIB */ 146# ifdef ZP_NEED_MEMCOMPR 147 local unsigned mem_read OF((char *buf, unsigned size)); 148# endif 149#endif /* ?USE_ZLIB */ 150 151/* zip64 support 08/29/2003 R.Nausedat */ 152local zoff_t filecompress OF((struct zlist far *z_entry, int *cmpr_method)); 153 154#ifdef BZIP2_SUPPORT 155local zoff_t bzfilecompress OF((struct zlist far *z_entry, int *cmpr_method)); 156#endif 157 158/* Deflate "internal" global data (currently not in zip.h) */ 159#if defined(MMAP) || defined(BIG_MEM) 160# ifdef USE_ZLIB 161 local uch *window = NULL; /* Used to read all input file at once */ 162 local ulg window_size; /* size of said window */ 163# else /* !USE_ZLIB */ 164 extern uch *window; /* Used to read all input file at once */ 165#endif /* ?USE_ZLIB */ 166#endif /* MMAP || BIG_MEM */ 167#ifndef USE_ZLIB 168 extern ulg window_size; /* size of said window */ 169 170 unsigned (*read_buf) OF((char *buf, unsigned size)) = file_read; 171 /* Current input function. Set to mem_read for in-memory compression */ 172#endif /* !USE_ZLIB */ 173 174 175/* Local data */ 176local ulg crc; /* crc on uncompressed file data */ 177local ftype ifile; /* file to compress */ 178#if defined(MMAP) || defined(BIG_MEM) 179 local ulg remain; 180 /* window bytes not yet processed. 181 * special value "(ulg)-1L" reserved to signal normal reads. 182 */ 183#endif /* MMAP || BIG_MEM */ 184#ifdef USE_ZLIB 185 local int deflInit = FALSE; /* flag: zlib deflate is initialized */ 186 local z_stream zstrm; /* zlib's data interface structure */ 187 local char *f_ibuf = NULL; 188 local char *f_obuf = NULL; 189#else /* !USE_ZLIB */ 190 local char file_outbuf[1024]; /* output buffer for compression to file */ 191 192# ifdef ZP_NEED_MEMCOMPR 193 local char *in_buf; 194 /* Current input buffer, in_buf is used only for in-memory compression. */ 195 local unsigned in_offset; 196 /* Current offset in input buffer. in_offset is used only for in-memory 197 * compression. On 16 bit machines, the buffer is limited to 64K. 198 */ 199 local unsigned in_size; /* size of current input buffer */ 200# endif /* ZP_NEED_MEMCOMPR */ 201#endif /* ?USE_ZLIB */ 202 203#ifdef BZIP2_SUPPORT 204 local int bzipInit; /* flag: bzip2lib is initialized */ 205 local bz_stream bstrm; /* zlib's data interface structure */ 206# if !defined(USE_ZLIB) 207 local char *f_ibuf = NULL; 208 local char *f_obuf = NULL; 209# endif /* !USE_ZLIB */ 210#endif /* BZIP2_SUPPORT */ 211 212#ifdef DEBUG 213 zoff_t isize; /* input file size. global only for debugging */ 214#else /* !DEBUG */ 215 local zoff_t isize; /* input file size. global only for debugging */ 216#endif /* ?DEBUG */ 217 /* If file_read detects binary it sets this flag - 12/16/04 EG */ 218 local int file_binary = 0; /* first buf */ 219 local int file_binary_final = 0; /* for bzip2 for entire file. assume text until find binary */ 220 221 222/* moved check to function 3/14/05 EG */ 223int is_seekable(y) 224 FILE *y; 225{ 226 zoff_t pos; 227 228#ifdef BROKEN_FSEEK 229 if (!fseekable(y)) { 230 return 0; 231 } 232#endif 233 234 pos = zftello(y); 235 if (zfseeko(y, pos, SEEK_SET)) { 236 return 0; 237 } 238 239 return 1; 240} 241 242 243int percent(n, m) 244 uzoff_t n; 245 uzoff_t m; /* n is the original size, m is the new size */ 246/* Return the percentage compression from n to m using only integer 247 operations */ 248{ 249 zoff_t p; 250 251#if 0 252 if (n > 0xffffffL) /* If n >= 16M */ 253 { /* then divide n and m by 256 */ 254 n += 0x80; n >>= 8; 255 m += 0x80; m >>= 8; 256 } 257 return n > m ? (int)(1 + (200 * (n - m)/n)) / 2 : 0; 258#endif 259 260/* 2004-12-01 SMS. 261 * Changed to do big-n test only for small zoff_t. 262 * Changed big-n arithmetic to accomodate apparently negative values 263 * when a small zoff_t value exceeds 2G. 264 * Increased the reduction divisor from 256 to 512 to avoid the sign bit 265 * in a reduced intermediate, allowing signed arithmetic for the final 266 * result (which is no longer artificially limited to non-negative 267 * values). 268 * Note that right shifts must be on unsigned values to avoid undesired 269 * sign extension. 270 */ 271 272/* Handle n = 0 case and account for int maybe being 16-bit. 12/28/2004 EG 273 */ 274 275#define PC_MAX_SAFE 0x007fffffL /* 9 clear bits at high end. */ 276#define PC_MAX_RND 0xffffff00L /* 8 clear bits at low end. */ 277 278 if (sizeof(uzoff_t) < 8) /* Don't fiddle with big zoff_t. */ 279 { 280 if ((ulg)n > PC_MAX_SAFE) /* Reduce large values. (n > m) */ 281 { 282 if ((ulg)n < PC_MAX_RND) /* Divide n by 512 with rounding, */ 283 n = ((ulg)n + 0x100) >> 9; /* if boost won't overflow. */ 284 else /* Otherwise, use max value. */ 285 n = PC_MAX_SAFE; 286 287 if ((ulg)m < PC_MAX_RND) /* Divide m by 512 with rounding, */ 288 m = ((ulg)m + 0x100) >> 9; /* if boost won't overflow. */ 289 else /* Otherwise, use max value. */ 290 m = PC_MAX_SAFE; 291 } 292 } 293 if (n != 0) 294 p = ((200 * ((zoff_t)n - (zoff_t)m) / (zoff_t)n) + 1) / 2; 295 else 296 p = 0; 297 return (int)p; /* Return (rounded) % reduction. */ 298} 299 300 301#ifndef RISCOS 302 303local int suffixes(a, s) 304 char *a; /* name to check suffix of */ 305 char *s; /* list of suffixes separated by : or ; */ 306/* Return true if a ends in any of the suffixes in the list s. */ 307{ 308 int m; /* true if suffix matches so far */ 309 char *p; /* pointer into special */ 310 char *q; /* pointer into name a */ 311 312#ifdef QDOS 313 short dlen = devlen(a); 314 a = a + dlen; 315#endif 316 317 m = 1; 318#ifdef VMS 319 if( (q = strrchr(a,';')) != NULL ) /* Cut out VMS file version */ 320 --q; 321 else 322 q = a + strlen(a) - 1; 323#else /* !VMS */ 324 q = a + strlen(a) - 1; 325#endif /* ?VMS */ 326 for (p = s + strlen(s) - 1; p >= s; p--) 327 if (*p == ':' || *p == ';') 328 { 329 if (m) 330 return 1; 331 else 332 { 333 m = 1; 334#ifdef VMS 335 if( (q = strrchr(a,';')) != NULL ) /* Cut out VMS file version */ 336 --q; 337 else 338 q = a + strlen(a) - 1; 339#else /* !VMS */ 340 q = a + strlen(a) - 1; 341#endif /* ?VMS */ 342 } 343 } 344 else 345 { 346 m = m && q >= a && case_map(*p) == case_map(*q); 347 q--; 348 } 349 return m; 350} 351 352#else /* RISCOS */ 353 354local int filetypes(a, s) 355char *a; /* extra field of file to check filetype of */ 356char *s; /* list of filetypes separated by : or ; */ 357/* Return true if a is any of the filetypes in the list s. */ 358{ 359 char *p; /* pointer into special */ 360 char typestr[4]; /* filetype hex string taken from a */ 361 362 if ((((unsigned*)a)[2] & 0xFFF00000) != 0xFFF00000) { 363 /* The file is not filestamped, always try to compress it */ 364 return 0; 365 } 366 367 sprintf(typestr,"%.3X",(((unsigned*)a)[2] & 0x000FFF00) >> 8); 368 369 for (p=s;p<=s+strlen(s)-3;p+=3) { /* p+=3 to skip 3 hex type */ 370 while (*p==':' || *p==';') 371 p++; 372 373 if (typestr[0] == toupper(p[0]) && 374 typestr[1] == toupper(p[1]) && 375 typestr[2] == toupper(p[2])) 376 return 1; 377 } 378 return 0; 379} 380#endif /* ?RISCOS */ 381 382 383 384/* Note: a zip "entry" includes a local header (which includes the file 385 name), an encryption header if encrypting, the compressed data 386 and possibly an extended local header. */ 387 388int zipup(z) 389struct zlist far *z; /* zip entry to compress */ 390/* Compress the file z->name into the zip entry described by *z and write 391 it to the file *y. Encrypt if requested. Return an error code in the 392 ZE_ class. Also, update tempzn by the number of bytes written. */ 393/* y is now global */ 394{ 395 iztimes f_utim; /* UNIX GMT timestamps, filled by filetime() */ 396 ulg tim; /* time returned by filetime() */ 397 ulg a = 0L; /* attributes returned by filetime() */ 398 char *b; /* malloc'ed file buffer */ 399 extent k = 0; /* result of zread */ 400 int l = 0; /* true if this file is a symbolic link */ 401 int m; /* method for this entry */ 402 403 zoff_t o = 0, p; /* offsets in zip file */ 404 zoff_t q = (zoff_t) -3; /* size returned by filetime */ 405 uzoff_t uq; /* unsigned q */ 406 zoff_t s = 0; /* size of compressed data */ 407 408 int r; /* temporary variable */ 409 int isdir; /* set for a directory name */ 410 int set_type = 0; /* set if file type (ascii/binary) unknown */ 411 zoff_t last_o; /* used to detect wrap around */ 412 413 ush tempext = 0; /* temp copies of extra fields */ 414 ush tempcext = 0; 415 char *tempextra = NULL; 416 char *tempcextra = NULL; 417 418 419#ifdef WINDLL 420# ifdef ZIP64_SUPPORT 421 extern _int64 filesize64; 422 extern unsigned long low; 423 extern unsigned long high; 424# endif 425#endif 426 427 z->nam = strlen(z->iname); 428 isdir = z->iname[z->nam-1] == (char)0x2f; /* ascii[(unsigned)('/')] */ 429 430 file_binary = -1; /* not set, set after first read */ 431 file_binary_final = 0; /* not set, set after first read */ 432 433#if defined(UNICODE_SUPPORT) && defined(WIN32) 434 if (!no_win32_wide) 435 tim = filetimew(z->namew, &a, &q, &f_utim); 436 else 437 tim = filetime(z->name, &a, &q, &f_utim); 438#else 439 tim = filetime(z->name, &a, &q, &f_utim); 440#endif 441 if (tim == 0 || q == (zoff_t) -3) 442 return ZE_OPEN; 443 444 /* q is set to -1 if the input file is a device, -2 for a volume label */ 445 if (q == (zoff_t) -2) { 446 isdir = 1; 447 q = 0; 448 } else if (isdir != ((a & MSDOS_DIR_ATTR) != 0)) { 449 /* don't overwrite a directory with a file and vice-versa */ 450 return ZE_MISS; 451 } 452 /* reset dot_count for each file */ 453 if (!display_globaldots) 454 dot_count = -1; 455 456 /* display uncompressed size */ 457 uq = ((uzoff_t) q > (uzoff_t) -3) ? 0 : (uzoff_t) q; 458 if (noisy && display_usize) { 459 fprintf(mesg, " ("); 460 DisplayNumString( mesg, uq ); 461 fprintf(mesg, ")"); 462 mesg_line_started = 1; 463 fflush(mesg); 464 } 465 if (logall && display_usize) { 466 fprintf(logfile, " ("); 467 DisplayNumString( logfile, uq ); 468 fprintf(logfile, ")"); 469 logfile_line_started = 1; 470 fflush(logfile); 471 } 472 473 /* initial z->len so if error later have something */ 474 z->len = uq; 475 476 z->att = (ush)UNKNOWN; /* will be changed later */ 477 z->atx = 0; /* may be changed by set_extra_field() */ 478 479 /* Free the old extra fields which are probably obsolete */ 480 /* Should probably read these and keep any we don't update. 12/30/04 EG */ 481 if (extra_fields == 2) { 482 /* If keeping extra fields, make copy before clearing for set_extra_field() 483 A better approach is to modify the port code, but maybe later */ 484 if (z->ext) { 485 if ((tempextra = malloc(z->ext)) == NULL) { 486 ZIPERR(ZE_MEM, "extra fields copy"); 487 } 488 memcpy(tempextra, z->extra, z->ext); 489 tempext = z->ext; 490 } 491 if (z->cext) { 492 if ((tempcextra = malloc(z->cext)) == NULL) { 493 ZIPERR(ZE_MEM, "extra fields copy"); 494 } 495 memcpy(tempcextra, z->cextra, z->cext); 496 tempcext = z->cext; 497 } 498 } 499 if (z->ext) { 500 free((zvoid *)(z->extra)); 501 } 502 if (z->cext && z->extra != z->cextra) { 503 free((zvoid *)(z->cextra)); 504 } 505 z->extra = z->cextra = NULL; 506 z->ext = z->cext = 0; 507 508#if defined(MMAP) || defined(BIG_MEM) 509 remain = (ulg)-1L; /* changed only for MMAP or BIG_MEM */ 510#endif /* MMAP || BIG_MEM */ 511#if (!defined(USE_ZLIB) || defined(MMAP) || defined(BIG_MEM)) 512 window_size = 0L; 513#endif /* !USE_ZLIB || MMAP || BIG_MEM */ 514 515 /* Select method based on the suffix and the global method */ 516#ifndef RISCOS 517 m = special != NULL && suffixes(z->name, special) ? STORE : method; 518#else /* RISCOS must set m after setting extra field */ 519 m = method; 520#endif /* ?RISCOS */ 521 522 /* For now force deflate if using descriptors. Instead zip and unzip 523 could check bytes read against compressed size in each data descriptor 524 found and skip over any that don't match. This is how at least one 525 other zipper does it. To be added later. Until then it 526 probably doesn't hurt to force deflation when streaming. 12/30/04 EG 527 */ 528 529 /* Now is a good time. For now allow storing for testing. 12/16/05 EG */ 530 /* By release need to force deflation based on reports some inflate 531 streamed data to find the end of the data */ 532 /* Need to handle bzip2 */ 533#ifdef NO_STREAMING_STORE 534 if (use_descriptors && m == STORE) 535 { 536 m = DEFLATE; 537 } 538#endif 539 540 /* Open file to zip up unless it is stdin */ 541 if (strcmp(z->name, "-") == 0) 542 { 543 ifile = (ftype)zstdin; 544#if defined(MSDOS) || defined(__human68k__) 545 if (isatty(zstdin) == 0) /* keep default mode if stdin is a terminal */ 546 setmode(zstdin, O_BINARY); 547#endif 548 z->tim = tim; 549 } 550 else 551 { 552#if !(defined(VMS) && defined(VMS_PK_EXTRA)) 553 if (extra_fields) { 554 /* create extra field and change z->att and z->atx if desired */ 555 set_extra_field(z, &f_utim); 556# ifdef QLZIP 557 if(qlflag) 558 a |= (S_IXUSR) << 16; /* Cross compilers don't set this */ 559# endif 560# ifdef RISCOS 561 m = special != NULL && filetypes(z->extra, special) ? STORE : method; 562# endif /* RISCOS */ 563 564 /* For now allow store for testing */ 565#ifdef NO_STREAMING_STORE 566 /* For now force deflation if using data descriptors. */ 567 if (use_descriptors && m == STORE) 568 { 569 m = DEFLATE; 570 } 571#endif 572 573 } 574#endif /* !(VMS && VMS_PK_EXTRA) */ 575 l = issymlnk(a); 576 if (l) { 577 ifile = fbad; 578 m = STORE; 579 } 580 else if (isdir) { /* directory */ 581 ifile = fbad; 582 m = STORE; 583 q = 0; 584 } 585#ifdef THEOS 586 else if (((a >> 16) & S_IFMT) == S_IFLIB) { /* library */ 587 ifile = fbad; 588 m = STORE; 589 q = 0; 590 } 591#endif 592 else { 593#ifdef CMS_MVS 594 if (bflag) { 595 if ((ifile = zopen(z->name, fhowb)) == fbad) 596 return ZE_OPEN; 597 } 598 else 599#endif /* CMS_MVS */ 600#if defined(UNICODE_SUPPORT) && defined(WIN32) 601 if (!no_win32_wide) { 602 if ((ifile = zwopen(z->namew, fhow)) == fbad) 603 return ZE_OPEN; 604 } else { 605 if ((ifile = zopen(z->name, fhow)) == fbad) 606 return ZE_OPEN; 607 } 608#else 609 if ((ifile = zopen(z->name, fhow)) == fbad) 610 return ZE_OPEN; 611#endif 612 } 613 614 z->tim = tim; 615 616#if defined(VMS) && defined(VMS_PK_EXTRA) 617 /* vms_get_attributes must be called after vms_open() */ 618 if (extra_fields) { 619 /* create extra field and change z->att and z->atx if desired */ 620 vms_get_attributes(ifile, z, &f_utim); 621 } 622#endif /* VMS && VMS_PK_EXTRA */ 623 624#if defined(MMAP) || defined(BIG_MEM) 625 /* Map ordinary files but not devices. This code should go in fileio.c */ 626 if (!translate_eol && m != STORE && q != -1L && (ulg)q > 0 && 627 (ulg)q + MIN_LOOKAHEAD > (ulg)q) { 628# ifdef MMAP 629 /* Map the whole input file in memory */ 630 if (window != NULL) 631 free(window); /* window can't be a mapped file here */ 632 window_size = (ulg)q + MIN_LOOKAHEAD; 633 remain = window_size & (PAGESIZE-1); 634 /* If we can't touch the page beyond the end of file, we must 635 * allocate an extra page. 636 */ 637 if (remain > MIN_LOOKAHEAD) { 638 window = (uch*)mmap(0, window_size, PROT_READ, MAP_PRIVATE, ifile, 0); 639 } else { 640 window = (uch*)valloc(window_size - remain + PAGESIZE); 641 if (window != NULL) { 642 window = (uch*)mmap((char*)window, window_size - remain, PROT_READ, 643 MAP_PRIVATE | MAP_FIXED, ifile, 0); 644 } else { 645 window = (uch*)(-1); 646 } 647 } 648 if (window == (uch*)(-1)) { 649 Trace((mesg, " mmap failure on %s\n", z->name)); 650 window = NULL; 651 window_size = 0L; 652 remain = (ulg)-1L; 653 } else { 654 remain = (ulg)q; 655 } 656# else /* !MMAP, must be BIG_MEM */ 657 /* Read the whole input file at once */ 658 window_size = (ulg)q + MIN_LOOKAHEAD; 659 window = window ? (uch*) realloc(window, (unsigned)window_size) 660 : (uch*) malloc((unsigned)window_size); 661 /* Just use normal code if big malloc or realloc fails: */ 662 if (window != NULL) { 663 remain = (ulg)zread(ifile, (char*)window, q+1); 664 if (remain != (ulg)q) { 665 fprintf(mesg, " q=%lu, remain=%lu ", (ulg)q, remain); 666 error("can't read whole file at once"); 667 } 668 } else { 669 window_size = 0L; 670 } 671# endif /* ?MMAP */ 672 } 673#endif /* MMAP || BIG_MEM */ 674 675 } /* strcmp(z->name, "-") == 0 */ 676 677 if (extra_fields == 2) { 678 unsigned len; 679 char *p; 680 681 /* step through old extra fields and copy over any not already 682 in new extra fields */ 683 p = copy_nondup_extra_fields(tempextra, tempext, z->extra, z->ext, &len); 684 free(z->extra); 685 z->ext = len; 686 z->extra = p; 687 p = copy_nondup_extra_fields(tempcextra, tempcext, z->cextra, z->cext, &len); 688 free(z->cextra); 689 z->cext = len; 690 z->cextra = p; 691 692 if (tempext) 693 free(tempextra); 694 if (tempcext) 695 free(tempcextra); 696 } 697 698 if (q == 0) 699 m = STORE; 700 if (m == BEST) 701 m = DEFLATE; 702 703 /* Do not create STORED files with extended local headers if the 704 * input size is not known, because such files could not be extracted. 705 * So if the zip file is not seekable and the input file is not 706 * on disk, obey the -0 option by forcing deflation with stored block. 707 * Note however that using "zip -0" as filter is not very useful... 708 * ??? to be done. 709 */ 710 711 /* An alternative used by others is to allow storing but on reading do 712 * a second check when a signature is found. This is simply to check 713 * the compressed size to the bytes read since the start of the file data. 714 * If this is the right signature then the compressed size should match 715 * the size of the compressed data to that point. If not look for the 716 * next signature. We should do this. 12/31/04 EG 717 * 718 * For reading and testing we should do this, but should not write 719 * stored streamed data unless for testing as finding the end of 720 * streamed deflated data can be done by inflating. 6/26/06 EG 721 */ 722 723 /* Fill in header information and write local header to zip file. 724 * This header will later be re-written since compressed length and 725 * crc are not yet known. 726 */ 727 728 /* (Assume ext, cext, com, and zname already filled in.) */ 729#if defined(OS2) || defined(WIN32) 730# ifdef WIN32_OEM 731 /* When creating OEM-coded names on Win32, the entries must always be marked 732 as "created on MSDOS" (OS_CODE = 0), because UnZip needs to handle archive 733 entry names just like those created by Zip's MSDOS port. 734 */ 735 z->vem = (ush)(dosify ? 20 : 0 + Z_MAJORVER * 10 + Z_MINORVER); 736# else 737 z->vem = (ush)(z->dosflag ? (dosify ? 20 : /* Made under MSDOS by PKZIP 2.0 */ 738 (0 + Z_MAJORVER * 10 + Z_MINORVER)) 739 : OS_CODE + Z_MAJORVER * 10 + Z_MINORVER); 740 /* For a plain old (8+3) FAT file system, we cheat and pretend that the file 741 * was not made on OS2/WIN32 but under DOS. unzip is confused otherwise. 742 */ 743# endif 744#else /* !(OS2 || WIN32) */ 745 z->vem = (ush)(dosify ? 20 : OS_CODE + Z_MAJORVER * 10 + Z_MINORVER); 746#endif /* ?(OS2 || WIN32) */ 747 748 z->ver = (ush)(m == STORE ? 10 : 20); /* Need PKUNZIP 2.0 except for store */ 749#ifdef BZIP2_SUPPORT 750 if (method == BZIP2) 751 z->ver = (ush)(m == STORE ? 10 : 46); 752#endif 753 z->crc = 0; /* to be updated later */ 754 /* Assume first that we will need an extended local header: */ 755 if (isdir) 756 /* If dir then q = 0 and extended header not needed */ 757 z->flg = 0; 758 else 759 z->flg = 8; /* to be updated later */ 760#if CRYPT 761 if (!isdir && key != NULL) { 762 z->flg |= 1; 763 /* Since we do not yet know the crc here, we pretend that the crc 764 * is the modification time: 765 */ 766 z->crc = z->tim << 16; 767 /* More than pretend. File is encrypted using crypt header with that. */ 768 } 769#endif /* CRYPT */ 770 z->lflg = z->flg; 771 z->how = (ush)m; /* may be changed later */ 772 z->siz = (zoff_t)(m == STORE && q >= 0 ? q : 0); /* will be changed later */ 773 z->len = (zoff_t)(q != -1L ? q : 0); /* may be changed later */ 774 if (z->att == (ush)UNKNOWN) { 775 z->att = BINARY; /* set sensible value in header */ 776 set_type = 1; 777 } 778 /* Attributes from filetime(), flag bits from set_extra_field(): */ 779#if defined(DOS) || defined(OS2) || defined(WIN32) 780 z->atx = z->dosflag ? a & 0xff : a | (z->atx & 0x0000ff00); 781#else 782 z->atx = dosify ? a & 0xff : a | (z->atx & 0x0000ff00); 783#endif /* DOS || OS2 || WIN32 */ 784 785 if ((r = putlocal(z, PUTLOCAL_WRITE)) != ZE_OK) { 786 if (ifile != fbad) 787 zclose(ifile); 788 return r; 789 } 790 791 /* now get split information set by bfwrite() */ 792 z->off = current_local_offset; 793 794 /* disk local header was written to */ 795 z->dsk = current_local_disk; 796 797 tempzn += 4 + LOCHEAD + z->nam + z->ext; 798 799 800#if CRYPT 801 if (!isdir && key != NULL) { 802 crypthead(key, z->crc); 803 z->siz += RAND_HEAD_LEN; /* to be updated later */ 804 tempzn += RAND_HEAD_LEN; 805 } 806#endif /* CRYPT */ 807 if (ferror(y)) { 808 if (ifile != fbad) 809 zclose(ifile); 810 ZIPERR(ZE_WRITE, "unexpected error on zip file"); 811 } 812 813 last_o = o; 814 o = zftello(y); /* for debugging only, ftell can fail on pipes */ 815 if (ferror(y)) 816 clearerr(y); 817 818 if (o != -1 && last_o > o) { 819 fprintf(mesg, "last %s o %s\n", zip_fzofft(last_o, NULL, NULL), 820 zip_fzofft(o, NULL, NULL)); 821 ZIPERR(ZE_BIG, "seek wrap - zip file too big to write"); 822 } 823 824 /* Write stored or deflated file to zip file */ 825 isize = 0L; 826 crc = CRCVAL_INITIAL; 827 828 if (isdir) { 829 /* nothing to write */ 830 } 831 else if (m != STORE) { 832 if (set_type) z->att = (ush)UNKNOWN; 833 /* ... is finally set in file compression routine */ 834#ifdef BZIP2_SUPPORT 835 if (m == BZIP2) { 836 s = bzfilecompress(z, &m); 837 } 838 else 839#endif /* BZIP2_SUPPORT */ 840 { 841 s = filecompress(z, &m); 842 } 843#ifndef PGP 844 if (z->att == (ush)BINARY && translate_eol && file_binary) { 845 if (translate_eol == 1) 846 zipwarn("has binary so -l ignored", ""); 847 else 848 zipwarn("has binary so -ll ignored", ""); 849 } 850 else if (z->att == (ush)BINARY && translate_eol) { 851 if (translate_eol == 1) 852 zipwarn("-l used on binary file - corrupted?", ""); 853 else 854 zipwarn("-ll used on binary file - corrupted?", ""); 855 } 856#endif 857 } 858 else 859 { 860 if ((b = malloc(SBSZ)) == NULL) 861 return ZE_MEM; 862 863 if (l) { 864 k = rdsymlnk(z->name, b, SBSZ); 865/* 866 * compute crc first because zfwrite will alter the buffer b points to !! 867 */ 868 crc = crc32(crc, (uch *) b, k); 869 if (zfwrite(b, 1, k) != k) 870 { 871 free((zvoid *)b); 872 return ZE_TEMP; 873 } 874 isize = k; 875 876#ifdef MINIX 877 q = k; 878#endif /* MINIX */ 879 } 880 else 881 { 882 while ((k = file_read(b, SBSZ)) > 0 && k != (extent) EOF) 883 { 884 if (zfwrite(b, 1, k) != k) 885 { 886 if (ifile != fbad) 887 zclose(ifile); 888 free((zvoid *)b); 889 return ZE_TEMP; 890 } 891 if (!display_globaldots) { 892 if (dot_size > 0) { 893 /* initial space */ 894 if (noisy && dot_count == -1) { 895#ifndef WINDLL 896 putc(' ', mesg); 897 fflush(mesg); 898#else 899 fprintf(stdout,"%c",' '); 900#endif 901 dot_count++; 902 } 903 dot_count++; 904 if (dot_size <= (dot_count + 1) * SBSZ) dot_count = 0; 905 } 906 if ((verbose || noisy) && dot_size && !dot_count) { 907#ifndef WINDLL 908 putc('.', mesg); 909 fflush(mesg); 910#else 911 fprintf(stdout,"%c",'.'); 912#endif 913 mesg_line_started = 1; 914 } 915 } 916 } 917 } 918 free((zvoid *)b); 919 s = isize; 920 } 921 if (ifile != fbad && zerr(ifile)) { 922 perror("\nzip warning"); 923 if (logfile) 924 fprintf(logfile, "\nzip warning: %s\n", strerror(errno)); 925 zipwarn("could not read input file: ", z->oname); 926 } 927 if (ifile != fbad) 928 zclose(ifile); 929#ifdef MMAP 930 if (remain != (ulg)-1L) { 931 munmap((caddr_t) window, window_size); 932 window = NULL; 933 } 934#endif /*MMAP */ 935 936 tempzn += s; 937 p = tempzn; /* save for future fseek() */ 938 939#if (!defined(MSDOS) || defined(OS2)) 940#if !defined(VMS) && !defined(CMS_MVS) && !defined(__mpexl) 941 /* Check input size (but not in VMS -- variable record lengths mess it up) 942 * and not on MSDOS -- diet in TSR mode reports an incorrect file size) 943 */ 944#ifndef TANDEM /* Tandem EOF does not match byte count unless Unstructured */ 945 if (!translate_eol && q != -1L && isize != q) 946 { 947 Trace((mesg, " i=%lu, q=%lu ", isize, q)); 948 zipwarn(" file size changed while zipping ", z->name); 949 } 950#endif /* !TANDEM */ 951#endif /* !VMS && !CMS_MVS && !__mpexl */ 952#endif /* (!MSDOS || OS2) */ 953 954 if (isdir) 955 { 956 /* A directory */ 957 z->siz = 0; 958 z->len = 0; 959 z->how = STORE; 960 z->ver = 10; 961 /* never encrypt directory so don't need extended local header */ 962 z->flg &= ~8; 963 z->lflg &= ~8; 964 } 965 else 966 { 967 /* Try to rewrite the local header with correct information */ 968 z->crc = crc; 969 z->siz = s; 970#if CRYPT 971 if (!isdir && key != NULL) 972 z->siz += RAND_HEAD_LEN; 973#endif /* CRYPT */ 974 z->len = isize; 975 /* if can seek back to local header */ 976#ifdef BROKEN_FSEEK 977 if (use_descriptors || !fseekable(y) || zfseeko(y, z->off, SEEK_SET)) 978#else 979 if (use_descriptors || zfseeko(y, z->off, SEEK_SET)) 980#endif 981 { 982 if (z->how != (ush) m) 983 error("can't rewrite method"); 984 if (m == STORE && q < 0) 985 ZIPERR(ZE_PARMS, "zip -0 not supported for I/O on pipes or devices"); 986 if ((r = putextended(z)) != ZE_OK) 987 return r; 988 /* if Zip64 and not seekable then Zip64 data descriptor */ 989#ifdef ZIP64_SUPPORT 990 tempzn += (zip64_entry ? 24L : 16L); 991#else 992 tempzn += 16L; 993#endif 994 z->flg = z->lflg; /* if z->flg modified by deflate */ 995 } else { 996 /* ftell() not as useful across splits */ 997 if (bytes_this_entry != (uzoff_t)(key ? s + 12 : s)) { 998 fprintf(mesg, " s=%s, actual=%s ", 999 zip_fzofft(s, NULL, NULL), zip_fzofft(bytes_this_entry, NULL, NULL)); 1000 error("incorrect compressed size"); 1001 } 1002#if 0 1003 /* seek ok, ftell() should work, check compressed size */ 1004# if !defined(VMS) && !defined(CMS_MVS) 1005 if (p - o != s) { 1006 fprintf(mesg, " s=%s, actual=%s ", 1007 zip_fzofft(s, NULL, NULL), zip_fzofft(p-o, NULL, NULL)); 1008 error("incorrect compressed size"); 1009 } 1010# endif /* !VMS && !CMS_MVS */ 1011#endif /* 0 */ 1012 z->how = (ush)m; 1013 switch (m) 1014 { 1015 case STORE: 1016 z->ver = 10; break; 1017 /* Need PKUNZIP 2.0 for DEFLATE */ 1018 case DEFLATE: 1019 z->ver = 20; break; 1020#ifdef BZIP2_SUPPORT 1021 case BZIP2: 1022 z->ver = 46; break; 1023#endif 1024 } 1025 /* 1026 * The encryption header needs the crc, but we don't have it 1027 * for a new file. The file time is used instead and the encryption 1028 * header then used to encrypt the data. The AppNote standard only 1029 * can be applied to a file that the crc is known, so that means 1030 * either an existing entry in an archive or get the crc before 1031 * creating the encryption header and then encrypt the data. 1032 */ 1033 if ((z->flg & 1) == 0) { 1034 /* not encrypting so don't need extended local header */ 1035 z->flg &= ~8; 1036 } 1037 /* deflate may have set compression level bit markers in z->flg, 1038 and we can't think of any reason central and local flags should 1039 be different. */ 1040 z->lflg = z->flg; 1041 1042 /* If not using descriptors, back up and rewrite local header. */ 1043 if (split_method == 1 && current_local_file != y) { 1044 if (zfseeko(current_local_file, z->off, SEEK_SET)) 1045 return ZE_READ; 1046 } 1047 1048 /* if local header in another split, putlocal will close it */ 1049 if ((r = putlocal(z, PUTLOCAL_REWRITE)) != ZE_OK) 1050 return r; 1051 1052 if (zfseeko(y, bytes_this_split, SEEK_SET)) 1053 return ZE_READ; 1054 1055 if ((z->flg & 1) != 0) { 1056 /* encrypted file, extended header still required */ 1057 if ((r = putextended(z)) != ZE_OK) 1058 return r; 1059#ifdef ZIP64_SUPPORT 1060 if (zip64_entry) 1061 tempzn += 24L; 1062 else 1063 tempzn += 16L; 1064#else 1065 tempzn += 16L; 1066#endif 1067 } 1068 } 1069 } /* isdir */ 1070 /* Free the local extra field which is no longer needed */ 1071 if (z->ext) { 1072 if (z->extra != z->cextra) { 1073 free((zvoid *)(z->extra)); 1074 z->extra = NULL; 1075 } 1076 z->ext = 0; 1077 } 1078 1079 /* Display statistics */ 1080 if (noisy) 1081 { 1082 if (verbose) { 1083 fprintf( mesg, "\t(in=%s) (out=%s)", 1084 zip_fzofft(isize, NULL, "u"), zip_fzofft(s, NULL, "u")); 1085 } 1086#ifdef BZIP2_SUPPORT 1087 if (m == BZIP2) 1088 fprintf(mesg, " (bzipped %d%%)\n", percent(isize, s)); 1089 else 1090#endif 1091 if (m == DEFLATE) 1092 fprintf(mesg, " (deflated %d%%)\n", percent(isize, s)); 1093 else 1094 fprintf(mesg, " (stored 0%%)\n"); 1095 mesg_line_started = 0; 1096 fflush(mesg); 1097 } 1098 if (logall) 1099 { 1100#ifdef BZIP2_SUPPORT 1101 if (m == BZIP2) 1102 fprintf(logfile, " (bzipped %d%%)\n", percent(isize, s)); 1103 else 1104#endif 1105 if (m == DEFLATE) 1106 fprintf(logfile, " (deflated %d%%)\n", percent(isize, s)); 1107 else 1108 fprintf(logfile, " (stored 0%%)\n"); 1109 logfile_line_started = 0; 1110 fflush(logfile); 1111 } 1112 1113#ifdef WINDLL 1114# ifdef ZIP64_SUPPORT 1115 /* The DLL api has been updated and uses a different 1116 interface. 7/24/04 EG */ 1117 if (lpZipUserFunctions->ServiceApplication64 != NULL) 1118 { 1119 if ((*lpZipUserFunctions->ServiceApplication64)(z->zname, isize)) 1120 ZIPERR(ZE_ABORT, "User terminated operation"); 1121 } 1122 else 1123 { 1124 filesize64 = isize; 1125 low = (unsigned long)(filesize64 & 0x00000000FFFFFFFF); 1126 high = (unsigned long)((filesize64 >> 32) & 0x00000000FFFFFFFF); 1127 if (lpZipUserFunctions->ServiceApplication64_No_Int64 != NULL) { 1128 if ((*lpZipUserFunctions->ServiceApplication64_No_Int64)(z->zname, low, high)) 1129 ZIPERR(ZE_ABORT, "User terminated operation"); 1130 } 1131 } 1132# else 1133 if (lpZipUserFunctions->ServiceApplication != NULL) 1134 { 1135 if ((*lpZipUserFunctions->ServiceApplication)(z->zname, isize)) 1136 { 1137 ZIPERR(ZE_ABORT, "User terminated operation"); 1138 } 1139 } 1140# endif 1141#endif 1142 1143 return ZE_OK; 1144} 1145 1146 1147 1148 1149local unsigned file_read(buf, size) 1150 char *buf; 1151 unsigned size; 1152/* Read a new buffer from the current input file, perform end-of-line 1153 * translation, and update the crc and input file size. 1154 * IN assertion: size >= 2 (for end-of-line translation) 1155 */ 1156{ 1157 unsigned len; 1158 char *b; 1159 zoff_t isize_prev; /* Previous isize. Used for overflow check. */ 1160 1161#if defined(MMAP) || defined(BIG_MEM) 1162 if (remain == 0L) { 1163 return 0; 1164 } else if (remain != (ulg)-1L) { 1165 /* The window data is already in place. We still compute the crc 1166 * by 32K blocks instead of once on whole file to keep a certain 1167 * locality of reference. 1168 */ 1169 Assert(buf == (char*)window + isize, "are you lost?"); 1170 if ((ulg)size > remain) size = (unsigned)remain; 1171 if (size > WSIZE) size = WSIZE; /* don't touch all pages at once */ 1172 remain -= (ulg)size; 1173 len = size; 1174 } else 1175#endif /* MMAP || BIG_MEM */ 1176 if (translate_eol == 0) { 1177 len = zread(ifile, buf, size); 1178 if (len == (unsigned)EOF || len == 0) return len; 1179#ifdef OS390 1180 b = buf; 1181 if (aflag == ASCII) { 1182 while (*b != '\0') { 1183 *b = (char)ascii[(uch)*b]; 1184 b++; 1185 } 1186 } 1187#endif 1188 } else if (translate_eol == 1) { 1189 /* translate_eol == 1 */ 1190 /* Transform LF to CR LF */ 1191 size >>= 1; 1192 b = buf+size; 1193 size = len = zread(ifile, b, size); 1194 if (len == (unsigned)EOF || len == 0) return len; 1195 1196 /* check buf for binary - 12/16/04 */ 1197 if (file_binary == -1) { 1198 /* first read */ 1199 file_binary = is_text_buf(b, size) ? 0 : 1; 1200 } 1201 1202 if (file_binary != 1) { 1203#ifdef EBCDIC 1204 if (aflag == ASCII) 1205 { 1206 do { 1207 char c; 1208 1209 if ((c = *b++) == '\n') { 1210 *buf++ = CR; *buf++ = LF; len++; 1211 } else { 1212 *buf++ = (char)ascii[(uch)c]; 1213 } 1214 } while (--size != 0); 1215 } 1216 else 1217#endif /* EBCDIC */ 1218 { 1219 do { 1220 if ((*buf++ = *b++) == '\n') *(buf-1) = CR, *buf++ = LF, len++; 1221 } while (--size != 0); 1222 } 1223 buf -= len; 1224 } else { /* do not translate binary */ 1225 memcpy(buf, b, size); 1226 } 1227 1228 } else { 1229 /* translate_eol == 2 */ 1230 /* Transform CR LF to LF and suppress final ^Z */ 1231 b = buf; 1232 size = len = zread(ifile, buf, size-1); 1233 if (len == (unsigned)EOF || len == 0) return len; 1234 1235 /* check buf for binary - 12/16/04 */ 1236 if (file_binary == -1) { 1237 /* first read */ 1238 file_binary = is_text_buf(b, size) ? 0 : 1; 1239 } 1240 1241 if (file_binary != 1) { 1242 buf[len] = '\n'; /* I should check if next char is really a \n */ 1243#ifdef EBCDIC 1244 if (aflag == ASCII) 1245 { 1246 do { 1247 char c; 1248 1249 if ((c = *b++) == '\r' && *b == '\n') { 1250 len--; 1251 } else { 1252 *buf++ = (char)(c == '\n' ? LF : ascii[(uch)c]); 1253 } 1254 } while (--size != 0); 1255 } 1256 else 1257#endif /* EBCDIC */ 1258 { 1259 do { 1260 if (( *buf++ = *b++) == CR && *b == LF) buf--, len--; 1261 } while (--size != 0); 1262 } 1263 if (len == 0) { 1264 zread(ifile, buf, 1); len = 1; /* keep single \r if EOF */ 1265#ifdef EBCDIC 1266 if (aflag == ASCII) { 1267 *buf = (char)(*buf == '\n' ? LF : ascii[(uch)(*buf)]); 1268 } 1269#endif 1270 } else { 1271 buf -= len; 1272 if (buf[len-1] == CTRLZ) len--; /* suppress final ^Z */ 1273 } 1274 } 1275 } 1276 crc = crc32(crc, (uch *) buf, len); 1277 /* 2005-05-23 SMS. 1278 Increment file size. A small-file program reading a large file may 1279 cause isize to overflow, so complain (and abort) if it goes 1280 negative or wraps around. Awful things happen later otherwise. 1281 */ 1282 isize_prev = isize; 1283 isize += (ulg)len; 1284 if (isize < isize_prev) { 1285 ZIPERR(ZE_BIG, "overflow in byte count"); 1286 } 1287 return len; 1288} 1289 1290 1291#ifdef USE_ZLIB 1292 1293local int zl_deflate_init(pack_level) 1294 int pack_level; 1295{ 1296 unsigned i; 1297 int windowBits; 1298 int err = Z_OK; 1299 int zp_err = ZE_OK; 1300 1301 if (zlib_version[0] != ZLIB_VERSION[0]) { 1302 sprintf(errbuf, "incompatible zlib version (expected %s, found %s)", 1303 ZLIB_VERSION, zlib_version); 1304 zp_err = ZE_LOGIC; 1305 } else if (strcmp(zlib_version, ZLIB_VERSION) != 0) { 1306 fprintf(mesg, 1307 "\twarning: different zlib version (expected %s, using %s)\n", 1308 ZLIB_VERSION, zlib_version); 1309 } 1310 1311 /* windowBits = log2(WSIZE) */ 1312 for (i = ((unsigned)WSIZE), windowBits = 0; i != 1; i >>= 1, ++windowBits); 1313 1314 zstrm.zalloc = (alloc_func)Z_NULL; 1315 zstrm.zfree = (free_func)Z_NULL; 1316 1317 Trace((stderr, "initializing deflate()\n")); 1318 err = deflateInit2(&zstrm, pack_level, Z_DEFLATED, -windowBits, 8, 0); 1319 1320 if (err == Z_MEM_ERROR) { 1321 sprintf(errbuf, "cannot initialize zlib deflate"); 1322 zp_err = ZE_MEM; 1323 } else if (err != Z_OK) { 1324 sprintf(errbuf, "zlib deflateInit failure (%d)", err); 1325 zp_err = ZE_LOGIC; 1326 } 1327 1328 deflInit = TRUE; 1329 return zp_err; 1330} 1331 1332 1333void zl_deflate_free() 1334{ 1335 int err; 1336 1337 if (f_obuf != NULL) { 1338 free(f_obuf); 1339 f_obuf = NULL; 1340 } 1341 if (f_ibuf != NULL) { 1342 free(f_ibuf); 1343 f_ibuf = NULL; 1344 } 1345 if (deflInit) { 1346 err = deflateEnd(&zstrm); 1347 if (err != Z_OK && err !=Z_DATA_ERROR) { 1348 ziperr(ZE_LOGIC, "zlib deflateEnd failed"); 1349 } 1350 deflInit = FALSE; 1351 } 1352} 1353 1354#else /* !USE_ZLIB */ 1355 1356# ifdef ZP_NEED_MEMCOMPR 1357/* =========================================================================== 1358 * In-memory read function. As opposed to file_read(), this function 1359 * does not perform end-of-line translation, and does not update the 1360 * crc and input size. 1361 * Note that the size of the entire input buffer is an unsigned long, 1362 * but the size used in mem_read() is only an unsigned int. This makes a 1363 * difference on 16 bit machines. mem_read() may be called several 1364 * times for an in-memory compression. 1365 */ 1366local unsigned mem_read(b, bsize) 1367 char *b; 1368 unsigned bsize; 1369{ 1370 if (in_offset < in_size) { 1371 ulg block_size = in_size - in_offset; 1372 if (block_size > (ulg)bsize) block_size = (ulg)bsize; 1373 memcpy(b, in_buf + in_offset, (unsigned)block_size); 1374 in_offset += (unsigned)block_size; 1375 return (unsigned)block_size; 1376 } else { 1377 return 0; /* end of input */ 1378 } 1379} 1380# endif /* ZP_NEED_MEMCOMPR */ 1381 1382 1383/* =========================================================================== 1384 * Flush the current output buffer. 1385 */ 1386void flush_outbuf(o_buf, o_idx) 1387 char *o_buf; 1388 unsigned *o_idx; 1389{ 1390 if (y == NULL) { 1391 error("output buffer too small for in-memory compression"); 1392 } 1393 /* Encrypt and write the output buffer: */ 1394 if (*o_idx != 0) { 1395 zfwrite(o_buf, 1, (extent)*o_idx); 1396 if (ferror(y)) ziperr(ZE_WRITE, "write error on zip file"); 1397 } 1398 *o_idx = 0; 1399} 1400 1401/* =========================================================================== 1402 * Return true if the zip file can be seeked. This is used to check if 1403 * the local header can be re-rewritten. This function always returns 1404 * true for in-memory compression. 1405 * IN assertion: the local header has already been written (ftell() > 0). 1406 */ 1407int seekable() 1408{ 1409 return fseekable(y); 1410} 1411#endif /* ?USE_ZLIB */ 1412 1413 1414/* =========================================================================== 1415 * Compression to archive file. 1416 */ 1417local zoff_t filecompress(z_entry, cmpr_method) 1418 struct zlist far *z_entry; 1419 int *cmpr_method; 1420{ 1421#ifdef USE_ZLIB 1422 int err = Z_OK; 1423 unsigned mrk_cnt = 1; 1424 int maybe_stored = FALSE; 1425 ulg cmpr_size; 1426#if defined(MMAP) || defined(BIG_MEM) 1427 unsigned ibuf_sz = (unsigned)SBSZ; 1428#else 1429# define ibuf_sz ((unsigned)SBSZ) 1430#endif 1431#ifndef OBUF_SZ 1432# define OBUF_SZ ZBSZ 1433#endif 1434 unsigned u; 1435 1436#if defined(MMAP) || defined(BIG_MEM) 1437 if (remain == (ulg)-1L && f_ibuf == NULL) 1438#else /* !(MMAP || BIG_MEM */ 1439 if (f_ibuf == NULL) 1440#endif /* MMAP || BIG_MEM */ 1441 f_ibuf = (char *)malloc(SBSZ); 1442 if (f_obuf == NULL) 1443 f_obuf = (char *)malloc(OBUF_SZ); 1444#if defined(MMAP) || defined(BIG_MEM) 1445 if ((remain == (ulg)-1L && f_ibuf == NULL) || f_obuf == NULL) 1446#else /* !(MMAP || BIG_MEM */ 1447 if (f_ibuf == NULL || f_obuf == NULL) 1448#endif /* MMAP || BIG_MEM */ 1449 ziperr(ZE_MEM, "allocating zlib file-I/O buffers"); 1450 1451 if (!deflInit) { 1452 err = zl_deflate_init(level); 1453 if (err != ZE_OK) 1454 ziperr(err, errbuf); 1455 } 1456 1457 if (level <= 2) { 1458 z_entry->flg |= 4; 1459 } else if (level >= 8) { 1460 z_entry->flg |= 2; 1461 } 1462#if defined(MMAP) || defined(BIG_MEM) 1463 if (remain != (ulg)-1L) { 1464 zstrm.next_in = (Bytef *)window; 1465 ibuf_sz = (unsigned)WSIZE; 1466 } else 1467#endif /* MMAP || BIG_MEM */ 1468 { 1469 zstrm.next_in = (Bytef *)f_ibuf; 1470 } 1471 zstrm.avail_in = file_read(zstrm.next_in, ibuf_sz); 1472 if (zstrm.avail_in < ibuf_sz) { 1473 unsigned more = file_read(zstrm.next_in + zstrm.avail_in, 1474 (ibuf_sz - zstrm.avail_in)); 1475 if (more == EOF || more == 0) { 1476 maybe_stored = TRUE; 1477 } else { 1478 zstrm.avail_in += more; 1479 } 1480 } 1481 zstrm.next_out = (Bytef *)f_obuf; 1482 zstrm.avail_out = OBUF_SZ; 1483 1484 if (!maybe_stored) while (zstrm.avail_in != 0 && zstrm.avail_in != EOF) { 1485 err = deflate(&zstrm, Z_NO_FLUSH); 1486 if (err != Z_OK && err != Z_STREAM_END) { 1487 sprintf(errbuf, "unexpected zlib deflate error %d", err); 1488 ziperr(ZE_LOGIC, errbuf); 1489 } 1490 if (zstrm.avail_out == 0) { 1491 if (zfwrite(f_obuf, 1, OBUF_SZ) != OBUF_SZ) { 1492 ziperr(ZE_TEMP, "error writing to zipfile"); 1493 } 1494 zstrm.next_out = (Bytef *)f_obuf; 1495 zstrm.avail_out = OBUF_SZ; 1496 } 1497 if (zstrm.avail_in == 0) { 1498 if (verbose || noisy) 1499 while((unsigned)(zstrm.total_in / (uLong)WSIZE) > mrk_cnt) { 1500 mrk_cnt++; 1501 if (!display_globaldots) { 1502 if (dot_size > 0) { 1503 /* initial space */ 1504 if (noisy && dot_count == -1) { 1505#ifndef WINDLL 1506 putc(' ', mesg); 1507 fflush(mesg); 1508#else 1509 fprintf(stdout,"%c",' '); 1510#endif 1511 dot_count++; 1512 } 1513 dot_count++; 1514 if (dot_size <= (dot_count + 1) * WSIZE) dot_count = 0; 1515 } 1516 if (noisy && dot_size && !dot_count) { 1517#ifndef WINDLL 1518 putc('.', mesg); 1519 fflush(mesg); 1520#else 1521 fprintf(stdout,"%c",'.'); 1522#endif 1523 mesg_line_started = 1; 1524 } 1525 } 1526 } 1527#if defined(MMAP) || defined(BIG_MEM) 1528 if (remain == (ulg)-1L) 1529 zstrm.next_in = (Bytef *)f_ibuf; 1530#else 1531 zstrm.next_in = (Bytef *)f_ibuf; 1532#endif 1533 zstrm.avail_in = file_read(zstrm.next_in, ibuf_sz); 1534 } 1535 } 1536 1537 do { 1538 err = deflate(&zstrm, Z_FINISH); 1539 if (maybe_stored) { 1540 if (err == Z_STREAM_END && zstrm.total_out >= zstrm.total_in && 1541 fseekable(zipfile)) { 1542 /* deflation does not reduce size, switch to STORE method */ 1543 unsigned len_out = (unsigned)zstrm.total_in; 1544 if (zfwrite(f_ibuf, 1, len_out) != len_out) { 1545 ziperr(ZE_TEMP, "error writing to zipfile"); 1546 } 1547 zstrm.total_out = (uLong)len_out; 1548 *cmpr_method = STORE; 1549 break; 1550 } else { 1551 maybe_stored = FALSE; 1552 } 1553 } 1554 if (zstrm.avail_out < OBUF_SZ) { 1555 unsigned len_out = OBUF_SZ - zstrm.avail_out; 1556 if (zfwrite(f_obuf, 1, len_out) != len_out) { 1557 ziperr(ZE_TEMP, "error writing to zipfile"); 1558 } 1559 zstrm.next_out = (Bytef *)f_obuf; 1560 zstrm.avail_out = OBUF_SZ; 1561 } 1562 } while (err == Z_OK); 1563 1564 if (err != Z_STREAM_END) { 1565 sprintf(errbuf, "unexpected zlib deflate error %d", err); 1566 ziperr(ZE_LOGIC, errbuf); 1567 } 1568 1569 if (z_entry->att == (ush)UNKNOWN) 1570 z_entry->att = (ush)(zstrm.data_type == Z_ASCII ? ASCII : BINARY); 1571 cmpr_size = (ulg)zstrm.total_out; 1572 1573 if ((err = deflateReset(&zstrm)) != Z_OK) 1574 ziperr(ZE_LOGIC, "zlib deflateReset failed"); 1575 return cmpr_size; 1576#else /* !USE_ZLIB */ 1577 1578 /* Set the defaults for file compression. */ 1579 read_buf = file_read; 1580 1581 /* Initialize deflate's internals and execute file compression. */ 1582 bi_init(file_outbuf, sizeof(file_outbuf), TRUE); 1583 ct_init(&z_entry->att, cmpr_method); 1584 lm_init(level, &z_entry->flg); 1585 return deflate(); 1586#endif /* ?USE_ZLIB */ 1587} 1588 1589#ifdef ZP_NEED_MEMCOMPR 1590/* =========================================================================== 1591 * In-memory compression. This version can be used only if the entire input 1592 * fits in one memory buffer. The compression is then done in a single 1593 * call of memcompress(). (An extension to allow repeated calls would be 1594 * possible but is not needed here.) 1595 * The first two bytes of the compressed output are set to a short with the 1596 * method used (DEFLATE or STORE). The following four bytes contain the CRC. 1597 * The values are stored in little-endian order on all machines. 1598 * This function returns the byte size of the compressed output, including 1599 * the first six bytes (method and crc). 1600 */ 1601 1602ulg memcompress(tgt, tgtsize, src, srcsize) 1603 char *tgt, *src; /* target and source buffers */ 1604 ulg tgtsize, srcsize; /* target and source sizes */ 1605{ 1606 ulg crc; 1607 unsigned out_total; 1608 int method = DEFLATE; 1609#ifdef USE_ZLIB 1610 int err = Z_OK; 1611#else 1612 ush att = (ush)UNKNOWN; 1613 ush flags = 0; 1614#endif 1615 1616 if (tgtsize <= (ulg)6L) error("target buffer too small"); 1617 out_total = 2 + 4; 1618 1619#ifdef USE_ZLIB 1620 if (!deflInit) { 1621 err = zl_deflate_init(level); 1622 if (err != ZE_OK) 1623 ziperr(err, errbuf); 1624 } 1625 1626 zstrm.next_in = (Bytef *)src; 1627 zstrm.avail_in = (uInt)srcsize; 1628 zstrm.next_out = (Bytef *)(tgt + out_total); 1629 zstrm.avail_out = (uInt)tgtsize - (uInt)out_total; 1630 1631 err = deflate(&zstrm, Z_FINISH); 1632 if (err != Z_STREAM_END) 1633 error("output buffer too small for in-memory compression"); 1634 out_total += (unsigned)zstrm.total_out; 1635 1636 if ((err = deflateReset(&zstrm)) != Z_OK) 1637 error("zlib deflateReset failed"); 1638#else /* !USE_ZLIB */ 1639 read_buf = mem_read; 1640 in_buf = src; 1641 in_size = (unsigned)srcsize; 1642 in_offset = 0; 1643 window_size = 0L; 1644 1645 bi_init(tgt + (2 + 4), (unsigned)(tgtsize - (2 + 4)), FALSE); 1646 ct_init(&att, &method); 1647 lm_init((level != 0 ? level : 1), &flags); 1648 out_total += (unsigned)deflate(); 1649 window_size = 0L; /* was updated by lm_init() */ 1650#endif /* ?USE_ZLIB */ 1651 1652 crc = CRCVAL_INITIAL; 1653 crc = crc32(crc, (uch *)src, (extent)srcsize); 1654 1655 /* For portability, force little-endian order on all machines: */ 1656 tgt[0] = (char)(method & 0xff); 1657 tgt[1] = (char)((method >> 8) & 0xff); 1658 tgt[2] = (char)(crc & 0xff); 1659 tgt[3] = (char)((crc >> 8) & 0xff); 1660 tgt[4] = (char)((crc >> 16) & 0xff); 1661 tgt[5] = (char)((crc >> 24) & 0xff); 1662 1663 return (ulg)out_total; 1664} 1665#endif /* ZP_NEED_MEMCOMPR */ 1666 1667#ifdef BZIP2_SUPPORT 1668 1669local int bz_compress_init(pack_level) 1670int pack_level; 1671{ 1672 int err = BZ_OK; 1673 int zp_err = ZE_OK; 1674 const char *bzlibVer; 1675 1676 bzlibVer = BZ2_bzlibVersion(); 1677 1678 /* $TODO - Check BZIP2 LIB version? */ 1679 1680 bstrm.bzalloc = NULL; 1681 bstrm.bzfree = NULL; 1682 bstrm.opaque = NULL; 1683 1684 Trace((stderr, "initializing bzlib compress()\n")); 1685 err = BZ2_bzCompressInit(&bstrm, pack_level, 0, 30); 1686 1687 if (err == BZ_MEM_ERROR) { 1688 sprintf(errbuf, "cannot initialize bzlib compress"); 1689 zp_err = ZE_MEM; 1690 } else if (err != BZ_OK) { 1691 sprintf(errbuf, "bzlib bzCompressInit failure (%d)", err); 1692 zp_err = ZE_LOGIC; 1693 } 1694 1695 bzipInit = TRUE; 1696 return zp_err; 1697} 1698 1699void bz_compress_free() 1700{ 1701 int err; 1702 1703 if (f_obuf != NULL) { 1704 free(f_obuf); 1705 f_obuf = NULL; 1706 } 1707 if (f_ibuf != NULL) { 1708 free(f_ibuf); 1709 f_ibuf = NULL; 1710 } 1711 if (bzipInit) { 1712 err = BZ2_bzCompressEnd(&bstrm); 1713 if (err != BZ_OK && err != BZ_DATA_ERROR) { 1714 ziperr(ZE_LOGIC, "bzlib bzCompressEnd failed"); 1715 } 1716 bzipInit = FALSE; 1717 } 1718} 1719 1720/* =========================================================================== 1721 * BZIP2 Compression to archive file. 1722 */ 1723 1724local zoff_t bzfilecompress(z_entry, cmpr_method) 1725struct zlist far *z_entry; 1726int *cmpr_method; 1727{ 1728 FILE *zipfile = y; 1729 1730 int err = BZ_OK; 1731 unsigned mrk_cnt = 1; 1732 int maybe_stored = FALSE; 1733 zoff_t cmpr_size; 1734#if defined(MMAP) || defined(BIG_MEM) 1735 unsigned ibuf_sz = (unsigned)SBSZ; 1736#else 1737# define ibuf_sz ((unsigned)SBSZ) 1738#endif 1739#ifndef OBUF_SZ 1740# define OBUF_SZ ZBSZ 1741#endif 1742 1743#if defined(MMAP) || defined(BIG_MEM) 1744 if (remain == (ulg)-1L && f_ibuf == NULL) 1745#else /* !(MMAP || BIG_MEM */ 1746 if (f_ibuf == NULL) 1747#endif /* MMAP || BIG_MEM */ 1748 f_ibuf = (char *)malloc(SBSZ); 1749 if (f_obuf == NULL) 1750 f_obuf = (char *)malloc(OBUF_SZ); 1751#if defined(MMAP) || defined(BIG_MEM) 1752 if ((remain == (ulg)-1L && f_ibuf == NULL) || f_obuf == NULL) 1753#else /* !(MMAP || BIG_MEM */ 1754 if (f_ibuf == NULL || f_obuf == NULL) 1755#endif /* MMAP || BIG_MEM */ 1756 ziperr(ZE_MEM, "allocating zlib/bzlib file-I/O buffers"); 1757 1758 if (!bzipInit) { 1759 err = bz_compress_init(level); 1760 if (err != ZE_OK) 1761 ziperr(err, errbuf); 1762 } 1763 1764#if defined(MMAP) || defined(BIG_MEM) 1765 if (remain != (ulg)-1L) { 1766 bstrm.next_in = (Bytef *)window; 1767 ibuf_sz = (unsigned)WSIZE; 1768 } else 1769#endif /* MMAP || BIG_MEM */ 1770 { 1771 bstrm.next_in = (char *)f_ibuf; 1772 } 1773 bstrm.avail_in = file_read(bstrm.next_in, ibuf_sz); 1774 if (file_binary_final == 0) { 1775 /* check for binary as library does not */ 1776 if (!is_text_buf(bstrm.next_in, ibuf_sz)) 1777 file_binary_final = 1; 1778 } 1779 if (bstrm.avail_in < ibuf_sz) { 1780 unsigned more = file_read(bstrm.next_in + bstrm.avail_in, 1781 (ibuf_sz - bstrm.avail_in)); 1782 if (more == (unsigned) EOF || more == 0) { 1783 maybe_stored = TRUE; 1784 } else { 1785 bstrm.avail_in += more; 1786 } 1787 } 1788 bstrm.next_out = (char *)f_obuf; 1789 bstrm.avail_out = OBUF_SZ; 1790 1791 if (!maybe_stored) { 1792 while (bstrm.avail_in != 0 && bstrm.avail_in != (unsigned) EOF) { 1793 err = BZ2_bzCompress(&bstrm, BZ_RUN); 1794 if (err != BZ_RUN_OK && err != BZ_STREAM_END) { 1795 sprintf(errbuf, "unexpected bzlib compress error %d", err); 1796 ziperr(ZE_LOGIC, errbuf); 1797 } 1798 if (bstrm.avail_out == 0) { 1799 if (zfwrite(f_obuf, 1, OBUF_SZ) != OBUF_SZ) { 1800 ziperr(ZE_TEMP, "error writing to zipfile"); 1801 } 1802 bstrm.next_out = (char *)f_obuf; 1803 bstrm.avail_out = OBUF_SZ; 1804 } 1805 /* $TODO what about high 32-bits of total-in??? */ 1806 if (bstrm.avail_in == 0) { 1807 if (verbose || noisy) 1808#ifdef LARGE_FILE_SUPPORT 1809 while((unsigned)((bstrm.total_in_lo32 1810 + (((zoff_t)bstrm.total_in_hi32) << 32)) 1811 / (zoff_t)(ulg)WSIZE) > mrk_cnt) { 1812#else 1813 while((unsigned)(bstrm.total_in_lo32 / (ulg)WSIZE) > mrk_cnt) { 1814#endif 1815 mrk_cnt++; 1816 if (!display_globaldots) { 1817 if (dot_size > 0) { 1818 /* initial space */ 1819 if (noisy && dot_count == -1) { 1820#ifndef WINDLL 1821 putc(' ', mesg); 1822 fflush(mesg); 1823#else 1824 fprintf(stdout,"%c",' '); 1825#endif 1826 dot_count++; 1827 } 1828 dot_count++; 1829 if (dot_size <= (dot_count + 1) * WSIZE) dot_count = 0; 1830 } 1831 if (noisy && dot_size && !dot_count) { 1832#ifndef WINDLL 1833 putc('.', mesg); 1834 fflush(mesg); 1835#else 1836 fprintf(stdout,"%c",'.'); 1837#endif 1838 mesg_line_started = 1; 1839 } 1840 } 1841 } 1842#if defined(MMAP) || defined(BIG_MEM) 1843 if (remain == (ulg)-1L) 1844 bstrm.next_in = (char *)f_ibuf; 1845#else 1846 bstrm.next_in = (char *)f_ibuf; 1847#endif 1848 bstrm.avail_in = file_read(bstrm.next_in, ibuf_sz); 1849 if (file_binary_final == 0) { 1850 /* check for binary as library does not */ 1851 if (!is_text_buf(bstrm.next_in, ibuf_sz)) 1852 file_binary_final = 1; 1853 } 1854 } 1855 } 1856 } 1857 1858 /* binary or text */ 1859 if (file_binary_final) 1860 /* found binary in file */ 1861 z_entry->att = (ush)BINARY; 1862 else 1863 /* text file */ 1864 z_entry->att = (ush)ASCII; 1865 1866 do { 1867 err = BZ2_bzCompress(&bstrm, BZ_FINISH); 1868 if (maybe_stored) { 1869 /* This code is only executed when the complete data stream fits 1870 into the input buffer (see above where maybe_stored gets set). 1871 So, it is safe to assume that total_in_hi32 (and total_out_hi32) 1872 are 0, because the input buffer size is well below the 32-bit 1873 limit. 1874 */ 1875 if (err == BZ_STREAM_END 1876 && bstrm.total_out_lo32 >= bstrm.total_in_lo32 1877 && fseekable(zipfile)) { 1878 /* BZIP2 compress does not reduce size, 1879 switch to STORE method */ 1880 unsigned len_out = (unsigned)bstrm.total_in_lo32; 1881 if (zfwrite(f_ibuf, 1, len_out) != len_out) { 1882 ziperr(ZE_TEMP, "error writing to zipfile"); 1883 } 1884 bstrm.total_out_lo32 = (ulg)len_out; 1885 *cmpr_method = STORE; 1886 break; 1887 } else { 1888 maybe_stored = FALSE; 1889 } 1890 } 1891 if (bstrm.avail_out < OBUF_SZ) { 1892 unsigned len_out = OBUF_SZ - bstrm.avail_out; 1893 if (zfwrite(f_obuf, 1, len_out) != len_out) { 1894 ziperr(ZE_TEMP, "error writing to zipfile"); 1895 } 1896 bstrm.next_out = (char *)f_obuf; 1897 bstrm.avail_out = OBUF_SZ; 1898 } 1899 } while (err == BZ_FINISH_OK); 1900 1901 if (err < BZ_OK) { 1902 sprintf(errbuf, "unexpected bzlib compress error %d", err); 1903 ziperr(ZE_LOGIC, errbuf); 1904 } 1905 1906 if (z_entry->att == (ush)UNKNOWN) 1907 z_entry->att = (ush)BINARY; 1908#ifdef LARGE_FILE_SUPPORT 1909 cmpr_size = (zoff_t)bstrm.total_out_lo32 1910 + (((zoff_t)bstrm.total_out_hi32) << 32); 1911#else 1912 cmpr_size = (zoff_t)bstrm.total_out_lo32; 1913#endif 1914 1915 if ((err = BZ2_bzCompressEnd(&bstrm)) != BZ_OK) 1916 ziperr(ZE_LOGIC, "zlib deflateReset failed"); 1917 bzipInit = FALSE; 1918 return cmpr_size; 1919} 1920 1921#endif /* BZIP2_SUPPORT */ 1922#endif /* !UTIL */ 1923