/[winpt]/trunk/PTD/wptZIP.cpp
ViewVC logotype

Contents of /trunk/PTD/wptZIP.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 46 - (show annotations)
Fri Oct 28 12:57:05 2005 UTC (19 years, 4 months ago) by werner
File size: 23185 byte(s)
Second set of changes to use autotools for building.
1 /* wptZIP.cpp
2 * Copyright (C) 2002-2004 Timo Schulz
3 *
4 * This file is part of WinPT.
5 *
6 * WinPT is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * WinPT is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with PTD; if not, write to the Free Software Foundation,
18 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20 #ifdef HAVE_CONFIG_H
21 #include <config.h>
22 #endif
23
24 #include <windows.h>
25 #include <windows.h>
26 #include <assert.h>
27 #include <stdlib.h>
28 #include <stdio.h>
29 #include <string.h>
30 #include <sys/stat.h>
31 #include <direct.h>
32 #include <time.h>
33
34 #include "wptZIP.h"
35
36 /*static int debug = 0;*/
37
38 enum zip_sig_t {
39 PK_SIG_LOCAL = 0x04034b50,
40 PK_SIG_FILE = 0x02014b50,
41 PK_SIG_END = 0x06054b50
42 };
43
44 enum zip_flag_t {
45 PK_FLAG_ENCRYPTED = 1, /* archive is encrypted. */
46 PK_FLAG_8KDICT = 2, /* used 8k dictionary */
47 PK_FLAG_SF = 4
48 };
49
50
51 typedef struct {
52 unsigned long magic;
53 unsigned short ver;
54 unsigned short flags;
55 unsigned short method;
56 unsigned short ftime;
57 unsigned short fdate;
58 unsigned long crc;
59 unsigned long c_size;
60 unsigned long u_size;
61 unsigned short f_len;
62 unsigned short extra_len;
63 char *name;
64 FILE *fp;
65 } PK_local_hdr;
66
67 typedef struct {
68 unsigned long magic;
69 unsigned short ver_made;
70 unsigned short ver_ext;
71 unsigned short flags;
72 unsigned short method;
73 unsigned short ftime;
74 unsigned short fdate;
75 unsigned long crc;
76 unsigned long c_size;
77 unsigned long u_size;
78 unsigned short f_len;
79 unsigned short extra_len;
80 unsigned short comment_len;
81 unsigned short disc_nr;
82 unsigned short int_attr;
83 unsigned long ext_attr;
84 unsigned long lochdr_off;
85 char *name;
86 size_t size;
87 } PK_file_hdr;
88
89
90 typedef struct {
91 unsigned long magic;
92 unsigned short disc_nr;
93 unsigned short disc_nr_cd;
94 unsigned short total_dirs_disc;
95 unsigned short total_dirs;
96 unsigned long size_of_dir;
97 unsigned long off_dir;
98 unsigned short comment_len;
99 char *comment;
100 } PK_end_hdr;
101
102
103 typedef struct {
104 union {
105 PK_local_hdr *local;
106 PK_file_hdr *file;
107 PK_end_hdr *end;
108 } u;
109 unsigned long pkttype;
110 } PK_packet;
111
112
113 struct PK_file_list {
114 struct PK_file_list *next;
115 PK_local_hdr *hdr;
116 size_t off;
117 size_t len;
118 char *d;
119 };
120
121
122 static unsigned long crc_table[256] = {
123 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
124 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
125 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
126 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
127 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
128 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
129 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
130 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
131 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
132 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
133 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
134 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
135 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
136 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
137 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
138 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
139 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
140 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
141 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
142 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
143 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
144 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
145 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
146 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
147 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
148 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
149 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
150 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
151 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
152 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
153 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
154 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
155 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
156 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
157 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
158 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
159 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
160 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
161 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
162 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
163 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
164 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
165 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
166 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
167 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
168 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
169 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
170 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
171 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
172 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
173 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
174 0x2d02ef8dL
175 };
176
177
178 /* Update the crc in @crc with the buffer @buf and the length @buflen. */
179 static unsigned long
180 update_crc (unsigned long crc, unsigned char *buf, size_t buflen)
181 {
182 crc ^= 0xffffffffL;
183 while (buflen--)
184 crc = crc_table[((int)(crc) ^ (*buf++)) & 0xff] ^ ((crc) >> 8);
185 crc ^= 0xffffffffL;
186 return crc;
187 }
188
189
190 static unsigned short
191 read_16 (FILE *in)
192 {
193 unsigned short u;
194 u = fgetc (in) ;
195 u |= fgetc (in) << 8;
196 return u;
197 }
198
199
200 static void
201 write_16 (FILE *out, unsigned short a)
202 {
203 fputc (a , out);
204 fputc (a >> 8, out);
205 }
206
207
208 static unsigned long
209 read_32 (FILE *in)
210 {
211 unsigned long u;
212 u = fgetc (in) ;
213 u |= fgetc (in) << 8;
214 u |= fgetc (in) << 16;
215 u |= fgetc (in) << 24;
216 return u;
217 }
218
219
220 static void
221 write_32 (FILE * out, unsigned long a)
222 {
223 fputc (a , out);
224 fputc (a >> 8 , out);
225 fputc (a >> 16, out);
226 fputc (a >> 24, out);
227 }
228
229
230 static unsigned short
231 date_to_dos (time_t t)
232 {
233 struct tm * tm;
234 tm = localtime (&t);
235 return tm->tm_mday | (tm->tm_mon+1)<<5 | ((tm->tm_year-80)<<9);
236 }
237
238
239 static unsigned short
240 time_to_dos (time_t t)
241 {
242 struct tm * tm;
243 tm = localtime (&t);
244 return (tm->tm_hour<<11) | (tm->tm_min<<5) | (tm->tm_sec>>1);
245 }
246
247
248 static char*
249 xstrdup (const char * s)
250 {
251 char *p = new char[strlen (s)+1];
252 if (!p)
253 abort ();
254 strcpy (p, s);
255 return p;
256 }
257
258
259 static PK_local_hdr*
260 create_local_header (const char *name, FILE *fp)
261 {
262 struct stat statbuf;
263 PK_local_hdr *a;
264
265 if (fstat (fileno (fp), &statbuf))
266 return NULL;
267 a = new PK_local_hdr;
268 if (!a)
269 return NULL;
270 memset (a, 0, sizeof *a);
271 a->magic = PK_SIG_LOCAL;
272 a->ver = 0 | (10 << 8);
273 a->flags = 0;
274 a->method = 0;
275 a->fdate = date_to_dos (statbuf.st_mtime);
276 a->ftime = time_to_dos (statbuf.st_mtime);
277 a->crc = 0;
278 a->c_size = statbuf.st_size;
279 a->u_size = statbuf.st_size;
280 a->f_len = strlen (name);
281 a->name = xstrdup (name);
282 a->extra_len = 0;
283 a->fp = fp;
284 return a;
285 }
286
287
288 static int
289 write_local_header (FILE *out, PK_local_hdr *hdr)
290 {
291 long crc_pos = 0, curr_pos = 0;
292
293 write_32 (out, hdr->magic);
294 write_16 (out, hdr->ver);
295 write_16 (out, hdr->flags);
296 write_16 (out, hdr->method);
297 write_16 (out, hdr->ftime);
298 write_16 (out, hdr->fdate);
299 crc_pos = ftell (out);
300 write_32 (out, hdr->crc);
301 write_32 (out, hdr->c_size);
302 write_32 (out, hdr->u_size);
303 write_16 (out, hdr->f_len);
304 write_16 (out, hdr->extra_len);
305 if (hdr->f_len > 0)
306 fwrite (hdr->name, 1, hdr->f_len, out);
307 if (hdr->extra_len)
308 fwrite (NULL, 1, hdr->extra_len, out); /* xxx */
309 while (!feof (hdr->fp)) {
310 unsigned char buf[2048];
311 unsigned long nread;
312 nread = fread (buf, 1, sizeof buf-1, hdr->fp);
313 if (nread > 0) {
314 /*fprintf (stderr, "** nread=%d\n", nread);*/
315 hdr->crc = update_crc (hdr->crc, buf, nread);
316 fwrite (buf, 1, nread, out);
317 }
318 }
319 curr_pos = ftell (out);
320 fseek (out, crc_pos, SEEK_SET);
321 write_32 (out, hdr->crc);
322 fseek (out, curr_pos, SEEK_SET);
323 return 0;
324 }
325
326
327 static int
328 create_missing_dirs (const char *name)
329 {
330 struct stat dirbuf;
331 char *p, *dir;
332 int rc;
333
334 p = strrchr (name, '/');
335 if (!p)
336 return PKERR_GENERAL;
337 dir = new char[(p-name)+1];
338 if (!dir)
339 abort ();
340 memset (dir, 0, (p-name)+1);
341 strncpy (dir, name, (p-name));
342 if (!stat (dir, &dirbuf) && (dirbuf.st_mode & _S_IFDIR))
343 rc = 0;
344 else
345 rc = mkdir (dir);
346 delete []dir;
347 return rc;
348 }
349
350
351 static PK_local_hdr*
352 read_local_header (FILE *in, unsigned long magic, int create)
353 {
354 PK_local_hdr *hdr;
355 FILE *out = NULL;
356 size_t n;
357
358 if (magic != PK_SIG_LOCAL)
359 return NULL;
360 hdr = new PK_local_hdr;
361 if (!hdr)
362 return NULL;
363 memset (hdr, 0, sizeof * hdr);
364 hdr->magic = magic;
365 hdr->ver = read_16 (in);
366 hdr->flags = read_16 (in);
367 hdr->method = read_16 (in);
368 hdr->ftime = read_16 (in);
369 hdr->fdate = read_16 (in);
370 hdr->crc = read_32 (in);
371 hdr->c_size = read_32 (in);
372 hdr->u_size = read_32 (in);
373 hdr->f_len = read_16 (in);
374 hdr->extra_len = read_16 (in);
375
376 /*if( debug ) {
377 printf("=====BEGIN LOCAL HEADER=====\n");
378 printf( "magic %08lX version=%d\n", hdr->magic, hdr->ver );
379 printf( "flags encrypted=%d 8k dict=%d shannon=%d\n",
380 hdr->flags & PK_FLAG_ENCRYPTED, hdr->flags & PK_FLAG_8KDICT,
381 hdr->flags & PK_FLAG_SF );
382 printf( "method=" );
383 switch( hdr->method ) {
384 case 0: printf( "stored\n" ); break;
385 default: printf( "unknown (%d)\n", hdr->method );
386 }
387 printf( "filetime=%d %d\n", hdr->ftime, hdr->fdate );
388 printf( "CRC=%08lX\n", hdr->crc );
389 printf( "size: compressed=%lu uncompressed=%lu\n",
390 hdr->c_size, hdr->u_size );
391 printf( "filename len=%d extra_len=%d\n", hdr->f_len, hdr->extra_len );
392 }*/
393
394 if (hdr->f_len) {
395 hdr->name = new char[hdr->f_len+1];
396 if (!hdr->name)
397 abort ();
398 memset (hdr->name, 0, hdr->f_len+1);
399 fread (hdr->name, 1, hdr->f_len, in);
400 /*if (debug)
401 printf ("filename %s\n", hdr->name);*/
402 }
403 /*if (debug)
404 printf ("skip extra header (%d)\n", hdr->extra_len);*/
405 n = hdr->extra_len;
406 while (n--)
407 fgetc (in);
408 /*if (debug)
409 printf ("skip compressed data (%lu)\n", hdr->c_size);*/
410 if (create && hdr->name) {
411 create_missing_dirs (hdr->name);
412 out = fopen (hdr->name, "wb");
413 /*if (debug)
414 printf( "create output `%s' (status %s)\n", hdr->name,
415 out? "success" : "failed" );*/
416 }
417 n = hdr->c_size;
418 while (n--) {
419 int c = fgetc (in);
420 if (out)
421 fputc (c, out);
422 }
423 if (out)
424 fclose (out);
425 return hdr;
426 }
427
428
429 static PK_file_hdr*
430 create_file_header (PK_local_hdr * loc, long loc_off)
431 {
432 PK_file_hdr * a;
433
434 a = new PK_file_hdr;
435 if (!a)
436 abort ();
437 memset (a, 0, sizeof *a);
438 a->magic = PK_SIG_FILE;
439 a->ver_made = loc->ver;
440 a->ver_ext = loc->ver;
441 a->flags = loc->flags;
442 a->method = loc->method;
443 a->ftime = loc->ftime;
444 a->fdate = loc->fdate;
445 a->crc = loc->crc;
446 a->c_size = loc->c_size;
447 a->u_size = loc->u_size;
448 a->f_len = loc->f_len;
449 a->extra_len = loc->extra_len;
450 a->comment_len = 0;
451 a->disc_nr = 0;
452 a->int_attr = 0;
453 a->ext_attr = 0;
454 a->lochdr_off = loc_off;
455 a->size = 46 + a->f_len;
456 a->name = xstrdup (loc->name);
457 return a;
458 }
459
460
461 static int
462 write_file_header (FILE *out, PK_file_hdr *hdr)
463 {
464 write_32 (out, hdr->magic);
465 write_16 (out, hdr->ver_made);
466 write_16 (out, hdr->ver_ext);
467 write_16 (out, hdr->flags);
468 write_16 (out, hdr->method);
469 write_16 (out, hdr->ftime);
470 write_16 (out, hdr->fdate);
471 write_32 (out, hdr->crc);
472 write_32 (out, hdr->c_size);
473 write_32 (out, hdr->u_size);
474 write_16 (out, hdr->f_len);
475 write_16 (out, hdr->extra_len);
476 write_16 (out, hdr->comment_len);
477 write_16 (out, hdr->disc_nr);
478 write_16 (out, hdr->int_attr);
479 write_32 (out, hdr->ext_attr);
480 write_32 (out, hdr->lochdr_off);
481 if (hdr->f_len > 0)
482 fwrite (hdr->name, 1, hdr->f_len, out);
483 if (hdr->extra_len > 0)
484 fwrite (NULL, 1, hdr->extra_len, out); /* xxx */
485 if (hdr->comment_len > 0)
486 fwrite (NULL, 1, hdr->comment_len, out); /* xxx */
487 return 0;
488 }
489
490
491 static PK_file_hdr*
492 read_file_header (FILE * in, unsigned long magic)
493 {
494 PK_file_hdr * hdr;
495 size_t n;
496
497 if (magic != PK_SIG_FILE)
498 return NULL;
499 hdr = new PK_file_hdr;
500 if (!hdr)
501 return NULL;
502 memset (hdr, 0, sizeof * hdr);
503 hdr->magic = magic;
504 hdr->ver_made = read_16( in );
505 hdr->ver_ext = read_16( in );
506 hdr->flags = read_16( in );
507 hdr->method = read_16( in );
508 hdr->ftime = read_16( in );
509 hdr->fdate = read_16( in );
510 hdr->crc = read_32( in );
511 hdr->c_size = read_32( in );
512 hdr->u_size = read_32( in );
513 hdr->f_len = read_16( in );
514 hdr->extra_len = read_16( in );
515 hdr->comment_len = read_16( in );
516 hdr->disc_nr = read_16( in );
517 hdr->int_attr = read_16( in );
518 hdr->ext_attr = read_32( in );
519 hdr->lochdr_off = read_32( in );
520
521 /*if( debug ) {
522 printf("=====BEGIN FILE HEADER=====\n");
523 printf( "magic=%08lX\n", hdr->magic );
524 printf( "version made=%d needed=%d\n", hdr->ver_made, hdr->ver_ext );
525 printf( "flags encrypted=%d endheader=%d extended=%d\n",
526 hdr->flags & PK_FLAG_ENCRYPTED, hdr->flags & PK_FLAG_8KDICT,
527 hdr->flags & PK_FLAG_SF );
528 printf( "method=" );
529 switch( hdr->method ) {
530 case 0: printf( "stored\n" ); break;
531 default: printf( "unknown (%d)\n", hdr->method );
532 }
533 printf( "filetime=%d %d\n", hdr->ftime, hdr->fdate );
534 printf( "CRC=%08lX\n", hdr->crc );
535 printf( "size compressed=%lu uncompressed=%lu\n",
536 hdr->c_size, hdr->u_size );
537 printf( "extra len=%d comment len=%d\n", hdr->extra_len,
538 hdr->comment_len );
539 printf( "disk nummer=%d\n", hdr->disc_nr );
540 printf( "attrs intern=%d extern=%lu\n", hdr->int_attr, hdr->ext_attr );
541 printf( "disk offset=%lu\n", hdr->lochdr_off );
542 }*/
543
544 if (hdr->f_len > 0) {
545 hdr->name = new char[hdr->f_len + 1];
546 if (!hdr->name)
547 abort ();
548 memset (hdr->name, 0, hdr->f_len+1);
549 fread (hdr->name, 1, hdr->f_len, in);
550 /*if( debug )
551 printf( "filename=%s\n", hdr->name );*/
552 }
553 n = hdr->extra_len;
554 while (n--)
555 fgetc (in);
556 n = hdr->comment_len;
557 while (n--)
558 fgetc (in);
559 return hdr;
560 }
561
562
563 static PK_end_hdr*
564 create_end_header (size_t ntotal, size_t nsize, long off_dir)
565 {
566 PK_end_hdr *a;
567
568 a = new PK_end_hdr;
569 if (!a)
570 abort ();
571 memset (a, 0, sizeof * a);
572 a->magic = PK_SIG_END;
573 a->disc_nr = 0;
574 a->disc_nr_cd = 0;
575 a->total_dirs = ntotal;
576 a->total_dirs_disc = ntotal;
577 a->size_of_dir = nsize;
578 a->off_dir = off_dir;
579 a->comment_len = 0;
580 return a;
581 }
582
583
584 static int
585 write_end_header (FILE *out, PK_end_hdr *hdr)
586 {
587 write_32 (out, hdr->magic);
588 write_16 (out, hdr->disc_nr);
589 write_16 (out, hdr->disc_nr_cd);
590 write_16 (out, hdr->total_dirs);
591 write_16 (out, hdr->total_dirs_disc);
592 write_32 (out, hdr->size_of_dir);
593 write_32 (out, hdr->off_dir);
594 write_16 (out, hdr->comment_len);
595 if (hdr->comment_len > 0)
596 fwrite (hdr->comment, 1, hdr->comment_len, out);
597 return 0;
598 }
599
600
601 static PK_end_hdr*
602 read_end_header (FILE * in, unsigned long magic)
603 {
604 PK_end_hdr * hdr;
605
606 if( magic != PK_SIG_END )
607 return NULL;
608 hdr = new PK_end_hdr;
609 if( !hdr )
610 abort ();
611 memset (hdr, 0, sizeof *hdr);
612 hdr->magic = magic;
613 hdr->disc_nr = read_16( in );
614 hdr->disc_nr_cd = read_16( in );
615 hdr->total_dirs = read_16( in );
616 hdr->total_dirs_disc = read_16( in );
617 hdr->size_of_dir = read_32( in );
618 hdr->off_dir = read_32( in );
619 hdr->comment_len = read_16( in );
620
621 /*if( debug ) {
622 printf("=====BEGIN END HEADER=====\n");
623 printf( "magic=%08lX\n", hdr->magic );
624 printf( "disc number=%d in this directory=%d\n", hdr->disc_nr,
625 hdr->disc_nr_cd );
626 printf( "total number of disc=%d in this directory=%d\n",
627 hdr->total_dirs, hdr->total_dirs_disc );
628 printf( "offset of central directory=%lu\n", hdr->off_dir );
629 printf( "size of directory=%lu\n", hdr->size_of_dir );
630 }*/
631
632 if (hdr->comment_len > 0) {
633 hdr->comment = new char[hdr->comment_len+1];
634 if( !hdr->comment )
635 abort ();
636 memset (hdr->comment, 0, hdr->comment_len+1);
637 fread( hdr->comment, 1, hdr->comment_len, in );
638 /*if( debug )
639 printf( "comment(%d)=%s\n", hdr->comment_len, hdr->comment );*/
640 }
641 return hdr;
642 }
643
644
645 static void
646 free_packet (PK_packet *pkt)
647 {
648 switch( pkt->pkttype ) {
649 case PK_SIG_LOCAL:
650 if (pkt->u.local->name)
651 delete []pkt->u.local->name;
652 delete pkt->u.local;
653 break;
654 case PK_SIG_FILE:
655 if (pkt->u.file->name)
656 delete[] pkt->u.file->name;
657 delete pkt->u.file;
658 break;
659 case PK_SIG_END:
660 if (pkt->u.end->comment)
661 delete [] pkt->u.end->comment;
662 delete pkt->u.end;
663 break;
664 }
665 pkt->pkttype = 0;
666 }
667
668
669 int
670 pk_archiv_parse (FILE *in)
671 {
672 unsigned long magic;
673 PK_packet pkt;
674
675 while( !feof( in ) ) {
676 magic = read_32( in );
677 if( feof( in ) )
678 break;
679 /*printf("\n** read magic value %08lX\n\n", magic );*/
680 switch( magic ) {
681 case PK_SIG_LOCAL:
682 pkt.u.local = read_local_header( in, magic, 1 );
683 pkt.pkttype = PK_SIG_LOCAL;
684 break;
685
686 case PK_SIG_FILE:
687 pkt.u.file = read_file_header( in, magic );
688 pkt.pkttype = PK_SIG_FILE;
689 break;
690
691 case PK_SIG_END:
692 pkt.u.end = read_end_header( in, magic );
693 pkt.pkttype = PK_SIG_END;
694 break;
695
696 default:
697 /*printf( "unknown magic value (%08lX).\n", magic );*/
698 if( ftell( in ) == 4 ) {
699 free_packet( &pkt );
700 return PKERR_INV_FILE;
701 }
702 break;
703 }
704 free_packet( &pkt );
705 }
706 return 0;
707 }
708
709
710 static int
711 is_directory (const char * fname)
712 {
713 struct stat statbuf;
714 if (stat (fname, &statbuf))
715 return 0;
716 return statbuf.st_mode & S_IFDIR;
717 }
718
719
720 int
721 pk_archiv_create (struct PK_file_list *list, const char *output)
722 {
723 struct PK_file_list *r;
724 PK_file_hdr *f;
725 PK_end_hdr *e;
726 PK_packet pkt;
727 FILE *fp, *out;
728 long foff = 0, n = 0;
729 size_t size = 0;
730
731 out = fopen (output, "wb");
732 if (!out)
733 return PKERR_FILE;
734
735 for (r = list; r; r = r->next) {
736 fprintf (stderr, "process file `%s'\n", r->d);
737 if (is_directory (r->d))
738 continue;
739 fp = fopen (r->d, "rb");
740 if (!fp) {
741 fclose (out);
742 return PKERR_FILE;
743 }
744 r->off = ftell (out);
745 r->hdr = create_local_header( r->d, fp );
746 if (!r->hdr) {
747 fclose (fp);
748 fclose (out);
749 return PKERR_GENERAL;
750 }
751 if (r->off)
752 r->off += r->hdr->c_size;
753 write_local_header (out, r->hdr);
754 n++;
755 fclose (fp);
756 }
757 foff = ftell( out );
758 for (r = list; r; r = r->next) {
759 if (is_directory (r->d))
760 continue;
761 fp = fopen (r->d, "rb");
762 if (!fp) {
763 fclose (out);
764 return PKERR_FILE;
765 }
766 f = create_file_header (r->hdr, r->off);
767 size += f->size;
768 write_file_header (out, f);
769 fclose (fp);
770 pkt.u.file = f;
771 free_packet (&pkt);
772 }
773
774 e = create_end_header (n, size, foff);
775 write_end_header (out, e);
776 fclose (out);
777 return 0;
778 }
779
780
781 void
782 pk_list_add (struct PK_file_list **list, const char *name)
783 {
784 struct PK_file_list * l;
785
786 l = new PK_file_list;
787 if (!l)
788 abort ();
789 memset (l, 0, sizeof *l);
790 l->next = *list;
791 l->d = new char[strlen (name)+2];
792 if (!l->d)
793 abort ();
794 strcpy (l->d, name);
795 *list = l;
796 }
797
798
799 void
800 pk_list_free (struct PK_file_list *list)
801 {
802 struct PK_file_list * l;
803 PK_packet pkt;
804
805 while (list) {
806 l = list->next;
807 if (list->hdr) {
808 pkt.pkttype = PK_SIG_LOCAL;
809 pkt.u.local = list->hdr;
810 free_packet (&pkt);
811 }
812 if (list->d)
813 delete []list->d;
814 delete list;
815 list = l;
816 }
817 }
818
819
820 #ifdef TEST
821
822 static void
823 test (const char *patt, const char *path, const char *out)
824 {
825 PK_FILE_LIST list = NULL;
826 WIN32_FIND_DATA findbuf;
827 HANDLE hd;
828 int rc = 0;
829
830 hd = FindFirstFile (patt, &findbuf );
831 if( !hd )
832 return;
833
834 if( strcmp( findbuf.cFileName, "." ) && strcmp( findbuf.cFileName, ".." ) ) {
835 char p[256];
836 _snprintf (p, sizeof (p)-1, "%s\\%s", path, findbuf.cFileName);
837 pk_list_add (&list, p);
838 }
839 while( FindNextFile( hd, &findbuf ) ) {
840 if( strcmp( findbuf.cFileName, "." ) && strcmp( findbuf.cFileName, ".." ) ) {
841 char p[256];
842 _snprintf (p, sizeof (p)-1, "%s\\%s", path, findbuf.cFileName);
843 pk_list_add (&list, p);
844 }
845 }
846
847 rc = pk_archiv_create (list, out);
848
849 pk_list_free (list);
850 FindClose (hd);
851 }
852
853 int
854 main (int argc, char **argv)
855 {
856 test ("c:\\gnupg\\*", "c:\\gnupg", "c:\\gnupg\\\\test\\sample.zip");
857 return 0;
858 }
859 #endif

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26