The R Project SVN R

Rev

Blame | Last modification | View Log | Download | RSS feed

/*
 *  R : A Computer Language for Statistical Data Analysis
 *  file dounzip.c
 *  Copyright (C) 1998--1999  Guido Masarotto and Brian Ripley
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include "Defn.h"
/* From system.c */
void (*my_message)(char *s);

static int unzip_is_loaded = 0;
static int Load_Unzip_DLL();
static int do_unzip(char *zipname, char *dest, int nfiles, char **files,
            int nxfiles, char **xfiles, int over);

SEXP do_int_unzip(SEXP call, SEXP op, SEXP args, SEXP env)
{
    SEXP  fn, ans;
    char zipname[MAX_PATH], *topics[50], dest[MAX_PATH];
    int i, ntopics, rc;

    if (!isString(CAR(args)) || LENGTH(CAR(args)) != 1)
    errorcall(call, "invalid zip name argument\n");
    strcpy(zipname, CHAR(STRING(CAR(args))[0]));
    args = CDR(args);
    fn = CAR(args);
    ntopics = length(fn);
    if (!isString(fn) || ntopics < 1 || ntopics > 50)
    errorcall(call, "invalid topics argument\n");
    for(i = 0; i < ntopics; i++)
    topics[i] = CHAR(STRING(fn)[i]);
    args = CDR(args);
    if (!isString(CAR(args)) || LENGTH(CAR(args)) != 1)
    errorcall(call, "invalid destination argument\n");
    strcpy(dest, CHAR(STRING(CAR(args))[0]));
    rc = Load_Unzip_DLL();
    if (rc > 0) {
    rc = 10;
    } else {
    rc = do_unzip(zipname, dest, ntopics, topics, 0 , NULL, 1);
    }
    PROTECT(ans = allocVector(INTSXP, 1));
    INTEGER(ans)[0] = rc;
    UNPROTECT(1);
    return ans;    
}


#include <windows.h>
#include <string.h>
#include "graphapp/graphapp.h"
#include "unzip/structs.h"

#define UNZ_DLL_NAME "UNZIP32.DLL\0"
typedef int (WINAPI * _DLL_UNZIP)(int, char **, int, char **,
                                  LPDCL, LPUSERFUNCTIONS);
_DLL_UNZIP Wiz_SingleEntryUnzip;
HINSTANCE hUnzipDll;

static int Load_Unzip_DLL()
{
    char szFullPath[PATH_MAX];

    if (unzip_is_loaded) return !(unzip_is_loaded >0);
    strcpy(szFullPath, R_HomeDir());
    strcat(szFullPath, "\\unzip\\");
    strcat(szFullPath, UNZ_DLL_NAME);

    hUnzipDll = LoadLibrary(szFullPath);
    if (hUnzipDll != NULL) {
    (_DLL_UNZIP)Wiz_SingleEntryUnzip =
        (_DLL_UNZIP)GetProcAddress(hUnzipDll, "Wiz_SingleEntryUnzip");
    } else {
    unzip_is_loaded = -1;
    return 1;
    }
    return 0;
}

void UnLoad_Unzip_Dll()
{
    if (unzip_is_loaded) FreeLibrary(hUnzipDll);
}


LPUSERFUNCTIONS lpUserFunctions;
HANDLE hUF = (HANDLE) NULL;
LPDCL lpDCL = NULL;
HANDLE hDCL = (HANDLE) NULL;
HANDLE hZCL = (HANDLE) NULL;

static int WINAPI UnzDisplayBuf(LPSTR msg, unsigned long size)
{
    return size;
}

static void WINAPI
ReceiveDllMessage(unsigned long ucsize, unsigned long csiz,
    unsigned cfactor,
    unsigned mo, unsigned dy, unsigned yr, unsigned hh, unsigned mm,
    char c, LPSTR filename, LPSTR methbuf, unsigned long crc, char fCrypt)
{
}

static int WINAPI password(char *p, int n, const char *m, const char *name)
{
    return 1;
}

static int WINAPI ReplaceYes(char *filename) {return 1;}

static int WINAPI ReplaceNo(char *filename) {return 0;}

static int WINAPI UnzipCallBack(LPCSTR member, unsigned long size)
{
    if(peekevent()) doevent();
    return 0;
}

static int do_unzip(char *zipname, char *dest, int nfiles, char **files,
        int nxfiles, char **xfiles, int over)
{
    int retcode;

    hDCL = GlobalAlloc(GPTR, (DWORD) sizeof(DCL));
    if (!hDCL) return 1;
    lpDCL = (LPDCL) GlobalLock(hDCL);
    if (!lpDCL) { GlobalFree(hDCL); return 1; }

    hUF = GlobalAlloc( GPTR, (DWORD) sizeof(USERFUNCTIONS));
    if (!hUF) { GlobalUnlock(hDCL); GlobalFree(hDCL); return 1;}

    lpUserFunctions = (LPUSERFUNCTIONS) GlobalLock(hUF);
    if (!lpUserFunctions)
    {
    GlobalUnlock(hDCL); GlobalFree(hDCL); GlobalFree(hUF);
    return 1;
    }
    lpUserFunctions->password = password;
    lpUserFunctions->print = UnzDisplayBuf;
    lpUserFunctions->sound = NULL;
    if(over) lpUserFunctions->replace = ReplaceYes;
    else     lpUserFunctions->replace = ReplaceNo;
    lpUserFunctions->SendApplicationMessage = ReceiveDllMessage;
    lpUserFunctions->ServCallBk = UnzipCallBack;


    lpDCL->ncflag = 0; /* Write to stdout if true */
    lpDCL->fQuiet = 2; /* We want all messages.
              1 = fewer messages,
              2 = no messages */
    lpDCL->ntflag = 0; /* test zip file if true */
    lpDCL->nvflag = 0; /* give a verbose listing if true */
    lpDCL->nUflag = 0; /* Do not extract only newer */
    lpDCL->nzflag = 0; /* display a zip file comment if true */
    lpDCL->ndflag = 1; /* Recreate directories if true */
    lpDCL->noflag = over > 0; /* Over-write all files if true */
    lpDCL->naflag = 0; /* Do not convert CR to CRLF */
    lpDCL->lpszZipFN = zipname; /* The archive name */
    lpDCL->lpszExtractDir = dest; /* The directory to extract to. This is set
                     to NULL if you are extracting to the
                     current directory.
                  */
    retcode = Wiz_SingleEntryUnzip(nfiles, files, nxfiles, xfiles,
                      lpDCL, lpUserFunctions);
    if (hDCL) { GlobalUnlock(hDCL); GlobalFree(hDCL); }
    if (hUF) { GlobalUnlock(hUF); GlobalFree(hUF); }
    return 0;
}