~ubuntu-branches/ubuntu/maverick/psi/maverick

« back to all changes in this revision

Viewing changes to src/tools/zip/minizip/other/zip.c

  • Committer: Bazaar Package Importer
  • Author(s): Jan Niehusmann
  • Date: 2006-01-20 00:20:36 UTC
  • mfrom: (1.2.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20060120002036-7nw6yo6totip0ee5
Tags: 0.10-2
* Added upstream changelog (Closes: Bug#327748)
* Mention --no-gpg and --no-gpg-agent in manpage (Closes: Bug#204416)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* zip.c -- IO on .zip files using zlib 
 
2
   Version 0.15 beta, Mar 19th, 1998,
 
3
 
 
4
   Read zip.h for more info
 
5
*/
 
6
 
 
7
 
 
8
#include <stdio.h>
 
9
#include <stdlib.h>
 
10
#include <string.h>
 
11
#include "zlib.h"
 
12
#include "zip.h"
 
13
 
 
14
#ifdef STDC
 
15
#  include <stddef.h>
 
16
#  include <string.h>
 
17
#  include <stdlib.h>
 
18
#endif
 
19
#ifdef NO_ERRNO_H
 
20
    extern int errno;
 
21
#else
 
22
#   include <errno.h>
 
23
#endif
 
24
 
 
25
 
 
26
#ifndef local
 
27
#  define local static
 
28
#endif
 
29
/* compile with -Dlocal if your debugger can't find static symbols */
 
30
 
 
31
#ifndef VERSIONMADEBY
 
32
# define VERSIONMADEBY   (0x0) /* platform depedent */
 
33
#endif
 
34
 
 
35
#ifndef Z_BUFSIZE
 
36
#define Z_BUFSIZE (16384)
 
37
#endif
 
38
 
 
39
#ifndef Z_MAXFILENAMEINZIP
 
40
#define Z_MAXFILENAMEINZIP (256)
 
41
#endif
 
42
 
 
43
#ifndef ALLOC
 
44
# define ALLOC(size) (malloc(size))
 
45
#endif
 
46
#ifndef TRYFREE
 
47
# define TRYFREE(p) {if (p) free(p);}
 
48
#endif
 
49
 
 
50
/*
 
51
#define SIZECENTRALDIRITEM (0x2e)
 
52
#define SIZEZIPLOCALHEADER (0x1e)
 
53
*/
 
54
 
 
55
/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
 
56
 
 
57
#ifndef SEEK_CUR
 
58
#define SEEK_CUR    1
 
59
#endif
 
60
 
 
61
#ifndef SEEK_END
 
62
#define SEEK_END    2
 
63
#endif
 
64
 
 
65
#ifndef SEEK_SET
 
66
#define SEEK_SET    0
 
67
#endif
 
68
 
 
69
const char zip_copyright[] =
 
70
   " zip 0.15 Copyright 1998 Gilles Vollant ";
 
71
 
 
72
 
 
73
#define SIZEDATA_INDATABLOCK (4096-(4*4))
 
74
 
 
75
#define LOCALHEADERMAGIC    (0x04034b50)
 
76
#define CENTRALHEADERMAGIC  (0x02014b50)
 
77
#define ENDHEADERMAGIC      (0x06054b50)
 
78
 
 
79
#define FLAG_LOCALHEADER_OFFSET (0x06)
 
80
#define CRC_LOCALHEADER_OFFSET  (0x0e)
 
81
 
 
82
#define SIZECENTRALHEADER (0x2e) /* 46 */
 
83
 
 
84
typedef struct linkedlist_datablock_internal_s
 
85
{
 
86
  struct linkedlist_datablock_internal_s* next_datablock;
 
87
  uLong  avail_in_this_block;
 
88
  uLong  filled_in_this_block;
 
89
  uLong  unused; /* for future use and alignement */
 
90
  unsigned char data[SIZEDATA_INDATABLOCK];
 
91
} linkedlist_datablock_internal;
 
92
 
 
93
typedef struct linkedlist_data_s
 
94
{
 
95
    linkedlist_datablock_internal* first_block;
 
96
    linkedlist_datablock_internal* last_block;
 
97
} linkedlist_data;
 
98
 
 
99
 
 
100
typedef struct
 
101
{
 
102
        z_stream stream;            /* zLib stream structure for inflate */
 
103
    int  stream_initialised;    /* 1 is stream is initialised */
 
104
    uInt pos_in_buffered_data;  /* last written byte in buffered_data */
 
105
 
 
106
    uLong pos_local_header;     /* offset of the local header of the file 
 
107
                                     currenty writing */
 
108
    char* central_header;       /* central header data for the current file */
 
109
    uLong size_centralheader;   /* size of the central header for cur file */
 
110
    uLong flag;                 /* flag of the file currently writing */
 
111
 
 
112
    int  method;                /* compression method of file currenty wr.*/
 
113
    Byte buffered_data[Z_BUFSIZE];/* buffer contain compressed data to be writ*/
 
114
    uLong dosDate;
 
115
    uLong crc32;
 
116
} curfile_info;
 
117
 
 
118
typedef struct
 
119
{
 
120
    FILE * filezip;
 
121
    linkedlist_data central_dir;/* datablock with central dir in construction*/
 
122
    int  in_opened_file_inzip;  /* 1 if a file in the zip is currently writ.*/
 
123
    curfile_info ci;            /* info on the file curretly writing */
 
124
 
 
125
    uLong begin_pos;            /* position of the beginning of the zipfile */
 
126
    uLong number_entry;
 
127
} zip_internal;
 
128
 
 
129
local linkedlist_datablock_internal* allocate_new_datablock()
 
130
{
 
131
    linkedlist_datablock_internal* ldi;
 
132
    ldi = (linkedlist_datablock_internal*)
 
133
                 ALLOC(sizeof(linkedlist_datablock_internal));
 
134
    if (ldi!=NULL)
 
135
    {
 
136
        ldi->next_datablock = NULL ;
 
137
        ldi->filled_in_this_block = 0 ;
 
138
        ldi->avail_in_this_block = SIZEDATA_INDATABLOCK ;
 
139
    }
 
140
    return ldi;
 
141
}
 
142
 
 
143
local void free_datablock(ldi)
 
144
    linkedlist_datablock_internal* ldi;
 
145
{
 
146
    while (ldi!=NULL)
 
147
    {
 
148
        linkedlist_datablock_internal* ldinext = ldi->next_datablock;
 
149
        TRYFREE(ldi);
 
150
        ldi = ldinext;
 
151
    }
 
152
}
 
153
 
 
154
local void init_linkedlist(ll)
 
155
    linkedlist_data* ll;
 
156
{
 
157
    ll->first_block = ll->last_block = NULL;
 
158
}
 
159
 
 
160
local void free_linkedlist(ll)
 
161
    linkedlist_data* ll;
 
162
{
 
163
    free_datablock(ll->first_block);
 
164
    ll->first_block = ll->last_block = NULL;
 
165
}
 
166
 
 
167
 
 
168
local int add_data_in_datablock(ll,buf,len)
 
169
    linkedlist_data* ll;    
 
170
    const void* buf;
 
171
    uLong len;
 
172
{
 
173
    linkedlist_datablock_internal* ldi;
 
174
    const unsigned char* from_copy;
 
175
 
 
176
    if (ll==NULL)
 
177
        return ZIP_INTERNALERROR;
 
178
 
 
179
    if (ll->last_block == NULL)
 
180
    {
 
181
        ll->first_block = ll->last_block = allocate_new_datablock();
 
182
        if (ll->first_block == NULL)
 
183
            return ZIP_INTERNALERROR;
 
184
    }
 
185
 
 
186
    ldi = ll->last_block;
 
187
    from_copy = (unsigned char*)buf;
 
188
 
 
189
    while (len>0)
 
190
    {
 
191
        uInt copy_this;
 
192
        uInt i;
 
193
        unsigned char* to_copy;
 
194
 
 
195
        if (ldi->avail_in_this_block==0)
 
196
        {
 
197
            ldi->next_datablock = allocate_new_datablock();
 
198
            if (ldi->next_datablock == NULL)
 
199
                return ZIP_INTERNALERROR;
 
200
            ldi = ldi->next_datablock ;
 
201
            ll->last_block = ldi;
 
202
        }
 
203
 
 
204
        if (ldi->avail_in_this_block < len)
 
205
            copy_this = (uInt)ldi->avail_in_this_block;
 
206
        else
 
207
            copy_this = (uInt)len;
 
208
 
 
209
        to_copy = &(ldi->data[ldi->filled_in_this_block]);
 
210
 
 
211
        for (i=0;i<copy_this;i++)
 
212
            *(to_copy+i)=*(from_copy+i);
 
213
 
 
214
        ldi->filled_in_this_block += copy_this;
 
215
        ldi->avail_in_this_block -= copy_this;
 
216
        from_copy += copy_this ;
 
217
        len -= copy_this;
 
218
    }
 
219
    return ZIP_OK;
 
220
}
 
221
 
 
222
 
 
223
local int write_datablock(fout,ll)
 
224
    FILE * fout;
 
225
    linkedlist_data* ll;    
 
226
{
 
227
    linkedlist_datablock_internal* ldi;
 
228
    ldi = ll->first_block;
 
229
    while (ldi!=NULL)
 
230
    {
 
231
        if (ldi->filled_in_this_block > 0)
 
232
            if (fwrite(ldi->data,(uInt)ldi->filled_in_this_block,1,fout)!=1)
 
233
                return ZIP_ERRNO;
 
234
        ldi = ldi->next_datablock;
 
235
    }
 
236
    return ZIP_OK;
 
237
}
 
238
 
 
239
/****************************************************************************/
 
240
 
 
241
/* ===========================================================================
 
242
   Outputs a long in LSB order to the given file
 
243
   nbByte == 1, 2 or 4 (byte, short or long)
 
244
*/
 
245
 
 
246
local int ziplocal_putValue OF((FILE *file, uLong x, int nbByte));
 
247
local int ziplocal_putValue (file, x, nbByte)
 
248
    FILE *file;
 
249
    uLong x;
 
250
    int nbByte;
 
251
{
 
252
    unsigned char buf[4];
 
253
    int n;
 
254
    for (n = 0; n < nbByte; n++) {
 
255
        buf[n] = (unsigned char)(x & 0xff);
 
256
        x >>= 8;
 
257
    }
 
258
    if (fwrite(buf,nbByte,1,file)!=1)
 
259
        return ZIP_ERRNO;
 
260
    else
 
261
        return ZIP_OK;
 
262
}
 
263
 
 
264
local void ziplocal_putValue_inmemory OF((void* dest, uLong x, int nbByte));
 
265
local void ziplocal_putValue_inmemory (dest, x, nbByte)
 
266
    void* dest;
 
267
    uLong x;
 
268
    int nbByte;
 
269
{
 
270
    unsigned char* buf=(unsigned char*)dest;
 
271
    int n;
 
272
    for (n = 0; n < nbByte; n++) {
 
273
        buf[n] = (unsigned char)(x & 0xff);
 
274
        x >>= 8;
 
275
    }
 
276
}
 
277
/****************************************************************************/
 
278
 
 
279
 
 
280
local uLong ziplocal_TmzDateToDosDate(ptm,dosDate)
 
281
    tm_zip* ptm;
 
282
    uLong dosDate;
 
283
{
 
284
    uLong year = (uLong)ptm->tm_year;
 
285
    if (year>1980)
 
286
        year-=1980;
 
287
    else if (year>80)
 
288
        year-=80;
 
289
    return
 
290
      (uLong) (((ptm->tm_mday) + (32 * (ptm->tm_mon+1)) + (512 * year)) << 16) |
 
291
        ((ptm->tm_sec/2) + (32* ptm->tm_min) + (2048 * (uLong)ptm->tm_hour));
 
292
}
 
293
 
 
294
 
 
295
/****************************************************************************/
 
296
 
 
297
extern zipFile ZEXPORT zipOpen (pathname, append)
 
298
    const char *pathname;
 
299
    int append;
 
300
{
 
301
    zip_internal ziinit;
 
302
    zip_internal* zi;
 
303
 
 
304
    ziinit.filezip = fopen(pathname,(append == 0) ? "wb" : "ab");
 
305
    if (ziinit.filezip == NULL)
 
306
        return NULL;
 
307
    ziinit.begin_pos = ftell(ziinit.filezip);
 
308
    ziinit.in_opened_file_inzip = 0;
 
309
    ziinit.ci.stream_initialised = 0;
 
310
    ziinit.number_entry = 0;
 
311
    init_linkedlist(&(ziinit.central_dir));
 
312
 
 
313
 
 
314
    zi = (zip_internal*)ALLOC(sizeof(zip_internal));
 
315
    if (zi==NULL)
 
316
    {
 
317
        fclose(ziinit.filezip);
 
318
        return NULL;
 
319
    }
 
320
 
 
321
    *zi = ziinit;
 
322
    return (zipFile)zi;
 
323
}
 
324
 
 
325
extern int ZEXPORT zipOpenNewFileInZip (file, filename, zipfi, 
 
326
                                        extrafield_local, size_extrafield_local,
 
327
                                        extrafield_global, size_extrafield_global,
 
328
                                        comment, method, level)
 
329
    zipFile file;
 
330
    const char* filename;
 
331
    const zip_fileinfo* zipfi;
 
332
    const void* extrafield_local;
 
333
    uInt size_extrafield_local;
 
334
    const void* extrafield_global;
 
335
    uInt size_extrafield_global;
 
336
    const char* comment;
 
337
    int method;
 
338
    int level;
 
339
{
 
340
    zip_internal* zi;
 
341
    uInt size_filename;
 
342
    uInt size_comment;
 
343
    uInt i;
 
344
    int err = ZIP_OK;
 
345
 
 
346
    if (file == NULL)
 
347
        return ZIP_PARAMERROR;
 
348
    if ((method!=0) && (method!=Z_DEFLATED))
 
349
        return ZIP_PARAMERROR;
 
350
 
 
351
    zi = (zip_internal*)file;
 
352
 
 
353
    if (zi->in_opened_file_inzip == 1)
 
354
    {
 
355
        err = zipCloseFileInZip (file);
 
356
        if (err != ZIP_OK)
 
357
            return err;
 
358
    }
 
359
 
 
360
 
 
361
    if (filename==NULL)
 
362
        filename="-";
 
363
 
 
364
    if (comment==NULL)
 
365
        size_comment = 0;
 
366
    else
 
367
        size_comment = strlen(comment);
 
368
 
 
369
    size_filename = strlen(filename);
 
370
 
 
371
    if (zipfi == NULL)
 
372
        zi->ci.dosDate = 0;
 
373
    else
 
374
    {
 
375
        if (zipfi->dosDate != 0)
 
376
            zi->ci.dosDate = zipfi->dosDate;
 
377
        else zi->ci.dosDate = ziplocal_TmzDateToDosDate(&zipfi->tmz_date,zipfi->dosDate);
 
378
    }
 
379
 
 
380
    zi->ci.flag = 0;
 
381
    if ((level==8) || (level==9))
 
382
      zi->ci.flag |= 2;
 
383
    if ((level==2))
 
384
      zi->ci.flag |= 4;
 
385
    if ((level==1))
 
386
      zi->ci.flag |= 6;
 
387
 
 
388
    zi->ci.crc32 = 0;
 
389
    zi->ci.method = method;
 
390
    zi->ci.stream_initialised = 0;
 
391
    zi->ci.pos_in_buffered_data = 0;
 
392
    zi->ci.pos_local_header = ftell(zi->filezip);
 
393
    zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename + 
 
394
                                      size_extrafield_global + size_comment;
 
395
    zi->ci.central_header = (char*)ALLOC((uInt)zi->ci.size_centralheader);
 
396
 
 
397
    ziplocal_putValue_inmemory(zi->ci.central_header,(uLong)CENTRALHEADERMAGIC,4);
 
398
    /* version info */
 
399
    ziplocal_putValue_inmemory(zi->ci.central_header+4,(uLong)VERSIONMADEBY,2);
 
400
    ziplocal_putValue_inmemory(zi->ci.central_header+6,(uLong)20,2);
 
401
    ziplocal_putValue_inmemory(zi->ci.central_header+8,(uLong)zi->ci.flag,2);
 
402
    ziplocal_putValue_inmemory(zi->ci.central_header+10,(uLong)zi->ci.method,2);
 
403
    ziplocal_putValue_inmemory(zi->ci.central_header+12,(uLong)zi->ci.dosDate,4);
 
404
    ziplocal_putValue_inmemory(zi->ci.central_header+16,(uLong)0,4); /*crc*/
 
405
    ziplocal_putValue_inmemory(zi->ci.central_header+20,(uLong)0,4); /*compr size*/
 
406
    ziplocal_putValue_inmemory(zi->ci.central_header+24,(uLong)0,4); /*uncompr size*/
 
407
    ziplocal_putValue_inmemory(zi->ci.central_header+28,(uLong)size_filename,2);
 
408
    ziplocal_putValue_inmemory(zi->ci.central_header+30,(uLong)size_extrafield_global,2);
 
409
    ziplocal_putValue_inmemory(zi->ci.central_header+32,(uLong)size_comment,2);
 
410
    ziplocal_putValue_inmemory(zi->ci.central_header+34,(uLong)0,2); /*disk nm start*/
 
411
 
 
412
    if (zipfi==NULL)
 
413
        ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)0,2); 
 
414
    else
 
415
        ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)zipfi->internal_fa,2); 
 
