Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
6725 siemargl 1
/*
2
  Copyright (c) 1990-2009 Info-ZIP.  All rights reserved.
3
 
4
  See the accompanying file LICENSE, version 2009-Jan-02 or later
5
  (the contents of which are also included in unzip.h) for terms of use.
6
  If, for some reason, all these files are missing, the Info-ZIP license
7
  also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
8
*/
9
/* Windows Info-ZIP Unzip DLL module
10
 *
11
 * Author: Mike White
12
 *
13
 * Original: 1996
14
 *
15
 * This module has the entry points for "unzipping" a zip file.
16
 */
17
 
18
/*---------------------------------------------------------------------------
19
 
20
  This file is the WINDLL replacement for the generic ``main program source
21
  file'' unzip.c.
22
 
23
  See the general comments in the header part of unzip.c.
24
 
25
  Copyrights:  see accompanying file "COPYING" in UnZip source distribution.
26
               (This software is free but NOT IN THE PUBLIC DOMAIN.  There
27
               are some restrictions on commercial use.)
28
 
29
  ---------------------------------------------------------------------------*/
30
 
31
#define __WINDLL_C      /* identifies this source module */
32
 
33
#define WIN32_LEAN_AND_MEAN
34
#define UNZIP_INTERNAL
35
#include "../unzip.h"
36
#include "../crypt.h"
37
#include "../unzvers.h"
38
#include "../windll/windll.h"
39
#include "../windll/structs.h"
40
#include "../consts.h"
41
#include 
42
 
43
/* Added type casts to prevent potential "type mismatch" error messages. */
44
#ifdef REENTRANT
45
#  undef __G
46
#  undef __G__
47
#  define __G                 (Uz_Globs *)pG
48
#  define __G__               (Uz_Globs *)pG,
49
#endif
50
 
51
HANDLE hwildZipFN;
52
HANDLE hInst;               /* current instance */
53
HANDLE hDCL;
54
int fNoPrinting = 0;
55
extern jmp_buf dll_error_return;
56
 
57
/* Helper function to release memory allocated by Wiz_SetOpts() */
58
static void FreeDllMem(__GPRO);
59
 
60
/* For displaying status messages and error messages */
61
static int UZ_EXP DllMessagePrint(zvoid *pG, uch *buf, ulg size, int flag);
62
 
63
#if 0 /* currently unused */
64
/* For displaying files extracted to the display window */
65
int DllDisplayPrint(zvoid *pG, uch *buf, ulg size, int flag);
66
#endif /* never */
67
 
68
/* Callback function for status report and/or user interception */
69
static int UZ_EXP Wiz_StatReportCB(zvoid *pG, int fnflag, ZCONST char *zfn,
70
                                   ZCONST char *efn, ZCONST zvoid *details);
71
 
72
/* Dummy sound function for those applications that don't use sound */
73
static void WINAPI DummySound(void);
74
 
75
static int UnzipAllocMemory(unsigned, char *, char *, char ***, unsigned *);
76
static int UnzipParseString(LPCSTR, unsigned *, char ***);
77
static void UnzipFreeArguments(unsigned, char ***);
78
 
79
#ifndef UNZIPLIB
80
/*  DLL Entry Point */
81
 
82
#ifdef __BORLANDC__
83
#pragma argsused
84
/* Borland seems to want DllEntryPoint instead of DllMain like MSVC */
85
#define DllMain DllEntryPoint
86
#endif
87
#ifdef WIN32
88
BOOL WINAPI DllMain( HINSTANCE hInstance,
89
                     DWORD dwReason,
90
                     LPVOID plvReserved)
91
#else
92
int FAR PASCAL LibMain( HINSTANCE hInstance,
93
                        WORD wDataSegment,
94
                        WORD wHeapSize,
95
                        LPSTR lpszCmdLine )
96
#endif
97
{
98
#ifndef WIN32
99
   /* The startup code for the DLL initializes the local heap(if there is one)
100
    * with a call to LocalInit which locks the data segment.
101
    */
102
 
103
   if ( wHeapSize != 0 )
104
      {
105
      UnlockData( 0 );
106
      }
107
   hInst = hInstance;
108
   return 1;   /* Indicate that the DLL was initialized successfully. */
109
#else
110
   BOOL rc = TRUE;
111
   switch( dwReason )
112
      {
113
      case DLL_PROCESS_ATTACH:
114
         // DLL is loaded. Do your initialization here.
115
         // If cannot init, set rc to FALSE.
116
         hInst = hInstance;
117
         break;
118
 
119
      case DLL_PROCESS_DETACH:
120
         // DLL is unloaded. Do your cleanup here.
121
         break;
122
      default:
123
         break;
124
      }
125
   return rc;
126
#endif
127
}
128
 
129
#ifdef __BORLANDC__
130
#pragma argsused
131
#endif
132
int FAR PASCAL WEP ( int bSystemExit )
133
{
134
   return 1;
135
}
136
#endif /* !UNZIPLIB */
137
 
138
static int UnzipAllocMemory(unsigned int i, char *cmd, char *str,
139
                            char ***pargVee, unsigned int *pargCee)
