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
 
4
#include "ZipFnc.h"
5
 
6
#include <assert.h>
7
#include "dz_errs.h"
8
 
9
#undef _DZ_FILE_
10
#define _DZ_FILE_ DZ_ZIPFNC_CPP
11
 
12
/* ZGlobals.c
13
 * Copyright (C) 1990-1996 Mark Adler, Richard B. Wales, Jean-loup Gailly,
14
 * Kai Uwe Rommel, Onno van der Linden and Igor Mandrichenko.
15
 * Permission is granted to any individual or institution to use, copy, or
16
 * redistribute this software so long as all of the original files are included,
17
 * that it is not sold for profit, and that this copyright notice is retained.
18
 * This version modified by Chris Vleghert for BCB/Delphi Zip.
19
  ** distributed under LGPL license ** see license.txt for details
20
 
21
  Copyright (c) 1990-2007 Info-ZIP.  All rights reserved.
22
 
23
  See the accompanying file LICENSE, version 2007-Mar-4 or later
24
  (the contents of which are also included in zip.h) for terms of use.
25
  If, for some reason, all these files are missing, the Info-ZIP license
26
  also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
27
 
28
  parts Copyright (C) 1997 Mike White, Eric W. Engler
29
************************************************************************
30
 Copyright (C) 2009, 2010  by Russell J. Peters, Roger Aelbrecht
31
 
32
   This file is part of TZipMaster Version 1.9.
33
 
34
    TZipMaster is free software: you can redistribute it and/or modify
35
    it under the terms of the GNU Lesser General Public License as published by
36
    the Free Software Foundation, either version 3 of the License, or
37
    (at your option) any later version.
38
 
39
    TZipMaster is distributed in the hope that it will be useful,
40
    but WITHOUT ANY WARRANTY; without even the implied warranty of
41
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
42
    GNU Lesser General Public License for more details.
43
 
44
    You should have received a copy of the GNU Lesser General Public License
45
    along with TZipMaster.  If not, see <http://www.gnu.org/licenses/>.
46
 
47
    contact: problems@delphizip.org (include ZipMaster in the subject).
48
    updates: http://www.delphizip.org
49
    DelphiZip maillist subscribe at http://www.freelists.org/list/delphizip
50
************************************************************************/
51
 
52
 
53
ZipFunc::ZipFunc(const DllCommands *C): ZipDflt(C)//, BaseOpts()
54
{
55
    fndlist = NULL;       // quicklist (internal) of found files
56
    IntList = NULL;
57
//    HdrList = NULL;
58
    faction = ADD;                 // Must be ADD - the default action
59
    fzipstate = -1;
60
    fuser_key = NULL;
61
    fglobal_error_code = 0;
62
    ffiles_acted_on = 0;
63
    CurPW = NULL;
64
    CurBase = NULL;
65
    fzcomlen = 0;
66
    fSpecials = NULL;
67
    fpcount = 0;
68
    ffound = NULL;
69
    fzfiles = NULL;
70
    VerFiles = NULL;
71
    fzfound = NULL;
72
    fzcount = 0;
73
    flatest = 0;
74
    ffcount = 0;
75
    faction = 0;
76
        fversion = 0;
77
        fjunk_sfx = 0;
78
    frecurse = 0;
79
    flinkput = 0;
80
    fBatchStarted = 0;
81
    fcenbeg = 0;
82
    fzipbeg = 0;
83
    fAllowGrow = 0;
84
 
85
    fhwbuf = NULL;
86
    fpathput = 1;
87
    fdirnames = 1;
88
 
89
    // linked list for new files to be added (not yet in ZIP)
90
    ffnxt = &ffound;
91
    fadjust = 1;
92
        fEncodeAs = C->fEncodeAs;     // write strings
93
        fArchiveFiles = C->fOptions.ArchiveFilesOnly;
94
        fResetArchiveBit = C->fOptions.ResetArchiveBit;
95
        // build the conventional cmd line switches
96
    if (C->fOptions.NoDirEntries) // Do not add directory entries -D
97
        fdirnames = 0;
98
    if (C->fOptions.Grow) // Allow appending to a zip file -g Normally TRUE
99
        fAllowGrow = 255;
100
    if (C->fOptions.JunkDir) // Junk directory names -j
101
        fpathput = 0;
102
    if (C->fOptions.JunkSFX) // Junk sfx prefix
103
        fjunk_sfx = 1;
104
    if (C->fOptions.Move) // Delete files added or updated in zip file -m
105
        fdispose = 1;
106
    if (C->fOptions.LatestTime) // Set zip file time to time of latest file in it -o
107
                flatest = 1;
108
        if (fNTFSStamps)
109
                fdirnames = 0;
110
 
111
    fHowToMove = C->fOptions.HowToMove;
112
    fNoPrecalc = C->fOptions.NoPrecalc;
113
    fGEncrypt = C->fOptions.Encrypt;
114
    frecurse = C->fOptions.Recurse;
115
        fbefore = C->fDate;
116
    fversion = C->fOptions.Versioning;
117
    VerDate = 0;
118
}
119
 
