Blame


1 ff3adf60 2004-04-14 devnull #include <u.h>
2 ff3adf60 2004-04-14 devnull #include <libc.h>
3 ff3adf60 2004-04-14 devnull #include <bio.h>
4 ff3adf60 2004-04-14 devnull #include <flate.h>
5 ff3adf60 2004-04-14 devnull #include "zip.h"
6 ff3adf60 2004-04-14 devnull
7 ff3adf60 2004-04-14 devnull enum
8 ff3adf60 2004-04-14 devnull {
9 ff3adf60 2004-04-14 devnull BufSize = 4096
10 ff3adf60 2004-04-14 devnull };
11 ff3adf60 2004-04-14 devnull
12 ff3adf60 2004-04-14 devnull static int cheader(Biobuf *bin, ZipHead *zh);
13 ff3adf60 2004-04-14 devnull static int copyout(int ofd, Biobuf *bin, long len);
14 ff3adf60 2004-04-14 devnull static int crcwrite(void *ofd, void *buf, int n);
15 ff3adf60 2004-04-14 devnull static int findCDir(Biobuf *bin, char *file);
16 ff3adf60 2004-04-14 devnull static int get1(Biobuf *b);
17 ff3adf60 2004-04-14 devnull static int get2(Biobuf *b);
18 8425b514 2010-02-23 rsc static u32int get4(Biobuf *b);
19 ff3adf60 2004-04-14 devnull static char *getname(Biobuf *b, int len);
20 ff3adf60 2004-04-14 devnull static int header(Biobuf *bin, ZipHead *zh);
21 ff3adf60 2004-04-14 devnull static long msdos2time(int time, int date);
22 ff3adf60 2004-04-14 devnull static int sunzip(Biobuf *bin);
23 ff3adf60 2004-04-14 devnull static int sunztable(Biobuf *bin);
24 ff3adf60 2004-04-14 devnull static void trailer(Biobuf *bin, ZipHead *zh);
25 ff3adf60 2004-04-14 devnull static int unzip(Biobuf *bin, char *file);
26 ff3adf60 2004-04-14 devnull static int unzipEntry(Biobuf *bin, ZipHead *czh);
27 ff3adf60 2004-04-14 devnull static int unztable(Biobuf *bin, char *file);
28 ff3adf60 2004-04-14 devnull static int wantFile(char *file);
29 ff3adf60 2004-04-14 devnull
30 8425b514 2010-02-23 rsc static void *emalloc(u32int);
31 ff3adf60 2004-04-14 devnull static void error(char*, ...);
32 ff3adf60 2004-04-14 devnull /* #pragma varargck argpos error 1 */
33 ff3adf60 2004-04-14 devnull
34 ff3adf60 2004-04-14 devnull static Biobuf bin;
35 8425b514 2010-02-23 rsc static u32int crc;
36 8425b514 2010-02-23 rsc static u32int *crctab;
37 ff3adf60 2004-04-14 devnull static int debug;
38 ff3adf60 2004-04-14 devnull static char *delfile;
39 ff3adf60 2004-04-14 devnull static int lower;
40 ff3adf60 2004-04-14 devnull static int nwant;
41 8425b514 2010-02-23 rsc static u32int rlen;
42 ff3adf60 2004-04-14 devnull static int settimes;
43 ff3adf60 2004-04-14 devnull static int stdout;
44 ff3adf60 2004-04-14 devnull static int verbose;
45 ff3adf60 2004-04-14 devnull static char **want;
46 ff3adf60 2004-04-14 devnull static int wbad;
47 8425b514 2010-02-23 rsc static u32int wlen;
48 ff3adf60 2004-04-14 devnull static jmp_buf zjmp;
49 ff3adf60 2004-04-14 devnull
50 ff3adf60 2004-04-14 devnull static void
51 ff3adf60 2004-04-14 devnull usage(void)
52 ff3adf60 2004-04-14 devnull {
53 ff3adf60 2004-04-14 devnull fprint(2, "usage: unzip [-tsv] [-f zipfile] [file ...]\n");
54 ff3adf60 2004-04-14 devnull exits("usage");
55 ff3adf60 2004-04-14 devnull }
56 ff3adf60 2004-04-14 devnull
57 ff3adf60 2004-04-14 devnull void
58 ff3adf60 2004-04-14 devnull main(int argc, char *argv[])
59 ff3adf60 2004-04-14 devnull {
60 ff3adf60 2004-04-14 devnull char *zfile;
61 ff3adf60 2004-04-14 devnull int fd, ok, table, stream;
62 ff3adf60 2004-04-14 devnull
63 ff3adf60 2004-04-14 devnull table = 0;
64 ff3adf60 2004-04-14 devnull stream = 0;
65 ff3adf60 2004-04-14 devnull zfile = nil;
66 ff3adf60 2004-04-14 devnull ARGBEGIN{
67 ff3adf60 2004-04-14 devnull case 'D':
68 ff3adf60 2004-04-14 devnull debug++;
69 ff3adf60 2004-04-14 devnull break;
70 ff3adf60 2004-04-14 devnull case 'c':
71 ff3adf60 2004-04-14 devnull stdout++;
72 ff3adf60 2004-04-14 devnull break;
73 ff3adf60 2004-04-14 devnull case 'i':
74 ff3adf60 2004-04-14 devnull lower++;
75 ff3adf60 2004-04-14 devnull break;
76 ff3adf60 2004-04-14 devnull case 'f':
77 ff3adf60 2004-04-14 devnull zfile = ARGF();
78 ff3adf60 2004-04-14 devnull if(zfile == nil)
79 ff3adf60 2004-04-14 devnull usage();
80 ff3adf60 2004-04-14 devnull break;
81 ff3adf60 2004-04-14 devnull case 's':
82 ff3adf60 2004-04-14 devnull stream++;
83 ff3adf60 2004-04-14 devnull break;
84 ff3adf60 2004-04-14 devnull case 't':
85 ff3adf60 2004-04-14 devnull table++;
86 ff3adf60 2004-04-14 devnull break;
87 ff3adf60 2004-04-14 devnull case 'T':
88 ff3adf60 2004-04-14 devnull settimes++;
89 ff3adf60 2004-04-14 devnull break;
90 ff3adf60 2004-04-14 devnull case 'v':
91 ff3adf60 2004-04-14 devnull verbose++;
92 ff3adf60 2004-04-14 devnull break;
93 ff3adf60 2004-04-14 devnull default:
94 ff3adf60 2004-04-14 devnull usage();
95 ff3adf60 2004-04-14 devnull break;
96 ff3adf60 2004-04-14 devnull }ARGEND
97 ff3adf60 2004-04-14 devnull
98 ff3adf60 2004-04-14 devnull nwant = argc;
99 ff3adf60 2004-04-14 devnull want = argv;
100 ff3adf60 2004-04-14 devnull
101 ff3adf60 2004-04-14 devnull crctab = mkcrctab(ZCrcPoly);
102 ff3adf60 2004-04-14 devnull ok = inflateinit();
103 ff3adf60 2004-04-14 devnull if(ok != FlateOk)
104 ff3adf60 2004-04-14 devnull sysfatal("inflateinit failed: %s\n", flateerr(ok));
105 ff3adf60 2004-04-14 devnull
106 ff3adf60 2004-04-14 devnull if(zfile == nil){
107 ff3adf60 2004-04-14 devnull Binit(&bin, 0, OREAD);
108 ff3adf60 2004-04-14 devnull zfile = "<stdin>";
109 ff3adf60 2004-04-14 devnull }else{
110 ff3adf60 2004-04-14 devnull fd = open(zfile, OREAD);
111 ff3adf60 2004-04-14 devnull if(fd < 0)
112 ff3adf60 2004-04-14 devnull sysfatal("can't open %s: %r", zfile);
113 ff3adf60 2004-04-14 devnull Binit(&bin, fd, OREAD);
114 ff3adf60 2004-04-14 devnull }
115 ff3adf60 2004-04-14 devnull
116 ff3adf60 2004-04-14 devnull if(table){
117 ff3adf60 2004-04-14 devnull if(stream)
118 ff3adf60 2004-04-14 devnull ok = sunztable(&bin);
119 ff3adf60 2004-04-14 devnull else
120 ff3adf60 2004-04-14 devnull ok = unztable(&bin, zfile);
121 ff3adf60 2004-04-14 devnull }else{
122 ff3adf60 2004-04-14 devnull if(stream)
123 ff3adf60 2004-04-14 devnull ok = sunzip(&bin);
124 ff3adf60 2004-04-14 devnull else
125 ff3adf60 2004-04-14 devnull ok = unzip(&bin, zfile);
126 ff3adf60 2004-04-14 devnull }
127 ff3adf60 2004-04-14 devnull
128 ff3adf60 2004-04-14 devnull exits(ok ? nil: "errors");
129 ff3adf60 2004-04-14 devnull }
130 ff3adf60 2004-04-14 devnull
131 ff3adf60 2004-04-14 devnull /*
132 ff3adf60 2004-04-14 devnull * print the table of contents from the "central directory structure"
133 ff3adf60 2004-04-14 devnull */
134 ff3adf60 2004-04-14 devnull static int
135 ff3adf60 2004-04-14 devnull unztable(Biobuf *bin, char *file)
136 ff3adf60 2004-04-14 devnull {
137 ff3adf60 2004-04-14 devnull ZipHead zh;
138 f7b74c17 2004-12-28 devnull int volatile entries;
139 ff3adf60 2004-04-14 devnull
140 ff3adf60 2004-04-14 devnull entries = findCDir(bin, file);
141 ff3adf60 2004-04-14 devnull if(entries < 0)
142 ff3adf60 2004-04-14 devnull return 0;
143 ff3adf60 2004-04-14 devnull
144 ff3adf60 2004-04-14 devnull if(verbose > 1)
145 ff3adf60 2004-04-14 devnull print("%d items in the archive\n", entries);
146 ff3adf60 2004-04-14 devnull while(entries-- > 0){
147 ff3adf60 2004-04-14 devnull if(setjmp(zjmp)){
148 ff3adf60 2004-04-14 devnull free(zh.file);
149 ff3adf60 2004-04-14 devnull return 0;
150 ff3adf60 2004-04-14 devnull }
151 ff3adf60 2004-04-14 devnull
152 ff3adf60 2004-04-14 devnull memset(&zh, 0, sizeof(zh));
153 ff3adf60 2004-04-14 devnull if(!cheader(bin, &zh))
154 ff3adf60 2004-04-14 devnull return 1;
155 ff3adf60 2004-04-14 devnull
156 ff3adf60 2004-04-14 devnull if(wantFile(zh.file)){
157 ff3adf60 2004-04-14 devnull if(verbose)
158 ff3adf60 2004-04-14 devnull print("%-32s %10lud %s", zh.file, zh.uncsize, ctime(msdos2time(zh.modtime, zh.moddate)));
159 ff3adf60 2004-04-14 devnull else
160 ff3adf60 2004-04-14 devnull print("%s\n", zh.file);
161 ff3adf60 2004-04-14 devnull
162 ff3adf60 2004-04-14 devnull if(verbose > 1){
163 ff3adf60 2004-04-14 devnull print("\tmade by os %d vers %d.%d\n", zh.madeos, zh.madevers/10, zh.madevers % 10);
164 ff3adf60 2004-04-14 devnull print("\textract by os %d vers %d.%d\n", zh.extos, zh.extvers/10, zh.extvers % 10);
165 ff3adf60 2004-04-14 devnull print("\tflags %x\n", zh.flags);
166 ff3adf60 2004-04-14 devnull print("\tmethod %d\n", zh.meth);
167 ff3adf60 2004-04-14 devnull print("\tmod time %d\n", zh.modtime);
168 ff3adf60 2004-04-14 devnull print("\tmod date %d\n", zh.moddate);
169 ff3adf60 2004-04-14 devnull print("\tcrc %lux\n", zh.crc);
170 ff3adf60 2004-04-14 devnull print("\tcompressed size %lud\n", zh.csize);
171 ff3adf60 2004-04-14 devnull print("\tuncompressed size %lud\n", zh.uncsize);
172 ff3adf60 2004-04-14 devnull print("\tinternal attributes %ux\n", zh.iattr);
173 ff3adf60 2004-04-14 devnull print("\texternal attributes %lux\n", zh.eattr);
174 ff3adf60 2004-04-14 devnull print("\tstarts at %ld\n", zh.off);
175 ff3adf60 2004-04-14 devnull }
176 ff3adf60 2004-04-14 devnull }
177 ff3adf60 2004-04-14 devnull
178 ff3adf60 2004-04-14 devnull free(zh.file);
179 ff3adf60 2004-04-14 devnull zh.file = nil;
180 ff3adf60 2004-04-14 devnull }
181 ff3adf60 2004-04-14 devnull
182 ff3adf60 2004-04-14 devnull return 1;
183 ff3adf60 2004-04-14 devnull }
184 ff3adf60 2004-04-14 devnull
185 ff3adf60 2004-04-14 devnull /*
186 ff3adf60 2004-04-14 devnull * print the "local file header" table of contents
187 ff3adf60 2004-04-14 devnull */
188 ff3adf60 2004-04-14 devnull static int
189 ff3adf60 2004-04-14 devnull sunztable(Biobuf *bin)
190 ff3adf60 2004-04-14 devnull {
191 ff3adf60 2004-04-14 devnull ZipHead zh;
192 ff3adf60 2004-04-14 devnull vlong off;
193 8425b514 2010-02-23 rsc u32int hcrc, hcsize, huncsize;
194 ff3adf60 2004-04-14 devnull int ok, err;
195 ff3adf60 2004-04-14 devnull
196 ff3adf60 2004-04-14 devnull ok = 1;
197 ff3adf60 2004-04-14 devnull for(;;){
198 ff3adf60 2004-04-14 devnull if(setjmp(zjmp)){
199 ff3adf60 2004-04-14 devnull free(zh.file);
200 ff3adf60 2004-04-14 devnull return 0;
201 ff3adf60 2004-04-14 devnull }
202 ff3adf60 2004-04-14 devnull
203 ff3adf60 2004-04-14 devnull memset(&zh, 0, sizeof(zh));
204 ff3adf60 2004-04-14 devnull if(!header(bin, &zh))
205 ff3adf60 2004-04-14 devnull return ok;
206 ff3adf60 2004-04-14 devnull
207 ff3adf60 2004-04-14 devnull hcrc = zh.crc;
208 ff3adf60 2004-04-14 devnull hcsize = zh.csize;
209 ff3adf60 2004-04-14 devnull huncsize = zh.uncsize;
210 ff3adf60 2004-04-14 devnull
211 ff3adf60 2004-04-14 devnull wlen = 0;
212 ff3adf60 2004-04-14 devnull rlen = 0;
213 ff3adf60 2004-04-14 devnull crc = 0;
214 ff3adf60 2004-04-14 devnull wbad = 0;
215 ff3adf60 2004-04-14 devnull
216 ff3adf60 2004-04-14 devnull if(zh.meth == 0){
217 ff3adf60 2004-04-14 devnull if(!copyout(-1, bin, zh.csize))
218 ff3adf60 2004-04-14 devnull error("reading data for %s failed: %r", zh.file);
219 ff3adf60 2004-04-14 devnull }else if(zh.meth == 8){
220 ff3adf60 2004-04-14 devnull off = Boffset(bin);
221 ff3adf60 2004-04-14 devnull err = inflate((void*)-1, crcwrite, bin, (int(*)(void*))Bgetc);
222 ff3adf60 2004-04-14 devnull if(err != FlateOk)
223 ff3adf60 2004-04-14 devnull error("inflate %s failed: %s", zh.file, flateerr(err));
224 ff3adf60 2004-04-14 devnull rlen = Boffset(bin) - off;
225 ff3adf60 2004-04-14 devnull }else
226 ff3adf60 2004-04-14 devnull error("can't handle compression method %d for %s", zh.meth, zh.file);
227 ff3adf60 2004-04-14 devnull
228 ff3adf60 2004-04-14 devnull trailer(bin, &zh);
229 ff3adf60 2004-04-14 devnull
230 ff3adf60 2004-04-14 devnull if(wantFile(zh.file)){
231 ff3adf60 2004-04-14 devnull if(verbose)
232 ff3adf60 2004-04-14 devnull print("%-32s %10lud %s", zh.file, zh.uncsize, ctime(msdos2time(zh.modtime, zh.moddate)));
233 ff3adf60 2004-04-14 devnull else
234 ff3adf60 2004-04-14 devnull print("%s\n", zh.file);
235 ff3adf60 2004-04-14 devnull
236 ff3adf60 2004-04-14 devnull if(verbose > 1){
237 ff3adf60 2004-04-14 devnull print("\textract by os %d vers %d.%d\n", zh.extos, zh.extvers / 10, zh.extvers % 10);
238 ff3adf60 2004-04-14 devnull print("\tflags %x\n", zh.flags);
239 ff3adf60 2004-04-14 devnull print("\tmethod %d\n", zh.meth);
240 ff3adf60 2004-04-14 devnull print("\tmod time %d\n", zh.modtime);
241 ff3adf60 2004-04-14 devnull print("\tmod date %d\n", zh.moddate);
242 ff3adf60 2004-04-14 devnull print("\tcrc %lux\n", zh.crc);
243 ff3adf60 2004-04-14 devnull print("\tcompressed size %lud\n", zh.csize);
244 ff3adf60 2004-04-14 devnull print("\tuncompressed size %lud\n", zh.uncsize);
245 ff3adf60 2004-04-14 devnull if((zh.flags & ZTrailInfo) && (hcrc || hcsize || huncsize)){
246 ff3adf60 2004-04-14 devnull print("\theader crc %lux\n", zh.crc);
247 ff3adf60 2004-04-14 devnull print("\theader compressed size %lud\n", zh.csize);
248 ff3adf60 2004-04-14 devnull print("\theader uncompressed size %lud\n", zh.uncsize);
249 ff3adf60 2004-04-14 devnull }
250 ff3adf60 2004-04-14 devnull }
251 ff3adf60 2004-04-14 devnull }
252 ff3adf60 2004-04-14 devnull
253 ff3adf60 2004-04-14 devnull if(zh.crc != crc)
254 ff3adf60 2004-04-14 devnull error("crc mismatch for %s", zh.file);
255 ff3adf60 2004-04-14 devnull if(zh.uncsize != wlen)
256 ff3adf60 2004-04-14 devnull error("output size mismatch for %s", zh.file);
257 ff3adf60 2004-04-14 devnull if(zh.csize != rlen)
258 ff3adf60 2004-04-14 devnull error("input size mismatch for %s", zh.file);
259 ff3adf60 2004-04-14 devnull
260 ff3adf60 2004-04-14 devnull
261 ff3adf60 2004-04-14 devnull free(zh.file);
262 ff3adf60 2004-04-14 devnull zh.file = nil;
263 ff3adf60 2004-04-14 devnull }
264 ff3adf60 2004-04-14 devnull }
265 ff3adf60 2004-04-14 devnull
266 ff3adf60 2004-04-14 devnull /*
267 ff3adf60 2004-04-14 devnull * extract files using the info in the central directory structure
268 ff3adf60 2004-04-14 devnull */
269 ff3adf60 2004-04-14 devnull static int
270 ff3adf60 2004-04-14 devnull unzip(Biobuf *bin, char *file)
271 ff3adf60 2004-04-14 devnull {
272 ff3adf60 2004-04-14 devnull ZipHead zh;
273 ff3adf60 2004-04-14 devnull vlong off;
274 f7b74c17 2004-12-28 devnull int volatile ok, eok, entries;
275 ff3adf60 2004-04-14 devnull
276 ff3adf60 2004-04-14 devnull entries = findCDir(bin, file);
277 ff3adf60 2004-04-14 devnull if(entries < 0)
278 ff3adf60 2004-04-14 devnull return 0;
279 ff3adf60 2004-04-14 devnull
280 ff3adf60 2004-04-14 devnull ok = 1;
281 ff3adf60 2004-04-14 devnull while(entries-- > 0){
282 ff3adf60 2004-04-14 devnull if(setjmp(zjmp)){
283 ff3adf60 2004-04-14 devnull free(zh.file);
284 ff3adf60 2004-04-14 devnull return 0;
285 ff3adf60 2004-04-14 devnull }
286 ff3adf60 2004-04-14 devnull memset(&zh, 0, sizeof(zh));
287 ff3adf60 2004-04-14 devnull if(!cheader(bin, &zh))
288 ff3adf60 2004-04-14 devnull return ok;
289 ff3adf60 2004-04-14 devnull
290 ff3adf60 2004-04-14 devnull
291 ff3adf60 2004-04-14 devnull off = Boffset(bin);
292 ff3adf60 2004-04-14 devnull if(wantFile(zh.file)){
293 ff3adf60 2004-04-14 devnull if(Bseek(bin, zh.off, 0) < 0){
294 ff3adf60 2004-04-14 devnull fprint(2, "unzip: can't seek to start of %s, skipping\n", zh.file);
295 ff3adf60 2004-04-14 devnull ok = 0;
296 ff3adf60 2004-04-14 devnull }else{
297 ff3adf60 2004-04-14 devnull eok = unzipEntry(bin, &zh);
298 ff3adf60 2004-04-14 devnull if(eok <= 0){
299 ff3adf60 2004-04-14 devnull fprint(2, "unzip: skipping %s\n", zh.file);
300 ff3adf60 2004-04-14 devnull ok = 0;
301 ff3adf60 2004-04-14 devnull }
302 ff3adf60 2004-04-14 devnull }
303 ff3adf60 2004-04-14 devnull }
304 ff3adf60 2004-04-14 devnull
305 ff3adf60 2004-04-14 devnull free(zh.file);
306 ff3adf60 2004-04-14 devnull zh.file = nil;
307 ff3adf60 2004-04-14 devnull
308 ff3adf60 2004-04-14 devnull if(Bseek(bin, off, 0) < 0){
309 ff3adf60 2004-04-14 devnull fprint(2, "unzip: can't seek to start of next entry, terminating extraction\n");
310 ff3adf60 2004-04-14 devnull return 0;
311 ff3adf60 2004-04-14 devnull }
312 ff3adf60 2004-04-14 devnull }
313 ff3adf60 2004-04-14 devnull
314 ff3adf60 2004-04-14 devnull return ok;
315 ff3adf60 2004-04-14 devnull }
316 ff3adf60 2004-04-14 devnull
317 ff3adf60 2004-04-14 devnull /*
318 ff3adf60 2004-04-14 devnull * extract files using the info the "local file headers"
319 ff3adf60 2004-04-14 devnull */
320 ff3adf60 2004-04-14 devnull static int
321 ff3adf60 2004-04-14 devnull sunzip(Biobuf *bin)
322 ff3adf60 2004-04-14 devnull {
323 ff3adf60 2004-04-14 devnull int eok;
324 ff3adf60 2004-04-14 devnull
325 ff3adf60 2004-04-14 devnull for(;;){
326 ff3adf60 2004-04-14 devnull eok = unzipEntry(bin, nil);
327 ff3adf60 2004-04-14 devnull if(eok == 0)
328 ff3adf60 2004-04-14 devnull return 1;
329 ff3adf60 2004-04-14 devnull if(eok < 0)
330 ff3adf60 2004-04-14 devnull return 0;
331 f8d580d8 2005-02-21 devnull }
332 f8d580d8 2005-02-21 devnull }
333 f8d580d8 2005-02-21 devnull
334 f8d580d8 2005-02-21 devnull static int
335 f8d580d8 2005-02-21 devnull makedir(char *s)
336 f8d580d8 2005-02-21 devnull {
337 f8d580d8 2005-02-21 devnull int f;
338 f8d580d8 2005-02-21 devnull
339 f8d580d8 2005-02-21 devnull if (access(s, AEXIST) == 0)
340 f8d580d8 2005-02-21 devnull return -1;
341 f8d580d8 2005-02-21 devnull f = create(s, OREAD, DMDIR | 0777);
342 f8d580d8 2005-02-21 devnull if (f >= 0)
343 f8d580d8 2005-02-21 devnull close(f);
344 f8d580d8 2005-02-21 devnull return f;
345 f8d580d8 2005-02-21 devnull }
346 f8d580d8 2005-02-21 devnull
347 f8d580d8 2005-02-21 devnull static void
348 f8d580d8 2005-02-21 devnull mkpdirs(char *s)
349 f8d580d8 2005-02-21 devnull {
350 f8d580d8 2005-02-21 devnull int done = 0;
351 f8d580d8 2005-02-21 devnull char *p = s;
352 f8d580d8 2005-02-21 devnull
353 f8d580d8 2005-02-21 devnull while (!done && (p = strchr(p + 1, '/')) != nil) {
354 f8d580d8 2005-02-21 devnull *p = '\0';
355 f8d580d8 2005-02-21 devnull done = (access(s, AEXIST) < 0 && makedir(s) < 0);
356 f8d580d8 2005-02-21 devnull *p = '/';
357 ff3adf60 2004-04-14 devnull }
358 ff3adf60 2004-04-14 devnull }
359 ff3adf60 2004-04-14 devnull
360 ff3adf60 2004-04-14 devnull /*
361 ff3adf60 2004-04-14 devnull * extracts a single entry from a zip file
362 ff3adf60 2004-04-14 devnull * czh is the optional corresponding central directory entry
363 ff3adf60 2004-04-14 devnull */
364 ff3adf60 2004-04-14 devnull static int
365 ff3adf60 2004-04-14 devnull unzipEntry(Biobuf *bin, ZipHead *czh)
366 ff3adf60 2004-04-14 devnull {
367 ff3adf60 2004-04-14 devnull Dir *d;
368 ff3adf60 2004-04-14 devnull ZipHead zh;
369 ff3adf60 2004-04-14 devnull char *p;
370 ff3adf60 2004-04-14 devnull vlong off;
371 ff3adf60 2004-04-14 devnull int fd, isdir, ok, err;
372 ff3adf60 2004-04-14 devnull
373 ff3adf60 2004-04-14 devnull zh.file = nil;
374 ff3adf60 2004-04-14 devnull if(setjmp(zjmp)){
375 ff3adf60 2004-04-14 devnull delfile = nil;
376 ff3adf60 2004-04-14 devnull free(zh.file);
377 ff3adf60 2004-04-14 devnull return -1;
378 ff3adf60 2004-04-14 devnull }
379 ff3adf60 2004-04-14 devnull
380 ff3adf60 2004-04-14 devnull memset(&zh, 0, sizeof(zh));
381 ff3adf60 2004-04-14 devnull if(!header(bin, &zh))
382 ff3adf60 2004-04-14 devnull return 0;
383 ff3adf60 2004-04-14 devnull
384 ff3adf60 2004-04-14 devnull ok = 1;
385 ff3adf60 2004-04-14 devnull isdir = 0;
386 ff3adf60 2004-04-14 devnull
387 ff3adf60 2004-04-14 devnull fd = -1;
388 ff3adf60 2004-04-14 devnull if(wantFile(zh.file)){
389 ff3adf60 2004-04-14 devnull if(verbose)
390 ff3adf60 2004-04-14 devnull fprint(2, "extracting %s\n", zh.file);
391 ff3adf60 2004-04-14 devnull
392 ff3adf60 2004-04-14 devnull if(czh != nil && czh->extos == ZDos){
393 ff3adf60 2004-04-14 devnull isdir = czh->eattr & ZDDir;
394 ff3adf60 2004-04-14 devnull if(isdir && zh.uncsize != 0)
395 ff3adf60 2004-04-14 devnull fprint(2, "unzip: ignoring directory data for %s\n", zh.file);
396 ff3adf60 2004-04-14 devnull }
397 ff3adf60 2004-04-14 devnull if(zh.meth == 0 && zh.uncsize == 0){
398 ff3adf60 2004-04-14 devnull p = strchr(zh.file, '\0');
399 ff3adf60 2004-04-14 devnull if(p > zh.file && p[-1] == '/')
400 ff3adf60 2004-04-14 devnull isdir = 1;
401 ff3adf60 2004-04-14 devnull }
402 ff3adf60 2004-04-14 devnull
403 ff3adf60 2004-04-14 devnull if(stdout){
404 ff3adf60 2004-04-14 devnull if(ok && !isdir)
405 ff3adf60 2004-04-14 devnull fd = 1;
406 ff3adf60 2004-04-14 devnull }else if(isdir){
407 ff3adf60 2004-04-14 devnull fd = create(zh.file, OREAD, DMDIR | 0775);
408 f8d580d8 2005-02-21 devnull if(fd < 0){
409 f8d580d8 2005-02-21 devnull mkpdirs(zh.file);
410 f8d580d8 2005-02-21 devnull fd = create(zh.file, OREAD, DMDIR | 0775);
411 f8d580d8 2005-02-21 devnull }
412 ff3adf60 2004-04-14 devnull if(fd < 0){
413 ff3adf60 2004-04-14 devnull d = dirstat(zh.file);
414 ff3adf60 2004-04-14 devnull if(d == nil || (d->mode & DMDIR) != DMDIR){
415 ff3adf60 2004-04-14 devnull fprint(2, "unzip: can't create directory %s: %r\n", zh.file);
416 ff3adf60 2004-04-14 devnull ok = 0;
417 ff3adf60 2004-04-14 devnull }
418 ff3adf60 2004-04-14 devnull free(d);
419 ff3adf60 2004-04-14 devnull }
420 ff3adf60 2004-04-14 devnull }else if(ok){
421 ff3adf60 2004-04-14 devnull fd = create(zh.file, OWRITE, 0664);
422 f8d580d8 2005-02-21 devnull if(fd < 0){
423 f8d580d8 2005-02-21 devnull mkpdirs(zh.file);
424 f8d580d8 2005-02-21 devnull fd = create(zh.file, OWRITE, 0664);
425 f8d580d8 2005-02-21 devnull }
426 ff3adf60 2004-04-14 devnull if(fd < 0){
427 ff3adf60 2004-04-14 devnull fprint(2, "unzip: can't create %s: %r\n", zh.file);
428 ff3adf60 2004-04-14 devnull ok = 0;
429 ff3adf60 2004-04-14 devnull }else
430 ff3adf60 2004-04-14 devnull delfile = zh.file;
431 ff3adf60 2004-04-14 devnull }
432 ff3adf60 2004-04-14 devnull }
433 ff3adf60 2004-04-14 devnull
434 ff3adf60 2004-04-14 devnull wlen = 0;
435 ff3adf60 2004-04-14 devnull rlen = 0;
436 ff3adf60 2004-04-14 devnull crc = 0;
437 ff3adf60 2004-04-14 devnull wbad = 0;
438 ff3adf60 2004-04-14 devnull
439 ff3adf60 2004-04-14 devnull if(zh.meth == 0){
440 ff3adf60 2004-04-14 devnull if(!copyout(fd, bin, zh.csize))
441 ff3adf60 2004-04-14 devnull error("copying data for %s failed: %r", zh.file);
442 ff3adf60 2004-04-14 devnull }else if(zh.meth == 8){
443 ff3adf60 2004-04-14 devnull off = Boffset(bin);
444 3ca675a5 2006-04-20 devnull err = inflate((void*)(uintptr)fd, crcwrite, bin, (int(*)(void*))Bgetc);
445 ff3adf60 2004-04-14 devnull if(err != FlateOk)
446 ff3adf60 2004-04-14 devnull error("inflate failed: %s", flateerr(err));
447 ff3adf60 2004-04-14 devnull rlen = Boffset(bin) - off;
448 ff3adf60 2004-04-14 devnull }else
449 ff3adf60 2004-04-14 devnull error("can't handle compression method %d for %s", zh.meth, zh.file);
450 ff3adf60 2004-04-14 devnull
451 ff3adf60 2004-04-14 devnull trailer(bin, &zh);
452 ff3adf60 2004-04-14 devnull
453 ff3adf60 2004-04-14 devnull if(zh.crc != crc)
454 ff3adf60 2004-04-14 devnull error("crc mismatch for %s", zh.file);
455 ff3adf60 2004-04-14 devnull if(zh.uncsize != wlen)
456 ff3adf60 2004-04-14 devnull error("output size mismatch for %s", zh.file);
457 ff3adf60 2004-04-14 devnull if(zh.csize != rlen)
458 ff3adf60 2004-04-14 devnull error("input size mismatch for %s", zh.file);
459 ff3adf60 2004-04-14 devnull
460 ff3adf60 2004-04-14 devnull delfile = nil;
461 ff3adf60 2004-04-14 devnull free(zh.file);
462 ff3adf60 2004-04-14 devnull
463 ff3adf60 2004-04-14 devnull if(fd >= 0 && !stdout){
464 ff3adf60 2004-04-14 devnull if(settimes){
465 ff3adf60 2004-04-14 devnull d = dirfstat(fd);
466 ff3adf60 2004-04-14 devnull if(d != nil){
467 ff3adf60 2004-04-14 devnull d->mtime = msdos2time(zh.modtime, zh.moddate);
468 ff3adf60 2004-04-14 devnull if(d->mtime)
469 ff3adf60 2004-04-14 devnull dirfwstat(fd, d);
470 ff3adf60 2004-04-14 devnull }
471 ff3adf60 2004-04-14 devnull }
472 ff3adf60 2004-04-14 devnull close(fd);
473 ff3adf60 2004-04-14 devnull }
474 ff3adf60 2004-04-14 devnull
475 ff3adf60 2004-04-14 devnull return ok;
476 ff3adf60 2004-04-14 devnull }
477 ff3adf60 2004-04-14 devnull
478 ff3adf60 2004-04-14 devnull static int
479 ff3adf60 2004-04-14 devnull wantFile(char *file)
480 ff3adf60 2004-04-14 devnull {
481 ff3adf60 2004-04-14 devnull int i, n;
482 ff3adf60 2004-04-14 devnull
483 ff3adf60 2004-04-14 devnull if(nwant == 0)
484 ff3adf60 2004-04-14 devnull return 1;
485 ff3adf60 2004-04-14 devnull for(i = 0; i < nwant; i++){
486 ff3adf60 2004-04-14 devnull if(strcmp(want[i], file) == 0)
487 ff3adf60 2004-04-14 devnull return 1;
488 ff3adf60 2004-04-14 devnull n = strlen(want[i]);
489 ff3adf60 2004-04-14 devnull if(strncmp(want[i], file, n) == 0 && file[n] == '/')
490 ff3adf60 2004-04-14 devnull return 1;
491 ff3adf60 2004-04-14 devnull }
492 ff3adf60 2004-04-14 devnull return 0;
493 ff3adf60 2004-04-14 devnull }
494 ff3adf60 2004-04-14 devnull
495 ff3adf60 2004-04-14 devnull /*
496 ff3adf60 2004-04-14 devnull * find the start of the central directory
497 ff3adf60 2004-04-14 devnull * returns the number of entries in the directory,
498 ff3adf60 2004-04-14 devnull * or -1 if there was an error
499 ff3adf60 2004-04-14 devnull */
500 ff3adf60 2004-04-14 devnull static int
501 ff3adf60 2004-04-14 devnull findCDir(Biobuf *bin, char *file)
502 ff3adf60 2004-04-14 devnull {
503 ff3adf60 2004-04-14 devnull vlong ecoff;
504 ff3adf60 2004-04-14 devnull long off, size;
505 ff3adf60 2004-04-14 devnull int entries, zclen, dn, ds, de;
506 ff3adf60 2004-04-14 devnull
507 ff3adf60 2004-04-14 devnull ecoff = Bseek(bin, -ZECHeadSize, 2);
508 ff3adf60 2004-04-14 devnull if(ecoff < 0){
509 ff3adf60 2004-04-14 devnull fprint(2, "unzip: can't seek to contents of %s; try adding -s\n", file);
510 ff3adf60 2004-04-14 devnull return -1;
511 ff3adf60 2004-04-14 devnull }
512 ff3adf60 2004-04-14 devnull if(setjmp(zjmp))
513 ff3adf60 2004-04-14 devnull return -1;
514 ff3adf60 2004-04-14 devnull
515 ff3adf60 2004-04-14 devnull if(get4(bin) != ZECHeader){
516 ff3adf60 2004-04-14 devnull fprint(2, "unzip: bad magic number for contents of %s\n", file);
517 ff3adf60 2004-04-14 devnull return -1;
518 ff3adf60 2004-04-14 devnull }
519 ff3adf60 2004-04-14 devnull dn = get2(bin);
520 ff3adf60 2004-04-14 devnull ds = get2(bin);
521 ff3adf60 2004-04-14 devnull de = get2(bin);
522 ff3adf60 2004-04-14 devnull entries = get2(bin);
523 ff3adf60 2004-04-14 devnull size = get4(bin);
524 ff3adf60 2004-04-14 devnull off = get4(bin);
525 ff3adf60 2004-04-14 devnull zclen = get2(bin);
526 ff3adf60 2004-04-14 devnull while(zclen-- > 0)
527 ff3adf60 2004-04-14 devnull get1(bin);
528 ff3adf60 2004-04-14 devnull
529 ff3adf60 2004-04-14 devnull if(verbose > 1){
530 ff3adf60 2004-04-14 devnull print("table starts at %ld for %ld bytes\n", off, size);
531 ff3adf60 2004-04-14 devnull if(ecoff - size != off)
532 ff3adf60 2004-04-14 devnull print("\ttable should start at %lld-%ld=%lld\n", ecoff, size, ecoff-size);
533 ff3adf60 2004-04-14 devnull if(dn || ds || de != entries)
534 ff3adf60 2004-04-14 devnull print("\tcurrent disk=%d start disk=%d table entries on this disk=%d\n", dn, ds, de);
535 ff3adf60 2004-04-14 devnull }
536 ff3adf60 2004-04-14 devnull
537 ff3adf60 2004-04-14 devnull if(Bseek(bin, off, 0) != off){
538 ff3adf60 2004-04-14 devnull fprint(2, "unzip: can't seek to start of contents of %s\n", file);
539 ff3adf60 2004-04-14 devnull return -1;
540 ff3adf60 2004-04-14 devnull }
541 ff3adf60 2004-04-14 devnull
542 ff3adf60 2004-04-14 devnull return entries;
543 ff3adf60 2004-04-14 devnull }
544 ff3adf60 2004-04-14 devnull
545 ff3adf60 2004-04-14 devnull static int
546 ff3adf60 2004-04-14 devnull cheader(Biobuf *bin, ZipHead *zh)
547 ff3adf60 2004-04-14 devnull {
548 8425b514 2010-02-23 rsc u32int v;
549 ff3adf60 2004-04-14 devnull int flen, xlen, fclen;
550 ff3adf60 2004-04-14 devnull
551 ff3adf60 2004-04-14 devnull v = get4(bin);
552 ff3adf60 2004-04-14 devnull if(v != ZCHeader){
553 ff3adf60 2004-04-14 devnull if(v == ZECHeader)
554 ff3adf60 2004-04-14 devnull return 0;
555 ff3adf60 2004-04-14 devnull error("bad magic number %lux", v);
556 ff3adf60 2004-04-14 devnull }
557 ff3adf60 2004-04-14 devnull zh->madevers = get1(bin);
558 ff3adf60 2004-04-14 devnull zh->madeos = get1(bin);
559 ff3adf60 2004-04-14 devnull zh->extvers = get1(bin);
560 ff3adf60 2004-04-14 devnull zh->extos = get1(bin);
561 ff3adf60 2004-04-14 devnull zh->flags = get2(bin);
562 ff3adf60 2004-04-14 devnull zh->meth = get2(bin);
563 ff3adf60 2004-04-14 devnull zh->modtime = get2(bin);
564 ff3adf60 2004-04-14 devnull zh->moddate = get2(bin);
565 ff3adf60 2004-04-14 devnull zh->crc = get4(bin);
566 ff3adf60 2004-04-14 devnull zh->csize = get4(bin);
567 ff3adf60 2004-04-14 devnull zh->uncsize = get4(bin);
568 ff3adf60 2004-04-14 devnull flen = get2(bin);
569 ff3adf60 2004-04-14 devnull xlen = get2(bin);
570 ff3adf60 2004-04-14 devnull fclen = get2(bin);
571 ff3adf60 2004-04-14 devnull get2(bin); /* disk number start */
572 ff3adf60 2004-04-14 devnull zh->iattr = get2(bin);
573 ff3adf60 2004-04-14 devnull zh->eattr = get4(bin);
574 ff3adf60 2004-04-14 devnull zh->off = get4(bin);
575 ff3adf60 2004-04-14 devnull
576 ff3adf60 2004-04-14 devnull zh->file = getname(bin, flen);
577 ff3adf60 2004-04-14 devnull
578 ff3adf60 2004-04-14 devnull while(xlen-- > 0)
579 ff3adf60 2004-04-14 devnull get1(bin);
580 ff3adf60 2004-04-14 devnull
581 ff3adf60 2004-04-14 devnull while(fclen-- > 0)
582 ff3adf60 2004-04-14 devnull get1(bin);
583 ff3adf60 2004-04-14 devnull
584 ff3adf60 2004-04-14 devnull return 1;
585 ff3adf60 2004-04-14 devnull }
586 ff3adf60 2004-04-14 devnull
587 ff3adf60 2004-04-14 devnull static int
588 ff3adf60 2004-04-14 devnull header(Biobuf *bin, ZipHead *zh)
589 ff3adf60 2004-04-14 devnull {
590 8425b514 2010-02-23 rsc u32int v;
591 ff3adf60 2004-04-14 devnull int flen, xlen;
592 ff3adf60 2004-04-14 devnull
593 ff3adf60 2004-04-14 devnull v = get4(bin);
594 ff3adf60 2004-04-14 devnull if(v != ZHeader){
595 ff3adf60 2004-04-14 devnull if(v == ZCHeader)
596 ff3adf60 2004-04-14 devnull return 0;
597 ff3adf60 2004-04-14 devnull error("bad magic number %lux at %lld", v, Boffset(bin)-4);
598 ff3adf60 2004-04-14 devnull }
599 ff3adf60 2004-04-14 devnull zh->extvers = get1(bin);
600 ff3adf60 2004-04-14 devnull zh->extos = get1(bin);
601 ff3adf60 2004-04-14 devnull zh->flags = get2(bin);
602 ff3adf60 2004-04-14 devnull zh->meth = get2(bin);
603 ff3adf60 2004-04-14 devnull zh->modtime = get2(bin);
604 ff3adf60 2004-04-14 devnull zh->moddate = get2(bin);
605 ff3adf60 2004-04-14 devnull zh->crc = get4(bin);
606 ff3adf60 2004-04-14 devnull zh->csize = get4(bin);
607 ff3adf60 2004-04-14 devnull zh->uncsize = get4(bin);
608 ff3adf60 2004-04-14 devnull flen = get2(bin);
609 ff3adf60 2004-04-14 devnull xlen = get2(bin);
610 ff3adf60 2004-04-14 devnull
611 ff3adf60 2004-04-14 devnull zh->file = getname(bin, flen);
612 ff3adf60 2004-04-14 devnull
613 ff3adf60 2004-04-14 devnull while(xlen-- > 0)
614 ff3adf60 2004-04-14 devnull get1(bin);
615 ff3adf60 2004-04-14 devnull
616 ff3adf60 2004-04-14 devnull return 1;
617 ff3adf60 2004-04-14 devnull }
618 ff3adf60 2004-04-14 devnull
619 ff3adf60 2004-04-14 devnull static void
620 ff3adf60 2004-04-14 devnull trailer(Biobuf *bin, ZipHead *zh)
621 ff3adf60 2004-04-14 devnull {
622 ff3adf60 2004-04-14 devnull if(zh->flags & ZTrailInfo){
623 ff3adf60 2004-04-14 devnull zh->crc = get4(bin);
624 ff3adf60 2004-04-14 devnull zh->csize = get4(bin);
625 ff3adf60 2004-04-14 devnull zh->uncsize = get4(bin);
626 ff3adf60 2004-04-14 devnull }
627 ff3adf60 2004-04-14 devnull }
628 ff3adf60 2004-04-14 devnull
629 ff3adf60 2004-04-14 devnull static char*
630 ff3adf60 2004-04-14 devnull getname(Biobuf *bin, int len)
631 ff3adf60 2004-04-14 devnull {
632 ff3adf60 2004-04-14 devnull char *s;
633 ff3adf60 2004-04-14 devnull int i, c;
634 ff3adf60 2004-04-14 devnull
635 ff3adf60 2004-04-14 devnull s = emalloc(len + 1);
636 ff3adf60 2004-04-14 devnull for(i = 0; i < len; i++){
637 ff3adf60 2004-04-14 devnull c = get1(bin);
638 ff3adf60 2004-04-14 devnull if(lower)
639 ff3adf60 2004-04-14 devnull c = tolower(c);
640 ff3adf60 2004-04-14 devnull s[i] = c;
641 ff3adf60 2004-04-14 devnull }
642 ff3adf60 2004-04-14 devnull s[i] = '\0';
643 ff3adf60 2004-04-14 devnull return s;
644 ff3adf60 2004-04-14 devnull }
645 ff3adf60 2004-04-14 devnull
646 ff3adf60 2004-04-14 devnull static int
647 ff3adf60 2004-04-14 devnull crcwrite(void *out, void *buf, int n)
648 ff3adf60 2004-04-14 devnull {
649 ff3adf60 2004-04-14 devnull int fd, nw;
650 ff3adf60 2004-04-14 devnull
651 ff3adf60 2004-04-14 devnull wlen += n;
652 ff3adf60 2004-04-14 devnull crc = blockcrc(crctab, crc, buf, n);
653 3ca675a5 2006-04-20 devnull fd = (int)(uintptr)out;
654 ff3adf60 2004-04-14 devnull if(fd < 0)
655 ff3adf60 2004-04-14 devnull return n;
656 ff3adf60 2004-04-14 devnull nw = write(fd, buf, n);
657 ff3adf60 2004-04-14 devnull if(nw != n)
658 ff3adf60 2004-04-14 devnull wbad = 1;
659 ff3adf60 2004-04-14 devnull return nw;
660 ff3adf60 2004-04-14 devnull }
661 ff3adf60 2004-04-14 devnull
662 ff3adf60 2004-04-14 devnull static int
663 ff3adf60 2004-04-14 devnull copyout(int ofd, Biobuf *bin, long len)
664 ff3adf60 2004-04-14 devnull {
665 ff3adf60 2004-04-14 devnull char buf[BufSize];
666 ff3adf60 2004-04-14 devnull int n;
667 ff3adf60 2004-04-14 devnull
668 ff3adf60 2004-04-14 devnull for(; len > 0; len -= n){
669 ff3adf60 2004-04-14 devnull n = len;
670 ff3adf60 2004-04-14 devnull if(n > BufSize)
671 ff3adf60 2004-04-14 devnull n = BufSize;
672 ff3adf60 2004-04-14 devnull n = Bread(bin, buf, n);
673 ff3adf60 2004-04-14 devnull if(n <= 0)
674 ff3adf60 2004-04-14 devnull return 0;
675 ff3adf60 2004-04-14 devnull rlen += n;
676 3ca675a5 2006-04-20 devnull if(crcwrite((void*)(uintptr)ofd, buf, n) != n)
677 ff3adf60 2004-04-14 devnull return 0;
678 ff3adf60 2004-04-14 devnull }
679 ff3adf60 2004-04-14 devnull return 1;
680 ff3adf60 2004-04-14 devnull }
681 ff3adf60 2004-04-14 devnull
682 8425b514 2010-02-23 rsc static u32int
683 ff3adf60 2004-04-14 devnull get4(Biobuf *b)
684 ff3adf60 2004-04-14 devnull {
685 8425b514 2010-02-23 rsc u32int v;
686 ff3adf60 2004-04-14 devnull int i, c;
687 ff3adf60 2004-04-14 devnull
688 ff3adf60 2004-04-14 devnull v = 0;
689 ff3adf60 2004-04-14 devnull for(i = 0; i < 4; i++){
690 ff3adf60 2004-04-14 devnull c = Bgetc(b);
691 ff3adf60 2004-04-14 devnull if(c < 0)
692 ff3adf60 2004-04-14 devnull error("unexpected eof reading file information");
693 ff3adf60 2004-04-14 devnull v |= c << (i * 8);
694 ff3adf60 2004-04-14 devnull }
695 ff3adf60 2004-04-14 devnull return v;
696 ff3adf60 2004-04-14 devnull }
697 ff3adf60 2004-04-14 devnull
698 ff3adf60 2004-04-14 devnull static int
699 ff3adf60 2004-04-14 devnull get2(Biobuf *b)
700 ff3adf60 2004-04-14 devnull {
701 ff3adf60 2004-04-14 devnull int i, c, v;
702 ff3adf60 2004-04-14 devnull
703 ff3adf60 2004-04-14 devnull v = 0;
704 ff3adf60 2004-04-14 devnull for(i = 0; i < 2; i++){
705 ff3adf60 2004-04-14 devnull c = Bgetc(b);
706 ff3adf60 2004-04-14 devnull if(c < 0)
707 ff3adf60 2004-04-14 devnull error("unexpected eof reading file information");
708 ff3adf60 2004-04-14 devnull v |= c << (i * 8);
709 ff3adf60 2004-04-14 devnull }
710 ff3adf60 2004-04-14 devnull return v;
711 ff3adf60 2004-04-14 devnull }
712 ff3adf60 2004-04-14 devnull
713 ff3adf60 2004-04-14 devnull static int
714 ff3adf60 2004-04-14 devnull get1(Biobuf *b)
715 ff3adf60 2004-04-14 devnull {
716 ff3adf60 2004-04-14 devnull int c;
717 ff3adf60 2004-04-14 devnull
718 ff3adf60 2004-04-14 devnull c = Bgetc(b);
719 ff3adf60 2004-04-14 devnull if(c < 0)
720 ff3adf60 2004-04-14 devnull error("unexpected eof reading file information");
721 ff3adf60 2004-04-14 devnull return c;
722 ff3adf60 2004-04-14 devnull }
723 ff3adf60 2004-04-14 devnull
724 ff3adf60 2004-04-14 devnull static long
725 ff3adf60 2004-04-14 devnull msdos2time(int time, int date)
726 ff3adf60 2004-04-14 devnull {
727 ff3adf60 2004-04-14 devnull Tm tm;
728 ff3adf60 2004-04-14 devnull
729 ff3adf60 2004-04-14 devnull tm.hour = time >> 11;
730 ff3adf60 2004-04-14 devnull tm.min = (time >> 5) & 63;
731 ff3adf60 2004-04-14 devnull tm.sec = (time & 31) << 1;
732 ff3adf60 2004-04-14 devnull tm.year = 80 + (date >> 9);
733 ff3adf60 2004-04-14 devnull tm.mon = ((date >> 5) & 15) - 1;
734 ff3adf60 2004-04-14 devnull tm.mday = date & 31;
735 ff3adf60 2004-04-14 devnull tm.zone[0] = '\0';
736 ff3adf60 2004-04-14 devnull tm.yday = 0;
737 ff3adf60 2004-04-14 devnull
738 ff3adf60 2004-04-14 devnull return tm2sec(&tm);
739 ff3adf60 2004-04-14 devnull }
740 ff3adf60 2004-04-14 devnull
741 ff3adf60 2004-04-14 devnull static void*
742 8425b514 2010-02-23 rsc emalloc(u32int n)
743 ff3adf60 2004-04-14 devnull {
744 ff3adf60 2004-04-14 devnull void *p;
745 ff3adf60 2004-04-14 devnull
746 ff3adf60 2004-04-14 devnull p = malloc(n);
747 ff3adf60 2004-04-14 devnull if(p == nil)
748 ff3adf60 2004-04-14 devnull sysfatal("out of memory");
749 ff3adf60 2004-04-14 devnull return p;
750 ff3adf60 2004-04-14 devnull }
751 ff3adf60 2004-04-14 devnull
752 ff3adf60 2004-04-14 devnull static void
753 ff3adf60 2004-04-14 devnull error(char *fmt, ...)
754 ff3adf60 2004-04-14 devnull {
755 ff3adf60 2004-04-14 devnull va_list arg;
756 ff3adf60 2004-04-14 devnull
757 ff3adf60 2004-04-14 devnull fprint(2, "unzip: ");
758 ff3adf60 2004-04-14 devnull va_start(arg, fmt);
759 ff3adf60 2004-04-14 devnull vfprint(2, fmt, arg);
760 ff3adf60 2004-04-14 devnull va_end(arg);
761 ff3adf60 2004-04-14 devnull fprint(2, "\n");
762 ff3adf60 2004-04-14 devnull
763 ff3adf60 2004-04-14 devnull if(delfile != nil){
764 ff3adf60 2004-04-14 devnull fprint(2, "unzip: removing output file %s\n", delfile);
765 ff3adf60 2004-04-14 devnull remove(delfile);
766 ff3adf60 2004-04-14 devnull delfile = nil;
767 ff3adf60 2004-04-14 devnull }
768 ff3adf60 2004-04-14 devnull
769 ff3adf60 2004-04-14 devnull longjmp(zjmp, 1);
770 ff3adf60 2004-04-14 devnull }