\n",
RecordNumber-1,
CgiScriptNamePtr,
UrlEncodedPathInfoPtr,
UrlEncodedHighlightString,
RecordNumber,
RecordNumber+NumberOfRecords,
UrlEncodedRequeryPtr,
NumberOfRecords+1,
CgiScriptNamePtr,
UrlEncodedPathInfoPtr,
UrlEncodedHighlightString,
RecordNumber,
UrlEncodedRequeryPtr,
UrlEncodedPathInfoPtr);
}
else
{
fprintf (stdout,
"
\n\
\n",
RecordNumber,
CgiScriptNamePtr,
UrlEncodedPathInfoPtr,
UrlEncodedHighlightString,
UrlEncodedRequeryPtr,
UrlEncodedPathInfoPtr);
}
}
else
fprintf (stdout, "
\n",
CgiFormRequeryPtr[0] ? "href=" : "blah=",
CgiFormRequeryPtr,
AboutPathPtr);
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,
BOOL CaseSensitive
)
{
BOOL 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)
UrlEncodedPathInfoPtr = (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");
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, "", 8))
{
InsideStyle = false;
memset (tptr, MASK_TAG_CHAR, 8);
tptr += 8;
rptr += 8;
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.
*/
BOOL 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,
BOOL CaseSensitive,
BOOL 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.
*/
BOOL 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);
}
/****************************************************************************/