/* mainly to allow easy use of the __unaligned directive */
#define ULONGPTR __unaligned unsigned long*
#define USHORTPTR __unaligned unsigned short*
#define INT64PTR __unaligned __int64*
#ifndef __VAX
# pragma nomember_alignment
#endif
#ifndef __VAX
# ifndef NO_ODS_EXTENDED
# define ODS_EXTENDED 1
/* this is smaller than the technical maximum, but still quite large! */
# define ODS_MAX_FILE_NAME_LENGTH 511
# define ODS_MAX_FILESYS_NAME_LENGTH 264
# endif
#endif
#define ODS2_MAX_FILE_NAME_LENGTH 255
#ifndef ODS_MAX_FILE_NAME_LENGTH
# define ODS_MAX_FILE_NAME_LENGTH ODS2_MAX_FILE_NAME_LENGTH
#endif
#if ODS_MAX_FILE_NAME_LENGTH < ODS2_MAX_FILE_NAME_LENGTH
# define ODS_MAX_FILE_NAME_LENGTH ODS2_MAX_FILE_NAME_LENGTH
#endif
#define boolean int
#define true 1
#define false 0
#define VMSok(x) ((x) & STS$M_SUCCESS)
#define VMSnok(x) !(((x) & STS$M_SUCCESS))
#define FI_LI __FILE__, __LINE__
/* macro provides NULL pointer if CGI variable does not exist */
#define GetCgiVarIfExists(CharPointer,CgiVariableName) \
CharPointer = getenv(CgiVariableName)
/* macro provides pointer to empty string even if CGI variable does not exist */
#define GetCgiVar(CharPointer,CgiVariableName) \
if ((CharPointer = getenv(CgiVariableName)) == NULL) \
CharPointer = ""; \
if (Debug) fprintf (stdout, "%s |%s|\n", CgiVariableName, CharPointer);
#define MAX_RECORD_SIZE 32767
/* use this character to mask out HTML tag characters when searching */
#define MASK_TAG_CHAR '\xff'
/*
The first comma delimits an empty file type (e.g. README.;)
HTML extensions are included here because they can be treated as plain
text files if being considered as source rather than marked-up text.
*/
#define DEFAULT_TEXT_TYPES \
",ADA,ASCII,BAS,C,CNF,COB,CONF,COM,CPP,DIS,FOR,JAVA,H,LIS,LOG,MAR,\
PAS,PRO,RELEASE_NOTES,SDML,TEX,TEXT,TXT,HTML,HTM,SHTML,HTMLX"
#define DEFAULT_HTML_TYPES "HTM,HTML,SHTML,HTMLX"
#define DEFAULT_BUTTONS ""
#define DEFAULT_PS_BGCOLOR "#ffffff"
#define DEFAULT_PS_TEXT "#000000"
#define DEFAULT_PS_LINK "#0000cc"
#define DEFAULT_PS_VLINK "#0000cc"
#define DEFAULT_PS_HEADBGCOLOR "#cccccc"
#define DEFAULT_PS_HEADBORDER "0"
#define DEFAULT_PS_HEADTEXT "#000000"
#define DEFAULT_PS_BUTTONBGCOLOR "#ffffff"
#define DEFAULT_PS_BUTTONBORDER "1"
#define PS_BACKGROUND 0
#define PS_BGCOLOR 1
#define PS_TEXT 2
#define PS_LINK 3
#define PS_VLINK 4
#define PS_HEADBGCOLOR 5
#define PS_HEADTEXT 6
#define PS_HEADBORDER 7
#define PS_BUTTONBGCOLOR 8
#define PS_BUTTONBORDER 9
#define PS_BODYTAG 10
#define PS_LAYOUT 11
#define PS_HEADLOCAL 12
#define PS_HEADPADDING 13
char *PageScheme [16];
char DefaultButtons [] = DEFAULT_BUTTONS,
DefaultHtmlTypes [] = DEFAULT_HTML_TYPES,
DefaultTextTypes [] = DEFAULT_TEXT_TYPES,
Utility [] = "EXTRACT";
boolean Debug,
FormatLikeVms,
ThereHasBeenOutput;
int ExtractNumberOfRecords,
OdsExtended;
char ContentTypeCharset [64],
SoftwareID [48];
char *ButtonPtr = DefaultButtons,
*CgiEnvironmentPtr,
*CgiFormAnchorPtr,
*CgiFormExactPtr,
*CgiFormCasePtr,
*CgiFormEndPtr,
*CgiFormHighlightPtr,
*CgiFormHtmlPtr,
*CgiFormPlainPtr,
*CgiFormStartPtr,
*CgiFormTextPtr,
*CgiPathInfoPtr,
*CgiPathTranslatedPtr,
*CgiRequestMethodPtr,
*CgiRequestSchemePtr,
*CgiScriptNamePtr,
*CgiServerNamePtr,
*CgiServerSoftwarePtr,
*CgiServerPortPtr,
*CharsetPtr,
*CliCharsetPtr,
*HtmlFileTypesPtr = DefaultHtmlTypes,
*TextFileTypesPtr = DefaultTextTypes,
*UrlEncodedCgiPathInfoPtr;
/* required prototypes */
char* SearchTextString (char*, char*, boolean, boolean, int*);
/*****************************************************************************/
/*
'argc/argv' are only required to support OSU, in particular CgiLibOsuInit().
*/
main
(
int argc,
char *argv[]
)
{
boolean CaseSensitive = false,
DocumentOnly = false;
int status,
EndRecordNumber,
StartRecordNumber;
char *cptr;
char ServerPort [32],
String [512];
/*********/
/* begin */
/*********/
sprintf (SoftwareID, "%s (%s)", SOFTWAREID, CgiLibEnvironmentVersion());
if (getenv ("EXTRACT$DBUG") != NULL) Debug = true;
CgiLibEnvironmentSetDebug (Debug);
if (Debug) fprintf (stdout, "Content-Type: text/plain\n\n");
CgiLibEnvironmentInit (argc, argv, false);
CgiEnvironmentPtr = CgiLibEnvironmentName ();
GetParameters ();
SetPageScheme ();
CgiLibResponseSetBody (PageScheme[PS_BODYTAG]);
CgiLibResponseSetCharset (CliCharsetPtr);
CgiLibResponseSetSoftwareID (SoftwareID);
CgiLibResponseSetErrorMessage ("Reported by WASDextract");
#ifdef ODS_EXTENDED
OdsExtended = (GetVmsVersion() >= 72);
ENAMEL_NAML_SANITY_CHECK
#endif /* ODS_EXTENDED */
#ifdef ODS_EXTENDED
OdsExtended = (GetVmsVersion() >= 72);
#endif /* ODS_EXTENDED */
if (Debug)
fprintf (stdout, "TextFileTypesPtr |%s|\n", TextFileTypesPtr);
if (!*TextFileTypesPtr)
{
CgiLibResponseError (FI_LI, 0, "Text file extensions not configured.");
exit (SS$_NORMAL);
}
if (Debug)
fprintf (stdout, "HtmlFileTypesPtr |%s|\n", HtmlFileTypesPtr);
if (!*HtmlFileTypesPtr)
{
CgiLibResponseError (FI_LI, 0, "HTML file extensions not configured.");
exit (SS$_NORMAL);
}
CgiServerSoftwarePtr = CgiVar ("WWW_SERVER_SOFTWARE");
CgiRequestMethodPtr = CgiVar ("WWW_REQUEST_METHOD");
if (strcmp (CgiRequestMethodPtr, "GET"))
{
CgiLibResponseHeader (501, "text/html");
fprintf (stdout, "Not implemented!\n");
return;
}
CgiPathInfoPtr = CgiVar ("WWW_PATH_INFO");
CgiPathTranslatedPtr = CgiVar ("WWW_PATH_TRANSLATED");
CgiScriptNamePtr = CgiVar ("WWW_SCRIPT_NAME");
CgiFormAnchorPtr = CgiVar ("WWW_FORM_ANCHOR");
CgiFormCasePtr = CgiVar ("WWW_FORM_CASE");
CgiFormEndPtr = CgiVar ("WWW_FORM_END");
CgiFormExactPtr = CgiVar ("WWW_FORM_EXACT");
CgiFormHighlightPtr = CgiVar ("WWW_FORM_HIGHLIGHT");
CgiFormHtmlPtr = CgiVar ("WWW_FORM_HTML");
CgiFormPlainPtr = CgiVar ("WWW_FORM_PLAIN");
CgiFormStartPtr = CgiVar ("WWW_FORM_START");
CgiFormTextPtr = CgiVar ("WWW_FORM_TEXT");
if (toupper(CgiFormCasePtr[0]) == 'Y')
CaseSensitive = true;
else
CaseSensitive = false;
CgiFormExactPtr[0] = toupper(CgiFormExactPtr[0]);
StartRecordNumber = atoi (CgiFormStartPtr);
EndRecordNumber = atoi (CgiFormEndPtr);
if (CgiFormHtmlPtr[0]) HtmlFileTypesPtr = CgiFormHtmlPtr;
if (CgiFormTextPtr[0]) TextFileTypesPtr = CgiFormTextPtr;
FormatLikeVms = false;
for (cptr = CgiPathInfoPtr; *cptr; cptr++);
while (cptr > CgiPathInfoPtr && *cptr != '/')
{
if (*cptr == ';') FormatLikeVms = true;
cptr--;
}
#ifdef ODS_EXTENDED
if (OdsExtended)
{
/* re-encode the path in case it's an extended file specification */
UrlEncodedCgiPathInfoPtr =
(char*)CgiLibUrlEncode (CgiPathInfoPtr, -1, NULL, -1);
}
else
#endif /* ODS_EXTENDED */
UrlEncodedCgiPathInfoPtr = CgiPathInfoPtr;
for (cptr = CgiPathTranslatedPtr; *cptr; cptr++);
while (cptr > CgiPathTranslatedPtr && *cptr != '.') cptr--;
if (*cptr == '.') cptr++;
if (SameFileType (HtmlFileTypesPtr, cptr))
{
/*************/
/* HTML file */
/*************/
if (CgiFormAnchorPtr[0])
{
/*******************/
/* provide anchors */
/*******************/
status = AnchorHtmlFile (CgiPathTranslatedPtr,
CgiFormHighlightPtr,
CaseSensitive);
if (VMSnok (status))
CgiLibResponseError (FI_LI, status, UrlEncodedCgiPathInfoPtr);
}
else
if (CgiFormPlainPtr[0])
{
/**************************/
/* treat as if plain text */
/**************************/
status = ExtractTextFile (CgiPathTranslatedPtr,
CgiFormHighlightPtr,
StartRecordNumber, EndRecordNumber,
CaseSensitive);
if (VMSnok (status))
CgiLibResponseError (FI_LI, status, UrlEncodedCgiPathInfoPtr);
}
else
{
/************/
/* redirect */
/************/
CgiLibResponseRedirect (UrlEncodedCgiPathInfoPtr);
}
}
else
if (SameFileType (TextFileTypesPtr, cptr))
{
/*************/
/* text file */
/*************/
status = ExtractTextFile (CgiPathTranslatedPtr,
CgiFormHighlightPtr,
StartRecordNumber, EndRecordNumber,
CaseSensitive);
if (VMSnok (status))
CgiLibResponseError (FI_LI, status, UrlEncodedCgiPathInfoPtr);
}
else
{
/*********************/
/* unknown file type */
/*********************/
/* just return the document/image/file via redirection */
CgiLibResponseRedirect (UrlEncodedCgiPathInfoPtr);
}
exit (SS$_NORMAL);
}
/*****************************************************************************/
/*
Get "command-line" parameters, whether from the command-line or from a
configuration symbol or logical containing the equivalent. OSU scripts have
the 'method', 'url' and 'protocol' supplied as P1, P2, P3 (these being detected
and used by CGILIB), and are of no interest to this function.
*/
GetParameters ()
{
static char CommandLine [256];
static unsigned long Flags = 0;
int status,
SkipParameters;
unsigned short Length;
char ch;
char *aptr, *cptr, *clptr, *sptr;
$DESCRIPTOR (CommandLineDsc, CommandLine);
/*********/
/* begin */
/*********/
if ((clptr = getenv ("EXTRACT$PARAM")) == NULL)
{
/* get the entire command line following the verb */
if (VMSnok (status =
lib$get_foreign (&CommandLineDsc, 0, &Length, &Flags)))
exit (status);
(clptr = CommandLine)[Length] = '\0';
}
/* if [C]SWS (VMS Apache) */
if (CgiLibEnvironmentIsApache())
{
/* CSWS 1.2/3 look for something non-space outside of quotes */
for (cptr = clptr; *cptr; cptr++)
{
if (isspace(*cptr)) continue;
if (*cptr != '\"') break;
cptr++;
while (*cptr && *cptr != '\"') cptr++;
if (*cptr) cptr++;
}
/* CSWS 1.2/3 if nothing outside of quotes then ignore command line */
if (!*cptr) return;
/* SWS 2.0 doesn't begin with /APACHE from DCL procedure wrapper */
if (!strsame (cptr, "/APACHE", 7)) return;
}
/* if OSU environment then skip P1, P2, P3 */
if (CgiLibEnvironmentIsOsu())
if (getenv ("WWWEXEC_RUNDOWN_STRING") != NULL)
SkipParameters = 3;
else
SkipParameters = 0;
aptr = NULL;
ch = *clptr;
for (;;)
{
if (aptr != NULL) *aptr = '\0';
if (!ch) break;
*clptr = ch;
if (Debug) fprintf (stdout, "clptr |%s|\n", clptr);
while (*clptr && isspace(*clptr)) *clptr++ = '\0';
aptr = clptr;
if (*clptr == '/') clptr++;
while (*clptr && !isspace (*clptr) && *clptr != '/')
{
if (*clptr != '\"')
{
clptr++;
continue;
}
cptr = clptr;
clptr++;
while (*clptr)
{
if (*clptr == '\"')
if (*(clptr+1) == '\"')
clptr++;
else
break;
*cptr++ = *clptr++;
}
*cptr = '\0';
if (*clptr) clptr++;
}
ch = *clptr;
if (*clptr) *clptr = '\0';
if (Debug) fprintf (stdout, "aptr |%s|\n", aptr);
if (!*aptr) continue;
if (SkipParameters)
{
SkipParameters--;
continue;
}
if (strsame (aptr, "/APACHE", 4))
{
/* just skip this marker for command-line parameters under SWS 2.0 */
continue;
}
if (strsame (aptr, "/ADDHTML=", 7))
{
for (cptr = aptr; *cptr && *cptr != '='; cptr++);
if (*cptr) cptr++;
sptr = malloc (strlen(HtmlFileTypesPtr)+strlen(cptr)+2);
strcpy (sptr, HtmlFileTypesPtr);
strcat (sptr, ",");
strcat (sptr, cptr);
HtmlFileTypesPtr = sptr;
continue;
}
if (strsame (aptr, "/ADDTEXT=", 7))
{
for (cptr = aptr; *cptr && *cptr != '='; cptr++);
if (*cptr) cptr++;
sptr = malloc (strlen(TextFileTypesPtr)+strlen(cptr)+2);
strcpy (sptr, TextFileTypesPtr);
strcat (sptr, ",");
strcat (sptr, cptr);
TextFileTypesPtr = sptr;
continue;
}
if (strsame (aptr, "/BUTTONS=", 4))
{
for (cptr = aptr; *cptr && *cptr != '='; cptr++);
if (*cptr) cptr++;
ButtonPtr = cptr;
continue;
}
if (strsame (aptr, "/CHARSET=", 4))
{
for (cptr = aptr; *cptr && *cptr != '='; cptr++);
if (*cptr) cptr++;
CliCharsetPtr = cptr;
continue;
}
if (strsame (aptr, "/DBUG", -1))
{
Debug = true;
continue;
}
if (strsame (aptr, "/ODS5", 5))
{
OdsExtended = true;
continue;
}
if (strsame (aptr, "/NOODS5", 7))
{
OdsExtended = false;
continue;
}
if (strsame (aptr, "/TEXT=", 4))
{
for (cptr = aptr; *cptr && *cptr != '='; cptr++);
if (*cptr) cptr++;
TextFileTypesPtr = cptr;
continue;
}
if (GetPageParameter (aptr)) continue;
if (*aptr != '/')
{
fprintf (stdout, "%%%s-E-MAXPARM, too many parameters\n \\%s\\\n",
Utility, aptr);
exit (STS$K_ERROR | STS$M_INHIB_MSG);
}
else
{
fprintf (stdout, "%%%s-E-IVQUAL, unrecognized qualifier\n \\%s\\\n",
Utility, aptr+1);
exit (STS$K_ERROR | STS$M_INHIB_MSG);
}
}
}
/*****************************************************************************/
/*
Get command-line parameters associated with page scheme.
*/
boolean GetPageParameter (char *aptr)
{
char *cptr;
/*********/
/* begin */
/*********/
if (strsame (aptr, "/PBACKGROUND=", 4))
{
for (cptr = aptr; *cptr && *cptr != '='; cptr++);
if (*cptr) cptr++;
PageScheme[PS_BACKGROUND] = cptr;
return (true);
}
if (strsame (aptr, "/PBGCOLOR=", 4))
{
for (cptr = aptr; *cptr && *cptr != '='; cptr++);
if (*cptr) cptr++;
PageScheme[PS_BGCOLOR] = cptr;
return (true);
}
if (strsame (aptr, "/PBBGCOLOR=", 5))
{
for (cptr = aptr; *cptr && *cptr != '='; cptr++);
if (*cptr) cptr++;
PageScheme[PS_BUTTONBGCOLOR] = cptr;
return (true);
}
if (strsame (aptr, "/PBBORDER=", 5))
{
for (cptr = aptr; *cptr && *cptr != '='; cptr++);
if (*cptr) cptr++;
PageScheme[PS_BUTTONBORDER] = cptr;
return (true);
}
if (strsame (aptr, "/PHBGCOLOR=", 5))
{
for (cptr = aptr; *cptr && *cptr != '='; cptr++);
if (*cptr) cptr++;
PageScheme[PS_HEADBGCOLOR] = cptr;
return (true);
}
if (strsame (aptr, "/PHBORDER=", 5))
{
for (cptr = aptr; *cptr && *cptr != '='; cptr++);
if (*cptr) cptr++;
PageScheme[PS_HEADBORDER] = cptr;
return (true);
}
if (strsame (aptr, "/PHTEXT=", 4))
{
for (cptr = aptr; *cptr && *cptr != '='; cptr++);
if (*cptr) cptr++;
PageScheme[PS_HEADTEXT] = cptr;
return (true);
}
if (strsame (aptr, "/PLAYOUT=", 4))
{
for (cptr = aptr; *cptr && *cptr != '='; cptr++);
if (*cptr) cptr++;
PageScheme[PS_LAYOUT] = cptr;
return (true);
}
if (strsame (aptr, "/PLINK=", 4))
{
for (cptr = aptr; *cptr && *cptr != '='; cptr++);
if (*cptr) cptr++;
PageScheme[PS_LINK] = cptr;
return (true);
}
if (strsame (aptr, "/PHLOCAL=", 4))
{
for (cptr = aptr; *cptr && *cptr != '='; cptr++);
if (*cptr) cptr++;
PageScheme[PS_HEADLOCAL] = cptr;
return (true);
}
if (strsame (aptr, "/PTEXT=", 4))
{
for (cptr = aptr; *cptr && *cptr != '='; cptr++);
if (*cptr) cptr++;
PageScheme[PS_TEXT] = cptr;
return (true);
}
if (strsame (aptr, "/PVLINK=", 4))
{
for (cptr = aptr; *cptr && *cptr != '='; cptr++);
if (*cptr) cptr++;
PageScheme[PS_VLINK] = cptr;
return (true);
}
return (false);
}
/*****************************************************************************/
/*
Set the page layout and colouration.
*/
SetPageScheme ()
{
int size;
char *sptr;
/*********/
/* begin */
/*********/
if (Debug) fprintf (stdout, "SetPageScheme()\n");
if (PageScheme[PS_LAYOUT] == NULL)
PageScheme[PS_LAYOUT] = "1";
if (PageScheme[PS_BACKGROUND] == NULL)
PageScheme[PS_BACKGROUND] = "";
if (PageScheme[PS_HEADLOCAL] == NULL)
PageScheme[PS_HEADLOCAL] = "";
if (PageScheme[PS_LAYOUT][0] == '2')
{
if (PageScheme[PS_BGCOLOR] == NULL) PageScheme[PS_BGCOLOR] = "";
if (PageScheme[PS_TEXT] == NULL) PageScheme[PS_TEXT] = "";
if (PageScheme[PS_LINK] == NULL) PageScheme[PS_LINK] = "";
if (PageScheme[PS_VLINK] == NULL) PageScheme[PS_VLINK] = "";
if (PageScheme[PS_HEADBGCOLOR] == NULL) PageScheme[PS_HEADBGCOLOR] = "";
if (PageScheme[PS_HEADBORDER] == NULL) PageScheme[PS_HEADBORDER] = "";
if (PageScheme[PS_HEADTEXT] == NULL) PageScheme[PS_HEADTEXT] = "";
if (PageScheme[PS_BUTTONBGCOLOR] == NULL) PageScheme[PS_BUTTONBGCOLOR] = "";
if (PageScheme[PS_BUTTONBORDER] == NULL) PageScheme[PS_BUTTONBORDER] = "";
}
else
{
if (PageScheme[PS_BGCOLOR] == NULL)
PageScheme[PS_BGCOLOR] = DEFAULT_PS_BGCOLOR;
if (PageScheme[PS_TEXT] == NULL)
PageScheme[PS_TEXT] = DEFAULT_PS_TEXT;
if (PageScheme[PS_LINK] == NULL)
PageScheme[PS_LINK] = DEFAULT_PS_LINK;
if (PageScheme[PS_VLINK] == NULL)
PageScheme[PS_VLINK] = DEFAULT_PS_VLINK;
if (PageScheme[PS_HEADBGCOLOR] == NULL)
PageScheme[PS_HEADBGCOLOR] = DEFAULT_PS_HEADBGCOLOR;
if (PageScheme[PS_HEADBORDER] == NULL)
PageScheme[PS_HEADBORDER] = DEFAULT_PS_HEADBORDER;
if (PageScheme[PS_HEADTEXT] == NULL)
PageScheme[PS_HEADTEXT] = DEFAULT_PS_HEADTEXT;
if (PageScheme[PS_BUTTONBGCOLOR] == NULL)
PageScheme[PS_BUTTONBGCOLOR] = DEFAULT_PS_BUTTONBGCOLOR;
if (PageScheme[PS_BUTTONBORDER] == NULL)
PageScheme[PS_BUTTONBORDER] = DEFAULT_PS_BUTTONBORDER;
}
/* tag attributes */
size = strlen(PageScheme[PS_BACKGROUND]) +
strlen(PageScheme[PS_BGCOLOR]) +
strlen(PageScheme[PS_TEXT]) +
strlen(PageScheme[PS_LINK]) +
strlen(PageScheme[PS_VLINK]);
if (size)
{
if ((sptr = calloc (1, size+64)) == NULL) exit (vaxc$errno);
PageScheme[PS_BODYTAG] = sptr;
if (PageScheme[PS_BACKGROUND][0])
sptr += sprintf (sptr, " BACKGROUND=\"%s\"", PageScheme[PS_BACKGROUND]);
if (PageScheme[PS_BGCOLOR][0])
sptr += sprintf (sptr, " BGCOLOR=\"%s\"", PageScheme[PS_BGCOLOR]);
if (PageScheme[PS_TEXT][0])
sptr += sprintf (sptr, " TEXT=\"%s\"", PageScheme[PS_TEXT]);
if (PageScheme[PS_LINK][0])
sptr += sprintf (sptr, " LINK=\"%s\"", PageScheme[PS_LINK]);
if (PageScheme[PS_VLINK][0])
sptr += sprintf (sptr, " VLINK=\"%s\"", PageScheme[PS_VLINK]);
}
else
PageScheme[PS_BODYTAG] = "";
if (PageScheme[PS_HEADBGCOLOR][0])
{
if ((sptr = calloc (1, strlen(PageScheme[PS_HEADBGCOLOR])+16)) == NULL)
exit (vaxc$errno);
sprintf (sptr, " BGCOLOR=\"%s\"", PageScheme[PS_HEADBGCOLOR]);
PageScheme[PS_HEADBGCOLOR] = sptr;
PageScheme[PS_HEADPADDING] = "10";
}
else
PageScheme[PS_HEADPADDING] = "0";
if (PageScheme[PS_BUTTONBGCOLOR][0])
{
if ((sptr = calloc (1, strlen(PageScheme[PS_BUTTONBGCOLOR])+16)) == NULL)
exit (vaxc$errno);
sprintf (sptr, " BGCOLOR=\"%s\"", PageScheme[PS_BUTTONBGCOLOR]);
PageScheme[PS_BUTTONBGCOLOR] = sptr;
}
}
/*****************************************************************************/
/*
Modified ButtonBar() for extract. Relies on calling code to set up button
enviroment. This function just creates the buttons. See other script for
information on how this function operates.
*/
ExtractButtonBar ()
{
#define MAX_BUTTON_COUNT 8
static int ButtonCount = -1;
static char *ButtonInternal [MAX_BUTTON_COUNT],
*ButtonLabel [MAX_BUTTON_COUNT],
*ButtonPath [MAX_BUTTON_COUNT];
int idx;
char *PathPtr;
/*********/
/* begin */
/*********/
if (Debug) fprintf (stdout, "ExtractButtonBar()\n");
if (ButtonCount == -1)
{
char *cptr, *sptr;
if (Debug) fprintf (stdout, "|%s|\n", ButtonPtr);
cptr = ButtonPtr;
for (ButtonCount = 0;
ButtonCount < MAX_BUTTON_COUNT && *cptr;
ButtonCount++)
{
for (sptr = cptr; *sptr && *sptr != '=' && *sptr != ';'; sptr++)
if (*sptr == '\\') memcpy (sptr, sptr+1, strlen(sptr));
if (*sptr == '=') *sptr++ = '\0';
ButtonLabel[ButtonCount] = cptr;
cptr = sptr;
for (sptr = cptr; *sptr && *sptr != ';'; sptr++)
if (*sptr == '\\') memcpy (sptr, sptr+1, strlen(sptr));
if (*sptr) *sptr++ = '\0';
ButtonPath[ButtonCount] = cptr;
cptr = sptr;
}
}
if (PageScheme[PS_LAYOUT][0] == '2')
{
/************/
/* format 2 */
/************/
for (idx = 0; idx < ButtonCount; idx++)
{
if (ButtonInternal[idx] == NULL)
PathPtr = ButtonPath[idx];
else
PathPtr = ButtonInternal[idx];
if (PathPtr[0])
fprintf (stdout, "[%s]\n",
PathPtr, ButtonLabel[idx]);
else
fprintf (stdout, "[%s]\n", ButtonLabel[idx]);
}
return;
}
else
{
/************/
/* format 1 */
/************/
for (idx = 0; idx < ButtonCount; idx++)
{
if (ButtonInternal[idx] == NULL)
PathPtr = ButtonPath[idx];
else
PathPtr = ButtonInternal[idx];
if (PathPtr[0])
fprintf (stdout,
"\
%s | \n",
PageScheme[PS_BUTTONBGCOLOR], PathPtr, ButtonLabel[idx]);
else
fprintf (stdout,
"\
%s | \n",
PageScheme[PS_BUTTONBGCOLOR], ButtonLabel[idx]);
}
}
}
/*****************************************************************************/
/*
Extract the specified record (line) range from a plain-text file. If the
search string is supplied then highlight the first matched string in any line.
*/
int ExtractTextFile
(
char *FileName,
char *HighlightString,
int StartRecordNumber,
int EndRecordNumber,
boolean CaseSensitive
)
{
int status,
NumberOfRecords,
RecordNumber = 0,
HighlightStringLength = 0;
char *rptr, *sptr;
char EscapedPath [ODS_MAX_FILE_NAME_LENGTH+1],
ExpFileName [ODS_MAX_FILE_NAME_LENGTH+1],
Record [MAX_RECORD_SIZE+1],
String [MAX_RECORD_SIZE*2],
UrlEncodedHighlightString [256] = "";
struct FAB FileFab;
struct RAB FileRab;
#ifdef ODS_EXTENDED
struct NAML FileNaml;
#endif /* ODS_EXTENDED */
struct NAM FileNam;
/*********/
/* begin */
/*********/
if (Debug)
fprintf (stdout, "ExtractTextFile() |%s|%s|\n",
FileName, HighlightString);
if (EndRecordNumber > StartRecordNumber)
NumberOfRecords = EndRecordNumber - StartRecordNumber;
else
NumberOfRecords = 0;
if (HighlightString[0])
{
HighlightStringLength = strlen(HighlightString);
CgiLibUrlEncode (HighlightString, -1, UrlEncodedHighlightString, -1);
}
FileFab = cc$rms_fab;
FileFab.fab$b_fac = FAB$M_GET;
FileFab.fab$b_shr = FAB$M_SHRGET;
#ifdef ODS_EXTENDED
if (OdsExtended)
{
FileFab.fab$l_fna = (char*)-1;
FileFab.fab$b_fns = 0;
FileFab.fab$l_nam = (struct namdef*)&FileNaml;
ENAMEL_RMS_NAML(FileNaml)
FileNaml.naml$l_long_filename = FileName;
FileNaml.naml$l_long_filename_size = strlen(FileName);
FileNaml.naml$l_long_expand = ExpFileName;
FileNaml.naml$l_long_expand_alloc = sizeof(ExpFileName)-1;
}
else
#endif /* ODS_EXTENDED */
{
FileFab.fab$l_fna = FileName;
FileFab.fab$b_fns = strlen(FileName);
FileFab.fab$l_nam = &FileNam;
FileNam = cc$rms_nam;
FileNam.nam$l_esa = ExpFileName;
FileNam.nam$b_ess = ODS2_MAX_FILE_NAME_LENGTH;
}
if (VMSnok (status = sys$open (&FileFab, 0, 0)))
{
/* if its a search list treat directory not found as if file not found */
#ifdef ODS_EXTENDED
if (OdsExtended)
{
if ((FileNaml.naml$l_fnb & NAM$M_SEARCH_LIST) && status == RMS$_DNF)
status = RMS$_FNF;
}
else
#endif /* ODS_EXTENDED */
{
if ((FileNam.nam$l_fnb & NAM$M_SEARCH_LIST) && status == RMS$_DNF)
status = RMS$_FNF;
}
if (Debug) fprintf (stdout, "sys$open() %%X%08.08X\n", status);
return (status);
}
#ifdef ODS_EXTENDED
if (OdsExtended)
{
/* if explicit version number display in VMS extended file syntax */
if (FormatLikeVms)
UrlEncodedCgiPathInfoPtr =
(char*)CgiLibHtmlEscape (CgiPathInfoPtr, -1, NULL, -1);
}
#endif /* ODS_EXTENDED */
FileRab = cc$rms_rab;
FileRab.rab$l_fab = &FileFab;
/* 2 buffers and read ahead performance option */
FileRab.rab$b_mbf = 2;
FileRab.rab$l_rop = RAB$M_RAH;
FileRab.rab$l_ubf = Record;
FileRab.rab$w_usz = sizeof(Record)-1;
if (VMSnok (status = sys$connect (&FileRab, 0, 0)))
{
if (Debug) fprintf (stdout, "sys$connect() %%X%08.08X\n", status);
sys$close (&FileFab, 0, 0);
return (status);
}
/*******************/
/* extract records */
/*******************/
while (VMSok (status = sys$get (&FileRab, 0, 0)))
{
RecordNumber++;
Record[FileRab.rab$w_rsz] = '\0';
if (Debug) fprintf (stdout, "Record |%d|%s|\n", RecordNumber, Record);
/* terminate at any carriage control that may be in the record */
for (rptr = Record; *rptr && *rptr != '\r' && *rptr != '\n'; rptr++);
*rptr = '\0';
if (StartRecordNumber && RecordNumber < StartRecordNumber) continue;
if (!ThereHasBeenOutput && !Record[0]) continue;
if (!ThereHasBeenOutput)
{
/**************/
/* begin page */
/**************/
if (FormatLikeVms)
CgiLibHtmlEscape (CgiPathTranslatedPtr, -1,
EscapedPath, sizeof(EscapedPath));
else
CgiLibHtmlEscape (CgiPathInfoPtr, -1,
EscapedPath, sizeof(EscapedPath));
CgiLibResponseHeader (200, "text/html");
fprintf (stdout,
"\n\
\n\
\n\
\n\
\n\
\n\
Extract ... %s\n\
\n\
\n",
SoftwareID,
CgiEnvironmentPtr,
TextFileTypesPtr,
HtmlFileTypesPtr,
EscapedPath,
PageScheme[PS_BODYTAG]);
if (PageScheme[PS_LAYOUT][0] == '2')
{
fprintf (stdout,
"%s\n\
%s\n\
\n\
\
\n\
*WASDextract\n\
\n",
PageScheme[PS_HEADLOCAL],
EscapedPath);
}
else
{
fprintf (stdout,
"\n\
\n\
\n\
%s\n\
\n\
\
\n\
*WASDextract\n\
\n\
| %s
\n\
\n",
PageScheme[PS_HEADBORDER],
PageScheme[PS_HEADPADDING],
PageScheme[PS_HEADBGCOLOR],
PageScheme[PS_HEADTEXT],
EscapedPath,
PageScheme[PS_HEADTEXT],
PageScheme[PS_HEADLOCAL]);
}
/******************/
/* top button bar */
/******************/
if (PageScheme[PS_LAYOUT][0] == '2')
{
fprintf (stdout, "\n[");
}
else
{
fprintf (stdout,
"\n\
\n\
\n\
\n\
\n\
",
PageScheme[PS_HEADBORDER],
PageScheme[PS_HEADBORDER],
PageScheme[PS_HEADBGCOLOR],
PageScheme[PS_BUTTONBORDER],
PageScheme[PS_BUTTONBGCOLOR]);
}
if (StartRecordNumber)
{
if (EndRecordNumber && StartRecordNumber - NumberOfRecords > 0)
{
fprintf (stdout,
"begins at line %d, retrieve \
previous %d lines or \
entire document \
or file",
StartRecordNumber,
CgiScriptNamePtr,
UrlEncodedCgiPathInfoPtr,
UrlEncodedHighlightString,
StartRecordNumber-NumberOfRecords-1,
StartRecordNumber-1,
NumberOfRecords+1,
CgiScriptNamePtr,
UrlEncodedCgiPathInfoPtr,
UrlEncodedHighlightString,
UrlEncodedCgiPathInfoPtr);
}
else
{
fprintf (stdout,
"begins at line %d, retrieve \
entire document \
or file",
RecordNumber,
CgiScriptNamePtr,
UrlEncodedCgiPathInfoPtr,
UrlEncodedHighlightString,
UrlEncodedCgiPathInfoPtr);
}
}
else
{
if (EndRecordNumber)
{
fprintf (stdout,
"begins at line %d (start of document), retrieve \
entire document \
or file",
RecordNumber,
CgiScriptNamePtr,
UrlEncodedCgiPathInfoPtr,
UrlEncodedHighlightString,
UrlEncodedCgiPathInfoPtr);
}
else
fprintf (stdout,
"entire document, retrieve file",
UrlEncodedCgiPathInfoPtr);
}
if (PageScheme[PS_LAYOUT][0] == '2')
fprintf (stdout, "]\n");
else
fprintf (stdout, " | \n");
ExtractButtonBar ();
if (PageScheme[PS_LAYOUT][0] == '2')
{
fprintf (stdout,
"\n\
\n\
");
}
else
{
fprintf (stdout,
" \n\
\n\
|
\n\
\n\
");
}
fflush (stdout);
ThereHasBeenOutput = true;
}
/******************/
/* process record */
/******************/
if (EndRecordNumber && RecordNumber > EndRecordNumber)
{
if (CgiFormExactPtr[0] == 'T' || CgiFormExactPtr[0] == 'Y') break;
/* if this is an empty (blank) line then end-of-section */
if (!FileRab.rab$w_rsz) break;
/* if there is only white-space in this line then end-of-section */
for (rptr = Record; *rptr && isspace(*rptr); rptr++);
if (!*rptr) break;
}
rptr = SearchTextString (Record, HighlightString,
CaseSensitive, true, NULL);
if (rptr != NULL)
{
/***********************************/
/* hit! - Highlight matched string */
/***********************************/
sptr = String;
/* copy the record up to the first character of the search string */
sptr += CgiLibHtmlEscape (Record, rptr-Record, sptr, -1);
/* emphasize the matched search string */
strcpy (sptr, ""); sptr += 3;
sptr += CgiLibHtmlEscape (rptr, HighlightStringLength, sptr, -1);
strcpy (sptr, ""); sptr += 4;
/* rest of record after the matched search string */
sptr += CgiLibHtmlEscape (rptr+HighlightStringLength, -1, sptr, -1);
*sptr++ = '\n'; *sptr = '\0';
}
else
{
/**********/
/* no hit */
/**********/
sptr = String;
sptr += CgiLibHtmlEscape (Record, -1, sptr, -1);
*sptr++ = '\n'; *sptr = '\0';
}
if (Debug) fprintf (stdout, "String |%s|\n", String);
fputs (String, stdout);
}
/***************/
/* end of file */
/***************/
if (status == RMS$_EOF) status = SS$_NORMAL;
sys$close (&FileFab, 0, 0);
/*********************/
/* bottom button bar */
/*********************/
fprintf (stdout, "
\n");
if (PageScheme[PS_LAYOUT][0] == '2')
{
fprintf (stdout,
"
\n\
[");
}
else
{
fprintf (stdout,
"\n\
\n\
\n\
\n\
",
PageScheme[PS_HEADBORDER],
PageScheme[PS_HEADBORDER],
PageScheme[PS_HEADBGCOLOR],
PageScheme[PS_BUTTONBORDER],
PageScheme[PS_BUTTONBGCOLOR]);
}
if (StartRecordNumber)
{
if (EndRecordNumber && RecordNumber > EndRecordNumber)
{
fprintf (stdout,
"ends at line %d, \
retrieve next %d lines or \
rest of document \
or file",
RecordNumber-1,
CgiScriptNamePtr,
UrlEncodedCgiPathInfoPtr,
UrlEncodedHighlightString,
RecordNumber,
RecordNumber+NumberOfRecords,
NumberOfRecords+1,
CgiScriptNamePtr,
UrlEncodedCgiPathInfoPtr,
UrlEncodedHighlightString,
RecordNumber,
UrlEncodedCgiPathInfoPtr);
}
else
{
fprintf (stdout,
"ends at line %d (end of document), \
retrieve entire document \
or file",
RecordNumber,
CgiScriptNamePtr,
UrlEncodedCgiPathInfoPtr,
UrlEncodedHighlightString,
UrlEncodedCgiPathInfoPtr);
}
}
else
fprintf (stdout, "entire document, retrieve file",
UrlEncodedCgiPathInfoPtr);
if (PageScheme[PS_LAYOUT][0] == '2')
fprintf (stdout, "]\n");
else
fprintf (stdout, " | \n");
ExtractButtonBar ();
if (PageScheme[PS_LAYOUT][0] == '2')
fprintf (stdout, "\n");
else
{
fprintf (stdout,
" \n\
\n\
|
\n\
\n");
}
fprintf (stdout, "\n\n");
return (status);
}
/*****************************************************************************/
/*
Add an HTML anchor around each highlight string corresonding to the hit number
displayed by query (blah). Due to the way the search
string is located within the HTML tags (by masking them out) it is possible
that search strings containg HTML entities may not be correctly found by this
function. The incidence of this should be quite low so abosulute accuracy has
been sacrificed to ease (and speed) in programming it.
*/
int AnchorHtmlFile
(
char *FileName,
char *HighlightString,
boolean CaseSensitive
)
{
boolean InsideApplet = false,
InsideComment = false,
InsideHead = false,
InsideScript = false,
InsideServer = false,
InsideStyle = false,
InsideTitle = false;
int status,
HighlightStringLength = 0,
HitCount = 0,
TagCharCount = 0;
char ch;
char *cptr, *rptr, *sptr, *tptr;
char ExpFileName [ODS_MAX_FILE_NAME_LENGTH+1],
Record [MAX_RECORD_SIZE+1],
String [MAX_RECORD_SIZE*2],
Text [MAX_RECORD_SIZE*2],
UrlEncodedHighlightString [256] = "";
struct FAB FileFab;
struct RAB FileRab;
#ifdef ODS_EXTENDED
struct NAML FileNaml;
#endif /* ODS_EXTENDED */
struct NAM FileNam;
/*********/
/* begin */
/*********/
if (Debug)
fprintf (stdout, "AnchorHtmlFile() |%s|%s|\n",
FileName, HighlightString);
if (HighlightString[0])
{
HighlightStringLength = strlen(HighlightString);
CgiLibUrlEncode (HighlightString, -1, UrlEncodedHighlightString, -1);
}
FileFab = cc$rms_fab;
FileFab.fab$b_fac = FAB$M_GET;
FileFab.fab$b_shr = FAB$M_SHRGET;
#ifdef ODS_EXTENDED
if (OdsExtended)
{
FileFab.fab$l_fna = (char*)-1;
FileFab.fab$b_fns = 0;
FileFab.fab$l_nam = (struct namdef*)&FileNaml;
ENAMEL_RMS_NAML(FileNaml)
FileNaml.naml$l_long_filename = FileName;
FileNaml.naml$l_long_filename_size = strlen(FileName);
FileNaml.naml$l_long_expand = ExpFileName;
FileNaml.naml$l_long_expand_alloc = sizeof(ExpFileName)-1;
}
else
#endif /* ODS_EXTENDED */
{
FileFab.fab$l_fna = FileName;
FileFab.fab$b_fns = strlen(FileName);
FileFab.fab$l_nam = &FileNam;
FileNam = cc$rms_nam;
FileNam.nam$l_esa = ExpFileName;
FileNam.nam$b_ess = ODS2_MAX_FILE_NAME_LENGTH;
}
if (VMSnok (status = sys$open (&FileFab, 0, 0)))
{
/* if its a search list treat directory not found as if file not found */
#ifdef ODS_EXTENDED
if (OdsExtended)
{
if ((FileNaml.naml$l_fnb & NAM$M_SEARCH_LIST) && status == RMS$_DNF)
status = RMS$_FNF;
}
else
#endif /* ODS_EXTENDED */
{
if ((FileNam.nam$l_fnb & NAM$M_SEARCH_LIST) && status == RMS$_DNF)
status = RMS$_FNF;
}
if (Debug) fprintf (stdout, "sys$open() %%X%08.08X\n", status);
return (status);
}
#ifdef ODS_EXTENDED
if (OdsExtended)
{
/* if explicit version number display in VMS extended file syntax */
if (FormatLikeVms)
UrlEncodedCgiPathInfoPtr =
(char*)CgiLibHtmlEscape (CgiPathInfoPtr, -1, NULL, -1);
}
#endif /* ODS_EXTENDED */
FileRab = cc$rms_rab;
FileRab.rab$l_fab = &FileFab;
/* 2 buffers and read ahead performance option */
FileRab.rab$b_mbf = 2;
FileRab.rab$l_rop = RAB$M_RAH;
FileRab.rab$l_ubf = Record;
FileRab.rab$w_usz = sizeof(Record)-1;
if (VMSnok (status = sys$connect (&FileRab, 0, 0)))
{
if (Debug) fprintf (stdout, "sys$connect() %%X%08.08X\n", status);
sys$close (&FileFab, 0, 0);
return (status);
}
/*******************/
/* extract records */
/*******************/
while (VMSok (status = sys$get (&FileRab, 0, 0)))
{
Record[FileRab.rab$w_rsz] = '\0';
if (Debug) fprintf (stdout, "Record |%s|\n", Record);
/* terminate at any carriage control that may be in the record */
for (rptr = Record; *rptr && *rptr != '\r' && *rptr != '\n'; rptr++);
/* add a single new-line carriage-control */
*rptr++ = '\n';
*rptr = '\0';
if (!ThereHasBeenOutput)
{
/**************/
/* begin page */
/**************/
CgiLibResponseHeader (200, "text/html");
fprintf (stdout, "\n", SoftwareID);
ThereHasBeenOutput = true;
}
/**************************************/
/* retrieve text not inside HTML tags */
/**************************************/
tptr = Text;
rptr = Record;
while (*rptr)
{
if (InsideComment)
{
if (rptr[0] == '-' && rptr[1] == '-' && rptr[2] == '>')
{
InsideComment = false;
memset (tptr, MASK_TAG_CHAR, 3);
tptr += 3;
rptr += 3;
TagCharCount++;
}
else
{
*tptr++ = MASK_TAG_CHAR;
rptr++;
}
continue;
}
if (*((USHORTPTR)rptr) == '')
{
if (InsideApplet)
{
if (strsame (rptr, "", 9))
{
InsideApplet = false;
memset (tptr, MASK_TAG_CHAR, 9);
tptr += 9;
rptr += 9;
continue;
}
}
if (InsideHead)
{
if (strsame (rptr, "", 7))
{
InsideHead = false;
memset (tptr, MASK_TAG_CHAR, 7);
tptr += 7;
rptr += 7;
continue;
}
}
if (InsideScript)
{
if (strsame (rptr, "", 9))
{
InsideScript = false;
memset (tptr, MASK_TAG_CHAR, 9);
tptr += 9;
rptr += 9;
continue;
}
}
if (InsideServer)
{
if (strsame (rptr, "", 9))
{
InsideServer = false;
memset (tptr, MASK_TAG_CHAR, 9);
tptr += 9;
rptr += 9;
continue;
}
}
if (InsideStyle)
{
if (strsame (rptr, "", 7))
{
InsideStyle = false;
memset (tptr, MASK_TAG_CHAR, 7);
tptr += 7;
rptr += 7;
continue;
}
}
if (InsideTitle)
{
if (strsame (rptr, "", 7))
{
InsideTitle = false;
memset (tptr, MASK_TAG_CHAR, 7);
tptr += 7;
rptr += 7;
continue;
}
}
}
if (*rptr == '<')
{
if (*((ULONGPTR)rptr) == '\n", SoftwareID);
return (status);
}
/*****************************************************************************/
/*
This function accepts a comma-separated list of (possibly wildcarded) file
types (extensions, e.g. "TXT,TEXT,COM,C,PAS,FOR,RPT*") and a VMS file type
(e.g. ".TXT;", ".TXT", "TXT"). It returns true if the file type is in the list,
false if not.
*/
boolean SameFileType
(
char *TypeList,
char *FileType
)
{
char ch;
char *cptr, *sptr;
/*********/
/* begin */
/*********/
if (Debug) fprintf (stdout, "SameFileType() |%s|%s|\n", FileType, TypeList);
cptr = TypeList;
while (*cptr)
{
for (sptr = cptr; *sptr && *sptr != ','; sptr++);
ch = *sptr;
*sptr = '\0';
if (Debug) fprintf (stdout, "|%s|%s|\n", FileType, cptr);
if ((SearchTextString (FileType, cptr, false, false, NULL)) != NULL)
{
*sptr = ch;
return (true);
}
if (*sptr = ch) sptr++;
cptr = sptr;
}
return (false);
}
/*****************************************************************************/
/*
String search allowing wildcard "*" (matching any multiple characters) and "%"
(matching any single character). Returns NULL if not found or a pointer to
start of matched string. Setting 'ImpliedWildcards' means the 'SearchFor'
string is processed as if enclosed by '*' wildcard characters.
*/
char* SearchTextString
(
char *SearchIn,
char *SearchFor,
boolean CaseSensitive,
boolean ImpliedWildcards,
int *MatchedLengthPtr
)
{
char *cptr, *sptr, *inptr,
*RestartCptr,
*RestartInptr,
*MatchPtr;
/*********/
/* begin */
/*********/
if (Debug)
fprintf (stdout, "SearchTextString() |%s|%s|\n", SearchIn, SearchFor);
if (MatchedLengthPtr != NULL) *MatchedLengthPtr = 0;
if (!*(cptr = SearchFor)) return (NULL);
inptr = MatchPtr = SearchIn;
if (ImpliedWildcards)
{
/* skip leading text up to first matching character (if any!) */
if (*cptr != '*' && *cptr != '%')
{
if (CaseSensitive)
while (*inptr && *inptr != *cptr) inptr++;
else
while (*inptr && toupper(*inptr) != toupper(*cptr)) inptr++;
if (Debug && !*inptr) fprintf (stdout, "1. NOT matched!\n");
if (!*inptr) return (NULL);
cptr++;
MatchPtr = inptr++;
}
}
for (;;)
{
if (CaseSensitive)
{
while (*cptr && *inptr && *cptr == *inptr)
{
cptr++;
inptr++;
}
}
else
{
while (*cptr && *inptr && toupper(*cptr) == toupper(*inptr))
{
cptr++;
inptr++;
}
}
if (ImpliedWildcards)
{
if (!*cptr)
{
if (Debug) fprintf (stdout, "1. matched!\n");
if (MatchedLengthPtr != NULL) *MatchedLengthPtr = inptr - MatchPtr;
return (MatchPtr);
}
}
else
{
if (!*cptr && !*inptr)
{
if (Debug) fprintf (stdout, "2. matched!\n");
if (MatchedLengthPtr != NULL) *MatchedLengthPtr = inptr - MatchPtr;
return (MatchPtr);
}
if (*cptr != '*' && *cptr != '%')
{
if (Debug && !*inptr) fprintf (stdout, "3. NOT matched!\n");
return (NULL);
}
}
if (*cptr != '*' && *cptr != '%')
{
if (!*inptr)
{
if (Debug) fprintf (stdout, "4. NOT matched!\n");
return (NULL);
}
cptr = SearchFor;
MatchPtr = ++inptr;
continue;
}
if (*cptr == '%')
{
/* single char wildcard processing */
if (!*inptr) break;
cptr++;
inptr++;
continue;
}
/* asterisk wildcard matching */
while (*cptr == '*') cptr++;
/* an asterisk wildcard at end matches all following */
if (!*cptr)
{
if (Debug) fprintf (stdout, "5. matched!\n");
while (*inptr) inptr++;
if (MatchedLengthPtr != NULL) *MatchedLengthPtr = inptr - MatchPtr;
return (MatchPtr);
}
/* note the current position in the string (first after the wildcard) */
RestartCptr = cptr;
for (;;)
{
/* find first char in SearchIn matching char after wildcard */
if (CaseSensitive)
while (*inptr && *cptr != *inptr) inptr++;
else
while (*inptr && toupper(*cptr) != toupper(*inptr)) inptr++;
/* if did not find matching char in SearchIn being searched */
if (Debug && !*inptr) fprintf (stdout, "6. NOT matched!\n");
if (!*inptr) return (NULL);
/* note the current position in SearchIn being searched */
RestartInptr = inptr;
/* try to match the remainder of the string and SearchIn */
if (CaseSensitive)
{
while (*cptr && *inptr && *cptr == *inptr)
{
cptr++;
inptr++;
}
}
else
{
while (*cptr && *inptr && toupper(*cptr) == toupper(*inptr))
{
cptr++;
inptr++;
}
}
/* if reached the end of both string and SearchIn - match! */
if (ImpliedWildcards)
{
if (!*cptr)
{
if (Debug) fprintf (stdout, "7. matched!\n");
if (MatchedLengthPtr != NULL)
*MatchedLengthPtr = inptr - MatchPtr;
return (MatchPtr);
}
}
else
{
if (!*cptr && !*inptr)
{
if (Debug) fprintf (stdout, "8. matched!\n");
if (MatchedLengthPtr != NULL)
*MatchedLengthPtr = inptr - MatchPtr;
return (MatchPtr);
}
}
/* break to the external loop if we encounter another wildcard */
if (*cptr == '*' || *cptr == '%') break;
/* lets have another go */
cptr = RestartCptr;
/* starting the character following the previous attempt */
inptr = MatchPtr = RestartInptr + 1;
}
}
}
/****************************************************************************/
/*
Return an integer reflecting the major and minor version of VMS (e.g. 60, 61,
62, 70, 71, 72, etc.)
*/
#ifdef ODS_EXTENDED
int GetVmsVersion ()
{
static char SyiVersion [16];
static struct {
short int buf_len;
short int item;
void *buf_addr;
unsigned short *ret_len;
}
SyiItems [] =
{
{ 8, SYI$_VERSION, &SyiVersion, 0 },
{ 0,0,0,0 }
};
int status,
version;
/*********/
/* begin */
/*********/
if (Debug) fprintf (stdout, "GetVmsVersion()\n");
if (VMSnok (status = sys$getsyiw (0, 0, 0, &SyiItems, 0, 0, 0)))
exit (status);
SyiVersion[8] = '\0';
version = ((SyiVersion[1]-48) * 10) + (SyiVersion[3]-48);
if (Debug) fprintf (stdout, "|%s| %d\n", SyiVersion, version);
return (version);
}
#endif /* ODS_EXTENDED */
/****************************************************************************/
/*
Does a case-insensitive, character-by-character string compare and returns
true if two strings are the same, or false if not. If a maximum number of
characters are specified only those will be compared, if the entire strings
should be compared then specify the number of characters as 0.
*/
boolean strsame
(
char *sptr1,
char *sptr2,
int count
)
{
while (*sptr1 && *sptr2)
{
if (toupper (*sptr1++) != toupper (*sptr2++)) return (false);
if (count)
if (!--count) return (true);
}
if (*sptr1 || *sptr2)
return (false);
else
return (true);
}
/****************************************************************************/