home *** CD-ROM | disk | FTP | other *** search
- /**********************************************************************
- * REXXUTIL.C *
- * *
- * This program extends the REXX language by providing many *
- * REXX external functions. *
- * This sample program contains a subset of the functions *
- * provided in the version of REXXUTIL.DLL that is included in *
- * the base OS/2 product. *
- * These functions are: *
- * SysCls -- Clear the screen in an OS/2 fullscreen *
- * or windowed command prompt session. *
- * SysCurPos -- Set and/or Query the cursor position *
- * in an OS/2 fullscreen or windowed *
- * command prompt session. *
- * SysCurState -- Make the cursor visible or invisible *
- * in an OS/2 fullscreen or windowed *
- * command prompt session. *
- * SysDriveInfo -- Returns information about a specific *
- * drive. *
- * SysDriveMap -- Returns a list of the drives on the *
- * machine *
- * SysDropFuncs -- Makes all functions in this package *
- * unknown to REXX. *
- * SysFileDelete -- Deletes a file *
- * SysFileSearch -- Searches for a file matching a given *
- * filespec. *
- * SysFileTree -- Searches for files matching a given *
- * filespec, including files in *
- * subdirectories. *
- * SysGetMessage -- Retrieves a message text from an OS/2 *
- * message file, substituting values *
- * provided. *
- * SysIni -- Reads and/or updates entries in .INI *
- * files. *
- * SysLoadFuncs -- Makes all functions in this package *
- * known to REXX so REXX programs may *
- * call them. *
- * SysMkDir -- Creates a directory *
- * SysOS2Ver -- Returns the OS/2 Version number *
- * SysRmDir -- Removes a directory *
- * SysSearchPath -- Searches throught a specified path *
- * for a file. *
- * SysSleep -- Suspends execution for a number of *
- * seconds. *
- * SysTempFileName -- Creates a unique filename *
- * SysTextScreenRead -- Reads characters from the screen, *
- * in an OS/2 fullscreen or windowed *
- * command prompt session. *
- * SysTextScreenSize -- Returns the size of the window in *
- * rows and columns, *
- * in an OS/2 fullscreen or windowed *
- * command prompt session. *
- * SysGetEA -- Reads an extended attribute *
- * for a file. *
- * SysPutEA -- Writes an extended attribute *
- * for a file. *
- * SysWaitNamedPipe -- Wait on a named pipe. *
- * SysMakeNamedPipe -- Create a named pipe. *
- * SysConnectNamedPipe -- Prepare a named pipe for connection. *
- * SysDisConnectNamedPipe -- Release a pipe connection. *
- * *
- * To compile: MAKE REXXUTIL *
- * *
- **********************************************************************/
- /* Include files */
-
- #define INCL_WINSHELLDATA
- #define INCL_VIO
- #define INCL_DOS
- #define INCL_DOSFILEMGR
- #define INCL_DOSMEMMGR
- #define INCL_DOSMISC
- #define INCL_DONMPIPES
- #define INCL_ERRORS
- #define INCL_REXXSAA
- #define _DLL
- #define _MT
- #include <os2.h>
- #include <rexxsaa.h>
- #include <memory.h>
- #include <malloc.h>
- #include <fcntl.h>
- #include <ctype.h>
- #include <string.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <conio.h>
-
-
- #define DosSetFileMode Dos16SetFileMode
- APIRET APIENTRY DosSetFileMode(PSZ pszFName, USHORT usAttr, ULONG ulReserved);
-
- /*********************************************************************/
- /* Declare all exported functions as REXX functions. */
- /*********************************************************************/
- RexxFunctionHandler SysCls;
- RexxFunctionHandler SysCurPos;
- RexxFunctionHandler SysCurState;
- RexxFunctionHandler SysDriveInfo;
- RexxFunctionHandler SysDriveMap;
- RexxFunctionHandler SysDropFuncs;
- RexxFunctionHandler SysFileDelete;
- RexxFunctionHandler SysFileSearch;
- RexxFunctionHandler SysFileTree;
- RexxFunctionHandler SysGetMessage;
- RexxFunctionHandler SysIni;
- RexxFunctionHandler SysLoadFuncs;
- RexxFunctionHandler SysMkDir;
- RexxFunctionHandler SysOS2Ver;
- RexxFunctionHandler SysRmDir;
- RexxFunctionHandler SysSearchPath;
- RexxFunctionHandler SysSleep;
- RexxFunctionHandler SysTempFileName;
- RexxFunctionHandler SysTextScreenRead;
- RexxFunctionHandler SysTextScreenSize;
- RexxFunctionHandler SysGetEA;
- RexxFunctionHandler SysPutEA;
- RexxFunctionHandler SysWaitNamedPipe;
-
-
- /*********************************************************************/
- /* Various definitions used by various functions. */
- /*********************************************************************/
-
- #define MAX_DIGITS 9 /* maximum digits in numeric arg */
- #define MAX 256 /* temporary buffer length */
- #define IBUF_LEN 4096 /* Input buffer length */
- #define AllocFlag PAG_COMMIT | PAG_WRITE /* for DosAllocMem */
-
- /*********************************************************************/
- /* Defines used by SysDriveMap */
- /*********************************************************************/
-
- #define USED 0
- #define FREE 1
- #define DETACHED 2
- #define REMOTE 3
- #define LOCAL 4
-
- /*********************************************************************/
- /* Defines uses by SysTree */
- /*********************************************************************/
-
- #define FIRST_TIME 0x0001
- #define RECURSE 0x0002
- #define DO_DIRS 0x0004
- #define DO_FILES 0x0008
- #define NAME_ONLY 0x0010
- #define EDITABLE_TIME 0x0020
- #define IGNORE 2 /* Ignore attributes entirely */
- #define AllAtts FILE_NORMAL | FILE_READONLY | FILE_HIDDEN | \
- FILE_SYSTEM | FILE_DIRECTORY | FILE_ARCHIVED
-
- /*********************************************************************/
- /* Structures used throughout REXXUTIL.C */
- /*********************************************************************/
-
- /*********************************************************************/
- /* RxTree Structure used by SysTree. */
- /*********************************************************************/
-
- typedef struct RxTreeData {
- ULONG count; /* Number of lines processed */
-
- SHVBLOCK shvb; /* Request block for RxVar */
- ULONG open_action; /* Action taken opening the */
- /* file */
- ULONG stemlen; /* Length of stem */
- ULONG vlen; /* Length of variable value */
- CHAR TargetSpec[MAX]; /* Filespec RxTree is looking */
- /* for */
- CHAR truefile[MAX]; /* Used to hold actual file */
- /* name */
- CHAR tempfile[MAX]; /* Used to hold temp file name*/
- CHAR Temp[MAX]; /* Used when building stem */
- /* element */
- CHAR ibuf[IBUF_LEN]; /* Input buffer */
- CHAR varname[MAX]; /* Buffer for the variable */
- /* name */
- ULONG j; /* Temp counter */
- ULONG nattrib; /* New attrib, diff for each */
- /* file */
- } RXTREEDATA;
-
- /*********************************************************************/
- /* RxStemData */
- /* Structure which describes as generic */
- /* stem variable. */
- /*********************************************************************/
-
- typedef struct RxStemData {
- SHVBLOCK shvb; /* Request block for RxVar */
- CHAR ibuf[IBUF_LEN]; /* Input buffer */
- CHAR varname[MAX]; /* Buffer for the variable */
- /* name */
- CHAR stemname[MAX]; /* Buffer for the variable */
- /* name */
- ULONG stemlen; /* Length of stem. */
- ULONG vlen; /* Length of variable value */
- ULONG j; /* Temp counter */
- ULONG tlong; /* Temp counter */
- ULONG count; /* Number of elements */
- /* processed */
- } RXSTEMDATA;
-
- /*********************************************************************/
- /* RxFncTable */
- /* Array of names of the REXXUTIL functions. */
- /* This list is used for registration and deregistration. */
- /*********************************************************************/
-
- static PSZ RxFncTable[] =
- {
- "SysCls",
- "SysCurpos",
- "SysCurState",
- "SysDriveInfo",
- "SysDriveMap",
- "SysDropFuncs",
- "SysFileDelete",
- "SysFileSearch",
- "SysFileTree",
- "SysGetEA",
- "SysGetMessage",
- "SysIni",
- "SysLoadFuncs",
- "SysMkDir",
- "SysOS2Ver",
- "SysRmDir",
- "SysSearchPath",
- "SysSleep",
- "SysTempFileName",
- "SysTextScreenRead",
- "SysTextScreenSize",
- "SysGetEA",
- "SysPutEA",
- "SysWaitNamedPipe",
- };
-
- /*********************************************************************/
- /* Numeric Error Return Strings */
- /*********************************************************************/
-
- #define NO_UTIL_ERROR "0" /* No error whatsoever */
- #define ERROR_NOMEM "2" /* Insufficient memory */
- #define ERROR_FILEOPEN "3" /* Error opening text file */
-
- /*********************************************************************/
- /* Alpha Numeric Return Strings */
- /*********************************************************************/
-
- #define ERROR_RETSTR "ERROR:"
-
- /*********************************************************************/
- /* 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)); \
- }
-
-
- /*********************************************************************/
- /**************** REXXUTIL Supporting Functions ********************/
- /**************** REXXUTIL Supporting Functions ********************/
- /**************** REXXUTIL Supporting Functions ********************/
- /*********************************************************************/
-
- /********************************************************************
- * Function: string2long(string, number) *
- * *
- * Purpose: Validates and converts an ASCII-Z string from string *
- * form to an unsigned long. Returns FALSE if the number *
- * is not valid, TRUE if the number was successfully *
- * converted. *
- * *
- * RC: TRUE - Good number converted *
- * FALSE - Invalid number supplied. *
- *********************************************************************/
-
- BOOL string2long(PSZ string, LONG *number)
- {
- ULONG accumulator; /* converted number */
- INT length; /* length of number */
- INT sign; /* sign of number */
-
- sign = 1; /* set default sign */
- if (*string == '-') { /* negative?
- sign = -1; /* change sign */
- string++; /* step past sign */
- }
-
- length = strlen(string); /* get length of string */
- if (length == 0 || /* if null string */
- length > MAX_DIGITS) /* or too long */
- return FALSE; /* not valid */
-
- accumulator = 0; /* start with zero */
-
- while (length) { /* while more digits */
- if (!isdigit(*string)) /* not a digit? */
- return FALSE; /* tell caller */
- /* add to accumulator */
- accumulator = accumulator *10 + (*string - '0');
- length--; /* reduce length */
- string++; /* step pointer */
- }
- *number = accumulator * sign; /* return the value */
- return TRUE; /* good number */
- }
-
- /********************************************************************
- * Function: mystrstr(haystack, needle, hlen, nlen, sensitive) *
- * *
- * Purpose: Determines if the string 'needle' is in the *
- * string 'haystack' by returning it's position or *
- * a NULL if not found. The length of haystack and *
- * needle are given by 'hlen' and 'nlen' respectively. *
- * *
- * If 'sensitive' is true, then the search is case *
- * sensitive, else it is case insensitive. *
- * *
- * RC: num - The pos where needle was found. *
- * NULL - needle not found. *
- * *
- * Used By: SysFileSearch() *
- *********************************************************************/
-
- ULONG mystrstr(CHAR *haystack,CHAR *needle,ULONG hlen,ULONG nlen,
- BOOL sensitive)
-
- {
- CHAR line[MAX];
- CHAR target[MAX];
- ULONG p;
-
- /* Copy line - Change nulls to spaces and uppercase if needed */
-
- for (p = 0; p < hlen; p++) {
-
- if (haystack[p] == '\0')
- line[p] = ' ';
- else if (sensitive)
- line[p] = haystack[p];
- else line[p] = (CHAR)toupper(haystack[p]);
- }
- line[p] = '\0';
-
- /* Copy target - Change nulls to spaces and uppercase if needed */
-
- for (p = 0; p < nlen; p++) {
-
- if (needle[p] == '\0')
- target[p] = ' ';
- else if (sensitive)
- target[p] = needle[p];
- else target[p] = (CHAR)toupper(needle[p]);
- }
- target[p] = '\0';
-
- return ((ULONG)strstr(line, target));
- }
-
-
- /*****************************************************************
- * Function: getpath(string, path, filename) *
- * *
- * Purpose: This function gets the PATH and FILENAME of the file *
- * target contained in STRING. The path will end with *
- * the '\' char if a path is supplied. *
- * *
- * Used By: RecursiveFindFile() *
- **************************************************************** */
-
- VOID getpath(CHAR *string,CHAR *path,CHAR *filename)
- {
- int len;
- int LastSlashPos;
-
- len = strlen(string); /* Get length of full file */
- /* spec */
- LastSlashPos = len; /* Get max pos of last '\' */
-
- /* Step back through string until at begin or at '\' char */
-
- while (string[LastSlashPos] != '\\' && LastSlashPos >= 0)
- --LastSlashPos;
-
- /* Copy filespec up to and including last '\' to path */
- memcpy(path, string, LastSlashPos+1);
- path[LastSlashPos+1] = '\0';
-
- /* Get file name from filespec (just after last '\') */
- strcpy(filename, &string[LastSlashPos+1]);
-
- }
-
-
- /*********************************************************************/
- /* Function: ULONG SameAttr(mask, attr) */
- /* */
- /* Purpose: Returns the value TRUE if the attribute is identical to */
- /* that specified by the mask. If not the same, then */
- /* returns the value FALSE. */
- /* */
- /* Used By: RecursiveFindFile() */
- /*********************************************************************/
-
- ULONG SameAttr(INT *mask,ULONG attr)
- {
-
- if (mask[0] == IGNORE)
- return TRUE;
-
- if (mask[0] < 0 && attr&FILE_ARCHIVED)
- return FALSE;
-
- if (mask[0] > 0 && !(attr&FILE_ARCHIVED))
- return FALSE;
-
- if (mask[1] < 0 && attr&FILE_DIRECTORY)
- return FALSE;
-
- if (mask[1] > 0 && !(attr&FILE_DIRECTORY))
- return FALSE;
-
- if (mask[2] < 0 && attr&FILE_HIDDEN)
- return FALSE;
-
- if (mask[2] > 0 && !(attr&FILE_HIDDEN))
- return FALSE;
-
- if (mask[3] < 0 && attr&FILE_READONLY)
- return FALSE;
-
- if (mask[3] > 0 && !(attr&FILE_READONLY))
- return FALSE;
-
- if (mask[4] < 0 && attr&FILE_SYSTEM)
- return FALSE;
-
- if (mask[4] > 0 && !(attr&FILE_SYSTEM))
- return FALSE;
- return TRUE;
- }
-
-
- /*********************************************************************/
- /* Function: ULONG NewAttr(mask, attr) */
- /* */
- /* Purpose: Returns the new file attribute, given the mask of */
- /* attributes to be cleared/set and the current attribute */
- /* settings. */
- /* */
- /* Used By: RecursiveFindFile() */
- /*********************************************************************/
-
- ULONG NewAttr(INT *mask,ULONG attr)
- {
-
- if (mask[0] == IGNORE)
- return attr;
-
- if (mask[0] < 0)
- attr &= ~FILE_ARCHIVED; /* Clear */
-
- if (mask[0] > 0)
- attr |= FILE_ARCHIVED; /* Set */
-
- if (mask[1] < 0)
- attr &= ~FILE_DIRECTORY; /* Clear */
-
- if (mask[1] > 0)
- attr |= FILE_DIRECTORY; /* Set */
-
- if (mask[2] < 0)
- attr &= ~FILE_HIDDEN; /* Clear */
-
- if (mask[2] > 0)
- attr |= FILE_HIDDEN; /* Set */
-
- if (mask[3] < 0)
- attr &= ~FILE_READONLY; /* Clear */
-
- if (mask[3] > 0)
- attr |= FILE_READONLY; /* Set */
-
- if (mask[4] < 0)
- attr &= ~FILE_SYSTEM; /* Clear */
-
- if (mask[4] > 0)
- attr |= FILE_SYSTEM; /* Set */
- return attr;
- }
-
-
- /*****************************************************************************
- * Function: RecursiveFindFile( FileSpec, lpd, smask, dmask, options ) *
- * *
- * Purpose: Finds all files starting with FileSpec, and will look down the *
- * directory tree if required. *
- * *
- * Params: FileSpec - ASCIIZ string which designates filespec to search *
- * for. *
- * *
- * ldp - Pointer to local data structure. *
- * *
- * smask - Array of integers which describe the source attribute *
- * mask. Only files with attributes matching this mask *
- * will be found. *
- * *
- * dmask - Array of integers which describe the target attribute *
- * mask. Attributes of all found files will be set *
- * using this mask. *
- * *
- * Note: Both source and targets mask are really arrays of *
- * integers. Each index of the mask corresponds *
- * to a different file attribute. Each indexe and *
- * its associated attribute follows: *
- * *
- * mask[0] = FILE_ARCHIVED *
- * mask[1] = FILE_DIRECTORY *
- * mask[2] = FILE_HIDDEN *
- * mask[3] = FILE_READONLY *
- * mask[4] = FILE_SYSTEM *
- * *
- * A negative value at a given index indicates that *
- * the attribute bit of the file is not set. A positive *
- * number indicates that the attribute should be set. *
- * A value of 0 indicates a "Don't Care" setting. *
- * *
- * options - The search/output options. The following options *
- * may be ORed together when calling this function: *
- * *
- * FIRST_TIME - Indicates this is initial call. This *
- * should always be used. *
- * RECURSE - Indicates that function should search *
- * all child subdirectories recursively. *
- * DO_DIRS - Indicates that directories should be *
- * included in the search. *
- * DO_FILES - Indicates that files should be included *
- * in the search. *
- * NAME_ONLY - Indicates that the output should be *
- * restricted to filespecs only. *
- * EDITABLE_TIME - Indicates time and date fields should *
- * be output as one timestamp. *
- * *
- * Used By: SysFileTree() *
- *****************************************************************************/
-
- LONG RecursiveFindFile(FileSpec,ldp,smask,dmask,options)
- CHAR *FileSpec; /* Filespecs to search for */
- RXTREEDATA *ldp; /* Pointer to local data */
- INT *smask; /* Mask of attributes to */
- /* search for */
- INT dmask; /* Mask of attributes to set */
- ULONG options; /* Search and output format */
- /* options */
- {
- FILEFINDBUF3 finfo; /* OS2 File Find Utility */
- /* Structure */
- ULONG SearchCount = 1; /* Num things searching for */
- /* per DosFindFirst */
- HDIR DirHandle = 0xFFFF; /* Directory handle used by */
- /* DosFindFirst() */
- CHAR path[MAX]; /* Path to target file(s) */
- CHAR filename[MAX]; /* Current file name */
- BOOL IsaDotdir = FALSE; /* Boolean for determining if */
- /* file is ./.. */
- BOOL IsaSubdir = FALSE; /* Boolean for determining if */
- /* file is a dir */
-
- /********************************************************************
- * Search Strategy Explained: *
- * *
- * Get path and filespec to be searched. *
- * *
- * If this is the initial call (see FIRST_TIME) and *
- * searching recursively, make sure to look for the *
- * original filespec in the initial directory. *
- * *
- * From then on, look for a filespec of *.* to expand *
- * the subdirectories. Once a subdirectory is expanded, *
- * search for the initial filespec again. *
- ********************************************************************/
-
- getpath(FileSpec, path, filename);
-
- /********************************************************************
- * Initial Recursive case: *
- * *
- * This section of code recurses to call itself in the *
- * non-recursive form. It will allow the function to *
- * gather all the files in the initial subdirectory. *
- * *
- * It also saves the initial filespec to be searched *
- * for in all directories which will be expanded (see *
- * ldp->TargetSpec). From then on, the recursive case *
- * will search for directories by examining all files *
- * matching the spec *.*. *
- ********************************************************************/
-
- /* Onye executed first time */
- if ((options&FIRST_TIME) && (options&RECURSE)) {
- if (RecursiveFindFile(FileSpec, ldp, smask, dmask,
- options&~RECURSE&~FIRST_TIME))
- return INVALID_ROUTINE;
- strcpy(ldp->TargetSpec, filename);
- strcpy(filename, "*.*");
- sprintf(FileSpec, "%s*.*", path);
- options &= ~FIRST_TIME;
- }
-
- /********************************************************************
- * Non-Recursive case: *
- * *
- * This section of code finds all files matching the *
- * filespec (filtering out . and ..) and stores them *
- * in stem elements if they meet the appropriate file *
- * attribute requirements. Each found file's attributes *
- * are set as required if needed. *
- ********************************************************************/
-
- if (!(options&RECURSE)) {
-
- if (!DosFindFirst((PSZ)FileSpec, (PHDIR)&DirHandle, (ULONG)
- AllAtts, (PVOID)&finfo, (ULONG)sizeof(finfo), (PULONG)
- &SearchCount, FIL_STANDARD)) {
-
- IsaSubdir = (BOOL)(finfo.attrFile&FILE_DIRECTORY);
- IsaDotdir = (BOOL)(!strcmp(finfo.achName, ".") ||
- !strcmp(finfo.achName, ".."));
-
- if (!IsaDotdir && SameAttr(smask, finfo.attrFile) &&
- ((IsaSubdir && (options&DO_DIRS)) ||
- (!IsaSubdir && (options&DO_FILES)))) {
- sprintf(ldp->tempfile, "%s%s", path, finfo.achName);
- /* Get full path */
- DosQueryPathInfo(ldp->tempfile, 5, ldp->truefile,
- sizeof(ldp->truefile));
-
- if (options&NAME_ONLY)
- strcpy(ldp->Temp, ldp->truefile);
- else {
- if (options&EDITABLE_TIME)
- sprintf(ldp->Temp, "%02d/%02d/%02d/%02d/%02d %10lu ",
- (finfo.fdateLastWrite.year+80)%100,
- finfo.fdateLastWrite.month,
- finfo.fdateLastWrite.day,
- finfo.ftimeLastWrite.hours,
- finfo.ftimeLastWrite.minutes,
- finfo.cbFile);
- else
- sprintf(ldp->Temp, "%2d/%02d/%02d %2d:%02d%c %10lu ",
- finfo.fdateLastWrite.month,
- finfo.fdateLastWrite.day,
- (finfo.fdateLastWrite.year+80)%100,
- (finfo.ftimeLastWrite.hours < 13?
- finfo.ftimeLastWrite.hours:
- (finfo.ftimeLastWrite.hours-(SHORT)12)),
- finfo.ftimeLastWrite.minutes,
- ((finfo.ftimeLastWrite.hours < 12 ||
- finfo.ftimeLastWrite.hours == 24)?'a':'p'),
- finfo.cbFile);
- ldp->nattrib = NewAttr((INT *)dmask, finfo.attrFile);
-
- if (ldp->nattrib != finfo.attrFile) {
- sprintf(ldp->tempfile, "%s%s", path, finfo.achName);
-
- if (DosSetFileMode(ldp->tempfile, (USHORT)(ldp->nattrib&~
- FILE_DIRECTORY), 0L)) /* Set the new file mode */
- ldp->nattrib = finfo.attrFile;/* Just in case of */
- /* failure */
- }
- sprintf(ldp->Temp, "%s%c%c%c%c%c %s", ldp->Temp,
- ((ldp->nattrib&FILE_ARCHIVED)?'A':'-'),
- ((ldp->nattrib&FILE_DIRECTORY)?'D':'-'),
- ((ldp->nattrib&FILE_HIDDEN)?'H':'-'),
- ((ldp->nattrib&FILE_READONLY)?'R':'-'),
- ((ldp->nattrib&FILE_SYSTEM)?'S':'-'),
- ldp->truefile);
- }
- /* Place new string in Stem */
- memcpy(ldp->ibuf, ldp->Temp, strlen(ldp->Temp));
- ldp->vlen = strlen(ldp->Temp);
- ldp->count++;
- sprintf(ldp->varname+ldp->stemlen,"%d", ldp->count);
- ldp->shvb.shvnext = NULL;
- ldp->shvb.shvname.strptr = ldp->varname;
- ldp->shvb.shvname.strlength = strlen(ldp->varname);
- ldp->shvb.shvvalue.strptr = ldp->ibuf;
- ldp->shvb.shvvalue.strlength = ldp->vlen;
- ldp->shvb.shvnamelen = ldp->shvb.shvname.strlength;
- ldp->shvb.shvvaluelen = ldp->vlen;
- ldp->shvb.shvcode = RXSHV_SET;
- ldp->shvb.shvret = 0;
- if (RexxVariablePool(&ldp->shvb) == RXSHV_BADN)
- return INVALID_ROUTINE; /* error on non-zero */
- }
-
- /* Get the rest of the files ................................*/
-
- while (!DosFindNext((HDIR)DirHandle, (PVOID)&finfo,
- (ULONG)sizeof(finfo), (PULONG)&SearchCount)) {
-
- IsaSubdir = (BOOL)(finfo.attrFile&FILE_DIRECTORY);
- IsaDotdir = (BOOL)(!strcmp(finfo.achName, ".") ||
- !strcmp(finfo.achName, ".."));
-
- if (!IsaDotdir && SameAttr(smask, finfo.attrFile) &&
- ((IsaSubdir && (options&DO_DIRS)) ||
- (!IsaSubdir && (options&DO_FILES)))) {
- sprintf(ldp->tempfile, "%s%s", path, finfo.achName);
- /* Get full path */
- DosQueryPathInfo(ldp->tempfile, 5, ldp->truefile,
- sizeof(ldp->truefile));
-
- if (options&NAME_ONLY)
- strcpy(ldp->Temp, ldp->truefile);
-
- else {
- if (options&EDITABLE_TIME)
- sprintf(ldp->Temp, "%02d/%02d/%02d/%02d/%02d %10lu ",
- (finfo.fdateLastWrite.year+80)%100,
- finfo.fdateLastWrite.month,
- finfo.fdateLastWrite.day,
- finfo.ftimeLastWrite.hours,
- finfo.ftimeLastWrite.minutes, finfo.cbFile);
- else
- sprintf(ldp->Temp,
- "%2d/%02d/%02d %2d:%02d%c %10lu ",
- finfo.fdateLastWrite.month,
- finfo.fdateLastWrite.day,
- (finfo.fdateLastWrite.year+80)%100,
- (finfo.ftimeLastWrite.hours < 13?
- finfo.ftimeLastWrite.hours:
- (finfo.ftimeLastWrite.hours - (SHORT)12)),
- finfo.ftimeLastWrite.minutes,
- ((finfo.ftimeLastWrite.hours < 12 ||
- finfo.ftimeLastWrite.hours == 24)?'a':'p'),
- finfo.cbFile);
- ldp->nattrib = NewAttr((INT *)dmask, finfo.attrFile);
-
- if (ldp->nattrib != finfo.attrFile) {
- sprintf(ldp->tempfile, "%s%s", path, finfo.achName);
-
- if (DosSetFileMode(ldp->tempfile, (USHORT)(ldp->nattrib&~
- FILE_DIRECTORY), 0L))/* Set the new file mode */
- ldp->nattrib = finfo.attrFile;/* Just in case of */
- /* failure */
- }
- sprintf(ldp->Temp, "%s%c%c%c%c%c %s", ldp->Temp,
- ((ldp->nattrib&FILE_ARCHIVED)?'A':'-'),
- ((ldp->nattrib&FILE_DIRECTORY)?'D':'-'),
- ((ldp->nattrib&FILE_HIDDEN)?'H':'-'),
- ((ldp->nattrib&FILE_READONLY)?'R':'-'),
- ((ldp->nattrib&FILE_SYSTEM)?'S':'-'),
- ldp->truefile);
- }
- /* Place new string in Stem */
- memcpy(ldp->ibuf, ldp->Temp, strlen(ldp->Temp));
- ldp->vlen = strlen(ldp->Temp);
- ldp->count++;
- sprintf(ldp->varname+ldp->stemlen, "%d", ldp->count);
- ldp->shvb.shvnext = NULL;
- ldp->shvb.shvname.strptr = ldp->varname;
- ldp->shvb.shvname.strlength = strlen(ldp->varname);
- ldp->shvb.shvvalue.strptr = ldp->ibuf;
- ldp->shvb.shvvalue.strlength = ldp->vlen;
- ldp->shvb.shvnamelen = ldp->shvb.shvname.strlength;
- ldp->shvb.shvvaluelen = ldp->vlen;
- ldp->shvb.shvcode = RXSHV_SET;
- ldp->shvb.shvret = 0;
- if (RexxVariablePool(&ldp->shvb) == RXSHV_BADN)
- return INVALID_ROUTINE; /* error on non-zero */
-
- }
- }
- }
- DosFindClose(DirHandle);
- }
-
- /********************************************************
- * Recursive case: *
- * *
- * This section of code searches for directories given *
- * the current FileSpec. When one is found, the *
- * function is called in the non-recursive mode to find *
- * all files matching the initial filespec. It is also *
- * called in the recursive mode to expand all subdirect- *
- * ories under the new found directory. *
- *********************************************************/
-
- else {
-
- if (!DosFindFirst((PSZ)FileSpec, (PHDIR)&DirHandle,
- (ULONG)AllAtts, (PVOID)&finfo, (ULONG)sizeof(finfo),
- (PULONG)&SearchCount, FIL_STANDARD)) {
-
- IsaSubdir = (BOOL)(finfo.attrFile&FILE_DIRECTORY);
- IsaDotdir = (BOOL)(!strcmp(finfo.achName, ".") ||
- !strcmp(finfo.achName, ".."));
-
- if (!IsaDotdir && IsaSubdir) {
- sprintf(ldp->tempfile, "%s%s\\%s", path, finfo.achName,
- ldp->TargetSpec);
- if (RecursiveFindFile(ldp->tempfile, ldp, smask, dmask,
- options&~RECURSE))
- return INVALID_ROUTINE;
- sprintf(ldp->tempfile, "%s%s\\%s", path, finfo.achName,
- filename);
- if (RecursiveFindFile(ldp->tempfile, ldp, smask, dmask, options))
- return INVALID_ROUTINE;
- }
-
- /* Get the rest of the files ................................*/
-
- while (!DosFindNext((HDIR)DirHandle, (PVOID)&finfo,
- (ULONG)sizeof(finfo), (PULONG)&SearchCount)) {
-
- IsaSubdir = (BOOL)(finfo.attrFile&FILE_DIRECTORY);
- IsaDotdir = (BOOL)(!strcmp(finfo.achName, ".") ||
- !strcmp(finfo.achName, ".."));
-
- if (!IsaDotdir && IsaSubdir) {
- sprintf(ldp->tempfile, "%s%s\\%s", path, finfo.achName,
- ldp->TargetSpec);
- if (RecursiveFindFile(ldp->tempfile, ldp, smask, dmask,
- options&~RECURSE))
- return INVALID_ROUTINE;
- sprintf(ldp->tempfile, "%s%s\\%s", path, finfo.achName,
- filename);
- if (RecursiveFindFile(ldp->tempfile, ldp, smask, dmask,
- options))
- return INVALID_ROUTINE;
- }
- }
- }
- DosFindClose(DirHandle);
- }
- return VALID_ROUTINE;
- }
-
-
- /****************************************************************
- * Function: GetUniqueFileName(Template, Filler, file) *
- * *
- * Purpose: This function returns a unique temporary file name *
- * given a template and a filler character. *
- * *
- * Params: CHAR* Template - The template. Must contain at *
- * least one or more filler chars. *
- * *
- * Example: "C:\TEMP\FILE????.DAT *
- * *
- * CHAR Filler - The character in the Template to *
- * be replaced with numbers. For *
- * the above example, the filler char *
- * would be '?'. *
- * CHAR* file - file name produced (output) *
- * *
- * Used By: RxTempFileName() *
- ****************************************************************/
-
- VOID GetUniqueFileName(CHAR *Template,CHAR Filler,CHAR *file)
- {
- CHAR numstr[6];
- BOOL Unique = FALSE;
-
- ULONG rc, /* return code for OS/2 call */
- x, /* loop index */
- i, /* */
- j = 0, /* number of filler chars */
- /* found */
- num, /* temporary random number */
- start, /* first random number */
- max = 1; /* maximum random number */
-
- ULONG SearchCount; /* count of files to search */
- /* for. */
- HDIR DirHandle; /* handle for found file */
- INT seed; /* to get current time */
- FILEFINDBUF3 finfo; /* OS2 File Find Utility */
- /* Structure */
- DATETIME DT; /* The date and time structure*/
-
- /** Determine number of filler characters * */
-
- for (x = 0; Template[x] != 0; x++)
-
- if (Template[x] == Filler) {
- max = max *10;
- j++;
- }
-
- /** Return NULL string if less than 1 or greater than 4 * */
-
- if (j == 0 || j > 5) {
- Unique = TRUE;
- strcpy(file, "");
- }
-
- /** Get a random number in the appropriate range */
-
- DosGetDateTime((PDATETIME)&DT); /* Get the time */
- seed = DT.hours*60 + DT.minutes; /* convert to hundreths */
- seed = seed*60 + DT.seconds;
- seed = seed*100 + DT.hundredths;
- srand((INT)seed); /* Set random number seed */
- num = (ULONG)rand()%max;
- start = num;
-
- /** Do until a unique name is found */
-
- while (!Unique) {
-
- /** Generate string which represents the number */
-
- switch (j) {
- case 1 :
- sprintf(numstr, "%01u", num);
- break;
- case 2 :
- sprintf(numstr, "%02u", num);
- break;
- case 3 :
- sprintf(numstr, "%03u", num);
- break;
- case 4 :
- sprintf(numstr, "%04u", num);
- break;
- case 5 :
- sprintf(numstr, "%05u", num);
- break;
- }
-
- /** Subsitute filler characters with numeric string */
-
- i = 0;
-
- for (x = 0; Template[x] != 0; x++)
-
- if (Template[x] == Filler)
- file[x] = numstr[i++];
-
- else
- file[x] = Template[x];
- file[x] = '\0';
-
- /** See if the file exists */
-
- DosError(0); /* Disable Hard-Error popups */
- DirHandle = 0xFFFF;
- SearchCount = 1;
- rc = DosFindFirst(file, &DirHandle, AllAtts, (PVOID)&finfo,
- (ULONG)sizeof(finfo), (PULONG)&SearchCount, FIL_STANDARD);
-
- if (rc == 2 || rc == 18)
- Unique = TRUE;
- DosFindClose(DirHandle);
- DosError(1); /* Enable Hard-Error popups */
-
- /** Make sure we are not wasting our time */
-
- num = (num+1)%max;
-
- if (num == start && !Unique) {
- Unique = TRUE;
- strcpy(file, "");
- }
- }
- }
-
-
- /*************************************************************************
- *** <<<<<< REXXUTIL Functions Follow >>>>>>> ***
- *** <<<<<< REXXUTIL Functions Follow >>>>>>> ***
- *** <<<<<< REXXUTIL Functions Follow >>>>>>> ***
- *** <<<<<< REXXUTIL Functions Follow >>>>>>> ***
- *************************************************************************/
- /*************************************************************************
- * Function: SysCls *
- * *
- * Syntax: call SysCls *
- * *
- * Return: NO_UTIL_ERROR - Successful. *
- *************************************************************************/
-
- ULONG SysCls(CHAR *name, ULONG numargs, RXSTRING args[],
- CHAR *queuename, RXSTRING *retstr)
- {
- BYTE bCell[2]; /* Char/Attribute array */
-
- if (numargs) /* arguments specified? */
- return INVALID_ROUTINE; /* raise the error */
-
- bCell[0] = 0x20; /* Space Character */
- bCell[1] = 0x07; /* Default Attrib */
- VioScrollDn( 0, 0, (USHORT)0xFFFF, (USHORT)0XFFFF,
- (USHORT)0xFFFF, bCell, (HVIO) 0);/* CLS */
- VioSetCurPos(0, 0, (HVIO) 0); /* Pos cursor */
- BUILDRXSTRING(retstr, NO_UTIL_ERROR);/* pass back result */
- return VALID_ROUTINE; /* no error on call */
- }
-
- /*************************************************************************
- * Function: SysCurPos - positions cursor in OS/2 session *
- * *
- * Syntax: call SysCurPos [row, col] *
- * *
- * Params: row - row to place cursor on *
- * col - column to place cursor on *
- * *
- * Return: row, col *
- *************************************************************************/
-
- ULONG SysCurPos(CHAR *name, ULONG numargs, RXSTRING args[],
- CHAR *queuename, RXSTRING *retstr)
- {
- USHORT start_row; /* Row at start */
- USHORT start_col; /* Col at start */
- LONG new_row; /* Row to change to */
- LONG new_col; /* Col to change to */
-
- BUILDRXSTRING(retstr, NO_UTIL_ERROR);/* set default result */
- /* check arguments */
- if ((numargs != 0 && numargs != 2)) /* wrong number? */
- return INVALID_ROUTINE; /* raise an error */
-
- VioGetCurPos(&start_row, &start_col, (HVIO) 0); /* get position */
- sprintf(retstr->strptr, "%d %d", (int)start_row, (int)start_col);
- retstr->strlength = strlen(retstr->strptr);
-
- if (numargs != 0) { /* reset position to given */
- if (!RXVALIDSTRING(args[0]) || /* not real arguments given? */
- !RXVALIDSTRING(args[1]))
- return INVALID_ROUTINE; /* raise an error */
- /* convert row to binary */
- if (!string2long(args[0].strptr, &new_row) || new_row < 0)
- return INVALID_ROUTINE; /* return error */
- /* convert row to binary */
- if (!string2long(args[1].strptr, &new_col) || new_col < 0)
- return INVALID_ROUTINE; /* return error */
-
- /* Set the cursor position, using the input values. */
- VioSetCurPos((USHORT) new_row, (USHORT) new_col, (HVIO) 0);
- }
-
- return VALID_ROUTINE; /* no error on call */
- }
-
- /*************************************************************************
- * Function: SysCurState *
- * *
- * Syntax: call SysCurState state *
- * *
- * Params: state - Either 'ON' or 'OFF'. *
- * *
- * Return: NO_UTIL_ERROR - Successful. *
- *************************************************************************/
-
- ULONG SysCurState(CHAR *name, ULONG numargs, RXSTRING args[],
- CHAR *queuename, RXSTRING *retstr)
- {
- USHORT state; /* State */
- VIOCURSORINFO vioci; /* Cursor info struct */
-
- BUILDRXSTRING(retstr, NO_UTIL_ERROR);/* pass back result */
- /* validate the arguments */
- if (numargs != 1)
- return INVALID_ROUTINE;
- /* Get state and validate */
- if (stricmp(args[0].strptr, "ON") == 0)
- state = (USHORT) 0;
- else if (stricmp(args[0].strptr, "OFF") == 0)
- state = (USHORT) -1;
- else
- return INVALID_ROUTINE; /* Invalid state */
-
- VioGetCurType(&vioci, (HVIO) 0); /* Get current state */
- vioci.attr= state; /* Set state info */
- VioSetCurType(&vioci, (HVIO) 0); /* Set new state */
- return VALID_ROUTINE; /* no error on call */
- }
-
- /*************************************************************************
- * Function: SysDriveInfo *
- * *
- * Syntax: call SysDriveInfo drive *
- * *
- * Params: drive - 'C', 'D', 'E', etc. *
- * *
- * Return: disk free total label *
- *************************************************************************/
-
- ULONG SysDriveInfo(CHAR *name, ULONG numargs, RXSTRING args[],
- CHAR *queuename, RXSTRING *retstr)
- {
- PSZ arg; /* Temp var for holding args */
- UCHAR buf[256]; /* Give DosQFSInfo 256 bytes */
-
- ULONG drivenum; /* Drive number (A=1, B=2, */
- /* etc) */
- FSALLOCATE FSInfoBuf; /* Structure required by */
- /* DosQfsInfo */
- LONG rc; /* OS/2 return code */
-
- /* validate arguments */
- if (numargs != 1 ||
- args[0].strlength > 2 ||
- args[0].strlength == 0)
- return INVALID_ROUTINE;
- /* validate the arg */
- arg = args[0].strptr; /* get argument pointer */
- /* drive letter? */
- if ((strlen(arg) == 2 &&
- arg[1] != ':') ||
- !isalpha(arg[0]))
- return INVALID_ROUTINE;
- else /* yep, convert to a number */
- drivenum = toupper(arg[0])-'A'+1; /* Get the drive number */
-
- /* query the disk */
- DosError(0); /* Disable hard-error pop-up */
- /* Get the drive info */
- rc = DosQueryFSInfo(drivenum, 2, buf, sizeof(buf));
- DosQueryFSInfo(drivenum, 1, (char *)&FSInfoBuf, sizeof(FSInfoBuf));
-
- if (rc == 0 || rc == 125) {
- sprintf(retstr->strptr,
- "%c: %-12lu %-12lu %-13s",
- (drivenum+'A'-1),
- FSInfoBuf.cSectorUnit * FSInfoBuf.cbSector *
- FSInfoBuf.cUnitAvail,
- FSInfoBuf.cSectorUnit * FSInfoBuf.cbSector *
- FSInfoBuf.cUnit, &buf[5]);
- /* create return string */
- retstr->strlength = strlen(retstr->strptr);
- }
- else
- retstr->strlength = 0; /* return null string */
-
- DosError(1); /* Enable hard-error pop-up */
- return VALID_ROUTINE; /* no error on call */
-
- }
-
- /*************************************************************************
- * Function: SysDriveMap *
- * *
- * Syntax: call SysDriveMap [drive] [,mode] *
- * *
- * Params: drive - 'C', 'D', 'E', etc. The drive to start the search *
- * with. *
- * mode - Any of the following: 'FREE', 'USED', 'DETACHED', *
- * 'LOCAL', 'REMOTE' *
- * *
- * Return: 'A: B: C: D: ...' *
- *************************************************************************/
-
- ULONG SysDriveMap(CHAR *name, ULONG numargs, RXSTRING args[],
- CHAR *queuename, RXSTRING *retstr)
- {
- CHAR temp[MAX]; /* Entire drive map built here*/
-
- CHAR tmpstr[MAX]; /* Single drive entries built */
- /* here */
- CHAR buf[256]; /* Give DosQFSInfo 256 bytes */
- CHAR DeviceName[3]; /* Device name or drive letter*/
- /* string */
- ULONG CurDrive; /* Current drive */
- ULONG DriveMap; /* Drive map */
- ULONG Ordinal; /* Ordinal of entry in name */
- /* list */
- ULONG FSAInfoLevel; /* Type of attached FSD data */
- /* required */
- ULONG DataBufferLen; /* Buffer length */
- ULONG dnum; /* Disk num variable */
- ULONG start = 3; /* Initial disk num */
- ULONG Mode = USED; /* Query mode USED, FREE, */
- /* LOCAL, etc */
- FSQBUFFER2 DataBuffer; /* Returned data buffer */
- LONG rc; /* OS/2 return codes */
-
- Ordinal = (ULONG )0;
- FSAInfoLevel = (ULONG )1;
-
- temp[0] = '\0';
-
- if (numargs > 2) /* validate arguments */
- return INVALID_ROUTINE;
- /* check starting drive letter*/
- if (numargs >= 1 && args[0].strptr) {
-
- if ((strlen(args[0].strptr) == 2 &&
- args[0].strptr[1] != ':') ||
- strlen(args[0].strptr) > 2 ||
- strlen(args[0].strptr) == 0 ||
- !isalpha(args[0].strptr[0]))
- return INVALID_ROUTINE;
- start = toupper(args[0].strptr[0])-'A'+1;
- }
- /* check the mode */
- if (numargs == 2 && args[1].strlength != 0) {
-
- if (!stricmp(args[1].strptr, "FREE"))
- Mode = FREE;
- else if (!stricmp(args[1].strptr, "USED"))
- Mode = USED;
- else if (!stricmp(args[1].strptr, "DETACHED"))
- Mode = DETACHED;
- else if (!stricmp(args[1].strptr, "REMOTE"))
- Mode = REMOTE;
- else if (!stricmp(args[1].strptr, "LOCAL"))
- Mode = LOCAL;
- else
- return INVALID_ROUTINE;
- }
- /* perform the query */
- DosError(0); /* Disable Hard-Error Popups */
- DosQueryCurrentDisk(&CurDrive, &DriveMap);
- DriveMap>>=start-1; /* Shift to the first drive */
- temp[0] = '\0'; /* Clear temporary buffer */
-
- for (dnum = start; dnum <= 26; dnum++) {
-
- /* Hey, we have a free drive */
- if (!(DriveMap&(ULONG)1) && Mode == FREE) {
- sprintf(tmpstr, "%c: ", dnum+'A'-1);
- strcat(temp, tmpstr);
- }
- /* Hey, we have a used drive */
- else if ((DriveMap&(ULONG)1) && Mode == USED) {
- sprintf(tmpstr, "%c: ", dnum+'A'-1);
- strcat(temp, tmpstr);
- }
-
- else if (DriveMap&(ULONG)1) { /* Check specific drive info */
- sprintf(DeviceName, "%c:", dnum+'A'-1);
- DataBufferLen = sizeof DataBuffer;
- DosQueryFSAttach(DeviceName, Ordinal, FSAInfoLevel,
- &DataBuffer, &DataBufferLen);
- rc = DosQueryFSInfo(dnum, 2, buf, sizeof(buf));
-
- if (rc == 67 && DataBuffer.iType == 4 && Mode == DETACHED) {
- /* Hey, we have a detached */
- /* drive */
- sprintf(tmpstr, "%c: ", dnum+'A'-1);
- strcat(temp, tmpstr);
- }
-
- else if (DataBuffer.iType == 4 && Mode == REMOTE) {
- sprintf(tmpstr, "%c: ", dnum+'A'-1);
- strcat(temp, tmpstr);
- }
-
- else if (DataBuffer.iType == 3 && Mode == LOCAL) {
- sprintf(tmpstr, "%c: ", dnum+'A'-1);
- strcat(temp, tmpstr);
- }
- }
- DriveMap>>=1; /* Shift to the next drive */
- }
-
- BUILDRXSTRING(retstr, temp); /* pass back result */
- if (retstr->strlength) /* if not a null string */
- retstr->strlength--; /* Get rid of last space */
- DosError(1); /* Enable Hard-Error Popups */
- return VALID_ROUTINE; /* no error on call */
- }
-
-
- /*************************************************************************
- * Function: SysDropFuncs *
- * *
- * Syntax: call SysDropFuncs *
- * *
- * Return: NO_UTIL_ERROR - Successful. *
- *************************************************************************/
-
- ULONG SysDropFuncs(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: SysFileDelete *
- * *
- * Syntax: call SysFileDelete file *
- * *
- * Params: file - file to be deleted. *
- * *
- * Return: Return code from DosDelete() function. *
- *************************************************************************/
-
- ULONG SysFileDelete(CHAR *name, ULONG numargs, RXSTRING args[],
- CHAR *queuename, RXSTRING *retstr)
- {
- ULONG rc; /* Ret code */
-
- if (numargs != 1) /* we need one argument */
- return INVALID_ROUTINE; /* raise an error */
-
- rc = DosDelete(args[0].strptr); /* delete the file */
- /* pass back return code */
- sprintf(retstr->strptr, "%d", rc);
- retstr->strlength = strlen(retstr->strptr);
-
- return VALID_ROUTINE; /* finished */
- }
-
- /*************************************************************************
- * Function: SysFileSearch *
- * *
- * Syntax: call SysFileSearch target, file, stem [, options] *
- * *
- * Params: target - String to search for. *
- * file - Filespec to search. *
- * stem - Stem variable name to place results in. *
- * options - Any combo of the following: *
- * 'C' - Case sensitive search (non-default). *
- * 'N' - Preceed each found string in result stem *
- * with it line number in file (non-default).*
- * *
- * Return: NO_UTIL_ERROR - Successful. *
- * ERROR_NOMEM - Out of memory. *
- *************************************************************************/
-
- ULONG SysFileSearch(CHAR *name, ULONG numargs, RXSTRING args[],
- CHAR *queuename, RXSTRING *retstr)
- {
- PSZ target; /* search string */
- PSZ file; /* search file */
- PSZ opts; /* option string */
- CHAR line[MAX]; /* Line read from file */
- ULONG ptr; /* Pointer to char str found */
- ULONG num = 0; /* Line number */
- ULONG len; /* Length of string */
- ULONG len2; /* Length of string */
- ULONG rc = 0; /* Return code of this func */
- BOOL linenums = FALSE; /* Set TRUE for linenums in */
- /* output */
- BOOL sensitive = FALSE; /* Set TRUE for case-sens */
- /* search */
- FILE *fp; /* Pointer to file to search */
- RXSTEMDATA ldp; /* stem data */
-
- BUILDRXSTRING(retstr, NO_UTIL_ERROR);/* pass back result */
- /* validate arguments */
- if (numargs < 3 || numargs > 4 ||
- !RXVALIDSTRING(args[0]) ||
- !RXVALIDSTRING(args[1]) ||
- !RXVALIDSTRING(args[2]))
- return INVALID_ROUTINE; /* raise an error */
-
- target = args[0].strptr; /* get target pointer */
- file = args[1].strptr; /* get file name */
-
- if (numargs == 4) { /* process options */
- opts = args[3].strptr; /* point to the options */
- if (strstr(opts, "N") || strstr(opts, "n"))
- linenums = TRUE;
-
- if (strstr(opts, "C") || strstr(opts, "c"))
- sensitive = TRUE;
- }
-
- /* Initialize data area */
- ldp.count = 0;
- strcpy(ldp.varname, args[2].strptr);
- ldp.stemlen = args[2].strlength;
- strupr(ldp.varname); /* uppercase the name */
-
- if (ldp.varname[ldp.stemlen-1] != '.')
- ldp.varname[ldp.stemlen++] = '.';
-
- fp = fopen(file, "r"); /* Open the file */
-
- if (fp == NULL) { /* Open error? */
- BUILDRXSTRING(retstr, ERROR_FILEOPEN);
- return VALID_ROUTINE; /* finished */
- }
- /* do the search...found lines*/
- /* are saved in stem vars */
- while (fgets(line, MAX - 1, fp) != NULL) {
- len = strlen(line);
- num++;
- ptr = mystrstr(line, target, len, args[0].strlength, sensitive);
-
- if (ptr != '\0') {
-
- if (linenums) {
- sprintf(ldp.ibuf, "%d ", num);
- len2 = strlen(ldp.ibuf);
- memcpy(ldp.ibuf+len2, line, len);
- ldp.vlen = len+len2;
- }
- else {
- memcpy(ldp.ibuf, line, len);
- ldp.vlen = len;
- }
- ldp.count++;
- sprintf(ldp.varname+ldp.stemlen, "%d", ldp.count);
-
- if (ldp.ibuf[ldp.vlen-1] == '\n')
- ldp.vlen--;
- ldp.shvb.shvnext = NULL;
- ldp.shvb.shvname.strptr = ldp.varname;
- ldp.shvb.shvname.strlength = strlen(ldp.varname);
- ldp.shvb.shvnamelen = ldp.shvb.shvname.strlength;
- ldp.shvb.shvvalue.strptr = ldp.ibuf;
- ldp.shvb.shvvalue.strlength = ldp.vlen;
- ldp.shvb.shvvaluelen = ldp.vlen;
- ldp.shvb.shvcode = RXSHV_SET;
- ldp.shvb.shvret = 0;
- if (RexxVariablePool(&ldp.shvb) == RXSHV_BADN)
- return INVALID_ROUTINE; /* error on non-zero */
- }
- }
-
- fclose(fp); /* Close that file */
- /* set stem.0 to lines read */
- sprintf(ldp.ibuf, "%d", ldp.count);
- ldp.varname[ldp.stemlen] = '0';
- ldp.varname[ldp.stemlen+1] = 0;
- ldp.shvb.shvnext = NULL;
- ldp.shvb.shvname.strptr = ldp.varname;
- ldp.shvb.shvname.strlength = ldp.stemlen+1;
- ldp.shvb.shvnamelen = ldp.stemlen+1;
- ldp.shvb.shvvalue.strptr = ldp.ibuf;
- ldp.shvb.shvvalue.strlength = strlen(ldp.ibuf);
- ldp.shvb.shvvaluelen = ldp.shvb.shvvalue.strlength;
- ldp.shvb.shvcode = RXSHV_SET;
- ldp.shvb.shvret = 0;
- if (RexxVariablePool(&ldp.shvb) == RXSHV_BADN)
- return INVALID_ROUTINE; /* error on non-zero */
-
- return VALID_ROUTINE; /* no error on call */
- }
-
- /*************************************************************************
- * Function: SysFileTree *
- * *
- * Syntax: call SysFileTree filespec, stem [, options] *
- * *
- * Params: filespec - Filespec to search for (may include * and ?). *
- * stem - Name of stem var to store results in. *
- * options - Any combo of the following: *
- * 'B' - Search for files and directories. *
- * 'D' - Search for directories only. *
- * 'F' - Search for files only. *
- * 'O' - Only output file names. *
- * 'S' - Recursively scan subdirectories. *
- * 'T' - Combine time & date fields into one. *
- * *
- * Return: NO_UTIL_ERROR - Successful. *
- * ERROR_NOMEM - Out of memory. *
- *************************************************************************/
-
- ULONG SysFileTree(CHAR *name, ULONG numargs, RXSTRING args[],
- CHAR *queuename, RXSTRING *retstr)
- {
- CHAR FileSpec[MAX]; /* File spec to look for */
-
- CHAR Opts[64]; /* Search options */
- ULONG options; /* Mask of options */
- ULONG x; /* Temp counter */
- ULONG y; /* Temp counter (II) */
- INT smask[5]; /* Source attribute mask */
- INT dmask[5]; /* Target attribute mask */
- RXTREEDATA ldp; /* local data */
-
- options = FIRST_TIME|DO_FILES|DO_DIRS;/* Clear if we should not */
- /* display files */
- smask[0] = IGNORE; /* No mask unless specified */
- dmask[0] = IGNORE; /* No mask unless specified */
- BUILDRXSTRING(retstr, NO_UTIL_ERROR);/* pass back result */
-
- /* validate arguments */
- if (numargs < 2 || numargs > 5 ||
- !RXVALIDSTRING(args[0]) ||
- !RXVALIDSTRING(args[1]) ||
- args[0].strlength > 255)
- return INVALID_ROUTINE; /* Invalid call to routine */
- /* initialize data area */
- ldp.count = 0;
- strcpy(ldp.varname, args[1].strptr);
- ldp.stemlen = args[1].strlength;
- strupr(ldp.varname); /* uppercase the name */
-
- if (ldp.varname[ldp.stemlen-1] != '.')
- ldp.varname[ldp.stemlen++] = '.';
-
- strcpy(FileSpec, args[0].strptr); /* get file spec */
-
- /** If FileSpec ends in \ then append *.* * */
-
- if (FileSpec[strlen(FileSpec)-1] == '\\')
- strcat(FileSpec, "*.*");
-
- if (numargs >= 3 && /* check third option */
- !RXNULLSTRING(args[2])) {
- if (!args[2].strlength) /* a zero length string isn't */
- return INVALID_ROUTINE; /* valid */
- strcpy(Opts, args[2].strptr);
- strupr(Opts); /* Uppercase the string */
-
- if (strchr(Opts, 'S') != NULL)
- options |= RECURSE; /* Should we recurse */
-
- if (strchr(Opts, 'O') != NULL)
- options |= NAME_ONLY; /* Should include names only */
-
- if (strchr(Opts, 'T') != NULL)
- options |= EDITABLE_TIME; /* Should create editable */
- /* timestamp */
-
- if (strchr(Opts, 'F') != NULL) {
- options &= ~DO_DIRS; /* Should not include dirs ! */
- options |= DO_FILES; /* Should include files ! */
- }
-
- if (strchr(Opts, 'D') != NULL) {
- options |= DO_DIRS; /* Should include dirs ! */
- options &= ~DO_FILES; /* Should not include files ! */
- }
-
- if (strchr(Opts, 'B') != NULL) {
- options |= DO_DIRS; /* Should include dirs ! */
- options |= DO_FILES; /* Should include files ! */
- }
- }
-
- if (numargs >= 4) { /* check fourth option */
- strcpy(Opts, args[3].strptr);
-
- smask[0] = smask[1] = smask[2] = smask[3] = smask[4] = 0;
- x = min(5, strlen(Opts));
-
- for (y = 0; y < x; y++) {
-
- if (Opts[y] == '+')
- smask[y] = 1;
-
- if (Opts[y] == '-')
- smask[y] = -1;
- }
- }
-
- if (numargs == 5) { /* check fifth argument */
- strcpy(Opts, args[4].strptr); /* point to string */
- dmask[0] = dmask[1] = dmask[2] = dmask[3] = dmask[4] = 0;
-
- x = min(5, strlen(Opts));
-
- for (y = 0; y < x; y++) {
-
- if (Opts[y] == '+')
- dmask[y] = 1;
-
- if (Opts[y] == '-')
- dmask[y] = -1;
- }
- dmask[1] = 0; /* Ignore directory bit of */
- /* destination mask */
- }
- /* recursively search */
- if (RecursiveFindFile(FileSpec, &ldp, smask, dmask, options))
- return INVALID_ROUTINE;
- /* return lines read */
- sprintf(ldp.ibuf, "%d", ldp.count);
- ldp.varname[ldp.stemlen] = '0';
- ldp.varname[ldp.stemlen+1] = 0;
- ldp.shvb.shvnext = NULL;
- ldp.shvb.shvname.strptr = ldp.varname;
- ldp.shvb.shvname.strlength = ldp.stemlen+1;
- ldp.shvb.shvnamelen = ldp.stemlen+1;
- ldp.shvb.shvvalue.strptr = ldp.ibuf;
- ldp.shvb.shvvalue.strlength = strlen(ldp.ibuf);
- ldp.shvb.shvvaluelen = ldp.shvb.shvvalue.strlength;
- ldp.shvb.shvcode = RXSHV_SET;
- ldp.shvb.shvret = 0;
- if (RexxVariablePool(&ldp.shvb) == RXSHV_BADN)
- return INVALID_ROUTINE; /* error on non-zero */
-
- return VALID_ROUTINE; /* no error on call */
- }
-
-
- /*************************************************************************
- * Function: SysGetMessage *
- * *
- * Syntax: call SysGetMessage [file], msgnum [,str1] ... [,str9] *
- * *
- * Params: file - Name of message file to get message from. *
- * Default is OSO001.MSG. *
- * msgnum - Number of message being queried. *
- * str1 ... str9 - Insertion strings. For messages which *
- * contain %1, %2, etc, the str1, str2, etc *
- * strings will be inserted (if given). *
- * *
- * Return: The message with the inserted strings (if given). *
- *************************************************************************/
-
- ULONG SysGetMessage(CHAR *name, ULONG numargs, RXSTRING args[],
- CHAR *queuename, RXSTRING *retstr)
- {
- PCHAR ivtable[9]; /* Array of pointers to */
- /* variables */
- CHAR dataarea[500]; /* Buffer address to return */
- /* message */
- ULONG msglen; /* Length of the returned */
- /* message */
- ULONG datalen = 500; /* Length of the input buffer */
- ULONG file_handle = 1; /* Output device handle for */
- /* the screen */
- ULONG ivcount = 3; /* Number of variables to */
- /* insert = 0 */
- LONG msgnum; /* Message number to get */
- LONG x; /* Loop counter */
- PSZ msgfile; /* Message file */
-
- if (numargs < 1 || numargs > 11 || /* validate arguments */
- !RXVALIDSTRING(args[0]))
- return INVALID_ROUTINE; /* exit with error */
- /* get message number */
- if (!string2long(args[0].strptr, &msgnum) || msgnum < 0)
- return INVALID_ROUTINE; /* exit with error */
- /* Get message file name. */
- /* Use "OSO001.MSG if not */
- /* given */
- if (numargs >= 2 && RXVALIDSTRING(args[1]))
- msgfile = args[1].strptr; /* use provided message file */
- else
- msgfile = "OSO001.MSG";
-
- /* copy insertion string */
- /* pointers */
- for (x = 2; x < numargs; x++) {
- if (RXNULLSTRING(args[x])) /* must be valid string */
- return INVALID_ROUTINE; /* leave now if bad */
- ivtable[x-2] = args[x].strptr;
- }
- /* set number of insertions */
- if (numargs >= 2)
- ivcount = numargs-2;
- else
- ivcount = 0;
- /* get the message */
- DosGetMessage(ivtable, ivcount, dataarea, datalen, msgnum, msgfile,
- &msglen);
- /* save the message */
- if (msglen > retstr->strlength)
- if (DosAllocMem((PPVOID)&retstr->strptr, msglen, AllocFlag)) {
- BUILDRXSTRING(retstr, ERROR_NOMEM);
- return VALID_ROUTINE;
- }
- memcpy(retstr->strptr, dataarea, msglen);
- retstr->strlength = msglen;
-
- return VALID_ROUTINE; /* no error on call */
- }
-
- /*************************************************************************
- * Function: SysIni *
- * *
- * Syntax: call SysIni [inifile], app [,key/stem] [,val/stem] *
- * *
- * Params: inifile - INI file from which to query or write info. The *
- * default is the current user INI file. *
- * app - Application title to work with. May be either *
- * of the following: *
- * 'ALL:' - All app titles will be returned in the *
- * stem variable specified by the next *
- * parameter. *
- * other - Specific app to work with. *
- * key - Key to work with. May be any of the following: *
- * 'ALL:' - All key titles will be returned in *
- * the stem variable specified by the *
- * next parameter. *
- * 'DELETE:' - All keys associated with the app *
- * will be deleted. *
- * other - Specific key to work with. *
- * val - Key to work with. May be either of the following: *
- * 'DELETE:' - Delete app/key pair. *
- * other - Set app/key pair info to data spec- *
- * ified. *
- * stem - Name of stem variable in which to store results. *
- * Stem.0 = Number found (n). *
- * Stem.1 - Stem.n = Entries found. *
- * *
- * Return: other - Info queried from specific app/key pair. *
- * '' - Info queried and placed in stem or data *
- * deleted successfully. *
- * ERROR_NOMEM - Out of memory. *
- * ERROR_RETSTR - Error opening INI or querying/writing info.*
- *************************************************************************/
-
- ULONG SysIni(CHAR *name, ULONG numargs, RXSTRING args[],
- CHAR *queuename, RXSTRING *retstr)
- {
- HAB hab; /* Anchor block */
- HINI hini; /* Ini file handle */
- ULONG x; /* Temp counter */
- ULONG len; /* Len var used when creating */
- /* stem */
- ULONG lSize; /* Size of queried info buffer*/
- /* area */
- PSZ IniFile; /* Ini file (USER, SYSTEM, */
- /* BOTH, file) */
- PSZ App; /* Application field */
- PSZ Key; /* Key field */
- CHAR *Val; /* Ptr to data associated w/ */
- /* App->Key */
- CHAR Temp[256]; /* Temp string var */
- CHAR UserName[256]; /* Filename of User INI */
- /* profile */
- CHAR SysName[256]; /* Filename of System INI */
- /* profile */
- PRFPROFILE PrfInfo; /* Profile name structure */
- LONG Error = FALSE; /* Set to true if error */
- /* encountered */
- BOOL WildCard = FALSE; /* Set to true if a wildcard */
- /* operation */
- BOOL QueryApps; /* Set to true if a query */
- /* operation */
- BOOL terminate = TRUE; /* perform WinTerminate call */
- RXSTEMDATA ldp; /* local data */
-
- IniFile = "";
- Key = "";
- /* validate arguments */
- if (numargs < 2 ||
- numargs > 4 ||
- !RXVALIDSTRING(args[1]))
- return INVALID_ROUTINE;
- /* get pointers to args */
- IniFile = args[0].strptr;
- App = args[1].strptr;
-
- if (numargs >= 3 && args[2].strptr)
- Key = args[2].strptr;
-
- if (numargs == 4)
- Val = args[3].strptr;
- /* Check KEY and APP values */
- /* for "WildCard" */
- if (!stricmp(App, "ALL:")) {
- App = "";
- QueryApps = TRUE;
- WildCard = TRUE;
-
- if (numargs != 3)
- return INVALID_ROUTINE; /* Error - Not enough args */
- else
- x = 2; /* Arg number of STEM variable*/
- }
-
- else if (!stricmp(Key, "ALL:")) {
- Key = "";
- Val = "";
- QueryApps = FALSE;
- WildCard = TRUE;
-
- if (numargs != 4)
- return INVALID_ROUTINE; /* Error - Not enough args */
-
- else
- x = 3; /* Arg number of STEM variable*/
- }
- /* If this is a "WildCard */
- /* search, then allocate mem */
- /* for stem struct and get the*/
- /* stem name */
- if (WildCard == TRUE) {
-
- ldp.count = 0; /* get the stem variable name */
- strcpy(ldp.varname, args[x].strptr);
- ldp.stemlen = args[x].strlength;
- strupr(ldp.varname); /* uppercase the name */
-
- if (ldp.varname[ldp.stemlen-1] != '.')
- ldp.varname[ldp.stemlen++] = '.';
- }
-
- hab = WinInitialize((USHORT)0); /* create anchor block */
- if (!hab) { /* already done? */
- /* get desktop anchor */
- hab = WinQueryAnchorBlock(HWND_DESKTOP);
- terminate = FALSE; /* don't terminate */
- }
-
- /**************************************************************
- * The following section of code gets the INI file handle *
- * given the INI file spec (IniFile). *
- * *
- * Possible Ini file specs: *
- * *
- * NULL - Same as USERPROFILE ( OS2.INI ) *
- * "BOTH" - Same as PROFILE ( OS2.INI & OS2SYS.INI ) *
- * "USER" - Same as USERPROFILE ( OS2.INI ) *
- * "SYSTEM" - Same as SYSTEMPROFILE ( OS2SYS.INI) *
- * other - Filespec of INI file. *
- **************************************************************/
-
- hini = NULLHANDLE;
-
- if (!IniFile)
- hini = HINI_USERPROFILE;
- else if (!stricmp(IniFile, "BOTH"))
- hini = HINI_PROFILE;
- else if (!stricmp(IniFile, "USER"))
- hini = HINI_USERPROFILE;
- else if (!stricmp(IniFile, "SYSTEM"))
- hini = HINI_SYSTEMPROFILE;
-
- /***********************************************************
- * If Ini file spec is 'other' then make sure it does not *
- * specify the current USER or SYSTEM profiles. *
- * *
- * Trying to open the current USER or SYSTEM ini file via *
- * PrfOpenProfile() will fail. Therefore, use the function *
- * PrfQueryProfile() to query the current USER and SYSTEM *
- * ini file specs. If the IniFile string matches either *
- * the current USER or SYSTEM file specs, then use either *
- * HINI_USERPROFILE or HINI_SYSTEMPROFILE as appropriate. *
- * *
- * If IniFile does not specify the current USER or SYSTEM *
- * ini file then use PrfOpenProfile() to get the ini file *
- * handle. *
- ***********************************************************/
-
- else {
- PrfInfo.pszUserName = UserName;
- PrfInfo.cchUserName = sizeof(UserName);
- PrfInfo.pszSysName = SysName;
- PrfInfo.cchSysName = sizeof(SysName);
-
- if (PrfQueryProfile(hab, &PrfInfo)) {
-
- if (!stricmp(IniFile, PrfInfo.pszUserName))
- hini = HINI_USERPROFILE;
- else if (!stricmp(IniFile, PrfInfo.pszSysName))
- hini = HINI_SYSTEMPROFILE;
- else
- hini = PrfOpenProfile(hab, IniFile);
- }
- else
- hini = PrfOpenProfile(hab, IniFile);
-
- /**************************************************
- * Exit with INI FILE error if the ini file handle *
- * is NULL at this point (and if IniFile != BOTH, *
- * as that would make the handle NULL also). *
- **************************************************/
-
- if (hini == NULLHANDLE && stricmp(IniFile, "BOTH")) {
- BUILDRXSTRING(retstr, ERROR_RETSTR);
- if (terminate)
- WinTerminate(hab);
- return VALID_ROUTINE;
- }
- }
- /* get value if is a query */
- if ((numargs == 3 && stricmp(Key, "DELETE:")) ||
- WildCard == TRUE) {
- lSize = 0x0000ffffL;
- /* Allocate a large buffer */
- if (DosAllocMem((PPVOID)&Val, lSize, AllocFlag)) {
- PrfCloseProfile(hini); /* close the INI file */
- if (terminate)
- WinTerminate(hab);
- BUILDRXSTRING(retstr, ERROR_NOMEM);
- return VALID_ROUTINE;
- }
-
- if (WildCard && QueryApps)
- Error = !PrfQueryProfileData(hini, NULL, NULL, Val, &lSize);
- else if (WildCard && !QueryApps)
- Error = !PrfQueryProfileData(hini, App, NULL, Val, &lSize);
- else
- Error = !PrfQueryProfileData(hini, App, Key, Val, &lSize);
-
- if (Error) {
- BUILDRXSTRING(retstr, ERROR_RETSTR);
- }
- else if (WildCard == FALSE) {
- if (lSize > retstr->strlength)
- if (DosAllocMem((PPVOID)&retstr->strptr, lSize, AllocFlag)) {
- DosFreeMem(Val); /* release buffer */
- PrfCloseProfile(hini); /* close the INI file */
- if (terminate)
- WinTerminate(hab);
- BUILDRXSTRING(retstr, ERROR_NOMEM);
- return VALID_ROUTINE;
- }
- memcpy(retstr->strptr, Val, lSize);
- retstr->strlength = lSize;
- DosFreeMem(Val); /* release buffer */
- }
- }
- else {
- /* set the var to new value */
- if (!stricmp(Key, "DELETE:") ||
- !RXVALIDSTRING(args[2]))
- Error = !PrfWriteProfileData(hini, App, NULL, NULL, 0L);
- else if (!stricmp(Val, "DELETE:") ||
- !RXVALIDSTRING(args[3]))
- Error = !PrfWriteProfileData(hini, App, Key, NULL, 0L);
- else {
- lSize = args[3].strlength;
- Error = !PrfWriteProfileData(hini, App, Key, Val, lSize);
- }
-
- if (Error) {
- BUILDRXSTRING(retstr, ERROR_RETSTR);
- }
- }
-
- PrfCloseProfile(hini); /* close the INI file */
-
- if (terminate)
- WinTerminate(hab); /* destroy anchor block */
-
- /******************************************
- * If this was a wildcard search, change *
- * the Val variable from one long string *
- * of values to a REXX stem variable. *
- ******************************************/
-
- if (WildCard == TRUE) { /* fill stem variable */
-
- if (Error == FALSE) {
- x = 0;
- ldp.count = 0;
-
- do {
- /* Copy string terminated by \0 to Temp. Last string will end */
- /* in \0\0 and thus have a length of 0. */
- len = 0;
-
- while (Val[x+len] != '\0')
- Temp[len++] = Val[x+len];
- Temp[len] = '\0';
- /* if non-zero length, then */
- /* set the stem element */
- if (len != 0) {
- x += (len+1); /* Increment pointer past the */
- /* new string */
- memcpy(ldp.ibuf, Temp, len);
- ldp.vlen = len;
- ldp.count++;
- sprintf(ldp.varname+ldp.stemlen, "%d", ldp.count);
-
- if (ldp.ibuf[ldp.vlen-1] == '\n')
- ldp.vlen--;
- ldp.shvb.shvnext = NULL;
- ldp.shvb.shvname.strptr = ldp.varname;
- ldp.shvb.shvname.strlength = strlen(ldp.varname);
- ldp.shvb.shvvalue.strptr = ldp.ibuf;
- ldp.shvb.shvvalue.strlength = ldp.vlen;
- ldp.shvb.shvnamelen = ldp.shvb.shvname.strlength;
- ldp.shvb.shvvaluelen = ldp.vlen;
- ldp.shvb.shvcode = RXSHV_SET;
- ldp.shvb.shvret = 0;
- if (RexxVariablePool(&ldp.shvb) == RXSHV_BADN)
- return INVALID_ROUTINE; /* error on non-zero */
- }
- }
-
- while (Val[x] != '\0');
- }
-
- else
- ldp.count = 0;
- /* set number returned */
- sprintf(ldp.ibuf, "%d", ldp.count);
- ldp.varname[ldp.stemlen] = '0';
- ldp.varname[ldp.stemlen+1] = 0;
- ldp.shvb.shvnext = NULL;
- ldp.shvb.shvname.strptr = ldp.varname;
- ldp.shvb.shvname.strlength = ldp.stemlen+1;
- ldp.shvb.shvnamelen = ldp.stemlen+1;
- ldp.shvb.shvvalue.strptr = ldp.ibuf;
- ldp.shvb.shvvalue.strlength = strlen(ldp.ibuf);
- ldp.shvb.shvvaluelen = ldp.shvb.shvvalue.strlength;
- ldp.shvb.shvcode = RXSHV_SET;
- ldp.shvb.shvret = 0;
- if (RexxVariablePool(&ldp.shvb) == RXSHV_BADN)
- return INVALID_ROUTINE; /* error on non-zero */
-
- } /* * End - IF (Wildcard ... * */
-
- return VALID_ROUTINE; /* no error on call */
- }
-
-
- /*************************************************************************
- * Function: SysLoadFuncs *
- * *
- * Syntax: call SysLoadFuncs [option] *
- * *
- * Params: none *
- * *
- * Return: null string *
- *************************************************************************/
-
- ULONG SysLoadFuncs(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],
- "REXXUTIL", RxFncTable[j]);
- }
- return VALID_ROUTINE;
- }
-
-
- /*************************************************************************
- * Function: SysMkDir *
- * *
- * Syntax: call SysMkDir dir *
- * *
- * Params: dir - Directory to be created. *
- * *
- * Return: NO_UTIL_ERROR *
- * Return code from DosMkDir() *
- *************************************************************************/
-
- ULONG SysMkDir(CHAR *name, ULONG numargs, RXSTRING args[],
- CHAR *queuename, RXSTRING *retstr)
- {
- ULONG rc; /* Ret code of func */
-
- if (numargs != 1)
- /* If no args, then its an */
- /* incorrect call */
- return INVALID_ROUTINE;
- rc = DosMkDir(args[0].strptr, 0L); /* make the directory */
- sprintf(retstr->strptr, "%d", rc); /* result is return code */
- retstr->strlength = strlen(retstr->strptr);
- return VALID_ROUTINE;
- }
-
-
- /*************************************************************************
- * Function: SysOS2Ver *
- * *
- * Syntax: call SysOS2Ver *
- * *
- * Return: OS/2 Version in for 1.1, 1.2, 1.3, 2.0. *
- *************************************************************************/
-
- ULONG SysOS2Ver(CHAR *name, ULONG numargs, RXSTRING args[],
- CHAR *queuename, RXSTRING *retstr)
- {
- ULONG rc = 0; /* Return code of this func */
- ULONG Versions[2]; /* Major version number */
-
- if (numargs != 0) /* validate arg count */
- return INVALID_ROUTINE;
-
- DosQuerySysInfo(QSV_VERSION_MAJOR, QSV_VERSION_MINOR, Versions,
- sizeof(Versions));
- sprintf(retstr->strptr, "%lu.%02lu", Versions[0]/10, Versions[1]);
- retstr->strlength = strlen(retstr->strptr);
- return VALID_ROUTINE;
- }
-
- /*************************************************************************
- * Function: SysRmDir *
- * *
- * Syntax: call SysRmDir dir *
- * *
- * Params: dir - Directory to be removed. *
- * *
- * Return: NO_UTIL_ERROR *
- * Return code from DosRmDir() *
- *************************************************************************/
-
- ULONG SysRmDir(CHAR *name, ULONG numargs, RXSTRING args[],
- CHAR *queuename, RXSTRING *retstr)
- {
- ULONG rc; /* Ret code of func */
-
- if (numargs != 1)
- /* If no args, then its an */
- /* incorrect call */
- return INVALID_ROUTINE;
- /* remove the directory */
- rc = DosRmDir(args[0].strptr);
- sprintf(retstr->strptr, "%d", rc);
- retstr->strlength = strlen(retstr->strptr);
- return VALID_ROUTINE;
- }
-
-
- /*************************************************************************
- * Function: SysSearchPath *
- * *
- * Syntax: call SysSearchPath path, file *
- * *
- * Params: path - Environment variable name which specifies a path *
- * to be searched (ie 'PATH', 'DPATH', etc). *
- * file - The file to search for. *
- * *
- * Return: other - Full path and filespec of found file. *
- * '' - Specified file not found along path. *
- *************************************************************************/
-
- ULONG SysSearchPath(CHAR *name, ULONG numargs, RXSTRING args[],
- CHAR *queuename, RXSTRING *retstr)
- {
- UCHAR buf[MAX]; /* returned file name */
-
- /* validate arguments */
- if (numargs != 2 ||
- !RXVALIDSTRING(args[0]) ||
- !RXVALIDSTRING(args[1]))
- return INVALID_ROUTINE;
-
- /* use DosSearchPath */
- DosSearchPath(7, args[0].strptr, args[1].strptr,
- buf, sizeof(buf));
-
- BUILDRXSTRING(retstr, buf); /* pass back result */
- return VALID_ROUTINE;
- }
-
-
- /*************************************************************************
- * Function: SysSleep *
- * *
- * Syntax: call SysSleep secs *
- * *
- * Params: secs - Number of seconds to sleep. *
- * *
- * Return: NO_UTIL_ERROR *
- *************************************************************************/
-
- ULONG SysSleep(CHAR *name, ULONG numargs, RXSTRING args[],
- CHAR *queuename, RXSTRING *retstr)
- {
- LONG secs; /* Time to sleep in secs */
-
- if (numargs != 1) /* Must have one argument */
- return INVALID_ROUTINE;
- /* get number of seconds */
- if (!string2long(args[0].strptr, &secs) || secs < 0)
- return INVALID_ROUTINE; /* raise error if bad */
-
- DosSleep(secs *1000);
- BUILDRXSTRING(retstr, NO_UTIL_ERROR);
- return VALID_ROUTINE;
- }
-
-
- /*************************************************************************
- * Function: SysTempFileName *
- * *
- * Syntax: call SysTempFileName template [,filler] *
- * *
- * Params: template - Description of filespec desired. For example: *
- * C:\TEMP\FILE.??? *
- * filler - A character which when found in template will be *
- * replaced with random digits until a unique file *
- * or directory is found. The default character *
- * is '?'. *
- * *
- * Return: other - Unique file/directory name. *
- * '' - No more files exist given specified template. *
- *************************************************************************/
-
- ULONG SysTempFileName(CHAR *name, ULONG numargs, RXSTRING args[],
- CHAR *queuename, RXSTRING *retstr)
- {
- CHAR filler; /* filler character */
-
- if (numargs < 1 || /* validate arguments */
- numargs > 2 ||
- !RXVALIDSTRING(args[0]) ||
- args[0].strlength > 512)
- return INVALID_ROUTINE;
-
- if (numargs == 2 && /* get filler character */
- !RXNULLSTRING(args[1])) {
- if (args[1].strlength != 1) /* must be one character */
- return INVALID_ROUTINE;
- filler = args[1].strptr[0];
- }
- else
- filler = '?';
- /* get the file id */
- GetUniqueFileName(args[0].strptr, filler, retstr->strptr);
- retstr->strlength = strlen(retstr->strptr);
- return VALID_ROUTINE;
- }
-
-
- /*************************************************************************
- * Function: SysTextScreenRead *
- * *
- * Syntax: call SysTextScreenRead row, col [,len] *
- * *
- * Params: row - Horizontal row on the screen to start reading from. *
- * The row at the top of the screen is 0. *
- * col - Vertical column on the screen to start reading from. *
- * The column at the left of the screen is 0. *
- * len - The number of characters to read. The default is the *
- * rest of the screen. *
- * *
- * Return: Characters read from text screen. *
- *************************************************************************/
-
- ULONG SysTextScreenRead(CHAR *name, ULONG numargs, RXSTRING args[],
- CHAR *queuename, RXSTRING *retstr)
- {
- LONG row; /* Row from which to start */
- /* read */
- LONG col; /* Column from which to start */
- /* read */
- LONG len = 8160; /* Max length of string, */
- /* default is 8160 (80x102) */
- CHAR temp[8160]; /* Array of CHARs, aka PCH */
-
- if (numargs < 2 || /* validate arguments */
- numargs > 3 ||
- !RXVALIDSTRING(args[0]) ||
- !RXVALIDSTRING(args[1]) ||
- !string2long(args[0].strptr, &row) || row < 0 ||
- !string2long(args[1].strptr, &col) || col < 0)
- return INVALID_ROUTINE;
-
- if (numargs == 3) { /* check the length */
- if (!RXVALIDSTRING(args[2]) || /* bad string? */
- !string2long(args[2].strptr, &len) || len < 0)
- return INVALID_ROUTINE; /* error */
- }
- /* read the screen */
- VioReadCharStr( temp, (PUSHORT)&len, row, col, (HVIO) 0);
-
- if (len > retstr->strlength) /* default too short? */
- /* allocate a new one */
- if (DosAllocMem((PPVOID)&retstr->strptr, len, AllocFlag)) {
- BUILDRXSTRING(retstr, ERROR_NOMEM);
- return VALID_ROUTINE;
- }
- memcpy(retstr->strptr, temp, len);
- retstr->strlength = len;
-
- return VALID_ROUTINE;
- }
-
-
- /*************************************************************************
- * Function: SysTextScreenSize *
- * *
- * Syntax: call SysTextScreenSize *
- * *
- * Return: Size of screen in row and columns returned as: row, col *
- *************************************************************************/
-
- ULONG SysTextScreenSize(CHAR *name, ULONG numargs, RXSTRING args[],
- CHAR *queuename, RXSTRING *retstr)
- {
- VIOMODEINFO ModeData; /* screen info structure */
-
- if (numargs != 0) /* no arguments on this func. */
- return INVALID_ROUTINE;
-
- ModeData.cb = sizeof(ModeData); /* find out screen size */
- VioGetMode(&ModeData, (HVIO) 0);
- sprintf(retstr->strptr, "%d %d",(int)ModeData.row,(int)ModeData.col);
- retstr->strlength = strlen(retstr->strptr);
- return VALID_ROUTINE;
- }
-
- /*************************************************************************
- * Function: SysGetEA *
- * *
- * Syntax: call SysGetEA file, EA_name, variable *
- * *
- * Params: file - file containing EA. *
- * EA_name - name of EA to be retrieved *
- * name of variable EA is placed in *
- * *
- * Return: Return code from DosQueryFileInfo. *
- *************************************************************************/
-
- ULONG SysGetEA(CHAR *name, ULONG numargs, RXSTRING args[],
- CHAR *queuename, RXSTRING *retstr)
- {
- LONG rc; /* Ret code */
- UCHAR geabuff[300]; /* buffer for GEA */
- PVOID fealist; /* fealist buffer */
- EAOP2 eaop; /* eaop structure */
- PGEA2 pgea; /* pgea structure */
- PFEA2 pfea; /* pfea structure */
- HFILE handle; /* file handle */
- ULONG act; /* open action */
- RXSTEMDATA ldp; /* stem data */
-
-
- if (numargs != 3 || /* wrong number of arguments? */
- !RXVALIDSTRING(args[0]) ||
- !RXVALIDSTRING(args[1]) ||
- !RXVALIDSTRING(args[2]))
- return INVALID_ROUTINE; /* raise error condition */
-
- ldp.count = 0; /* get the stem variable name */
- strcpy(ldp.varname, args[2].strptr);
- ldp.stemlen = args[2].strlength;
- strupr(ldp.varname); /* uppercase the name */
-
- if (rc = DosOpen(args[0].strptr, &handle, &act,
- 0L, 0, OPEN_ACTION_OPEN_IF_EXISTS,
- OPEN_ACCESS_READONLY + OPEN_SHARE_DENYREADWRITE +
- OPEN_FLAGS_FAIL_ON_ERROR + OPEN_FLAGS_WRITE_THROUGH,NULL)) {
- sprintf(retstr->strptr, "%d", rc);
- retstr->strlength = strlen(retstr->strptr);
- return VALID_ROUTINE;
- } /* get the file status info */
-
- if (DosAllocMem((PPVOID)&fealist, 0x00010000L, AllocFlag)) {
- BUILDRXSTRING(retstr, ERROR_NOMEM);
- return VALID_ROUTINE;
- }
- /* FEA and GEA lists */
- eaop.fpGEA2List = (PGEA2LIST)geabuff;
- eaop.fpFEA2List = (PFEA2LIST)fealist;
- eaop.oError = 0; /* no error occurred yet */
- pgea = &eaop.fpGEA2List->list[0]; /* point to first GEA */
- eaop.fpGEA2List->cbList = sizeof(ULONG) + sizeof(GEA2) +
- args[1].strlength;
- eaop.fpFEA2List->cbList = (ULONG)0xffff;
-
- /* fill in the EA name length */
- pgea->cbName = (BYTE)args[1].strlength;
- strcpy(pgea->szName, args[1].strptr);/* fill in the name */
- pgea->oNextEntryOffset = 0; /* fill in the next offset */
- /* read the extended attribute*/
- rc = DosQueryFileInfo(handle, 3, (PSZ)&eaop, sizeof(EAOP2));
- DosClose(handle); /* close the file */
- if (eaop.fpFEA2List->cbList <= sizeof(ULONG))
- rc = ERROR_EAS_NOT_SUPPORTED; /* this is error also */
-
- sprintf(retstr->strptr, "%d", rc); /* format return code */
- retstr->strlength = strlen(retstr->strptr);
-
- if (rc) { /* failure? */
- DosFreeMem(fealist); /* error, get out */
- return VALID_ROUTINE;
- }
-
- pfea = &(eaop.fpFEA2List->list[0]); /* point to the first FEA */
- ldp.shvb.shvnext = NULL;
- ldp.shvb.shvname.strptr = ldp.varname;
- ldp.shvb.shvname.strlength = ldp.stemlen;
- ldp.shvb.shvnamelen = ldp.stemlen;
- ldp.shvb.shvvalue.strptr = ((PSZ)pfea->szName+(pfea->cbName+1));
- ldp.shvb.shvvalue.strlength = pfea->cbValue;
- ldp.shvb.shvvaluelen = ldp.shvb.shvvalue.strlength;
- ldp.shvb.shvcode = RXSHV_SET;
- ldp.shvb.shvret = 0;
- if (RexxVariablePool(&ldp.shvb) == RXSHV_BADN) {
- DosFreeMem(fealist); /* free our buffer */
- return INVALID_ROUTINE; /* error on non-zero */
- }
-
- DosFreeMem(fealist); /* free our buffer */
- return VALID_ROUTINE;
- }
-
- /*************************************************************************
- * Function: SysPutEA *
- * *
- * Syntax: call SysPutEA file, EA_name, value *
- * *
- * Params: file - file containing EA. *
- * EA_name - name of EA to be written *
- * new value for the EA *
- * *
- * Return: Return code from DosQueryFileInfo. *
- *************************************************************************/
-
- ULONG SysPutEA(CHAR *name, ULONG numargs, RXSTRING args[],
- CHAR *queuename, RXSTRING *retstr)
- {
- LONG rc; /* Ret code */
- PVOID fealist; /* fealist buffer */
- EAOP2 eaop; /* eaop structure */
- PFEA2 pfea; /* pfea structure */
- HFILE handle; /* file handle */
- ULONG act; /* open action */
-
-
- if (numargs != 3 || /* wrong number of arguments? */
- !RXVALIDSTRING(args[0]) ||
- !RXVALIDSTRING(args[1]))
- return INVALID_ROUTINE; /* raise error condition */
-
- if (rc = DosOpen2(args[0].strptr, &handle, &act,
- 0L, 0, OPEN_ACTION_OPEN_IF_EXISTS,
- OPEN_ACCESS_READWRITE + OPEN_SHARE_DENYWRITE +
- OPEN_FLAGS_FAIL_ON_ERROR + OPEN_FLAGS_WRITE_THROUGH, NULL)) {
- sprintf(retstr->strptr, "%d", rc);
- retstr->strlength = strlen(retstr->strptr);
- return VALID_ROUTINE;
- }
-
- if (DosAllocMem((PPVOID)&fealist, 0x00010000L, AllocFlag)) {
- BUILDRXSTRING(retstr, ERROR_NOMEM);
- return VALID_ROUTINE;
- }
-
- eaop.fpFEA2List = (PFEA2LIST)fealist;/* Set memory for the FEA */
- eaop.fpGEA2List = NULL; /* GEA is unused */
- pfea = &eaop.fpFEA2List->list[0]; /* point to first FEA */
- pfea->fEA = '\0'; /* set the flags */
- /* Size of FEA name field */
- pfea->cbName = (BYTE)args[1].strlength;
- /* Size of Value for this one */
- pfea->cbValue = (SHORT)args[2].strlength;
- /* Set the name of this FEA */
- strcpy((PSZ)pfea->szName, args[1].strptr);
- /* Set the EA value */
- memcpy((PSZ)pfea->szName+(pfea->cbName+1), args[2].strptr,
- args[2].strlength);
- pfea->oNextEntryOffset = 0; /* no next entry */
- eaop.fpFEA2List->cbList = /* Set the total size var */
- sizeof(ULONG) + sizeof(FEA2) + pfea->cbName + pfea->cbValue;
-
- /* set the file info */
- rc = DosSetFileInfo(handle, 2, (PSZ)&eaop, sizeof(EAOP2));
- DosClose(handle); /* Close the File */
- DosFreeMem(fealist); /* Free the memory */
- sprintf(retstr->strptr, "%d", rc); /* format return code */
- retstr->strlength = strlen(retstr->strptr);
- return VALID_ROUTINE;
- }
-
- /*************************************************************************
- * Function: SysWaitNamedPipe *
- * *
- * Syntax: result = SysWaitNamedPipe(name, timeout) *
- * *
- * Params: name - name of the pipe *
- * timeout - amount of time to wait. *
- * *
- * Return: Return code from DosWaitNPipe *
- *************************************************************************/
-
- ULONG SysWaitNamedPipe(CHAR *name, ULONG numargs, RXSTRING args[],
- CHAR *queuename, RXSTRING *retstr)
- {
- LONG rc; /* Ret code */
- LONG timeout; /* timeout value */
-
-
- if (numargs < 1 || /* wrong number of arguments? */
- numargs > 2 ||
- !RXVALIDSTRING(args[0]))
- return INVALID_ROUTINE; /* raise error condition */
-
- if (numargs == 2) { /* have a timeout value? */
- if (!string2long(args[1].strptr, &timeout) ||
- (timeout < 0 && timeout != -1))
- return INVALID_ROUTINE; /* raise error condition */
- }
-
- rc = DosWaitNPipe(args[0].strptr, timeout);
- sprintf(retstr->strptr, "%d", rc);
- retstr->strlength = strlen(retstr->strptr);
- return VALID_ROUTINE;
- }
-