Subversion Repositories autosfx

Rev

Blame | Last modification | View Log | RSS feed

  1. #include "stdafx.h"
  2. #pragma hdrstop
  3.  
  4. #include "ZipOp.h"
  5. //---------------------------------------------------------------------------
  6.  
  7. #include "enter.h"
  8. #include "dz_errs.h"
  9.  
  10. #undef _DZ_FILE_
  11. #define _DZ_FILE_ DZ_ZIPOP_CPP
  12.  
  13. /* ZGlobals.c
  14.  * Copyright (C) 1990-1996 Mark Adler, Richard B. Wales, Jean-loup Gailly,
  15.  * Kai Uwe Rommel, Onno van der Linden and Igor Mandrichenko.
  16.  * Permission is granted to any individual or institution to use, copy, or
  17.  * redistribute this software so long as all of the original files are included,
  18.  * that it is not sold for profit, and that this copyright notice is retained.
  19.  * This version modified by Chris Vleghert for BCB/Delphi Zip.
  20.   ** distributed under LGPL license ** see license.txt for details
  21.  
  22.   Copyright (c) 1990-2007 Info-ZIP.  All rights reserved.
  23.  
  24.   See the accompanying file LICENSE, version 2007-Mar-4 or later
  25.   (the contents of which are also included in zip.h) for terms of use.
  26.   If, for some reason, all these files are missing, the Info-ZIP license
  27.   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
  28.  
  29.   parts Copyright (C) 1997 Mike White, Eric W. Engler
  30. ************************************************************************
  31.  Copyright (C) 2009, 2010  by Russell J. Peters, Roger Aelbrecht
  32.  
  33.    This file is part of TZipMaster Version 1.9.
  34.  
  35.     TZipMaster is free software: you can redistribute it and/or modify
  36.     it under the terms of the GNU Lesser General Public License as published by
  37.     the Free Software Foundation, either version 3 of the License, or
  38.     (at your option) any later version.
  39.  
  40.     TZipMaster is distributed in the hope that it will be useful,
  41.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  42.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  43.     GNU Lesser General Public License for more details.
  44.  
  45.     You should have received a copy of the GNU Lesser General Public License
  46.     along with TZipMaster.  If not, see <http://www.gnu.org/licenses/>.
  47.  
  48.     contact: problems@delphizip.org (include ZipMaster in the subject).
  49.     updates: http://www.delphizip.org
  50.     DelphiZip maillist subscribe at http://www.freelists.org/list/delphizip
  51. ************************************************************************/
  52.  
  53. ZipOp::ZipOp(const DllCommands *C): ZipFunc(C)
  54. {
  55.     fnoisy = 1;
  56.  
  57.     fuser_notified_of_abort = 0;
  58.     fdll_handles_errors = 1;       // By dflt, this DLL will generate error msg boxes
  59.  
  60.     fvolume_label = 0;
  61.     fhidden_files = 0;
  62.     ffix = 0;
  63.  
  64.     if (C->fOptions.System) // include system and hidden files -S
  65.         fhidden_files = 1;
  66.  
  67.     if (C->fOptions.Volume) // Include volume label -$
  68.         fvolume_label = 1;
  69.  
  70.     if (C->fOptions.Quiet || !C->fHandle)
  71.     {
  72.         // quiet operation -q
  73.         fnoisy = 0; // shut us up!
  74.         fdll_handles_errors = 0; // All error msgs passed to caller via callback function
  75.     }
  76.  
  77.     if (Verbose)
  78.         fnoisy = 1;
  79.     // give the component the 'key'
  80.     CB->Arg1 = ((unsigned)this) >> 2;
  81.     Set_Oper(this, ZIPOPER);        // add to 'active' list
  82.     CB->UserCB(zacKey);
  83. }
  84.  
  85. ZipOp::~ZipOp(void)
  86. {
  87.     Set_Oper(this, 0);  // remove from list
  88.     CB->Arg1 = 0;
  89.     CB->UserCB(zacKey);
  90. //  ZipCleanup();   // something may have failed
  91. }
  92.  
  93.  
  94. // Add (or exclude) the name of an existing disk file. Return an error code
  95. //   in the ZEN_ class. Return DZ_ERR_GOOD if OK. n :: Name to add (or exclude).
  96. //   nSize :: Size of the file or dir(0).
  97. int ZipOp::newname(const DZStrW &nme, ZInt64 nSize)
  98. {
  99.     FndItem  *f;  // where in found, or new found entry
  100.     ZipItem  *z;  // where in zfiles (if found)
  101.     int           dosflag;    // force 8x3?
  102.     int           ErrMsg = DZ_ERR_GOOD;
  103.     int           levl;       // required compression
  104.     bool          noext = false;  // don't ignore extension
  105.  
  106.     DZStrW name, undosm, tmp;
  107.     DZStrW iname;
  108.     DZStrW m;
  109. //    ArgSplitter splitter;
  110. //      if (Verbose)
  111. //              Notify(IVERBOSE, _T("adding file %s to found list"), nme.c_str());
  112.         int r = CleanPath(nme, name);//, fEncodeAs == zeoNone);
  113.  
  114.         if (r)
  115.     {
  116.         if (Verbose)
  117.             Notify(IERROR, _T("invalid new name %s"), nme.c_str());
  118.  
  119.         return DZ_ERM_INVAL_NAME;
  120.     }
  121.  
  122.     levl = flevel;
  123.     do
  124.     {
  125.         // Just one loop, with this w'll get a better error handling. RCV: 1.605
  126.         dosflag = (fEncodeAs == zeoOEM) ? 3 : 0;
  127.  
  128. //        if (fdosify)
  129. //            dosflag = 1;
  130.  
  131.         m = ex2IntForm(name, false);
  132.         // Discard directory names with zip -rj
  133.         if (m.IsEmpty())
  134.         {
  135.             // If extensions needs to be swapped, we will have empty directory
  136.             //   names instead of the original directory. For example, zipping 'c.',
  137.             //   'c.main' should zip only 'main.c' while 'c.' will be converted to
  138.             //   '\0' by ex2in.
  139.             if (fpathput)
  140.                 throw DZException(DZ_ERM_LOGIC_ERROR);
  141.  
  142. //                ziperr(ZEN_LOGIC05);
  143.             break;
  144.         }
  145.  
  146.         undosm = m;
  147.  
  148.         if (dosflag || !fpathput)
  149.         {
  150.             // use default settings
  151.             undosm = ex2IntForm(name, true);
  152.             if (undosm.IsEmpty())
  153.                 undosm = m;
  154.         }
  155.  
  156.         // check excluded before going further
  157.                 if (fpcount && ZMatch(fExcludes, undosm))
  158.         {
  159.             // Do not clear z->mark if "exclude", because, when "dosify ||
  160.             //   !pathput" is in effect, two files with different filter options
  161.             //   may hit the same z entry.
  162.             if (Verbose)
  163.                 Notify(IVERBOSE, _T("excluding %s"), name.c_str());
  164.  
  165.             break;
  166.         }
  167.  
  168.         // **** start of rename check
  169.         // Give the user a chance to change the internal name
  170.         if (Is_DrvEx(name))
  171.             tmp = name;
  172.         else
  173.                         tmp = GetFullPath(name); // uses current root
  174.  
  175.         CB->Msg2 = tmp;// full path/name
  176.                 CB->Msg = undosm;// proposed name
  177.                 if (CB->UserCB(zacNewName) == CALLBACK_TRUE)  // changed
  178.                 {
  179.                         int nerr;// = 0;
  180.                         tmp = CB->Msg;
  181.                         unsigned index = 0;
  182.                         DZStrW fs;
  183.  
  184.                         DZStrW arg = GetArg(tmp, index, false);
  185.                         nerr = CleanPath(arg, fs);
  186.                         if (!nerr)
  187.                         {
  188.                                 if (arg.IsEmpty())
  189.                                 {
  190.                                         if (Verbose)
  191.                                                 Notify(IVERBOSE, _T("caller excluding %s"), tmp.c_str());
  192.  
  193.                                         break;
  194.                                 }
  195.                                 // any switches issued
  196.                                 while (!nerr && tmp[index] == '/')
  197.                                 {
  198.                                         // process switches
  199.                                         arg = GetArg(tmp, ++index, false);
  200.                                         if (arg.length() < 1)
  201.                                                 continue;
  202.                                         TCHAR ch = arg[0]; // the switch
  203.                                         if (arg.length() == 3 && arg[1] == _T(':') &&
  204.                                                 (ch == _T('c') || ch == _T('C')) && _istdigit(arg[2]))
  205.                                         {
  206.                                                 // new compression level
  207.                                                 levl = arg[2] - _T('0');
  208.                                                 noext = true;
  209.                                                 continue;
  210.                                         }
  211.                                         nerr = 55;
  212. //                                      if (Verbose)
  213. //                                              Notify(IVERBOSE, _T("invalid switch %s ignored"), arg.c_str());
  214.                                 }
  215.                                 if (tmp[index] == ZPasswordFollows)
  216.                                 {
  217.                                         nerr = 66;
  218.                                 }
  219.                         }
  220.                         if (nerr)// < 0)
  221.                         {
  222.                                 nerr = DZ_ERM_INVAL_NAME;
  223.                                 Notify(nerr, _T("invalid new name %s"), tmp.c_str());
  224.                                 return nerr;
  225.                         }
  226.                         // prepare the new name
  227.                         m = ex2IntForm(fs, false);
  228.  
  229.                         // Discard directory names with zip -rj
  230.                         if (m.IsEmpty())
  231.                         {
  232.                                 // If extensions needs to be swapped, we will have empty directory
  233.                                 //   names instead of the original directory. For example, zipping 'c.',
  234.                                 //   'c.main' should zip only 'main.c' while 'c.' will be converted to
  235.                                 //   '\0' by ex2in.
  236.                                 if (fpathput)
  237.                                         throw DZException(DZ_ERM_LOGIC_ERROR);
  238.                                 break;
  239.                         }
  240.  
  241.                         if (dosflag || !fpathput)
  242.                         {
  243.                                 undosm = ex2IntForm(name, true);
  244.                                 if (undosm.IsEmpty())
  245.                                         undosm = m;
  246.                         }
  247.                 }
  248.  
  249.         // Search for name in zip file. If there, mark it, else add to list of
  250.         //   new names to do (or remove from that list).
  251. //        if ((z = zsearch(undosm)) != NULL)
  252.         if ((z = zsearch(m)) != NULL)
  253.         {
  254.             z->mark = 1;
  255.             z->XName = name;
  256.             z->Passw = fkey;                 // p RP 173 current password
  257.             z->Base = CurBase->Base;
  258.             z->options.keepver = fversion ? 1 : 0;
  259. #ifdef FORCE_NEWNAME
  260.             z->IName = m;//undosm;
  261. #endif
  262.  
  263.             // Better keep the old name. Useful when updating on MSDOS a zip
  264.             //   file made on Unix.
  265.             z->options.dosflag = dosflag & 3;  // want OEM
  266. #ifdef _ZDEBUG
  267. Notify(ITRACE, _T("newname 1: %s dosflag %i"), z->iname, z->options.dosflag);
  268. #endif
  269.  
  270.             if (Verbose)
  271.                 Notify(IVERBOSE, _T("including %s"), name.c_str());
  272.  
  273.             if (name == flabel)
  274.                 flabel = z->iname;
  275.         }
  276.         else
  277.         {
  278.             // not in zipfile already - add to or remove from list
  279.             // if (!pcount || filter(undosm, pG)) RP cannot get here if excluded
  280.             // Check that we are not adding the zip file to itself. This catches
  281.             //   cases like "zip -m foo ../dir/foo.zip". SLASH
  282.             if (SameNameExt(fzipfile, name))  // check likely same
  283.             {
  284.  
  285.                 struct stati64 statb;
  286.  
  287.                 if (fzipstate == -1)
  288.                 {
  289.                     fzipstate = /*fzipfile.CompareExact(_T("-")) &&*/
  290.                                 _tstati64(fzipfile, &fzipstatb) == 0;
  291.                 }
  292.  
  293.                 if (fzipstate == 1
  294.                         && (statb = fzipstatb, ZStat(GetFullPath(name), &statb) == 0
  295.                             && fzipstatb.st_mode == statb.st_mode
  296.                             && fzipstatb.st_ino == statb.st_ino
  297.                             && fzipstatb.st_dev == statb.st_dev
  298.                             && fzipstatb.st_uid == statb.st_uid
  299.                             && fzipstatb.st_gid == statb.st_gid
  300.                             && fzipstatb.st_size == statb.st_size
  301.                             && fzipstatb.st_mtime == statb.st_mtime
  302.                             && fzipstatb.st_ctime == statb.st_ctime
  303.                            ))
  304.                 {
  305.                     // Don't compare a_time since we are reading the file
  306.                     break;                // is same
  307.                 }
  308.             }
  309.  
  310.             // allocate space and add to list
  311.             f = new FndItem;
  312.             *(ffnxt) = f;
  313. //            f->lst = ffnxt;
  314.             f->nxt = NULL;
  315.             ffnxt = &f->nxt;
  316.             ffcount++;
  317.             f->xname = name;
  318.             f->Passw = fkey;       // p 173
  319.             f->Base = CurBase->Base;
  320.             f->options.keepver = fversion ? 1 : 0;
  321.             f->IName = m;//undosm;
  322.             f->options.dosflag = dosflag & 3;  // want OEM
  323.             f->options.level = levl & 15;
  324.             f->options.noext = (noext || fNoExtChk) ? 1 : 0;
  325.             f->len = nSize;           // RCV added.
  326.             if (name == flabel)
  327.                 flabel = f->iname;
  328. #ifdef _ZDEBUG
  329. Notify(ITRACE, _T("newname 2: %s dosflag %i"), f->xname, f->options.dosflag);
  330. #endif
  331.         }
  332.  
  333.         break;
  334.     }
  335.     while (true);
  336.  
  337.     return ErrMsg;
  338. }
  339.  
  340. #define PATHCUT _T('\\')
  341. // If the file name *s has a dot (other than the first char), or if the -A
  342. //   option is used (adjust self-extracting file) then return the name,
  343. //   otherwise append .zip to the name. Allocate the space for the name in
  344. //   either case. Return a pointer to the new name, or NULL if malloc() fails.
  345. //   s :: File name to force to zip.
  346. DZStrW ZipOp::ziptyp(const DZStrW &s)
  347. {
  348.     DZStrW tmp;
  349.  
  350.     if (s.IsEmpty())
  351.         return tmp;
  352.  
  353.     unsigned res = GetFullPathName(s, MAX_PATH, tmp.GetBuffer(MAX_PATH), NULL);
  354.  
  355.     tmp.ReleaseBuffer(res);
  356.  
  357.     if (tmp.IsEmpty() || !fadjust)
  358.         return tmp;
  359.  
  360.     int sp = tmp.ReverseFind(BSLASH);
  361.  
  362.     if (tmp.ReverseFind(_T('.')) <= sp)
  363.         tmp += _T(".zip");
  364.  
  365.     return tmp;
  366. }
  367.  
  368.  
  369.  
  370. DZOp *MakeZipper(const DllCommands *C)
  371. {
  372.     return new ZipOp(C);
  373. }
  374.  
  375. int ZEN_Rank(int err)
  376. {
  377.     int t = DZ_ERR(err);
  378.     if (t == DZ_ERR_MISS || t == DZ_ERR_INVAL_NAME)
  379.         return -1;
  380.     return t;
  381. }
  382.