Annotation of coherent/b/bin/zip/zip.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:  *  zip.c by Mark Adler.
        !            14:  */
        !            15: 
        !            16: #include "revision.h"
        !            17: #include "zip.h"
        !            18: #ifdef VMS
        !            19: #  include "VMSmunch.h"
        !            20: #  define echon() echo(1)
        !            21: #endif
        !            22: #include <signal.h>
        !            23: 
        !            24: #ifdef MACOS
        !            25: #  include <console.h>
        !            26: #endif
        !            27: 
        !            28: #define PWLEN 80        /* Input buffer size for reading encryption key */
        !            29: #define MAXCOM 256      /* Maximum one-line comment size */
        !            30: 
        !            31: 
        !            32: /* Local option flags */
        !            33: #define DELETE  0
        !            34: #define ADD     1
        !            35: #define UPDATE  2
        !            36: #define FRESHEN 3
        !            37: local int action = ADD; /* one of ADD, UPDATE, FRESHEN, or DELETE */
        !            38: local int comadd = 0;   /* 1=add comments for new files */
        !            39: local int zipedit = 0;  /* 1=edit zip comment and all file comments */
        !            40: local int dispose = 0;  /* 1=remove files after put in zip file */
        !            41: local int latest = 0;   /* 1=set zip file time to time of latest file */
        !            42: local ulg before = 0;   /* 0=ignore, else exclude files before this time */
        !            43: 
        !            44: 
        !            45: /* Temporary zip file name and file pointer */
        !            46: local char *tempzip;
        !            47: local FILE *tempzf;
        !            48: 
        !            49: 
        !            50: /* Local functions */
        !            51: #ifdef PROTO
        !            52:    local void freeup(void);
        !            53:    local void leave(int);
        !            54:    local void handler(int);
        !            55:    local void license(void);
        !            56:    local void help(void);
        !            57:    local void zipstdout(void);
        !            58:    void main(int, char **);
        !            59:    local int count_args(char *s);
        !            60:    local void envargs(int *Pargc, char ***Pargv, char *envstr);
        !            61: #endif /* PROTO */
        !            62: 
        !            63: 
        !            64: 
        !            65: local void freeup()
        !            66: /* Free all allocations in the found list and the zfiles list */
        !            67: {
        !            68:   struct flist far *f;  /* steps through found list */
        !            69:   struct zlist far *z;  /* pointer to next entry in zfiles list */
        !            70: 
        !            71:   for (f = found; f != NULL; f = fexpel(f))
        !            72:     ;
        !            73:   while (zfiles != NULL)
        !            74:   {
        !            75:     z = zfiles->nxt;
        !            76:     free((voidp *)(zfiles->name));
        !            77:     free((voidp *)(zfiles->zname));
        !            78:     if (zfiles->ext)
        !            79:       free((voidp *)(zfiles->extra));
        !            80:     if (zfiles->cext && zfiles->cextra != zfiles->extra)
        !            81:       free((voidp *)(zfiles->cextra));
        !            82:     if (zfiles->com)
        !            83:       free((voidp *)(zfiles->comment));
        !            84:     farfree((voidp far *)zfiles);
        !            85:     zfiles = z;
        !            86:     zcount--;
        !            87:   }
        !            88: }
        !            89: 
        !            90: 
        !            91: local void leave(e)
        !            92: int e;                  /* exit code */
        !            93: /* Process -o and -m options (if specified), free up malloc'ed stuff, and
        !            94:    exit with the code e. */
        !            95: {
        !            96:   int r;                /* return value from trash() */
        !            97:   ulg t;                /* latest time in zip file */
        !            98:   struct zlist far *z;  /* pointer into zfile list */
        !            99: 
        !           100:   /* If latest, set time to zip file to latest file in zip file */
        !           101:   if (latest && strcmp(zipfile, "-"))
        !           102:   {
        !           103:     diag("changing time of zip file to time of latest file in it");
        !           104:     /* find latest time in zip file */
        !           105:     if (zfiles == NULL)
        !           106:        warn("zip file is empty, can't make it as old as latest entry", "");
        !           107:     else {
        !           108:       t = zfiles->tim;
        !           109:       for (z = zfiles->nxt; z != NULL; z = z->nxt)
        !           110:         if (t < z->tim)
        !           111:           t = z->tim;
        !           112:       /* set modified time of zip file to that time */
        !           113:       stamp(zipfile, t);
        !           114:     }
        !           115:   }
        !           116:   if (tempath != NULL)
        !           117:   {
        !           118:     free((voidp *)tempath);
        !           119:     tempath = NULL;
        !           120:   }
        !           121:   if (zipfile != NULL)
        !           122:   {
        !           123:     free((voidp *)zipfile);
        !           124:     zipfile = NULL;
        !           125:   }
        !           126: 
        !           127: 
        !           128:   /* If dispose, delete all files in the zfiles list that are marked */
        !           129:   if (dispose)
        !           130:   {
        !           131:     diag("deleting files that were added to zip file");
        !           132:     if ((r = trash()) != ZE_OK)
        !           133:       err(r, "was deleting moved files and directories");
        !           134:   }
        !           135: 
        !           136: 
        !           137:   /* Done! */
        !           138:   freeup();
        !           139: #ifdef VMS
        !           140:   exit(0);
        !           141: #else /* !VMS */
        !           142:   exit(e);
        !           143: #endif /* ?VMS */
        !           144: }
        !           145: 
        !           146: 
        !           147: void err(c, h)
        !           148: int c;                  /* error code from the ZE_ class */
        !           149: char *h;                /* message about how it happened */
        !           150: /* Issue a message for the error, clean up files and memory, and exit. */
        !           151: {
        !           152:   static int error_level;
        !           153:   if (error_level++ > 0) exit(0);  /* avoid recursive err() */
        !           154: 
        !           155:   if (PERR(c))
        !           156:     perror("zip error");
        !           157:   fprintf(stderr, "zip error: %s (%s)\n", errors[c-1], h);
        !           158:   if (tempzip != NULL)
        !           159:   {
        !           160:     if (tempzip != zipfile) {
        !           161:       if (tempzf != NULL)
        !           162:         fclose(tempzf);
        !           163: #ifndef DEBUG
        !           164:       destroy(tempzip);
        !           165: #endif
        !           166:       free((voidp *)tempzip);
        !           167:     } else {
        !           168:       /* -g option, attempt to restore the old file */
        !           169:       int k = 0;                        /* keep count for end header */
        !           170:       ulg cb = cenbeg;                  /* get start of central */
        !           171:       struct zlist far *z;  /* steps through zfiles linked list */
        !           172: 
        !           173:       fprintf(stderr, "attempting to restore %s to its previous state\n",
        !           174:          zipfile);
        !           175:       fseek(tempzf, cenbeg, SEEK_SET);
        !           176:       tempzn = cenbeg;
        !           177:       for (z = zfiles; z != NULL; z = z->nxt)
        !           178:       {
        !           179:         putcentral(z, tempzf);
        !           180:         tempzn += 4 + CENHEAD + z->nam + z->cext + z->com;
        !           181:         k++;
        !           182:       }
        !           183:       putend(k, tempzn - cb, cb, zcomlen, zcomment, tempzf);
        !           184:       tempzf = NULL;
        !           185:       fclose(tempzf);
        !           186:     }
        !           187:   }
        !           188:   if (key != NULL)
        !           189:     free((voidp *)key);
        !           190:   if (tempath != NULL)
        !           191:     free((voidp *)tempath);
        !           192:   if (zipfile != NULL)
        !           193:     free((voidp *)zipfile);
        !           194:   freeup();
        !           195: #ifdef VMS
        !           196:   c = 0;
        !           197: #endif
        !           198:   exit(c);
        !           199: }
        !           200: 
        !           201: 
        !           202: void error(h)
        !           203:   char *h;
        !           204: /* Internal error, should never happen */
        !           205: {
        !           206:   err(ZE_LOGIC, h);
        !           207: }
        !           208: 
        !           209: local void handler(s)
        !           210: int s;                  /* signal number (ignored) */
        !           211: /* Upon getting a user interrupt, turn echo back on for tty and abort
        !           212:    cleanly using err(). */
        !           213: {
        !           214: #ifndef MSDOS
        !           215: # ifdef CRYPT
        !           216:    echon();
        !           217: # endif
        !           218:   putc('\n', stderr);
        !           219: #endif /* !MSDOS */
        !           220:   err(ZE_ABORT, "aborting");
        !           221:   s++;                                  /* keep some compilers happy */
        !           222: }
        !           223: 
        !           224: 
        !           225: void warn(a, b)
        !           226: char *a, *b;            /* message strings juxtaposed in output */
        !           227: /* Print a warning message to stderr and return. */
        !           228: {
        !           229:   fprintf(stderr, "zip warning: %s%s\n", a, b);
        !           230: }
        !           231: 
        !           232: 
        !           233: local void license()
        !           234: /* Print license information to stdout. */
        !           235: {
        !           236:   extent i;             /* counter for copyright array */
        !           237: 
        !           238:   for (i = 0; i < sizeof(copyright)/sizeof(char *); i++) {
        !           239:     printf(copyright[i], "zip");
        !           240:     putchar('\n');
        !           241:   }
        !           242:   for (i = 0; i < sizeof(disclaimer)/sizeof(char *); i++)
        !           243:     puts(disclaimer[i]);
        !           244: }
        !           245: 
        !           246: 
        !           247: local void help()
        !           248: /* Print help (along with license info) to stdout. */
        !           249: {
        !           250:   extent i;             /* counter for help array */
        !           251: 
        !           252:   /* help array */
        !           253:   static char *text[] = {
        !           254: "",
        !           255: "Zip %d.%d (%s). Usage:",
        !           256: "zip [-options] [-b path] [-t mmddyy] [-n suffixes] [zipfile list] [-x list]",
        !           257: "  The default action is to add or replace zipfile entries from list, which",
        !           258: "  can include the special name - to compress standard input.",
        !           259: "  If zipfile and list are ommitted, zip compresses stdin to stdout.",
        !           260: "  -f   freshen: only changed files  -u   update: only changed or new files",
        !           261: "  -d   delete entries in zipfile    -m   move into zipfile (delete files)",
        !           262: "  -k   simulate PKZIP made zipfile  -g   allow growing existing zipfile",
        !           263: "  -h   show this help               -L   show software license",
        !           264: "  -r   recurse into directories     -j   junk (don't record) directory names",
        !           265: "  -0   store only                   -l   translate end-of-line",
        !           266: "  -1   compress faster              -9   compress better",
        !           267: "  -q   quiet operation              -n   don't compress these suffixes",
        !           268: "  -c   add one-line comments        -z   add zipfile comment",
        !           269: "  -b   use \"path\" for temp files    -t   only do files after \"mmddyy\"",
        !           270: "  -@   read names from stdin        -o   make zipfile as old as latest entry",
        !           271: #ifdef CRYPT
        !           272: "  -e   encrypt  (-ee verify key)",
        !           273: #endif
        !           274: #ifdef VMS
        !           275: "  -w   append the VMS version number to the name stored in the zip file",
        !           276: "  -V   save VMS file attributes",
        !           277: #endif /* VMS */
        !           278: #ifdef OS2
        !           279: "  -E   use the .LONGNAME Extended attribute (if found) as filename",
        !           280: #endif /* OS2 */
        !           281: #ifdef S_IFLNK
        !           282: "  -y   store symbolic links as the link instead of the referenced file",
        !           283: #endif /* !S_IFLNK */
        !           284: "  -x   exclude the names that follow from those operated on"
        !           285:   };
        !           286: 
        !           287:   for (i = 0; i < sizeof(copyright)/sizeof(char *); i++)
        !           288:   {
        !           289:     printf(copyright[i], "zip");
        !           290:     putchar('\n');
        !           291:   }
        !           292:   for (i = 0; i < sizeof(text)/sizeof(char *); i++)
        !           293:   {
        !           294:     printf(text[i], REVISION / 10, REVISION % 10, REVDATE);
        !           295:     putchar('\n');
        !           296:   }
        !           297: }
        !           298: 
        !           299: 
        !           300: /* Do command line expansion for MSDOS and VMS */
        !           301: #if defined(MSVMS) && !defined(__GO32__)
        !           302: #  define PROCNAME(n) (action==ADD||action==UPDATE?wild(n):procname(n))
        !           303: #else /* !MSVMS */
        !           304: #  define PROCNAME(n) procname(n)
        !           305: #endif /* ?MSVMS */
        !           306: 
        !           307: local void zipstdout()
        !           308: /* setup for writing zip file on stdout */
        !           309: {
        !           310:   int r;
        !           311:   mesg = stderr;
        !           312:   if (isatty(1))
        !           313:     err(ZE_PARMS, "no zip file provided");
        !           314:   if ((zipfile = malloc(4)) == NULL)
        !           315:     err(ZE_MEM, "was processing arguments");
        !           316:   strcpy(zipfile, "-");
        !           317:   if ((r = readzipfile()) != ZE_OK)
        !           318:     err(r, zipfile);
        !           319: }
        !           320: 
        !           321: 
        !           322: void main(argc, argv)
        !           323: int argc;               /* number of tokens in command line */
        !           324: char **argv;            /* command line tokens */
        !           325: /* Add, update, freshen, or delete zip entries in a zip file.  See the
        !           326:    command help in help() above. */
        !           327: {
        !           328:   int a;                /* attributes of zip file */
        !           329:   ulg c;                /* start of central directory */
        !           330:   int d;                /* true if just adding to a zip file */
        !           331:   char *e;              /* malloc'd comment buffer */
        !           332:   struct flist far *f;  /* steps through found linked list */
        !           333:   int i;                /* arg counter, root directory flag */
        !           334:   int k;                /* next argument type, marked counter,
        !           335:                            comment size, entry count */
        !           336:   ulg n;                /* total of entry len's */
        !           337:   int o;                /* true if there were any ZE_OPEN errors */
        !           338:   char *p;              /* steps through option arguments */
        !           339:   char *pp;             /* temporary pointer */
        !           340:   int r;                /* temporary variable */
        !           341:   ulg t;                /* file time, length of central directory */
        !           342:   struct zlist far *v;  /* temporary variable */
        !           343:   struct zlist far * far *w;    /* pointer to last link in zfiles list */
        !           344:   FILE *x, *y;          /* input and output zip files */
        !           345:   struct zlist far *z;  /* steps through zfiles linked list */
        !           346:   char *zipbuf;         /* stdio buffer for the zip file */
        !           347: 
        !           348:   mesg = (FILE *) stdout; /* cannot be made at link time for VMS */
        !           349:   init_upper();           /* build case map table */
        !           350: 
        !           351: #ifdef MACOS
        !           352:    argc = ccommand(&argv);
        !           353: #endif
        !           354: 
        !           355:   /* Process arguments */
        !           356:   diag("processing arguments");
        !           357:   if (argc == 1 && isatty(1))
        !           358:   {
        !           359:     help();
        !           360:     exit(0);
        !           361:   }
        !           362:   envargs(&argc, &argv, "ZIPOPT"); /* get options from environment */
        !           363: 
        !           364:   zipfile = tempzip = NULL;
        !           365:   tempzf = NULL;
        !           366:   d = 0;                        /* disallow adding to a zip file */
        !           367:   signal(SIGINT, handler);
        !           368:   signal(SIGTERM, handler);
        !           369:   k = 0;                        /* Next non-option argument type */
        !           370:   for (i = 1; i < argc; i++)
        !           371:   {
        !           372:     if (argv[i][0] == '-')
        !           373:       if (argv[i][1])
        !           374:         for (p = argv[i]+1; *p; p++)
        !           375:           switch(*p)
        !           376:           {
        !           377:             case '0':
        !           378:               method = STORE; level = 0; break;
        !           379:             case '1':  case '2':  case '3':  case '4':
        !           380:             case '5':  case '6':  case '7':  case '8':  case '9':
        !           381:                         /* Set the compression efficacy */
        !           382:               level = *p - '0';  break;
        !           383:             case 'b':   /* Specify path for temporary file */
        !           384:               if (k != 0)
        !           385:                 err(ZE_PARMS, "use -b before zip file name");
        !           386:               else
        !           387:                 k = 1;          /* Next non-option is path */
        !           388:               break;
        !           389:             case 'c':   /* Add comments for new files in zip file */
        !           390:               comadd = 1;  break;
        !           391:             case 'd':   /* Delete files from zip file */
        !           392:               if (action != ADD)
        !           393:                 err(ZE_PARMS, "specify just one action");
        !           394:               action = DELETE;
        !           395:               break;
        !           396: #ifdef CRYPT
        !           397:             case 'e':   /* Encrypt */
        !           398:               e = key == NULL ? (char *)NULL : key;
        !           399:               if ((key = malloc(PWLEN+1)) == NULL)
        !           400:                 err(ZE_MEM, "was getting encryption password");
        !           401:               if (getp(e == NULL ? "Enter password: " : "Verify password: ",
        !           402:                        key, PWLEN+1) == NULL)
        !           403:                 err(ZE_PARMS, "stderr is not a tty");
        !           404:               if (e != NULL)
        !           405:               {
        !           406:                 r = strcmp(key, e);
        !           407:                 free((voidp *)e);
        !           408:                 if (r)
        !           409:                   err(ZE_PARMS, "password not verified");
        !           410:               }
        !           411:               latest = 1;               /* to make breaking the code harder */
        !           412:               break;
        !           413: #endif /* CRYPT */
        !           414:             case 'f':   /* Freshen zip file--overwrite only */
        !           415:               if (action != ADD)
        !           416:                 err(ZE_PARMS, "specify just one action");
        !           417:               action = FRESHEN;
        !           418:               break;
        !           419:             case 'g':   /* Allow appending to a zip file */
        !           420:               d = 1;  break;
        !           421:             case 'h': case 'H': case '?':  /* Help */
        !           422:               help();
        !           423:               leave(ZE_OK);
        !           424:             case 'j':   /* Junk directory names */
        !           425:               pathput = 0;  break;
        !           426:             case 'k':   /* Make entries using DOS names (k for Katz) */
        !           427:               dosify = 1;  break;
        !           428:             case 'l':   /* Translate end-of-line */
        !           429:               translate_eol = 1; break;
        !           430:             case 'L':   /* Show license, version */
        !           431:               license();
        !           432:               leave(ZE_OK);
        !           433:             case 'm':   /* Delete files added or updated in zip file */
        !           434:               dispose = 1;  break;
        !           435:             case 'n':   /* Don't compress files with a special suffix */
        !           436:               special = NULL;
        !           437:               break;
        !           438:             case 'o':   /* Set zip file time to time of latest file in it */
        !           439:               latest = 1;  break;
        !           440:             case 'p':   /* Store path with name */
        !           441:               break;            /* (do nothing as annoyance avoidance) */
        !           442:             case 'q':   /* Quiet operation */
        !           443:               noisy = 0;  break;
        !           444:             case 'r':   /* Recurse into subdirectories */
        !           445:               recurse = 1;  break;
        !           446:             case 't':   /* Exclude files earlier than specified date */
        !           447:               if (before)
        !           448:                 err(ZE_PARMS, "can only have one -t");
        !           449:               k = 2;  break;
        !           450:             case 'u':   /* Update zip file--overwrite only if newer */
        !           451:               if (action != ADD)
        !           452:                 err(ZE_PARMS, "specify just one action");
        !           453:               action = UPDATE;
        !           454:               break;
        !           455:             case 'v':   /* Mention oddities in zip file structure */
        !           456:               verbose++;
        !           457:               break;
        !           458: #ifdef VMS
        !           459:             case 'w':   /* Append the VMS version number */
        !           460:               vmsver = 1;  break;
        !           461:             case 'V':   /* Store in VMS format */
        !           462:               vms_native = 1; break;
        !           463: #endif /* VMS */
        !           464:             case 'x':   /* Exclude following files */
        !           465:               if (k != 4 &&
        !           466:                   (k != 3 || (action != UPDATE && action != FRESHEN)))
        !           467:                 err(ZE_PARMS, "nothing to exclude (-x) from");
        !           468:               if (k == 3)       /* must be -u or -f */
        !           469:                 for (z = zfiles; z != NULL; z = z->nxt)
        !           470:                   z->mark = 1;  /* mark all of them */
        !           471:               k = 5;
        !           472:               if ((r = exclude()) != ZE_OK)
        !           473:                 if (r == ZE_PARMS)
        !           474:                   err(r, "cannot repeat names in zip file");
        !           475:                 else
        !           476:                   err(r, "was processing list of files");
        !           477:               break;
        !           478: #ifdef S_IFLNK
        !           479:             case 'y':   /* Store symbolic links as such */
        !           480:               linkput = 1;  break;
        !           481: #endif /* S_IFLNK */
        !           482:             case 'z':   /* Edit zip file comment */
        !           483:               zipedit = 1;  break;
        !           484:             case '@':   /* read file names from stdin */
        !           485:               while ((pp = getnam(errbuf)) != NULL)
        !           486:               {
        !           487:                 if ((r = PROCNAME(pp)) != ZE_OK)
        !           488:                   if (r == ZE_MISS)
        !           489:                     warn("name not matched: ", pp);
        !           490:                   else
        !           491:                     err(r, pp);
        !           492:               }
        !           493:               break;
        !           494: #ifdef OS2
        !           495:             case 'E':
        !           496:               /* use the .LONGNAME EA (if any) as the file's name. */
        !           497:               use_longname_ea = 1;
        !           498:               break;
        !           499: #endif
        !           500:             default:
        !           501:             {
        !           502:               sprintf(errbuf, "no such option: %c", *p);
        !           503:               err(ZE_PARMS, errbuf);
        !           504:             }
        !           505:           }
        !           506:       else              /* just a dash */
        !           507:         switch (k)
        !           508:         {
        !           509:         case 0:
        !           510:           zipstdout();
        !           511:           k = 3;
        !           512:           break;
        !           513:         case 1:
        !           514:           err(ZE_PARMS, "invalid path");
        !           515:           break;
        !           516:         case 2:
        !           517:           err(ZE_PARMS, "invalid time");
        !           518:           break;
        !           519:         case 3:  case 4:  case 5:
        !           520:           if ((r = PROCNAME(argv[i])) != ZE_OK)
        !           521:             if (r == ZE_MISS)
        !           522:               warn("name not matched: ", argv[i]);
        !           523:             else
        !           524:               err(r, argv[i]);
        !           525:           if (k == 3)
        !           526:             k = 4;
        !           527:         }
        !           528:     else                /* not an option */
        !           529:     {
        !           530:       if (special == NULL)
        !           531:         special = argv[i];
        !           532:       else
        !           533:         switch (k)
        !           534:       {
        !           535:         case 0:
        !           536:           if ((zipfile = ziptyp(argv[i])) == NULL)
        !           537:             err(ZE_MEM, "was processing arguments");
        !           538:           if ((r = readzipfile()) != ZE_OK)
        !           539:             err(r, zipfile);
        !           540:           k = 3;
        !           541:           break;
        !           542:         case 1:
        !           543:           if ((tempath = malloc(strlen(argv[i]) + 1)) == NULL)
        !           544:             err(ZE_MEM, "was processing arguments");
        !           545:           strcpy(tempath, argv[i]);
        !           546:           k = 0;
        !           547:           break;
        !           548:         case 2:
        !           549:         {
        !           550:           int yy, mm, dd;       /* results of sscanf() */
        !           551: 
        !           552:           if (sscanf(argv[i], "%2d%2d%2d", &mm, &dd, &yy) != 3 ||
        !           553:               mm < 1 || mm > 12 || dd < 1 || dd > 31)
        !           554:             err(ZE_PARMS, "invalid date entered for -t option");
        !           555:           before = dostime(yy + (yy < 80 ? 2000 : 1900), mm, dd, 0, 0, 0);
        !           556:           k = 0;
        !           557:           break;
        !           558:         }
        !           559:         case 3:  case 4:  case 5:
        !           560:           if ((r = PROCNAME(argv[i])) != ZE_OK)
        !           561:             if (r == ZE_MISS)
        !           562:               warn("name not matched: ", argv[i]);
        !           563:             else
        !           564:               err(r, argv[i]);
        !           565:           if (k == 3)
        !           566:             k = 4;
        !           567:       }
        !           568:     }
        !           569:   }
        !           570:   if (k < 3) {               /* zip used as filter */
        !           571:     zipstdout();
        !           572:     if ((r = procname("-")) != ZE_OK)
        !           573:       if (r == ZE_MISS)
        !           574:         warn("name not matched: ", "-");
        !           575:       else
        !           576:         err(r, "-");
        !           577:     k = 4;
        !           578:   }
        !           579: 
        !           580:   if (k != 5)                   /* Clean up selections */
        !           581:   {
        !           582:     if (k == 3 && (action == UPDATE || action == FRESHEN))
        !           583:       for (z = zfiles; z != NULL; z = z->nxt)
        !           584:         z->mark = 1;                    /* if -u or -f with no args, do all */
        !           585:     if ((r = exclude()) != ZE_OK)       /* remove duplicates in found list */
        !           586:       if (r == ZE_PARMS)
        !           587:         err(r, "cannot repeat names in zip file");
        !           588:       else
        !           589:         err(r, "was processing list of files");
        !           590:   }
        !           591:   if (zcount)
        !           592:     free((voidp *)zsort);
        !           593: 
        !           594:   /* Check option combinations */
        !           595:   if (action == DELETE && (method != BEST || dispose || recurse ||
        !           596:       key != NULL || comadd || zipedit))
        !           597:     err(ZE_PARMS, "invalid option(s) used with -d");
        !           598:   if (linkput && dosify)
        !           599:     err(ZE_PARMS, "can't use -y with -k");
        !           600:   if ((action != ADD || d) && !strcmp(zipfile, "-"))
        !           601:     err(ZE_PARMS, "can't use -d,-f,-u or -g on standard output");
        !           602: #ifdef VMS
        !           603:   if (vms_native && translate_eol)
        !           604:     err(ZE_PARMS, "can't use -V with -l");
        !           605: #endif
        !           606:   if (zcount == 0 && (action != ADD || d))
        !           607:     warn(zipfile, " not found or empty");
        !           608: 
        !           609: 
        !           610:   /* If -b not specified, make temporary path the same as the zip file */
        !           611: #ifdef MSDOS
        !           612:   if (tempath == NULL && ((p = strrchr(zipfile, '/')) != NULL ||
        !           613:                           (p = strrchr(zipfile, '\\')) != NULL ||
        !           614:                           (p = strrchr(zipfile, ':')) != NULL))
        !           615:   {
        !           616:     if (*p == ':')
        !           617:       p++;
        !           618: #else /* !MSDOS */
        !           619:   if (tempath == NULL && (p = strrchr(zipfile, '/')) != NULL)
        !           620:   {
        !           621: #endif /* ?MSDOS */
        !           622:     if ((tempath = malloc((int)(p - zipfile) + 1)) == NULL)
        !           623:       err(ZE_MEM, "was processing arguments");
        !           624:     r = *p;  *p = 0;
        !           625:     strcpy(tempath, zipfile);
        !           626:     *p = (char)r;
        !           627:   }
        !           628: 
        !           629:   /* For each marked entry, if not deleting, check if it exists, and if
        !           630:      updating or freshening, compare date with entry in old zip file.
        !           631:      Unmark if it doesn't exist or is too old, else update marked count. */
        !           632:   diag("stating marked entries");
        !           633:   k = 0;                        /* Initialize marked count */
        !           634:   for (z = zfiles; z != NULL; z = z->nxt)
        !           635:     if (z->mark)
        !           636:       if (action != DELETE &&
        !           637:                 ((t = filetime(z->name, (ulg *)NULL, (long *)NULL)) == 0 ||
        !           638:                  t < before ||
        !           639:                  ((action == UPDATE || action == FRESHEN) && t <= z->tim)))
        !           640:       {
        !           641:         z->mark = 0;
        !           642:         z->trash = t && t >= before;    /* delete if -um or -fm */
        !           643:         if (verbose)
        !           644:           fprintf(mesg, "zip diagnostic: %s %s\n", z->name,
        !           645:                  z->trash ? "up to date" : "missing or early");
        !           646:       }
        !           647:       else
        !           648:         k++;
        !           649: 
        !           650: 
        !           651:   /* Remove entries from found list that do not exist or are too old */
        !           652:   diag("stating new entries");
        !           653:   for (f = found; f != NULL;)
        !           654:     if (action == DELETE || action == FRESHEN ||
        !           655:         (t = filetime(f->name, (ulg *)NULL, (long *)NULL)) == 0 ||
        !           656:         t < before || (namecmp(f->name, zipfile) == 0 && strcmp(zipfile, "-")))
        !           657:       f = fexpel(f);
        !           658:     else
        !           659:       f = f->nxt;
        !           660: 
        !           661:   /* Make sure there's something left to do */
        !           662:   if (k == 0 && found == NULL && !(zfiles != NULL && (latest || zipedit)))
        !           663:     if (action == UPDATE || action == FRESHEN)
        !           664:       leave(ZE_OK);
        !           665:     else if (zfiles == NULL && latest)
        !           666:       err(ZE_NAME, zipfile);
        !           667:     else
        !           668:       err(ZE_NONE, zipfile);
        !           669:   d = (d && k == 0 && (zipbeg || zfiles != NULL)); /* d true if appending */
        !           670: 
        !           671: 
        !           672:   /* Before we get carried away, make sure zip file is writeable */
        !           673:   if (strcmp(zipfile, "-"))
        !           674:   {
        !           675:     x = zfiles == NULL && zipbeg == 0 ? fopen(zipfile, FOPW) : 
        !           676:                                         fopen(zipfile, FOPM);
        !           677:     /* Note: FOPW and FOPM expand to several parameters for VMS */
        !           678:     if (x == NULL)
        !           679:       err(ZE_CREAT, zipfile);
        !           680:     fclose(x);
        !           681:     a = getfileattr(zipfile);
        !           682:     if (zfiles == NULL && zipbeg == 0)
        !           683:       destroy(zipfile);
        !           684:   }
        !           685:   else
        !           686:     a = 0;
        !           687: 
        !           688: 
        !           689:   /* Open zip file and temporary output file */
        !           690:   diag("opening zip file and creating temporary zip file");
        !           691:   x = NULL;
        !           692:   tempzn = 0;
        !           693:   if (strcmp(zipfile, "-") == 0)
        !           694:   {
        !           695: #ifdef MSDOS
        !           696:     /* Set stdout mode to binary for MSDOS systems */
        !           697:     setmode(fileno(stdout), O_BINARY);
        !           698:     tempzf = y = fdopen(fileno(stdout), FOPW);
        !           699: #else
        !           700:     tempzf = y = stdout;
        !           701: #endif
        !           702:     tempzip = "-";
        !           703:   }
        !           704:   else if (d) /* d true if just appending (-g) */
        !           705:   {
        !           706:     if ((y = fopen(zipfile, FOPM)) == NULL)
        !           707:       err(ZE_NAME, zipfile);
        !           708:     tempzip = zipfile;
        !           709:     tempzf = y;
        !           710:     if (fseek(y, cenbeg, SEEK_SET))
        !           711:       err(ferror(y) ? ZE_READ : ZE_EOF, zipfile);
        !           712:     tempzn = cenbeg;
        !           713:   }
        !           714:   else
        !           715:   {
        !           716:     if ((zfiles != NULL || zipbeg) && (x = fopen(zipfile, FOPR_EX)) == NULL)
        !           717:       err(ZE_NAME, zipfile);
        !           718:     if ((tempzip = tempname(zipfile)) == NULL)
        !           719:       err(ZE_MEM, tempzip);
        !           720:     if ((tempzf = y = fopen(tempzip, FOPW)) == NULL)
        !           721:       err(ZE_TEMP, tempzip);
        !           722:     if (zipbeg && (r = fcopy(x, y, zipbeg)) != ZE_OK)
        !           723:       err(r, r == ZE_TEMP ? tempzip : zipfile);
        !           724:     tempzn = zipbeg;
        !           725:   }
        !           726: #ifndef VMS
        !           727:   /* Use large buffer to speed up stdio: */
        !           728:   zipbuf = (char *)malloc(ZBSZ);
        !           729:   if (zipbuf == NULL)
        !           730:     err(ZE_MEM, tempzip);
        !           731: # ifdef _IOFBF
        !           732:   setvbuf(y, zipbuf, _IOFBF, ZBSZ);
        !           733: # else
        !           734:   setbuf(y, zipbuf);
        !           735: # endif /* _IOBUF */
        !           736: #endif /* VMS */
        !           737:   o = 0;                                /* no ZE_OPEN errors yet */
        !           738: 
        !           739: 
        !           740:   /* Process zip file, updating marked files */
        !           741:   if (zfiles != NULL)
        !           742:     diag("going through old zip file");
        !           743:   w = &zfiles;
        !           744:   while ((z = *w) != NULL)
        !           745:     if (z->mark)
        !           746:     {
        !           747:       /* if not deleting, zip it up */
        !           748:       if (action != DELETE)
        !           749:       {
        !           750:         if (noisy)
        !           751:         {
        !           752:           fprintf(mesg, "updating %s", z->zname);
        !           753:           fflush(mesg);
        !           754:         }
        !           755:         if ((r = zipup(z, y)) != ZE_OK && r != ZE_OPEN)
        !           756:         {
        !           757:           if (noisy)
        !           758:           {
        !           759:             putc('\n', mesg);
        !           760:             fflush(mesg);
        !           761:           }
        !           762:           sprintf(errbuf, "was zipping %s", z->name);
        !           763:           err(r, errbuf);
        !           764:         }
        !           765:         if (r == ZE_OPEN)
        !           766:         {
        !           767:           o = 1;
        !           768:           if (noisy)
        !           769:           {
        !           770:             putc('\n', mesg);
        !           771:             fflush(mesg);
        !           772:           }
        !           773:           perror("zip warning");
        !           774:           warn("could not open for reading: ", z->name);
        !           775:           warn("will just copy entry over: ", z->zname);
        !           776:           if ((r = zipcopy(z, x, y)) != ZE_OK)
        !           777:           {
        !           778:             sprintf(errbuf, "was copying %s", z->zname);
        !           779:             err(r, errbuf);
        !           780:           }
        !           781:           z->mark = 0;
        !           782:         }
        !           783:         w = &z->nxt;
        !           784:       }
        !           785:       else
        !           786:       {
        !           787:         if (noisy)
        !           788:         {
        !           789:           fprintf(mesg, "deleting %s\n", z->zname);
        !           790:           fflush(mesg);
        !           791:         }
        !           792:         v = z->nxt;                     /* delete entry from list */
        !           793:         free((voidp *)(z->name));
        !           794:         free((voidp *)(z->zname));
        !           795:         if (z->ext)
        !           796:           free((voidp *)(z->extra));
        !           797:         if (z->cext && z->cextra != z->extra)
        !           798:           free((voidp *)(z->cextra));
        !           799:         if (z->com)
        !           800:           free((voidp *)(z->comment));
        !           801:         farfree((voidp far *)z);
        !           802:         *w = v;
        !           803:         zcount--;
        !           804:       }
        !           805:     }
        !           806:     else
        !           807:     {
        !           808:       /* copy the original entry verbatim */
        !           809:       if (!d && (r = zipcopy(z, x, y)) != ZE_OK)
        !           810:       {
        !           811:         sprintf(errbuf, "was copying %s", z->zname);
        !           812:         err(r, errbuf);
        !           813:       }
        !           814:       w = &z->nxt;
        !           815:     }
        !           816: 
        !           817: 
        !           818:   /* Process the edited found list, adding them to the zip file */
        !           819:   diag("zipping up new entries, if any");
        !           820:   for (f = found; f != NULL; f = fexpel(f))
        !           821:   {
        !           822:     /* add a new zfiles entry and set the name */
        !           823:     if ((z = (struct zlist far *)farmalloc(sizeof(struct zlist))) == NULL)
        !           824:       err(ZE_MEM, "was adding files to zip file");
        !           825:     z->nxt = NULL;
        !           826:     z->name = f->name;
        !           827:     f->name = NULL;
        !           828:     z->zname = f->zname;
        !           829:     f->zname = NULL;
        !           830:     z->ext = z->cext = z->com = 0;
        !           831:     z->mark = 1;
        !           832:     z->dosflag = f->dosflag;
        !           833:     /* zip it up */
        !           834:     if (noisy)
        !           835:     {
        !           836:       fprintf(mesg, "adding %s", z->zname);
        !           837:       fflush(mesg);
        !           838:     }
        !           839:     if ((r = zipup(z, y)) != ZE_OK  && r != ZE_OPEN)
        !           840:     {
        !           841:       if (noisy)
        !           842:       {
        !           843:         putc('\n', mesg);
        !           844:         fflush(mesg);
        !           845:       }
        !           846:       sprintf(errbuf, "was zipping %s", z->name);
        !           847:       err(r, errbuf);
        !           848:     }
        !           849:     if (r == ZE_OPEN)
        !           850:     {
        !           851:       o = 1;
        !           852:       if (noisy)
        !           853:       {
        !           854:         putc('\n', mesg);
        !           855:         fflush(mesg);
        !           856:       }
        !           857:       perror("zip warning");
        !           858:       warn("could not open for reading: ", z->name);
        !           859:       free((voidp *)(z->name));
        !           860:       free((voidp *)(z->zname));
        !           861:       farfree((voidp far *)z);
        !           862:     }
        !           863:     else
        !           864:     {
        !           865:       *w = z;
        !           866:       w = &z->nxt;
        !           867:       zcount++;
        !           868:     }
        !           869:   }
        !           870:   if (key != NULL)
        !           871:   {
        !           872:     free((voidp *)key);
        !           873:     key = NULL;
        !           874:   }
        !           875: 
        !           876: 
        !           877:   /* Get one line comment for each new entry */
        !           878:   if (comadd)
        !           879:   {
        !           880:     if ((e = malloc(MAXCOM + 1)) == NULL)
        !           881:       err(ZE_MEM, "was reading comment lines");
        !           882:     for (z = zfiles; z != NULL; z = z->nxt)
        !           883:       if (z->mark)
        !           884:       {
        !           885:         if (noisy)
        !           886:           fprintf(mesg, "Enter comment for %s:\n", z->name);
        !           887:         /* ??? reopen /dev/tty if one file was zipped from stdin
        !           888:          * or if file names were read from stdin.
        !           889:          */
        !           890:         if (fgets(e, MAXCOM+1, stdin) != NULL)
        !           891:         {
        !           892:           if ((p = malloc((k = strlen(e))+1)) == NULL)
        !           893:           {
        !           894:             free((voidp *)e);
        !           895:             err(ZE_MEM, "was reading comment lines");
        !           896:           }
        !           897:           strcpy(p, e);
        !           898:           if (p[k-1] == '\n')
        !           899:             p[--k] = 0;
        !           900:           z->comment = p;
        !           901:           z->com = k;
        !           902:         }
        !           903:       }
        !           904:     free((voidp *)e);
        !           905:   }
        !           906: 
        !           907:   /* Get multi-line comment for the zip file */
        !           908:   if (zipedit)
        !           909:   {
        !           910:     if ((e = malloc(MAXCOM + 1)) == NULL)
        !           911:       err(ZE_MEM, "was reading comment lines");
        !           912:     if (noisy && zcomlen)
        !           913:     {
        !           914:       fputs("current zip file comment is:\n", mesg);
        !           915:       fwrite(zcomment, 1, zcomlen, mesg);
        !           916:       if (zcomment[zcomlen-1] != '\n')
        !           917:         putc('\n', mesg);
        !           918:       free((voidp *)zcomment);
        !           919:     }
        !           920:     zcomment = malloc(1);
        !           921:     *zcomment = 0;
        !           922:     if (noisy)
        !           923:       fputs("enter new zip file comment (end with .):\n", mesg);
        !           924:      /* ??? reopen /dev/tty if one file was zipped from stdin
        !           925:       * or if file names were read from stdin.
        !           926:       */
        !           927:     while (fgets(e, MAXCOM+1, stdin) != NULL && strcmp(e, ".\n"))
        !           928:     {
        !           929:       if (e[(r = strlen(e)) - 1] == '\n')
        !           930:         e[--r] = 0;
        !           931:       if ((p = malloc((*zcomment ? strlen(zcomment) + 3 : 1) + r)) == NULL)
        !           932:       {
        !           933:         free((voidp *)e);
        !           934:         err(ZE_MEM, "was reading comment lines");
        !           935:       }
        !           936:       if (*zcomment)
        !           937:         strcat(strcat(strcpy(p, zcomment), "\r\n"), e);
        !           938:       else
        !           939:         strcpy(p, *e ? e : "\r\n");
        !           940:       free((voidp *)zcomment);
        !           941:       zcomment = p;
        !           942:     }
        !           943:     zcomlen = strlen(zcomment);
        !           944:     free((voidp *)e);
        !           945:   }
        !           946: 
        !           947: 
        !           948:   /* Write central directory and end header to temporary zip */
        !           949:   diag("writing central directory");
        !           950:   k = 0;                        /* keep count for end header */
        !           951:   c = tempzn;                   /* get start of central */
        !           952:   n = t = 0;
        !           953:   for (z = zfiles; z != NULL; z = z->nxt)
        !           954:   {
        !           955:     if ((r = putcentral(z, y)) != ZE_OK)
        !           956:       err(r, tempzip);
        !           957:     tempzn += 4 + CENHEAD + z->nam + z->cext + z->com;
        !           958:     n += z->len;
        !           959:     t += z->siz;
        !           960:     k++;
        !           961:   }
        !           962:   if (k == 0)
        !           963:     warn("zip file empty", "");
        !           964:   if (verbose)
        !           965:     fprintf(mesg, "total bytes=%lu, compressed=%lu -> %d%% savings\n",
        !           966:            n, t, percent(n, t));
        !           967:   t = tempzn - c;               /* compute length of central */
        !           968:   diag("writing end of central directory");
        !           969:   if ((r = putend(k, t, c, zcomlen, zcomment, y)) != ZE_OK)
        !           970:     err(r, tempzip);
        !           971:   tempzf = NULL;
        !           972:   if (fclose(y))
        !           973:     err(d ? ZE_WRITE : ZE_TEMP, tempzip);
        !           974:   if (x != NULL)
        !           975:     fclose(x);
        !           976: 
        !           977: 
        !           978:   /* Replace old zip file with new zip file, leaving only the new one */
        !           979:   if (strcmp(zipfile, "-") && !d)
        !           980:   {
        !           981:     diag("replacing old zip file with new zip file");
        !           982:     if ((r = replace(zipfile, tempzip)) != ZE_OK)
        !           983:     {
        !           984:       warn("new zip file left as: ", tempzip);
        !           985:       free((voidp *)tempzip);
        !           986:       tempzip = NULL;
        !           987:       err(r, "was replacing the original zip file");
        !           988:     }
        !           989:     free((voidp *)tempzip);
        !           990:   }
        !           991:   tempzip = NULL;
        !           992:   if (strcmp(zipfile, "-")) {
        !           993:     setfileattr(zipfile, a);
        !           994: #ifdef VMS
        !           995:     /* If the zip file existed previously, restore its record format: */
        !           996:     if (x != NULL)
        !           997:       VMSmunch(zipfile, RESTORE_RTYPE, NULL);
        !           998: #endif
        !           999:   }
        !          1000: 
        !          1001:   /* Finish up (process -o, -m, clean up).  Exit code depends on o. */
        !          1002:   leave(o ? ZE_OPEN : ZE_OK);
        !          1003: }
        !          1004: 
        !          1005: /*****************************************************************
        !          1006:  | envargs - add default options from environment to command line
        !          1007:  |----------------------------------------------------------------
        !          1008:  | Author: Bill Davidsen, original 10/13/91, revised 23 Oct 1991.
        !          1009:  | This program is in the public domain.
        !          1010:  |----------------------------------------------------------------
        !          1011:  | Minor program notes:
        !          1012:  |  1. Yes, the indirection is a tad complex
        !          1013:  |  2. Parenthesis were added where not needed in some cases
        !          1014:  |     to make the action of the code less obscure.
        !          1015:  ****************************************************************/
        !          1016: 
        !          1017: local void
        !          1018: envargs(Pargc, Pargv, envstr)
        !          1019: int *Pargc;
        !          1020: char ***Pargv;
        !          1021: char *envstr;
        !          1022: {
        !          1023:     char *getenv();
        !          1024:     char *envptr;                               /* value returned by getenv */
        !          1025:     char *bufptr;                               /* copy of env info */
        !          1026:     int argc = 0;                               /* internal arg count */
        !          1027:     int ch;                                             /* spare temp value */
        !          1028:     char **argv;                                /* internal arg vector */
        !          1029:     char **argvect;                             /* copy of vector address */
        !          1030: 
        !          1031:     /* see if anything in the environment */
        !          1032:     envptr = getenv(envstr);
        !          1033:     if (envptr == NULL || *envptr == 0) return;
        !          1034: 
        !          1035:     /* count the args so we can allocate room for them */
        !          1036:     argc = count_args(envptr);
        !          1037:     bufptr = malloc(1+strlen(envptr));
        !          1038:     if (bufptr == NULL)
        !          1039:         err(ZE_MEM, "Can't get memory for arguments");
        !          1040: 
        !          1041:     strcpy(bufptr, envptr);
        !          1042: 
        !          1043:     /* allocate a vector large enough for all args */
        !          1044:     argv = (char **)malloc((argc+*Pargc+1)*sizeof(char *));
        !          1045:     if (argv == NULL)
        !          1046:         err(ZE_MEM, "Can't get memory for arguments");
        !          1047:     argvect = argv;
        !          1048: 
        !          1049:     /* copy the program name first, that's always true */
        !          1050:     *(argv++) = *((*Pargv)++);
        !          1051: 
        !          1052:     /* copy the environment args first, may be changed */
        !          1053:     do {
        !          1054:         *(argv++) = bufptr;
        !          1055:         /* skip the arg and any trailing blanks */
        !          1056:         while ((ch = *bufptr) != '\0' && ch != ' ') ++bufptr;
        !          1057:         if (ch == ' ') *(bufptr++) = '\0';
        !          1058:         while ((ch = *bufptr) != '\0' && ch == ' ') ++bufptr;
        !          1059:     } while (ch);
        !          1060: 
        !          1061:     /* now save old argc and copy in the old args */
        !          1062:     argc += *Pargc;
        !          1063:     while (--(*Pargc)) *(argv++) = *((*Pargv)++);
        !          1064: 
        !          1065:     /* finally, add a NULL after the last arg, like UNIX */
        !          1066:     *argv = NULL;
        !          1067: 
        !          1068:     /* save the values and return */
        !          1069:     *Pargv = argvect;
        !          1070:     *Pargc = argc;
        !          1071: }
        !          1072: 
        !          1073: static int
        !          1074: count_args(s)
        !          1075: char *s;
        !          1076: {
        !          1077:     int count = 0;
        !          1078:     int ch;
        !          1079: 
        !          1080:     do {
        !          1081:         /* count and skip args */
        !          1082:         ++count;
        !          1083:         while ((ch = *s) != '\0' && ch != ' ') ++s;
        !          1084:         while ((ch = *s) != '\0' && ch == ' ') ++s;
        !          1085:     } while (ch);
        !          1086: 
        !          1087:     return count;
        !          1088: }

unix.superglobalmegacorp.com

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