120
ZipFunc::~ZipFunc(void)
121
{
122
    if (fSpecials) {          
123
        delete fSpecials;
124
        fSpecials = NULL;
125
    }
126
    ZipCleanup();   // something may have failed
127
    if (CurPW) {
128
        PWRec* t, *p = CurPW;
129
        CurPW = 0;
130
        while (p)
131
        {
132
            t = p;
133
            p = p->Next;
134
            delete t;
135
        }
136
    }
137
    if (CurBase) {
138
        BaseRec* t, *p = CurBase;
139
        CurBase = 0;
140
        while (p)
141
        {
142
            t = p;
143
            p = p->Next;
144
            delete t;
145
        }
146
    }
147
 
148
    if (IntList)
149
    {
150
        delete IntList;
151
        IntList = NULL;
152
    }
153
 
154
    if (fndlist)
155
    {
156
        delete fndlist;
157
        fndlist = NULL;
158
    }
159
 
160
    FndItem *f; // steps through found list
161
        ZipItem *z; // pointer to next entry in zfiles list
162
    while (ffound != NULL)
163
    {
164
        f = ffound;
165
        ffound = f->nxt;
166
        delete f;
167
    }
168
 
169
    while (fzfiles != NULL)
170
        {
171
        z = fzfiles;
172
        fzfiles = z->nxt;
173
        delete z;
174
    }
175
 
176
    while (VerFiles != NULL)
177
        {
178
        z = VerFiles;
179
        VerFiles = z->nxt;
180
        delete z;
181
    }
182
 
183
    while (fzfound != NULL)
184
    {
185
        z = fzfound;
186
        fzfound = z->nxt;
187
        delete z;
188
    }
189
}
190
 
191
int ZipFunc::Init(void) // after construction
192
{
193
    int r = ZipDflt::Init();
194
    if (r)
195
        return r;
196
    // do active initialisation
197
 
198
    DZStrW cd = CB->UserArg(zcbRootDir, 0, 0);
199
    if (cd.IsEmpty())    
200
        cd = _T(".\\");    // use current
201
 
202
    if (!GetFullPathName(cd, MAX_PATH, fRootDir.GetBuffer(MAX_PATH), NULL))
203
    {
204
        throw DZFatalException(DZ_ERM_MEMORY);
205
        }
206
        fRootDir.ReleaseBuffer();
207
        if (fRootDir.LastChar() != BSLASH)
208
                fRootDir += BSLASH;
209
    AddBase(fRootDir, true);
210
 
211
    fGPassword = CB->UserArg(zcbPassword, 0, 0);
212
    AddPW(fGPassword, true);
213
 
214
    return 0;
215
}
216
 
217
PWRec::PWRec(const DZStrA &pw)
218
{
219
    fpw = NULL;
220
    if (!pw.IsEmpty())
221
        fpw = DupStr(pw);
222
    fnext = NULL;
223
}
224
 
225
PWRec::~PWRec()
226
{
227
    delete[] fpw;
228
}
229
 
230
 
231
BaseRec::BaseRec(const DZStrW &base)
232
{
233
    fbase = DupStr(base);
234
    fnext = NULL;
235
}
236
 
