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

Annotation of /trunk/PTD/wptGPGZIP.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2 - (hide annotations)
Mon Jan 31 11:02:21 2005 UTC (20 years, 1 month ago) by twoaday
File size: 23426 byte(s)
WinPT initial checkin.


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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26