140
{
141
    if (((*pargVee)[i] = (char *)malloc(sizeof(char) * strlen(cmd)+1 ))
142
        == NULL)
143
    {
144
        if (pargCee != NULL)
145
            (*pargCee)++;
146
        UnzipFreeArguments(*pargCee, pargVee);
147
        fprintf(stdout, "Unable to allocate memory in unzip library at %s\n",
148
                str);
149
        return PK_MEM;
150
    }
151
    strcpy((*pargVee)[i], cmd);
152
    (*pargCee)++;
153
    return PK_OK;
154
}
155
 
156
static void UnzipFreeArguments(unsigned int argCee, char ***pargVee)
157
{
158
    unsigned i;
159
 
160
    /* Free the arguments in the arrays */
161
    for (i = 0; i < argCee; i++)
162
    {
163
        free ((*pargVee)[i]);
164
        (*pargVee)[i] = NULL;
165
    }
166
 
167
    /* Then free the arrays themselves */
168
    free(*pargVee);
169
}
170
 
171
 
172
static int UnzipParseString(LPCSTR s, unsigned int *pargCee, char ***pargVee)
173
{
174
    unsigned int i = 0;
175
    char *str1, *str2, *str3;
176
    size_t size;
177
 
178
    str1 = (char *) malloc(lstrlen(s)+4);
179
    lstrcpy(str1, s);
180
    lstrcat(str1, " @");
181
 
182
    str2 = strchr(str1, '\"'); // get first occurance of double quote
183
 
184
    while ((str3 = strchr(str1, '\t')) != NULL)
185
    {
186
        str3[0] = ' '; // Change tabs into a single space
187
    }
188
 
189
    /* Note that if a quoted string contains multiple adjacent spaces, they
190
       will not be removed, because they could well point to a valid
191
       folder/file name.
192
     */
193
    while ((str2 = strchr(str1, '\"')) != NULL)
194
    {
195
        // Found an opening double quote; get the corresponding closing quote
196
        str3 = strchr(str2+1, '\"');
197
        if (str3 == NULL)
198
        {
199
            free(str1);
200
            return PK_PARAM; /* Something is screwy with the
201
                                string, bail out */
202
        }
203
        str3[0] = '\0';  // terminate str2 with a NULL
204
 
205
        size = _msize(*pargVee);
206
        if ((*pargVee = (char **)realloc(*pargVee, size + sizeof(char *)))
207
            == NULL)
208
        {
209
            fprintf(stdout, "Unable to allocate memory in unzip dll\n");
210
            return PK_MEM;
211
        }
212
        // argCee is incremented in UnzipAllocMemory
213
        if (UnzipAllocMemory(i, str2+1, "Creating file list from string",
214
                             pargVee, pargCee) != PK_OK)
215
        {
216
            free(str1);
217
            return PK_MEM;
218
        }
219
        i++;
220
        str3+=2;  // Point past the whitespace character
221
        str2[0] = '\0'; // Terminate str1
222
        lstrcat(str1, str3);
223
    }    // end while
224
 
225
    /* points to first occurance of a space */
226
    str2 = strchr(str1, ' ');
227
 
228
    /*  Go through the string character by character, looking for instances
229
        of two spaces together. Terminate when you find the trailing @
230
    */
231
    while ((str2[0] != '\0') && (str2[0] != '@'))
232
    {
233
        while ((str2[0] == ' ') && (str2[1] == ' '))
234
        {
235
            str3 = &str2[1];
236
            str2[0] = '\0';
237
            lstrcat(str1, str3);
238
        }
239
        str2++;
240
    }
241
 
242
    /* Do we still have a leading space? */
243
    if (str1[0] == ' ')
244
    {
245
        str3 = &str1[1];
246
        lstrcpy(str1, str3); // Dump the leading space
247
    }
248
 
249
 
250
    /* Okay, now we have gotten rid of any tabs and replaced them with
251
       spaces, and have replaced multiple spaces with a single space. We
252
       couldn't do this before because the folder names could have actually
253
       contained these characters.
254
    */
255
 
256
    str2 = str3 = str1;
257
 
258
    while ((str2[0] != '\0') && (str3[0] != '@'))
259
    {
260
        str3 = strchr(str2+1, ' ');
261
        str3[0] = '\0';
262
        size = _msize(pargVee);
263
        if ((*pargVee = (char **)realloc(*pargVee, size + sizeof(char *)))
264
            == NULL)
265
        {
266
            fprintf(stdout, "Unable to allocate memory in unzip dll\n");
267
            return PK_MEM;
268
        }
269
        if (UnzipAllocMemory(i, str2, "Creating file list from string",
270
                             pargVee, pargCee) != PK_OK)
271
        {
272
            free(str1);
273
            return PK_MEM;
274
        }
275
        i++;
276
        str3++;
277
        str2 = str3;
278
    }
279
    free(str1);
280
    return PK_OK;
281
}
282
 
283
/* DLL calls */
284
 
