git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/WX_2_2_BRANCH@7117 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
		
			
				
	
	
		
			887 lines
		
	
	
		
			33 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			887 lines
		
	
	
		
			33 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /**********************************************************************
 | |
| *   REXXAPI.C                                                         *
 | |
| *                                                                     *
 | |
| *   This program adds a ZIP engine directly to the REXX language.     *
 | |
| *   The functions are:                                                *
 | |
| *       UZDropFuncs         -- Makes all functions in this package    *
 | |
| *                              unknown to REXX.                       *
 | |
| *       UZLoadFuncs         -- Makes all functions in this package    *
 | |
| *                              known to REXX so REXX programs may     *
 | |
| *                              call them.                             *
 | |
| *       UZFileTree          -- Searches for files matching a given    *
 | |
| *                              filespec, including files in           *
 | |
| *                              subdirectories.                        *
 | |
| *       UZUnZip             -- Unzip command-line entry point.        *
 | |
| *                              This is functionally equivalent to     *
 | |
| *                              using Unzip as an external program.    *
 | |
| *       UZUnZipToVar            -- Unzip one file to a variable       *
 | |
| *       UZUnZipToStem       -- Unzip files to a variable array        *
 | |
| *       UZVer               -- Returns the Unzip version number       *
 | |
| *                                                                     *
 | |
| **********************************************************************/
 | |
| /* Include files */
 | |
| 
 | |
| #ifdef OS2DLL
 | |
| 
 | |
| #define  INCL_DOS
 | |
| #define  INCL_DOSMEMMGR
 | |
| #include <string.h>
 | |
| #include <stdlib.h>
 | |
| #include <stdio.h>
 | |
| #include <stdarg.h>
 | |
| 
 | |
| #define UNZIP_INTERNAL
 | |
| #include "../unzip.h"
 | |
| #include "../version.h"
 | |
| 
 | |
| 
 | |
| /*********************************************************************/
 | |
| /*  Various definitions used by various functions.                   */
 | |
| /*********************************************************************/
 | |
| 
 | |
| RexxFunctionHandler UZDropFuncs;
 | |
| RexxFunctionHandler UZLoadFuncs;
 | |
| RexxFunctionHandler UZFileTree;
 | |
| RexxFunctionHandler UZUnZip;
 | |
| RexxFunctionHandler UZUnZipToVar;
 | |
| RexxFunctionHandler UZUnZipToStem;
 | |
| RexxFunctionHandler UZVer;
 | |
| RexxFunctionHandler UZAPIVer;
 | |
| 
 | |
| 
 | |
| int SetOutputVar(__GPRO__ const char *name);
 | |
| int SetOutputVarStem(__GPRO__ const char *name);
 | |
| int SetOutputVarLength(__GPRO);
 | |
| int WriteToVariable(__GPRO__ const char *name, char *buffer, int len);
 | |
| int PrintToSubVariable(__GPRO__ int idx, const char *format,...);
 | |
| int PrintToVariable(__GPRO__ const char *name, const char *format,...);
 | |
| int _PrintToVariable(__GPRO__ const char *name, const char *format, va_list arg_ptr);
 | |
| int TextSetNext(__GPRO__ char *format, int len, int all);
 | |
| 
 | |
| #define EZRXSTRING(r,p)  {(r).strptr=(PCH)p;(r).strlength=(ULONG)strlen((r).strptr);}
 | |
| 
 | |
| 
 | |
| /*********************************************************************/
 | |
| /* RxFncTable                                                        */
 | |
| /*   Array of names of the UNZIPAPI functions.                       */
 | |
| /*   This list is used for registration and deregistration.          */
 | |
| /*********************************************************************/
 | |
| 
 | |
| static PSZ  RxFncTable[] =
 | |
|    {
 | |
|       "UZDropFuncs",
 | |
|       "UZLoadFuncs",
 | |
|       "UZFileSearch",
 | |
|       "UZFileTree",
 | |
|       "UZUnZip",
 | |
|       "UZUnZipToVar",
 | |
|       "UZUnZipToStem",
 | |
|       "UZVer",
 | |
|    };
 | |
| 
 | |
| /*********************************************************************/
 | |
| /* Numeric Error Return Strings                                      */
 | |
| /*********************************************************************/
 | |
| 
 | |
| #define  NO_UTIL_ERROR    "0"          /* No error whatsoever        */
 | |
| #define  ERROR_NOMEM      "2"          /* Insufficient memory        */
 | |
| 
 | |
| /*********************************************************************/
 | |
| /* Numeric Return calls                                              */
 | |
| /*********************************************************************/
 | |
| 
 | |
| #define  INVALID_ROUTINE 40            /* Raise Rexx error           */
 | |
| #define  VALID_ROUTINE    0            /* Successful completion      */
 | |
| 
 | |
| /*********************************************************************/
 | |
| /* Some useful macros                                                */
 | |
| /*********************************************************************/
 | |
| 
 | |
| #define BUILDRXSTRING(t, s) { \
 | |
|   strcpy((t)->strptr,(s));\
 | |
|   (t)->strlength = strlen((s)); \
 | |
| }
 | |
| 
 | |
| 
 | |
| /*********************************************************************/
 | |
| /****************  UNZIPAPI Supporting Functions  ********************/
 | |
| /****************  UNZIPAPI Supporting Functions  ********************/
 | |
| /****************  UNZIPAPI Supporting Functions  ********************/
 | |
| /*********************************************************************/
 | |
