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

Contents of /trunk/PTD/wptGPGZIP.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 32 - (show annotations)
Mon Oct 24 08:03:48 2005 UTC (19 years, 4 months ago) by twoaday
File size: 23943 byte(s)
2005-10-23  Timo Schulz  <twoaday@g10code.com>
 
        * wptFileManager.cpp (fm_get_file_type): Detect detached sigs.
        * wptKeyList.cpp (keylist_cmp_cb): Take care of expired/revoked keys.
        (get_ext_validity): New.
        * wptFileVerifyDlg.cpp (file_verify_dlg_proc): Several cleanups.
        * wptClipEditDlg.cpp (load_clipboard): Factored out some code into
        this function.
        (load_clipboard_from_file): Likewise.
        (save_clipboard_to_file): New.
        * wptKeyManagerDlg.cpp (keyprops_dlg_proc): Fix stack overflow.

For complete details, see the ChangeLog files.

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26