285
BOOL WINAPI Wiz_Init(pG, lpUserFunc)
286
zvoid *pG;
287
LPUSERFUNCTIONS lpUserFunc;
288
{
289
    G.message = DllMessagePrint;
290
    G.statreportcb = Wiz_StatReportCB;
291
    if (lpUserFunc->sound == NULL)
292
       lpUserFunc->sound = DummySound;
293
    G.lpUserFunctions = lpUserFunc;
294
 
295
    SETLOCALE(LC_CTYPE, "");
296
 
297
    if (!G.lpUserFunctions->print ||
298
        !G.lpUserFunctions->sound ||
299
        !G.lpUserFunctions->replace)
300
        return FALSE;
301
 
302
    return TRUE;
303
}
304
 
305
/*
306
    StructVersID      = version of this structure (= UZ_DCL_STRUCTVER)
307
    ExtractOnlyNewer  = TRUE for "update" without interaction
308
                        (extract only newer/new files, without queries)
309
    SpaceToUnderscore = TRUE if convert space to underscore
310
    PromptToOverwrite = TRUE if prompt to overwrite is wanted
311
    fQuiet            = quiet flag:
312
 
313
    ncflag            = write to stdout if TRUE
314
    ntflag            = test zip file
315
    nvflag            = verbose listing
316
    nfflag            = "freshen" (replace existing files by newer versions)
317
    nzflag            = display zip file comment
318
    ndflag            = controls (sub)directory recreation during extraction
319
 
320
                        1 = "safe" usage of paths in filenames (skip "../")
321
                        2 = allow also unsafe path components (dir traversal)
322
    noflag            = always overwriting existing files if TRUE
323
    naflag            = do end-of-line translation
324
    nZIflag           = get ZipInfo if TRUE
325
    B_flag            = backup existing files if TRUE
326
    C_flag            = be case insensitive if TRUE
327
    D_flag            = controls restoration of timestamps
328
 
329
                        1 = skip restoration of timestamps for folders
330
                            created on behalf of directory entries in the
331
                            Zip archive
332
                        2 = do not restore any timestamps; extracted files
333
                            and directories get stamped with the current time
334
    U_flag            = controls UTF-8 filename coding support
335
 
336
                        1 = recognize UTF-8 coded names, but all non-ASCII
337
                            characters are "escaped" into "#Uxxxx"
338
                        2 = UTF-8 support is disabled, filename handling
339
                            works exactly as in previous UnZip versions
340
    fPrivilege        = 1 => restore ACLs in user mode,
341
                        2 => try to use privileges for restoring ACLs
342
    lpszZipFN         = zip file name
343
    lpszExtractDir    = directory to extract to. This should be NULL if you
344
                        are extracting to the current directory.
345
 */
346
 
347
BOOL WINAPI Wiz_SetOpts(pG, lpDCL)
348
zvoid *pG;
349
LPDCL lpDCL;
350
{
351
    if (lpDCL->StructVersID != UZ_DCL_STRUCTVER)
352
        return FALSE;
353
 
354
    uO.qflag = lpDCL->fQuiet;  /* Quiet flag */
355
    G.pfnames = (char **)&fnames[0];    /* assign default file name vector */
356
    G.pxnames = (char **)&fnames[1];
357
 
358
    uO.jflag = (lpDCL->ndflag == 0);
359
    uO.ddotflag = (lpDCL->ndflag >= 2);
360
    uO.cflag = lpDCL->ncflag;
361
    uO.tflag = lpDCL->ntflag;
362
    uO.vflag = lpDCL->nvflag;
363
    uO.zflag = lpDCL->nzflag;
364
    uO.aflag = lpDCL->naflag;
365
#ifdef UNIXBACKUP
366
    uO.B_flag = lpDCL->B_flag;
367
#endif
368
    uO.C_flag = lpDCL->C_flag;
369
    uO.D_flag = lpDCL->D_flag;
370
    uO.U_flag = lpDCL->U_flag;
371
    uO.overwrite_all = lpDCL->noflag;
372
    uO.overwrite_none = !(lpDCL->noflag || lpDCL->PromptToOverwrite);
373
    uO.uflag = lpDCL->ExtractOnlyNewer || lpDCL->nfflag;
374
    uO.fflag = lpDCL->nfflag;
375
#ifdef WIN32
376
    uO.X_flag = lpDCL->fPrivilege;
377
#endif
378
    uO.sflag = lpDCL->SpaceToUnderscore; /* Translate spaces to underscores? */
379
    if (lpDCL->nZIflag)
380
      {
381
      uO.zipinfo_mode = TRUE;
382
      uO.hflag = TRUE;
383
      uO.lflag = 10;
384
      uO.qflag = 2;
385
      }
386
    else
387
      {
388
      uO.zipinfo_mode = FALSE;
389
      }
390
 
391
    G.extract_flag = (!uO.zipinfo_mode &&
392
                      !uO.cflag && !uO.tflag && !uO.vflag && !uO.zflag
393
#ifdef TIMESTAMP
394
                      && !uO.T_flag
395
#endif
396
                     );
397
 
398
    if (lpDCL->lpszExtractDir != NULL && G.extract_flag)
399
       {
400
#ifndef CRTL_CP_IS_ISO
401
       char *pExDirRoot = (char *)malloc(strlen(lpDCL->lpszExtractDir)+1);
402
 
403
       if (pExDirRoot == NULL)
404
           return FALSE;
405
       ISO_TO_INTERN(lpDCL->lpszExtractDir, pExDirRoot);
406
#else
407
#  define pExDirRoot lpDCL->lpszExtractDir
408
#endif
409
       if (strlen(pExDirRoot) >= FILNAMSIZ)
410
           {
411
           /* The supplied extract root path exceed the filename size limit. */
412
#ifndef CRTL_CP_IS_ISO
413
           free(pExDirRoot);
414
#endif
415
           return FALSE;
416
           }
417
       uO.exdir = pExDirRoot;
418
       }
419
    else
420
       {
421
       uO.exdir = (char *)NULL;
422
       }
423
 
424
/* G.wildzipfn needs to be initialized so that do_wild does not wind
425
   up clearing out the zip file name when it returns in process.c
426
*/
427
    if (strlen(lpDCL->lpszZipFN) >= FILNAMSIZ)
428
       /* length of supplied archive name exceed the system's filename limit */
429
       return FALSE;
430
 
431
    hwildZipFN = GlobalAlloc(GPTR, FILNAMSIZ);
432
    if (hwildZipFN == (HGLOBAL) NULL)
433
       return FALSE;
434
 
435
    G.wildzipfn = GlobalLock(hwildZipFN);
436
    lstrcpy(G.wildzipfn, lpDCL->lpszZipFN);
437
    _ISO_INTERN(G.wildzipfn);
438
 
439
    return TRUE;    /* set up was OK */
440
}
441
 