| 
 | |
| 
 | |
| int RexxReturn(__GPRO__ int nodefault, RXSTRING *retstr)
 | |
| {
 | |
|   int ret = G.os2.rexx_error;
 | |
|   if (G.filenotfound)
 | |
|     G.os2.rexx_mes = "file not found";
 | |
|   if (*G.os2.rexx_mes != '0') {
 | |
|     if (retstr->strlength > 255) {
 | |
|       DosFreeMem(retstr->strptr);
 | |
|       retstr->strptr = NULL;
 | |
|     }
 | |
|   } else if (nodefault)
 | |
|     goto noBuild;
 | |
|   BUILDRXSTRING(retstr, G.os2.rexx_mes);
 | |
|  noBuild:
 | |
|   DESTROYGLOBALS();
 | |
|   return ret;
 | |
| }
 | |
| 
 | |
| /* Get a variable from REXX, return 0 if OK */
 | |
| int GetVariable(__GPRO__ const char *name)
 | |
| {
 | |
|   G.os2.request.shvnext = NULL;
 | |
|   EZRXSTRING(G.os2.request.shvname, name);
 | |
|   G.os2.request.shvnamelen = G.os2.request.shvname.strlength;
 | |
|   G.os2.request.shvvalue.strptr = G.os2.buffer;
 | |
|   G.os2.request.shvvalue.strlength = IBUF_LEN;
 | |
|   G.os2.request.shvvaluelen = IBUF_LEN;
 | |
|   G.os2.request.shvcode = RXSHV_SYFET;
 | |
|   G.os2.request.shvret = 0;
 | |
|   switch (RexxVariablePool(&G.os2.request)) {
 | |
|   case RXSHV_MEMFL:
 | |
|     G.os2.rexx_mes = ERROR_NOMEM;
 | |
|     break;
 | |
|   case RXSHV_BADN:
 | |
|   case RXSHV_NEWV:
 | |
|     G.os2.request.shvvaluelen = 0;
 | |
|   case RXSHV_OK:
 | |
|     *(G.os2.buffer+G.os2.request.shvvaluelen) = 0;
 | |
|     return G.os2.request.shvvaluelen;
 | |
|   }
 | |
|   return 0;
 | |
| }
 | |
| 
 | |
| 
 | |
| /* Get REXX compound variable */
 | |
| /* Stem must exist in G.os2.getvar_buf w/ length in G.os2.getvar_len */
 | |
| int GetVariableIndex(__GPRO__ int index)
 | |
| {
 | |
|   sprintf(G.os2.getvar_buf+G.os2.getvar_len,"%d",index);
 | |
|   return GetVariable(__G__ G.os2.getvar_buf);
 | |
| }
 | |
| 
 | |
| 
 | |
| /* Transfer REXX array to standard C string array */
 | |
| /* Returns number of elements */
 | |
| /* User is responsible for calling KillStringArray */
 | |
| 
 | |
| int CompoundToStringArray(__GPRO__ char ***pointer, const char *name)
 | |
| {
 | |
|   int count;
 | |
|   int total;
 | |
|   char **trav;
 | |
| 
 | |
|   G.os2.getvar_len = strlen(name);
 | |
|   memcpy(G.os2.getvar_buf,name,G.os2.getvar_len+1);
 | |
|   if (*(G.os2.getvar_buf+G.os2.getvar_len-1) != '.')
 | |
|     *(G.os2.getvar_buf+G.os2.getvar_len++) = '.', *(G.os2.getvar_buf+G.os2.getvar_len) = 0;
 | |
| 
 | |
|   if (GetVariableIndex(__G__ 0))
 | |
|     return 0;
 | |
| 
 | |
|   total = atoi(G.os2.buffer);
 | |
|   *pointer = (char **)malloc((total+1)<<2);
 | |
|   trav = *pointer;
 | |
|   for (count = 1; count <= total; count++) {
 | |
|     GetVariableIndex(__G__ count);
 | |
|     trav[count-1] = (char *)malloc(strlen(G.os2.buffer)+1);
 | |
|     strcpy(trav[count-1],G.os2.buffer);
 | |
|   }
 | |
|   trav[count-1] = NULL;
 | |
|   return total;
 | |
| }
 | |
| 
 | |
| 
 | |
| /* Kill string array created by CompoundToStringArray */
 | |
| 
 | |
| void KillStringArray(char **pointer)
 | |
| {
 | |
|   char **trav=pointer;
 | |
|   while (*trav != NULL) {
 | |
|     free(*trav);
 | |
|     trav++;
 | |
|   }
 | |
|   free(pointer);
 | |
| }
 | |
| 
 | |
| 
 | |
| /*************************************************************************
 | |
| * Function:  UZDropFuncs                                                 *
 | |
| *                                                                        *
 | |
| * Syntax:    call UZDropFuncs                                            *
 | |
| *                                                                        *
 | |
| * Return:    NO_UTIL_ERROR - Successful.                                 *
 | |
| *************************************************************************/
 | |
| 
 | |
| ULONG UZDropFuncs(CHAR *name, ULONG numargs, RXSTRING args[],
 | |
|                   CHAR *queuename, RXSTRING *retstr)
 | |
