1 /*
2 Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
3
4 See the accompanying file LICENSE, version 2000-Apr-09 or later
5 (the contents of which are also included in unzip.h) for terms of use.
6 If, for some reason, all these files are missing, the Info-ZIP license
7 also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
8 */
9 /*
10 * makesfx - Makes a QDOS sfx zip file
11 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
12 * created by Jonathan Hudson, 04/09/95
13 */
14
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <string.h>
18 #include <unistd.h>
19 #include <fcntl.h>
20
21 #define SFXFLAG "??Special Flag for unzipsfx hack ??"
22
23 #ifdef QDOS
24 # include <qdos.h>
25 # define ZMODE (X_OK|R_OK)
26 # define rev_long(x) (x)
27 # define XFLAG 0x4afb
28 #else
29 # define ZMODE (R_OK)
30 # define getchid(p1) p1
31 # include <sys/stat.h>
32 long rev_long(long l);
33 # define XFLAG 0xfb4a
34
35 typedef struct
36 {
37 long id;
38 long dlen;
39 } NTC;
40
41 struct qdirect {
42 long d_length __attribute__ ((packed)); /* file length */
43 unsigned char d_access __attribute__ ((packed)); /* file access type */
44 unsigned char d_type __attribute__ ((packed)); /* file type */
45 long d_datalen __attribute__ ((packed)); /* data length */
46 long d_reserved __attribute__ ((packed));/* Unused */
47 short d_szname __attribute__ ((packed)); /* size of name */
48 char d_name[36] __attribute__ ((packed));/* name area */
49 long d_update __attribute__ ((packed)); /* last update */
50 long d_refdate __attribute__ ((packed));
51 long d_backup __attribute__ ((packed)); /* EOD */
52 } ;
53
fs_headr(int fd,long t,struct qdirect * qs,short size)54 int fs_headr (int fd, long t, struct qdirect *qs, short size)
55 {
56 NTC ntc;
57 int r = -1;
58 struct stat s;
59
60 fstat(fd, &s);
61 qs->d_length = s.st_size;
62 lseek(fd, -8, SEEK_END);
63 read(fd, &ntc, 8);
64 if(ntc.id == *(long *)"XTcc")
65 {
66 qs->d_datalen = ntc.dlen; /* This is big endian */
67 qs->d_type = 1;
68 r = 0;
69 }
70 lseek(fd, 0, 0);
71 return 42; /* why not ??? */
72 }
73
74 typedef unsigned char uch;
75
rev_long(long l)76 long rev_long (long l)
77 {
78 uch cc[4];
79 cc[0] = (uch)(l >> 24);
80 cc[1] = (uch)((l >> 16) & 0xff);
81 cc[2] = (uch)((l >> 8) & 0xff);
82 cc[3] = (uch)(l & 0xff);
83 return *(long *)cc;
84 }
85
86 #endif
87
88 #define RBUFSIZ 4096
89
usage(void)90 void usage(void)
91 {
92 fputs("makesfx -o outfile -z zipfile -xunzipsfx -sstubfile\n", stderr);
93 exit(0);
94 }
95
main(int ac,char ** av)96 int main (int ac, char **av)
97 {
98 int fd, fo;
99 static char local_sig[4] = "PK\003\004";
100 char *p, tmp[4];
101 short ok = 0;
102 char *of = NULL;
103 char *xf = NULL;
104 char *zf = NULL;
105 char *sf = NULL;
106 int c;
107
108 while((c = getopt(ac, av, "o:z:x:s:h")) != EOF)
109 {
110 switch(c)
111 {
112 case 'o':
113 of = optarg;
114 break;
115 case 'z':
116 zf = optarg;
117 break;
118 case 'x':
119 xf = optarg;
120 break;
121 case 's':
122 sf = optarg;
123 break;
124 case 'h':
125 usage();
126 break;
127 }
128 }
129
130
131 if(zf && xf && of && sf)
132 {
133 if((fd = open(zf, O_RDONLY)) > 0)
134 {
135 if((read(fd, tmp, 4) == 4))
136 {
137 if(*(long *)tmp == *(long *)local_sig)
138 {
139 ok = 1;
140 }
141 }
142 close(fd);
143 }
144 if(!ok)
145 {
146 fprintf(stderr,
147 "Huum, %s doesn't look like a ZIP file to me\n", zf);
148 exit(0);
149 }
150
151 if(strstr(xf, "unzipsfx"))
152 {
153 if(access(xf, ZMODE))
154 {
155 fprintf(stderr, "Sorry, don't like the look of %s\n", xf);
156 exit(0);
157 }
158 }
159
160 if((fo = open(of, O_CREAT|O_TRUNC|O_RDWR, 0666)) != -1)
161 {
162 struct qdirect sd,xd;
163 int n;
164 int dsoff = 0;
165 int nfoff = 0;
166 int zlen = 0;
167
168 if((fd = open(sf, O_RDONLY)) != -1)
169 {
170 if(fs_headr(getchid(fd), -1, &sd, sizeof(sd)) > 0)
171 {
172 unsigned short *q;
173 p = malloc(sd.d_length);
174 n = read(fd, p, sd.d_length);
175 for(q = (unsigned short *)p;
176 q != (unsigned short *)(p+sd.d_length); q++)
177 {
178 if(*q == XFLAG && *(q+1) == XFLAG)
179 {
180 dsoff = (int)q-(int)p;
181 break;
182 }
183 }
184 write(fo, p, n);
185 close(fd);
186 }
187 }
188
189 if(dsoff == 0)
190 {
191 puts("Fails");
192
193 exit(0);
194 }
195
196 if((fd = open(xf, O_RDONLY)) != -1)
197 {
198 char *q;
199 if(fs_headr(getchid(fd), -1, &xd, sizeof(xd)) > 0)
200 {
201 p = realloc(p, xd.d_length);
202 n = read(fd, p, xd.d_length);
203 {
204 for(q = p; q < p+xd.d_length ; q++)
205 {
206 if(*q == '?')
207 {
208 if(memcmp(q, SFXFLAG, sizeof(SFXFLAG)-1) == 0)
209 {
210 nfoff = (int)(q-p);
211 break;
212 }
213 }
214 }
215 }
216 write(fo, p, n);
217 close(fd);
218
219 if((fd = open(zf, O_RDONLY)) > 0)
220 {
221 p = realloc(p, RBUFSIZ);
222 while((n = read(fd, p, RBUFSIZ)) > 0)
223 {
224 write(fo, p, n);
225 zlen += n;
226 }
227 close(fd);
228 }
229 lseek(fo, dsoff+4, SEEK_SET);
230 n = rev_long((sd.d_length-dsoff));
231 write(fo, &n, sizeof(long));
232 n = rev_long(xd.d_length);
233 write(fo, &n, sizeof(long));
234 write(fo, &xd.d_datalen, sizeof(long));
235 n = rev_long(nfoff);
236 write(fo, &n, sizeof(long));
237 n = rev_long(zlen);
238 write(fo, &n, sizeof(long));
239 close(fo);
240 }
241 else
242 {
243 close(fd);
244 fputs("Can't read unzipsfx header", stderr);
245 exit(0);
246 }
247 }
248 free(p);
249 }
250 }
251 else
252 usage();
253
254 return 0;
255 }
256