442
static void FreeDllMem(__GPRO)
443
{
444
    if (G.wildzipfn) {
445
        GlobalUnlock(hwildZipFN);
446
        G.wildzipfn = NULL;
447
    }
448
    if (hwildZipFN)
449
        hwildZipFN = GlobalFree(hwildZipFN);
450
 
451
#ifndef CRTL_CP_IS_ISO
452
    if (uO.exdir != NULL) {
453
        free(uO.exdir);
454
        uO.exdir = NULL;
455
    }
456
#endif
457
 
458
    uO.zipinfo_mode = FALSE;
459
}
460
 
461
int WINAPI Wiz_Unzip(pG, ifnc, ifnv, xfnc, xfnv)
462
zvoid *pG;
463
int ifnc;
464
char **ifnv;
465
int xfnc;
466
char **xfnv;
467
{
468
    int retcode, f_cnt;
469
#ifndef CRTL_CP_IS_ISO
470
    unsigned bufsize;
471
    char **intern_ifv = NULL, **intern_xfv = NULL;
472
#endif
473
 
474
    if (ifnv == (char **)NULL && ifnc != 0)
475
        ifnc = 0;
476
    else
477
        for (f_cnt = 0; f_cnt < ifnc; f_cnt++)
478
            if (ifnv[f_cnt] == (char *)NULL) {
479
                ifnc = f_cnt;
480
                break;
481
            }
482
    if (xfnv == (char **)NULL && xfnc != 0)
483
        xfnc = 0;
484
    else
485
        for (f_cnt = 0; f_cnt < xfnc; f_cnt++)
486
            if (xfnv[f_cnt] == (char *)NULL) {
487
                xfnc = f_cnt;
488
                break;
489
            }
490
 
491
    G.process_all_files = (ifnc == 0 && xfnc == 0);         /* for speed */
492
    G.filespecs = ifnc;
493
    G.xfilespecs = xfnc;
494
 
495
    if (ifnc > 0) {
496
        for (f_cnt = ifnc; --f_cnt >= 0;)
497
            if (strlen(ifnv[f_cnt]) > ((WSIZE>>2) - 160)) {
498
                /* include filename pattern is too long for internal buffers */
499
                FreeDllMem(__G);
500
                return PK_PARAM;
501
            }
502
 
503
#ifdef CRTL_CP_IS_ISO
504
        G.pfnames = ifnv;
505
#else /* !CRTL_CP_IS_ISO */
506
        intern_ifv = (char **)malloc((ifnc+1)*sizeof(char **));
507
        if (intern_ifv == (char **)NULL)
508
        {
509
            FreeDllMem(__G);
510
            return PK_BADERR;
511
        }
512
 
513
        bufsize = 0;
514
        for (f_cnt = ifnc; --f_cnt >= 0;)
515
            bufsize += strlen(ifnv[f_cnt]) + 1;
516
        intern_ifv[0] = (char *)malloc(bufsize);
517
        if (intern_ifv[0] == (char *)NULL)
518
        {
519
            free(intern_ifv);
520
            FreeDllMem(__G);
521
            return PK_BADERR;
522
        }
523
 
524
        for (f_cnt = 0; ; f_cnt++)
525
        {
526
            ISO_TO_INTERN(ifnv[f_cnt], intern_ifv[f_cnt]);
527
            if ((f_cnt+1) >= ifnc)
528
                break;
529
            intern_ifv[f_cnt+1] = intern_ifv[f_cnt] +
530
                                  (strlen(intern_ifv[f_cnt]) + 1);
531
        }
532
        intern_ifv[ifnc] = (char *)NULL;
533
        G.pfnames = intern_ifv;
534
#endif /* ?CRTL_CP_IS_ISO */
535
    }
536
 
537
    if (xfnc > 0) {
538
        for (f_cnt = xfnc; --f_cnt >= 0;)
539
            if (strlen(xfnv[f_cnt]) > ((WSIZE>>2) - 160))
540
            {
541
                /* exclude filename pattern is too long for internal buffers */
542
#ifndef CRTL_CP_IS_ISO
543
                if (ifnc > 0)
544
                {
545
                    free(intern_ifv[0]);
546
                    free(intern_ifv);
547
                }
548
#endif
549
                FreeDllMem(__G);
550
                return PK_PARAM;
551
            }
552
 
553
#ifdef CRTL_CP_IS_ISO
554
        G.pxnames = xfnv;
555
#else /* !CRTL_CP_IS_ISO */
556
        intern_xfv = (char **)malloc((xfnc+1)*sizeof(char **));
557
        if (intern_xfv == (char **)NULL)
558
        {
559
            if (ifnc > 0)
560
            {
561
                free(intern_ifv[0]);
562
                free(intern_ifv);
563
            }
564
            FreeDllMem(__G);
565
            return PK_BADERR;
566
        }
567
 
568
        bufsize = 0;
569
        for (f_cnt = xfnc; --f_cnt >= 0;)
570
            bufsize += strlen(xfnv[f_cnt]) + 1;
571
        intern_xfv[0] = (char *)malloc(bufsize);
572
        if (intern_xfv[0] == (char *)NULL)
573
        {
574
            free(intern_xfv);
575
            if (ifnc > 0)
576
            {
577
                free(intern_ifv[0]);
578
                free(intern_ifv);
579
            }
580
            FreeDllMem(__G);
581
            return PK_BADERR;
582
        }
583
 
584
        for (f_cnt = 0; ; f_cnt++)
585
        {
586
            ISO_TO_INTERN(xfnv[f_cnt], intern_xfv[f_cnt]);
587
            if ((f_cnt+1) >= xfnc)
588
                break;
589
            intern_xfv[f_cnt+1] = intern_xfv[f_cnt] +
590
                                  (strlen(intern_xfv[f_cnt]) + 1);
591
        }
592
        intern_xfv[xfnc] = (char *)NULL;
593
        G.pxnames = intern_xfv;
594
#endif /* ?CRTL_CP_IS_ISO */
595
    }
596
 
597
/*---------------------------------------------------------------------------
598
    Okey dokey, we have everything we need to get started.  Let's roll.
599
  ---------------------------------------------------------------------------*/
600
 
601
    retcode = setjmp(dll_error_return);
602
    if (retcode)
603
    {
604
#ifndef CRTL_CP_IS_ISO
605
        if (xfnc > 0)
606
        {
607
            free(intern_xfv[0]);
608
            free(intern_xfv);
609
        }
610
        if (ifnc > 0)
611
        {
612
            free(intern_ifv[0]);
613
            free(intern_ifv);
614
        }
615
#endif
616
        FreeDllMem(__G);
617
        return PK_BADERR;
618
    }
619
 
620
    retcode = process_zipfiles(__G);
621
#ifndef CRTL_CP_IS_ISO
622
    if (xfnc > 0)
623
    {
624
        free(intern_xfv[0]);
625
        free(intern_xfv);
626
    }
627
    if (ifnc > 0)
628
    {
629
        free(intern_ifv[0]);
630
        free(intern_ifv);
631
    }
632
#endif
633
    FreeDllMem(__G);
634
    return retcode;
635
}
636
 
