1 /*
2   zipcloak.c - Zip 3
3 
4   Copyright (c) 1990-2008 Info-ZIP.  All rights reserved.
5 
6   See the accompanying file LICENSE, version 2007-Mar-4 or later
7   (the contents of which are also included in zip.h) for terms of use.
8   If, for some reason, all these files are missing, the Info-ZIP license
9   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
10 */
11 /*
12    This code was originally written in Europe and could be freely distributed
13    from any country except the U.S.A. If this code was imported into the U.S.A,
14    it could not be re-exported from the U.S.A to another country. (This
15    restriction might seem curious but this is what US law required.)
16 
17    Now this code can be freely exported and imported.  See README.CR.
18  */
19 #define __ZIPCLOAK_C
20 
21 #ifndef UTIL
22 # define UTIL
23 #endif
24 #include "zip.h"
25 #define DEFCPYRT        /* main module: enable copyright string defines! */
26 #include "revision.h"
27 #include "crc32.h"
28 #include "crypt.h"
29 #include "ttyio.h"
30 #include <signal.h>
31 #ifndef NO_STDLIB_H
32 #  include <stdlib.h>
33 #endif
34 
35 #if CRYPT       /* defined (as TRUE or FALSE) in crypt.h */
36 
37 int main OF((int argc, char **argv));
38 
39 local void handler OF((int sig));
40 local void license OF((void));
41 local void help OF((void));
42 local void version_info OF((void));
43 
44 /* Temporary zip file pointer */
45 local FILE *tempzf;
46 
47 /* Pointer to CRC-32 table (used for decryption/encryption) */
48 #if (!defined(USE_ZLIB) || defined(USE_OWN_CRCTAB))
49 ZCONST ulg near *crc_32_tab;
50 #else
51 ZCONST uLongf *crc_32_tab;
52 #endif
53 
set_filetype(out_path)54 int set_filetype(out_path)
55   char *out_path;
56 {
57 #ifdef __BEOS__
58   /* Set the filetype of the zipfile to "application/zip" */
59   setfiletype( out_path, "application/zip" );
60 #endif
61 
62 #ifdef __ATHEOS__
63   /* Set the filetype of the zipfile to "application/x-zip" */
64   setfiletype(out_path, "application/x-zip");
65 #endif
66 
67 #ifdef MACOS
68   /* Set the Creator/Type of the zipfile to 'IZip' and 'ZIP ' */
69   setfiletype(out_path, 'IZip', 'ZIP ');
70 #endif
71 
72 #ifdef RISCOS
73   /* Set the filetype of the zipfile to &DDC */
74   setfiletype(out_path, 0xDDC);
75 #endif
76   return ZE_OK;
77 }
78 
79 /* rename a split
80  * A split has a tempfile name until it is closed, then
81  * here rename it as out_path the final name for the split.
82  */
rename_split(temp_name,out_path)83 int rename_split(temp_name, out_path)
84   char *temp_name;
85   char *out_path;
86 {
87   int r;
88   /* Replace old zip file with new zip file, leaving only the new one */
89   if ((r = replace(out_path, temp_name)) != ZE_OK)
90   {
91     zipwarn("new zip file left as: ", temp_name);
92     free((zvoid *)tempzip);
93     tempzip = NULL;
94     ZIPERR(r, "was replacing split file");
95   }
96   if (zip_attributes) {
97     setfileattr(out_path, zip_attributes);
98   }
99   return ZE_OK;
100 }
101 
zipmessage_nl(a,nl)102 void zipmessage_nl(a, nl)
103 ZCONST char *a;     /* message string to output */
104 int nl;             /* 1 = add nl to end */
105 /* If nl false, print a message to mesg without new line.
106    If nl true, print and add new line. */
107 {
108   if (noisy) {
109     fprintf(mesg, "%s", a);
110     if (nl) {
111       fprintf(mesg, "\n");
112       mesg_line_started = 0;
113     } else {
114       mesg_line_started = 1;
115     }
116     fflush(mesg);
117   }
118 }
119 
zipmessage(a,b)120 void zipmessage(a, b)
121 ZCONST char *a, *b;     /* message strings juxtaposed in output */
122 /* Print a message to mesg and flush.  Write new line first
123    if current line has output already. */
124 {
125   if (noisy) {
126     if (mesg_line_started)
127       fprintf(mesg, "\n");
128     fprintf(mesg, "%s%s\n", a, b);
129     mesg_line_started = 0;
130     fflush(mesg);
131   }
132 }
133 
134 /***********************************************************************
135  * Issue a message for the error, clean up files and memory, and exit.
136  */
ziperr(code,msg)137 void ziperr(code, msg)
138     int code;               /* error code from the ZE_ class */
139     ZCONST char *msg;       /* message about how it happened */
140 {
141     if (PERR(code)) perror("zipcloak error");
142     fprintf(mesg, "zipcloak error: %s (%s)\n", ZIPERRORS(code), msg);
143     if (tempzf != NULL) fclose(tempzf);
144     if (tempzip != NULL) {
145         destroy(tempzip);
146         free((zvoid *)tempzip);
147     }
148     if (zipfile != NULL) free((zvoid *)zipfile);
149     EXIT(code);
150 }
151 
152 /***********************************************************************
153  * Print a warning message to mesg (usually stderr) and return.
154  */
zipwarn(msg1,msg2)155 void zipwarn(msg1, msg2)
156     ZCONST char *msg1, *msg2;   /* message strings juxtaposed in output */
157 {
158     fprintf(mesg, "zipcloak warning: %s%s\n", msg1, msg2);
159 }
160 
161 
162 /***********************************************************************
163  * Upon getting a user interrupt, turn echo back on for tty and abort
164  * cleanly using ziperr().
165  */
handler(sig)166 local void handler(sig)
167     int sig;                  /* signal number (ignored) */
168 {
169 #if (!defined(MSDOS) && !defined(__human68k__) && !defined(RISCOS))
170     echon();
171     putc('\n', mesg);
172 #endif
173     ziperr(ZE_ABORT +sig-sig, "aborting");
174     /* dummy usage of sig to avoid compiler warnings */
175 }
176 
177 
178 static ZCONST char *public[] = {
179 "The encryption code of this program is not copyrighted and is",
180 "put in the public domain. It was originally written in Europe",
181 "and can be freely distributed in both source and object forms",
182 "from any country, including the USA under License Exception",
183 "TSU of the U.S. Export Administration Regulations (section",
184 "740.13(e)) of 6 June 2002.  (Prior to January 2000, re-export",
185 "from the US was a violation of US law.)"
186 };
187 
188 /***********************************************************************
189  * Print license information to stdout.
190  */
license()191 local void license()
192 {
193     extent i;             /* counter for copyright array */
194 
195     for (i = 0; i < sizeof(swlicense)/sizeof(char *); i++) {
196         puts(swlicense[i]);
197     }
198     putchar('\n');
199     printf("Export notice:\n");
200     for (i = 0; i < sizeof(public)/sizeof(char *); i++) {
201         puts(public[i]);
202     }
203 }
204 
205 
206 static ZCONST char *help_info[] = {
207 "",
208 "ZipCloak %s (%s)",
209 #ifdef VM_CMS
210 "Usage:  zipcloak [-dq] [-b fm] zipfile",
211 #else
212 "Usage:  zipcloak [-dq] [-b path] zipfile",
213 #endif
214 "  the default action is to encrypt all unencrypted entries in the zip file",
215 "",
216 "  -d  --decrypt      decrypt encrypted entries (copy if given wrong password)",
217 #ifdef VM_CMS
218 "  -b  --temp-mode    use \"fm\" as the filemode for the temporary zip file",
219 #else
220 "  -b  --temp-path    use \"path\" for the temporary zip file",
221 #endif
222 "  -O  --output-file  write output to new zip file",
223 "  -q  --quiet        quiet operation, suppress some informational messages",
224 "  -h  --help         show this help",
225 "  -v  --version      show version info",
226 "  -L  --license      show software license"
227   };
228 
229 /***********************************************************************
230  * Print help (along with license info) to stdout.
231  */
help()232 local void help()
233 {
234     extent i;             /* counter for help array */
235 
236     for (i = 0; i < sizeof(help_info)/sizeof(char *); i++) {
237         printf(help_info[i], VERSION, REVDATE);
238         putchar('\n');
239     }
240 }
241 
242 
version_info()243 local void version_info()
244 /* Print verbose info about program version and compile time options
245    to stdout. */
246 {
247   extent i;             /* counter in text arrays */
248 
249   /* Options info array */
250   static ZCONST char *comp_opts[] = {
251 #ifdef DEBUG
252     "DEBUG",
253 #endif
254 #if CRYPT && defined(PASSWD_FROM_STDIN)
255     "PASSWD_FROM_STDIN",
256 #endif /* CRYPT && PASSWD_FROM_STDIN */
257     NULL
258   };
259 
260   for (i = 0; i < sizeof(copyright)/sizeof(char *); i++)
261   {
262     printf(copyright[i], "zipcloak");
263     putchar('\n');
264   }
265   putchar('\n');
266 
267   for (i = 0; i < sizeof(versinfolines)/sizeof(char *); i++)
268   {
269     printf(versinfolines[i], "ZipCloak", VERSION, REVDATE);
270     putchar('\n');
271   }
272 
273   version_local();
274 
275   puts("ZipCloak special compilation options:");
276   for (i = 0; (int)i < (int)(sizeof(comp_opts)/sizeof(char *) - 1); i++)
277   {
278     printf("\t%s\n",comp_opts[i]);
279   }
280   printf("\t[encryption, version %d.%d%s of %s]\n",
281             CR_MAJORVER, CR_MINORVER, CR_BETA_VER, CR_VERSION_DATE);
282 }
283 
284 /* options for zipcloak - 3/5/2004 EG */
285 struct option_struct far options[] = {
286   /* short longopt        value_type        negatable        ID    name */
287 #ifdef VM_CMS
288     {"b",  "temp-mode",   o_REQUIRED_VALUE, o_NOT_NEGATABLE, 'b',  "temp file mode"},
289 #else
290     {"b",  "temp-path",   o_REQUIRED_VALUE, o_NOT_NEGATABLE, 'b',  "path for temp file"},
291 #endif
292     {"d",  "decrypt",     o_NO_VALUE,       o_NOT_NEGATABLE, 'd',  "decrypt"},
293     {"h",  "help",        o_NO_VALUE,       o_NOT_NEGATABLE, 'h',  "help"},
294     {"L",  "license",     o_NO_VALUE,       o_NOT_NEGATABLE, 'L',  "license"},
295     {"l",  "",            o_NO_VALUE,       o_NOT_NEGATABLE, 'L',  "license"},
296     {"O",  "output-file", o_REQUIRED_VALUE, o_NOT_NEGATABLE, 'O',  "output to new archive"},
297     {"v",  "version",     o_NO_VALUE,       o_NOT_NEGATABLE, 'v',  "version"},
298     /* the end of the list */
299     {NULL, NULL,          o_NO_VALUE,       o_NOT_NEGATABLE, 0,    NULL} /* end has option_ID = 0 */
300   };
301 
302 
303 /***********************************************************************
304  * Encrypt or decrypt all of the entries in a zip file.  See the command
305  * help in help() above.
306  */
307 
main(argc,argv)308 int main(argc, argv)
309     int argc;                   /* number of tokens in command line */
310     char **argv;                /* command line tokens */
311 {
312     int attr;                   /* attributes of zip file */
313     zoff_t start_offset;        /* start of central directory */
314     int decrypt;                /* decryption flag */
315     int temp_path;              /* 1 if next argument is path for temp files */
316     char passwd[IZ_PWLEN+1];    /* password for encryption or decryption */
317     char verify[IZ_PWLEN+1];    /* password for encryption or decryption */
318 #if 0
319     char *q;                    /* steps through option arguments */
320     int r;                      /* arg counter */
321 #endif
322     int res;                    /* result code */
323     zoff_t length;              /* length of central directory */
324     FILE *inzip, *outzip;       /* input and output zip files */
325     struct zlist far *z;        /* steps through zfiles linked list */
326     /* used by get_option */
327     unsigned long option; /* option ID returned by get_option */
328     int argcnt = 0;       /* current argcnt in args */
329     int argnum = 0;       /* arg number */
330     int optchar = 0;      /* option state */
331     char *value = NULL;   /* non-option arg, option value or NULL */
332     int negated = 0;      /* 1 = option negated */
333     int fna = 0;          /* current first non-opt arg */
334     int optnum = 0;       /* index in table */
335 
336     char **args;               /* copy of argv that can be freed */
337 
338 #ifdef THEOS
339     setlocale(LC_CTYPE, "I");
340 #endif
341 
342 #ifdef UNICODE_SUPPORT
343 # ifdef UNIX
344   /* For Unix, set the locale to UTF-8.  Any UTF-8 locale is
345      OK and they should all be the same.  This allows seeing,
346      writing, and displaying (if the fonts are loaded) all
347      characters in UTF-8. */
348   {
349     char *loc;
350 
351     /*
352       loc = setlocale(LC_CTYPE, NULL);
353       printf("  Initial language locale = '%s'\n", loc);
354     */
355 
356     loc = setlocale(LC_CTYPE, "en_US.UTF-8");
357 
358     /*
359       printf("langinfo %s\n", nl_langinfo(CODESET));
360     */
361 
362     if (loc != NULL) {
363       /* using UTF-8 character set so can set UTF-8 GPBF bit 11 */
364       using_utf8 = 1;
365       /*
366         printf("  Locale set to %s\n", loc);
367       */
368     } else {
369       /*
370         printf("  Could not set Unicode UTF-8 locale\n");
371       */
372     }
373   }
374 # endif
375 #endif
376 
377     /* If no args, show help */
378     if (argc == 1) {
379         help();
380         EXIT(ZE_OK);
381     }
382 
383     /* Informational messages are written to stdout. */
384     mesg = stdout;
385 
386     init_upper();               /* build case map table */
387 
388     crc_32_tab = get_crc_table();
389                                 /* initialize crc table for crypt */
390 
391     /* Go through args */
392     zipfile = tempzip = NULL;
393     tempzf = NULL;
394 #ifdef SIGINT
395     signal(SIGINT, handler);
396 #endif
397 #ifdef SIGTERM                  /* Some don't have SIGTERM */
398     signal(SIGTERM, handler);
399 #endif
400 #ifdef SIGABRT
401     signal(SIGABRT, handler);
402 #endif
403 #ifdef SIGBREAK
404     signal(SIGBREAK, handler);
405 #endif
406 #ifdef SIGBUS
407     signal(SIGBUS, handler);
408 #endif
409 #ifdef SIGILL
410     signal(SIGILL, handler);
411 #endif
412 #ifdef SIGSEGV
413     signal(SIGSEGV, handler);
414 #endif
415     temp_path = decrypt = 0;
416 #if 0
417     /* old command line */
418     for (r = 1; r < argc; r++) {
419         if (*argv[r] == '-') {
420             if (!argv[r][1]) ziperr(ZE_PARMS, "zip file cannot be stdin");
421             for (q = argv[r]+1; *q; q++) {
422                 switch (*q) {
423                 case 'b':   /* Specify path for temporary file */
424                     if (temp_path) {
425                         ziperr(ZE_PARMS, "use -b before zip file name");
426                     }
427                     temp_path = 1;          /* Next non-option is path */
428                     break;
429                 case 'd':
430                     decrypt = 1;  break;
431                 case 'h':   /* Show help */
432                     help();
433                     EXIT(ZE_OK);
434                 case 'l': case 'L':  /* Show copyright and disclaimer */
435                     license();
436                     EXIT(ZE_OK);
437                 case 'q':   /* Quiet operation, suppress info messages */
438                     noisy = 0;  break;
439                 case 'v':   /* Show version info */
440                     version_info();
441                     EXIT(ZE_OK);
442                 default:
443                     ziperr(ZE_PARMS, "unknown option");
444                 } /* switch */
445             } /* for */
446 
447         } else if (temp_path == 0) {
448             if (zipfile != NULL) {
449                 ziperr(ZE_PARMS, "can only specify one zip file");
450 
451             } else if ((zipfile = ziptyp(argv[r])) == NULL) {
452                 ziperr(ZE_MEM, "was processing arguments");
453             }
454         } else {
455             tempath = argv[r];
456             temp_path = 0;
457         } /* if */
458     } /* for */
459 
460 #else
461 
462     /* new command line */
463 
464     zipfile = NULL;
465     out_path = NULL;
466 
467     /* make copy of args that can use with insert_arg() */
468     args = copy_args(argv, 0);
469 
470     /*
471     -------------------------------------------
472     Process command line using get_option
473     -------------------------------------------
474 
475     Each call to get_option() returns either a command
476     line option and possible value or a non-option argument.
477     Arguments are permuted so that all options (-r, -b temp)
478     are returned before non-option arguments (zipfile).
479     Returns 0 when nothing left to read.
480     */
481 
482     /* set argnum = 0 on first call to init get_option */
483     argnum = 0;
484 
485     /* get_option returns the option ID and updates parameters:
486            args    - usually same as argv if no argument file support
487            argcnt  - current argc for args
488            value   - char* to value (free() when done with it) or NULL if no value
489            negated - option was negated with trailing -
490     */
491 
492     while ((option = get_option(&args, &argcnt, &argnum,
493                                 &optchar, &value, &negated,
494                                 &fna, &optnum, 0)))
495     {
496       switch (option)
497       {
498         case 'b':   /* Specify path for temporary file */
499           if (temp_path) {
500             ziperr(ZE_PARMS, "more than one temp_path");
501           }
502           temp_path = 1;
503           tempath = value;
504           break;
505         case 'd':
506           decrypt = 1;  break;
507         case 'h':   /* Show help */
508           help();
509           EXIT(ZE_OK);
510         case 'l': case 'L':  /* Show copyright and disclaimer */
511           license();
512           EXIT(ZE_OK);
513         case 'O':   /* Output to new zip file instead of updating original zip file */
514           if ((out_path = ziptyp(value)) == NULL) {
515             ziperr(ZE_MEM, "was processing arguments");
516           }
517           free(value);
518           break;
519         case 'q':   /* Quiet operation, suppress info messages */
520           noisy = 0;  break;
521         case 'v':   /* Show version info */
522           version_info();
523           EXIT(ZE_OK);
524         case o_NON_OPTION_ARG:
525           /* not an option */
526           /* no more options as permuting */
527           /* just dash also ends up here */
528 
529           if (strcmp(value, "-") == 0) {
530             ziperr(ZE_PARMS, "zip file cannot be stdin");
531           } else if (zipfile != NULL) {
532             ziperr(ZE_PARMS, "can only specify one zip file");
533           }
534 
535           if ((zipfile = ziptyp(value)) == NULL) {
536             ziperr(ZE_MEM, "was processing arguments");
537           }
538           free(value);
539           break;
540 
541         default:
542           ziperr(ZE_PARMS, "unknown option");
543       }
544     }
545 
546     free_args(args);
547 
548 #endif
549 
550     if (zipfile == NULL) ziperr(ZE_PARMS, "need to specify zip file");
551 
552     /* in_path is the input zip file */
553     if ((in_path = malloc(strlen(zipfile) + 1)) == NULL) {
554       ziperr(ZE_MEM, "input");
555     }
556     strcpy(in_path, zipfile);
557 
558     /* out_path defaults to in_path */
559     if (out_path == NULL) {
560       if ((out_path = malloc(strlen(zipfile) + 1)) == NULL) {
561         ziperr(ZE_MEM, "output");
562       }
563       strcpy(out_path, zipfile);
564     }
565 
566     /* Read zip file */
567     if ((res = readzipfile()) != ZE_OK) ziperr(res, zipfile);
568     if (zfiles == NULL) ziperr(ZE_NAME, zipfile);
569 
570     /* Check for something to do */
571     for (z = zfiles; z != NULL; z = z->nxt) {
572         if (decrypt ? z->flg & 1 : !(z->flg & 1)) break;
573     }
574     if (z == NULL) {
575         ziperr(ZE_NONE, decrypt ? "no encrypted files"
576                        : "all files encrypted already");
577     }
578 
579     /* Before we get carried away, make sure zip file is writeable */
580     if ((inzip = fopen(zipfile, "a")) == NULL) ziperr(ZE_CREAT, zipfile);
581     fclose(inzip);
582     attr = getfileattr(zipfile);
583 
584     /* Open output zip file for writing */
585 #if defined(UNIX) && !defined(NO_MKSTEMP)
586     {
587       int yd;
588       int i;
589 
590       /* use mkstemp to avoid race condition and compiler warning */
591 
592       if (tempath != NULL)
593       {
594         /* if -b used to set temp file dir use that for split temp */
595         if ((tempzip = malloc(strlen(tempath) + 12)) == NULL) {
596           ZIPERR(ZE_MEM, "allocating temp filename");
597         }
598         strcpy(tempzip, tempath);
599         if (lastchar(tempzip) != '/')
600           strcat(tempzip, "/");
601       }
602       else
603       {
604         /* create path by stripping name and appending template */
605         if ((tempzip = malloc(strlen(zipfile) + 12)) == NULL) {
606         ZIPERR(ZE_MEM, "allocating temp filename");
607         }
608         strcpy(tempzip, zipfile);
609         for(i = strlen(tempzip); i > 0; i--) {
610           if (tempzip[i - 1] == '/')
611             break;
612         }
613         tempzip[i] = '\0';
614       }
615       strcat(tempzip, "ziXXXXXX");
616 
617       if ((yd = mkstemp(tempzip)) == EOF) {
618         ZIPERR(ZE_TEMP, tempzip);
619       }
620       if ((y = tempzf = outzip = fdopen(yd, FOPW_TMP)) == NULL) {
621         ZIPERR(ZE_TEMP, tempzip);
622       }
623     }
624 #else
625     if ((y = tempzf = outzip = fopen(tempzip = tempname(zipfile), FOPW)) == NULL) {
626         ziperr(ZE_TEMP, tempzip);
627     }
628 #endif
629 
630     /* Get password */
631     if (getp("Enter password: ", passwd, IZ_PWLEN+1) == NULL)
632         ziperr(ZE_PARMS,
633                "stderr is not a tty (you may never see this message!)");
634 
635     if (decrypt == 0) {
636         if (getp("Verify password: ", verify, IZ_PWLEN+1) == NULL)
637                ziperr(ZE_PARMS,
638                       "stderr is not a tty (you may never see this message!)");
639 
640         if (strcmp(passwd, verify))
641                ziperr(ZE_PARMS, "password verification failed");
642 
643         if (*passwd == '\0')
644                ziperr(ZE_PARMS, "zero length password not allowed");
645     }
646 
647     /* Open input zip file again, copy preamble if any */
648     if ((in_file = fopen(zipfile, FOPR)) == NULL) ziperr(ZE_NAME, zipfile);
649 
650     if (zipbeg && (res = bfcopy(zipbeg)) != ZE_OK)
651     {
652         ziperr(res, res == ZE_TEMP ? tempzip : zipfile);
653     }
654     tempzn = zipbeg;
655 
656     /* Go through local entries, copying, encrypting, or decrypting */
657     for (z = zfiles; z != NULL; z = z->nxt) {
658         if (decrypt && (z->flg & 1)) {
659             printf("decrypting: %s", z->zname);
660             fflush(stdout);
661             if ((res = zipbare(z, passwd)) != ZE_OK)
662             {
663                 if (res != ZE_MISS) ziperr(res, "was decrypting an entry");
664                 printf(" (wrong password--just copying)");
665                 fflush(stdout);
666             }
667             putchar('\n');
668 
669         } else if ((!decrypt) && !(z->flg & 1)) {
670             printf("encrypting: %s\n", z->zname);
671             fflush(stdout);
672             if ((res = zipcloak(z, passwd)) != ZE_OK)
673             {
674                 ziperr(res, "was encrypting an entry");
675             }
676         } else {
677             printf("   copying: %s\n", z->zname);
678             fflush(stdout);
679             if ((res = zipcopy(z)) != ZE_OK)
680             {
681                 ziperr(res, "was copying an entry");
682             }
683         } /* if */
684     } /* for */
685 
686     fclose(in_file);
687 
688 
689     /* Write central directory and end of central directory */
690 
691     /* get start of central */
692     if ((start_offset = zftello(outzip)) == (zoff_t)-1)
693         ziperr(ZE_TEMP, tempzip);
694 
695     for (z = zfiles; z != NULL; z = z->nxt) {
696         if ((res = putcentral(z)) != ZE_OK) ziperr(res, tempzip);
697     }
698 
699     /* get end of central */
700     if ((length = zftello(outzip)) == (zoff_t)-1)
701         ziperr(ZE_TEMP, tempzip);
702 
703     length -= start_offset;               /* compute length of central */
704     if ((res = putend((zoff_t)zcount, length, start_offset, zcomlen,
705                       zcomment)) != ZE_OK) {
706         ziperr(res, tempzip);
707     }
708     tempzf = NULL;
709     if (fclose(outzip)) ziperr(ZE_TEMP, tempzip);
710     if ((res = replace(out_path, tempzip)) != ZE_OK) {
711         zipwarn("new zip file left as: ", tempzip);
712         free((zvoid *)tempzip);
713         tempzip = NULL;
714         ziperr(res, "was replacing the original zip file");
715     }
716     free((zvoid *)tempzip);
717     tempzip = NULL;
718     setfileattr(zipfile, attr);
719 #ifdef RISCOS
720     /* Set the filetype of the zipfile to &DDC */
721     setfiletype(zipfile, 0xDDC);
722 #endif
723     free((zvoid *)in_path);
724     free((zvoid *)out_path);
725 
726     free((zvoid *)zipfile);
727     zipfile = NULL;
728 
729     /* Done! */
730     RETURN(0);
731 }
732 #else /* !CRYPT */
733 
734 
735 /* below is only used if crypt is not enabled */
736 
737 struct option_struct far options[] = {
738   /* short longopt        value_type        negatable        ID    name */
739     {"h",  "help",        o_NO_VALUE,       o_NOT_NEGATABLE, 'h',  "help"},
740     /* the end of the list */
741     {NULL, NULL,          o_NO_VALUE,       o_NOT_NEGATABLE, 0,    NULL} /* end has option_ID = 0 */
742   };
743 
744 
745 int main OF((void));
746 
zipwarn(msg1,msg2)747 void zipwarn(msg1, msg2)
748 ZCONST char  *msg1, *msg2;
749 {
750     /* Tell picky compilers to shut up about unused variables */
751     msg1 = msg1; msg2 = msg2;
752 }
753 
ziperr(c,h)754 void ziperr(c, h)
755 int  c;
756 ZCONST char *h;
757 {
758     /* Tell picky compilers to shut up about unused variables */
759     c = c; h = h;
760 }
761 
main()762 int main()
763 {
764     fprintf(mesg, "\
765 This version of ZipCloak does not support encryption.  Get the current Zip\n\
766 source distribution and recompile ZipCloak after you have added an option to\n\
767 define the symbol USE_CRYPT to the C compiler's command arguments.\n");
768     RETURN(1);
769 }
770 
771 #endif /* ?CRYPT */
772