Annotation of coherent/b/bin/zip/zipup.c, revision 1.1.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.