637
 
638
/*
639
ifnc       = number of file names being passed. If all files are to be
640
             extracted, then this can be zero.
641
ifnv       = file names to be unarchived. Wildcard patterns are recognized
642
             and expanded. If all files are to be extracted, then this can
643
             be NULL.
644
xfnc       = number of "file names to be excluded from processing" being
645
             passed. If all files are to be extracted, set this to zero.
646
xfnv       = file names to be excluded from the unarchiving process. Wildcard
647
             characters are allowed and expanded. If all files are to be
648
             extracted, set this argument to NULL.
649
lpDCL      = pointer to a structure with the flags for setting the
650
             various options, as well as the zip file name.
651
lpUserFunc = pointer to a structure that contains pointers to functions
652
             in the calling application, as well as sizes passed back to
653
             the calling application etc.
654
*/
655
 
656
int WINAPI Wiz_SingleEntryUnzip(int ifnc, char **ifnv, int xfnc, char **xfnv,
657
   LPDCL lpDCL, LPUSERFUNCTIONS lpUserFunc)
658
{
659
   int retcode;
660
   CONSTRUCTGLOBALS();
661
 
662
   if (!Wiz_Init((zvoid *)&G, lpUserFunc))
663
   {
664
      DESTROYGLOBALS();
665
      return PK_BADERR;
666
   }
667
 
668
   if (lpDCL->lpszZipFN == NULL)
669
   {
670
      /* Something has screwed up, we don't have a filename */
671
      DESTROYGLOBALS();
672
      return PK_NOZIP;
673
   }
674
 
675
   if (!Wiz_SetOpts((zvoid *)&G, lpDCL))
676
   {
677
      DESTROYGLOBALS();
678
      return PK_MEM;
679
   }
680
 
681
#ifdef SFX
682
   G.zipfn = lpDCL->lpszZipFN;
683
   G.argv0 = lpDCL->lpszZipFN;
684
#endif
685
 
686
   /* Here is the actual call to "unzip" the files (or whatever else you
687
    * are doing.)
688
    */
689
   retcode = Wiz_Unzip((zvoid *)&G, ifnc, ifnv, xfnc, xfnv);
690
 
691
   DESTROYGLOBALS();
692
   return retcode;
693
}
694
 
