Annotation of coherent/b/bin/zip/zipup.c, revision 1.1

1.1     ! root        1: /*
        !             2: 
        !             3:  Copyright (C) 1990-1992 Mark Adler, Richard B. Wales, Jean-loup Gailly,
        !             4:  Kai Uwe Rommel and Igor Mandrichenko.
        !             5:  Permission is granted to any individual or institution to use, copy, or
        !             6:  redistribute this software so long as all of the original files are included
        !             7:  unmodified, that it is not sold for profit, and that this copyright notice
        !             8:  is retained.
        !             9: 
        !            10: */
        !            11: 
        !            12: /*
        !            13:  *  zipup.c by Mark Adler. Includes modifications by Jean-loup Gailly.
        !            14:  */
        !            15: 
        !            16: #define NOCPYRT         /* this is not a main module */
        !            17: #include <ctype.h>
        !            18: #include "zip.h"
        !            19: #include "revision.h"
        !            20: #ifdef OS2
        !            21: #  include "os2zip.h"
        !            22: #endif
        !            23: 
        !            24: /* Use the raw functions for MSDOS and Unix to save on buffer space.
        !            25:    They're not used for VMS since it doesn't work (raw is weird on VMS).
        !            26:    (This sort of stuff belongs in fileio.c, but oh well.) */
        !            27: #ifdef VMS
        !            28: #  define fhow "r"
        !            29: #  define fbad NULL
        !            30:    typedef void *ftype;
        !            31: #  define zopen(n,p)   (vms_native?vms_open(n)    :(ftype)fopen((n),(p)))
        !            32: #  define zread(f,b,n) (vms_native?vms_read(f,b,n):fread((b),1,(n),(FILE*)(f)))
        !            33: #  define zclose(f)    (vms_native?vms_close(f)   :fclose((FILE*)(f)))
        !            34: #  define zerr(f)      (vms_native?vms_error(f)   :ferror((FILE*)(f)))
        !            35: #  define zstdin stdin
        !            36:    ftype vms_open OF((char *));
        !            37:    int vms_read OF((ftype, char *, int));
        !            38:    int vms_close OF((ftype));
        !            39:    int vms_error OF((ftype));
        !            40: #else /* !VMS */
        !            41: #  if defined(MSDOS) && !defined(ATARI_ST)
        !            42: #    include <io.h>
        !            43: #    include <fcntl.h>
        !            44: #    define fhow (O_RDONLY|O_BINARY)
        !            45: #  else /* !MSDOS */
        !            46:      int open OF((char *, int));
        !            47:      int read OF((int, char *, int));
        !            48:      int close OF((int));
        !            49:      int lseek OF((int, long, int));
        !            50: #    define fhow 0
        !            51: #  endif /* ?MSDOS */
        !            52:    typedef int ftype;
        !            53: #  define fbad (-1)
        !            54: #  define zopen(n,p) open(n,p)
        !            55: #  define zread(f,b,n) read(f,b,n)
        !            56: #  define zclose(f) close(f)
        !            57: #  define zerr(f) (k==(extent)(-1L))
        !            58: #  define zstdin 0
        !            59: #endif /* ?VMS */
        !            60: 
        !            61: 
        !            62: /* Local data */
        !            63: 
        !            64: #ifndef UTIL
        !            65: local ulg crc;       /* crc on uncompressed file data */
        !            66: local ftype ifile;   /* file to compress */
        !            67: #endif
        !            68: ulg isize;           /* input file size. global only for debugging */    
        !            69: 
        !            70: /* Local functions */
        !            71: #if defined(PROTO) && !defined(UTIL)
        !            72:    local int suffixes(char *, char *);
        !            73: #endif
        !            74: 
        !            75: 
        !            76: /* Note: a zip "entry" includes a local header (which includes the file
        !            77:    name), an encryption header if encrypting, the compressed data
        !            78:    and possibly an extended local header. */
        !            79: 
        !            80: int zipcopy(z, x, y)
        !            81: struct zlist far *z;    /* zip entry to copy */
        !            82: FILE *x, *y;            /* source and destination files */
        !            83: /* Copy the zip entry described by *z from file *x to file *y.  Return an
        !            84:    error code in the ZE_ class.  Also update tempzn by the number of bytes
        !            85:    copied. */
        !            86: {
        !            87:   ulg n;                /* holds local header offset */
        !            88: 
        !            89:   if (fseek(x, z->off, SEEK_SET))
        !            90:     return ferror(x) ? ZE_READ : ZE_EOF;
        !            91:   z->off = tempzn;
        !            92:   n = 4 + LOCHEAD + (long)z->nam + (long)z->ext + z->siz;
        !            93:   /* copy the extended local header if there is one */
        !            94:   if (z->lflg & 8) n += 16;
        !            95:   tempzn += n;
        !            96:   return fcopy(x, y, n);
        !            97: }
        !            98: 
        !            99: 
        !           100: #ifndef UTIL
        !           101: 
        !           102: int percent(n, m)
        !           103: long n, m;               /* n is the original size, m is the new size */
        !           104: /* Return the percentage compression from n to m using only integer
        !           105:    operations */
        !           106: {
        !           107:   if (n > 0xffffffL)            /* If n >= 16M */
        !           108:   {                             /*  then divide n and m by 256 */
        !           109:     n += 0x80;  n >>= 8;
        !           110:     m += 0x80;  m >>= 8;
        !           111:   }
        !           112:   return n ? (int)(1 + (200 * (n - m)/n)) / 2 : 0;
        !           113: }
        !           114: 
        !           115: local int suffixes(a, s)
        !           116: char *a;                /* name to check suffix of */
        !           117: char *s;                /* list of suffixes separated by : or ; */
        !           118: /* Return true if a ends in any of the suffixes in the list s. */
        !           119: {
        !           120:   int m;                /* true if suffix matches so far */
        !           121:   char *p;              /* pointer into special */
        !           122:   char *q;              /* pointer into name a */
        !           123: 
        !           124:   m = 1;
        !           125: #ifdef VMS
        !           126:   if( (q = strrchr(a,';')) != NULL )    /* Cut out VMS file version */
        !           127:     --q;
        !           128:   else
        !           129:     q = a + strlen(a) - 1;
        !           130: #else
        !           131:   q = a + strlen(a) - 1;
        !           132: #endif
        !           133:   for (p = s + strlen(s) - 1; p >= s; p--)
        !           134:     if (*p == ':' || *p == ';')
        !           135:       if (m)
        !           136:         return 1;
        !           137:       else
        !           138:       {
        !           139:         m = 1;
        !           140: #ifdef VMS
        !           141:         if( (q = strrchr(a,';')) != NULL )      /* Cut out VMS file version */
        !           142:           --q;
        !           143:         else
        !           144:           q = a + strlen(a) - 1;
        !           145: #else
        !           146:         q = a + strlen(a) - 1;
        !           147: #endif
        !           148:       }
        !           149:     else
        !           150:     {
        !           151:       m = m && q >= a && case_map(*p) == case_map(*q);
        !           152:       q--;
        !           153:     }
        !           154:   return m;
        !           155: }
        !           156: 
        !           157: int zipup(z, y)
        !           158: struct zlist far *z;    /* zip entry to compress */
        !           159: FILE *y;                /* output file */
        !           160: /* Compress the file z->name into the zip entry described by *z and write
        !           161:    it to the file *y. Encrypt if requested.  Return an error code in the
        !           162:    ZE_ class.  Also, update tempzn by the number of bytes written. */
        !           163: {
        !           164:   ulg a = 0L;           /* attributes returned by filetime() */
        !           165:   char *b;              /* malloc'ed file buffer */
        !           166:   extent k = 0;         /* result of zread */
        !           167:   int l = 0;            /* true if this file is a symbolic link */
        !           168:   int m;                /* method for this entry */
        !           169:   ulg o, p;             /* offsets in zip file */
        !           170:   long q = -2L;         /* size returned by filetime */
        !           171:   int r;                /* temporary variable */
        !           172:   ulg s = 0L;           /* size of compressed data */
        !           173:   int isdir;            /* set for a directory name */
        !           174: 
        !           175:   isdir = z->name[strlen(z->name)-1] == '/';
        !           176: 
        !           177:   if ((z->tim = filetime(z->name, &a, &q)) == 0 || q < -1L)
        !           178:     return ZE_OPEN;
        !           179:   /* q is set to -1 if the input file is a device */
        !           180: 
        !           181:   z->nam = strlen(z->zname);
        !           182: 
        !           183:   /* Select method based on the suffix and the global method */
        !           184:   m = special != NULL && suffixes(z->name, special) ? STORE : method;
        !           185: 
        !           186:   /* Open file to zip up unless it is stdin */
        !           187:   if (strcmp(z->name, "-") == 0)
        !           188:   {
        !           189:     ifile = (ftype)zstdin;
        !           190: #ifdef MSDOS
        !           191:     setmode(zstdin, O_BINARY);
        !           192: #endif
        !           193:   }
        !           194:   else
        !           195:   {
        !           196: #ifdef VMS
        !           197:    if (vms_native)
        !           198:      get_vms_attributes(z);
        !           199: #endif
        !           200: #ifdef OS2
        !           201:     GetEAs(z->name, &z->extra, &z->ext, &z->cextra, &z->cext);
        !           202:     /* store data in local header, and size only in central headers */
        !           203: #endif
        !           204:     l = issymlnk(a);
        !           205:     if (l)
        !           206:       ifile = fbad;
        !           207:     else if (isdir) { /* directory */
        !           208:       ifile = fbad;
        !           209:       m = STORE;
        !           210:     }
        !           211:     else if ((ifile = zopen(z->name, fhow)) == fbad)
        !           212:       return ZE_OPEN;
        !           213:   }
        !           214: 
        !           215:   if (l || q == 0)
        !           216:     m = STORE;
        !           217:   if (m == BEST)
        !           218:     m = DEFLATE;
        !           219: 
        !           220:   /* Do not create STORED files with extended local headers if the
        !           221:    * input size is not known, because such files could not be extracted.
        !           222:    * So if the zip file is not seekable and the input file is not
        !           223:    * on disk, obey the -0 option by forcing deflation with stored block.
        !           224:    * Note however that using "zip -0" as filter is not very useful...
        !           225:    * ??? to be done.
        !           226:    */
        !           227: 
        !           228:   /* Fill in header information and write local header to zip file.
        !           229:    * This header will later be re-written since compressed length and
        !           230:    * crc are not yet known.
        !           231:    */
        !           232: 
        !           233:   /* (Assume ext, cext, com, and zname already filled in.) */
        !           234: #ifdef OS2
        !           235:   z->vem = z->dosflag ? 20 :            /* Made under MSDOS by PKZIP 2.0 */
        !           236:   /* We for a FAT file system, we must cheat and pretend that the
        !           237:    * file was not made on OS2 but under DOS. unzip is confused otherwise.
        !           238:    */
        !           239: #else
        !           240:   z->vem = dosify ? 20 :                /* Made under MSDOS by PKZIP 2.0 */
        !           241: #endif
        !           242: #ifdef VMS
        !           243:                     0x200 + REVISION;   /* Made under VMS by this Zip */
        !           244: #else /* !VMS */
        !           245: # ifdef OS2
        !           246:                     0x600 + REVISION;   /* Made under OS/2 by this Zip */
        !           247: # else /* !OS2 */
        !           248: #  ifdef MSDOS
        !           249:                     0     + REVISION;   /* Made under MSDOS by this Zip */
        !           250: #  else
        !           251:                     0x300 + REVISION;   /* Made under Unix by this Zip */
        !           252: #  endif /* MSDOS */
        !           253: # endif /* ?OS2 */
        !           254: #endif /* ?VMS */
        !           255: 
        !           256:   z->ver = 20;                          /* Need PKUNZIP 2.0 */
        !           257:   z->crc = 0;  /* to be updated later */
        !           258:   /* Assume first that we will need an extended local header: */
        !           259:   z->flg = 8;  /* to be updated later */
        !           260: #ifdef CRYPT
        !           261:   if (key != NULL) {
        !           262:     z->flg |= 1;
        !           263:     /* Since we do not yet know the crc here, we pretend that the crc
        !           264:      * is the modification time:
        !           265:      */
        !           266:     z->crc = z->tim << 16;
        !           267:   }
        !           268: #endif
        !           269:   z->lflg = z->flg;
        !           270:   z->how = m;                             /* may be changed later  */
        !           271:   z->siz = m == STORE && q >= 0 ? q : 0;  /* will be changed later  */
        !           272:   z->len = q >= 0 ? q : 0;                /* may be changed later  */
        !           273:   z->dsk = 0;
        !           274:   z->att = BINARY;                        /* may be changed later */
        !           275:   z->atx = z->dosflag ? a & 0xff : a;      /* Attributes from filetime() */
        !           276:   z->off = tempzn;
        !           277:   if ((r = putlocal(z, y)) != ZE_OK)
        !           278:     return r;
        !           279:   tempzn += 4 + LOCHEAD + z->nam + z->ext;
        !           280: 
        !           281: #ifdef CRYPT
        !           282:   if (key != NULL) {
        !           283:     crypthead(key, z->crc, y);
        !           284:     z->siz += 12;  /* to be updated later */
        !           285:     tempzn += 12;
        !           286:   }
        !           287: #endif
        !           288:   o = ftell(y); /* for debugging only */
        !           289: 
        !           290:   /* Write stored or deflated file to zip file */
        !           291:   isize = 0L;
        !           292:   crc = updcrc((char *)NULL, 0);
        !           293: 
        !           294:   if (m == DEFLATE) {
        !           295:      bi_init(y);
        !           296:      z->att = (ush)UNKNOWN;
        !           297:      ct_init(&z->att, &m);
        !           298:      lm_init(level, &z->flg);
        !           299:      s = deflate();
        !           300:   }
        !           301:   else
        !           302:   {
        !           303:     if ((b = malloc(CBSZ)) == NULL)
        !           304:        return ZE_MEM;
        !           305: 
        !           306:     if (!isdir) /* no read for directories */
        !           307:     while ((k = l ? rdsymlnk(z->name, b, CBSZ) : zread(ifile, b, CBSZ)) > 0)
        !           308:     {
        !           309:       isize += k;
        !           310:       crc = updcrc(b, k);
        !           311:       if (zfwrite(b, 1, k, y) != k)
        !           312:       {
        !           313:         free((voidp *)b);
        !           314:         return ZE_TEMP;
        !           315:       }
        !           316: #ifdef MINIX
        !           317:       if (l)
        !           318:         q = k;
        !           319: #endif /* MINIX */
        !           320:       if (l)
        !           321:         break;
        !           322:     }
        !           323:     free((voidp *)b);
        !           324:     s = isize;
        !           325:   }
        !           326:   if (ifile != fbad && zerr(ifile))
        !           327:     return ZE_READ;
        !           328:   if (ifile != fbad)
        !           329:     zclose(ifile);
        !           330: 
        !           331:   tempzn += s;
        !           332:   p = tempzn; /* save for future fseek() */
        !           333: 
        !           334: #ifndef VMS
        !           335:   /* Check input size (but not in VMS--variable record lengths mess it up) */
        !           336:   if (q >= 0 && isize != (ulg)q && !translate_eol)
        !           337:   {
        !           338:     fprintf(mesg, " i=%ld, q=%ld ", isize, q);
        !           339:     error("incorrect input size");
        !           340:   }
        !           341: #endif /* !VMS */
        !           342: 
        !           343:   /* Try to rewrite the local header with correct information */
        !           344:   z->crc = crc;
        !           345:   z->siz = s;
        !           346: #ifdef CRYPT
        !           347:   if (key != NULL)
        !           348:     z->siz += 12;
        !           349: #endif
        !           350:   z->len = isize;
        !           351:   if (fseek(y, z->off, SEEK_SET)) {
        !           352:     if (z->how != (ush) m)
        !           353:        error("can't rewrite method");
        !           354:     if (m == STORE && q < 0)
        !           355:        error("zip -0 not allowed for input/output from/to pipe or device");
        !           356:     if ((r = putextended(z, y)) != ZE_OK)
        !           357:       return r;
        !           358:     tempzn += 16L;
        !           359:     z->flg = z->lflg; /* if flg modified by inflate */
        !           360:   } else {
        !           361:      /* seek ok, ftell() should work, check compressed size */
        !           362: #ifndef VMS
        !           363:     if (p - o != s) {
        !           364:       fprintf(mesg, " s=%ld, actual=%ld ", s, p-o);
        !           365:       error("incorrect compressed size");
        !           366:     }
        !           367: #endif
        !           368:     z->how = m;
        !           369:     if ((z->flg & 1) == 0)
        !           370:       z->flg &= ~8; /* clear the extended local header flag */
        !           371:     z->lflg = z->flg;
        !           372:     /* rewrite the local header: */
        !           373:     if ((r = putlocal(z, y)) != ZE_OK)
        !           374:       return r;
        !           375:     if (fseek(y, p, SEEK_SET))
        !           376:       return ZE_READ;
        !           377:     if ((z->flg & 1) != 0) {
        !           378:       /* encrypted file, extended header still required */
        !           379:       if ((r = putextended(z, y)) != ZE_OK)
        !           380:         return r;
        !           381:       tempzn += 16L;
        !           382:     }
        !           383:   }
        !           384: 
        !           385:   /* Display statistics */
        !           386:   if (noisy)
        !           387:   {
        !           388:     if (verbose)
        !           389:       fprintf(mesg, " (in=%lu) (out=%lu)", isize, s);
        !           390:     if (m == DEFLATE)
        !           391:       fprintf(mesg, " (deflated %d%%)\n", percent(isize, s));
        !           392:     else
        !           393:       fprintf(mesg, " (stored 0%%)\n");
        !           394:     fflush(mesg);
        !           395:   }
        !           396:   return ZE_OK;
        !           397: }
        !           398: 
        !           399: 
        !           400: int file_read(buf, size)
        !           401:   char *buf;
        !           402:   unsigned size;
        !           403: /* Read a new buffer from the current input file, and update the crc and
        !           404:  * input file size.
        !           405:  * IN assertion: size >= 2 (for end-of-line translation)
        !           406:  */
        !           407: {
        !           408:   unsigned len;
        !           409:   char far *b;
        !           410:   if (translate_eol) {
        !           411:     size >>= 1;
        !           412:     b = buf+size;
        !           413:     size = len = zread(ifile, b, size);
        !           414:     if (len == (unsigned)EOF || len == 0) return len;
        !           415:     do {
        !           416:        if ((*buf++ = *b++) == '\n') *(buf-1) = '\r', *buf++ = '\n', len++;
        !           417:     } while (--size != 0);
        !           418:     buf -= len;
        !           419:   } else {
        !           420:     len = zread(ifile, buf, size);
        !           421:     if (len == (unsigned)EOF || len == 0) return len;
        !           422:   }
        !           423:   crc = updcrc(buf, len);
        !           424:   isize += (ulg)len;
        !           425:   return len;
        !           426: }
        !           427: #endif /* !UTIL */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.