Subversion Repositories autosfx

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 daniel-mar 1
#include "stdafx.h"
2
#pragma hdrstop
3
#include "ZipFnc.h"
4
#include "Helpers.h"
5
#include <stdlib.h>
6
#include "dz_errs.h"
7
 
8
#undef _DZ_FILE_
9
#define _DZ_FILE_ DZ_ZIPUP_CPP
10
 
11
/* ZipUp.c Copyright (C) 1990-1996 Mark Adler, Richard B. Wales, Jean-loup
12
     Gailly, Kai Uwe Rommel, Onno van der Linden and Igor Mandrichenko. This
13
     version modified by Chris Vleghert and Eric Engler for BCB/Delphi Zip.
14
     distributed under LGPL license ** see license.txt for details
15
 
16
  Copyright (c) 1990-2007 Info-ZIP.  All rights reserved.
17
 
18
  See the accompanying file LICENSE, version 2007-Mar-4 or later
19
  (the contents of which are also included in zip.h) for terms of use.
20
  If, for some reason, all these files are missing, the Info-ZIP license
21
  also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
22
 
23
  parts Copyright (C) 1997 Mike White, Eric W. Engler
24
************************************************************************
25
 Copyright (C) 2009, 2010  by Russell J. Peters, Roger Aelbrecht
26
 
27
   This file is part of TZipMaster Version 1.9.
28
 
29
    TZipMaster is free software: you can redistribute it and/or modify
30
    it under the terms of the GNU Lesser General Public License as published by
31
    the Free Software Foundation, either version 3 of the License, or
32
    (at your option) any later version.
33
 
34
    TZipMaster is distributed in the hope that it will be useful,
35
    but WITHOUT ANY WARRANTY; without even the implied warranty of
36
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
37
    GNU Lesser General Public License for more details.
38
 
39
    You should have received a copy of the GNU Lesser General Public License
40
    along with TZipMaster.  If not, see <http://www.gnu.org/licenses/>.
41
 
42
    contact: problems@delphizip.org (include ZipMaster in the subject).
43
    updates: http://www.delphizip.org
44
    DelphiZip maillist subscribe at http://www.freelists.org/list/delphizip
45
************************************************************************/
46
 
47
#include <share.h>
48
 
49
// Return the percentage compression from n to m using only integer
50
//   operations. n :: Is the original size. m :: Is the new size.
51
//int percent(ulg n, ulg m)
52
int percent(__int64 n, __int64 m)
53
{
54
    while (n > 0xFFFFFFL)
55
    {
56
        // If n >= 16M
57
        n += 0x80;
58
        n >>= 8; // then divide n and m by 256
59
        m += 0x80;
60
        m >>= 8;
61
    }
62
 
63
    return n > m ? (int)(1 + (200 *(n - m) / n)) / 2 : 0;
64
}
65
 
66
// Note: a zip "entry" includes a local header (which includes the file
67
//   name), an encryption header if encrypting, the compressed data and
68
//   possibly an extended local header.
69
// Compress the file z->name into the zip entry described by *z and write it
70
//   to the file. Encrypt if requested. Return an error code in the ZEN_
71
//   class. Also, update tempzn by the number of bytes written. z :: Zip entry
72
//   to compress.
73
// writes to fhOutz
74
#define OPENREADFLAGS (FILE_ATTRIBUTE_ARCHIVE | FILE_ATTRIBUTE_HIDDEN |  \
75
                        FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_SYSTEM | \
76
                        FILE_FLAG_SEQUENTIAL_SCAN)
77
                         //FILE_SHARE_READ |}