416
 
 
417
    if (zipfi==NULL)
 
418
        ziplocal_putValue_inmemory(zi->ci.central_header+38,(uLong)0,4); 
 
419
    else
 
420
        ziplocal_putValue_inmemory(zi->ci.central_header+38,(uLong)zipfi->external_fa,4);
 
421
 
 
422
    ziplocal_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_local_header,4);
 
423
 
 
424
    for (i=0;i<size_filename;i++)
 
425
        *(zi->ci.central_header+SIZECENTRALHEADER+i) = *(filename+i);
 
426
 
 
427
    for (i=0;i<size_extrafield_global;i++)
 
428
        *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+i) =
 
429
              *(((const char*)extrafield_global)+i);
 
430
 
 
431
    for (i=0;i<size_comment;i++)
 
432
        *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+
 
433
              size_extrafield_global+i) = *(filename+i);
 
434
    if (zi->ci.central_header == NULL)
 
435
        return ZIP_INTERNALERROR;
 
436
 
 
437
    /* write the local header */
 
438
    err = ziplocal_putValue(zi->filezip,(uLong)LOCALHEADERMAGIC,4);
 
439
 
 
440
    if (err==ZIP_OK)
 
441
        err = ziplocal_putValue(zi->filezip,(uLong)20,2);/* version needed to extract */
 