| {
 | |
|   INT     entries;                     /* Num of entries             */
 | |
|   INT     j;                           /* Counter                    */
 | |
| 
 | |
|   if (numargs != 0)                    /* no arguments for this      */
 | |
|     return INVALID_ROUTINE;            /* raise an error             */
 | |
| 
 | |
|   retstr->strlength = 0;               /* return a null string result*/
 | |
| 
 | |
|   entries = sizeof(RxFncTable)/sizeof(PSZ);
 | |
| 
 | |
|   for (j = 0; j < entries; j++)
 | |
|     RexxDeregisterFunction(RxFncTable[j]);
 | |
| 
 | |
|   return VALID_ROUTINE;                /* no error on call           */
 | |
| }
 | |
| 
 | |
| 
 | |
| /*************************************************************************
 | |
| * Function:  UZFileTree                                                  *
 | |
| *                                                                        *
 | |
| * Syntax:    call UZFileTree zipfile, stem[, include-filespec]           *
 | |
| *                                [, exclude-filespec][, options]         *
 | |
| *                                                                        *
 | |
| * Params:    zipfile  - Name of zip file to search.                      *
 | |
| *            stem     - Name of stem var to store results in.            *
 | |
| *            include  - Filespec to search for (may include * and ?).    *
 | |
| *            exclude  - Filespec to exclude (may include * and ?).       *
 | |
| *            options  - Either of the following:                         *
 | |
| *                       'F' - Give file statistics.                      *
 | |
| *                          Length Date Time Name                         *
 | |
| *                       'Z' - Give zip statistics, too.                  *
 | |
| *                          Length Method Size Ratio Date Time CRC-32 Name*
 | |
| *                       Default is to return only filenames              *
 | |
| *                                                                        *
 | |
| * Return:    NO_UTIL_ERROR   - Successful.                               *
 | |
| *            ERROR_NOMEM     - Out of memory.                            *
 | |
| *************************************************************************/
 | |
| 
 | |
| ULONG UZFileTree(CHAR *name, ULONG numargs, RXSTRING args[],
 | |
|                  CHAR *queuename, RXSTRING *retstr)
 | |
| {
 | |
|                                        /* validate arguments         */
 | |
|   char *incname[2];
 | |
|   char *excname[2];
 | |
|   CONSTRUCTGLOBALS();
 | |
| 
 | |
|   if (numargs < 2 || numargs > 5 ||
 | |
|       !RXVALIDSTRING(args[0]) ||
 | |
|       !RXVALIDSTRING(args[1]) ||
 | |
|       args[0].strlength > 255) {
 | |
|     DESTROYGLOBALS();
 | |
|     return INVALID_ROUTINE;            /* Invalid call to routine    */
 | |
|   }
 | |
|                                        /* initialize data area       */
 | |
|   SetOutputVarStem(__G__ args[1].strptr);
 | |
|   G.wildzipfn = args[0].strptr;
 | |
|   G.process_all_files = TRUE;
 | |
| 
 | |
|   uO.lflag = 1;
 | |
|   uO.zipinfo_mode = TRUE;
 | |
|   uO.C_flag = 1;
 | |
|   G.extract_flag = FALSE;
 | |
|   uO.qflag = 2;
 | |
| 
 | |
|   if (numargs >= 3 &&                  /* check third option         */
 | |
|       !RXNULLSTRING(args[2]) &&
 | |
|       args[2].strlength > 0) {            /* a zero length string isn't */
 | |
|     if (!(G.filespecs = CompoundToStringArray(__G__ &G.pfnames,args[2].strptr))) {
 | |
|       G.pfnames = incname;
 | |
|       incname[0] = args[2].strptr;
 | |
|       incname[1] = NULL;
 | |
|       G.filespecs = 1;
 | |
|     }
 | |
|     G.process_all_files = FALSE;
 | |
|   }
 | |
| 
 | |
|   if (numargs >= 4 &&                  /* check third option         */
 | |
|       !RXNULLSTRING(args[3]) &&
 | |
|       args[3].strlength > 0) {            /* a zero length string isn't */
 | |
|     if (!(G.xfilespecs = CompoundToStringArray(__G__ &G.pxnames,args[3].strptr))) {
 | |
|       G.pxnames = excname;
 | |
|       excname[0] = args[3].strptr;
 | |
|       excname[1] = NULL;
 | |
|       G.xfilespecs = 1;
 | |
|     }
 | |
|     G.process_all_files = FALSE;
 | |
|   }
 | |
| 
 | |
|   if (numargs == 5 &&                  /* check third option         */
 | |
|       !RXNULLSTRING(args[4]) &&
 | |
|       args[4].strlength > 0) {            /* a zero length string isn't */
 | |
|     int first = *args[4].strptr & 0x5f;
 | |
| 
 | |
|     if (first == 'Z')
 | |
|       uO.vflag = 2, uO.lflag = 0, uO.zipinfo_mode = FALSE;
 | |
|     else if (first == 'F')
 | |
|       uO.vflag = 1, uO.lflag = 0, uO.zipinfo_mode = FALSE;
 | |
|   }
 | |
| 
 | |
|   process_zipfiles(__G);
 | |
|   SetOutputVarLength(__G);
 | |
|   if (G.filespecs > 0 && G.pfnames != incname)
 | |
|     KillStringArray(G.pfnames);
 | |
|   if (G.xfilespecs > 0 && G.pxnames != excname)
 | |
|     KillStringArray(G.pxnames);
 | |
|   return RexxReturn(__G__ 0,retstr);        /* no error on call           */
 | |
| }
 | |
| 
 | |
| 
 | |