237
BaseRec::~BaseRec()
238
{
239
    delete[] fbase;
240
}
241
 
242
XItem::XItem()
243
{
244
    finame = NULL;
245
    fxname = NULL;
246
    fhname = NULL;
247
        options._opts = 0;
248
    Base = NULL;
249
    Passw = NULL;
250
    len = 0;
251
}
252
 
253
XItem::~XItem()
254
{
255
    if (fhname)
256
        delete[] fhname;
257
    if (finame)
258
        delete[] finame;
259
    if (fxname)
260
        delete[] fxname;
261
    // does not own Base or Passw
262
}
263
 
264
XItem::XItem(const XItem& other)
265
{
266
    fhname = NULL;
267
    finame = NULL;
268
        fxname = NULL;
269
        options._opts = 0;
270
    if (other.hname)
271
        fhname = zstrdupB(other.hname);
272
    if (other.iname)
273
        finame = zstrdup(other.iname);
274
    if (other.xname)
275
                fxname = zstrdup(other.xname);
276
//    how = other.how;
277
    Base = other.Base;
278
        Passw = other.Passw;
279
    // does not copy options or cextra
280
}
281
 
282
XItem& XItem::operator=(const XItem& other)
283
{
284
        if (&other != this) {
285
        if (fhname)
286
            delete[] fhname;
287
        if (finame)
288
            delete finame;
289
        if (fxname)
290
            delete[] fxname;
291
        fhname = NULL;
292
        finame = NULL;
293
        fxname = NULL;      
294
        if (other.hname)
295
            fhname = zstrdupB(other.hname);
296
        if (other.iname)
297
            finame = zstrdup(other.iname);
298
        if (other.xname)
299
                        fxname = zstrdup(other.xname);
300
        Base = other.Base;
301
                Passw = other.Passw;
302
                // does not copy options or cextra
303
                options._opts = other.options._opts;
304
    }
305
    return *this;
306
}
307
 
308
DZStrW __fastcall XItem::FullPath(void) const
309
{
310
    if (!Is_DrvEx(xname))
311
    {
312
        DZStrW tmp(Base);
313
        tmp += xname;
314
        return tmp;
315
    }
316
    return DZStrW(xname);
317
}
318
 
319
void __fastcall XItem::Setxname(const TCHAR *value)
320
{
321
    if (fxname)
322
        delete[] fxname;
323
    fxname = NULL;
324
    if (value)
325
        fxname = zstrdup(value);
326
}
327
 
328
 
329
void __fastcall XItem::Setiname(const TCHAR *value)
330
{
331
    if (finame)
332
        delete[] finame;
333
    finame = NULL;
334
    if (value)
335
        finame = zstrdup(value);
336
}
337
 
338
void __fastcall XItem::Sethname(const char* value)
339
{
340
    if (fhname)
341
        delete[] fhname;
342
    fhname = NULL;
343
    if (value)
344
        fhname = zstrdupB(value);
345
}
346
 
347
bool __fastcall XItem::GetIsFolder(void) const
348
{
349
    return finame[_tcslen(finame)- 1] == BSLASH;
350
}
351
 
352
HL_node::HL_node()
353
{
354
    nxt = NULL;
355
    hash = 0;
356
    xdata = NULL;
357
};
358
 
359
HL_block::HL_block(HL_block *prev)
360
{
361
    prv = prev;
362
    memset(nodes, 0, sizeof(nodes));
363
}
364
 
365
HL_block::~HL_block(void)
366
{
367
    if (prv)
368
    {
369
        HL_block *tmp = prv;
370
        prv = NULL;
371
        delete tmp;
372
    }
373
}
374
 
375
typedef HL_node* PHL_node;
376
 
377
HashList::HashList(int siz)
378
{
379
    int size = 512;  // smallest allowing MAX_PATH strings
380
    while (size < 16384 && size < siz)
381
        size += size;
382
    Mask = size - 1;
383
        Table = new PHL_node[size];
384
    memset(Table, 0, size * sizeof(PHL_node));
385
    blocks = NULL;
386
    nno = 0;
387
}
388
 
389
HashList::~HashList(void)
390
{
391
    if (blocks)
392
        delete blocks;
393
    delete [] Table;
394
}
395
 