442
    if (err==ZIP_OK)
 
443
        err = ziplocal_putValue(zi->filezip,(uLong)zi->ci.flag,2);
 
444
 
 
445
    if (err==ZIP_OK)
 
446
        err = ziplocal_putValue(zi->filezip,(uLong)zi->ci.method,2);
 
447
 
 
448
    if (err==ZIP_OK)
 
449
        err = ziplocal_putValue(zi->filezip,(uLong)zi->ci.dosDate,4);
 
450
 
 
451
    if (err==ZIP_OK)
 
452
        err = ziplocal_putValue(zi->filezip,(uLong)0,4); /* crc 32, unknown */
 
453
    if (err==ZIP_OK)
 
454
        err = ziplocal_putValue(zi->filezip,(uLong)0,4); /* compressed size, unknown */
 
455
    if (err==ZIP_OK)
 
456
        err = ziplocal_putValue(zi->filezip,(uLong)0,4); /* uncompressed size, unknown */
 
457
 
 
458
    if (err==ZIP_OK)
 
459
        err = ziplocal_putValue(zi->filezip,(uLong)size_filename,2);
 
460
 
 
461
    if (err==ZIP_OK)
 
462
        err = ziplocal_putValue(zi->filezip,(uLong)size_extrafield_local,2);
 