78
int ZipFunc::zipup(ZipItem *z)
79
{
80
        ulg tim; // Time returned by filetime()
81
        ulg attr = 0L; // Attributes returned by filetime()
82
        int k = 0; // Result of zread
83
        int mthd; // Method for this entry
84
        __int64 o, p; // Offsets in zip file
85
        __int64 fsize = -3; // ZFT_SIZE; // Size returned by filetime
86
        int r; // Temporary variable
87
        __int64 csize = 0L; // Size of compressed data
88
        int isdir; // Set for a directory name
89
        int set_type = 0; // Set if file type (ascii/binary) unknown
90
        unsigned char *tempextra; // to hold pointer returned by user
91
        ZInt64 HChk; // position after local header
92
        AutoStream inz(NULL);
93
 
94
        fimax = 0;
95
        isdir = z->IsFolder;
96
 
97
        if (Verbose < 0)
98
                Notify(ITRACE, _T("zipup: %s"), z->iname);
99
 
100
        {
101
                if ((tim = zfiletime(z->FullPath(), &attr, &fsize, NULL)) == 0)
102
                        return DZ_ERM_NO_FILE_OPEN;
103
        }
104
 
105
        // fsize is set to -1 if the input file is a device, -2 for a volume label
106
        if (fsize == ZFT_LABEL)
107
        {
108
                isdir = 1;
109
                fsize = 0;
110
        }
111
        else if (isdir != ((attr & MSDOS_DIR_ATTR) != 0))
112
        // don't overwrite a directory with a file and vice-versa
113
                return DZ_ERM_MISS;
114
 
115
        z->att = (ush)UNKNOWN; // will be changed later
116
        z->atx = 0; // may be changed by set_extra_field()
117
 
118
        fkey = z->Passw; // 1.73 restore global password
119
        fwindow_size = 0L;
120
        // Select method based on the suffix and the global method
121
        mthd = DEFLATE; // default method
122
        flevel = z->options.level;
123
 
124
        if (flevel && !z->options.noext && fSpecials)
125
        {
126
                ZFilter *f = fSpecials->Find(z->xname);
127
                if (f)
128
                {
129
                        if (f->Level < flevel)
130
                                flevel = f->Level;
131
                }
132
        }
133
 
134
        if (!flevel || isdir)
135
                mthd = STORE;
136
 
137
        // CHANGE 1.73 RAEL changed RPETERS Code added to generate and handle
138
        // action code 14 file extra data Extra data needs to be delivered
139
        // formatted according to PKZIP appnote.txt
140
        CB->Arg1 = z->ext; // size
141
        CB->Data2 = (const char*)z->extra.begin(); // old data
142
        CB->Arg2 = z->options.level;
143
        int uret = CB->UserCB(zacData, z->FullPath());
144
        if (uret <= CALLBACK_CANCEL) // TODO: should not happen
145
                Fatal(DZ_ERM_ABORT, 0);
146
 
147
        // free any old data - probably obsolete
148
        z->cextra.Empty();
149
        z->extra.Empty();
150
        if (z->ntfs)
151
        {
152
                delete z->ntfs;
153
                z->ntfs = NULL;
154
        }
155
 
156
        if (uret > 0 && uret & 2)
157
        {
158
                unsigned lvl = CB->Arg2;
159
 
160
                if (lvl <= 9)
161
                {
162
                        z->options.level = lvl;
163
                        z->options.noext = 1;
164
                        mthd = lvl ? DEFLATE : STORE;
165
                        flevel = lvl;
166
                }
167
        }
168
 
169
        if (uret > 0 && uret & 1)
170
        {
171
                // user changed extrafield data
172
                tempextra = (unsigned char*)CB->Data;
173
 
174
                if (!tempextra)
175
                        CB->Arg1 = 0;
176
 
177
                // user changed extrafield data
178
                if (CB->Arg1)
179
                {
180
                        z->extra.Assign(tempextra, CB->Arg1);
181
                        if (fNTFSStamps)
182
                                z->extra -= NTFS_STAMP_TAG; // - most likely wrong stamp
183
                        z->cextra = z->extra;
184
                }
185
        }
186
        if (!z->options.dosflag && !z->HName.BadDOS())  // mimic WinZip
187
                z->options.dosflag = 2; // if has no extended chars use MSDOS
188
 
189
        // For a FAT file system, we cheat and pretend that the file was not made
190
        // on OS2, but under DOS. unzip is confused otherwise.
191
        // Made under MSDOS by PKZIP 2.0, NTFS by PKZIP 2.2
192
        z->vem = (ush)(z->options.dosflag ? 20 : OS_NTFS + 22);
193
        if (z->Enc >= zeoUTF8)
194
                z->vem = OUR_VEM;
195
 
196
        // Need PKUNZIP 2.0 to extract, unless it is stored
197
        z->ver = (ush)((mthd == STORE) ? 10 : 20);
198
 
199
        if (isdir)
200
        {
201
                if (IsNTorAbove && fNTFSStamps)
202
                {
203
                        // get folder stamps
204
                        HANDLE hFolder = CreateFile(z->FullPath(), GENERIC_WRITE,
205
                                FILE_SHARE_READ, NULL, OPEN_EXISTING,
206
                                FILE_ATTRIBUTE_DIRECTORY | FILE_FLAG_BACKUP_SEMANTICS, NULL);
207
                        if (hFolder == INVALID_HANDLE_VALUE)
208
                        {
209
                                if (Verbose < 0)
210
                                        Notify(IWARNING, _T("Could not get times for %s"),
211
                                        z->FullPath().c_str());
212
                        }
213
                        else
214
                        {
215
                                // get stamps
216
                                XNTFSData stamps;
217
                                if (GetFileTime(hFolder, &stamps.CTime, &stamps.ATime,
218
                                                &stamps.MTime))
219
                                {
220
                                        z->ntfs = new XNTFSData;
221
                                        memcpy(z->ntfs, &stamps, sizeof(XNTFSData));
222
                                }
223
                                CloseHandle(hFolder);
224
                        }
225
                }
226
                // directory
227
                mthd = STORE;
228
                fsize = 0;
229
        }
230
        else
231
        {
232
                // Callback: action, error code, filesize, filename
233
                CB->UserItem(z->len, z->XName);
234
 
235
                if (Abort_Flag)
236
                        Fatal(DZ_ERM_ABORT, 0);
237
 
238
                fZipInfile = NULL;
239
                if (Is_Drv(z->XName) < 0)
240
                        fZipInfile = new ZStream(this, z->XName);
241
                else
242
                        fZipInfile = new ZFile(this, z->FullPath(), OPENREADFLAGS);
243
 
244
                inz.Assign(&fZipInfile); // make certain it is destroyed when finished
245
                if (fZipInfile == NULL)
246
                        Notify(ITRACE, _T("no input file"));
247
 
248
                if (fZipInfile != NULL && !fZipInfile->IsOpen())
249
                {
250
                        int le = GetLastError();
251
                        if (Verbose < 0)
252
                                Notify(IWARNING, _T("Could not open %s [%X]"),
253
                                fZipInfile->fname.c_str(), le);
254
                        // give zacSkipped
255
                        int typ = SKIPPED_NO_OPEN;
256
                        if (le == ERROR_SHARING_VIOLATION)
257
                                typ = SKIPPED_NO_SHARE;
258
                        else if (le == ERROR_ACCESS_DENIED)
259
                                typ = SKIPPED_NO_ACCESS;
260
 
261
                        if (Skipping(z->FullPath(), DZ_ERR_NO_FILE_OPEN, typ))
262
                                Fatal(DZ_ERM_SKIPPING, 2);
263
 
264
                        return DZ_ERR_NO_FILE_OPEN;
265
                }
266
                if (IsNTorAbove && fNTFSStamps)
267
                {
268
                        // get stamps
269
                        XNTFSData stamps;
270
                        if (fZipInfile->GetTime(&stamps.CTime, &stamps.ATime,
271
                                        &stamps.MTime))
272
                        {
273
                                z->ntfs = new XNTFSData;
274
                                memcpy(z->ntfs, &stamps, sizeof(XNTFSData));
275
                        }
276
                        else if (Verbose < 0)
277
                                Notify(IWARNING, _T("Could not get times for %s"),
278
                                fZipInfile->fname.c_str());
279
                }
280
        }
281
 
282
        z->tim = tim;
283
        fFileError = 0;
284
        if (fsize == 0)
285
                mthd = STORE;
286
 
287
        // Do not create STORED files with extended local headers if the input
288
        // size is not known, because such files could not be extracted. So if the
289
        // zip file is not seekable and the input file is not on disk, obey the -0
290
        // option by forcing deflation with stored block. Note however that using
291
        // "zip -0" as filter is not very useful... ??? to be done.
292
        // Fill in header information and write local header to zip file. This
293
        // header will later be re-written since compressed length and crc are not
294
        // yet known.
295
        // (Assume ext, cext, com, and zname already filled in.)
296
        // (RCV Added (ush)(...)
297
        z->flg = FLAG_EXTEND_BIT; // to be updated later
298
 
299
        // (RCV Added below (ush)
300
        z->how = (ush)mthd; // may be changed later
301
 
302
        if (z->att == (ush)UNKNOWN)
303
        {
304
                z->att = BINARY; // set sensible value in header
305
                set_type = 1;
306
        }
307
 
308
        // Attributes from filetime(), flag bits from set_extra_field():
309
        z->atx = z->options.dosflag ? attr & 0xFF : attr | (z->atx & 0x0000FFFF);
310
        z->crc = 0; // to be updated later
311
#ifdef _ZDEBUG
312
        Notify(ITRACE, _T("zipup: %s dosflag %i"), z->iname, z->options.dosflag);
313
#endif
314
 
315
        // Assume first that we will need an extended local header:
316
        ulg f_crc = 0;
317
        __int64 fsz = 0;
318
        bool haveCRC = false;
319
 
320
        if (fkey && !isdir && fsize)
321
        {
322
                if (!fNoPrecalc)
323
                {
324
                        // get CRC before we start
325
                        __int64 pos1 = 0;
326
 
327
                        if (!fZipInfile->IsFile)
328
                                pos1 = fZipInfile->SetPosition(0, FILE_CURRENT);
329
                        // get start posn
330
 
331
                        f_crc = crc32(0L, (uch*)NULL, 0);
332
                        unsigned long byts;
333
 
334
                        while (fZipInfile->Read(fwindow, sizeof(fwindow), &byts))
335
                        {
336
                                if (!byts)
337
                                        break;
338
 
339
                                fsz += byts;
340
                                f_crc = crc32(f_crc, (uch*)fwindow, byts);
341
                        }
342
 
343
                        // Check input size
344
                        if (fsz != fsize)
345
                        {
346
//                              Notify(IWARNING, _T(" file size changed while zipping: %s"),
347
//                                      z->xname);
348
//
349
//                              if (Verbose < 0)
350
//                                      Notify(ITRACE, _T(" is=%Lu, expected=%Lu "), fsz, fsize);
351
//                              fsize = fsz;
352
                                // don't Ask skip - may be stable next time
353
//                      {
354
                                int skip;
355
                                int re;
356
                                // may be file error
357
                                if (fFileError)
358
                                {
359
                                        if (fFileError == ERROR_LOCK_VIOLATION)
360
                                                Notify(DZ_ERR_LOCKED | IWARNING, z->xname);
361
                                        else if (fFileError == ERROR_ACCESS_DENIED)
362
                                                Notify(DZ_ERR_DENIED | IWARNING, z->xname);
363
                                        else
364
                                                Notify(DZ_ERR_NO_FILE_OPEN | IWARNING,
365
                                                _T(" File read error [%d]: %s"), fFileError, z->xname);
366
 
367
                                        re = DZ_ERM_ERROR_READ;
368
                                        Notify(re, _T(" File error [%d] while zipping: %s"), fFileError, z->xname);
369
                                        skip = SKIPPED_READ_ERROR;
370
                                }
371
                                else
372
                                {
373
                                        re = DZ_ERM_SKIPPED;
374
                                        Notify(IWARNING, _T(" file size changed while zipping: %s"),
375
                                                z->xname);
376
 
377
                                        if (Verbose < 0)
378
                                                Notify(ITRACE, _T(" was=%Lu, expected=%Lu "), fisize, fsize);
379
                                        skip = SKIPPED_SIZE_CHANGE;
380
                                }
381
                                if (Skipping(z->XName, 0, skip))
382
                                                Fatal(DZ_ERM_SKIPPED, 2);
383
                                return re;              // skip the file
384
//                              fsize = fsz;    // ignore and try to zip again
385
//                      }
386
                        }
387
                        else
388
                        {
389
                                z->crc = f_crc;
390
                                haveCRC = true;
391
                        }
392
 
393
                        if (fZipInfile->SetPosition(pos1, FILE_BEGIN) != pos1)
394
                        {
395
                                if (Verbose)
396
                                        Notify(IVERBOSE, _T("Could not reposition %s [%s]"),
397
                                        z->FullPath().c_str(), SysMsg().c_str());
398
 
399
                                if (fZipInfile->IsFile)
400
                                {
401
                                        inz.Assign(NULL);
402
                                        fZipInfile = new ZFile(this, z->FullPath(), OPENREADFLAGS);
403
                                        inz.Assign(&fZipInfile);
404
 
405
                                        if (fZipInfile == NULL || !fZipInfile->IsOpen())
406
                                                return DZError(DZ_ERM_ERROR_READ);
407
                                }
408
                                else
409
                                        return DZError(DZ_ERM_ERROR_READ);
410
                        }
411
                }
412
 
413
                z->flg |= FLAG_ENCRYPT_BIT;
414
                // Since we do not yet know the crc here, we pretend that the crc is the
415
                // modification time:
416
                if (!haveCRC)
417
                        z->crc = z->tim << 16;
418
        }
419
 
420
        fFileError = 0;
421
        if (fsize == 0)
422
                mthd = STORE;
423
        z->how = (ush)mthd; // may be changed later
424
        z->lflg = z->flg;
425
        z->siz = fsize; // not compressed yet
426
        z->len = fsize; // may be changed later
427
        z->dsk = 0;
428
        z->off = fOutPosn;
429
        Assert(fOutPosn == fZipOutfile->SetPosition(0, 1),
430
                _T("invalid out posn 1"));
431
 
432
        // now put it in the file
433
        if ((r = PutLocal(z)) != DZ_ERR_GOOD)
434
                return r;
435
 
436
        HChk = fOutPosn; // save position after header
437
        if (HChk == -1)
438
                DZError(DZ_ERM_ERROR_WRITE);
439
 
440
        if (fkey)
441
        {
442
                crypthead(fkey, z->crc);
443
                z->siz += RAND_HEAD_LEN; // to be updated later
444
                fOutPosn += RAND_HEAD_LEN;
445
        }
446
 
447
        // for error checking, ftell can fail on pipes
448
        o = fOutPosn;
449
        // Write stored or deflated file to zip file
450
        fisize = 0; // L;
451
        fcrc = crc32(0L, (uch*)NULL, 0);
452
 
453
        if (fsize == 0)
454
                mthd = STORE;
455
        // Need PKUNZIP 2.0 to extract, unless it is stored
456
        z->ver = (ush)((mthd == STORE) ? 10 : 20);
457
        z->how = (ush)mthd; // may be changed later
458
 
459
        if (mthd == DEFLATE)
460
        {
461
                bi_init();
462
 
463
                if (set_type)
464
                        z->att = (ush)UNKNOWN;
465
 
466
                // will be changed in deflate()
467
                ct_init(&z->att, &mthd);
468
                lm_init(flevel, &z->flg);
469
 
470
                // PERFORM THE DEFLATE
471
                csize = deflate();
472
 
473
                if (Abort_Flag)
474
                        Fatal(DZ_ERM_ABORT, 0);
475
        }
476
        else if (!isdir)
477
        {
478
                if (Verbose)
479
                        Notify(IVERBOSE, _T("Storing %s "), z->FullPath().c_str());
480
 
481
                while ((k = read_buf(fwindow, sizeof(fwindow))) > 0 && k != EOF)
482
                {
483
                        if (Abort_Flag)
484
                                Fatal(DZ_ERM_ABORT, 0);
485
 
486
                        if (!zfwrite(fwindow, k))
487
                                return DZ_ERM_TEMP_FAILED;
488
                }
489
 
490
                csize = fisize;
491
        }
492
 
493
        if (!fZipInfile && k == (-1))
494
                Notify(IWARNING, _T("could not read input file: %s"), z->xname);
495
 
496
        if (fZipInfile != NULL)
497
                fZipInfile->Close(); // Close the input file
498
 
499
        fOutPosn += csize;
500
        p = fOutPosn; // save for future fseek()
501
 
502
        if (haveCRC && f_crc != fcrc)
503
        {
504
                int re = DZ_ERM_ERROR_READ;
505
                Notify(re, _T(" File CRC changed while zipping: %s"), z->xname);
506
                return re;
507
        }
508
 
509
        // Check input size
510
        if (fisize != fsize)
511
        {
512
                int skip;
513
                int re;
514
                // may be file error
515
                if (fFileError)
516
                {
517
                        if (fFileError == ERROR_LOCK_VIOLATION)
518
                                Notify(DZ_ERR_LOCKED | IWARNING, z->xname);
519
                        else if (fFileError == ERROR_ACCESS_DENIED)
520
                                Notify(DZ_ERR_DENIED | IWARNING, z->xname);
521
                        else
522
                                Notify(DZ_ERR_NO_FILE_OPEN | IWARNING,
523
                                _T(" File read error [%d]: %s"), fFileError, z->xname);
524
 
525
                        /*int*/ re = DZ_ERM_ERROR_READ;
526
                        Notify(re, _T(" File error [%d] while zipping: %s"), fFileError, z->xname);
527
                        skip = SKIPPED_READ_ERROR;
528
//                      return re;
529
                }
530
                else
531
                {
532
                        re = DZ_ERM_SKIPPED;
533
                        Notify(IWARNING, _T(" file size changed while zipping: %s"),
534
                                z->xname);
535
 
536
                        if (Verbose < 0)
537
                                Notify(ITRACE, _T(" was=%Lu, expected=%Lu "), fisize, fsize);
538
                        skip = SKIPPED_SIZE_CHANGE;
539
                }
540
                if (Skipping(z->XName, 0, skip))
541
                                Fatal(DZ_ERM_SKIPPED, 2);
542
                // reposition
543
                if (fZipOutfile->SetPosition(z->off, FILE_BEGIN) == -1)
544
                {
545
                        if (Verbose)// < 0)
546
                                Notify(ITRACE, _T(" could not reposition file "));
547
                        DZError(DZ_ERM_ERROR_SEEK);
548
                }
549
                fZipOutfile->SetEndOfFile();
550
                return re;
551
        }
552
 
553
        // Try to rewrite the local header with correct information
554
        z->crc = fcrc;
555
        z->siz = csize; // compressed size
556
        z->len = fisize;
557
 
558
        if (fkey)
559
                z->siz += RAND_HEAD_LEN;
560
 
561
        if (fZipOutfile->SetPosition(z->off, FILE_BEGIN) == -1)
562
        {
563
                if (z->how != (ush)mthd)
564
                        DZError(DZ_ERM_ERROR_WRITE);
565
 
566
                putextended(z);
567
                z->flg = z->lflg; // if flg modified by inflate
568
        }
569
        else
570
        {
571
                // seek ok, ftell() should work, check compressed size
572
                if (p - o != csize)
573
                {
574
                        Notify(IWARNING, _T(" s=%Lu, actual=%Lu "), csize, p - o);
575
                        DZError(DZ_ERM_LOGIC_ERROR);
576
                }
577
 
578
                // (RCV Added in two lines below (ush)(...)
579
                z->how = (ush)mthd;
580
 
581
                if ((z->flg & FLAG_ENCRYPT_BIT) == 0 || haveCRC)
582
                        z->flg &= ~FLAG_EXTEND_BIT;
583
                // clear the extended local header flag
584
                z->lflg = z->flg;
585
 
586
                // rewrite the local header:
587
                if ((r = UpdateLocal(z)) != DZ_ERR_GOOD)
588
                        return r;
589
 
590
                if (HChk != fZipOutfile->SetPosition(0, FILE_CURRENT))
591
                        return DZ_ERM_LOGIC_ERROR; // size changed
592
 
593
                fOutPosn = fZipOutfile->SetPosition(p, FILE_BEGIN);
594
 
595
                if (fOutPosn < p)
596
                        return DZ_ERM_ERROR_SEEK;
597
 
598
                if ((z->flg & (FLAG_EXTEND_BIT | FLAG_ENCRYPT_BIT)) != 0)
599
                {
600
                        // encrypted file, extended header still required
601
                        if ((r = putextended(z)) != DZ_ERR_GOOD)
602
                                return r;
603
                }
604
        }
605
 
606
        // Free the local extra field which is no longer needed
607
        if (z->ext)
608
        {
609
                z->ext = 0;
610
        }
611
 
612
        // Display statistics
613
        if (Verbose)
614
        {
615
                Notify(0, _T("%s  in=%Lu,  out=%Lu,  %d%%"),
616
                        (mthd == DEFLATE) ? _T("deflated") : _T("stored"), fisize, csize,
617
                        percent(fisize, csize));
618
        }
619
        /* TODO 1 -oRP -cenhancement : Finished Item */
620
        return DZ_ERR_GOOD;
621
}
622
 