396
 
397
HL_node * HashList::NewNode(const XItem *x, ulg hash)
398
{
399
    if (!blocks || nno >= NODE_BLOCK_SIZE)
400
    {
401
        blocks = new HL_block(blocks);
402
        nno = 0;
403
    }
404
    HL_node *ret = &blocks->nodes[nno++];
405
    ret->nxt = NULL;
406
    ret->hash = hash;
407
    ret->xdata = x;
408
    return ret;
409
}
410
 
411
const XItem *HashList::AddANode(const XItem *xname)
412
{
413
        HL_node *lr, *lt;
414
    lr = Prepare();
415
    if (!lr)
416
    {
417
        // no entries
418
        Table[Index] = NewNode(xname, Hash);  // add it
419
        return NULL;
420
    }
421
    lt = NULL;
422
    while (lr)
423
    {
424
        if (Hash == lr->hash && Matches(lr))
425
        {
426
            // exists
427
            return lr->xdata;  // return existing
428
        }
429
 
430
        lt = lr;
431
        lr = lr->nxt;
432
    }
433
    // chain it to lt
434
    if (lt)
435
        lt->nxt = NewNode(xname, Hash);
436
 
437
    return NULL;
438
}
439
 
440
XItem *HashList::FindAName(void)
441
{
442
    HL_node* lr = Prepare();
443
    while (lr)  // search chain
444
    {
445
        if (Hash == lr->hash && Matches(lr))
446
            break; // exists @lr
447
        lr = lr->nxt;
448
    }
449
    if (lr)
450
        return (XItem*)lr->xdata;
451
    return NULL;
452
}
453
 
454
HashListExt::~HashListExt(void)
455
{
456
    //
457
}
458
 
459
XItem *HashListExt::FindName(const DZStrW& name)
460
{
461
    fxname = name;
462
    return FindAName();
463
}
464
 
465
// returns pointer to existing entry if duplicate
466
const XItem *HashListExt::AddNode(const XItem *xname)
467
{
468
    fxname = xname->XName;
469
    return AddANode(xname);
470
}
471
 
472
bool HashListExt::Matches(const HL_node *node) const
473
{
474
    return fxname.CompareNoCase(node->xdata->XName) == 0;
475
}
476
 
477
HL_node* HashListExt::Prepare(void)
478
{
479
    fxname.ToUpper();
480
    int len = fxname.length();
481
    Hash = crc32(0, (uch*)fxname.c_str(), len * sizeof(TCHAR));
482
    Index = Hash & Mask;
483
    Hash = (Hash & ~Mask) | (len & Mask);
484
    return Table[Index];
485
}
486
 
487
HashListInt::~HashListInt(void)
488
{
489
    //
490
}
491
 
492
XItem *HashListInt::FindName(const DZStrW& name)
493
{                      
494
    finame = name;
495
    return FindAName();
496
}
497
 
498
// returns pointer to existing entry if duplicate
499
const XItem *HashListInt::AddNode(const XItem *xname)
500
{                            
501
    finame = xname->IName;
502
    return AddANode(xname);
503
}
504
 
505
bool HashListInt::Matches(const HL_node *node) const
506
{
507
    return finame.CompareNoCase(node->xdata->IName) == 0;
508
}
509
 
510
HL_node* HashListInt::Prepare(void)
511
{
512
    finame.ToUpper();
513
    int len = finame.length();
514
    Hash = crc32(0, (uch*)finame.c_str(), len * sizeof(TCHAR));
515
    Index = Hash & Mask;
516
    Hash = (Hash & ~Mask) | (len & Mask);
517
    return Table[Index];
518
}
519
 
520
ZipItem::ZipItem() : XItem()
521
{
522
    vem = 0;
523
        ver = 0;
524
        flg = 0;
525
        how = 0;
526
        nam = 0;
527
        ext = 0;
528
    cext = 0;
529
    com = 0;
530
    dsk = 0;
531
    att = 0;
532
    lflg = 0;
533
    atx = 0;
534
    tim = 0;
535
    crc = 0;
536
    siz = 0;
537
    off = 0;
538
    fextra = NULL;
539
    fcextra = NULL;
540
    fcomment = NULL;
541
    fntfs = NULL;
542
    mark = 0;
543
    trash = 0;
544
    nxt = NULL;
545
}        
546
 
