Develop and Download Open Source Software

Browse CVS Repository

Annotation of /xoonips/AL/zip.c

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.1 - (hide annotations) (download) (as text)
Thu Feb 10 02:10:21 2005 UTC (19 years, 2 months ago) by youi
Branch: MAIN
CVS Tags: mv_to_sourceforge_20050217, AL_PORTING, MergePnt_20051116, REL20051226, XOONIPS_RC1, REL20060323, tag20060615, tag20070307current, tag20061115, MergePnt_20051220, tag20061130, merge_to_20060605, tag20070307, REL20060213, RELENG_2_0_0a_RELEASE, RELEASE_1_0_0, RELEASE_1_0_1, tag20060622, merge_to_20060411, HEAD
Branch point for: XOONIPS_STABLE_32, XOONIPS_STABLE, XOONIPS_STABLE_3, XOONIPS_STABLE_2
File MIME type: text/x-csrc
initial version

1 youi 1.1 /* zip.c -- IO on .zip files using zlib
2     Version 1.00, September 10th, 2003
3    
4     Copyright (C) 1998-2003 Gilles Vollant
5    
6     Read zip.h for more info
7     */
8    
9    
10     #include <stdio.h>
11     #include <stdlib.h>
12     #include <string.h>
13     #include <time.h>
14     #include "zlib.h"
15     #include "zip.h"
16    
17     #ifdef STDC
18     # include <stddef.h>
19     # include <string.h>
20     # include <stdlib.h>
21     #endif
22     #ifdef NO_ERRNO_H
23     extern int errno;
24     #else
25     # include <errno.h>
26     #endif
27    
28    
29     #ifndef local
30     # define local static
31     #endif
32     /* compile with -Dlocal if your debugger can't find static symbols */
33    
34     #ifndef VERSIONMADEBY
35     # define VERSIONMADEBY (0x0) /* platform depedent */
36     #endif
37    
38     #ifndef Z_BUFSIZE
39     #define Z_BUFSIZE (16384)
40     #endif
41    
42     #ifndef Z_MAXFILENAMEINZIP
43     #define Z_MAXFILENAMEINZIP (256)
44     #endif
45    
46     #ifndef ALLOC
47     # define ALLOC(size) (malloc(size))
48     #endif
49     #ifndef TRYFREE
50     # define TRYFREE(p) {if (p) free(p);}
51     #endif
52    
53     /*
54     #define SIZECENTRALDIRITEM (0x2e)
55     #define SIZEZIPLOCALHEADER (0x1e)
56     */
57    
58     /* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
59    
60     #ifndef SEEK_CUR
61     #define SEEK_CUR 1
62     #endif
63    
64     #ifndef SEEK_END
65     #define SEEK_END 2
66     #endif
67    
68     #ifndef SEEK_SET
69     #define SEEK_SET 0
70     #endif
71    
72     #ifndef DEF_MEM_LEVEL
73     #if MAX_MEM_LEVEL >= 8
74     # define DEF_MEM_LEVEL 8
75     #else
76     # define DEF_MEM_LEVEL MAX_MEM_LEVEL
77     #endif
78     #endif
79     const char zip_copyright[] =
80     " zip 1.00 Copyright 1998-2003 Gilles Vollant - http://www.winimage.com/zLibDll";
81    
82    
83     #define SIZEDATA_INDATABLOCK (4096-(4*4))
84    
85     #define LOCALHEADERMAGIC (0x04034b50)
86     #define CENTRALHEADERMAGIC (0x02014b50)
87     #define ENDHEADERMAGIC (0x06054b50)
88    
89     #define FLAG_LOCALHEADER_OFFSET (0x06)
90     #define CRC_LOCALHEADER_OFFSET (0x0e)
91    
92     #define SIZECENTRALHEADER (0x2e) /* 46 */
93    
94     typedef struct linkedlist_datablock_internal_s
95     {
96     struct linkedlist_datablock_internal_s* next_datablock;
97     uLong avail_in_this_block;
98     uLong filled_in_this_block;
99     uLong unused; /* for future use and alignement */
100     unsigned char data[SIZEDATA_INDATABLOCK];
101     } linkedlist_datablock_internal;
102    
103     typedef struct linkedlist_data_s
104     {
105     linkedlist_datablock_internal* first_block;
106     linkedlist_datablock_internal* last_block;
107     } linkedlist_data;
108    
109    
110     typedef struct
111     {
112     z_stream stream; /* zLib stream structure for inflate */
113     int stream_initialised; /* 1 is stream is initialised */
114     uInt pos_in_buffered_data; /* last written byte in buffered_data */
115    
116     uLong pos_local_header; /* offset of the local header of the file
117     currenty writing */
118     char* central_header; /* central header data for the current file */
119     uLong size_centralheader; /* size of the central header for cur file */
120     uLong flag; /* flag of the file currently writing */
121    
122     int method; /* compression method of file currenty wr.*/
123     int raw; /* 1 for directly writing raw data */
124     Byte buffered_data[Z_BUFSIZE];/* buffer contain compressed data to be writ*/
125     uLong dosDate;
126     uLong crc32;
127     int encrypt;
128     #ifndef NOCRYPT
129     unsigned long keys[3]; /* keys defining the pseudo-random sequence */
130     const unsigned long* pcrc_32_tab;
131     int crypt_header_size;
132     #endif
133     } curfile_info;
134    
135     typedef struct
136     {
137     zlib_filefunc_def z_filefunc;
138     voidpf filestream; /* io structore of the zipfile */
139     linkedlist_data central_dir;/* datablock with central dir in construction*/
140     int in_opened_file_inzip; /* 1 if a file in the zip is currently writ.*/
141     curfile_info ci; /* info on the file curretly writing */
142    
143     uLong begin_pos; /* position of the beginning of the zipfile */
144     uLong add_position_when_writting_offset;
145     uLong number_entry;
146     } zip_internal;
147    
148    
149    
150     #ifndef NOCRYPT
151     #define INCLUDECRYPTINGCODE_IFCRYPTALLOWED
152     #include "crypt.h"
153     #endif
154    
155     local linkedlist_datablock_internal* allocate_new_datablock()
156     {
157     linkedlist_datablock_internal* ldi;
158     ldi = (linkedlist_datablock_internal*)
159     ALLOC(sizeof(linkedlist_datablock_internal));
160     if (ldi!=NULL)
161     {
162     ldi->next_datablock = NULL ;
163     ldi->filled_in_this_block = 0 ;
164     ldi->avail_in_this_block = SIZEDATA_INDATABLOCK ;
165     }
166     return ldi;
167     }
168    
169     local void free_datablock(ldi)
170     linkedlist_datablock_internal* ldi;
171     {
172     while (ldi!=NULL)
173     {
174     linkedlist_datablock_internal* ldinext = ldi->next_datablock;
175     TRYFREE(ldi);
176     ldi = ldinext;
177     }
178     }
179    
180     local void init_linkedlist(ll)
181     linkedlist_data* ll;
182     {
183     ll->first_block = ll->last_block = NULL;
184     }
185    
186     local void free_linkedlist(ll)
187     linkedlist_data* ll;
188     {
189     free_datablock(ll->first_block);
190     ll->first_block = ll->last_block = NULL;
191     }
192    
193    
194     local int add_data_in_datablock(ll,buf,len)
195     linkedlist_data* ll;
196     const void* buf;
197     uLong len;
198     {
199     linkedlist_datablock_internal* ldi;
200     const unsigned char* from_copy;
201    
202     if (ll==NULL)
203     return ZIP_INTERNALERROR;
204    
205     if (ll->last_block == NULL)
206     {
207     ll->first_block = ll->last_block = allocate_new_datablock();
208     if (ll->first_block == NULL)
209     return ZIP_INTERNALERROR;
210     }
211    
212     ldi = ll->last_block;
213     from_copy = (unsigned char*)buf;
214    
215     while (len>0)
216     {
217     uInt copy_this;
218     uInt i;
219     unsigned char* to_copy;
220    
221     if (ldi->avail_in_this_block==0)
222     {
223     ldi->next_datablock = allocate_new_datablock();
224     if (ldi->next_datablock == NULL)
225     return ZIP_INTERNALERROR;
226     ldi = ldi->next_datablock ;
227     ll->last_block = ldi;
228     }
229    
230     if (ldi->avail_in_this_block < len)
231     copy_this = (uInt)ldi->avail_in_this_block;
232     else
233     copy_this = (uInt)len;
234    
235     to_copy = &(ldi->data[ldi->filled_in_this_block]);
236    
237     for (i=0;i<copy_this;i++)
238     *(to_copy+i)=*(from_copy+i);
239    
240     ldi->filled_in_this_block += copy_this;
241     ldi->avail_in_this_block -= copy_this;
242     from_copy += copy_this ;
243     len -= copy_this;
244     }
245     return ZIP_OK;
246     }
247    
248    
249    
250     /****************************************************************************/
251    
252     #ifndef NO_ADDFILEINEXISTINGZIP
253     /* ===========================================================================
254     Inputs a long in LSB order to the given file
255     nbByte == 1, 2 or 4 (byte, short or long)
256     */
257    
258     local int ziplocal_putValue OF((const zlib_filefunc_def* pzlib_filefunc_def,
259     voidpf filestream, uLong x, int nbByte));
260     local int ziplocal_putValue (pzlib_filefunc_def, filestream, x, nbByte)
261     const zlib_filefunc_def* pzlib_filefunc_def;
262     voidpf filestream;
263     uLong x;
264     int nbByte;
265     {
266     unsigned char buf[4];
267     int n;
268     for (n = 0; n < nbByte; n++) {
269     buf[n] = (unsigned char)(x & 0xff);
270     x >>= 8;
271     }
272     if (ZWRITE(*pzlib_filefunc_def,filestream,buf,nbByte)!=(uLong)nbByte)
273     return ZIP_ERRNO;
274     else
275     return ZIP_OK;
276     }
277    
278     local void ziplocal_putValue_inmemory OF((void* dest, uLong x, int nbByte));
279     local void ziplocal_putValue_inmemory (dest, x, nbByte)
280     void* dest;
281     uLong x;
282     int nbByte;
283     {
284     unsigned char* buf=(unsigned char*)dest;
285     int n;
286     for (n = 0; n < nbByte; n++) {
287     buf[n] = (unsigned char)(x & 0xff);
288     x >>= 8;
289     }
290     }
291     /****************************************************************************/
292    
293    
294     local uLong ziplocal_TmzDateToDosDate(ptm,dosDate)
295     const tm_zip* ptm;
296     uLong dosDate;
297     {
298     uLong year = (uLong)ptm->tm_year;
299     if (year>1980)
300     year-=1980;
301     else if (year>80)
302     year-=80;
303     return
304     (uLong) (((ptm->tm_mday) + (32 * (ptm->tm_mon+1)) + (512 * year)) << 16) |
305     ((ptm->tm_sec/2) + (32* ptm->tm_min) + (2048 * (uLong)ptm->tm_hour));
306     }
307    
308    
309     /****************************************************************************/
310    
311     local int ziplocal_getByte OF((
312     const zlib_filefunc_def* pzlib_filefunc_def,
313     voidpf filestream,
314     int *pi));
315    
316     local int ziplocal_getByte(pzlib_filefunc_def,filestream,pi)
317     const zlib_filefunc_def* pzlib_filefunc_def;
318     voidpf filestream;
319     int *pi;
320     {
321     unsigned char c;
322     int err = (int)ZREAD(*pzlib_filefunc_def,filestream,&c,1);
323     if (err==1)
324     {
325     *pi = (int)c;
326     return ZIP_OK;
327     }
328     else
329     {
330     if (ZERROR(*pzlib_filefunc_def,filestream))
331     return ZIP_ERRNO;
332     else
333     return ZIP_EOF;
334     }
335     }
336    
337    
338     /* ===========================================================================
339     Reads a long in LSB order from the given gz_stream. Sets
340     */
341     local int ziplocal_getShort OF((
342     const zlib_filefunc_def* pzlib_filefunc_def,
343     voidpf filestream,
344     uLong *pX));
345    
346     local int ziplocal_getShort (pzlib_filefunc_def,filestream,pX)
347     const zlib_filefunc_def* pzlib_filefunc_def;
348     voidpf filestream;
349     uLong *pX;
350     {
351     uLong x ;
352     int i;
353     int err;
354    
355     err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
356     x = (uLong)i;
357    
358     if (err==ZIP_OK)
359     err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
360     x += ((uLong)i)<<8;
361    
362     if (err==ZIP_OK)
363     *pX = x;
364     else
365     *pX = 0;
366     return err;
367     }
368    
369     local int ziplocal_getLong OF((
370     const zlib_filefunc_def* pzlib_filefunc_def,
371     voidpf filestream,
372     uLong *pX));
373    
374     local int ziplocal_getLong (pzlib_filefunc_def,filestream,pX)
375     const zlib_filefunc_def* pzlib_filefunc_def;
376     voidpf filestream;
377     uLong *pX;
378     {
379     uLong x ;
380     int i;
381     int err;
382    
383     err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
384     x = (uLong)i;
385    
386     if (err==ZIP_OK)
387     err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
388     x += ((uLong)i)<<8;
389    
390     if (err==ZIP_OK)
391     err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
392     x += ((uLong)i)<<16;
393    
394     if (err==ZIP_OK)
395     err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
396     x += ((uLong)i)<<24;
397    
398     if (err==ZIP_OK)
399     *pX = x;
400     else
401     *pX = 0;
402     return err;
403     }
404    
405     #ifndef BUFREADCOMMENT
406     #define BUFREADCOMMENT (0x400)
407     #endif
408     /*
409     Locate the Central directory of a zipfile (at the end, just before
410     the global comment)
411     */
412     local uLong ziplocal_SearchCentralDir OF((
413     const zlib_filefunc_def* pzlib_filefunc_def,
414     voidpf filestream));
415    
416     local uLong ziplocal_SearchCentralDir(pzlib_filefunc_def,filestream)
417     const zlib_filefunc_def* pzlib_filefunc_def;
418     voidpf filestream;
419     {
420     unsigned char* buf;
421     uLong uSizeFile;
422     uLong uBackRead;
423     uLong uMaxBack=0xffff; /* maximum size of global comment */
424     uLong uPosFound=0;
425    
426     if (ZSEEK(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
427     return 0;
428    
429    
430     uSizeFile = ZTELL(*pzlib_filefunc_def,filestream);
431    
432     if (uMaxBack>uSizeFile)
433     uMaxBack = uSizeFile;
434    
435     buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
436     if (buf==NULL)
437     return 0;
438    
439     uBackRead = 4;
440     while (uBackRead<uMaxBack)
441     {
442     uLong uReadSize,uReadPos ;
443     int i;
444     if (uBackRead+BUFREADCOMMENT>uMaxBack)
445     uBackRead = uMaxBack;
446     else
447     uBackRead+=BUFREADCOMMENT;
448     uReadPos = uSizeFile-uBackRead ;
449    
450     uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
451     (BUFREADCOMMENT+4) : (uSizeFile-uReadPos);
452     if (ZSEEK(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
453     break;
454    
455     if (ZREAD(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
456     break;
457    
458     for (i=(int)uReadSize-3; (i--)>0;)
459     if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
460     ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
461     {
462     uPosFound = uReadPos+i;
463     break;
464     }
465    
466     if (uPosFound!=0)
467     break;
468     }
469     TRYFREE(buf);
470     return uPosFound;
471     }
472     #endif /* !NO_ADDFILEINEXISTINGZIP*/
473    
474     /************************************************************/
475     extern zipFile ZEXPORT zipOpen2 (pathname, append, globalcomment, pzlib_filefunc_def)
476     const char *pathname;
477     int append;
478     zipcharpc* globalcomment;
479     zlib_filefunc_def* pzlib_filefunc_def;
480     {
481     zip_internal ziinit;
482     zip_internal* zi;
483     int err=ZIP_OK;
484    
485    
486     if (pzlib_filefunc_def==NULL)
487     fill_fopen_filefunc(&ziinit.z_filefunc);
488     else
489     ziinit.z_filefunc = *pzlib_filefunc_def;
490    
491     ziinit.filestream = (*(ziinit.z_filefunc.zopen_file))
492     (ziinit.z_filefunc.opaque,
493     pathname,
494     (append == APPEND_STATUS_CREATE) ?
495     (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE) :
496     (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING));
497    
498     if (ziinit.filestream == NULL)
499     return NULL;
500     ziinit.begin_pos = ZTELL(ziinit.z_filefunc,ziinit.filestream);
501     ziinit.in_opened_file_inzip = 0;
502     ziinit.ci.stream_initialised = 0;
503     ziinit.number_entry = 0;
504     ziinit.add_position_when_writting_offset = 0;
505     init_linkedlist(&(ziinit.central_dir));
506    
507    
508     zi = (zip_internal*)ALLOC(sizeof(zip_internal));
509     if (zi==NULL)
510     {
511     ZCLOSE(ziinit.z_filefunc,ziinit.filestream);
512     return NULL;
513     }
514    
515     /* now we add file in a zipfile */
516     # ifndef NO_ADDFILEINEXISTINGZIP
517     if (append == APPEND_STATUS_ADDINZIP)
518     {
519     uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
520    
521     uLong size_central_dir; /* size of the central directory */
522     uLong offset_central_dir; /* offset of start of central directory */
523     uLong central_pos,uL;
524    
525     uLong number_disk; /* number of the current dist, used for
526     spaning ZIP, unsupported, always 0*/
527     uLong number_disk_with_CD; /* number the the disk with central dir, used
528     for spaning ZIP, unsupported, always 0*/
529     uLong number_entry;
530     uLong number_entry_CD; /* total number of entries in
531     the central dir
532     (same than number_entry on nospan) */
533     uLong size_comment;
534    
535     central_pos = ziplocal_SearchCentralDir(&ziinit.z_filefunc,ziinit.filestream);
536     if (central_pos==0)
537     err=ZIP_ERRNO;
538    
539     if (ZSEEK(ziinit.z_filefunc, ziinit.filestream,
540     central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
541     err=ZIP_ERRNO;
542    
543     /* the signature, already checked */
544     if (ziplocal_getLong(&ziinit.z_filefunc, ziinit.filestream,&uL)!=ZIP_OK)
545     err=ZIP_ERRNO;
546    
547     /* number of this disk */
548     if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_disk)!=ZIP_OK)
549     err=ZIP_ERRNO;
550    
551     /* number of the disk with the start of the central directory */
552     if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_disk_with_CD)!=ZIP_OK)
553     err=ZIP_ERRNO;
554    
555     /* total number of entries in the central dir on this disk */
556     if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_entry)!=ZIP_OK)
557     err=ZIP_ERRNO;
558    
559     /* total number of entries in the central dir */
560     if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_entry_CD)!=ZIP_OK)
561     err=ZIP_ERRNO;
562    
563     if ((number_entry_CD!=number_entry) ||
564     (number_disk_with_CD!=0) ||
565     (number_disk!=0))
566     err=ZIP_BADZIPFILE;
567    
568     /* size of the central directory */
569     if (ziplocal_getLong(&ziinit.z_filefunc, ziinit.filestream,&size_central_dir)!=ZIP_OK)
570     err=ZIP_ERRNO;
571    
572     /* offset of start of central directory with respect to the
573     starting disk number */
574     if (ziplocal_getLong(&ziinit.z_filefunc, ziinit.filestream,&offset_central_dir)!=ZIP_OK)
575     err=ZIP_ERRNO;
576    
577     /* zipfile comment length */
578     if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&size_comment)!=ZIP_OK)
579     err=ZIP_ERRNO;
580    
581     if ((central_pos<offset_central_dir+size_central_dir) &&
582     (err==ZIP_OK))
583     err=ZIP_BADZIPFILE;
584    
585     if (err!=ZIP_OK)
586     {
587     ZCLOSE(ziinit.z_filefunc, ziinit.filestream);
588     return NULL;
589     }
590    
591     byte_before_the_zipfile = central_pos -
592     (offset_central_dir+size_central_dir);
593     ziinit.add_position_when_writting_offset = byte_before_the_zipfile ;
594    
595     {
596     uLong size_central_dir_to_read = size_central_dir;
597     size_t buf_size = SIZEDATA_INDATABLOCK;
598     void* buf_read = (void*)ALLOC(buf_size);
599     if (ZSEEK(ziinit.z_filefunc, ziinit.filestream,
600     offset_central_dir + byte_before_the_zipfile,
601     ZLIB_FILEFUNC_SEEK_SET) != 0)
602     err=ZIP_ERRNO;
603    
604     while ((size_central_dir_to_read>0) && (err==ZIP_OK))
605     {
606     uLong read_this = SIZEDATA_INDATABLOCK;
607     if (read_this > size_central_dir_to_read)
608     read_this = size_central_dir_to_read;
609     if (ZREAD(ziinit.z_filefunc, ziinit.filestream,buf_read,read_this) != read_this)
610     err=ZIP_ERRNO;
611    
612     if (err==ZIP_OK)
613     err = add_data_in_datablock(&ziinit.central_dir,buf_read,
614     (uLong)read_this);
615     size_central_dir_to_read-=read_this;
616     }
617     TRYFREE(buf_read);
618     }
619     ziinit.begin_pos = byte_before_the_zipfile;
620     ziinit.number_entry = number_entry_CD;
621    
622     if (ZSEEK(ziinit.z_filefunc, ziinit.filestream,
623     offset_central_dir+byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0)
624     err=ZIP_ERRNO;
625     }
626     # endif /* !NO_ADDFILEINEXISTINGZIP*/
627    
628     if (err != ZIP_OK)
629     {
630     TRYFREE(zi);
631     return NULL;
632     }
633     else
634     {
635     *zi = ziinit;
636     return (zipFile)zi;
637     }
638     }
639    
640     extern zipFile ZEXPORT zipOpen (pathname, append)
641     const char *pathname;
642     int append;
643     {
644     return zipOpen2(pathname,append,NULL,NULL);
645     }
646    
647     extern int ZEXPORT zipOpenNewFileInZip3 (file, filename, zipfi,
648     extrafield_local, size_extrafield_local,
649     extrafield_global, size_extrafield_global,
650     comment, method, level, raw,
651     windowBits, memLevel, strategy,
652     password, crcForCrypting)
653     zipFile file;
654     const char* filename;
655     const zip_fileinfo* zipfi;
656     const void* extrafield_local;
657     uInt size_extrafield_local;
658     const void* extrafield_global;
659     uInt size_extrafield_global;
660     const char* comment;
661     int method;
662     int level;
663     int raw;
664     int windowBits;
665     int memLevel;
666     int strategy;
667     const char* password;
668     uLong crcForCrypting;
669     {
670     zip_internal* zi;
671     uInt size_filename;
672     uInt size_comment;
673     uInt i;
674     int err = ZIP_OK;
675    
676     # ifdef NOCRYPT
677     if (password != NULL)
678     return ZIP_PARAMERROR;
679     # endif
680    
681     if (file == NULL)
682     return ZIP_PARAMERROR;
683     if ((method!=0) && (method!=Z_DEFLATED))
684     return ZIP_PARAMERROR;
685    
686     zi = (zip_internal*)file;
687    
688     if (zi->in_opened_file_inzip == 1)
689     {
690     err = zipCloseFileInZip (file);
691     if (err != ZIP_OK)
692     return err;
693     }
694    
695    
696     if (filename==NULL)
697     filename="-";
698    
699     if (comment==NULL)
700     size_comment = 0;
701     else
702     size_comment = strlen(comment);
703    
704     size_filename = strlen(filename);
705    
706     if (zipfi == NULL)
707     zi->ci.dosDate = 0;
708     else
709     {
710     if (zipfi->dosDate != 0)
711     zi->ci.dosDate = zipfi->dosDate;
712     else zi->ci.dosDate = ziplocal_TmzDateToDosDate(&zipfi->tmz_date,zipfi->dosDate);
713     }
714    
715     zi->ci.flag = 0;
716     if ((level==8) || (level==9))
717     zi->ci.flag |= 2;
718     if ((level==2))
719     zi->ci.flag |= 4;
720     if ((level==1))
721     zi->ci.flag |= 6;
722     if (password != NULL)
723     zi->ci.flag |= 1;
724    
725     zi->ci.crc32 = 0;
726     zi->ci.method = method;
727     zi->ci.encrypt = 0;
728     zi->ci.stream_initialised = 0;
729     zi->ci.pos_in_buffered_data = 0;
730     zi->ci.raw = raw;
731     zi->ci.pos_local_header = ZTELL(zi->z_filefunc,zi->filestream) ;
732     zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename +
733     size_extrafield_global + size_comment;
734     zi->ci.central_header = (char*)ALLOC((uInt)zi->ci.size_centralheader);
735    
736     ziplocal_putValue_inmemory(zi->ci.central_header,(uLong)CENTRALHEADERMAGIC,4);
737     /* version info */
738     ziplocal_putValue_inmemory(zi->ci.central_header+4,(uLong)VERSIONMADEBY,2);
739     ziplocal_putValue_inmemory(zi->ci.central_header+6,(uLong)20,2);
740     ziplocal_putValue_inmemory(zi->ci.central_header+8,(uLong)zi->ci.flag,2);
741     ziplocal_putValue_inmemory(zi->ci.central_header+10,(uLong)zi->ci.method,2);
742     ziplocal_putValue_inmemory(zi->ci.central_header+12,(uLong)zi->ci.dosDate,4);
743     ziplocal_putValue_inmemory(zi->ci.central_header+16,(uLong)0,4); /*crc*/
744     ziplocal_putValue_inmemory(zi->ci.central_header+20,(uLong)0,4); /*compr size*/
745     ziplocal_putValue_inmemory(zi->ci.central_header+24,(uLong)0,4); /*uncompr size*/
746     ziplocal_putValue_inmemory(zi->ci.central_header+28,(uLong)size_filename,2);
747     ziplocal_putValue_inmemory(zi->ci.central_header+30,(uLong)size_extrafield_global,2);
748     ziplocal_putValue_inmemory(zi->ci.central_header+32,(uLong)size_comment,2);
749     ziplocal_putValue_inmemory(zi->ci.central_header+34,(uLong)0,2); /*disk nm start*/
750    
751     if (zipfi==NULL)
752     ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)0,2);
753     else
754     ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)zipfi->internal_fa,2);
755    
756     if (zipfi==NULL)
757     ziplocal_putValue_inmemory(zi->ci.central_header+38,(uLong)0,4);
758     else
759     ziplocal_putValue_inmemory(zi->ci.central_header+38,(uLong)zipfi->external_fa,4);
760    
761     ziplocal_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_local_header- zi->add_position_when_writting_offset,4);
762    
763     for (i=0;i<size_filename;i++)
764     *(zi->ci.central_header+SIZECENTRALHEADER+i) = *(filename+i);
765    
766     for (i=0;i<size_extrafield_global;i++)
767     *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+i) =
768     *(((const char*)extrafield_global)+i);
769    
770     for (i=0;i<size_comment;i++)
771     *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+
772     size_extrafield_global+i) = *(comment+i);
773     if (zi->ci.central_header == NULL)
774     return ZIP_INTERNALERROR;
775    
776     /* write the local header */
777     err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)LOCALHEADERMAGIC,4);
778    
779     if (err==ZIP_OK)
780     err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)20,2);/* version needed to extract */
781     if (err==ZIP_OK)
782     err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.flag,2);
783    
784     if (err==ZIP_OK)
785     err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.method,2);
786    
787     if (err==ZIP_OK)
788     err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.dosDate,4);
789    
790     if (err==ZIP_OK)
791     err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* crc 32, unknown */
792     if (err==ZIP_OK)
793     err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* compressed size, unknown */
794     if (err==ZIP_OK)
795     err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* uncompressed size, unknown */
796    
797     if (err==ZIP_OK)
798     err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_filename,2);
799    
800     if (err==ZIP_OK)
801     err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_extrafield_local,2);
802    
803     if ((err==ZIP_OK) && (size_filename>0))
804     if (ZWRITE(zi->z_filefunc,zi->filestream,filename,size_filename)!=size_filename)
805     err = ZIP_ERRNO;
806    
807     if ((err==ZIP_OK) && (size_extrafield_local>0))
808     if (ZWRITE(zi->z_filefunc,zi->filestream,extrafield_local,size_extrafield_local)
809     !=size_extrafield_local)
810     err = ZIP_ERRNO;
811    
812     zi->ci.stream.avail_in = (uInt)0;
813     zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
814     zi->ci.stream.next_out = zi->ci.buffered_data;
815     zi->ci.stream.total_in = 0;
816     zi->ci.stream.total_out = 0;
817    
818     if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
819     {
820     zi->ci.stream.zalloc = (alloc_func)0;
821     zi->ci.stream.zfree = (free_func)0;
822     zi->ci.stream.opaque = (voidpf)0;
823    
824     if (windowBits>0)
825     windowBits = -windowBits;
826    
827     err = deflateInit2(&zi->ci.stream, level,
828     Z_DEFLATED, windowBits, memLevel, strategy);
829    
830     if (err==Z_OK)
831     zi->ci.stream_initialised = 1;
832     }
833     # ifndef NOCRYPT
834     zi->ci.crypt_header_size = 0;
835     if ((err==Z_OK) && (password != NULL))
836     {
837     unsigned char bufHead[RAND_HEAD_LEN];
838     unsigned int sizeHead;
839     zi->ci.encrypt = 1;
840     zi->ci.pcrc_32_tab = get_crc_table();
841     /*init_keys(password,zi->ci.keys,zi->ci.pcrc_32_tab);*/
842    
843     sizeHead=crypthead(password,bufHead,RAND_HEAD_LEN,zi->ci.keys,zi->ci.pcrc_32_tab,crcForCrypting);
844     zi->ci.crypt_header_size = sizeHead;
845    
846     if (ZWRITE(zi->z_filefunc,zi->filestream,bufHead,sizeHead) != sizeHead)
847     err = ZIP_ERRNO;
848     }
849     # endif
850    
851     if (err==Z_OK)
852     zi->in_opened_file_inzip = 1;
853     return err;
854     }
855    
856     extern int ZEXPORT zipOpenNewFileInZip2(file, filename, zipfi,
857     extrafield_local, size_extrafield_local,
858     extrafield_global, size_extrafield_global,
859     comment, method, level, raw)
860     zipFile file;
861     const char* filename;
862     const zip_fileinfo* zipfi;
863     const void* extrafield_local;
864     uInt size_extrafield_local;
865     const void* extrafield_global;
866     uInt size_extrafield_global;
867     const char* comment;
868     int method;
869     int level;
870     int raw;
871     {
872     return zipOpenNewFileInZip3 (file, filename, zipfi,
873     extrafield_local, size_extrafield_local,
874     extrafield_global, size_extrafield_global,
875     comment, method, level, raw,
876     -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
877     NULL, 0);
878     }
879    
880     extern int ZEXPORT zipOpenNewFileInZip (file, filename, zipfi,
881     extrafield_local, size_extrafield_local,
882     extrafield_global, size_extrafield_global,
883     comment, method, level)
884     zipFile file;
885     const char* filename;
886     const zip_fileinfo* zipfi;
887     const void* extrafield_local;
888     uInt size_extrafield_local;
889     const void* extrafield_global;
890     uInt size_extrafield_global;
891     const char* comment;
892     int method;
893     int level;
894     {
895     return zipOpenNewFileInZip2 (file, filename, zipfi,
896     extrafield_local, size_extrafield_local,
897     extrafield_global, size_extrafield_global,
898     comment, method, level, 0);
899     }
900    
901     local int zipFlushWriteBuffer(zi)
902     zip_internal* zi;
903     {
904     int err=ZIP_OK;
905    
906     if (zi->ci.encrypt != 0)
907     {
908     #ifndef NOCRYPT
909     uInt i;
910     int t;
911     for (i=0;i<zi->ci.pos_in_buffered_data;i++)
912     zi->ci.buffered_data[i] = zencode(zi->ci.keys, zi->ci.pcrc_32_tab,
913     zi->ci.buffered_data[i],t);
914     #endif
915     }
916     if (ZWRITE(zi->z_filefunc,zi->filestream,zi->ci.buffered_data,zi->ci.pos_in_buffered_data)
917     !=zi->ci.pos_in_buffered_data)
918     err = ZIP_ERRNO;
919     zi->ci.pos_in_buffered_data = 0;
920     return err;
921     }
922    
923     extern int ZEXPORT zipWriteInFileInZip (file, buf, len)
924     zipFile file;
925     const void* buf;
926     unsigned len;
927     {
928     zip_internal* zi;
929     int err=ZIP_OK;
930    
931     if (file == NULL)
932     return ZIP_PARAMERROR;
933     zi = (zip_internal*)file;
934    
935     if (zi->in_opened_file_inzip == 0)
936     return ZIP_PARAMERROR;
937    
938     zi->ci.stream.next_in = (void*)buf;
939     zi->ci.stream.avail_in = len;
940     zi->ci.crc32 = crc32(zi->ci.crc32,buf,len);
941    
942     while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0))
943     {
944     if (zi->ci.stream.avail_out == 0)
945     {
946     if (zipFlushWriteBuffer(zi) == ZIP_ERRNO)
947     err = ZIP_ERRNO;
948     zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
949     zi->ci.stream.next_out = zi->ci.buffered_data;
950     }
951    
952    
953     if(err != ZIP_OK)
954     break;
955    
956     if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
957     {
958     uLong uTotalOutBefore = zi->ci.stream.total_out;
959     err=deflate(&zi->ci.stream, Z_NO_FLUSH);
960     zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;
961    
962     }
963     else
964     {
965     uInt copy_this,i;
966     if (zi->ci.stream.avail_in < zi->ci.stream.avail_out)
967     copy_this = zi->ci.stream.avail_in;
968     else
969     copy_this = zi->ci.stream.avail_out;
970     for (i=0;i<copy_this;i++)
971     *(((char*)zi->ci.stream.next_out)+i) =
972     *(((const char*)zi->ci.stream.next_in)+i);
973     {
974     zi->ci.stream.avail_in -= copy_this;
975     zi->ci.stream.avail_out-= copy_this;
976     zi->ci.stream.next_in+= copy_this;
977     zi->ci.stream.next_out+= copy_this;
978     zi->ci.stream.total_in+= copy_this;
979     zi->ci.stream.total_out+= copy_this;
980     zi->ci.pos_in_buffered_data += copy_this;
981     }
982     }
983     }
984    
985     return err;
986     }
987    
988     extern int ZEXPORT zipCloseFileInZipRaw (file, uncompressed_size, crc32)
989     zipFile file;
990     uLong uncompressed_size;
991     uLong crc32;
992     {
993     zip_internal* zi;
994     uLong compressed_size;
995     int err=ZIP_OK;
996    
997     if (file == NULL)
998     return ZIP_PARAMERROR;
999     zi = (zip_internal*)file;
1000    
1001     if (zi->in_opened_file_inzip == 0)
1002     return ZIP_PARAMERROR;
1003     zi->ci.stream.avail_in = 0;
1004    
1005     if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
1006     while (err==ZIP_OK)
1007     {
1008     uLong uTotalOutBefore;
1009     if (zi->ci.stream.avail_out == 0)
1010     {
1011     if (zipFlushWriteBuffer(zi) == ZIP_ERRNO)
1012     err = ZIP_ERRNO;
1013     zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
1014     zi->ci.stream.next_out = zi->ci.buffered_data;
1015     }
1016     uTotalOutBefore = zi->ci.stream.total_out;
1017     err=deflate(&zi->ci.stream, Z_FINISH);
1018     zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;
1019     }
1020    
1021     if (err==Z_STREAM_END)
1022     err=ZIP_OK; /* this is normal */
1023    
1024     if ((zi->ci.pos_in_buffered_data>0) && (err==ZIP_OK))
1025     if (zipFlushWriteBuffer(zi)==ZIP_ERRNO)
1026     err = ZIP_ERRNO;
1027    
1028     if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
1029     {
1030     err=deflateEnd(&zi->ci.stream);
1031     zi->ci.stream_initialised = 0;
1032     }
1033    
1034     if (!zi->ci.raw)
1035     {
1036     crc32 = (uLong)zi->ci.crc32;
1037     uncompressed_size = (uLong)zi->ci.stream.total_in;
1038     }
1039     compressed_size = (uLong)zi->ci.stream.total_out;
1040     # ifndef NOCRYPT
1041     compressed_size += zi->ci.crypt_header_size;
1042     # endif
1043    
1044     ziplocal_putValue_inmemory(zi->ci.central_header+16,crc32,4); /*crc*/
1045     ziplocal_putValue_inmemory(zi->ci.central_header+20,
1046     compressed_size,4); /*compr size*/
1047     if (zi->ci.stream.data_type == Z_ASCII)
1048     ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)Z_ASCII,2);
1049     ziplocal_putValue_inmemory(zi->ci.central_header+24,
1050     uncompressed_size,4); /*uncompr size*/
1051    
1052     if (err==ZIP_OK)
1053     err = add_data_in_datablock(&zi->central_dir,zi->ci.central_header,
1054     (uLong)zi->ci.size_centralheader);
1055     free(zi->ci.central_header);
1056    
1057     if (err==ZIP_OK)
1058     {
1059     long cur_pos_inzip = ZTELL(zi->z_filefunc,zi->filestream);
1060     if (ZSEEK(zi->z_filefunc,zi->filestream,
1061     zi->ci.pos_local_header + 14,ZLIB_FILEFUNC_SEEK_SET)!=0)
1062     err = ZIP_ERRNO;
1063    
1064     if (err==ZIP_OK)
1065     err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */
1066    
1067     if (err==ZIP_OK) /* compressed size, unknown */
1068     err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,compressed_size,4);
1069    
1070     if (err==ZIP_OK) /* uncompressed size, unknown */
1071     err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,4);
1072    
1073     if (ZSEEK(zi->z_filefunc,zi->filestream,
1074     cur_pos_inzip,ZLIB_FILEFUNC_SEEK_SET)!=0)
1075     err = ZIP_ERRNO;
1076     }
1077    
1078     zi->number_entry ++;
1079     zi->in_opened_file_inzip = 0;
1080    
1081     return err;
1082     }
1083    
1084     extern int ZEXPORT zipCloseFileInZip (file)
1085     zipFile file;
1086     {
1087     return zipCloseFileInZipRaw (file,0,0);
1088     }
1089    
1090     extern int ZEXPORT zipClose (file, global_comment)
1091     zipFile file;
1092     const char* global_comment;
1093     {
1094     zip_internal* zi;
1095     int err = 0;
1096     uLong size_centraldir = 0;
1097     uLong centraldir_pos_inzip ;
1098     uInt size_global_comment;
1099     if (file == NULL)
1100     return ZIP_PARAMERROR;
1101     zi = (zip_internal*)file;
1102    
1103     if (zi->in_opened_file_inzip == 1)
1104     {
1105     err = zipCloseFileInZip (file);
1106     }
1107    
1108     if (global_comment==NULL)
1109     size_global_comment = 0;
1110     else
1111     size_global_comment = strlen(global_comment);
1112    
1113    
1114     centraldir_pos_inzip = ZTELL(zi->z_filefunc,zi->filestream);
1115     if (err==ZIP_OK)
1116     {
1117     linkedlist_datablock_internal* ldi = zi->central_dir.first_block ;
1118     while (ldi!=NULL)
1119     {
1120     if ((err==ZIP_OK) && (ldi->filled_in_this_block>0))
1121     if (ZWRITE(zi->z_filefunc,zi->filestream,
1122     ldi->data,ldi->filled_in_this_block)
1123     !=ldi->filled_in_this_block )
1124     err = ZIP_ERRNO;
1125    
1126     size_centraldir += ldi->filled_in_this_block;
1127     ldi = ldi->next_datablock;
1128     }
1129     }
1130     free_datablock(zi->central_dir.first_block);
1131    
1132     if (err==ZIP_OK) /* Magic End */
1133     err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)ENDHEADERMAGIC,4);
1134    
1135     if (err==ZIP_OK) /* number of this disk */
1136     err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);
1137    
1138     if (err==ZIP_OK) /* number of the disk with the start of the central directory */
1139     err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);
1140    
1141     if (err==ZIP_OK) /* total number of entries in the central dir on this disk */
1142     err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
1143    
1144     if (err==ZIP_OK) /* total number of entries in the central dir */
1145     err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
1146    
1147     if (err==ZIP_OK) /* size of the central directory */
1148     err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_centraldir,4);
1149    
1150     if (err==ZIP_OK) /* offset of start of central directory with respect to the
1151     starting disk number */
1152     err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,
1153     (uLong)(centraldir_pos_inzip - zi->add_position_when_writting_offset),4);
1154    
1155     if (err==ZIP_OK) /* zipfile comment length */
1156     err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_global_comment,2);
1157    
1158     if ((err==ZIP_OK) && (size_global_comment>0))
1159     if (ZWRITE(zi->z_filefunc,zi->filestream,
1160     global_comment,size_global_comment) != size_global_comment)
1161     err = ZIP_ERRNO;
1162    
1163     if (ZCLOSE(zi->z_filefunc,zi->filestream) != 0)
1164     if (err == ZIP_OK)
1165     err = ZIP_ERRNO;
1166    
1167     TRYFREE(zi);
1168    
1169     return err;
1170     }

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26