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

Annotation of /trunk/PTD/wptZIP.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 46 - (hide 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 werner 46 /* 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 twoaday 33 }
188 werner 46
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