623
 
624
// copy an existing entry with updated name
625
int ZipFunc::zipVersion(ZipItem *z)
626
{
627
        int r;        // Temporary variable
628
 
629
    fwindow_size = 0L;
630
 
631
    // Callback: action, error code, filesize, filename
632
        CB->UserItem(z->len, z->IName);
633
    if (Abort_Flag)
634
                Fatal(DZ_ERM_ABORT, 0);
635
 
636
    fFileError = 0;
637
    ZInt64 lofs = z->off;   // local header offset
638
    lofs += sizeof(ZipLocalHeader) + z->nam + z->ext;
639
 
640
    // seek to local data
641
    if (SetFilePointer64(fhInz, lofs, FILE_BEGIN) == -1)
642
        return DZ_ERR_ERROR_READ;
643
 
644
    z->off = fOutPosn;
645
    ZInt64 n = z->siz;
646
 
647
    // copy the compressed data and the extended local header if there is one
648
    if (z->lflg & FLAG_EXTEND_BIT)
649
        n += (z->ver >= 45 ? 20 : 16);
650
 
651
    // write the modified header
652
    if ((r = PutLocal(z)) != DZ_ERR_GOOD)
653
        return r;
654
 
655
    fOutPosn += n;
656
 
657
//    return fcopy(n);
658
        int err = fcopy(n);
659
 
660
    /* TODO 1 -oRP -cenhancement : Finished Item */
661
        return err;
662
}