695
 
696
/*
697
This calling wrapper provided a method to pass file lists as plain strings
698
instead of the usual string arrays. For VB Users only...
699
ifnc       = number of file names being passed. If all files are to be
700
             extracted, then this can be zero.
701
ExtList    = Pointer to a list of file names to be extracted, separated by
702
             white space. If all files are to be extracted, then this should
703
             be NULL. Parameter ifnc should have an accurate count of the
704
             number of filenames being passed in.
705
xfnc       = number of "file names to be excluded from processing" being
706
             passed. If all files are to be extracted, set this to zero.
707
ExcList    = Pointer to a list of file names to be excluded from processing.
708
             Parameter xfnc should have an accurate count of the number of
709
             the number of filenames being passed in.
710
lpDCL      = pointer to a structure with the flags for setting the
711
             various options, as well as the zip file name.
712
lpUserFunc = pointer to a structure that contains pointers to functions
713
             in the calling application, as well as sizes passed back to
714
             the calling application etc.
715
*/
716
 
717
int WINAPI Wiz_SingleEntryUnzpList(unsigned int ifnc, LPCSTR ExtList,
718
   unsigned int xfnc, LPCSTR ExcList,
719
   LPDCL lpDCL, LPUSERFUNCTIONS lpUserFunc)
720
{
721
    int retcode;
722
    char **argVExt, **argVExc;
723
    unsigned int argCExt, argCExc;
724
 
725
    argCExt = argCExc = 0;
726
 
727
    if (ExtList != NULL)
728
    {
729
        if ((argVExt = (char **)malloc((ifnc)*sizeof(char *))) == NULL)
730
        {
731
            fprintf(stdout, "Unable to allocate memory in unzip dll\n");
732
            return PK_MEM;
733
        }
734
        if ((retcode = UnzipParseString(ExtList, &argCExt, &argVExt)) != PK_OK)
735
            return retcode;
736
    }
737
 
738
    if (ExcList != NULL)
739
    {
740
        if ((argVExc = (char **)malloc((ifnc)*sizeof(char *))) == NULL)
741
        {
742
            fprintf(stdout, "Unable to allocate memory in unzip dll\n");
743
            UnzipFreeArguments(argCExt, &argVExt);
744
            return PK_MEM;
745
        }
746
        if ((retcode = UnzipParseString(ExcList, &argCExc, &argVExc)) != PK_OK)
747
        {
748
            UnzipFreeArguments(argCExt, &argVExt);
749
            return retcode;
750
        }
751
    }
752
 
753
    retcode = Wiz_SingleEntryUnzip(argCExt, argVExt, argCExc, argVExc,
754
                                   lpDCL, lpUserFunc);
755
    UnzipFreeArguments(argCExc, &argVExc);
756
    UnzipFreeArguments(argCExt, &argVExt);
757
    return retcode;
758
}
759
 
760
 
761
int win_fprintf(zvoid *pG, FILE *file, unsigned int size, char far *buffer)
762
{
763
   if ((file != stderr) && (file != stdout))
764
   {
765
      return write(fileno(file),(char far *)(buffer),size);
766
   }
767
   if (!fNoPrinting)
768
      return G.lpUserFunctions->print((LPSTR)buffer, size);
769
   return (int)size;
770
}
771
 
772
/**********************************
773
 * Function DllMessagePrint()     *
774
 *                                *
775
 * Send messages to status window *
776
 **********************************/
777
#ifdef __BORLANDC__
778
#pragma argsused
779
#endif
780
static int UZ_EXP DllMessagePrint(pG, buf, size, flag)
781
    zvoid *pG;      /* globals struct:  always passed */
782
    uch *buf;       /* preformatted string to be printed */
783
    ulg size;       /* length of string (may include nulls) */
784
    int flag;       /* flag bits */
785
{
786
    if (!fNoPrinting)
787
        return G.lpUserFunctions->print((LPSTR)buf, size);
788
    else
789
        return (int)size;
790
}
791
 
792
#if 0 /* currently unused */
793
/********************************
794
 * Function DllDisplayPrint()   *
795
 *                              *
796
 * Send files to display window *
797
 ********************************/
798
#ifdef __BORLANDC__
799
#pragma argsused
800
#endif
801
int DllDisplayPrint(pG, buf, size, flag)
802
    zvoid *pG;      /* globals struct:  always passed */
803
    uch *buf;       /* preformatted string to be printed */