| /*************************************************************************
 | |
| * Function:  UZUnZipToVar                                                *
 | |
| *                                                                        *
 | |
| * Syntax:    call UZUnZipToVar zipfile, filespec [, stem]                *
 | |
| *                                                                        *
 | |
| * Params:    zipfile  - Name of zip file to search.                      *
 | |
| *            filespec - File to extract                                  *
 | |
| *            stem     - If you specify a stem variable, the file will be *
 | |
| *                       extracted to the variable, one line per index    *
 | |
| *                       In this case, 0 will be returned                 *
 | |
| *                                                                        *
 | |
| * Return:    Extracted file                                              *
 | |
| *            ERROR_NOMEM     - Out of memory.                            *
 | |
| *************************************************************************/
 | |
| 
 | |
| ULONG UZUnZipToVar(CHAR *name, ULONG numargs, RXSTRING args[],
 | |
|                           CHAR *queuename, RXSTRING *retstr)
 | |
| {
 | |
|   CONSTRUCTGLOBALS();
 | |
|   UzpBuffer *ub = (UzpBuffer *)retstr;
 | |
|                                        /* validate arguments         */
 | |
|   if (numargs < 2 || numargs > 3 ||
 | |
|       !RXVALIDSTRING(args[0]) ||
 | |
|       !RXVALIDSTRING(args[1]) ||
 | |
|       args[0].strlength == 0 ||
 | |
|       args[1].strlength == 0) {
 | |
|     DESTROYGLOBALS();
 | |
|     return INVALID_ROUTINE;            /* Invalid call to routine    */
 | |
|   }
 | |
| 
 | |
|   uO.C_flag = 1;
 | |
|   G.redirect_data=1;
 | |
|   if (numargs == 3) {
 | |
|     if (!RXVALIDSTRING(args[2]) ||
 | |
|         RXNULLSTRING(args[1]) ||
 | |
|         args[2].strlength == 0) {
 | |
|       DESTROYGLOBALS();
 | |
|       return INVALID_ROUTINE;            /* Invalid call to routine    */
 | |
|     }
 | |
|     SetOutputVarStem(__G__ args[2].strptr);
 | |
|     G.redirect_text = 0;
 | |
|     G.redirect_data++;
 | |
|   }
 | |
|   unzipToMemory(__G__ args[0].strptr, args[1].strptr,
 | |
|                 G.redirect_data==1 ? ub : NULL);
 | |
|   return RexxReturn(__G__ G.redirect_data==1,retstr);
 | |
| }
 | |
| 
 | |
| 
 | |
| /*************************************************************************
 | |
| * Function:  UZUnZipToStem                                               *
 | |
| *                                                                        *
 | |
| * Syntax:    call UZUnZipToStem zipfile, stem[, include-filespec]        *
 | |
| *                                [, exclude-filespec][, mode]            *
 | |
| *                                                                        *
 | |
| * Params:    zipfile  - Name of zip file to search.                      *
 | |
| *            stem     - Name of stem var to store files in.              *
 | |
| *            include  - Filespec to search for (may include * and ?).    *
 | |
| *            exclude  - Filespec to exclude (may include * and ?).       *
 | |
| *            mode     - Specifies 'F'lat or 'T'ree mode.  Umm, this is   *
 | |
| *                        hard to explain so I'll give an example, too.   *
 | |
| *                       Assuming a file unzip.zip containing:            *
 | |
| *                               unzip.c                                  *
 | |
| *                               unshrink.c                               *
 | |
| *                               extract.c                                *
 | |
| *                               os2/makefile.os2                         *
 | |
| *                               os2/os2.c                                *
 | |
| *                               os2/dll/dll.def                          *
 | |
| *                               os2/dll/unzipapi.c                       *
 | |
| *                                                                        *
 | |
| *                       -- In flat mode, each file is stored in          *
 | |
| *                          stem.fullname i.e. stem."os2/dll/unzipapi.c"  *
 | |
| *                          A list of files is created in stem.<index>    *
 | |
| *                                                                        *
 | |
| *                       Flat mode returns:                               *
 | |
| *                               stem.0 = 7                               *
 | |
| *                               stem.1 = unzip.c                         *
 | |
| *                               stem.2 = unshrink.c                      *
 | |
| *                               stem.3 = extract.c                       *
 | |
| *                               stem.4 = os2/makefile.os2                *
 | |
| *                               stem.5 = os2/os2.c                       *
 | |
| *                               stem.6 = os2/dll/dll.def                 *
 | |
| *                               stem.7 = os2/dll/unzipapi.c              *
 | |
| *                                                                        *
 | |
| *                       And the following contain the contents of the    *
 | |
| *                       various programs:                                *
 | |
| *                               stem.unzip.c                             *
 | |
| *                               stem.unshrink.c                          *
 | |
| *                               stem.extract.c                           *
 | |
| *                               stem.os2/makefile.os2                    *
 | |
| *                               stem.os2/os2.c                           *
 | |
| *                               stem.os2/dll/dll.def                     *
 | |
| *                               stem.os2/dll/unzipapi.c                  *
 | |
| *                                                                        *
 | |
| *                       -- In tree mode, slashes are converted to periods*
 | |
| *                          in the pathname thus the above file would have*
 | |
| *                          been stored in stem.os2.dll.unzipapi.c        *
 | |
| *                          The index would then be stored in stem.OS2.   *
 | |
| *                          DLL.<index>.                                  *
 | |
| *                                                                        *
 | |
| *                       NOTE: All path names are converted to uppercase  *
 | |
| *                                                                        *
 | |
| *                       Tree mode returns:                               *
 | |
| *                               stem.0 = 4                               *
 | |
| *                               stem.1 = unzip.c                         *
 | |
| *                               stem.2 = unshrink.c                      *
 | |
| *                               stem.3 = extract.c                       *
 | |
| *                               stem.4 = OS2/                            *
 | |
| *                                                                        *
 | |
| *                               stem.OS2.0 = 3                           *
 | |
| *                               stem.OS2.1 = makefile.os2                *
 | |
| *                               stem.OS2.2 = os2.c                       *
 | |
| *                               stem.OS2.3 = DLL/                        *
 | |
| *                                                                        *
 | |
| *                               stem.OS2.DLL.0 = 2                       *
 | |
| *                               stem.OS2.DLL.1 = def                     *
 | |
| *                               stem.OS2.DLL.2 = unzipapi.c              *
 | |
| *                                                                        *
 | |
| *                       And the following contain the contents of the    *
 | |
| *                       various programs:                                *
 | |
| *                               stem.unzip.c                             *
 | |
| *                               stem.unshrink.c                          *
 | |
| *                               stem.extract.c                           *
 | |
| *                               stem.OS2.makefile.os2                    *
 | |
| *                               stem.OS2.os2.c                           *
 | |
| *                               stem.OS2.DLL.dll.def                     *
 | |
| *                               stem.OS2.DLL.unzipapi.c                  *
 | |
| *                                                                        *
 | |
| *                                                                        *
 | |
| * Return:    NO_UTIL_ERROR   - Successful.                               *
 | |
| *            ERROR_NOMEM     - Out of memory.                            *
 | |
| *************************************************************************/
 | |
