123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256 |
- /*
- Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 2000-Apr-09 or later
- (the contents of which are also included in unzip.h) for terms of use.
- If, for some reason, all these files are missing, the Info-ZIP license
- also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
- */
- /*
- * makesfx - Makes a QDOS sfx zip file
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- * created by Jonathan Hudson, 04/09/95
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <unistd.h>
- #include <fcntl.h>
- #define SFXFLAG "??Special Flag for unzipsfx hack ??"
- #ifdef QDOS
- # include <qdos.h>
- # define ZMODE (X_OK|R_OK)
- # define rev_long(x) (x)
- # define XFLAG 0x4afb
- #else
- # define ZMODE (R_OK)
- # define getchid(p1) p1
- # include <sys/stat.h>
- long rev_long(long l);
- # define XFLAG 0xfb4a
- typedef struct
- {
- long id;
- long dlen;
- } NTC;
- struct qdirect {
- long d_length __attribute__ ((packed)); /* file length */
- unsigned char d_access __attribute__ ((packed)); /* file access type */
- unsigned char d_type __attribute__ ((packed)); /* file type */
- long d_datalen __attribute__ ((packed)); /* data length */
- long d_reserved __attribute__ ((packed));/* Unused */
- short d_szname __attribute__ ((packed)); /* size of name */
- char d_name[36] __attribute__ ((packed));/* name area */
- long d_update __attribute__ ((packed)); /* last update */
- long d_refdate __attribute__ ((packed));
- long d_backup __attribute__ ((packed)); /* EOD */
- } ;
- int fs_headr (int fd, long t, struct qdirect *qs, short size)
- {
- NTC ntc;
- int r = -1;
- struct stat s;
- fstat(fd, &s);
- qs->d_length = s.st_size;
- lseek(fd, -8, SEEK_END);
- read(fd, &ntc, 8);
- if(ntc.id == *(long *)"XTcc")
- {
- qs->d_datalen = ntc.dlen; /* This is big endian */
- qs->d_type = 1;
- r = 0;
- }
- lseek(fd, 0, 0);
- return 42; /* why not ??? */
- }
- typedef unsigned char uch;
- long rev_long (long l)
- {
- uch cc[4];
- cc[0] = (uch)(l >> 24);
- cc[1] = (uch)((l >> 16) & 0xff);
- cc[2] = (uch)((l >> 8) & 0xff);
- cc[3] = (uch)(l & 0xff);
- return *(long *)cc;
- }
- #endif
- #define RBUFSIZ 4096
- void usage(void)
- {
- fputs("makesfx -o outfile -z zipfile -xunzipsfx -sstubfile\n", stderr);
- exit(0);
- }
- int main (int ac, char **av)
- {
- int fd, fo;
- static char local_sig[4] = "PK\003\004";
- char *p, tmp[4];
- short ok = 0;
- char *of = NULL;
- char *xf = NULL;
- char *zf = NULL;
- char *sf = NULL;
- int c;
- while((c = getopt(ac, av, "o:z:x:s:h")) != EOF)
- {
- switch(c)
- {
- case 'o':
- of = optarg;
- break;
- case 'z':
- zf = optarg;
- break;
- case 'x':
- xf = optarg;
- break;
- case 's':
- sf = optarg;
- break;
- case 'h':
- usage();
- break;
- }
- }
- if(zf && xf && of && sf)
- {
- if((fd = open(zf, O_RDONLY)) > 0)
- {
- if((read(fd, tmp, 4) == 4))
- {
- if(*(long *)tmp == *(long *)local_sig)
- {
- ok = 1;
- }
- }
- close(fd);
- }
- if(!ok)
- {
- fprintf(stderr,
- "Huum, %s doesn't look like a ZIP file to me\n", zf);
- exit(0);
- }
- if(strstr(xf, "unzipsfx"))
- {
- if(access(xf, ZMODE))
- {
- fprintf(stderr, "Sorry, don't like the look of %s\n", xf);
- exit(0);
- }
- }
- if((fo = open(of, O_CREAT|O_TRUNC|O_RDWR, 0666)) != -1)
- {
- struct qdirect sd,xd;
- int n;
- int dsoff = 0;
- int nfoff = 0;
- int zlen = 0;
- if((fd = open(sf, O_RDONLY)) != -1)
- {
- if(fs_headr(getchid(fd), -1, &sd, sizeof(sd)) > 0)
- {
- unsigned short *q;
- p = malloc(sd.d_length);
- n = read(fd, p, sd.d_length);
- for(q = (unsigned short *)p;
- q != (unsigned short *)(p+sd.d_length); q++)
- {
- if(*q == XFLAG && *(q+1) == XFLAG)
- {
- dsoff = (int)q-(int)p;
- break;
- }
- }
- write(fo, p, n);
- close(fd);
- }
- }
- if(dsoff == 0)
- {
- puts("Fails");
- exit(0);
- }
- if((fd = open(xf, O_RDONLY)) != -1)
- {
- char *q;
- if(fs_headr(getchid(fd), -1, &xd, sizeof(xd)) > 0)
- {
- p = realloc(p, xd.d_length);
- n = read(fd, p, xd.d_length);
- {
- for(q = p; q < p+xd.d_length ; q++)
- {
- if(*q == '?')
- {
- if(memcmp(q, SFXFLAG, sizeof(SFXFLAG)-1) == 0)
- {
- nfoff = (int)(q-p);
- break;
- }
- }
- }
- }
- write(fo, p, n);
- close(fd);
- if((fd = open(zf, O_RDONLY)) > 0)
- {
- p = realloc(p, RBUFSIZ);
- while((n = read(fd, p, RBUFSIZ)) > 0)
- {
- write(fo, p, n);
- zlen += n;
- }
- close(fd);
- }
- lseek(fo, dsoff+4, SEEK_SET);
- n = rev_long((sd.d_length-dsoff));
- write(fo, &n, sizeof(long));
- n = rev_long(xd.d_length);
- write(fo, &n, sizeof(long));
- write(fo, &xd.d_datalen, sizeof(long));
- n = rev_long(nfoff);
- write(fo, &n, sizeof(long));
- n = rev_long(zlen);
- write(fo, &n, sizeof(long));
- close(fo);
- }
- else
- {
- close(fd);
- fputs("Can't read unzipsfx header", stderr);
- exit(0);
- }
- }
- free(p);
- }
- }
- else
- usage();
- return 0;
- }
|