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

Contents of /trunk/PTD/wptGPGZIP.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2 - (show 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 /* 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