804
    ulg size;       /* length of string (may include nulls) */
805
    int flag;       /* flag bits */
806
{
807
    return (!fNoPrinting
808
            ? G.lpUserFunctions->print((LPSTR)buf, size)
809
            : (int)size);
810
}
811
#endif /* never */
812
 
813
 
814
/**********************************
815
 * Function UzpPassword()         *
816
 *                                *
817
 * Prompt for decryption password *
818
 **********************************/
819
#ifdef __BORLANDC__
820
#pragma argsused
821
#endif
822
int UZ_EXP UzpPassword(pG, rcnt, pwbuf, size, zfn, efn)
823
    zvoid *pG;          /* globals struct: always passed */
824
    int *rcnt;          /* retry counter */
825
    char *pwbuf;        /* buffer for password */
826
    int size;           /* size of password buffer */
827
    ZCONST char *zfn;   /* name of zip archiv */
828
    ZCONST char *efn;   /* name of archiv entry being processed */
829
{
830
#if CRYPT
831
    LPCSTR m;
832
 
833
    if (*rcnt == 0) {
834
        *rcnt = 2;
835
        m = "Enter password for: ";
836
    } else {
837
        (*rcnt)--;
838
        m = "Password incorrect--reenter: ";
839
    }
840
 
841
    return (*G.lpUserFunctions->password)((LPSTR)pwbuf, size, m, (LPCSTR)efn);
842
#else /* !CRYPT */
843
    return IZ_PW_ERROR; /* internal error, function should never get called */
844
#endif /* ?CRYPT */
845
} /* end function UzpPassword() */
846
 
847
/* Turn off all messages to the calling application */
848
void WINAPI Wiz_NoPrinting(int f)
849
{
850
    fNoPrinting = f;
851
}
852
 
853
/* Dummy sound function for those applications that don't use sound */
854
static void WINAPI DummySound(void)
855
{
856
}
857
 
858
/* Interface between WINDLL specific service callback functions and the
859
   generic DLL's "status report & user interception" callback */
860
#ifdef __BORLANDC__
861
#pragma argsused
862
#endif
863
static int WINAPI Wiz_StatReportCB(zvoid *pG, int fnflag, ZCONST char *zfn,
864
                    ZCONST char *efn, ZCONST zvoid *details)
865
{
866
    int rval = UZ_ST_CONTINUE;
867
 
868
    switch (fnflag) {
869
      case UZ_ST_START_EXTRACT:
870
        if (G.lpUserFunctions->sound != NULL)
871
            (*G.lpUserFunctions->sound)();
872
        break;
873
      case UZ_ST_FINISH_MEMBER:
874
        if ((G.lpUserFunctions->ServCallBk != NULL) &&
875
            (*G.lpUserFunctions->ServCallBk)(efn,
876
                                             (details == NULL ? 0L :
877
#ifdef Z_UINT8_DEFINED
878
                                              (z_uint8)(*((zusz_t *)details))
879
#else
880
                                              *((zusz_t *)details)
881
#endif
882
                                             )))
883
            rval = UZ_ST_BREAK;
884
        else if (G.lpUserFunctions->ServCallBk_i32 != NULL) {
885
             unsigned long siz_u4L = 0L;
886
             unsigned long siz_u4H = 0L;
887
             if (details != NULL) {
888
                 siz_u4L = (unsigned long)(*(zusz_t *)details);
889
#ifdef ZIP64_SUPPORT
890
                 siz_u4H = (unsigned long)((*(zusz_t *)details) >> 32);
891
#endif
892
             }
893
             if ((*G.lpUserFunctions->ServCallBk_i32)(efn, siz_u4L, siz_u4H))
894
                 rval = UZ_ST_BREAK;
895
        }
896
        break;
897
      case UZ_ST_IN_PROGRESS:
898
        break;
899
      default:
900
        break;
901
    }
902
    return rval;
903
}
904
 
905
 
906
#ifndef SFX
907
#ifndef __16BIT__
908
 
909
int WINAPI Wiz_UnzipToMemory(LPSTR zip, LPSTR file,
910
    LPUSERFUNCTIONS lpUserFunctions, UzpBuffer *retstr)
911
{
912
    int r;
913
#ifndef CRTL_CP_IS_ISO
914
    char *intern_zip, *intern_file;
915
#endif
916
 
917
    CONSTRUCTGLOBALS();
918
#ifndef CRTL_CP_IS_ISO
919
    intern_zip = (char *)malloc(strlen(zip)+1);
920
    if (intern_zip == NULL) {
921
       DESTROYGLOBALS();
922
       return PK_MEM;
923
    }
924
    intern_file = (char *)malloc(strlen(file)+1);
925
    if (intern_file == NULL) {
926
       DESTROYGLOBALS();
927
       free(intern_zip);
928
       return PK_MEM;
929
    }
930
    ISO_TO_INTERN(zip, intern_zip);
931
    ISO_TO_INTERN(file, intern_file);
932
#   define zip intern_zip
933
#   define file intern_file
934
#endif
935
    if (!Wiz_Init((zvoid *)&G, lpUserFunctions)) {
936
       DESTROYGLOBALS();
937
       return PK_BADERR;
938
    }
939
    G.redirect_data = 1;
940
 
941
    r = (unzipToMemory(__G__ zip, file, retstr) == PK_COOL);
942
 
943
    DESTROYGLOBALS();
944
#ifndef CRTL_CP_IS_ISO
945
#  undef file
946
#  undef zip
947
    free(intern_file);
948
    free(intern_zip);
949
#endif
950
    if (!r && retstr->strlength) {
951
       free(retstr->strptr);
952
       retstr->strptr = NULL;
953
    }
954
    return r;
955
}
956
 
