home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 18 REXX
/
18-REXX.zip
/
SAAREXX.ZIP
/
XMPFXDLL.C
< prev
next >
Wrap
Text File
|
1991-08-02
|
15KB
|
348 lines
/*******************************************************************/
/* */
/* Module Name: XMPFXDLL */
/* */
/* Description: Example external functio for REXX/2. */
/* */
/* Function: File directory utility function. */
/* */
/* Entry points: RexDir */
/* */
/* Notes: */
/* */
/* The entry points obey the calling conventions for REXX */
/* external functions. Please use the following switches */
/* when you compile this module: */
/* */
/* -Alfu -G2s */
/* */
/*******************************************************************/
/* Modifications: */
/* */
/* Date Who Reason */
/* -------- --- ---------------------------------------------- */
/* 08/01/91 WDA Original issue. */
/* */
/*******************************************************************/
#define INCL_DOS
#define INCL_RXSHV
#include <os2.h>
#include <stdlib.h>
#include <string.h>
#include <rexxsaa.h>
#include "xmpfxdll.h"
/*******************************************************************/
/* */
/* Global definitions follow. */
/* */
/*******************************************************************/
/* none */
/*******************************************************************/
/* */
/* Global variables follow. */
/* */
/*******************************************************************/
static PCHAR szVersion = "1.00";
static CHAR szCompDate[] = __DATE__;
/*******************************************************************/
/* */
/* Internal function prototypes follow. */
/* */
/*******************************************************************/
PSZ Rx2psz (RXSTRING rxsSource);
SHORT SetRexVar (PSZ pszVar, PVOID pValue, ULONG ulLen);
/*******************************************************************/
/* */
/* Function: RexDir() */
/* */
/* Description: Retrieve file specs. */
/* */
/* Input: File search specification */
/* Stem variable name */
/* Search option(s) (optional) */
/* */
/* Returns: Return code: '' = invalid arguments */
/* 0 = success */
/* 1 = REXX variable pool error */
/* 2 = memory error */
/* */
/* External References: DosFindFirst() */
/* DosFindNext() */
/* DosFindClose() */
/* */
/* Internal References: Rx2psz() */
/* SetRexVar() */
/* */
/* Notes: */
/* */
/* This routine takes 2 or 3 parameters. The form of the call is:*/
/* */
/* retc = RexDir(filespec, stem); */
/* or */
/* retc = RexDir(filespec, stem, options); */
/* */
/*******************************************************************/
SHORT APIENTRY RexDir (
PSZ function_name, /* Function invocation name.*/
SHORT argc, /* Number of arguments. */
PRXSTRING argv, /* Function arguments. */
PSZ queue_name, /* Current queue name. */
PRXSTRING retval) { /* Value returned by funct. */
PSZ pszFname, pszStem, pszOptions;
SHORT i;
SHORT retc;
HDIR hdir = HDIR_CREATE;
USHORT usSearchCount = 1;
FILEFINDBUF findbuf;
USHORT usOptions = 0;
CHAR cOutline [256];
CHAR cTail [18], cStem [251], cSymbol [251];
/*****************************************************************/
/* Initialize the return buffer to 0 and the return value to */
/* empty. */
/* */
/* Please note that the REXX interpreter allocates 250 bytes in */
/* the return string. This will suffice for us. */
/*****************************************************************/
retval -> strlength = 0;
/*****************************************************************/
/* If the argument count is valid (i.e. 2 or 3) and the argument */
/* is not too short, perform function. */
/*****************************************************************/
if ((argc >= 2) && (argc <= 3) && /* Arg count valid? */
(argv[0].strlength > 0) && /* Filespec > 0? */
(argv[1].strlength > 0)) { /* Stem variable name > 0? */
/* Extract the caller's arguments from the RXSTRING */
/* in argv into a null-terminated C strings. */
pszFname = Rx2psz (argv[0]);
if (pszFname == NULL) {
*(retval -> strptr) = '2';
retval -> strlength = 1L;
return (0);
}
pszStem = Rx2psz (argv[1]);
if (pszFname == NULL) {
*(retval -> strptr) = '2';
retval -> strlength = 1L;
free (pszFname);
return (0);
}
if ((argc == 3) && (argv[2].strlength > 0)) {
pszOptions = Rx2psz (argv[2]);
if (pszFname == NULL) {
free (pszFname);
free (pszStem);
*(retval -> strptr) = '2';
retval -> strlength = 1L;
return (0);
}
strupr (pszOptions);
if (strchr (pszOptions, 'F') != NULL)
usOptions |= FILE_NORMAL;
else if (strchr (pszOptions, 'D') != NULL)
usOptions |= FILE_DIRECTORY;
else if (strchr (pszOptions, 'B') != NULL)
usOptions |= FILE_DIRECTORY | FILE_NORMAL;
else
usOptions |= FILE_NORMAL;
if (strchr (pszOptions, 'S') != NULL)
usOptions |= FILE_SYSTEM;
if (strchr (pszOptions, 'H') != NULL)
usOptions |= FILE_HIDDEN;
free (pszOptions);
}
else
usOptions |= FILE_NORMAL;
/* Initialize stem */
strcpy (cStem, pszStem);
if ((CHAR) *(pszStem + strlen (pszStem) - 1) != '.')
strcat (cStem, ".");
/* Find first file */
i = 0;
retc = DosFindFirst (pszFname, &hdir, usOptions, &findbuf,
sizeof (findbuf), &usSearchCount, 0L);
/* If retc == 0 then keep getting next file specs */
while (retc == 0) {
i += 1;
/* set up stem.tail REXX variable */
sprintf (cOutline, "%2d-%02d-%04d %02d:%02d %8d ",
findbuf.fdateLastWrite.month,
findbuf.fdateLastWrite.day,
findbuf.fdateLastWrite.year + 1980,
findbuf.ftimeLastWrite.hours,
findbuf.ftimeLastWrite.minutes,
findbuf.cbFileAlloc);
if (findbuf.attrFile & FILE_HIDDEN)
strcat (cOutline, "H");
else
strcat (cOutline, " ");
if (findbuf.attrFile & FILE_SYSTEM)
strcat (cOutline, "S");
else
strcat (cOutline, " ");
if (findbuf.attrFile & FILE_DIRECTORY)
strcat (cOutline, "<DIR> ");
else
strcat (cOutline, " ");
strcat (cOutline, findbuf.achName);
/* set up stem.tail name including trailer */
strcpy (cSymbol, cStem);
itoa (i, cTail, 10);
strcat (cSymbol, cTail);
/* set variable in pool */
retc = SetRexVar (cSymbol, cOutline,
(ULONG) strlen (cOutline));
/* test return codes */
if (retc != 0) {
DosFindClose (hdir);
free (pszFname);
free (pszStem);
*(retval -> strptr) = '1';
retval -> strlength = 1L;
return (0);
}
retc = DosFindNext (hdir, &findbuf, sizeof (findbuf),
&usSearchCount);
}
DosFindClose (hdir);
/* Set number of lines into stem.0 variable */
itoa (i, cOutline, 10);
/* set up stem.0 name including trailer */
strcpy (cSymbol, cStem);
strcat (cSymbol, "0");
/* set variable in pool */
retc = SetRexVar (cSymbol, cOutline, (ULONG) strlen (cOutline));
/* test return codes */
if (retc != 0) {
free (pszFname);
free (pszStem);
*(retval -> strptr) = '1';
retval -> strlength = 1L;
return (0);
}
/* Free memory */
free (pszFname);
free (pszStem);
/* set up return value for caller */
*(retval -> strptr) = '0';
retval -> strlength = 1L;
}
return (0);
}
/*******************************************************************/
/* */
/* Function: Rx2psz() */
/* */
/* Description: Create PSZ from a RXSTRING. The caller is */
/* responsible for freeing the memory */
/* allocated by this function via free(). */
/* */
/* Input: RXSTRING - string to be converted */
/* */
/* Returns: PSZ - converted string */
/* */
/* References: memmove(), malloc() */
/* */
/* Notes: */
/* */
/* None. */
/* */
/*******************************************************************/
PSZ Rx2psz (
RXSTRING rxsSource) { /* Source struc */
PSZ pszTemp;
/* Calculate destination buffer size and allocate buffer */
pszTemp = malloc ((USHORT) rxsSource.strlength + 1);
if (pszTemp == NULL)
return (NULL);
/* Move source into dest buffer */
memmove (pszTemp, rxsSource.strptr, (USHORT) rxsSource.strlength);
/* Zero-terminate dest buffer */
pszTemp[rxsSource.strlength] = '\0';
return (pszTemp);
}
/*******************************************************************/
/* */
/* Function: SetRexVar() */
/* */
/* Description: Sets the contents of a variable in the */
/* Rexx Variable Pool. */
/* */
/* Input: PSZ - Rexx variable name */
/* PVOID - Value */
/* ULONG - Value length */
/* */
/* Returns: Return code from RxVar() */
/* */
/* References: RxVar() */
/* */
/* Notes: */
/* */
/* None. */
/* */
/*******************************************************************/
SHORT SetRexVar (
PSZ pszVar, /* Variable name */
PVOID pValue, /* Ptr to value */
ULONG ulLen) { /* Value length */
SHVBLOCK RxVarBlock;
SHORT retc;
/* Initialize RxVarBlock */
RxVarBlock.shvnext = NULL;
RxVarBlock.shvname.strptr = pszVar;
RxVarBlock.shvname.strlength = (ULONG) strlen (pszVar);
RxVarBlock.shvnamelen = RxVarBlock.shvname.strlength;
RxVarBlock.shvvalue.strptr = pValue;
RxVarBlock.shvvalue.strlength = ulLen;
RxVarBlock.shvvaluelen = ulLen;
RxVarBlock.shvcode = RXSHV_SYSET;
RxVarBlock.shvret = RXSHV_OK;
/* set variable in pool */
retc = RxVar (&RxVarBlock);
/* test return codes */
if (retc == RXSHV_NEWV)
return (RXSHV_OK);
return (retc);
}