463
 
 
464
    if ((err==ZIP_OK) && (size_filename>0))
 
465
        if (fwrite(filename,(uInt)size_filename,1,zi->filezip)!=1)
 
466
                err = ZIP_ERRNO;
 
467
 
 
468
    if ((err==ZIP_OK) && (size_extrafield_local>0))
 
469
        if (fwrite(extrafield_local,(uInt)size_extrafield_local,1,zi->filezip)
 
470
                                                                           !=1)
 
471
                err = ZIP_ERRNO;
 
472
 
 
473
    zi->ci.stream.avail_in = (uInt)0;
 
474
    zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
 
475
    zi->ci.stream.next_out = zi->ci.buffered_data;
 
476
    zi->ci.stream.total_in = 0;
 
477
    zi->ci.stream.total_out = 0;
 
478
 
 
479
    if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED))
 
480
    {
 
481
        zi->ci.stream.zalloc = (alloc_func)0;
 
482
        zi->ci.stream.zfree = (free_func)0;
 
483
        zi->ci.stream.opaque = (voidpf)0;
 
484
 
 
485
        err = deflateInit2(&zi->ci.stream, level,
 
486
               Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, 0);
 
487
 
 
488
        if (err==Z_OK)
 
489
            zi->ci.stream_initialised = 1;
 
490
    }
 