957
 
958
 
959
 
960
/* Purpose: Determine if file in archive contains the string szSearch
961
 
962
   Parameters: archive  = archive name
963
               file     = file contained in the archive. This cannot be
964
                          a wildcard to be meaningful
965
               pattern  = string to search for
966
               cmd      = 0 - case-insensitive search
967
                          1 - case-sensitve search
968
                          2 - case-insensitive, whole words only
969
                          3 - case-sensitive, whole words only
970
               SkipBin  = if true, skip any files that have control
971
                          characters other than CR, LF, or tab in the first
972
                          100 characters.
973
 
974
   Returns:    TRUE if a match is found
975
               FALSE if no match is found
976
               -1 on error
977
 
978
   Comments: This does not pretend to be as useful as the standard
979
             Unix grep, which returns the strings associated with a
980
             particular pattern, nor does it search past the first
981
             matching occurrence of the pattern.
982
 */
983
 
984
int WINAPI Wiz_Grep(LPSTR archive, LPSTR file, LPSTR pattern, int cmd,
985
                   int SkipBin, LPUSERFUNCTIONS lpUserFunctions)
986
{
987
    int retcode = FALSE, compare;
988
    ulg i, j, patternLen, buflen;
989
    char * sz, *p;
990
    UzpBuffer retstr;
991
 
992
    /* Turn off any windows printing functions, as they may not have been
993
     * identified yet. There is no requirement that we initialize the
994
     * dll with printing stuff for this. */
995
    Wiz_NoPrinting(TRUE);
996
 
997
    if (!Wiz_UnzipToMemory(archive, file, lpUserFunctions, &retstr)) {
998
       Wiz_NoPrinting(FALSE);
999
       return -1;   /* not enough memory, file not found, or other error */
1000
    }
1001
 
1002
    if (SkipBin) {
1003
        if (retstr.strlength < 100)
1004
            buflen = retstr.strlength;
1005
        else
1006
            buflen = 100;
1007
        for (i = 0; i < buflen; i++) {
1008
            if (iscntrl(retstr.strptr[i])) {
1009
                if ((retstr.strptr[i] != 0x0A) &&
1010
                    (retstr.strptr[i] != 0x0D) &&
1011
                    (retstr.strptr[i] != 0x09))
1012
                {
1013
                    /* OK, we now think we have a binary file of some sort */
1014
                    free(retstr.strptr);
1015
                    Wiz_NoPrinting(FALSE);
1016
                    return FALSE;
1017
                }
1018
            }
1019
        }
1020
    }
1021
 
1022
    patternLen = strlen(pattern);
1023
 
1024
    if (retstr.strlength < patternLen) {
1025
        free(retstr.strptr);
1026
        Wiz_NoPrinting(FALSE);
1027
        return FALSE;
1028
    }
1029
 
1030
    sz = malloc(patternLen + 3); /* add two in case doing whole words only */
1031
    if (cmd > 1) {
1032
        strcpy(sz, " ");
1033
        strcat(sz, pattern);
1034
        strcat(sz, " ");
1035
    } else
1036
        strcpy(sz, pattern);
1037
 
1038
    if ((cmd == 0) || (cmd == 2)) {
1039
        for (i = 0; i < strlen(sz); i++)
1040
            sz[i] = toupper(sz[i]);
1041
        for (i = 0; i < retstr.strlength; i++)
1042
            retstr.strptr[i] = toupper(retstr.strptr[i]);
1043
    }
1044
 
1045
    for (i = 0; i < (retstr.strlength - patternLen); i++) {
1046
        p = &retstr.strptr[i];
1047
        compare = TRUE;
1048
        for (j = 0; j < patternLen; j++) {
1049
            /* We cannot do strncmp here, as we may be dealing with a
1050
             * "binary" file, such as a word processing file, or perhaps
1051
             * even a true executable of some sort. */
1052
            if (p[j] != sz[j]) {
1053
                compare = FALSE;
1054
                break;
1055
            }
1056
        }
1057
        if (compare == TRUE) {
1058
            retcode = TRUE;
1059
            break;
1060
        }
1061
    }
1062
 
1063
    free(sz);
1064
    free(retstr.strptr);
1065
    Wiz_NoPrinting(FALSE); /* Turn printing back on */
1066
    return retcode;
1067
}
1068
#endif /* !__16BIT__ */
1069
 
1070
int WINAPI Wiz_Validate(LPSTR archive, int AllCodes)
1071
{
1072
    return UzpValidate((char *)archive, AllCodes);
1073
}
1074
 
1075
#endif /* !SFX */