Subversion Repositories autosfx

Rev

Blame | Last modification | View Log | RSS feed

  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.  
  683.