| 
 | |
| ULONG UZUnZipToStem(CHAR *name, ULONG numargs, RXSTRING args[],
 | |
|                           CHAR *queuename, RXSTRING *retstr)
 | |
| {
 | |
|   char *incname[2];
 | |
|   char *excname[2];
 | |
|   CONSTRUCTGLOBALS();
 | |
|                                        /* validate arguments         */
 | |
|   if (numargs < 2 || numargs > 5 ||
 | |
|       !RXVALIDSTRING(args[0]) ||
 | |
|       !RXVALIDSTRING(args[1]) ||
 | |
|       args[0].strlength > 255) {
 | |
|     DESTROYGLOBALS();
 | |
|     return INVALID_ROUTINE;            /* Invalid call to routine    */
 | |
|   }
 | |
|                                        /* initialize data area       */
 | |
|   G.wildzipfn = args[0].strptr;
 | |
|   G.process_all_files = TRUE;
 | |
| 
 | |
|   uO.C_flag = 1;
 | |
|   G.extract_flag = TRUE;
 | |
|   SetOutputVarStem(__G__ args[1].strptr);
 | |
|   G.redirect_data = 3;
 | |
|   G.redirect_text = 0;
 | |
| 
 | |
|   if (numargs >= 3 &&                  /* check third option         */
 | |
|       !RXNULLSTRING(args[2]) &&
 | |
|       args[2].strlength > 0) {            /* a zero length string isn't */
 | |
|     if (!(G.filespecs = CompoundToStringArray(__G__ &G.pfnames,args[2].strptr))) {
 | |
|       G.pfnames = incname;
 | |
|       incname[0] = args[2].strptr;
 | |
|       incname[1] = NULL;
 | |
|       G.filespecs = 1;
 | |
|     }
 | |
|     G.process_all_files = FALSE;
 | |
|   }
 | |
| 
 | |
|   if (numargs >= 4 &&                  /* check third option         */
 | |
|       !RXNULLSTRING(args[3]) &&
 | |
|       args[3].strlength > 0) {            /* a zero length string isn't */
 | |
|     if (!(G.xfilespecs = CompoundToStringArray(__G__ &G.pxnames,args[3].strptr))) {
 | |
|       G.pxnames = excname;
 | |
|       excname[0] = args[3].strptr;
 | |
|       excname[1] = NULL;
 | |
|       G.xfilespecs = 1;
 | |
|     }
 | |
|     G.process_all_files = FALSE;
 | |
|   }
 | |
| 
 | |
|   if (numargs == 5 &&                  /* check third option         */
 | |
|       !RXNULLSTRING(args[4]) &&
 | |
|       (*args[4].strptr & 0x5f) == 'T') {
 | |
|     G.redirect_data++;
 | |
|     G.os2.request.shvnext = NULL;
 | |
|     EZRXSTRING(G.os2.request.shvname, args[4].strptr);
 | |
|     G.os2.request.shvnamelen = G.os2.request.shvname.strlength;
 | |
|     G.os2.request.shvcode = RXSHV_SYDRO;
 | |
|     G.os2.request.shvret = 0;
 | |
|     RexxVariablePool(&G.os2.request);
 | |
|   }
 | |
| 
 | |
| 
 | |
|   uO.qflag = 2;
 | |
| 
 | |
|   process_zipfiles(__G);
 | |
|   if (G.filespecs > 0 && G.pfnames != incname)
 | |
|     KillStringArray(G.pfnames);
 | |
|   if (G.xfilespecs > 0 && G.pxnames != excname)
 | |
|     KillStringArray(G.pxnames);
 | |
|   if (G.redirect_data == 3)
 | |
|     SetOutputVarLength(__G);
 | |
|   return RexxReturn(__G__ 0,retstr);            /* no error on call           */
 | |
| }
 | |
| 
 | |
| 
 | |
