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 "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
}