home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 35 Internet
/
35-Internet.zip
/
goswish5.zip
/
GOSWISH.CMD
< prev
next >
Wrap
OS/2 REXX Batch file
|
1999-06-08
|
127KB
|
4,131 lines
/* 8 June 1999: The GoSWISH front end to the SWISH search engine, ver 1.48
GOSWISH can be called in a number of different manners:
a) As a cgi-bin script, or sre-http addon, to create a
swish index
b) Called as a Detached program, in order to create a
description cache
c) As a cgi-bin script (or sre-http addon) to search a swish index
(and possibly a description cache)
d) As a cgi-bin script (or sre-http addon) to display list of current
"search forms" (stored in goswish.ind)
Regardless of how you use it .... you'll need to set a few parameters below
(the same settings are use in all modes).
*/
/********************* BEGIN USER CONFIGURABLE PARAMETERS ***************/
/* If you do not set these parameters (i.e.; set them =""); then
defaults will be used. These defaults will make some sense if
you run this as an sre-http addon, but will probably be
barely tolerable if you run this as a cgi-bin script.
*/
/* SWISH_DIR should be the fully qualified name of the directory
used for storing SWISH Index Files. It should also contain SWISH.EXE
(or, SWISH should be in your PATH).
If called as an SRE-http addon, the default is the SRE-http DATA directory.
If called as CGI-BIN, the default is the current directory (which is probably
inappropriate).
*/
SWISH_DIR='swish_directory'
/* WEB_ROOT_DIR is the root of your web directories.
If called as an SRE-http addon, the default is the GoServe data directory.
If called as CGI-BIN, the default is the current directory (which is probably
inappropriate).
*/
WEB_ROOT_DIR='web_root_directory'
/* SRE-http option (only used if GOSWISH is run under the SRE-http server):
NEED_PRIVS is a set of "privileges" that permit creation of a swish
index. That is, to create a swish index, the client must have ONE
of these privileges (not all of, but at least one of).
If she doesn't have one of these
privileges, an authorization request will be returned.
If this is called as a cgi-bin script, NEED_PRIVS is ignored.
If need_privs contains an *, then need_privs is ignored (open access)
*/
need_privs='*'
/* Swish version:
Identifies the version of swish you are using
11 == version 1.1
12 == version 1.2
13 == version 1.3
13_DLL = use rxSWISH DLL
*/
swish_version='13'
/* how to display links to "other matches" (i.e. 1-20, 20-40, etc.)
If all_sets=0, then just show link to prior and next set.
If all_sets=1, then show numbers (1 2 3 ... ) linking to
1st, 2nd, etc. sets.
This is only used when the START=0 1 option is used when first invoking
the GoSWISH search mode */
all_sets=1
/* Add a modifier to process execution commands. This can be used
with SPE, and other programs, to lower the priority of the submission
Set to 0, or '', if you don't want to do this "priority modification"
For example, the freeware SPE package can use used to execute programs
using a given priority; with a syntax of SPE i-20 file.cmd opt1 opt2.
In this example, EXEC_MODIFIER would be 'SPE i-20 ', and you should
have a copy of SPE.EXE in your PATH.
*/
exec_modifier=' '
/* Add hit number to matches (i.e.; 1).... 20) )
Set to 1 to enable, 0 to disable */
Add_Hit_Num=1
/* Suppress writing the "Tips" section in the "search form"
NO_TIPS=1 : suppress
NO_TIPS=0 : do NOT suppress
*/
no_tips=0
/* ovewrite=1 means "overwrite files",0 means "use new name"
This can be overridden by an OVERWRITE=1 or OVERWRITE=2 (2=no) request option */
overwrite=1
/* DEF_HTMLS is used to identify extensions used for HTML documents.
This is ONLY used when summaries are being created "on the fly". At
other times, parameters in the configuration file are used */
def_Htmls="SHT SHTML HTM HTML HTM-SSI HTML-SSI"
/* CGI_STRING is the "prefix" for cgi-bin scripts. If blank, then
/cgi-bin/ is used. This is used in "description regeneration" lists */
cgi_string=''
/********************** END of USER CONFIGURABLE PARAMETERS ****************/
goswish:
parse arg ddir, tempfile, reqstrg,list,verb ,uri,user, ,
basedir ,workdir,privset,enmadd,transaction,verbose, ,
servername,host_nickname,homedir,xx,semqueue,prog_file
signal on error name foo10 ; signal on syntax name foo10
call load_dll /* load some dlls */
crlf='0d0a'x
if abbrev(strip(ddir),'*DESCRIBE')=1 then do
verb='DESCRIBE'
parse var ddir . daswishdir dawwwdir daswifile ','dafdescribe','darepwith','datype','dasummfile
end /* do */
if WEB_ROOT_DIR=0 then WEB_ROOT_DIR="" /* double check directories */
if SWISH_DIR=0 then SWISH_DIR=""
privset=translate(privset)
if exec_modifiler=0 then exec_modifier=''
use_swish_dll=0
if translate(swish_version)="13_DLL" then do
swish_version=13
use_swish_dll=1
end
/*
Check for CGI-BIN call */
is_cgi=0
if verb="" then do /* is it cgi-bin? */
method = value("REQUEST_METHOD",,'os2environment')
if method="" then do
say "This script is not meant to be run in standalone mode "
exit
end /* Do */
else do
is_cgi=1
if method='GET' then do
list=value("QUERY_STRING",,'os2environment')
end
else do
tlen = value("CONTENT_LENGTH",,'os2environment')
list=charin(,,tlen)
end /* do */
servername=value("SERVER_NAME",,'os2environment')
end
if WEB_ROOT_DIR='' then WEB_ROOT_DIR=directory()
if SWISH_DIR='' then SWISH_DIR=directory()
prog_file=''
end
list0=list /* used by search_it et al */
/* clear up directory names */
SWISH_DIR=strip(translate(SWISH_DIR,'\','/'),'t','\')
okk=dir_exists(SWISH_DIR)
if okk=0 then do
foo=is_error(' Sorry, bad index directory: 'SWISH_DIR)
exit
end /* do */
WEB_ROOT_DIR=strip(WEB_ROOT_DIR,'t','\')
okk=dir_exists(WEB_ROOT_DIR)
if okk=0 then do
foo=is_error(' Sorry, bad www directory: 'WEB_ROOT_DIR)
exit
end /* do */
/* set defaults */
deflist='sel swifile repwith indexname indexadmin indexdescription indexpointer ',
'extlist extlist_nofollow ignorelimit ignorewords file mode summaryfile ',
' makesummary filename describefile htmls dostem propnames metanames ',
'fr_directory fr_title fr_filename fr_pathname watch searchdoc dctfile ' ,
'FORM_TITLE RESULTS_TITLE indexcomments showprop swishversion overwrite '
deflist=translate(deflist)
vs.!verbose=3
vs.!wwwdir=WEB_ROOT_DIR /* NOTE: wwwdir request option no longer supported */
vs.!FORM_TITLE=''
vs.!RESULTS_TITLE=''
vs.!sel='/'
vs.!showprop=''
vs.!indexcomments=0
vs.!overwrite=overwrite
vs.!searchdoc=''
vs.!dctfile=''
vs.!summaryfile=''
vs.!dostem=0
vs.!propnames=0
vs.!metanames=0
vs.!repwith=0
vs.!watch=1
vs.!indexname=0
vs.!indexdescription=0
vs.!indexadmin='Created by 'user
vs.!indexpointer=servername
vs.!makesummary=0
vs.!swishversion=swish_version
vs.!swifile=''
vs.!extlist='.htm .txt .gif .xbm .jpg .doc .sht .html .shtml '
vs.!extlist_nofollow=' .gif .xbm .jpg '
vs.!ignorelimit='50 100'
vs.!ignorewords='SwishDefault'
vs.!fr_pathname='contains admin testing demo trash construction PRIVATE private confidential '
vs.!fr_filename='contains # % ~ .bak .orig .old old. '
vs.!fr_title='contains construction example pointers '
vs.!fr_directory='contains .htaccess'
vs.!htmls=" HTM HTML SHTML SHT "
vs.!describefile='DESCRIBE.TXT'
/* parse options, and load them into the "VS." stem variable */
do until list=""
parse var list aw '&' list
parse var aw a1 '=' a2
a1=translate(strip(a1))
if wordpos(a1,deflist)=0 then iterate /* not a valid option */
aa='!'||a1
a2=strip(decodekeyval(translate(a2,' ','+'||'00090a0d'x)))
if a2="" | a2=0 then iterate /* blank, don't change */
vs.aa=a2
end /* do */
if vs.!summaryfile<>"" then vs.!dctfile=vs.!summaryfile
swish_version=vs.!swishversion /* might be user specified */
if wordpos(swish_version,'11 12 13 13_DLL')=0 then do
if is_cgi=1 then say "ERROR: not a known swish version " swish_version
exit
end /* do */
if translate(swish_version)="13_DLL" then do
swish_version=13
use_swish_dll=1
end
/* clean up the options */
vs.!repwith=translate(vs.!repwith,' ',',"'||"'"||'00090d0a'x)
select
when swish_version=11 then do /* suppress 1.2+ options? */
vs.!dostem=0
vs.!indexcomments=1
vs.!propnames=0
vs.!metanames=0
vs.!showprop=0
end
when swish_version=12 then do /* suppress 1.3 options? */
vs.!dostem=0
vs.!propnames=0
vs.!showprop=0
end
otherwise do
if wordpos(translate(vs.!dostem),'1 YES Y')>0 then vs.!dostem=1
if wordpos(translate(vs.!dostem),'0 NO N')>0 then vs.!dostem=0
end
end
/*** Check for SEARCH mode or LIST INDICES MODE DREGEN 2DREGEN REGEN REGEN2 */
if abbrev(translate(vs.!mode),'S')=1 then do /* SEARCH MODE */
foo=search_it(list0)
return 0
end /* do */
if abbrev(translate(Vs.!mode),'L')=1 then do /* LIST INDICES MODE */
foo=show_forms(list0)
return 0
end /* do */
if abbrev(translate(Vs.!mode),'REGEN')=1 then do /* choose index to regenerate */
foo=choose_confile(list0)
return 0
end /* do */
/* choose descriptive summaries to regenerate */
/************ n.a.
if abbrev(translate(Vs.!mode),'DREGEN')=1 then do
foo=choose_dctfile(list0)
return 0
end ***********/
/* regen descriptive summaries */
/************** N.a.
if abbrev(translate(Vs.!mode),'2DREGEN')=1 then do
dafile='<html><head><title>Regenerating descriptive summaries</title>'crlf
dafile=dafile||'<body><h2>Regenerating descriptive summaries</h2>'crlf
dafile=dafile||'Regenerating descriptive summaries for 'vs.!swifile ' <p>'
dafile=dafile||'<em>with search document of: </em> <a href="'vs.!searchdoc'">'vs.!searchdoc'</a><p>'
if is_cgi=0 then do
fii=value('SREF_PREFIX',,'os2environment')
if fii='' then do
if fex>0 then foo=sref_expire_response(fex,0,,'Y')
'SEND TYPE text/html '
'var name dafile'
end
else do
fii=sref_multi_send(dafile,'text/html','1S')
end
end
else do
say 'Content-Type: text/html'
say ""
say dafile
end
vs.!watch=0
vs.!makesummary=2
signal jump3
end ******************************* */
if abbrev(translate(Vs.!mode),'2REGEN')=1 then do /* provides a conf file to reuse */
isconf=use_conffile(list0)
if isconf=0 then return 0 /* no such configuration file */
parse var isconf conffile (crlf) .
dafile='<html><head><title>Regenerating a Swish Index</title>'crlf
dafile=dafile||'<body><h2>Regenerating a Swish Index</h2>'crlf
dafile=dafile||'Using 'conffile ' to regenerate a swish index <p>'crlf
dafile=dafile||'<em>with search document of: </em> <a href="'vs.!searchdoc'">'vs.!searchdoc'</a><br>'crlf
dafile=dafile||' Note that <tt>descriptive summaries</tt> will <b>not</b> be regenerated<p>'crlf
if is_cgi=0 then do
fii=value('SREF_PREFIX',,'os2environment')
if fii='' then do /* 1.2 */
if fex>0 then foo=sref_expire_response(fex,0,,'Y')
'SEND TYPE text/html '
'var name dafile'
end
else do
fii=sref_multi_send(dafile,'text/html','1S') /* sre ver 1.3 */
end /* do */
end
else do
say 'Content-Type: text/html'
say ""
say dafile /* cgi-bin output */
end
vs.!watch=0
signal jump2
end /* do */
/***** IF here--- we are making an index, or making a description */
/* is this an "addon" call, other then for "making descriptions ? */
if is_cgi=0 & verb<>'DESCRIBE' then do /* yes, let's check SRE-http privileges */
isp=0
if wordpos('*',need_privs)>0 then do
isp=1
end /* do */
else do
do mm=1 to words(need_privs)
aww=strip(translate(word(need_privs,mm)))
if wordpos(aww,privset)>0 then do
isp=mm ; leave
end /* do */
end /* do */
end
if isp=0 then do
'header add WWW-Authenticate: Basic Realm=<!SWISH_INDEX>' /* challenge */
return sref_response('unauth', "You do not have SWISH Index creation rights ",tempfile,servername)
end /* Do */
if method="GET" then parse var uri . '?' list
if WEB_ROOT_DIR='' then WEB_ROOT_DIR=ddir
if SWISH_DIR='' then SWISH_DIR=get_value('workdata_dir')
end
/* if here, either not an sre-http addon call, or sre-http privileges are fine. */
/* If it's not a "Make description call", then determine the "index file" */
if verb<>"DESCRIBE" then do /* creating an index */
vs.!swifile=mk_filename(vs.!swifile,SWISH_DIR,'INDEX','SWI',vs.!Overwrite)
foo=sysfiledelete(vs.!swifile)
end
vs.!wwwdir=strip(translate(vs.!wwwdir,'\','/'),'t','\') /* fix up the WEB_ROOT_DIR */
if dir_exists(vs.!wwwdir)=0 then do
foo=is_error(' Sorry, no such Web_Root directory: 'vs.!wwwdir)
exit
end
/*** Let's clean up some more parameters, now that we now we might need 'em */
/* What type of "summary" should be made? (if any)*/
vv=translate(vs.!makesummary)
select
when wordpos(vv,'N NO 0')>0 then
vs.!makesummary=0
when wordpos(vv,'Y YES 1')>0 then
vs.!makesummary=1
when wordpos(vv,'C CREATE 2')>0 then
vs.!makesummary=2
otherwise
vs.!makesummary=0
end
if vs.!makesummary>0 then do
parse var vs.!swifile taa '.' .
vs.!dctfile=taa||'.dct'
end /* do */
tt=""
do until vs.!htmls="" /* list of HTML extentions */
parse var vs.!htmls a1 vs.!htmls ;a1=strip(a1)
tt=tt||' '||strip(a1,'l','.')
end /* do */
vs.!htmls=strip(tt)
tt="" /* list of "text" extensions */
vs.!extlist=translate(vs.!extlist,' ','00090a0d'x||',')
do until vs.!extlist=""
parse var vs.!extlist a1 vs.!extlist ;a1=strip(a1)
tt=tt||' .'||strip(a1,'l','.')
end /* do */
vs.!extlist=strip(tt)
tt="" /* list of "non text, but index anyways, extensions */
do until vs.!extlist_nofollow=""
parse var vs.!extlist_nofollow a1 vs.!extlist_nofollow ;a1=strip(a1)
tt=tt||' .'||strip(a1,'l','.')
end /* do */
vs.!extlist_nofollow=strip(tt)
/* used in sre-http addon mode (to enable real time reporting of status */
if wordpos(translate(vs.!watch),'1 YES Y')>0 then vs.!watch=1
if wordpos(translate(vs.!watch),') NO N')>0 then vs.!watch=0
if is_cgi=1 then vs.!watch=0 /* cgi-bin monitoring of output is too hard */
vs.!sel=space(translate(vs.!sel,' ','00090d0a'x))
vs.!selorig=vs.!sel
vsel=vs.!sel /* fix up each of possibly several "directories to index */
vs.!sel=''
do forever /* fix up \'s */
if vsel='' then leave
parse var vsel a1 vsel ; a1=strip(a1)
a1=translate(a1,'\','/')
a1=strip(a1,,'\')
if pos(':',a1)>0 then
vs.!sel=vs.!sel' 'a1
else
vs.!sel=vs.!sel' \'||a1
end /* do */
if datatype(vs.!verbose)<>'NUM' then vs.!verbose=3
if vs.!verbose>3 | vs.!verbose<0 then vs.!verbose=3
/*** Make a summary; from an invocation of GOSWISH (as a 2nd, detached process) */
if verb="DESCRIBE" then do /* make a summary mode ? */
vs.!swifile=daswifile ; SWF=VS.!SWIFILE
vs.!dctfile=dasummfile
vs.!makesummary=datype
vs.!watch=0 ; vs.!mode='SUMMARY'
vs.!repwith=darepwith
vs.!describefile=dafdescribe
web_root_dir=dawwwdir
vs.!wwwdir=dawwwdir
swish_dir=daswishdir
do forever /* wait until vs.!swifile is avaiable */
if stream(swf,'c','query exists')<>"" then leave
call syssleep 2
end /* do */
call syssleep 1
fpp=make_dctfile()
exit
end /* When done making summary, EXIT */
/**** If here, we are making a swish index -------------------- */
/* the search-form document to create (and a link to it */
usedoc0=translate(strip(vs.!searchdoc),' ','+')
parse var usedoc0 usedoc doob
aform=mk_filename(usedoc,vs.!wwwdir,'SEARCH','HTM',vs.!overwrite)
foo=sysfiledelete(aform)
if words(usedoc0)=1 then
doob=translate(substr(aform,length(vs.!wwwdir)+1),'/','\')
doob=translate(substr(aform,length(vs.!wwwdir)+1),'/','\')
if pos('.',doob)=0 then doob=doob'.' /* avoid "implicit directory types of problems*/
yeek=filespec('D',aform)||filespec('P',aform)
if dir_exists(yeek)=0 then do
foo=is_error(' Sorry, bad search-document name: 'aform)
exit
end /* do */
fff=sysfiledelete(aforM)
if vs.!indexdescription=0 | vs.!indexdescription=' ' then
vs.!indexdescription=vs.!selorig' on ' servername
if vs.!indexname=0 | vs.!indexname=' ' then
vs.!indexname='Index of 'vs.!selorig
/* write the response to client */
dafile='<html><head><title>Swish Configuration File</title>'crlf
dafile=dafile||' <SCRIPT language="Javascript">'crlf
dafile=dafile||'<!-- 'crlf
dafile=dafile||'var iloaded=0 'crlf
dafile=dafile||'function chekit(aname) { 'crlf
dafile=dafile||' if (iloaded==1) {return true}'crlf
dafile=dafile||' return window.confirm("GoSWISH is still uploading contents...\n' ,
' Are you sure you want to load: \n " + aname )'crlf
dafile=dafile||'}'crlf
dafile=dafile||'// -->'crlf
dafile=dafile||'</script>'crlf
dafile=dafile'</head>'crlf
dafile=dafile'<body onLoad="iloaded=1">'crlf
dafile=dafile||'<a name="TOP"><h2 align="CENTER">Creating a Swish Index </h2></a>'crlf
swiver=1.3
if swish_version=11 then swiver=1.1
if swish_version=12 then swiver=1.2
dafile=dafile||'<table><tr><td colspan=2> Using SWISH version: <b>'swiver'</b></td>'crlf
dafile=dafile||'<tr><td valign="TOP" nowrap>Creating an <b>index</b> of files in: </td>'crlf
dafile=dafile||'<td valign="TOP">'vs.!selorig'</td>'crlf
dafile=dafile||'<tr><td valign="TOP">SWISH <b>Index</b> file: </td><td align="top">'vs.!swifile'</td>'crlf
dafile=dafile||'<tr><td valign="TOP"> <tt>Search form</tt>: </td> 'crlf
bobo='"'doob'"'
bobo0="'"doob"'"
if doob<>'' then
dafile=dafile||'<td valign="TOP"> <a onClick="return chekit('||bobo0||') " href='||bobo||'>'aform||'</a>'crlf
else
dafile=dafile||' <td valign="TOP"> 'aform||crlf
dafile=dafile||'<em>(wait until this page is completely downloaded, and then you can try this link!)</em></td>'
if abbrev(translate(vs.!swifile),translate(swish_dir))=1 then
eekz=substr(vs.!swifile,length(swish_dir)+2)
else
eekz=vs.!swifile
eekz2=vs.!dctfile
if eekz2<>'' then do
if abbrev(translate(eekz2),translate(swish_dir))=1 then
eekz2=substr(eekz2,length(swish_dir)+2)
end
xx=write_form(aform,eekz,eekz2,doob) /* write stuff to search-form document */
dafile=dafile||'<tr><td colspan=2>You can use this <tt>Search form</tt> to search the <TT>'vs.!swifile'</TT> SWISH index'
if vs.!makesummary>0 then do
dafile=dafile||', or the <TT>'vs.!dctfile '</TT> descriptions file'crlf
end
else do
dafile=dafile||'.'crlf
end
dafile=dafile||'</td></table>'crlf
if vs.!watch=0 then dafile=dafile||'<p> <b>You may need to wait for a few minutes </b> (until SWISH completes 'vs.!swifile')'crlf
parse var vs.!swifile a1 '.' .
cnffile=mk_filename(a1'.CON',swish_dir,'INDEX','.con',vs.!Overwrite)
foo=sysfiledelete(cnffile)
dafile=dafile||'<hr><h3> The configuration file </h3> 'crlf
dafile=dafile||' The following configuration file ('cnffile ') is used to generate the <b>' vs.!swifile '</b> <em> SWISH index</em><br>'
if is_cgi=0 then do
fii=value('SREF_PREFIX',,'os2environment')
if fii='' then do /* 1.2 */
if fex>0 then foo=sref_expire_response(fex,0,,'Y')
'SEND TYPE text/html '
'var name dafile'
end
else do
fii=sref_multi_send(dafile,'text/html','1S') /* sre ver 1.3 */
end /* do */
end
else do
say 'Content-Type: text/html'
say ""
say dafile /* cgi-bin output */
end
isconf=''
jump2: /* jump here if regenerateing index */
dafile=write_conf(isconf) /* create the swish configuration file, and run swish */
if dafile=0 & vs.!watch=1 then signal onerr2
if vs.!watch=0 then do
dafile='<br><em> Construction of 'vs.!swifile' may take a few minutes.</em><br>'
call write_her(dafile)
end /* do */
jump3: /* jump here on regenerate summaries, when supported */
/* make a summary (here, with echoing; or via a detach */
if vs.!makesummary>0 then do
if vs.!watch=1 then do
call write_her('<hr><pre>')
aa=time('r')
swf=vs.!swifile
do forever /* wait until vs.!swifile is avaiable */
if stream(swf,'c','query exists')="" then do
if is_cgi=0 then do
if vs.!watch=1 then call write_her('Waiting for 'swf' '||time('e'))
if result<0 then return 0
end /* do */
call syssleep 1
iterate
end /* do */
else do
if vs.!watch=1 then call write_her('</pre><h3>Creating Descriptions </h3>')
leave
end
end /* do */
fpp=make_dctfile() /* make_dctfile does the summary creation */
end /* watch mode */
else do /* non-watch -- detach GoSWISH in DESCRIBE mode*/
if prog_file<>" " then
xxx=prog_file
else
xxx=SWISH_DIR'\goswish'
tmp1=translate(vs.!repwith,'\','/')
arglist='*DESCRIBE ' ,
swish_dir' 'web_root_dir' 'vs.!swifile','vs.!describefile','tmp1',' ,
vs.!makesummary',' ,
vs.!dctfile
if is_cgi=0 then do
gloob=exec_modifier||xxx
address cmd 'detach 'gloob' 'arglist
end
else do
crob=left(vs.!selorig,min(35,length(vs.!selorig)))
bubba='"Descriptions of 'crob'" /C /MIN 'exec_modifier||xxx ' 'arglist ' > nul '
address cmd '@start 'bubba
end /* do */
end /* do */
end
call write_her('<hr><a href="#top">Top of document</a>')
onerr2: nop /* jump here on error (i.e.; no such dir */
dafile='</pre></body></html>'
call write_her(dafile)
if is_cgi=0 then do
if fii='' then /* sre 1.2 */
'SEND COMPLETE '
else
foo=sref_multi_send(' ',,'1E') /* sre 1.3 */
end
/* write info to the "index "*/
tbo=date('n')' 'time('n')
if vs.!makesummary>0 then tbo=tbo' (w/summaries) '
aline=doob','aform','vs.!swifile' 'cnffile' 'vs.!dctfile' 'vs.!describefile','tbo','vs.!indexname
goindx=SWISH_DIR'\goswish.ind'
if stream(goindx,'c','query exists')<>"" then do
oo=translate(stream(goindx,'c','open'))
if abbrev(oo,'READY')=0 then return 0 /* can't open, give up */
aa=charin(goindx,1,chars(goindx))
aa=strip(aa,'t','1a'x)
end
else do
aa=''
end /* do */
aa=aline||'0d0a'x||aa
aa2=charout(goindx,aa,1)
foo=stream(goindx,'c','close')
return 0
/***********************/
/* write the configuration file, with parameters */
write_conf:procedure expose vs. SWISH_DIR WEB_ROOT_DIR servername is_cgi realsel realdir ,
enmadd ddir transaction homedir host_nickname cnffile swish_version ,
exec_modifier use_swish_dll
crlf='0d0a'x
parse arg gotconf
use_swish_dll=0 /* for now, suppress use of dll on writes */
if gotconf<>"" then do /* user supplied configuration file */
parse arg cnffile (crlf) gotconf
aboo='<pre>'gotconf'</pre>'
call write_her(aboo)
signal makeindx
end /* do */
/* else, write conf file from form input */
if is_cgi=0 then do /* use a virtual dir */
vsel=vs.!sel ; realdir='' ; realsel=''
do forever
if vsel='' then leave
parse var vsel eek1 vsel ; eek1=strip(eek1)
if pos(':',eek1)=0 then do
eek1=translate(eek1,'/','\')||'/'
realdir9=sref_do_virtual(ddir,eek1,enmadd,0,trans,homedir,host_nickname)
end /* do */
else do
realdir9=eek1
end
realdir=realdir' 'strip(realdir9,'t','\')
if eek1='//' | eek1='/' then
realsel=realsel' /'
else
realsel=realsel' 'strip(eek1,'t','/')
end
end
else do
vsel=vs.!sel ; realdir='' ; realsel=''
do forever
if vsel='' then leave
parse var vsel eek1 vsel ; eek1=strip(eek1)
if pos(':',eek1)=0 then do
eek1=translate(eek1,'/','\')
realdir9=strip(strip(vs.!wwwdir,'t','\')||eek1,'t','\')
realdir9=translate(realdir9,'\','/')
end /* do */
else do
realdir9=eek1
end
realdir=realdir' 'strip(realdir9,'t','\')
if eek1='//' | eek1='/' then
realsel=realsel' /'
else
realsel=realsel' 'strip(eek1,'t','/')
end
end
crlf='0d0a'x
do ii=1 to 50
conf.ii=' '
end
conf.0=50
swiver=1.3
if swish_version=11 then swiver=1.1
if swish_version=12 then swiver=1.2
if swish_version=13 then swiver=1.3
conf.1='#Auto-generated SWISH (ver 'swiver') configuration file '||date('n')' 'time('n')
conf.3=' '
conf.4='# space delimited list of files/directories to index '
conf.5='IndexDir '
rrr=fixslash(realdir,swish_version)
do ik=1 to words(rrr)
rrr1=strip(word(rrr,ik))
if pos('*',rrr1)=0 then do
conf.5=conf.5' 'rrr1
end
else do
oo=sysfiletree(rrr1,'tff','FO')
if tff.0>1 & length(conf.5)>30 then conf.5=conf.5||crlf||'IndexDir '
do ik2=1 to tff.0
rrr3=fixslash(tff.ik2,swish_version)
conf.5=conf.5' 'rrr3
if (ik2//5)=4 then conf.5=conf.5||crlf||'IndexDir '
end /* do */
end
end /* do */
/* quick check on # of files to be indexed */
do mm=1 to words(realdir)
dadd=strip(word(realdir,mm))
if pos('*',dadd)=0 then do
if dir_exists(dadd)=0 then do /* no such dir! */
call write_her('<B> Error. No such directory: 'dadd)
return 0
end /* do */
dadd2=strip(dadd,'t','\')||'\*.*'
oo=sysfiletree(dadd2,'tff','FSO')
oo2=sysfiletree(dadd2,'tff2','DSO')
conf.5=conf.5||crlf||'# 'dadd' contains 'tff2.0' subdirectories and 'tff.0' files'
end
else do
oo=sysfiletree(dadd,'tff','FO')
conf.5=conf.5||crlf||'# 'dadd' matches 'tff.0' files'
end /* do */
end /* do */
conf.6=' '
conf.7='# the generated index file '
conf.8='IndexFile '||fixslash(vs.!swifile,swish_version)
conf.9=' '
conf.10='#some identification info '
conf.11='IndexName 'vs.!indexname
conf.12='IndexDescription 'vs.!indexdescription
conf.13='IndexPointer 'vs.!indexpointer
conf.14='IndexAdmin 'VS.!indexadmin
conf.15=' '
conf.16='# Only files with these suffixes will be indexed.'
if pos('*',vs.!extlist)=0 then
conf.17='IndexOnly 'vs.!extlist
conf.18='# but do not look at contents of these files '
if pos('*',vs.!extlist_nofollow)=0 then
conf.19='NoContents 'vs.!extlist_nofollow
conf.21='# this converts fully qualified file references into urls '
/* do the replace rules */
conf.22=''
if vs.!repwith=0 | vs.!repwith=' ' then do /* defaults */
repwithb=''; vs.!repwith=''
do mm=1 to words(realsel)
aw=strip(word(realsel,mm))
if pos(':',aw)>0 then iterate /* no auto reprules for fully qualified dirs */
if aw='/' then aw='' /* if "search web_root was chowdn */
if pos('*',aw)>0 then do
jm=max(lastpos('\',aw),lastpos('/',aw))
if jm>0 then aw=left(aw,jm-1)
end
repwithb='http://'||servername||aw
rdir=strip(word(realdir,mm))
if pos('*',rdir)>0 then do
jm=max(lastpos('\',rdir),lastpos('/',rdir))
if jm>0 then rdir=left(rdir,jm-1)
end /* do */
repwitha=fixslash(rdir,swish_version)
if conf.22<>'' then conf.22=conf.22||'0d0a'x
conf.22=conf.22|| ,
'ReplaceRules replace "'repwitha'" "'||repwithb||'" '
/* vs.!repwith is used in make_dctfile */
vs.!repwith=vs.!repwith' 'repwitha' 'repwithb
end
end
else do /* do user specified */
tmp=vs.!repwith
if translate(Tmp)='NONE' | translate(tmp)='NO' then do
conf.22='# no replace rules were specified '
end /* do */
else do
repwitha='' ; repwithb=''
do forever
parse var tmp a1 a2 tmp
if a2='' then leave
a1=fixslash(strip(a1),swish_version) ; a2=strip(a2)
if conf.22<>'' then conf.22=conf.22||'0d0a'x
conf.22=conf.22|| ,
'ReplaceRules replace "'a1'" "'||a2||'" '
end
end /* reprules <> NONE */
end
conf.24='# these are used to not search files and directories '
if vs.!fr_pathname<>0 & vs.!fr_pathname<>' ' then conf.25='FileRules pathname 'vs.!fr_pathname
if vs.!fr_filename<>0 & vs.!fr_filename<>" " then conf.26='FileRules filename 'vs.!fr_filename
if vs.!fr_title<>0 & vs.!fr_title<>' 'then conf.27='FileRules title 'vs.!fr_title
if vs.!fr_directory<>0 & vs.!fr_directory<>' 'then conf.28='FileRules directory 'vs.!fr_directory
conf.30='# ignore certain common words '
conf.31='IgnoreLimit ' vs.!ignorelimit
conf.32='IgnoreWords ' vs.!ignorewords
conf.34='# the following are SWISH 1.3 options '
conf.35='# UseStemming yes to apply word stemming algorithm during indexing, no otherwise'
if swish_version=13 then do
conf.36='UseStemming no'
if vs.!dostem=1 then conf.36='UseStemming yes'
end
else do
conf.36='# UseStemming not supported under SWISH 1.2 or less '
end /* do */
conf.37='# IndexComments 1 to NOT examine html comments, 0 otherwise '
if swish_version<>11 then do
conf.38="IndexComments 0"
if vs.!indexcomments=1 then conf.38="IndexComments 1"
end
else do
conf.38="# IndexComments not supported under SWISH 1.1 "
end /* do */
conf.40='# List of meta tags names that can be retrieved with the -p option.'
if swish_version=11 | swish_version=12 then do
conf.41='# PropertyaNames not supported under SWISH 1.2 or less '
end /* do */
else do
if vs.!propnames=0 | vs.!propnames='' then
conf.41='#PropertyNames description author datamodified'
else
conf.41='PropertyNames 'vs.!propnames
end
conf.42='# List of metanames for use with -w mname=awords option.'
if swish_version=11 then do
conf.43='# MetaNames not supported under SWISH 1.1 '
end /* do */
else do
if vs.!metanames=0 | vs.!metanames='' then
conf.43='MetaNames '
else
conf.43='MetaNames 'vs.!metanames
end
conf.46='# verbosity, and an os/2 necessary switch '
conf.47=' IndexReport ' vs.!verbose
conf.48=' followSymLinks no '
aboo=""
do mm=1 to conf.0
call lineout cnffile,strip(conf.mm)
aboo=aboo||conf.mm||'0d0a'x
end /* do */
call lineout cnffile
aboo='<pre>'aboo'</pre>'
call write_her(aboo)
makeindx: /* jump here if user supplied configuration file */
/* which swish? */
select
/* when use_Swish_dll=1 then nop -- doesn't work yet */
when swish_version=11 then xxx=SWISH_DIR'\swish'
otherwise xxx=SWISH_DIR'\swish-e'
end
if use_swish_dll=0 then do
if exec_modifier<>'' & exec_modifier<>0 then
xxx2=exec_modifier' 'xxx
else
xxx2=xxx
end
/* cgi bin? */
if is_cgi=1 & use_swish_dll=0 then do
if stream(xxx'.exe','c','query exists')="" then do
say "<b> ERROR: Could not find " xxx'.exe </b>'
return 0
end
address cmd '@START "Swish Index for 'VS.!selorig '" /N /MIN 'xxx2 ' -c 'cnffile ' > nul'
call write_her('<p><em>Hint: you can monitor the status of SWISH by viewing the <tt>ctrl-esc</tt> process list </em>')
return 1
end
/* sre-http.. */
/* monitor output via RXQUEUE */
useq=''
if vs.!watch<>0 & use_swish_dll=0 then do
oldq=rxqueue('g')
useq=rxqueue('c','SWISHQ')
foo=rxqueue('s',useq)
do queued(); pull .; end /* flush */
end
if use_swish_dll=0 then do
fdr=directory(swish_dir)
if vs.!watch=1 then do
if swish_version=11 then
address cmd 'detach ' exec_modifier||'swish -c 'cnffile ' | rxqueue "'useq'"'
else
address cmd 'detach ' exec_modifier||'swish-e -c 'cnffile ' | rxqueue "'useq'"'
end
else do
if swish_version=11 then
address cmd 'detach ' exec_modifier||' swish -c 'cnffile
else
address cmd 'detach ' exec_modifier||'swish-e -c 'cnffile
end /* do */
end
else do /* use dll mode */
rc=rxswEmulate('-c 'cnffile)
end /* do */
aa=directory(fdr)
if vs.!watch=0 then return 0
/* monitor output of swish */
aboo='<hr><h3> SWISH Results </h3><pre>'||crlf
call write_her(aboo)
if result<0 then do
'string 'crlf||'</pre> .. broken connection, but SWISH is still running)<p> '
return 0
end
oo=time('r')
ipo=0
do forever
ipo2=0 ;bbb=""
if queued()>0 then do
parse pull aline
if TRANSLATE(strip(aline))='INDEXING DONE!' then leave
ipo2=ipo2+1 ;ipo=0
bbb=bbb||aline||crlf
if ipo2>10 then do
call write_her(bbb)
bbb=""
foo=time('r')
end
end
if length(bbb)>0 then do
call write_her(bbb)
foo=time('r')
end
if time('e')>15 then do
'string 'crlf||'</pre> ... (monitoring now ending, but SWISH is still running)<p> '
return 0
end /* do */
end
foo=rxqueue('d',useq)
foo=rxqueue('s',oldq)
call write_her('</pre>')
return 1
/**************************/
/* convert \ to / ? */
fixslash:procedure
parse arg amess,swver
if swver=11 then return amess
return translate(amess,'/','\')
/**************************/
/* create file name, numbered from 1...
call as:
afile=mk_filename(usefile,defdir,defname,detext,overwrite)
usefile= suggested filename; lots of possibilities
defdir = default directory to write to
defname = default name to use (no path, no extension)
defext = default extentsion
overwrite = overwrite file, otherwise modify name
****/
mk_filename:procedure
parse arg aname,defdir,defname,defext,overwrite
defext=strip(strip(defext),,'.'); defname=strip(defname)
parse var defname defname '.' .
aname=strip(aname)
aname=translate(aname,'\','/')
defdir=strip(translate(defdir,'\','/'),'t','\')
/* case 1: drive provided; so this is fully qualifed path (or more) */
if pos(':',aname)>0 then do
if right(aname,1)='\' then do /* D:\foo\bar\ : a subdir-- use defaults */
aname=aname||defname'.'defext
end
if pos('.',aname)=0 then do /* D:\FOO\BAR : a subdir */
aname=aname'\'defname'.'defext
end
end
if aname='' then do /* use a defaultt */
aname=defdir'\'||defname'.'defext
end
if pos(':',aname)=0 then do /* relative dir */
aname=defdir||'\'||strip(aname,'l','\')
if right(aname,1)='\' then do /* D:\foo\bar\ : a subdir-- use defaults */
aname=aname||defname'.'defext
end /* do */
if pos('.',aname)=0 then do /* FOO\BAR : a name */
aname=aname'.'defext
end
end
if overwrite=1 then return aname
if stream(aname,'c','query exists')="" then return aname /* doesn't exist, so use */
/* does exist, and not overwrite -- look for different name */
PARSE var aname aname '.' aext0
do mm=1 to 999
f1=aname||mm||'.'aext0
if stream(f1,'c','query exists')="" then do
return f1
end /* do */
end /* do */
return f1 /* use name999.ext in a pinch */
/************************************************/
/* procedure from TEST-CGI.CMD by Frankie Fan <kfan@netcom.com> 7/11/94 */
DecodeKeyVal: procedure
parse arg Code
Text=''
Code=translate(Code, ' ', '+')
rest='%'
do while (rest\='')
Parse var Code T '%' rest
Text=Text || T
if (rest\='' ) then
do
ch = left( rest,2)
if verify(ch,'01234567890ABCDEF')=0 then
c=X2C(ch)
else
c=ch
Text=Text || c
Code=substr( rest, 3)
end
end
return Text
/*********/
/* return error message */
is_error:procedure expose is_cgi
parse arg amess
if is_cgi=0 then do
'string ' amess
end
else do
say 'Content-type: text/plain'
say
say amess
end
return 1
/***********/
/* generate form that calls the "search in a swish index" document */
write_form:procedure expose vs. is_cgi swish_version add_hit_num no_tips
parse arg tofile,swifile,sumfile,doob
crlf='0d0a'x
do mmm=1 to 65
frm.mmm=''
end /* do */
frm.1='<!doctype html public "-//IETF//DTD HTML 2.0//EN">'
frm.2='<html><head><title>Search an index </title></head><body>'
frm.3= '<a name="top"> '
if vs.!FORM_TITLE='' then do
frm.3=frm.3||'<h2 align="CENTER">Search an index of: 'vs.!selorig'</h2></a>'
end
else do
form_title=translate(form_title,'`','"')
frm.3=frm.3||vs.!form_title
end
frm.3=frm.3||' </a>'
if is_cgi=1 then
frm.5='<FORM ACTION="/cgi-bin/goswish.cmd" METHOD="POST">'
else
frm.5='<FORM ACTION="/goswish" METHOD="POST">'
frm.6='<INPUT TYPE="hidden" NAME="index" VALUE="'swifile'">'crlf
if sumfile<>'' then
frm.7='<INPUT TYPE="hidden" NAME="dct_file" VALUE="'sumfile'">'
frm.8=' '
if no_tips=0 then
frm.9='<a href="#tips"><em>(tips)</em></a> 'crlf
frm.10='Enter search string: <INPUT TYPE="text" NAME="keyword" VALUE="help" SIZE=40 >'
if vs.!makesummary>0 then do
frm.11=' <nobr><input type="checkbox" name="summary" value="1">Display summaries </nobr>'
end
/* choose to display property names */
if vs.!propnames<>0 & vs.!propnames<>'' then do
ise=words(vs.!propnames)
if vs.!makesummary>0 then ise=ise+1
rr='<select name="showprop" size='||strip(ise)' multiple>'||'0d0a'x
if vs.!makesummary>0 then do
rr=rr||'<Option value="_summary_1">Summary.'||'0d0a'x
frm.11=' <nobr>Display: '
end /* do */
do np=1 to words(vs.!propnames)
apr=strip(word(vs.!Propnames,np))
rr=rr||'<option value="'apr'">'apr||'0d0a'x
end
rr=rr||'</select></nobr>'
frm.12=frm.12||'0d0a'x||rr
end
frm.13='<br>'crlf
frm.14='<br><INPUT TYPE="submit" VALUE="Start the search"> <INPUT TYPE="reset" VALUE="reset values">'
frm.15='<h3> Options: </h3>'
frm.16='<table border=1><tr><td><INPUT TYPE=RADIO NAME="cond" VALUE="OR">Match any word ||'
frm.17='<INPUT TYPE=RADIO NAME="cond" checked VALUE="AND">Match all words<br>'
frm.18=''
frm.19='<INPUT TYPE=RADIO NAME="cond" VALUE="NOT">Match first word, but not others<br>'
frm.20='<INPUT TYPE=RADIO NAME="option1" VALUE="-m 10">Best 10 matches ||'
frm.21='<INPUT TYPE=RADIO NAME="option1" checked VALUE="-m 20">Best 20 matches <br>'
frm.22='<INPUT TYPE=RADIO NAME="option1" VALUE="-m 40">Best 40 matches || '
frm.23='<INPUT TYPE=RADIO NAME="option1" VALUE="-m 150">Best 150 matches <br>'
frm.23=frm.23||'0d0a'x||'<INPUT TYPE=RADIO NAME="option1" VALUE="-m 100000">All matches <br>'
i6=6
if vs.!makesummary=0 then i6=4
frm.24='</td><td><SELECT NAME="option2" SIZE='i6'> '
frm.25='<OPTION SELECTED value="" >Search all documents'
frm.26='<OPTION value="-t+HB">Search HTML documents: text'
frm.27='<OPTION value="-t+ehtc">Search HTML documents: "descriptive" elements'
frm.28='<OPTION value="-t+t">Search HTML documents: <TITLE> only'
if vs.!makesummary>0 then do
frm.29='<option value="summary"> Search "summaries" only'
frm.30='<OPTION value="path">Search path and file names only'
frm.31='<OPTION value="file">Search file names only'
/* frm.33='<input type="checkbox" name="summary" value="1">Display summaries '*/
frm.33=''
end
frm.32='</SELECT></td></table><p>'
/* Too slow, so don't make it automatically available.
if is_cgi=0 then frm.34='<br> <input type="checkbox" name="exists" value=1"> Check that document exists <br>'
*/
if vs.!results_title='' then do
frm.35='<input type="hidden" name="H2" value="Search of 'vs.!selorig'">'
end
else do
vs.!results_title=translate(vs.!results_title,'`','"')
frm.35='<input type="hidden" name="HEADER" value="'vs.!results_title'">'
end
frm.36='<input type="hidden" name="MODE" value="S"> '
Frm.36=frm.36||' <input type="Hidden" name="START" value="1+0">'
frm.37='<p><INPUT TYPE="hidden" NAME="ADD_HIT" value="'add_hit_num'">'
frm.38='<input type="hidden" name="search_link" value="'doob'">'
frm.39='</FORM>'
if no_tips=0 then do
frm.40='</ul><a name="tips"><hr></a><h4>Useful tips</h4>'
frm.41='<blockquote>Using this form, you can search: <tt>'vs.!indexdescription'</tt></blockquote>'
frm.42='<menu><li> You can enter multiple words. '
frm.43='<li> You can use <b>AND, NOT, OR,</strong> and <b>( )</b> to further modify search logic'
frm.44='<li> Search is case insensitive.'
if vs.!dostem=1 then do
frm.44=frm.44'<li>Search uses <em>stemming rules</em> to remove "s", "ed", and other common stems.'
end /* do */
if vs.!indexcomments=1 then do
frm.44=frm.44'<br>Search ignores HTML <!-- comments -->. '
end
frm.45='<li> You can use * to match the </em>beginning of words <em> (for example, SHIP* will match <tt>SHIP</tt> and <tt>ShipMate</tt>)</em>'
if vs.!makesummary>0 then do
frm.45=frm.45||'<br> For searches of filenames and summaries, do NOT use * (a substring match is used for all searches)'
end
frm.46='<li><em>descriptive HTML elements</em> include Emphasis (I, EM, B and STRONG), Titles, H1 .. H7 headers, and comments.'
if vs.!makesummary>0 then do
frm.48='<li> If selected, short (3-5 line) <strong>summaries </strong>will be displayed (when available) for each matching file'
end
if vs.!propnames<>0 & vs.!propnames<>'' then do
frm.50='<li> You can also display the contents of the following <META> tags: ' ,
'<b> ' vs.!propnames '</b>'
end
if vs.!metanames<>0 & vs.!metanames<>'' then do
frm.52='<li> You can also search for words in the folllowing <META> fields: <b>' vs.!metanames '</b>'
frm.53='<br> Example: <tt> MymetaName1 = (a1 or a4) not (a3 and a7) </tt><br>'
frm.54='This query will retrieve all the files in which the "MymetaName1" is associated either with "a1" or "a4" and that do '
frm.55='not contain the words "a3" and "a7", where "a3" and "a7" are not associated to any meta name.'
end
frm.61='</menu>'
frm.62='<hr><a href="#top">Top of document</a>'
end
frm.63='</body></html>'
do mm=1 to 65
call lineout tofile,frm.mm
end
call lineout tofile
return 1
foo10:
say " GOSWISH: error at " sigl rc
exit 0
/* See if directory exists , 0=no 1=yes*/
dir_exists:procedure
parse upper arg lookfor
lookfor=strip(lookfor,'t','\')
adrive=filespec('d',lookfor) /* does drive exist? */
if adrive<>"" then do
oo2=sysdrivemap(,'used')
if pos(translate(adrive),translate(oo2))=0 then return 0 /* no such drive */
end
eek=lastpos('\',lookfor)
if eek>0 then do
lookfor1=substr(lookfor,eek+1)
foo=delstr(lookfor,eek)
end
else do
return 1 /* it's a root dir */
end /* do */
foo=foo'\*.*'
aa=sysfiletree(foo,'eek','DO')
do mm=1 to eek.0
if translate(filespec('n',eek.mm))=lookfor1 then do
return 1
end /* do */
end /* do */
return 0
/* ----------- */
/* get environment value, possibly host specific */
/* ------------ */
get_value: procedure expose enmadd host_nickname
parse arg vname,hname0
if hname0=0 then
hname=' '
else
hname=strip(host_nickname)
vname=strip(vname) ;
if hname<>' ' then do
aval=value(enmadd||vname||'.'||hname,,'os2environment')
if aval<>' ' Then
return aval
end
aval=value(enmadd||vname,,'os2environment')
return aval
/********/
/* say or send , or not, adesc */
write_her:procedure expose vs. is_cgi fii swish_version
parse arg axx
if translate(fii)='FII' then fii=value('SREF_PREFIX',,'os2environment')
if is_cgi=1 then do
say axx
end
else do
if fii='' then do
'VAR 'Axx
end
else do
foo=sref_multi_send(axx)
if foo<0 then exit -1
end
end
return 1
/***********************************************************/
/* create a "dct file" */
make_dctfile:procedure expose vs. swish_version servername realsel realdir
/* parameters */
htmls=vs.!htmls
nocontents=vs.!extlist_Nofollow
outname=vs.!dctfile
fdescribe=vs.!describefile
daindx=vs.!swifile
defdir=vs.!wwwdir
crlf='0d0a'x
/* These are used as default "summaries" */
gmess.1=' File not available'
gmess.2=' Summary not available'
gmess.3=' Summary not available'
gmess.4=' No summary available'
/* This is the character used to signal "continuation of a description"
I.e. (assuming continuation_flag='|'
FOOBAR.TXT This is the description of foobar.txt
| And this is the second line.
Note that the | should be the first non space character */
continuation_flag='|'
/* and this is a comment flag */
comment_flag='; '
if vs.!repwith=0 | vs.!repwith='' then do
nreps=0
reprules.0=0
end /* do */
else do
reps=vs.!repwith ; nbb=0
do forever
if reps='' then leave
nbb=nbb+1
parse var reps afile asel reps
reprules.nbb.!old=fixslash(strip(translate(afile)),swish_version)
reprules.nbb.!new=fixslash(strip(translate(asel)),1.3)
end
reprules.0=nbb
end /* do */
call get_swifile /* read filenames from .swi file */
call get_filelist_info /* assign "file types" based on file extension */
if vs.!watch=1 then call write_her(" Creating descriptions for " filelist.0 " files <ol> ")
latestd.=''
latestd.!dir=' '
do m=1 to filelist.0
bigd.m=translate(filelist.m.!original,'/','\')
bigd.m.!title=filelist.m.!title
bigd.m.!size=filelist.m.!size
bigd.m.!ASUMMARY=strip(make_summary(filelist.m,filelist.m.!type,vs.!makesummary))
bigd.m.!sumtype=yaman /* yaman is exposed: 0-none, 1=from contents, 2=from dir-spec file */
if vs.!watch=1 then do
if yaman>0 then
call write_her(' <li> 'bigd.m', 'bigd.m.!title)
else
call write_her(' <li> 'bigd.m', No Description is Available')
end
end /* do */
bigd.0=filelist.0
div=' &^%^& '
div2=' #$*~~#$* '
allf=""
do ii=1 to bigd.0
aa=bigd.ii.!sumtype||div||bigd.ii||div||bigd.ii.!title||div||bigd.ii.!size|| ,
div||bigd.ii.!ASUMMARY
allf=allf||aa
if ii<>bigd.0 then allf=allf||div2
end /* do */
outname=strip(outname)
sike=charout(outname,allf,1)
sike=stream(outname,'c','close')
outname=strip(outname)
div=' &^%^& '
div2=' #$*~~#$* '
allf=""
foo=stream(outname,'c','open write')
if translate(foo)<>'READY:' then do
say "ERROR: could not open " outname
exit
end /* do */
do ii=1 to bigd.0
aa=bigd.ii.!sumtype||div||bigd.ii||div||bigd.ii.!title||div||bigd.ii.!size|| ,
div||bigd.ii.!asummary
allf=allf||aa
if ii<>bigd.0 then allf=allf||div2
if length(allf)>10000 then do
aba=charout(outname,allf)
allf=''
end
end /* do */
if length(allf)>0 then aba=charout(outname,allf)
sike=stream(outname,'c','close')
if vs.!watch=1 then call write_her("</ol>Description-cache (DCT) index file ("outname") has been created.")
return 1
/*********************************************************/
/* read swish file, create a file list (uses reprules found in con file */
get_swifile:
call syssleep 2 /* make sure things are properly closed */
nfiles=get_swish_filelist(daindx)
if nfiles<1 then do
foo=is_error("Error: not a swish index file: "nfiles)
return 0
end
/* convert url style names back to original files */
do nf=1 to nfiles
afil=filelist.nf.!original
do il=1 to reprules.0 /* convert to fully qualified names */
if abbrev(afil,reprules.il.!new)=1 then do
aa=reprules.il.!old
bb=substr(afil,1+length(reprules.il.!new))
aa=aa||bb
leave
end /* Do */
end /* do */
filelist.nf=aa
end /* do */
return nfiles
/****************************/
/* given a filefilst, get descriptions */
get_filelist_info:
/* determine type of file: 2=text, 1=html, 0=non-text */
htmls=translate(translate(htmls),' ','.')
nocontents=translate(translate(nocontents),' ','.')
do mm=1 to filelist.0
aff=filelist.mm
filelist.mm.!type=2 /* assume it's text */
foo=lastpos('.',aff)
if foo=0 then iterate
anext=strip(translate(substr(aff,foo+1)))
if wordpos(anext,htmls)>0 then do
filelist.mm.!type=1
iterate
end
if wordpos(anext,nocontents)>0 then filelist.mm.!type=0
end /* do */
return 0
/***************/
/* ------------------------------------- */
/* create summary info: from explicit description in fdescribe (DESCRIBE.TXT)
or by parsing contents of file
afilename: fully qualified filename to investigate
atype: 1- html, 2-non-html text, 0-non text (of file)
asummary: 1- pre-existent only (in describe.txt),
2-create if necessary
returns a text or html summary, or a numeric code:
1= File not available
2= Summary not available
3= Explicit summary not available
4= Error in routine -- no summary available
yaman is also returned:
0-no description, 1=created, 2=explicit (from describe.txt, or <META> )
*/
make_summary:procedure expose yaman atitle asize fdescribe latestd. comment_flag continuation_flag swish_version
parse arg afilename,atype,asummary
gmess.1=' File not available'
gmess.2=' Summary not available'
gmess.3=' Summary not available'
gmess.4=' No summary available'
yaman=0
eek=stream(afilename,'c','query exists') /* check for existence*/
if eek="" then return gmess.4 /* error */
/* check in directory-specific description file (I.E.; describe.txt) */
if fdescribe<>" " then do
checkd=filespec('d',afilename)||filespec('p',afilename)
checkd=translate(checkd,'\','/')
checkd=strip(checkd,'t,','\')||'\'
if checkd<> latestd.!dir then do
call make_desc(checkd) /* saves latestd.filename=a summary */
latestd.!dir=checkd
end
fnm=strip(translate(filespec('n',afilename))) /* check the descriptions, and return match if found */
if latestd.fnm<>'' then do /* got a match, use it */
yaman=2
return latestd.fnm
end /* do */
end /* check description file */
/* no directory-specific summary -- perhaps create summary from file contents ? */
select
when atype=0 | asummary<2 then /* not text, or not "create description */
return gmess.2
when atype=2 then do /* non-html text, create mode */
alen=min(chars(afilename),300)
stuff=charin(afilename,1,alen)
fpp=stream(afilename,'c','close')
yaman=1
wow=replacestrg(wow,'&','&','ALL')
wow=replacestrg(stuff,'<','<','ALL')
wow=replacestrg(wow,'>','>','ALL')
wow=replacestrg(wow,'"','"','ALL')
return wow
end
when atype=1 then do /* html text, create mode */
alen=min(chars(afilename),10000)
stuff=charin(afilename,1,alen)
fpp=stream(afilename,'c','close')
stuff=space(translate(stuff,' ','00090a0d1a1b'x))
wow=look_header(afilename)
if wow<>0 then do
yaman=2
return wow
end /* Do */
if wow=0 & asummary<>2 then
return gmess.4
WOW=LOOK_HTAG() /* use <Hn> for summary */
if wow<>0 then do
yaman=1
return wow
end /* Do */
return gmess.3
end
otherwise do
say " ERROR: should not be here in make summary "
return gmess.4
end
end
/******************/
/* read a description file with possible continuation lines */
make_desc:procedure expose comment_Flag continuation_flag latestd. fdescribe
parse arg checkd
latestd.=''
foo2=checkd||fdescribe
if stream(foo2,'c','query exists')="" then do /*no such file */
checkd.0=0
return 0
end /* do */
aname='';build1=''
do forever
if lines(foo2)=0 then leave
if abbrev(strip(alin),comment_flag) then iterate /* comments */
alin=strip(linein(foo2))
if abbrev(alin,continuation_flag)=1 then do /* continuations */
build1=build1||substr(alin,length(continuation_flag)+1)
iterate
end /* else, got a file name. So write prior entry */
if aname<>'' then do
fnm=strip(translate(filespec('n',aname))) /* check the descriptions, and return match if found */
latestd.fnm=build1
end
parse var alin aname build1
end /* do */
if aname<>'' then do
fnm=strip(translate(filespec('n',aname))) /* check the descriptions, and return match if found */
latestd.fnm=build1
end
xx=stream(foo2,'c','close')
return igoo
/* ----------------------------------------------------------------------- */
/* Look for "desc" field in header */
/* ----------------------------------------------------------------------- */
look_header: procedure expose stuff url_title swish_version
parse arg afile
dowrite=0
do until stuff=""
parse var stuff p1 '<' tag '>' stuff
if translate(word(tag,1))="HEAD" then do /* now in head !*/
dowrite=1
iterate
end
if dowrite=0 then iterate /* wait till we get into head .. */
if translate(word(tag,1))="/HEAD" then /* out of head, all done ! */
leave
/* IT IS A TITLE TAG? */
if translate(word(tag,1))="TITLE" then do
parse var stuff url_title '<' footag '>' stuff
end
/* is it a META HTTP-EQUIV or a META NAME ? */
if translate(word(tag,1))="META" then do
parse var tag ameta atype '=' rest
tatype=translate(atype)
if tatype="HTTP-EQUIV" | tatype="NAME" then do
parse var rest aval1 rest
REST=STRIP(REST)
aval1=strip(aval1) ;
aval1=strip(aval1,,'"')
if abbrev(translate(aval1),'DESC')<>1 then iterate
aval2=" "
foo1=ABBREV(translate(rest),'CONTENT')
if foo1>0 then do
PARSE VAR REST FOO '=' AVAL2
aval2=strip(aval2)
aval2=strip(aval2,'b','"')
WOW=LEFT(AVAL2,500)
return WOW
end
end /* name or http-equiv */
end /* meta */
end /* stuff */
return 0
/* ----------------------------------------------------------------------- */
/* Extract <hn> fields */
/* ----------------------------------------------------------------------- */
look_htag: procedure expose stuff filename swish_version
stuff0=left(stuff,1000)
amessage=""
dowrite=0
do until stuff=""
parse var stuff p1 '<' tag '>' stuff
ttag=translate(word(tag,1))
if wordpos(ttag,' H1 H2 H3 H4 TITLE')>0 THEN DO /* grab stuff */
parse var stuff amess '<' tag2 '>' stuff
amessage=amessage||amess||'<b> | </b>'
end
end
if amessage="" then do /* getting desperate -- grab any old words! */
do until stuff0=""
parse var stuff0 p1 '<' tag '>' stuff0
amessage=amessage||' '||p1
end
end
if amessage="" then
return 0
amessage=left(amessage,300) /* keep it short */
return amessage
/* ------------- */
/* ----------------------------------------------------------------------- */
/* REPLACESTRG: In string astring, find first occurence substring target and
. replace it with substring putme
. if no target, return unchanged astring
. if no putme, then remove target
. if type=backward, then find/change LAST occurence
. if type=all, find/change all occurences
. if exactmatch=yes, then do not capitalize during search (exact match only */
/* ----------------------------------------------------------------------- */
replacestrg:procedure
exactmatch=0
backward=0 ; doall=0
parse arg astring , target , putme , type , exactmatch
type = translate(type)
if type="BACKWARD" then backward="YES"
if type="ALL" then doall="YES"
iat=1
joelen=length(target)
joelen2=length(putme)
doagain: /* here if doall=yes */
if exactmatch="YES" then do
if backward="YES" then
joe= lastpos(target,astring)
else
joe= pos(target,astring,iat)
end
else do
if backward="YES" then
joe= lastpos(translate(target),translate(astring))
else
joe= pos(translate(target),translate(astring),iat)
end
if joe=0 then
return astring
astring=delstr(astring,joe,joelen)
if putme<>' ' then
astring=insert(putme,astring,joe-1)
if doall="YES" then do
iat=joe+joelen2
signal doagain
end
/* else, all done */
return astring
/*********************************************/
/* SHOW list of SEARCH FORMS */
/*********************************************/
show_Forms:procedure expose SWISH_DIR vs. is_cgi swish_version
parse arg list
crlf='0d0a'x
if is_cgi=1 then do
call dumpit('content-type: text/html')
call dumpit("")
end /* do */
dafile='<html><head><title>List of SWISH search forms</title></head></body>'crlf
dafile=dafile||'<a name="TOP"><h2>List of SWISH search forms </h2></a>'crlf
goindx=stream(SWISH_DIR'\goswish.ind','c','query exists')
if goindx<>"" then
yow=charin(goindx,1,chars(goindx))
else
yow=""
nin=0
do until yow=""
parse var yow aline (crlf) yow ; aline=strip(aline)
if aline="" then iterate
if abbrev(aline,';')=1 then iterate
parse var aline theurl','thefile','hoog','thetime','thedesc
parse upper var hoog theswi theconf thedct thedescribe
if thefile='' | theswi='' | theurl='' then iterate
if stream(thefile,'c','query exists')='' then iterate /* relevant files still exist? */
if stream(theswi,'c','query exists')='' then iterate
nin=nin+1
outs.nin='<a href="'theurl'">'thedesc'</a> <em>( 'thetime ')</em>'
end
if nin=0 then do /* no legit entries */
dafile=dafile||' <b>Sorry.</b> Currently, no search forms are available.</BODY> </HTML> '
if is_cgi=0 then do
call write_her(dafile)
end
else do
say dafile ; dafile=''
end
return 0
end
/* got some still alive forms -- present them in a list */
dafile=dafile||'<b> The following search indices are current available:</b><br><ul>'
if is_cgi=1 then do
call dumpit(dafile); dafile=''
end /* do */
do mm=1 to nin
if is_cgi=0 then do
dafile=dafile||crlf||'<li>'outs.mm
end
else do
call dumpit(crlf||'<li>'outs.mm) ; dafile=''
end
end
if is_cgi=0 then do
dafile=dafile||crlf||'</ul></body></html>'
end
else do
call dumpit(crlf||'</ul></body></html>') ; dafile=''
end
if is_cgi=0 then do
gaz=value('SREF_PREFIX',,'os2environment')
if gaz='' then
'VAR type text/html name dafile '
else
foo=sref_gos('VAR type text/html name dafile ',dafile)
end
else do
call dumpit(dafile)
end
return 1
/*********************************************/
/* regenerate using given configureation file */
use_conffile:procedure expose SWISH_DIR vs. is_cgi swish_version
crlf='0d0a'x
if is_cgi=1 then do
call dumpit('content-type: text/html')
call dumpit("")
end /* do */
dafile='<html><head><title>Can not Regenerate a SWISH index</title></head></body>'crlf
dafile=dafile||'<a name="TOP"><h2>Can not Regenerate a SWISH index </h2></a>'crlf
aconf=stream(vs.!file,'c','query exists')
if aconf='' then do
dafile=dafile||' No such configuration file: 'vs.!file'</body></html>'
signal nocando
end
isize=stream(aconf,'c','query size')
foo=stream(aconf,'c','open read')
if abbrev(translate(foo),'READY')=0 then do
dafile=dafile||' Unable to open configuration file: 'aconf'</body></html>'
signal nocando
end
getit=charin(aconf,1,isize)
foo=stream(aconf,'c','close')
return aconf||crlf||getit
nocando: /* error */
if is_cgi=0 then do
gaz=value('SREF_PREFIX',,'os2environment')
if gaz='' then
'VAR type text/html name dafile '
else
foo=sref_gos('VAR type text/html name dafile ',dafile)
end
else do
call dumpit(dafile)
end
return 0
/*********************************************/
/* choose a .CON file, for regenerating an index */
choose_confile:procedure expose SWISH_DIR vs. is_cgi swish_version cgi_string
parse arg list
crlf='0d0a'x
if cgi_string='' then cgi_string='/cgi-bin/'
if is_cgi=1 then do
call dumpit('content-type: text/html')
call dumpit("")
end /* do */
dafile='<html><head><title>Regenerate a SWISH index</title></head></body>'crlf
dafile=dafile||'<a name="TOP"><h2>Regenerate a SWISH index </h2></a>'crlf
goindx=stream(SWISH_DIR'\goswish.ind','c','query exists')
if goindx<>"" then
yow=charin(goindx,1,chars(goindx))
else
yow=""
nin=0
do until yow=""
parse var yow aline (crlf) yow ; aline=strip(aline)
if aline="" then iterate
if abbrev(aline,';')=1 then iterate
parse var aline theurl','thefile','hoog','thetime','thedesc
parse upper var hoog theswi theconf thedct thedescribe
if theconf='' then iterate
if stream(thefile,'c','query exists')='' then iterate /* relevant files still exist? */
if stream(theconf,'c','query exists')='' then iterate
nin=nin+1
if is_cgi=1 then
outs.nin='<a href="'cgi_string'GOSWISH.CMD?MODE=2REGEN&file='theconf'&swifile='theswi'&searchdoc='theurl
else
outs.nin='<a href="GOSWISH?MODE=2REGEN&file='theconf'&swifile='theswi'&searchdoc='theurl
outs.nin=outs.nin||'">'thedesc'</a> '
outs.nin=outs.nin': <a href="'theurl'">search form</a>'
outs.nin=outs.nin|| ' <em>('thetime')</em>'
end
if nin=0 then do /* no legit entries */
dafile=dafile||' <b>Sorry.</b> Currently, no configuration files are available.</BODY> </HTML> '
if is_cgi=0 then do
call write_her(dafile)
end
else do
say dafile ; dafile=''
end
return 0
end
/* got some still alive forms -- present them in a list */
dafile=dafile||'<b> The following configuration files are current available:</b><br><ul>'
if is_cgi=1 then do
call dumpit(dafile); dafile=''
end /* do */
do mm=1 to nin
if is_cgi=0 then do
dafile=dafile||crlf||'<li>'outs.mm
end
else do
call dumpit(crlf||'<li>'outs.mm) ; dafile=''
end
end
if is_cgi=0 then do
dafile=dafile||crlf||'</ul></body></html>'
end
else do
call dumpit(crlf||'</ul></body></html>') ; dafile=''
end
if is_cgi=0 then do
gaz=value('SREF_PREFIX',,'os2environment')
if gaz='' then
'VAR type text/html name dafile '
else
foo=sref_gos('VAR type text/html name dafile ',dafile)
end
else do
call dumpit(dafile)
end
return 1
/*********************************************/
/* NOT FULLY SUPPORTED */
/* choose a descriptive summaries file, for regenerating an index */
choose_dctfile:procedure expose SWISH_DIR vs. is_cgi swish_version
parse arg list
crlf='0d0a'x
if is_cgi=1 then do
call dumpit('content-type: text/html')
call dumpit("")
end /* do */
dafile='<html><head><title>Regenerate a SWISH index</title></head></body>'crlf
dafile=dafile||'<a name="TOP"><h2>Regenerate a SWISH index </h2></a>'crlf
goindx=stream(SWISH_DIR'\goswish.ind','c','query exists')
if goindx<>"" then
yow=charin(goindx,1,chars(goindx))
else
yow=""
nin=0
do until yow=""
parse var yow aline (crlf) yow ; aline=strip(aline)
if aline="" then iterate
if abbrev(aline,';')=1 then iterate
parse var aline theurl','thefile','hoog','thetime','thedesc
parse upper var hoog theswi theconf thedct thedescribe
if theconf='' | thefile='' | thedct='' then iterate
if stream(thefile,'c','query exists')='' then iterate /* relevant files still exist? */
if stream(theconf,'c','query exists')='' then iterate
nin=nin+1
outs.nin='<a href="GOSWISH?MODE=2DREGEN&file='theconf'&swifile='theswi'&searchdoc='theurl
outs.nin=outs.nin||'&dctfile='thedct'&describefile='thedescribe
outs.nin=outs.nin||'">'thedesc'</a> '
outs.nin=outs.nin': <a href="'theurl'">search form</a>'
outs.nin=outs.nin|| ' <em>('thetime')</em>'
end
if nin=0 then do /* no legit entries */
dafile=dafile||' <b>Sorry.</b> Currently, no configuration files are available.</BODY> </HTML> '
if is_cgi=0 then do
call write_her(dafile)
end
else do
say dafile ; dafile=''
end
return 0
end
/* got some still alive forms -- present them in a list */
dafile=dafile||'<b> The following configuration files are current available:</b><br><ul>'
if is_cgi=1 then do
call dumpit(dafile); dafile=''
end /* do */
do mm=1 to nin
if is_cgi=0 then do
dafile=dafile||crlf||'<li>'outs.mm
end
else do
call dumpit(crlf||'<li>'outs.mm) ; dafile=''
end
end
if is_cgi=0 then do
dafile=dafile||crlf||'</ul></body></html>'
end
else do
call dumpit(crlf||'</ul></body></html>') ; dafile=''
end
if is_cgi=0 then do
gaz=value('SREF_PREFIX',,'os2environment')
if gaz='' then
'VAR type text/html name dafile '
else
foo=sref_gos('VAR type text/html name dafile ',dafile)
end
else do
call dumpit(dafile)
end
return 1
/******************************************************************/
/* THIS IS THE SEARCH COMPONENT OF GOSWISH */
/******************************************************************/
SEARCH_IT:procedure expose SWISH_DIR swish_version is_cgi servername tempfile ,
all_sets verb uri reqstrg def_htmls use_swish_dll
parse arg list
signal on error name errarf ; signal on syntax name errarf ;
if is_cgi=1 then do
method = value("REQUEST_METHOD",,'os2environment')
verb=method
servername=value("SERVER_NAME",,'os2environment')
end
else do
bigstuff=''
end /* do */
crlf='0d0a'x
/* A temporary file to capture output from SWISH */
turkey=SWISH_DIR'\ST$?????.OUT'
TEMPOUT = systempfileName(turkey)
searchwhat='documents'
if is_cgi=1 then do
call dumpit "Content-type: text/html"
call dumpit ' '
end
if tempout = "0" | tempout="" then do
tt='<!doctype html public "-//IETF//DTD HTML 2.0//EN">' crlf ,
"<html><head><title>Index search results </title></head>" crlf ,
"<body> <STRONG> ERROR: Could not access working directory </STRONG>" crlf ,
" </BODY> </HTML> "
call dumpit tt
signal donesearch
end
keywords='help'
index_file="INDEX.SWI"
dct_file=' '
plist=''
ndofiles=20
didnew=0
swopts=' '
header_file=' '
footer_file=' '
search_link=''
isfilesearch=0 /* 0=ignore, 1= path&filename search, 2=description search, 3= filename search */
aheader="Search the site-index "
ncmt=0 ; door=0
summary=0
nfound=0
NUMBEROFHITS=0
exists=0
add_hit_num=0
start=0
max_find=-1 /* if max_find is set to 0 below, then we get "all" the matches */
incache=0
dctindx.=0
dcache.=0 ; dcachel.=0
cache_type=0 /* 0=none, 1=regular, 2=structured */
/* newlist is needed to make "pointers to next set of matches */
if is_cgi=0 then do
if verb='GET' then
parse var uri newlist '?' list
else
newlist=reqstrg
end
else do
newlist=value('SCRIPT_NAME',,'os2environment')
end /* do */
newlist=newlist||'?' /* links have to be "GETS" */
/* Rescan options list... */
do until list=""
parse var list v1 '&' list ; oldv1=v1
parse var v1 avar '=' aval ; avar=translate(avar) ;
aval=decodekeyval(translate(aval,' ','+'))
aval=strip(aval,,'"')
if abbrev(avar,"KEYWORD")=1 then do
keywords=decodekeyval(translate(aval,' ','+'))
end
if avar='H1' | avar='HEADER' | avar='H2' then do
aheader=decodekeyval(translate(aval,' ','+'||'000d0a09'x))
if avar='H1' then aheader='<h1>'aheader'</h1>'
if avar='H2' then aheader='<h2>'aheader'</h2>'
end
if abbrev(avar,'HEADER_FILE')=1 then do
header_file=decodekeyval(translate(aval,' ','+'))
header_file=strip(translate(header_file,'\','/'),'t','\')
end
if abbrev(avar,'FOOTER_FILE')=1 then do
footer_file=decodekeyval(translate(aval,' ','+'))
footer_file=strip(translate(footer_file,'\','/'),'t','\')
end
if abbrev(avar,"SEARCH_LINK")=1 then do
search_link=decodekeyval(aval)
end /* do */
if abbrev(avar,'START')=1 then do
tt=translate(decodekeyval(translate(aval,' ','+')))
parse var tt tt1 tt2
if datatype(tt1)='NUM' then start=tt1
if start<0 then start=0
found_matches=tt2
if datatype(tt2)='NUM' then max_find=tt2
if datatype(max_find)<>'NUM' then max_find=-1 /* -1 is a "suppresion" */
oldv1='' /* suppress it in "next match" links -- appropriate start will be added below*/
end /* do */
if abbrev(avar,'SHOWPROP')=1 then do
taval=translate(aval)
if abbrev(taval,'_SUMMARY_')=1 then do /* a SUMMARY synonym */
parse var taval '_SUMMARY_' tt . ; tt=strip(tt)
if tt="NO" then summary=0
if tt="YES" | tt=1 then summary=1
if tt="CREATE"| tt=2 then summary=2
end /* do */ /* and SUMMA will pick this up below */
else do
plist=plist' 'taval
end /* do */
end /* do */
if abbrev(avar,'INDEX')=1 then do
indxfile=''
tmp=aval
do forever
if tmp='' then leave
parse var tmp a1 tmp ; a1=strip(a1) ; a1=translate(a1,'\','/')
if pos(':',a1)=0 then do
a1=SWISH_DIR||'\'||strip(a1,'l','\')
end
if stream(a1,'c','query exists')="" then do
aa=" <p><b>Sorry</b>, the requested search index does not exist (" a1 ") "
call dumpit(aa)
rmessage=' Error: No SWISH index file: 'a1
signal sendher
end
indxfile=indxfile' 'a1
end /* forever */
end
/* text_dct_File is the old name for DCT_FILE */
if abbrev(avar,'TEXT_DESCRIP_FILE')=1 | abbrev(avar,'DCT_F')=1 then do
dct_File=''
tmp=aval
do forever
if tmp='' then leave
parse var tmp a1 tmp ; a1=strip(a1) ; a1=translate(a1,'\','/')
if pos(':',a1)=0 then do
a1=SWISH_DIR||'\'||strip(a1,'l','\')
end
if stream(a1,'c','query exists')="" then do
aa=" <p><b>Warning:</b>, a requested DCT file does not exist (" a1 ")<p> "
call dumpit(aa)
iterate
end
dct_File=dct_File' 'a1
end /* forever */
end
if abbrev(avar,'COMMENT')=1 then do
ncmt=ncmt+1
comments.ncmt=translate(aval, ' ','+'||'00090d0a'x)
end
if abbrev(avar,'COND')=1 then do
select
when abbrev(translate(aval),'Y')=1 then
door=' or '
when abbrev(translate(aval),'O')=1 then
door=' or '
when abbrev(translate(aval),'N')=1 then
door=' not '
otherwise
door=0
end
end
if abbrev(avar,"ADD_HIT")=1 then do
if wordpos(translate(aval),'1 Y YES')>0 then add_hit_num=1
if wordpos(translate(aval),'0 N NO')>0 then add_hit_num=0
end /* do */
if abbrev(avar,'SUMMA')=1 then do
tt=translate(aval)
summary=tt
if tt="NO" then summary=0
if tt="YES" then summary=1
if tt="CREATE" then summary=2
end
if abbrev(avar,'EXIST')=1 then do
tt=translate(aval)
if wordpos(translate(tt),'YES Y 1')>0 then
exists=1
else
exists=0
end
if abbrev(avar,'OPTION')=1 then do /* one of several possible options */
aval=strip(translate(aval,' ','+'))
select
when abbrev(translate(aval),'PATH')=1 then
isfilesearch=1 /* filename */
when abbrev(translate(aval),'SUMMARY')=1 then
isfilesearch=2 /* summary */
when abbrev(translate(aval),'FILE')=1 then
isfilesearch=3 /* summary */
otherwise do
select
when abbrev(AVAL,'-m')=1 then do
parse var aval '-m' ndofiles
if datatype(ndofiles)<>'NUM' then ndofiles=20 /* if bad syntax, use default */
aval='-m '||strip(ndofiles)
end
when aval='-t HB' then searchwhat='Contents of HTML documents'
when aval='-t t' then searchwhat='TITLEs of HTML documents'
when aval='-t ehtc' then searchwhat='<em>descriptive elements</em> in HTML documents'
otherwise nop
end
swopts=swopts||" "||aval /*SWOPTS "accumulates" OPTIONx options */
end /* select aval */
end /* do */
end
if oldv1<>'' then newlist=newlist||oldv1||'&'
end /* Options parsing */
newlist=strip(newlist,'t','&') /* preparatory for adding "next links */
/* -------- We now have all the options ... */
/*** load the one (or more) old-style "dct" files */
if dct_file<>' ' & (summary>0 | isfilesearch>0) then do
div=' &^%^& '
div2=' #$*~~#$* '
ndcts=words(dct_File)
tmpfs=dct_File
ii=0
do forever
if tmpfs='' then leave
parse var tmpfs adfil tmpfs ; adfil=strip(adfil)
if stream(adfil,'c','query exists')='' then do
call dumpit('<p><B>Warning: </b> No such DCT file='adfil)
iterate
end
bobo=stream(adfil,'c','open read')
goofy=charin(adfil,1,10)
if abbrev(goofy,'#GOSWISH')=1 then do
if ndcts>1 then do
call dumpit('<p><B>Warning: </b> can not combine structured DCT file= 'adfil)
iterate
end
istat=load_desc_cache(adfil)
if istat<0 then do
call dumpit,' Error using description cache file: 'istat
signal donesearch
end
incache=DCTINDX.0
cache_type=2 ; scachename=adfil
end /* structured dct */
else do /* regular dct */
llena=stream(adfil,'c','query size')
goofy=charin(adfil,1,llena)
bobo=stream(adfil,'c','open read')
i1=1 ; lengoofy=length(goofy) ;isleave=0
do forever
i2=pos(div2,goofy,i1)
if i2=0 then do
isleave=1
i2=lengoofy
end /* do */
aa=substr(goofy,i1,i2-i1)
i1=i2+length(div2)
ii=ii+1 ; dcache.0=ii
parse var aa dcache.ii.!sumtype (div) dcache.ii (div) dcache.ii.!title (div) ,
dcache.ii.!size (div) dcache.ii.!ASUMMARY
if (isleave=1) then leave
end /* do forever; read lines from a dct ifle */
cache_type=1
end /* is a regular dct */
end /* do forever: reading multiple dct files*/
end /* dctfile <>' '*/
if cache_type=2 & isfilesearch>0 then do /* copy structured dct to non structured */
bodyat=dctindx.!offset+1
fsize=stream(scachename,'c','query size')
goofy=charin(scachename,bodyat,1+fsize-(bodyat+8))
div5='05'x
ii=0
i1=1 ;ii=0 ;leaveit=0
do forever
ii=ii+1
do rr=1 to 6
i2=pos(div5,goofy,i1)
if i2=0 then do
leaveit=1
leave
end /* do */
abb.rr=substr(goofy,i1,i2-i1)
i1=i2+1
end /* do */
if leaveit=1 then leave
dcache.ii.!sumtype=abb.2 ; dcache.ii=abb.3
dcache.ii.!title=abb.4 ; dcache.ii.!size=abb.5
dcache.ii.!asummary=abb.6
dcachel.II=dcache.II
end
DCACHE.0=DCTINDX.0 ; DCACHEL=0=DCACHE.0
drop goofy
end /* do */
if cache_type=1 then do
do mm=1 to dcache.0 /* copy urls to a url array */
dcachel.mm=dcache.mm
end /* do */
dcachel.0=dcache.0
incache=dcache.0
end /* do */
/* Double check the number to find; and if not specified, use the default */
parse var swopts p1 '-m' TOFIND p2 /* How many matches to find? */
IF TOFIND="" then TOFIND=ndofiles
mmx=tofind
if start>0 then do /* If START option given, then adjust the -m option */
MMX=TOFIND+START-1 /* since we might need all of them? */
if max_find=0 then mmx=1000 /* max_find=0 means "this is the first of 1+0 call */
end /* do */
swopts=p1||' -m '||mmx||' '||p2 /* reconstitute the swish options list */
START=MAX(START,1) /* DON'T NEED "START=0" FLAG ANYMORE */
/* if filesearch and no description file, it's an error */
if isfilesearch>0 & dcache.0=0 then do
tt='<!doctype html public "-//IETF//DTD HTML 2.0//EN">' crlf ,
"<html><head><title>Index search results </title></head>" crlf ,
" <STRONG>Sorry</strong> FileSearch requires a description file. </BODY> </HTML> " crlf
call dumpit tt
signal donesearch
end /* Do */
/* write the top part of the response */
aa=""
aa=aa|| '<!doctype html public "-//IETF//DTD HTML 2.0//EN">'
aa=aa|| "<html><head><title>Index search results </title>"
aa=aa||"</head>"
call dumpit(aa)
/* write the header -- use HEADER, H1, H2, and COMMENTS */
aa=""
if header_file<>' ' then do
tff=swish_dir'\'header_file
wow=afileread(tff)
if wow=0 & is_cgi=0 then call pmprintf("GoSWISH warning: no header file="tff)
do ww=1 to wow
aa=aa||crlf||ffread.ww
end /* do */
end /* Do */
if aa="" then do
aa='<body> '||aheader||'<p>'||crlf /* Aheader set by HEADER, H1, and H2 options */
end
call dumpit(aa)
aa="" /* write out "comments" */
do mm=1 to ncmt
aa=aa||' <em> ' comments.mm ' </em> <br>'crlf
end
call dumpit(aa)
/* fix up keyword list (words to search for) */
twords=translate(keywords) ; srchwords=""
/* remove silly srchwords */
do mm=1 to words(twords)
aword=word(twords,mm)
igu=wordpos(translate(aword),'AND OR NOT')
if igu>0 then aword=strip(word('and or not',igu))
srchwords=srchwords||" "||aword
end
/* add implicit NOT or OR conditions? */
if door<>0 & words(keywords)>1 then do /* insert not / or into keyword list */
tmp=word(keywords,1) ; wasand=0
do mmm=2 to words(keywords)
aww=word(keywords,mmm) ; taw=strip(translate(aww))
if wasand=1 then do
tmp=tmp||' '||aww
wasand=0
iterate
end
if translate(taw)="OR"| translate(taw)="AND" | translate(taw)="NOT"then do
tmp=tmp||' '||aww
wasand=1
iterate
end
tmp=tmp||door||aww
end
keywords=tmp
end
/**** NOW we are ready to ask SWISH to do the search! Note the 1.1 and 1.3 modes */
/* Or, search in the "description" file */
if isfilesearch=0 then do
/* read the type of the indexfile(s) */
itype=check_indxfile_type(indxfile) /* returns 11, 12, 13, or error message */
if wordpos(itype,'11 12 13')=0 then do
call dumpit(itype'<p>')
signal donesearch
end /* do */
swish_version=itype /* this is the type to use (effects which swish to use*/
izs=stream(indxfile,'c','query size')
if iz2s=0 | iz2='' then do
call dumpit(' Error. No such SWISH index file: 'indxfile)
call donesearch
end /* do */
if swish_version=11 then do
t1='swish -f '||INDXfile ||' -w '||keywords||' '||swopts||' > '||tempout
end
else do
if plist<>'' then plist=' -p '||plist||' '
t1='swish-e -f '||INDXfile ||' -w '||keywords||' '||swopts||plist||' > '||tempout
end
if use_swish_dll=1 then do /* dll mode */
oof='-f '||INDXfile ||' -w '||keywords||' '||swopts||plist
/* oof='-f '||INDXfile ||' -w '||strip(keywords)||' -t ehtc'
aa=directory('e:\goserve\swish\godata')
oof="-f index12.swi -w help " */
rc=rxswEmulate(oof,"1","FILELINES")
if rc<>0 then do then
call dumpit("GoSwish error (rxswEmulate): "rc)
signal donesearch
end /* do */
gotem=filelines.0
end /* do */
else do /* exe mode */
if is_cgi=1 then t1='@'t1
foodir=directory(SWISH_DIR)
signal on error name askerr2 ; signal on syntax name askerr2
didt1=0
address cmd
t1
address
foodir=directory(foodir)
didt1=1
gotem=afileread(tempout) /* get results from the temporary file SWISH wrote to */
do iij=1 to gotem
filelines.iij=ffread.iij
end /* do */
filelines.0=gotem
goo=sysfiledelete(tempout)
end
signal on error name errarf ; signal on syntax name errarf ; /* reset error loction */
end
else do /* don't use swish inde -- instead, search the description file.... */
gotem=do_fsearch(isfilesearch,keywords,start,ndofiles) /* one of the cache search variants */
end
askerr2: /* jump here if error */
if didt1=0 then do
foodir=directory(foodir)
gotem=afileread(tempout)
call dumpit('<b> SWISH search error, unable to complete request.</b> <pre>')
do iij=1 to gotem
filelines.iij=ffread.iij
call dumpit(filelines.iij)
end /* do */
call dumpit('</pre>')
filelines.0=gotem
goo=sysfiledelete(tempout)
signal donesearch
end
if gotem=0 then do /* nothing returned */
aa=" <p><STRONG> No matches found </STRONG> </BODY> </HTML> "
call dumpit aa
signal donesearch
end
/** Got some results, let's display them */
igot=0
aa=' <b>Searching 'searchwhat' for: </b></tt>'keywords'</tt> <dl>'
call dumpit(aa)
swiver=0
propnames.0=0 /* what property names are returned? */
do mm=1 to gotem
RLINE = filelines.mm
IF RLINE = '' THEN leave
IF RLINE = '.' THEN leave
/* examine comment lines -- should all be at beginning of file */
/* We need to extract "number of hits", DOC PROPERTY, and COUNTS */
IF abbrev(RLINE,'#') = 1 THEN do
parse var rline '#' a1 ':' a2 ; a1=translate(space(a1,0))
select
when a1='NUMBEROFHITS' then DO
IF MAX_FIND=0 THEN max_find=strip(a2)
NUMBEROFHITS=STRIP(A2)
end /* do */
when abbrev(a1,'DOCPROPERTY')=1 then do
parse var a1 'DOCPROPERTY' np
propnames.np=strip(a2) ; propnames.0=np
end /* do */
when a1="SWISHFORMAT1.1" then swiver=11
when a1="SWISHFORMAT1.2" then swiver=12
when a1="SWISHFORMAT1.3" then swiver=13
when a1="GOSWISHSEARCH" then swiver=10 /* goswish search of filenames/summaries */
otherwise nop
end
iterate
end /* do */
/* Split the line into fields. */
/* if here, might be a result, might be an error */
PARSE VAR RLINE R_SCORE R_FILE R_stuff
if translate(r_file)='WORDS:' then iterate /* a 1.1 format comment */
/* check for some kind of error */
trs=strip(translate(r_score))
if abbrev(trs,'SWISH:')+abbrev(trs,'ERR:')+abbrev(trs,'USAGE:')>0 then do
parse var rline . ':' anerr
if strip(translate(anerr))="NO RESULTS" then do
call dumpit('<p><em>NO matches. </em><BR> ')
end
else do
call dumpit('<b>A SWISH error occurred:'anerr' </b><p>')
end
signal donesearch
end /* do */
/* if here, it's a real entry */
igot=igot+1
if igot=1 then do /* on first entry, there might be things to do*/
if swiver=0 then do /* not a swish return */
call dumpit('<b>Error. Not a recognized SWISH format ')
signal donesearch
end /* do */
if swiver=11 then do /* best guess as to # of good entries */
numberofhits=filelines.0-mm
IF MAX_FIND=0 THEN max_find=max(numberofhits,max_find)
end /* do */
end /* do */
if igot<start then iterate /* skip if a START is binding */
/* read fields (possibly propnames, if swish 1.3) */
PARSE VAR R_STUFF '"' R_TITLE '"' R_POSITION R_STUFF
gotprop=0
DO IPQ=1 TO PROPNAMES.0
PARSE VAR R_STUFF '"' APROP.IPq '"' R_STUFF
if aprop.ipq<>'' then gotprop=1
end /* do */
/* Spit out this reference as a HTML link. */
r_file=translate(r_file,'/','\')
r_title=strip(strip(r_title),,'"')
if r_title="" then do
tmp2=translate(r_file,' ','\/'); r_title=word(tmp2,words(tmp2))
end /* do */
if add_hit_num=1 then
aa2='<dt> <em>'igot') </em>   <A href=' r_file '>' r_title '</a>'crlf
else
aa2='<dt> <A href=' r_file '>' r_title '</a>'crlf
/**** MAKE A SUMMARY (either on the fly, or from a DESCRIPTION CACHE file .... */
aa=' <em> Score= ' r_score ' </em> 'crlf
aa=aa||' <code> , ' r_position 'bytes </code> <br>'crlf
if summary>0 | exists>0 then do
oof=''
if add_hit_num=1 then oof='<em>'igot') </em>   '
foo=make_summary2(aa,r_title,r_file,summary,srchwords,exists,gotprop,oof,incache,cache_type)
end
else do
call dumpit(aa2||aa)
if gotproP>0 then call dumpit('<ul>')
end /* do */
if gotprop>0 then do /* display "properties" */
do ihh=1 to propnames.0
if aprop.ihh='' then iterate
aa='<li><b>'propnames.ihh':</b> 'aprop.ihh
call dumpit(aa)
end /* do */
end
if gotprop>0 then call dumpit('</ul>')
nfound=nfound+1
IF IGOT>=(START+TOFIND-1) then leave
end
if igot>start then call dumpit('</dl>')
/* write a summarization line */
makelink=0
select
when NUMBEROFHITS=0 then
call dumpit('<p><em>No matches... </em><BR> ')
when nfound=0 then /* > 0 HITS, BUT ALL LESS THEN START # */
call dumpit('<p> <em> Number of matches less then requested starting match (at # 'start') </em><BR>')
when nfound<tofind & start<2 then
call dumpit("<p> <em> Total of " igot " matches </em><BR>")
otherwise do
if max_find>0 then do
call dumpit("<p> <em> Displaying " (1+igot-start) " of " MAX_FIND" total matches (starting from match # "start ") </em><BR>")
makelink=1
end
else do
call dumpit("<p> <em> Displaying " (1+igot-start) " matches (starting from match # "start ") </em><BR>")
end
end
end
if makelink=1 then do
if max_find>0 then do /* set up links to next/prior matches */
call dumpit('<br>')
if all_sets<>1 then
call show_prior_next
else
call show_all_sets
end /* do */
if search_link<>'' then do
aa=' || <a href="'search_link'">New search?</a><br>'||crlf
call dumpit(aa)
didnew=1
end /* do */
end
call dumpit('<p>')
donesearch: /* skip here on error */
if didnew=0 & search_link<>'' then do
aa=' <a href="'search_link'">New search?</a><br>'||crlf
call dumpit(aa)
end /* do */
/*write a footer file */
if footer_file<>' ' then do
aa=""
if footer_file<>' ' then do
tff=swish_dir'\'footer_file
wow=afileread(tff)
if wow=0 & is_cgi=0 then call pmprintf("GoSWISH warning: no footer file="tff)
do ww=1 to wow
aa=aa||crlf||ffread.ww
end /* do */
call dumpit(aa)
end /* Do */
end /* Do */
sendher: nop
aa='</body></html> '
call dumpit aa
if is_cgi=0 then do
gaz=value('SREF_PREFIX',,'os2environment')
if gaz='' then
'VAR type text/html name bigstuff'
else
foo=sref_gos('VAR type text/html name bigstuff ',bigstuff)
end
return 0
/**************************/
/* links to sets of matches */
show_all_sets:
call dumpit('<br><tt>Other matches:</em> ')
glen=0
do mj1=1 to max_find by tofind
newlist1=newlist||'&START='||mj1||'+'||max_find
call dumpit('<a href="'||newlist1||'">' mj1'</a> ')
glen=glen+1
end /* do */
return 1
/**************************/
/* links to prior & next matches */
show_prior_next:
if igot>tofind then do /* setup link for prior TOFIND */
j1=MAX(1,start-tofind)
newlist1=newlist||'&START='||j1||'+'||max_find
call dumpit('<a href="'||newlist1||'">Prior' tofind ' matches </a> ')
end
if igot<max_find then do /* set up link for next TOFIND */
j1=start+nfound
newlist1=newlist||'&START='||j1||'+'||max_find
eef=' '
if igot>tofind then eef=' || '
call dumpit(eef' <a href="'||newlist1||'"> Next' tofind ' matches </a> ')
end /* do */
return 1
/*******************/
/**************** say ***/
/* say to stdout */
dumpit:procedure expose is_cgi bigstuff
parse arg aa
if is_cgi=0 then do
bigstuff=bigstuff||aa||'0d0a'x
return 0
end /* do */
aa=aa||'0d0a'x
say aa
return 0
/*****************************/
/* check swish indices of a list of indices.
Returns 11 if (all) are 1.1
12 if (all) are 1.2
13 if all are 1.3
Error message if a problem (missing file, mixed types, non-swish index */
check_indxfile_type:procedure
parse arg fils
is11=0 ; is13=0 ; is12=0
do forever
if fils='' then leave
parse var fils afil fils
afil=translate(strip(afil),'\','/')
if stream(afil,'c','query exists')='' then return 'No such file: 'afil
aa=charin(afil,1,80) ;saa=stream(afil,'c','close')
a1=translate(space(aa,0))
select
when abbrev(a1,'#SWISHFORMAT1.1')=1 then is11=1
when abbrev(a1,'#SWISHFORMAT1.2')=1 then is12=1
when abbrev(a1,'#SWISHFORMAT1.3')=1 then is13=1
otherwise return 'Error. Not a SWISH index file: 'afil
end
if (is11+is13+is12)>1 then return 'Error: can not examine a mixture of SWISH index types'
end
iu=(is11*11)+(is13*13)+(is12*12)
if iu=0 then return 'Error. Could not determin SWISH index type'
return iu
/************/
/* read file into ffread stem var */
afileread:procedure expose ffread.
parse arg hfile
crlf='0d0a'x
if stream(hfile,'c','query exists')="" then return 0
tmp=strip(charin(hfile,1,chars(hfile)),'t','1a'x)
tt=stream(hfile,'c','close')
itmp=0
do until tmp=""
itmp=itmp+1
parse var tmp ffread.itmp (crlf) tmp
end /* do */
ffread.0=itmp
return itmp
/***********************************/
/* search files names, etc instead of keyword index
dcache. contains cache index
dcachel. just the urls (for searching in)
filelines. return these to be displayed
isfilesearch: 0= normal keywords, 1=search pathnames, 2=search summarys, 3=search filenames
keywords: keywords to search for (and highlight)
ndofiles: max matches to display
ktall: count all matches (only return ndofiles
*/
do_fsearch:procedure expose dcache. dcachel. filelines. swish_version is_cgi bigstuff
parse arg isfilesearch,keywords,start,ndofiles
keywords='OR '||translate(strip(keywords))
/* seperate out OR AND and NOT keywords. Default is AND (first
one is OR) */
alist.1=' ' ; alist.2=' ' ; alist.3=' ';ismod=1
do mm=1 to words(keywords)
aw=translate(strip(word(keywords,mm)))
oop= wordpos(aw,'OR AND NOT')
if oop=0 then do
alist.ismod=alist.ismod||' '||aw
ismod=2 /* reset to AND */
end
else do
ismod=oop
end /* Do */
end /* do */
oof=keywords
if strip(translate(word(keywords,1)))="OR" then oof=subword(keywords,2)
select
when isfilesearch=3 then
bb='<p><strong> Searching file names for: </strong><code> 'oof||'</code>'||'0d0a'x
when isfilesearch=1 then
bb='<p><strong> Searching path & file names for: </strong><code> 'oof||'</code>'||'0d0a'x
otherwise
bb='<p><strong> Searching <em>summaries </em> for: </strong><code> 'oof||'</code>'||'0d0a'x
end
call dumpit(bb)
ors=alist.1 ; ors.0=0
if ors<>' ' then ors.0=words(ors)
ands=alist.2 ; ands.0=0
if ands<>' ' then ands.0=words(ands)
nots=alist.3 ; nots.0=0
if nots<>' ' then nots.0=words(nots)
/* check each line for ors, ands, and nots */
do mm=1 to dcache.0
isok.mm=0 /* assume faiulre */
select
when isfilesearch=3 then do
aurl=strip(translate(dcachel.mm))
booi=lastpos('/',translate(aurl,'/','\'))
if booi>0 then aurl=substr(aurl,booi+1)
end /* do */
when isfilesearch=1 then do
aurl=strip(translate(dcachel.mm))
end
otherwise do
aurl=strip(translate(dcache.mm.!ASUMMARY))
end
end
/* if it's a not, failure */
do mm2=1 to nots.0
if pos(strip(word(nots,mm2)),aurl)>0 then iterate mm
end
/* all and's have to be there */
do mm2=1 to ands.0
if pos(strip(word(ands,mm2)),aurl)=0 then iterate mm
end /* do */
/*any of the ors */
isok.mm=1
if ors.0=0 then iterate /* >0 ors, 1 must be fulfilled */
do mm2=1 to ors.0
jj=strip(word(ors,mm2))
if pos(jj,aurl)>0 then iterate mm /* success*/
end /* do */
isok.mm=0 /* did not match an ors */
end /* do */
/* if isok=1, then this is a match. Return the first ndo matches in
the filelines. stem variable. Filelines. should contain:
score url title position:
score=100 (that is, no score)
url=dcache.n
title=dcache.n.!title
bytes=title.n.!size
*/
filelines.1='# GoSWISH Search'
imatch=0
do mm=1 to dcache.0
if isok.mm=1 then imatch=imatch+1
end
filelines.2='# Number of hits: 'imatch
noks=2
do mm=1 to dcache.0
if isok.mm=1 then do
noks=noks+1
atitle=dcache.mm.!title ; if atitle="" then atitle=dcache.mm
filelines.noks='100 ' dcache.mm ' ' atitle ' ' dcache.mm.!size
if noks0=(2+start+ndofiles) then leave
end /* Do */
end /* do */
filelines.0=noks
return noks
/* ---------------------------------------------------------------------- */
/* extract summary info from cache-descripton file (or create it on the
fly
Asummary: 1=use preexsiting only, 2=create if necessary
acheck:1=check on existence of file or url
cache_type : 0=none, 1=old style, 2= new (big) style
*/
make_summary2:procedure expose tempfile ddir enmadd transaction dcache. dcachel. ,
swish_version is_cgi bigstuff dctindx. def_htmls
parse arg aa,a_title,aurl,asummary, srchwords,acheck,addli,addhit,incache,cache_type
crlf='0a0d'x
if addli>0 then do
atag='<li>'
end
else do
atag='<dd>'
end
aayes='<dt>'addhit' <A href=' aurl '>' a_title '</a>'crlf
aano='<dt>'addhit' <u>' a_title '</u>'crlf
ishttp=abbrev(strip(translate(aurl)),"HTTP://") /* file, or url? */
/* if acheck=1, then check on existence of file, or of url */
if acheck=1 then do
if ishttp=0 then do
afilenam=aurl
if afilenam<>"" then afilenam=stream(afilenam,'c','query exists')
if afilename="" then
call dumpit(aano||aa)
else
call dumpit(aayes||aa)
end
else do /* use HEAD request for url */
stuff=a_head_url(aurl)
if stuff=0 then
call dumpit(aano||aa)
else
call dumpit(aayes||aa)
end /* do */
end
else do /* no check, assume it exists */
call dumpit(aayes||aa)
end
if asummary<1 then return 0 /* no summary desired, so return */
if addli>0 then call dumpit('<ul>')
if asummary=1 & (cache_type=0 | incache=0 ) then do /* no create, no cache ..*/
call dumpit(' 'atag' <code> Summary not available </code> ')
return 0
end
/******* try and find, or create, a summary */
/* note: .!sumtype values: 0-none, 1=created, 2=explicit */
aurl=translate(aurl)
if cache_type>0 then do /* cache exists:ALWAYS Use it! */
gotit=0
if cache_type=1 then do /* scan regular index */
do mm=1 to dcachel.0
if dcachel.mm=aurl then do
gotit=mm ; leave
end /* do */
end /* do */
end
else do /* extract from the structured index */
gotit=1
arecord=read_desc_record(aurl)
if arecord<>'' then do
div='05'x
parse var arecord sumtype (div) . (div) . (div) dathing
if sumtype=0 then do /* signal "no sumary */
call dumpit(atag' <code> '|| dathing|| ' </code> ')
return 0
end
end
else do /* signal "no match */
gotit=0
end /* do */
end /* do */
if gotit=0 then do /* shouldn't happen (all files should have some entry */
call dumpit(' 'atag' <code> Summary is not available </code> ')
return 0
end
/* if here, got some kind of match */
if cache_type=1 then do
dathing=strip(dcache.GOTIT.!ASUMMARY) /* if cache_type=2, already know it*/
if dcache.gotit.!sumtype=0 then do /* no match signal */
call dumpit(atag' <code> '|| dathing|| ' </code> ')
return 0
end /* Do */
end
wow=space(translate(dathing,' ','00090a0d1a1b'x)) /* cleanup selection */
srchwords2=what_words(srchwords)
do jmm=1 to words(srchwords2)
aword=strip(word(srchwords2,jmm))
if wordpos(translate(aword),'OR NOT AND ( )')=0 then
wow=make_block(aword,wow,'<u>','</u>') /* highlight matches */
end
if dcache.gotit.!sumtype=1 then /* "created" is a "rougher" match */
aa=atag' <code> ' wow ' </code>'
else
aa=atag' ' wow
call dumpit(aa)
return 0
end /* search in description-cache file */
/* if here == no cache, but create */
/***** generate on the fly ***/
anext=''
goo=lastpos('.',aurl)
if goo>0 then
anext=substr(aurl,goo+1)
ishtml=0
if wordpos(translate(strip(anext)),translate(def_htmls))>0 then ishtml=1
/* strip out http://a.b.c/ */
if ishttp=0 then do
if afilenam="" then do
call dumpit(atag' <code> No summary available </code> ')
return 0
end
eek=sysfiletree(afilenam,'aflist','F') /* check for existence*/
if eek<>0 | aflist.0=0 then do /* error */
call dumpit(atag' <code> Summary not available </code> ')
return 0
end
end
/* text/plain summary ... */
if ISHTML=0 then do
if ishttp=1 then do
stuff=get_url(aurl,500)
if length(stuff)>500 then stuff=left(stuff,500)
else
if stuff=0 then do
call dumpit(atag' <code> Summary not available </code> ')
return 0
end
end
else do
filename=aflist.1
filename=strip(word(aflist.1,words(aflist.1)))
alen=min(chars(filename),500)
stuff=charin(filename,1,alen)
end
wow=space(translate(stuff,' ','00090a0d1a1b'x))
wow=replacestrg(wow,'&','&','ALL')
wow=replacestrg(wow,'<','<','ALL')
wow=replacestrg(wow,'>','>','ALL')
wow=replacestrg(wow,'"','"','ALL')
srchwords2=what_words(srchwords)
do jmm=1 to words(srchwords2)
aword=strip(word(srchwords2,jmm))
if wordpos(translate(aword),'OR NOT AND ( )')=0 then
wow=make_block(aword,wow,'<u>','</u>') /* highlight matches */
end
call dumpit(atag' '|| wow)
return 0
end
/* if not html (and not text/plain), return no summary*/
if ISHTML=0 then do
call dumpit(atag' <code> Summary not available </code> ')
return 0
end
/* if here-- html*/
/* and the url points to a legit file; read it in (up to 10000 characters */
if ishttp=1 then do
stuff=get_url(aurl,10000)
if stuff=0 then do
call dumpit(atag' <code> Summary not available </code> ')
return 0
end
end
else do
filename=aflist.1
filename=strip(word(aflist.1,words(aflist.1)))
alen=min(chars(filename),10000)
stuff=charin(filename,1,alen)
end
stuff=space(translate(stuff,' ','00090a0d1a1b'x))
url_title=0
wow=look_header(filename)
if wow<>0 then do
srchwords2=what_words(srchwords)
do jmm=1 to words(srchwords2)
aword=strip(word(srchwords2,jmm))
if wordpos(translate(aword),'OR NOT AND ( )')=0 then
wow=make_block(aword,wow,'<u>','</u>') /* highlight matches */
end
call dumpit(atag' '|| wow)
return 0
end
WOW=LOOK_HTAG()
if wow<>0 then do
do jmm=1 to words(srchwords)
aword=strip(strip(word(srchwords,jmm)),'t','*')
if wordpos(translate(aword),'OR NOT AND ( )')=0 then
wow=make_block(aword,wow,'<u>','</u>') /* highlight matches */
end
call dumpit(atag' <code>'|| wow ||' </code>')
return 0
end
if url_title<>0 then
aa=atag' <code> ' url_title ' </code> '
else
aa=atag' <code> Summary not available </code> '
call dumpit(aa)
return 0
/* do a head request */
a_head_url:procedure
parse arg aurl
crlf='0d0a'x
got=""
aurl=fix_url(aurl)
if abbrev(translate(aurl),'HTTP://')=1 then do
aurl=substr(aurl,8)
end
parse var aurl server '/' request
family ='AF_INET'
httpport=80
rc=sockgethostbyname(server, "serv.0") /* get dotaddress of server */
if rc=0 then do; return 0; end
dotserver=serv.0addr /* .. */
gosaddr.0family=family /* set up address */
gosaddr.0port =httpport
gosaddr.0addr =dotserver
gosock = SockSocket(family, "SOCK_STREAM", "IPPROTO_TCP")
request=strip(request,'l','/')
message='HEAD /'request' HTTP/1.0'crlf'HOST:'server||crlf
message=message||crlf
got=''
rc = SockConnect(gosock,"gosaddr.0")
if rc<0 then do; return 0 ; end
rc = SockSend(gosock, message)
/* Now wait for the response */
do r=1 by 1
rc = SockRecv(gosock, "response", 1000)
got=got||response
if rc<=0 then leave
end r
rc = SockClose(gosock)
parse var got aa (crlf) .
parse var aa a1 a2 a3
if a2>=300 then return 0
return 1
/*--------------------------- */
/* exract search words */
what_words:procedure
parse arg wlist
wlist=strip(translate(wlist,' ','()*'))
if pos('=',wlist)=0 then return strip(space(wlist))
/*else, remove "meta names" */
bm=''
do forever
if wlist='' then return strip(space(bm))
parse var wlist a1 '=' wlist
if words(a1)>1 then do
a1=delword(a1,words(a1))
bm=bm' 'a1
end
end
/* ----------------------------------------------------------------------- */
/* MAKE BLOCK: Replace all occurences of NEEDLE in HAYSTACK
. with delim1 needle delim2.
. If delim1 and delim2 not give, then { AND } are used.
. Example: make_block(boys,' there are wild boys out there','<b>',' </b>')
. returns 'there are wild <b>boys </b> out there'
. (note that spaces are all retained)
*/
/* ----------------------------------------------------------------------- */
make_block:procedure
parse arg needle, haystack, delim1 , delim2, check_case
if delim1="" then delim1='{'
if delim2="" then delim1='}'
build=""
do forever
if check_case<>1 then
mm=pos(translate(needle),translate(haystack))
else
mm=pos(needle,haystack)
if mm=0 then do
build=build||haystack
return build
end
t1=substr(haystack,1,mm-1)
t2=substr(haystack,mm,length(needle))
haystack=substr(haystack,mm+length(needle))
build=build||t1||delim1||t2||delim2
end
/* ---------------------------------------------*/
/* get a url from some site, return first
maxchar characters (if maxchar missing, get 10million (the whole thing?) */
/* ---------------------------------------------*/
get_url:procedure
parse arg aurl,maxchar
if maxchar="" then maxchar=10000000
got=""
aurl=fix_url(aurl)
if abbrev(translate(aurl),'HTTP://')=1 then do
aurl=substr(aurl,8)
end
parse var aurl server '/' request
/* now get the url. This is based on GoServe's MOVEAUD command. It
requires the RxSock.DLL be in your LIBPATH. */
crlf ='0d0a'x /* constants */
family ='AF_INET'
httpport=80
rc=sockgethostbyname(server, "serv.0") /* get dotaddress of server */
if rc=0 then do
return 0
end
dotserver=serv.0addr /* .. */
gosaddr.0family=family /* set up address */
gosaddr.0port =httpport
gosaddr.0addr =dotserver
gosock = SockSocket(family, "SOCK_STREAM", "IPPROTO_TCP")
/* Set up request [HTTP 0.9 style, for all servers] */
message="GET /"request''crlf
got=''
rc = SockConnect(gosock,"gosaddr.0")
if rc<0 then do
return 0
end
rc = SockSend(gosock, message)
/* Now wait for the response */
do r=1 by 1
rc = SockRecv(gosock, "response", 1000)
got=got||response
if rc<=0 then leave
tmplen=length(got)
if tmplen> maxchar then leave
end r
rc = SockClose(gosock)
return got
/* ----------------------------------------------------------------------- */
/* FIX_URL: Make a fully specified http://url out of message */
/* mayl not work if subdirectories have periods */
/* ----------------------------------------------------------------------- */
fix_url:procedure
parse arg message,servername,serverport
/* use defaults if not provided */
if servername="" then servername=get_hostname()
if serverport="" then serverport=80
message=strip(translate(message,'/','\'))
if abbrev(translate(message),"HTTP://")=1 then
return message /* assume the rest is legit */
/* if not a fully qualified http url (i.e. http://xxx.yyy/zzz) then
make it so
Rule: (assuming no http:// in message)
Strip leading any leading /
Look for a / If no slash found,
look for periods. If > 1 found, it's a "default" for a ip address
if <2 found, it's a local file
Check stuff before first /.
If it has any periods, its an ip address (stuff after is the url)
If no periods, it's a local url (stuff before is first subdirectory)
*/
message=strip(message,'l','/')
islash=pos('/',message)
if islash=0 then do
foo=translate(message,' ','.')
if words(foo)>2 then do
anip=message
aport=80
afile=""
end
else do
anip=servername
aport=serverport
afile=message
end
end /* no slashes found */
else do
parse var message p1 '/' p2 /* slash found,extract what's before it */
foo=translate(p1,' ','.')
if words(foo)>1 then do /* >0 periods signifies this is an ip address */
anip=p1
aport=80
afile=p2
end
else do
anip=servername
aport=serverport
afile=message
end
end
isit="http://"||anip
if aport<>80 then
isit=isit||':'||aport
isit=isit||'/'||afile
return isit
/* get the hostname (aa.bb.cc) for this machine */
get_hostname: procedure
do queued(); pull .; end /* flush */
address cmd '@hostname | rxqueue'
parse pull hostname
return hostname
errarf:
say " ERROR at line " sigl' 'rc
return 0
/***********************/
/* read entry names (files, or replacerule'd files, from a 1.3 swish index.
Call as
nfiles=get_swish_filelist(swish_index_file)
where
nfiles: # of files or an error code
and
filelist. is an "expose" stem containing these entries (in "reverse" order),
with tails
n.!original -- the entry name in the index
n.!title -- it's title
n.!size -- it's size
and with
filelist.0=nfiles (assuming no error, else filelist.0=0)
The error codes are:
-1 -- could not file swish_index_file
-2 -- is not a swish_index_file (first line does not look like "# SWISH format 1.3"
-3 -- could not find file count in swish_index_file
-4 -- could not open swish_index_file
-5 -- not a proper 1.3 or 1.2 index file (did not end in a '0a'x)
-6 -- file does not contain nfile entries
-7 -- file contains nfiles-1 entries, but could not find nfile'th entry
-8 -- it's a swish index, but not a 1.1, 1.2 or a 1.3 swish index
-9 -- same as -8
*/
get_swish_filelist:procedure expose filelist.
parse arg filename
cr='0a'x
filelist.0=0
filelen=stream(filename,'c','query size')
if filelen=0 | filelen='' then return -1
aa=stream(filename,'c','open read')
if translate(aa)<>'READY:' then return '-4 '
chunk=charin(filename,1,min(filelen,1000))
parse var chunk aline (cr) chunk
parse upper var aline a1 a2 a3 verswi dpg
verswi=strip(verswi)
if strip(a2)<>'SWISH' | strip(a3)<>'FORMAT' then return -2 /* not a swish file,give up*/
nfiles=0
do mm=1 to 100 /* read lines until you find # Counts: 6193 words, 100 files */
parse var chunk aline (cr) chunk
parse upper var aline . a1 . ',' a2 .
if a1="COUNTS:" then do
nfiles=a2
leave
end /* do */
end /* do */
if nfiles=0 then return -3
if verswi=1.1 then signal is11
if verswi=1.2 then signal is12
if wordpos(verswi,'1.2 1.3')=0 then return -9
/* try this sized chunk, up it if not big enough */
perfile=220
tryagain: /* jump here to try again */
nget=perfile*nfiles
ifrom=max(1,1+filelen-nget) /* get chunk starting here */
chunk=charin(filename,ifrom,nget)
if right(chunk,1)<>'0a'x then return -5 /* 1.3 always ends in '0a'x */
nget2=length(chunk)
ii=lastpos('0a'x,chunk,nget2-1) /* get beyoud property names */
ii2=lastpos('0a'x,chunk,ii-1) /* and some other number stuff */
/* now scan back in chunk, parsing on '0000'x (which seems to signal "end of entry" */
do jj=1 to nfiles-1
ii2=lastpos('0000'x,chunk,ii2-1)
if ii2=0 then do /* perhaps didn't get enough info ? */
if ifrom=1 then return -6 /* can't get more? give up */
perfile=perfile*2 /* so get a bigger chunk this time */
leave
end /* do */
kj=pos('0a'x,chunk,ii2+1)
baa=substr(chunk,ii2,kj-ii2)
baa=strip(translate(baa,' ','00090d0a'x))
parse var baa aa '"' atitle '"' asize .
filelist.jj.!original=translate(strip(aa))
filelist.jj.!title=atitle
filelist.jj.!size=asize
end /* do */
if ii2=0 then signal tryagain /* rexx can be buggy when signaling from a do loop */
/* last one is tricky -- can't search for 0000 */
do forever /* exit via a return or a signal */
ii2=lastpos('0a'x,chunk,ii2-2)
if ii2=0 then do /* perhaps didn't get enough info ? */
if ifrom=1 then return -7 /* can't get more? give up */
perfile=perfile*2 /* so get a bigger chunk this time */
leave
end /* do */
isa=c2d(substr(chunk,ii2+1,1))
if isa>31 then do
kj=pos('0a'x,chunk,ii2+1)
baa=substr(chunk,ii2,kj-ii2)
baa=strip(translate(baa,' ','00090d0a'x))
parse var baa aa '"' atitle '"' asize .
filelist.nfiles.!original=translate(strip(aa))
filelist.nfiles.!title=atitle
filelist.nfiles.!size=asize
filelist.0=nfiles
return nfiles
end
end /* do */
signal tryagain /* only way to get here is by ii2=0 */
/* ----------------------- */
is11: /* jump here if 1.1 format */
/* count lines in the file */
call linein filename,1,0
ndo=0
do until lines(filename)=0
foo=linein(filename)
ndo=ndo+1
end /* do */
/* now get the lines ndo-nfiles to ndo-1 */
call linein filename,1,0
i1=1
do ij=1 to ndo-(i1+nfiles)
foo=linein(filename)
end /* do */
do nf=1 to nfiles /* extract the filenames */
baa=linein(filename)
baa=strip(translate(baa,' ','00090d0a'x))
parse var baa aa '"' atitle '"' asize .
afil=translate(strip(word(aa,1)))
filelist.nf.!original=afil
filelist.nf.!title=atitle
filelist.nf.!size=asize
end /* do */
filelist.0=nfiles
return nfiles
/* ----------------------- */
is12: /* jump here if 1.2 format */
/* count lines in the file */
call linein filename,1,0
ndo=0
do until lines(filename)=0
foo=linein(filename)
ndo=ndo+1
end /* do */
/* now get the lines ndo-nfiles to ndo-1 */
call linein filename,1,0
i1=1
do ij=1 to (ndo-1)-(i1+nfiles)
foo=linein(filename)
end /* do */
do nf=1 to nfiles /* extract the filenames */
baa=linein(filename)
baa=strip(translate(baa,' ','00090d0a'x))
parse var baa aa '"' atitle '"' asize .
afil=translate(strip(word(aa,1)))
filelist.nf.!original=afil
filelist.nf.!title=atitle
filelist.nf.!size=asize
end /* do */
filelist.0=nfiles
return nfiles
/***************************************************/
/* build a "description-cache index"
Call as:
status=build_desc_cache(outname,swifile)
where
outname: .dct file to create
swifile : index file built from
and
status = 1 : success, 0=failure
And where the DESC. variable is used (via an expose)
DESC. should be structured as:
desc.0 : # of records
desc.i : the identifier (as stored in the swish index file)
desc.i.!sumtype : 0= none,
1= generated
2= derived from directory-specific description file
desc.i.!title : the title (as stored in the swish index file)
desc.i.!size : the size (as stored in the swish index file)
desc.i.!summary : the summary. Might be "No Summary Available "
*/
build_desc_cache:procedure expose desc.
parse arg outname,amessage
/*
The structure is:
idstring : identifies the file type, starts with a #GOSWISH and ends with a crlf
Example: #GOSWISH 1.4 This is descriptive summaries for foo.swi
The idstring must be less then 500 characters.
parameters: A space delimited list of parameters:
NRECS: # of records,
IDBYTES: # of bytes used to score record id digests,
OFFBYTES: # of bytes used to store offset in body-of-records, and
BODYAT: # offset to first byte of body-of-records
indx: list of record-id digests and offsets.
body-of-records: the various records; with fields seperated by '05'x character
Terminator: a string consisting of crlf"END." (useful for checking integrity)
*/
idstring="#GOSWISH 1.4 : "||strip(amessage)||'0d0a'x
/* create a list of digests of each entry name */
do mm=1 to desc.0
md5s.mm=rexx_md0(desc.mm)
end /* do */
/* check for 4 char, 8 char and 16 char uniqueness. If all
these fail, all 32 characters (16 bytes) */
iuse=2
do iss=2 to 8 by 2
iuse=iss*2 /*4,6,8,..,16 */
drop tlist.
drop idlist.
tlist.=0
iok=1 /* assume okay */
do mm=1 to desc.0
a1=left(md5s.mm,iuse) /* left most iuse characters of md5 digest*/
if tlist.a1=1 then do /* is this "id" already used? */
say ' repeated 'iuse ' character id ='a1
iok=0 /* yep, leave and try larger set of character */
leave
end /* do */
tlist.a1=1 /* mark this id as used */
idlist.mm=a1 /* save for later use */
end /* do */
if iok=1 then leave /* this size works */
end /* do */
if iok=0 then
idbytes=16
else
idbytes=iuse/2 /* # hex chars /2 = # of bytes */
/* Build the string of contents. An entry at a time.
Each entry has fields seperated by '05'x.
Each entry starts with a 2 byte size code (hence max entry size is 60k), where
the size includes seperators but NOT the two byte size code
Iats.ii points to the start of the entry (to first byte of the 2 byte size code)
*/
div='05'x
body_of_records=''
do ii=1 to desc.0
blk0=desc.ii.!sumtype||div||desc.ii||div||desc.ii.!title||div||desc.ii.!size
c2=translate(desc.ii.!summary,' ','0001020304050607'x) /* convert some stuff to ' '*/
blk0=blk0||div||c2||div
il=length(blk0)
if il>99999 then do
blk0=left(blk0,99999) /* should never happen, but ... */
il=99999
end
ilc=left(il,5,' ')
blk0=ilc||div||blk0
iats.ii=length(body_of_records)+1
body_of_records=body_of_records||blk0
end
/* Create offset to the entries contained in body_of_records (use iats.)
But first-- how many bytes needed for this offset value? */
select
when length(body_of_records)<64000 then offbytes=2
when length(body_of_records)<16000000 then offbytes=3
otherwise offbytes=4
end
parameters=desc.0' 'idbytes' 'offbytes' '
/* build the index to bigblock: desc.0 items with each item consisting of
an id (with a length of idbytes bytes) and an offset (with a length of offbytes bytes)
*/
indx=''
jpt=offbytes*2
do mm=1 to desc.0
ida=x2c(idlist.mm)
apt= right(d2x(iats.mm),jpt,0)
apt=x2c(apt)
indx=indx||ida||apt
end /* do */
indx=indx||'ENDINDEX'||'0d0a'x
/* we now have id string, index, and body of entries.
Compute total length of idstring + parameters + index + 10 -- add this value
to parameters (in a 8 character integer + crlf) */
isize=length(idstring)+length(parameters)+10+length(indx)+1
parameters=parameters||right(isize,8,' ')||'0d0a'x
/*
Put 'em together and write'em out */
bigblock=idstring||parameters||indx||body_of_records||'0d0a'x||'END.'
ff=sysfiledelete(outname)
sike=charout(outname,bigblock,1)
if sike<>0 then return 0
sike=stream(outname,'c','close')
return 1
/****************************************/
/* return a record, given a string (as pulled from swish index)
Requires dctindx. file (as reated by load_desc_cache) to be expose
Call as:
arecord=read_desc_record(lookfor)
where
lookfor : string to look for (should be one of the identifiers in the swish index file)
and
arecord :the record corresponding to lookfor, or a blank if no such record
Arecord can be parsed using
div='05'x
parse var arecord summary_type (div) title (div) size (div) description
where summary_type: 0= none,
1= generated,
2= derived from directory-specific description file
3= hand entered (i.e.; edit mode
*/
read_desc_record:procedure expose dctindx.
parse arg lookfor
div='05'x
md5=rexx_md0(strip(lookfor))
rr=left(x2c(md5),dctindx.!keylen)
thisoff=dctindx.rr
if thisoff=0 then return ""
off2=thisoff+dctindx.!offset
reclen=strip(charin(dctindx.!file,off2,5))
arec=charin(dctindx.!file,off2,reclen+6)
parse var arec dlen (div) summary_type (div) thename (div) thetitle (div) ,
thesize (div) thesummary (div) .
return summary_type||div||thetitle||div||thesize||div||thesummary
/****************************************/
/* load the index, and other info, from a decription-cache file
Call as:
status=load_desc_cache(dctfile)
where
dctfile : the name of the description cache file
and
status is 1 for okay, or a negative valued error code
error codes are:
-1 = "Not a GoSWISH descriptive-summaries cache file"
-2 = "File corrupted (problem with terminiator) "
-3 = Corrupted GoSWISH description-cache file (improper termination of index): "
And where
dctindx. is set (it's exposed). Note that dctindx. will be intialized.
DCTINDX. is structured as:
DCTINDX.0 = # records
DCTINDX.!KEYLEN : size (in bytes) of the "tails"
DCTINDX.!OFFSET : start (in dctfile) of first record
DCTINDX.!FILE : name of file this is derived from
DCTINDX.!MESSAGE : message stored with file
DCTINDX.atail=offset
where atail is the DCTINDX.!KEYLEN length (in bytes) x2c hash of what you want to lookup
offset is the offset (after DCTINDX.!OFFSET, of the start of this record.
******/
load_desc_cache:procedure expose dctindx.
parse arg dctfile
drop dctindx.
dctindx.=0
fsize=stream(dctfile,'c','query size')
abegin=charin(dctfile,1,min(600,fsize))
parse var abegin agoswish iver ':' amess '0d0a'x abegin
if strip(translate(agoswish))<>'#GOSWISH' then return -1
aend=charin(dctfile,fsize-3,4)
if aend<>'END.' then return -2
parse var abegin nrecs idbytes offbytes bodyat '0d0a'x .
dctindx.!message=amess
dctindx.0=nrecs
dctindx.!keylen=idbytes
dctindx.!offset=bodyat-1
dctindx.!file=dctfile
/* get the index */
iget=((idbytes+offbytes)*nrecs)
goof=charin(dctfile,1,iget+600)
parse var goof . '0d0a'x . '0d0a'x goof
goof=left(goof,iget+8)
if right(goof,8)<>'ENDINDEX' then return -3
do ii=1 to nrecs
igg=((ii-1)*(idbytes+offbytes))+1
atail=substr(goof,igg,idbytes)
dctindx.atail=c2d(substr(goof,igg+idbytes,offbytes) )
end /* do */
return 1
/***************************************************/
/* a hash, based on md5 */
rexx_md0:procedure
parse arg stuff
numeric digits 11
lenstuff=length(stuff)
c0=d2c(0)
c1=d2c(128)
c1a=d2c(255)
c1111=c1a||c1a||c1a||c1a
slen=length(stuff)*8
slen512=slen//512
/* pad message to multiple of 512 bits. Last 2 words are 64 bit # bits in message*/
if slen512=448 then addme=512
if slen512<448 then addme=448-slen512
if slen512>448 then addme=960-slen512
addwords=addme/8
apad=c1||copies(c0,addwords-1)
xlen=reverse(right(d2c(lenstuff*8),4,c0))||c0||c0||c0||c0 /* 2**32 max bytes in message */
/* NEWSTUFF is the message to be md5'ed */
newstuff=stuff||apad||xlen
/* starting values of registers */
a ='67452301'x;
b ='efcdab89'x;
c ='98badcfe'x;
d ='10325476'x;
lennews=length(newstuff)/4
/* loop through entire message */
do i1 = 0 to ((lennews/16)-1)
i16=i1*64
do j=1 to 16
j4=((j-1)*4)+1
jj=i16+j4
m.j=reverse(substr(newstuff,jj,4))
end /* do */
/* transform this block of 16 chars to 4 values. Save prior values first */
aa=a;bb=b;cc=c;dd=d
/* do 4 rounds, 16 operations per round (rounds differ in bit'ing functions */
S11=7
S12=12
S13=17
S14=22
a=round1( a, b, c, d, 0 , S11, 3614090360); /* 1 */
d=round1( d, a, b, c, 1 , S12, 3905402710); /* 2 */
c=round1( c, d, a, b, 2 , S13, 606105819); /* 3 */
b=round1( b, c, d, a, 3 , S14, 3250441966); /* 4 */
a=round1( a, b, c, d, 4 , S11, 4118548399); /* 5 */
d=round1( d, a, b, c, 5 , S12, 1200080426); /* 6 */
c=round1( c, d, a, b, 6 , S13, 2821735955); /* 7 */
b=round1( b, c, d, a, 7 , S14, 4249261313); /* 8 */
a=round1( a, b, c, d, 8 , S11, 1770035416); /* 9 */
d=round1( d, a, b, c, 9 , S12, 2336552879); /* 10 */
c=round1( c, d, a, b, 10 , S13, 4294925233); /* 11 */
b=round1( b, c, d, a, 11 , S14, 2304563134); /* 12 */
a=round1( a, b, c, d, 12 , S11, 1804603682); /* 13 */
d=round1( d, a, b, c, 13 , S12, 4254626195); /* 14 */
c=round1( c, d, a, b, 14 , S13, 2792965006); /* 15 */
b=round1( b, c, d, a, 15 , S14, 1236535329); /* 16 */
a=m32add(aa,a) ; b=m32add(bb,b) ; c=m32add(cc,c) ; d=m32add(dd,d)
end
aa=c2x(reverse(a))||c2x(reverse(b))||c2x(reverse(C))||c2x(reverse(D))
return aa
/* round 1 to 4 functins */
round1:procedure expose m. c1111 c0 c1
parse arg a1,b1,c1,d1,kth,shift,sini
kth=kth+1
t1=c2d(a1)+c2d(f(b1,c1,d1))+ c2d(m.kth) + sini
t1a=right(d2c(t1),4,c0)
t2=rotleft(t1a,shift)
t3=m32add(t2,b1)
return t3
/* add to "char" numbers, modulo 2**32, return as char */
m32add:procedure expose c0 c1 c1111
parse arg v1,v2
t1=c2d(v1)+c2d(v2)
t2=d2c(t1)
t3=right(t2,4,c0)
return t3
/*********** Basic functions */
/* F(x, y, z) == (((x) & (y)) | ((~x) & (z))) */
f:procedure expose c0 c1 c1111
parse arg x,y,z
t1=bitand(x,y)
notx=bitxor(x,c1111)
t2=bitand(notx,z)
return bitor(t1,t2)
/* G(x, y, z) == (((x) & (z)) | ((y) & (~z)))*/
g:procedure expose c0 c1 c1111
parse arg x,y,z
t1=bitand(x,z)
notz=bitxor(z,c1111)
t2=bitand(y,notz)
return bitor(t1,t2)
/* H(x, y, z) == ((x) ^ (y) ^ (z)) */
h:procedure expose c0 c1 c1111
parse arg x,y,z
t1=bitxor(x,y)
return bitxor(t1,z)
/* I(x, y, z) == ((y) ^ ((x) | (~z))) */
i:procedure expose c0 c1 c1111
parse arg x,y,z
notz=bitxor(z,c1111)
t2=bitor(x,notz)
return bitxor(y,t2)
/* bit rotate to the left by s positions */
rotleft:procedure
parse arg achar,s
if s=0 then return achar
bits=x2b(c2x(achar))
lb=length(bits)
t1=left(bits,s)
t2=bits||t1
yib=right(t2,lb)
return x2c(b2x(yib))
/*****************/
/* load various dlls */
load_dll:procedure
/*--- Load REXX libraries ----- */
/* Load up advanced REXX functions */
foo=rxfuncquery('sysloadfuncs')
if foo=1 then do
call RxFuncAdd 'SysLoadFuncs', 'RexxUtil', 'SysLoadFuncs'
call SysLoadFuncs
end
if \RxFuncQuery("SockLoadFuncs") then nop
else do
call RxFuncAdd "SockLoadFuncs","rxSock","SockLoadFuncs"
call SockLoadFuncs
end
if rxfuncquery('rxswLoadFuncs')=1 then do
call RxFuncAdd 'rxswLoadFuncs', 'RXSWISH', 'rxswLoadFuncs'
call rxswLoadFuncs
end /* if */
if rxfuncquery('rxswLoadFuncs')=1 then do
say "GoSWISH: could not find RXSWISH.DLL "
end
return 0