491
 
 
492
 
 
493
    if (err==Z_OK)
 
494
        zi->in_opened_file_inzip = 1;
 
495
    return err;
 
496
}
 
497
 
 
498
extern int ZEXPORT zipWriteInFileInZip (file, buf, len)
 
499
    zipFile file;
 
500
    const voidp buf;
 
501
    unsigned len;
 
502
{
 
503
    zip_internal* zi;
 
504
    int err=ZIP_OK;
 
505
 
 
506
    if (file == NULL)
 
507
        return ZIP_PARAMERROR;
 
508
    zi = (zip_internal*)file;
 
509
 
 
510
    if (zi->in_opened_file_inzip == 0)
 
511
        return ZIP_PARAMERROR;
 
512
 
 
513
    zi->ci.stream.next_in = buf;
 
514
    zi->ci.stream.avail_in = len;
 
515
    zi->ci.crc32 = crc32(zi->ci.crc32,buf,len);
 
516
 
 
517
    while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0))
 
518
    {
 
519
        if (zi->ci.stream.avail_out == 0)
 
520
        {
 
521
            if (fwrite(zi->ci.buffered_data,(uInt)zi->ci.pos_in_buffered_data,1,zi->filezip)
 
522
                                                                           !=1)
 
523
                err = ZIP_ERRNO;
 
524
            zi->ci.pos_in_buffered_data = 0;
 
525
            zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
 
526
            zi->ci.stream.next_out = zi->ci.buffered_data;
 
527
        }
 
528
 
 
529
        if (zi->ci.method == Z_DEFLATED)
 
530
        {
 
531
            uLong uTotalOutBefore = zi->ci.stream.total_out;
 
532
            err=deflate(&zi->ci.stream,  Z_NO_FLUSH);
 
533
            zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;
 
534
 
 
535
        }
 
536
        else
 
537
        {
 
538
            uInt copy_this,i;
 
539
            if (zi->ci.stream.avail_in < zi->ci.stream.avail_out)
 
540
                copy_this = zi->ci.stream.avail_in;
 
541
            else
 
542
                copy_this = zi->ci.stream.avail_out;
 
543
            for (i=0;i<copy_this;i++)
 
544
                *(((char*)zi->ci.stream.next_out)+i) =
 
545
                    *(((const char*)zi->ci.stream.next_in)+i);
 
546
            {
 
547
                zi->ci.stream.avail_in -= copy_this;
 
548
                zi->ci.stream.avail_out-= copy_this;
 
549
                zi->ci.stream.next_in+= copy_this;
 
550
                zi->ci.stream.next_out+= copy_this;
 
551
                zi->ci.stream.total_in+= copy_this;
 
552
                zi->ci.stream.total_out+= copy_this;
 
553
                zi->ci.pos_in_buffered_data += copy_this;
 
554
            }
 
555
        }
 
556
    }
 