547
ZipItem::ZipItem(const ZipItem& other): XItem(other)
548
{
549
        Copy(other);
550
}
551
 
552
ZipItem& ZipItem::operator=(const ZipItem& other)
553
{
554
        if (&other != this)
555
        {
556
                *((XItem*)this) = (const XItem&)other;
557
                Copy(other);
558
                nxt = other.nxt;
559
        }
560
        return *this;
561
}
562
 
563
ZipItem::ZipItem(const FndItem* f): XItem(*f)
564
{
565
    vem = 0;
566
    ver = 0;
567
    flg = 0;
568
    how = 0;
569
    nam = 0;
570
    ext = 0;
571
    cext = 0;
572
    com = 0;
573
    dsk = 0;
574
    att = 0;
575
    lflg = 0;
576
    atx = 0;
577
    tim = 0;
578
    crc = 0;
579
    siz = 0;
580
        off = 0;
581
    fntfs = NULL;
582
    fcomment = NULL;
583
    mark = 0;
584
    trash = 0;
585
    nxt = NULL;
586
        options = f->options;
587
        len = f->len; // RCV added.
588
}
589
 
590
ZipItem::~ZipItem()
591
{
592
    if (fcomment)
593
        delete[] fcomment;
594
    if (fntfs)
595
        delete fntfs;
596
}
597
 
598
void __fastcall ZipItem::Copy(const ZipItem& other)
599
{
600
        if (&other != this)
601
        {
602
                vem = other.vem;
603
                ver = other.ver;
604
                flg = other.flg;
605
                how = other.how;
606
                nam = other.nam;
607
                ext = other.ext;
608
        cext = other.cext;
609
                com = other.com;
610
        dsk = other.dsk;
611
                att = other.att;
612
        lflg = other.lflg;
613
                atx = other.atx;
614
        tim = other.tim;
615
        crc = other.crc;
616
                siz = other.siz;
617
        len = other.len;
618
                off = other.off;
619
        mark = other.mark;
620
                trash = other.trash;
621
                nxt = NULL;
622
                fextra = NULL;
623
                fcextra = NULL;
624
        fcomment = NULL;
625
                extra = other.extra;
626
        cextra = other.cextra;
627
                Comment = other.Comment;
628
 
629
                fntfs = NULL;
630
        if (other.fntfs)
631
                {
632
                        fntfs = new XNTFSData;
633
            memcpy(fntfs, other.ntfs, sizeof(XNTFSData));
634
                }
635
        }
636
}
637
 
638
void __fastcall ZipItem::SetComment(const DZStrW& value)
639
{
640
    if (fcomment)
641
        delete[] fcomment;
642
    fcomment = NULL;
643
    if (value)
644
    {
645
        fcomment = (wchar_t*) DupStr(value);
646
        com = value.length();
647
    }
648
    else
649
        com = 0;
650
}
651
 
652
FndItem::FndItem(): XItem()
653
{
654
    nxt = NULL;
655
}
656
 
657
FndItem::FndItem(const XItem& other) : XItem(other)
658
{
659
    nxt = NULL;
660
}
661
 
662
FndItem::~FndItem()
663
{
664
        //
665
}
666
 
667
 
668
// ? CompNameExt compare ends of strings for name.ext
669
int __fastcall SameNameExt(const DZStrW& fname, const DZStrW& oname)
670
{
671
  if (fname.IsEmpty() || oname.IsEmpty())
672
    return 0;         // cannot do it
673
  int fs, os;
674
  if (fname.LastChar() != oname.LastChar())
675
      return 0;
676
  fs = fname.ReverseFind(_T('\\'));
677
  os = oname.ReverseFind(_T('\\'));
678
  DZStrW f = fs >= 0 ? fname.Mid(fs+1) : fname;
679
  DZStrW o = os >= 0 ? oname.Mid(os+1) : oname;
680
  return (f.length() == o.length()) ? f.CompareNoCase(o) == 0 : 0;
681
}
682