| /*************************************************************************
 | |
| * Function:  UZLoadFuncs                                                 *
 | |
| *                                                                        *
 | |
| * Syntax:    call UZLoadFuncs [option]                                   *
 | |
| *                                                                        *
 | |
| * Params:    none                                                        *
 | |
| *                                                                        *
 | |
| * Return:    null string                                                 *
 | |
| *************************************************************************/
 | |
| 
 | |
| ULONG UZLoadFuncs(CHAR *name, ULONG numargs, RXSTRING args[],
 | |
|                            CHAR *queuename, RXSTRING *retstr)
 | |
| {
 | |
|   INT    entries;                      /* Num of entries             */
 | |
|   INT    j;                            /* Counter                    */
 | |
| 
 | |
|   retstr->strlength = 0;               /* set return value           */
 | |
|                                        /* check arguments            */
 | |
|   if (numargs > 0)
 | |
|     return INVALID_ROUTINE;
 | |
| 
 | |
|   entries = sizeof(RxFncTable)/sizeof(PSZ);
 | |
| 
 | |
|   for (j = 0; j < entries; j++) {
 | |
|     RexxRegisterFunctionDll(RxFncTable[j],
 | |
|           "UNZIP32", RxFncTable[j]);
 | |
|   }
 | |
|   return VALID_ROUTINE;
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| /*************************************************************************
 | |
| * Function:  UZVer                                                       *
 | |
| *                                                                        *
 | |
| * Syntax:    call UZVer                                                  *
 | |
| *                                                                        *
 | |
| * Return:    Version of Unzip                                            *
 | |
| *************************************************************************/
 | |
| 
 | |
| ULONG UZVer(CHAR *name, ULONG numargs, RXSTRING args[],
 | |
|                         CHAR *queuename, RXSTRING *retstr)
 | |
| {
 | |
|   if (numargs > 1)                    /* validate arg count         */
 | |
|     return INVALID_ROUTINE;
 | |
| 
 | |
|   if (numargs == 0 || (*args[0].strptr & 0x5f) != 'L')
 | |
|     /* strcpy( retstr->strptr, UZ_VERNUM );    "5.13a BETA" */
 | |
|     sprintf( retstr->strptr, "%d.%d%d%s", UZ_MAJORVER, UZ_MINORVER,
 | |
|       PATCHLEVEL, BETALEVEL );
 | |
|   else
 | |
|     /* strcpy( retstr->strptr, UZ_VERSION );   UZ_VERNUM" of 26 Sep 94" */
 | |
|     sprintf( retstr->strptr, "%d.%d%d%s of %s", UZ_MAJORVER, UZ_MINORVER,
 | |
|       PATCHLEVEL, BETALEVEL, VERSION_DATE );
 | |
|   retstr->strlength = strlen(retstr->strptr);
 | |
|   return VALID_ROUTINE;
 | |
| }
 | |
| 
 | |
| 
 | |
| /*************************************************************************
 | |
| * Function:  UZUnZip                                                     *
 | |
| *                                                                        *
 | |
| * Syntax:    call UZUnZip                                                *
 | |
| *                                                                        *
 | |
| * Return:    Unzip return code                                           *
 | |
| *************************************************************************/
 | |
| 
 | |
| ULONG UZUnZip(CHAR *name, ULONG numargs, RXSTRING args[],
 | |
|                         CHAR *queuename, RXSTRING *retstr)
 | |
| {
 | |
|   char *argv[30];
 | |
|   char *scan;
 | |
|   int argc=0;
 | |
|   int idx;
 | |
|   CONSTRUCTGLOBALS();
 | |
| 
 | |
|   if (numargs < 1 || numargs > 2 ||
 | |
|       args[0].strlength > 255) {
 | |
|     DESTROYGLOBALS();
 | |
|     return INVALID_ROUTINE;            /* Invalid call to routine    */
 | |
|   }
 | |
|                                        /* initialize data area       */
 | |
|   if (numargs == 2)
 | |
|     SetOutputVarStem(__G__ args[1].strptr);
 | |
| 
 | |
|   scan = args[0].strptr;
 | |
|   argv[argc++] = "";         /* D:\\SOURCECODE\\UNZIP51S\\UNZIP.COM"; */
 | |
|   while (*scan == ' ')
 | |
|     scan++;
 | |
|   argv[argc++] = scan;
 | |
|   while ( (scan = strchr(scan,' ')) != NULL) {
 | |
|     *scan++ = 0;
 | |
|     while (*scan == ' ')
 | |
|       scan++;
 | |
|     argv[argc++] = scan;
 | |
|   }
 | |
|   if (*argv[argc-1] == 0)
 | |
|     argc--;
 | |
|   argv[argc] = 0;
 | |
| 
 | |
|          /* GRR:  should resetMainFlags() be called in here somewhere? */
 | |
| 
 | |
|   sprintf(retstr->strptr, "%d", unzip(__G__ argc, argv));   /* a.k.a. MAIN() */
 | |
|   if (numargs == 2)
 | |
|     SetOutputVarLength(__G);
 | |
|   retstr->strlength = strlen(retstr->strptr);
 | |
|   return RexxReturn(__G__ 1,retstr);
 | |
| }
 | |
| 
 | |
| int varmessage(__GPRO__ uch *buf, ulg size)
 | |
| {
 | |
|   if (size > 0)
 | |
|     memcpy(G.os2.buffer+G.os2.putchar_idx,buf,size);
 | |
|     G.os2.putchar_idx = TextSetNext(__G__ G.os2.buffer, size+G.os2.putchar_idx,0);
 | |
|   return 0;
 | |
| }
 | |
| 
 | |
| int varputchar(__GPRO__ int c)
 | |
| {
 | |
|   G.os2.buffer[G.os2.putchar_idx++] = c;
 | |
|   if (c == '\n') {
 | |
|     G.os2.buffer[G.os2.putchar_idx] = 0;
 | |
|     if (G.os2.output_var[0])
 | |
|       G.os2.putchar_idx = TextSetNext(__G__ G.os2.buffer, G.os2.putchar_idx,0);
 | |
|     else {
 | |
|       G.os2.buffer[--G.os2.putchar_idx] = 0;
 | |
|       puts(G.os2.buffer);
 | |
|       G.os2.putchar_idx = 0;
 | |
|     }
 | |
|   }
 | |
|   return 1;
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| int SetOutputVarStem(__GPRO__ const char *name)
 | |
| {
 | |
|   int len=strlen(name);
 | |
|   G.redirect_text=1;
 | |
|   G.os2.output_idx = 0;
 | |
|   strcpy(G.os2.output_var, name);
 | |
|   if (len) {
 | |
|     strupr(G.os2.output_var);                 /* uppercase the name         */
 | |
|     if (*(G.os2.output_var+len-1) != '.') {
 | |
|       *(G.os2.output_var+len) = '.';
 | |
|       len++;
 | |
|       *(G.os2.output_var+len) = 0;
 | |
|     }
 | |
|     WriteToVariable(__G__ G.os2.output_var,"",0);
 | |
|   }
 | |
|   G.os2.stem_len = len;
 | |
|   return G.os2.stem_len;
 | |
| }
 | |
| 
 | |
| int SetOutputVar(__GPRO__ const char *name)
 | |
| {
 | |
|   int len=strlen(name);
 | |
|   G.redirect_text=1;
 | |
|   G.os2.output_idx = 0;
 | |
|   strcpy(G.os2.output_var, name);
 | |
|   strupr(G.os2.output_var);                 /* uppercase the name         */
 | |
|   if (*(name+len-1) == '.')
 | |
|     G.os2.stem_len = len;
 | |
|   else
 | |
|     G.os2.stem_len = 0;
 | |
|   return G.os2.stem_len;
 | |
| }
 | |
| 
 | |
| int SetOutputVarLength(__GPRO)
 | |
| {
 | |
|   if (G.os2.stem_len > 0) {
 | |
|     if (G.os2.putchar_idx)
 | |
|       TextSetNext(__G__ G.os2.buffer,G.os2.putchar_idx,1);
 | |
|     return PrintToSubVariable(__G__ 0,"%d",G.os2.output_idx);
 | |
|   }
 | |
|   return 0;
 | |
| }
 | |
| 
 | |
| int PrintToVariable(__GPRO__ const char *name, const char *format,...)
 | |
| {
 | |
|   va_list arg_ptr;
 | |
|   int ret;
 | |
| 
 | |
|   va_start(arg_ptr, format);
 | |
|   ret = _PrintToVariable(__G__ name, format, arg_ptr);
 | |
|   va_end(arg_ptr);
 | |
|   return ret;
 | |
| }
 | |
| 
 | |
| int WriteToVariable(__GPRO__ const char *name, char *buffer, int len)
 | |
| {
 | |
|   G.os2.request.shvnext = NULL;
 | |
|   EZRXSTRING(G.os2.request.shvname, name);
 | |
|   G.os2.request.shvnamelen = G.os2.request.shvname.strlength;
 | |
|   G.os2.request.shvvalue.strptr = buffer;
 | |
|   G.os2.request.shvvalue.strlength = len;
 | |
|   G.os2.request.shvvaluelen = len;
 | |
|   G.os2.request.shvcode = RXSHV_SET;
 | |
|   G.os2.request.shvret = 0;
 | |
|   switch (RexxVariablePool(&G.os2.request)) {
 | |
|   case RXSHV_BADN:
 | |
|     G.os2.rexx_error = INVALID_ROUTINE;
 | |
|     break;
 | |
|   case RXSHV_MEMFL:
 | |
|     G.os2.rexx_mes = ERROR_NOMEM;
 | |
|     break;
 | |
|   case RXSHV_OK:
 | |
|     return 0;
 | |
|   }
 | |
|   return INVALID_ROUTINE;      /* error on non-zero          */
 | |
| }
 | |
| 
 | |
| int _PrintToVariable(__GPRO__ const char *name, const char *format, va_list arg_ptr)
 | |
| {
 | |
|   int ret = vsprintf(G.os2.buffer, format, arg_ptr);
 | |
|   WriteToVariable(__G__ name, G.os2.buffer, strlen(G.os2.buffer));
 | |
|   return ret;
 | |
| }
 | |
| 
 | |
| int PrintToSubVariable(__GPRO__ int idx, const char *format, ...)
 | |
| {
 | |
|   va_list arg_ptr;
 | |
|   int ret;
 | |
| 
 | |
|   if (G.os2.stem_len == 0)
 | |
|     return INVALID_ROUTINE;      /* error on non-zero          */
 | |
|   sprintf(G.os2.output_var+G.os2.stem_len,"%d",idx);
 | |
| 
 | |
|   va_start(arg_ptr, format);
 | |
|   ret = _PrintToVariable(__G__ G.os2.output_var, format, arg_ptr);
 | |
|   va_end(arg_ptr);
 | |
|   return ret;
 | |
| }
 | |
| 
 | |
| 
 | |
| int WriteToNextVariable(__GPRO__ char *buffer, int len)
 | |
| {
 | |
|   if (G.os2.stem_len > 0) {
 | |
|     G.os2.output_idx++;
 | |
|     sprintf(G.os2.output_var+G.os2.stem_len,"%d",G.os2.output_idx);
 | |
|   }
 | |
|   return WriteToVariable(__G__ G.os2.output_var, buffer, len);
 | |
| }
 | |
| 
 | |
| 
 | |
| int TextSetNext(__GPRO__ char *buffer, int len, int all)
 | |
| {
 | |
|   char *scan = buffer, *next, *base=buffer;
 | |
|   int remaining=len;
 | |
|   int ret;
 | |
| 
 | |
|   while ((next = strchr(scan,'\n')) != NULL && remaining > 0) {
 | |
|     if (next > scan && *(next-1) == 0xd)
 | |
|       *(next-1) = 0;
 | |
|     else
 | |
|       *next = 0;
 | |
|     if (WriteToNextVariable(__G__ scan,strlen(scan)))
 | |
|       return 0;
 | |
|     next++;
 | |
|     remaining -= (next-scan);
 | |
|     scan = next;
 | |
|   }
 | |
|   if (remaining > 0)
 | |
|     if (all) {
 | |
|       *(scan+remaining) = 0;
 | |
|       WriteToNextVariable(__G__ scan,remaining);
 | |
|     } else {
 | |
|       memcpy(buffer,scan,remaining);
 | |
|       return remaining;
 | |
|     }
 | |
| 
 | |
|   return 0;
 | |
| }
 | |
| 
 | |
| int finish_REXX_redirect(__GPRO)
 | |
| {
 | |
|   char *scan, *ptr;
 | |
|   int idx=0, first=1, offset;
 | |
| 
 | |
|   if (!G.redirect_size)
 | |
|     return 0;
 | |
|   switch(G.redirect_data) {
 | |
|   case 1:
 | |
|     break;
 | |
|   case 2:
 | |
|     TextSetNext(__G__ G.redirect_buffer, G.redirect_size, 1);
 | |
|     SetOutputVarLength(__G);
 | |
|     DosFreeMem(G.redirect_buffer);
 | |
|     G.redirect_buffer = NULL;
 | |
|     G.redirect_size = 0;
 | |
|     break;
 | |
|   case 3:
 | |
|     WriteToNextVariable(__G__ G.filename,strlen(G.filename));
 | |
|     sprintf(G.os2.output_var+G.os2.stem_len,G.filename);
 | |
|     WriteToVariable(__G__ G.os2.output_var, G.redirect_buffer, G.redirect_size);
 | |
|     DosFreeMem(G.redirect_buffer);
 | |
|     G.redirect_buffer = NULL;
 | |
|     G.redirect_size = 0;
 | |
|     break;
 | |
|   case 4:
 | |
|     if ((scan = strrchr(G.filename,'/')) != NULL) {
 | |
|       idx = *scan;
 | |
|       *scan = 0;
 | |
|       strupr(G.filename);
 | |
|       *scan = idx;
 | |
|     }
 | |
|     scan = G.os2.output_var+G.os2.stem_len;
 | |
|     strcpy(scan,G.filename);
 | |
|     while ((scan = strchr(scan,'/')) != NULL)
 | |
|       *scan = '.';
 | |
|     WriteToVariable(__G__ G.os2.output_var, G.redirect_buffer, G.redirect_size);
 | |
|     DosFreeMem(G.redirect_buffer);
 | |
|     G.redirect_buffer = NULL;
 | |
|     G.redirect_size = 0;
 | |
|     strcpy(G.os2.getvar_buf, G.os2.output_var);
 | |
|     do {
 | |
|       if ((scan = strrchr(G.filename,'/')) == NULL)
 | |
|         offset = 0;
 | |
|       else
 | |
|         offset = scan-G.filename+1;
 | |
|       if (first || !GetVariable(__G__ G.os2.output_var)) {
 | |
|         ptr = G.os2.getvar_buf+offset+G.os2.stem_len;
 | |
|         *ptr = '0';
 | |
|         *(ptr+1) = 0;
 | |
|         if (!GetVariable(__G__ G.os2.getvar_buf))
 | |
|           idx = 1;
 | |
|         else
 | |
|           idx = atoi(G.os2.buffer)+1;
 | |
|         PrintToVariable(__G__ G.os2.getvar_buf,"%d",idx);
 | |
|         sprintf(ptr,"%d",idx);
 | |
|         if (!first) {
 | |
|           PrintToVariable(__G__ G.os2.output_var,"%d",idx);
 | |
|           idx = strlen(G.filename);
 | |
|           *(G.filename+idx)   = '/';
 | |
|           *(G.filename+idx+1) = 0;
 | |
|         }
 | |
|         WriteToVariable(__G__ G.os2.getvar_buf,G.filename+offset,strlen(G.filename+offset));
 | |
|         first=0;
 | |
|       }
 | |
|       if (offset) {
 | |
|         *(G.os2.output_var+G.os2.stem_len+offset-1)   = 0;
 | |
|         *scan = 0;
 | |
|       }
 | |
|     } while (offset);
 | |
|     break;
 | |
|   }
 | |
|   return 0;
 | |
| }
 | |
| 
 | |
| #endif /* OS2DLL */
 |