557
 
 
558
    return 0;
 
559
}
 
560
 
 
561
extern int ZEXPORT zipCloseFileInZip (file)
 
562
    zipFile file;
 
563
{
 
564
    zip_internal* zi;
 
565
    int err=ZIP_OK;
 
566
 
 
567
    if (file == NULL)
 
568
        return ZIP_PARAMERROR;
 
569
    zi = (zip_internal*)file;
 
570
 
 
571
    if (zi->in_opened_file_inzip == 0)    
 
572
        return ZIP_PARAMERROR;
 
573
    zi->ci.stream.avail_in = 0;
 
574
    
 
575
    if (zi->ci.method == Z_DEFLATED)
 
576
        while (err==ZIP_OK)
 
577
    {
 
578
        uLong uTotalOutBefore;
 
579
        if (zi->ci.stream.avail_out == 0)
 
580
        {
 
581
            if (fwrite(zi->ci.buffered_data,(uInt)zi->ci.pos_in_buffered_data,1,zi->filezip)
 
582
                                                                           !=1)
 
583
                err = ZIP_ERRNO;
 
584
            zi->ci.pos_in_buffered_data = 0;
 
585
            zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
 
586
            zi->ci.stream.next_out = zi->ci.buffered_data;
 
587
        }
 
588
        uTotalOutBefore = zi->ci.stream.total_out;
 
589
        err=deflate(&zi->ci.stream,  Z_FINISH);
 
590
        zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;
 
591
    }
 
592
 
 
593
    if (err==Z_STREAM_END)
 
594
        err=ZIP_OK; /* this is normal */
 
595
 
 
596
    if ((zi->ci.pos_in_buffered_data>0) && (err==ZIP_OK))
 
597
        if (fwrite(zi->ci.buffered_data,(uInt)zi->ci.pos_in_buffered_data,1,zi->filezip)
 
598
                                                                       !=1)
 
599
            err = ZIP_ERRNO;
 
600
 
 
601
    if ((zi->ci.method == Z_DEFLATED) && (err==ZIP_OK))
 
602
    {
 
603
        err=deflateEnd(&zi->ci.stream);
 
604
        zi->ci.stream_initialised = 0;
 
605
    }
 
606
 
 
607
    ziplocal_putValue_inmemory(zi->ci.central_header+16,(uLong)zi->ci.crc32,4); /*crc*/
 
608
    ziplocal_putValue_inmemory(zi->ci.central_header+20,
 
609
                                (uLong)zi->ci.stream.total_out,4); /*compr size*/
 
610
    ziplocal_putValue_inmemory(zi->ci.central_header+24,
 
611
                                (uLong)zi->ci.stream.total_in,4); /*uncompr size*/
 
612
 
 
613
    if (err==ZIP_OK)
 
614
        err = add_data_in_datablock(&zi->central_dir,zi->ci.central_header,
 
615
                                       (uLong)zi->ci.size_centralheader);
 
616
    free(zi->ci.central_header);
 
617
 
 
618
    if (err==ZIP_OK)
 
619
    {
 
620
        long cur_pos_inzip = ftell(zi->filezip);
 
621
            if (fseek(zi->filezip,
 
622
                  zi->ci.pos_local_header + 14,SEEK_SET)!=0)
 
623
                    err = ZIP_ERRNO;
 
624
 
 
625
        if (err==ZIP_OK)
 
626
            err = ziplocal_putValue(zi->filezip,(uLong)zi->ci.crc32,4); /* crc 32, unknown */
 
627
 
 
628
        if (err==ZIP_OK) /* compressed size, unknown */
 
629
            err = ziplocal_putValue(zi->filezip,(uLong)zi->ci.stream.total_out,4); 
 
630
 
 
631
        if (err==ZIP_OK) /* uncompressed size, unknown */
 
632
            err = ziplocal_putValue(zi->filezip,(uLong)zi->ci.stream.total_in,4);
 
633
 
 
634
            if (fseek(zi->filezip,
 
635
                  cur_pos_inzip,SEEK_SET)!=0)
 
636
                    err = ZIP_ERRNO;
 
637
    }
 
638
 
 
639
    zi->number_entry ++;
 
640
    zi->in_opened_file_inzip = 0;
 
641
 
 
642
    return err;
 
643
}
 
644
 
 
645
extern int ZEXPORT zipClose (file, global_comment)
 
646
    zipFile file;
 
647
    const char* global_comment;
 
648
{
 
649
    zip_internal* zi;
 
650
    int err = 0;
 
651
    uLong size_centraldir = 0;
 
652
    uLong centraldir_pos_inzip ;
 
653
    uInt size_global_comment;
 
654
    if (file == NULL)
 
655
        return ZIP_PARAMERROR;
 
656
    zi = (zip_internal*)file;
 
657
 
 
658
    if (zi->in_opened_file_inzip == 1)
 
659
    {
 
660
        err = zipCloseFileInZip (file);
 
661
    }
 
662
 
 
663
    if (global_comment==NULL)
 
664
        size_global_comment = 0;
 
665
    else
 
666
        size_global_comment = strlen(global_comment);
 
667
 
 
668
 
 
669
    centraldir_pos_inzip = ftell(zi->filezip);
 
670
    if (err==ZIP_OK)
 
671
    {
 
672
        linkedlist_datablock_internal* ldi = zi->central_dir.first_block ;
 
673
        while (ldi!=NULL)
 
674
        {
 
675
            if ((err==ZIP_OK) && (ldi->filled_in_this_block>0))
 
676
                if (fwrite(ldi->data,(uInt)ldi->filled_in_this_block,
 
677
                                        1,zi->filezip) !=1 )
 
678
                    err = ZIP_ERRNO;
 
679
 
 
680
            size_centraldir += ldi->filled_in_this_block;
 
681
            ldi = ldi->next_datablock;
 
682
        }
 
683
    }
 
684
    free_datablock(zi->central_dir.first_block);
 
685
 
 
686
    if (err==ZIP_OK) /* Magic End */
 
687
        err = ziplocal_putValue(zi->filezip,(uLong)ENDHEADERMAGIC,4);
 
688
 
 
689
    if (err==ZIP_OK) /* number of this disk */
 
690
        err = ziplocal_putValue(zi->filezip,(uLong)0,2);
 
691
 
 
692
    if (err==ZIP_OK) /* number of the disk with the start of the central directory */
 
693
        err = ziplocal_putValue(zi->filezip,(uLong)0,2);
 
694
 
 
695
    if (err==ZIP_OK) /* total number of entries in the central dir on this disk */
 
696
        err = ziplocal_putValue(zi->filezip,(uLong)zi->number_entry,2);
 
697
 
 
698
    if (err==ZIP_OK) /* total number of entries in the central dir */
 
699
        err = ziplocal_putValue(zi->filezip,(uLong)zi->number_entry,2);
 
700
 
 
701
    if (err==ZIP_OK) /* size of the central directory */
 
702
        err = ziplocal_putValue(zi->filezip,(uLong)size_centraldir,4);
 
703
 
 
704
    if (err==ZIP_OK) /* offset of start of central directory with respect to the 
 
705
                                starting disk number */
 
706
        err = ziplocal_putValue(zi->filezip,(uLong)centraldir_pos_inzip ,4);
 
707
 
 
708
    if (err==ZIP_OK) /* zipfile comment length */
 
709
        err = ziplocal_putValue(zi->filezip,(uLong)size_global_comment,2);
 
710
 
 
711
    if ((err==ZIP_OK) && (size_global_comment>0))
 
712
        if (fwrite(global_comment,(uInt)size_global_comment,1,zi->filezip) !=1 )
 
713
                err = ZIP_ERRNO;
 
714
    fclose(zi->filezip);
 
715
    TRYFREE(zi);
 
716
 
 
717
    return err;
 
718
}