/* SRE-http monitor routine (run as a non-transient thread in same process
as goserve */

/*BEGIN  --- */


/* check that GoServe's settings are appropriate for http/1.1 compliance 
  (1=check, 0=do not check). If 1, and not compliant, error occurs*/
check_compliance=1

/* set to 1 to clear macrospace at startup */
clear_macrospace=0

/* reset after this many loops */
doanyway_loops=300      

 /* set = 1 to occasionally cleanup orphaned cgi-bin temp files */
do_cleanup=1     


/* the maximum size of common, referer and browser log 
  files (in kbytes). When the size of a log file exceeds
  this length, it will be renamed.
  Set to 0 to supress this renaming.
*/
logfile_maxsize=0

/* Size of MD5 cache (used by DOMD5.RXX daemon.
   If 0, then do NOT use md5 daemon (compute each
   md5 as needed.
   A non-0 cache (hence use of the md5 daemon) can speed up 
   throughput (especially if the number of commonly used files
   is fairly small), and may avoid sys3175 errors on some
   systems
   A recommended non-zero size is 800.
   Note: if content_md5=0 (in initfilt.80), 
          you SHOULD set md5_cache=0
*/
md5_cache=0


/* Check MEDIATYP.RXX before checking default "mime type mappings".
   If 0, only check MEDIATYP.RXX when no default "extension to
   mimetype" entry can be found.
   If 1, always check MEDIATYP.RXX, and allow MEDIATYP.RXX 
   entries to override default entries.
   Note: default entries are hard coded in MEDIATYP.SRF
*/
MEDIATYPE_FILE_ALWAYS=1

/* set=1 to suppress clientname lookup (returns ip number whenever
         clientname is asked for (useful if no DNS is available) */
no_dns=0

/* set=1 to suppress search-for & use of superceding realms */
NO_SUPERCEDING_REALM=0

/* max line length to "sref_pmprintf" */
pmprintf_line_length=150 

/* name of the sref_pmprintf log file (in goserve directory) */
pmprintf_log_file='SREHTTP.LOG ' 


/* Number of "variable storage daemons" to start. If you are use 
   SRE-http queues, it can be useful to start multiple instances of the
   variable storage daemon (say, one per queue). The default is 1 
   (see SREFQUE.DOC for details) */
storage_daemons=1

/* set to 0 to suppress dynamic loading of sre-http procedures 
   If you set this to 0, then you must create the SREFPRC.RXL file
   (using the makelib.cmd program) */
use_dynamic_lib=1    


/* Fully qualified directory: the location of the .SRF "macrospace" 
  procedures. 
  If blank, use the default (LIB subdirectory under your goserve directory). 
  We  STRONGLY recommend using the '' (blank) default! */
use_lib_dir=''


/* Fully qualified directory: the location of the SRE-http configuration files
  If blank, use the default (CFG subdirectory under your goserve directory). 
  We STRONGLY recommend using the '' (blank) default! */
CFGs_dir=''


/*END --- */

/* ---------- DO NOT CHANGE BELOW HERE  ----------------*/

signal on error name yipes ; signal on syntax name yipes ;
signal on failure name yipes ; signal on halt name yipes ;


parse arg goserve_pid, thesem,servdir,SERVERPORT,envadd,max_semwait,moreargs,key_preface, ,
                x_limitclients,x_fasfile,x_limittimewait,x_gmtset,x_server

if servdir=" " then do
   say " This SRE-http daemon is NOT meant to be invoked from an OS/2 prompt!"
  exit
end  /* Do */


/* CHeck connection maintain on and gmt */
if check_compliance=1 then do
  a1=x_fastfile   /* extract('fastfile') */
  a2=x_limittimewait /* extract('limittimewait') */
  a3=x_gmtset        /* extract('gmtset') */
  a4=x_server       /*  server('h') */
  parse var a4 .'/' gver
  if a1='ON' then do
     call pmprintf(' Caution: The GoServe Cache is enabled.  ')
     call pmprintf('      The GoServe 2.52 (or less) cache is NOT http/1.1 compliant.')
     call pmprintf('      (that is: the goserve cache should be used with care!')
  end /* do */
  if a2 <= 0 then do
     call pmprintf(' **** ERROR: Connection Maintain is NOT enabled')
     call pmprintf('             Http 1.1 compliance requires persistent connections.')
     call pmprintf('      (set the GoServe-Options-Limits-Connection_Maintain parameter)')
     call gosexit 'Connection Maintain is NOT enabled'
  end /* do */
  if a3='OFF' then do
     call pmprintf(' **** ERROR: GMT not available.')
     call pmprintf('             Http 1.1 compliance requires GMT time information')
     call pmprintf('       (you should check the TZ parameter in CONFIG.SYS)')
     call gosexit 'GMT not available.'
  end /* do */
  if gver<2.52 then do
     call pmprintf(' **** ERROR: Pre 2.52 version of GoServe.')
     call pmprintf('             Http 1.1 compliance requires GoServe 2.52 or above')
     call pmprintf('      (see http://www2.hursley.ibm.com/goserve for the latest GoServe).')
     call gosexit 'Pre 2.52 version of GoServe.'
  end
end

parse var moreargs loadthreshold ',' backupserverlist ','  ,
   delay_seconds ',' message_scramble ',' record_cache_lines ',' logon_limit ',' ssi_extensions ',' ,
   ssi_cache_size ',' ssi_cache_duration ',' ssi_cache_stamp ',' no_no_record ',' hit_superuser_suppress ',' pmprintf_opt ',' ,
   NO_REMOTE_CONFIG '!!' custom_inits '!!' cgi_post_long_get ',' get_decode_options ',' ,
   never_publicurls ',' digest_auth ',' proxy_cache ',' suppress_gzip_te','pre_reply_procedure

loadthreshold=strip(loadthreshold) ; backupserverlist=strip(backupserverlist)
delay_seconds=strip(delay_seconds) ; message_scramble=strip(message_scramble)
record_cache_lines=strip(record_cache_lines)
logon_limit=strip(logon_limit)
pmprintf_opt=strip(pmprintf_opt)
if wordpos(pmprintf_opt,'1 2 3')=0 then pmprintf_opt=1
if wordpos(digest_auth,'Y YES 1')=0 then
   digest_auth=0
else
   digest_auth=1

if wordpos(SUPPRESS_GZIP_TE,'Y YES 1')=0 then
   suppress_gzip_te=0
else
   suppress_gzip_te=1

if pre_reply_procedure='' then pre_reply_procedure=0

a1=left(strip(proxy_cache),1)  /* n_wait or n (n=0,1,2,3, wait=seconts */
if wordpos(a1,'1 2 3')=0 then proxy_cache=0  /* 0 otherwise */

ssi_extensions=strip(ssi_extensions)
ssi_cache_size=strip(ssi_cache_size)
ssi_cache_duration=strip(ssi_cache_duration)
ssi_cache_stamp=upper(strip(ssi_cache_stamp))
no_no_record=strip(no_no_record)
IF WORDPOS(NO_REMOTE_CONFIG,'0 1 2')=0 THEN NO_REMOTE_CONFIG=0
custom_inits=strip(custom_inits)

tmp=upper(strip(cgi_post_long_get))
if datatype(tmp)<>'NUM' then tmp=0
cgi_post_long_get=tmp
if wordpos(tmp,'1 YES Y')>0 then cgi_post_long_get=240
if wordpos(tmp,'0 NO N') then cgi_post_long_get=20000

tmp=upper(strip(get_decode_options))
get_decode_options=0
if wordpos(tmp,'1 YES Y')>0 then get_decode_options=1


/* pmprintf modiification? */
foo=start_pmprintf(pmprintf_opt,pmprintf_line_length,pmprintf_log_file)

if datatype(logon_limit)<>'NUM' then logon_limit=0
if datatype(delay_seconds)<>'NUM' then delay_Seconds=9
if datatype(message_scramble)<>'NUM' then message_scramble=12415

if datatype(doanyway_loops)<>'NUM' then doanyway_loops=150

foo=value('SREF_NODNS',no_dns,'os2environment')

foo=value('SREF_MEDIATYPE_FILE_ALWAYS',mediatype_file_always,'os2environment')

if no_superceding_realm<>1 then no_superceding_realm=0
foo=value("SREF_NO_SUPERCEDING_REALM",no_superceding_realm,'os2environment')

foo=value('SREF_ENABLE_ENCRYPTION',,'OS2ENVIRONMENT')
if wordpos(foo,'0 1 2 3')=0 then do
    foo=value('SREF_ENABLE_ENCRYPTION',0,'os2environment')
end /* do */

foo=value('SREF_DEFAULT_ENCRYPTION',,'OS2ENVIRONMENT')
if  foo='' | foo=0 then do
   foo=value('SREF_DEFAULT_ENCRYPTION','SRE_A','OS2ENVIRONMENT')
end

if datatype(md5_cache)<>'NUM' then md5_cache=0

if \RxFuncQuery("SockLoadFuncs") then nop
else do
       call RxFuncAdd "SockLoadFuncs","rxSock","SockLoadFuncs"
       call SockLoadFuncs
end
foo=rxfuncquery('UZLoadFuncs')   /* load UNZIP dll */
if foo=1 then do
  call RxFuncAdd 'UZLoadFuncs', 'UNZIPAPI', 'UZLoadFuncs'
  call UZLoadFuncs
end

foo=rxfuncquery('UZLoadFuncs')   /* load UNZIP dll */
if foo=1  then call pmprintf(' SRE-http Monitor WARNING: UNZIPAPI.DLL not found ')

if rxfuncquery('sref_fileread')<>0 then do
  ik=rxfuncadd('sref_fileread','rexxlib','LIB_FILEREAD')
  if ik<>0 then call pmprintf(' SRE-http Monitor WARNING: unable to register SREF_FILEREAD')
end


if rxfuncquery('sref_filewrite')<>0 then do
  ik=rxfuncadd('sref_filewrite','rexxlib','LIB_FILEWRITE')
  if ik<>0 then call pmprintf(' SRE-http Monitor WARNING: unable to register SREF_FILEWRITE')
end


if rxfuncquery('srx_md5')=1  then do
  call RXFuncAdd 'SRXLoadFuncs', 'SRXFUNC', 'SRXLoadFuncs'
  call SRXLoadFuncs
end
if rxfuncquery('srx_md5')=1  then 
  call pmprintf("SRE-http Monitor: Unable to load SRX_MD5 from SRXFUNC.DLL")


if max_semwait="" then max_semwait=3000

if clear_macrospace=1 then fo=macroclear()

CALL  load_rxl(0)  /* load macrospace library */


/* set configuration files directory */
if CFGs_dir='' then
   CFGs_dir=servdir||'\CFGS'
else
   CFGs_dir=strip(cfgs_dir,'t','\')
aa=value('SRE_CFGS_DIR',CFGs_dir,'os2environment')

cfglist_file=cfgs_dir||'\CFGLIST.CFG'



IF result<0  then    do       /* fatal error if not found */
  call pmprintf(' SRE-http Monitor: ERROR: could not load macrospace library ')
  call gosEXIT ' could not load macrospace library '
end

IF PRE_REPLY_PROCEDURE<>0 then DO
   FOO=STREAM(PRE_REPLY_PROCEDURE,'C','query exists')
   if foo='' then do
       call pmprintf("SRE-http Monitor: ERROR: no such PRE_REPLY_PROCEDURE: "pre_reply_procedure)
       call gosEXIT ' missing pre_reply_procedure'
   end /* do */
/* load into macrospace */
   foo=macroadd('SREF_PREREPLY_PROC',pre_reply_procedure,'B')
   if foo=0 then do
       call pmprintf("SRE-http Monitor: ERROR: error loading PRE_REPLY_PROCEDURE: "pre_reply_procedure)
       call gosEXIT ' bad pre_reply_procedure'
   end
   foo=value('SREF_PRE_REPLY',1,'os2environment')
   if verbose>1  then call pmprintf("SRE-http Monitor: PRE_REPLY_PROCEDURE enabled ")
end /* do */
else do
   foo=value('SREF_PRE_REPLY',0,'os2environment')
end /* do */


doo=dostid()
oo=dospid()||' '||dostid()

numeric digits 11

call pmprintf(" SRE-http Monitor: Initializing on port "|| serverport || ": " || filter_name' ('filter_number)
call pmprintf(" SRE-http Monitor: Goserve pid ="|| goserve_pid' , Monitor thread '||doo)
call pmprintf(" SRE-http Monitor: Using semaphore "|| thesem)
parse upper version rexxtype .
os2ver=sysos2ver()
call pmprintf(" SRE-http Monitor: Using REXX version: " rexxtype ', under OS/2 ver 'os2ver)


/* cycle through list of custom_init routines */
foo=call_custom_Inits(custom_Inits)


/* after this, use pmprintf_sref */

/* start variable storage daemon */
if storage_daemons=0 | datatype(storage_daemons)<>'NUM' then storage_Daemoms=1
do iss=1 to storage_daemons
   if iss=1 then
     goon=''
   else
     goon='_'||iss
   aa=start_varstore(goon)
end /* do */
call syssleep 1         /* wait for daemons to settle down */

if record_cache_lines>0 then
   foo=pmprintf_sr(" SRE-http Monitor: Record cache file size= "||record_cache_lines)


/* set location of init_File (check cgs_dir first, then servdir */
init_File=stream(cfgs_dir"\INITFILT."||serverport,'c','query exists')
if init_file='' then  init_file=servdir||"\INITFILT."||serverport
filedate.initfilt=file_juldate(init_file)

filedate.cfglist=file_juldate(cfglist_file)


call get_initfilt(0)  /* and read cfglist.cfg */

if result<0 then do
          call pmprintf(' SRE-http Monitor ERROR: aborting due to initfilt error(s) ')
          call gosexit 'initfilt error(s) '
end

call clear_temp(0)

if result<0  then do
  call pmprintf(" SRE-http Monitor ERROR : No INITFILT file ")
  call gosexit "no INITFILT file "
end

DEFREALM_FILE=cfgs_dir||'\ATTRIBS.CFG'
DEFREALM_FILE_temp=tempdata_dir||'\$DFREALM.'||serverport

filedate.DEFREALM=file_juldate(DEFREALM_FILE)

foo= update_addons(0)

mediatyp_file=servdir||"\MEDIATYP.RXX"
filedate.mediatyp=file_juldate(mediatyp_file)
mediatyp_tfile=tempdata_dir||'\MEDIATYP.TMP'
call value 'SREF_MEDIATYP_TFILE',mediatyp_tfile,'os2environment'
call chk_mediatyp(0)


call value 'SREF_DEFREALM_FILE',DEFREALM_FILE,'os2environment'
call value 'SREF_DEFREALM_FILE_TEMP',DEFREALM_FILE_temp,'os2environment'
call make_DEFREALM_FILE_temp(0)

filedate.repstrgs=file_juldate(repstrgs_file)
repsvars.0=0
call chk_repstrgs(0)


filedate.access=file_juldate(access_file)
aa=start_access(0)

filedate.alias=file_juldate(alias_file)
aa=start_alias(0)

filedate.puburl=file_juldate(puburl_file)
aa=start_puburl(0)

filedate.user=file_juldate(user_file)
aa=start_user(0)

filedate.virtual=file_juldate(virtual_file)
aa=start_virtual(0)

call start_srealm(0)

aa=start_ssicache(0)

aa=start_sreproxy(0)
if aa=-1 then do
   call pmprintf(' SRE-http Monitor ERROR: aborting due to sreproxy error ')
   call gosexit 'SREProxy error '
end 

aa=start_postf(0)

if md5_cache>0 then do
   arxx=servdir||'\SREdomd5.cmd'
   foo=n_launch('MD5_DMN_SREF',arxx,md5_cache)
  
   if strip(word(foo,1))<0 then do
       call pmprintf(" SRE-http Monitor: could not launch md5 daemon: "foo)
       foo=value('SREF_MD5DMN',1,'os2environment')
   end
   else do
       call pmprintf(" SRE-http Monitor: MD5 daemon in seperate process "foo)
       md5pid=foo
       foo=value('SREF_MD5DMN',1,'os2environment')
   end
end
else do
   foo=value('SREF_MD5DMN',0,'os2environment')
end


aa=eventsem_create(thesem)
if aa<0 then do
 call pmprintf(" SRE-http Monitor: ERROR: could not create semaphore: "||thesem)
 call gosexit "could not create semaphore: "||thesem
end
foo=eventsem_post(thesem)       /* let the boys have it */

foo=value('SREF_WAIT_FLAG',0,'os2environment')

foo=pmprintf_sr(' SRE-http Monitor: Begin Monitoring parameters files ..... ')
nloops=0
geelist="INITFILT REPSTRGS MEDIATYP ALIAS ACCESS USER VIRTUAL PUBURL CFGLIST DEFREALM "

do forever
  nloops=nloops+1
   IF result<0 then do
      call pmprintf(' SRE-http Monitor ERROR: leaving after rxl error')
      leave
   end

/* get dates of current files  -- 0 if doesnt exist */
   t1.initfilt=file_juldate(init_file)
   t1.cfglist=file_Juldate(cfglist_file)
   t1.DEFREALM=file_Juldate(DEFREALM_FILE)

   t1.repstrgs=file_juldate(repstrgs_file)
   t1.mediatyp=file_juldate(mediatyp_file)

   t1.alias=file_juldate(alias_file)
   t1.puburl=file_juldate(puburl_file)

   t1.access=file_juldate(access_file)
   t1.user=file_juldate(user_file)
   t1.virtual=file_juldate(virtual_file)

   if md5_cache>0 then do            /* md5 cache still healthy? */
        afoo=dosprocinfo('N',md5pid)
        if afoo='' then do
           foo=value('SREF_MD5DMN',-1,'os2environment')
           call pmprintf(' SRE-http Monitor: MD5 digest wil not be computed -- daemon disappeared! ')
           md5_cache=0
        end
   end


/* any of them newer then last stored files */
   redo=0
   do mm=1 to words(geelist)
       oo1=word(geelist,mm)
       if t1.oo1 > filedate.oo1 then do
           redo=1
           filedate.oo1=t1.oo1
        end
   end

   if nloops>doanyway_loops then do         /* every 60 (or so) minutes, reset it anyways */
        nloops=1                  /* just to be safe! */
        redo=1
   end
   foo=value('SREF_REDO',,'os2environment')
   if foo=1 then do 
      redo=1
   end  /* Do */
   foo=value('SREF_REDO',0,'os2environment')  /* reset to 0*/

/* one of three ways of being a redo? then reset */
   if redo=1 then do            /* reset all stuff */

      foo=pmprintf_sr(" SRE-http resetting variables ")

      call get_initfilt(filedate.initfilt)  /* and read hosts.cfg */
      if result<0 then do
          call pmprintf(' SRE-http Monitor ERROR: aborting due to initfilt error(s) ')
          leave
      end
      call start_access(1)
      call start_alias(1)
      call start_puburl(1)

      call start_user(1)

      foo=start_pmprintf(pmprintf_opt,pmprintf_line_length,pmprintf_log_file,1)
      aa=start_postf(1)

      call start_srealm(1)

      call start_virtual(1)
      call chk_repstrgs(0)
      call chk_mediatyp(0)
      call make_DEFREALM_FILE_temp(0)

      call start_sreproxy(1)

      foo= update_addons(0)

/* store dates of just reset files (initfilt may have changed names */
     filedate.access=file_juldate(access_file)
     filedate.alias=file_juldate(alias_file)
     filedate.puburl=file_juldate(puburl_file)

     filedate.user=file_juldate(user_file)
     filedate.virtual=file_juldate(virtual_file)
     filedate.repstrgs=file_juldate(repstrgs_file)
     filedate.mediatyp=file_juldate(mediatyp_file)
     filedate.initfilt=file_juldate(init_file)
     filedate.cfglist=file_juldate(cfglist_file)
     filedate.DEFREALM=file_juldate(DEFREALM_FILE)

     CALL load_rxl(1)

     foo=pmprintf_sr(' SRE-http Monitor: Success resetting parameters ')
    end

/* always check up on cached files (note that they may have
changed if initfilt was updated */

    n=delay(delay_seconds)

/* get current env variables, perhaps write to pmprintf */
   if display_env=1  then do
       foo=pmprintf_sr(" Current SREF environment variables -----  ")
       wow=dosenvlist(envs)
       do kj=1 to envs.0
           tv=strip(envs.kj)
           if abbrev(tv,'SRE')=0 then iterate
           ares=value(tv,,'os2environment')
           iii=min(100,length(ares))
           if abbrev(tv,'SREF_')=1 then 
                parse var tv . '_' . '_' atv
           else
                parse var tv . "_" atv 
           foo=pmprintf_sr(atv'='left(ares,iii))
       end
       foo=pmprintf_sr(' --- end of sref environment variables ')
       display_env=0
   end

/* CAN'T DO THIS UNDER NEW GOSERVE 
   ext1=extract('clients') */

/* note: small chance that this will delete a client's cgi-stuff that
get's invoked just after the above extract('clients'). But, that just
messes 1 client up, and it's so unlikely that it's not worth worrying about */
   if redo=1 & do_cleanup=1 then foo=clear_temp(1)

end  /* forever loop */


exit            /* should never get here ! */

yipes:
call pmprintf(" SRE-http Monitor ERROR at: " sigl', rc='rc )
exit 'Error in SREFMON'

/* --------- END OF MAIN ---------------------------------------- */

/* ------------------------------------------------- */
/* Routine to check, and load if neccessary,  SREFPRC.RXL into macrospace */
/* ------------------------------------------------- */

load_rxl:

if use_dynamic_lib<>1 then do                /* load srefprc.rxl */
  call load_rxl_old
  return 1
end

if use_lib_dir='' then
   lib_dir=servdir||'\LIB'
else
   lib_dir=strip(use_lib_dir,'t','\')

aa=value('SRE_LIBDIR',lib_dir,'os2environment')
tempsref=lib_dir||'\TEMPSREF.CMD'

parse arg eek1
if dosisdir(lib_dir)=0 then do
  call pmprintf(' SRE-http Monitor: FATAL ERROR: could not find Library Directory: 'lib_dir)
  call gosexit 'could not find Library Directory: 'lib_dir
end  /* Do */

nosref0=0
first_load=0
if macroquery('SREF_ERROR')="" then do  /* load rxl library? */
   first_load=1
   call pmprintf('SRE-http Monitor: Library directory= 'lib_dir)
   parse upper version rexxtype .
   if rexxtype="OBJREXX" then do
        call pmprintf(" SRE-http Monitor: ERROR. SRE-http will not run under object rexx ")
        call gosexit  "SRE-http will not run under object rexx "
   end
   else do
       call pmprintf(" SRE-http Monitor: Loading SREFPRC.RXL into macrospace ")
       rxlfile=lib_dir||'\SREFPRC.RXL'
   end
/* get procedure with procnames in it */
   aa=macroload(rxlfile)
   if aa=0 then do
      call pmprintf(" SRE-http Monitor: ERROR: "|| rxlfile ||" not available! "|| aa)
      call gosEXIT  rxlfile ||" not available! "|| aa
   end
   CALL pmprintf(" SRE-http Monitor: Success on macrospace dynamic library load ")
end
filter_name=sref_version()
filter_number=sref_version(,1)



RETURN 1

/* old, non-dynamic version */

load_rxl_old:
nosref0=0
first_load=0
if macroquery('SREF_VERSION')="" then do  /* load rxl library? */
   first_load=1

   parse upper version rexxtype .
   if rexxtype="OBJREXX" then do
        call pmprintf(" SRE-http Monitor: ERROR. SRE-http will not run under object rexx ")
        call gosexit  "SRE-http will not run under object rexx "
   end
   else do
       call pmprintf(" SRE-http Monitor: Loading SREFPRCS.RXL into macrospace ")
       tt=servdir||'\SREFPRCS.RXL'  
   end
   aa=macroload(tt)
   if aa=0 then do
      call pmprintf(" SRE-http Monitor: ERROR: "|| tt ||" not available! "|| aa)
      RETURN -1
   end
   foo=pmprintf_sr(" SRE-http Monitor: Success on macrospace library load ")
end
filter_name=sref_version()
filter_number=sref_version(,1)
return 1



/* md5 daemon (process) launcher. */
n_launch:procedure 

parse arg daemon_name,file_name,init_arg

/* relative file name? Then assume it's under the goserve addon
directory */

fname=strip(upper(file_name))
if pos(':',fname)=0 & abbrev(fname,'\')=0 then do  /*  a relative file */
   addir=sref_value('ADDON_DIR',,'INI')
   if addir<>"" then fname=strip(addir,'t','\')||'\'||fname
end
if fname=' ' then return '-1 Could not find file: 'file_name
fname=stream(fname,'c','query exists')   /* does this file exist */

stat=make_em(daemon_name)            /* create queue and semaphore */
if stat=0 then return '-2 Problem creating queue or semaphore '

/* launch the daemon as a thread. Provide opitonal argument 
foo=rexxthread('F',fname,daemon_name,init_arg)
if foo=0 then return '-3 Daemon could not be launched '
*/

/* launch as process */
'@start "SRE-http MD5 daemon" /C 'fname' 'daemon_name' 'init_arg' '||dospid()
if rc<>0 then call pmprintf('SRE-http Monitor WARNING: rc from start 'fname'='rc) 

wpid=sref_dmn_ask('MD5_DMN_SREF','*PID*',30)

return wpid                /* success */

/*****************************/
/* make queue and semaphore */
make_em:procedure
parse arg aname

usesem='\SEM32\SRE_DMN_'||aname
usequeue='SRE_DMN_'||aname

aqueue=rxqueue('C',usequeue)
if aqueue<>usequeue then do    /* usequese exists, so kill unneeded new q */
  foo=rxqueue('d',aqueue)      /* kill unneeded queue */
  foo=rxqueue('s',usequeue)
  ik=queued()
  do ll=1 to ik               /* clear out pre existing queue */
       pull boop
   end
end

wow=eventsem_query(usesem)
if wow=-187 then do
  foo=eventsem_create(usesem)
  if foo<>0 then return 0
end /* do */
oo=eventsem_reset(usesem)

return 1

/* ------------------------------------------------- */
/* get date (fat and julian) of a file */
/* ------------------------------------------------- */

file_juldate:procedure


parse arg get_file , isquiet
if GET_file=" " then return 0

eek=sysfiletree(translate(get_file,'\','/'),'gosh','FT')
if gosh.0=0 then do  /* no file */
   return 0
end
parse var gosh.1  atime .
aa=sref_juldate('F',atime)
return aa

/* ------------------------------------------------- */
/* clear all $*.80, and other temporary files out of tempdata_Dir */
/* ------------------------------------------------- */
clear_temp:
parse arg cl1

if cl1<>1 then do               /* only do on startup */
  lookstar=tempdata_dir||'\_DIRLIST.IDX'
  foo=sysfiledelete(lookstar)

  lookstar=tempdata_dir||'\MEDIATYP.TMP'
  foo=sysfiledelete(lookstar)

  lookstar=tempdata_dir||'\_*.DSH'         /* delete old directory cache files */
  foo=sysfiletree(lookstar,stuff,'Fo')
  do mm=1 to stuff.0
    foo=sysfiledelete(stuff.mm)
  end /* do */
  if stuff.0>0 then
  foo=pmprintf_sr('SRE-http Monitor: Deleted ' stuff.0 ' old directory cache files from: 'tempdata_dir)

  lookstar=tempdata_dir||'\_*.TMP'         /* delete old .TMP files */
  foo=sysfiletree(lookstar,stuff,'FO')
  do mm=1 to stuff.0
    foo=sysfiledelete(stuff.mm)
  end /* do */
  if stuff.0>0 then
    foo=pmprintf_sr('SRE-http Monitor: Deleted ' stuff.0 ' _*.TMP files from: 'tempdata_dir)

  lookstar=strip(tempdata_dir||'\_T*.'||serverport)         /* delete old .TMP  files */
  foo=sysfiletree(lookstar,stuff,'FO')
  do mm=1 to stuff.0
   foo=sysfiledelete(stuff.mm)
  end /* do */
  if stuff.0>0 then
    foo=pmprintf_sr('SRE-http Monitor: Deleted ' stuff.0 ' _T*.'serverport ' files from: 'tempdata_dir)

  lookstar=strip(tempdata_dir||'\_HT*.'||serverport)         /* delete old remote virtual files */
  foo=sysfiletree(lookstar,stuff,'FO')
  do mm=1 to stuff.0
   foo=sysfiledelete(stuff.mm)
  end /* do */
  if stuff.0>0 then
    foo=pmprintf_sr('SRE-http Monitor: Deleted ' stuff.0 ' _HT*.'serverport ' files from: 'tempdata_dir)


  lookstar=strip(tempdata_dir||'\_ADDPRIV.'||serverport)         /* delete old additional privs  files */
  foo=stream(lookstar,'c','query exists')
  if foo<>'' then do
     foo=sysfiledelete(foo)
     foo=pmprintf_sr('SRE-http Monitor: Deleted additional privileges file ')
  end /* do */

end             /* cleanup on startup only */


/* do on startup, and on periodic cleanup */
nowtime=date('b')+(time('s')/(24*60*60))

lookstar=tempdata_dir||'\~*.'||serverport         /* delete old cgi-bin temp files */
foo=sysfiletree(lookstar,stuff,'Ft')

kkt=0           /* note: only delete if < .1 day (2.4 hours) old */

do mm=1 to stuff.0
   parse var stuff.mm adate ff1 ff2 afile ; afile=strip(afile)
   if cl1==1 then do            /* check time before deleting */
        ttime=dateconv_3(adate,'o','b')
        if nowtime-ttime<0.1 then iterate 
   end
   foo=sysfiledelete(afile)
   kkt=kkt+1
end /* do */
if kkt>0 then
  foo=pmprintf_sr('SRE-http Monitor: Deleted ' kkt ' ~*.80 files from: 'tempdata_dir)

lookstar=tempdata_dir||'\$*.'||serverport         /* delete old cgi-bin temp files */
foo=sysfiletree(lookstar,stuff,'Ft')
kkt=0
do mm=1 to stuff.0
   parse var stuff.mm adate ff1 ff2 afile ;afile=strip(afile)
   if cl1==1 then do            /* check time before deleting */
        ttime=dateconv_3(adate,'o','b')
        if nowtime-ttime<0.1 then iterate 
   end
   foo=sysfiledelete(afile)
   kkt=kkt+1
end /* do */
if kkt>0 then
  foo=pmprintf_sr('SRE-http Monitor: Deleted ' kkt ' $*.80 files from: 'tempdata_dir)


lookstar=strip(tempdata_dir||'\F*.cmd')         /* delete old .TMP  files */
foo=sysfiletree(lookstar,stuff,'Ft')
kkt=0
do mm=1 to stuff.0
   parse var stuff.mm adate ff1 ff2 afile ; afile=strip(afile)
   if cl1=1 then do            /* check time before deleting */
        ttime=dateconv_3(adate,'o','b')
        if nowtime-ttime<0.1 then iterate 
   end
   foo=sysfiledelete(afile)
   kkt=kkt+1
end /* do */
if kkt>0 then
  foo=pmprintf_sr('SRE-http Monitor: Deleted ' kkt ' F*.CMD  files from: 'tempdata_dir)


return 0



/* ------------------------------------------------- */
/* routine to load initfilt.nnn into macrospace
   return 0= no change , 1= change,return<0=error 
  NOte: if line starts with $xxx, then see if xxx = the MACHINE_ID_SRE.
  If not, skip it
*/
/* ------------------------------------------------- */
get_initfilt:
PARSE ARG DACALL

get_file=init_file
if get_file=" " then return 0
oy=stream(get_file,'c','query exists')
if oy=' ' then do
   CALL pmprintf("SRE-http Monitor:FATAL ERROR. INITFILT file not found, "|| get_file)
   call gosexit  "INITFILT file not found, "|| get_file
end

/* get machine if, if set */
machine_id=value('MACHINE_ID_SRE',,'os2environment')  /* should be a global env var */
if verbose>2 then call pmprintf(" SRE-http Monitor: Machine ID = " machine_id)


/* get list of possible host specific variables: and clear their values */
a=rxqueue('s','session')
wow=dosenvlist(envs)
if wow=0 then do
    call pmprintf(" SRE-http WARNING: Environment appears to be empty ")
end /* do */
else do
   do mm=1 to envs.0
      ares0=envs.mm
      if abbrev(upper(ares0),'SREF_')=1 then do
         parse upper var ares0 ares '=' .
         ibeam=lastpos('.',ares)
         if ibeam>0 then do
           cat3=substr(ares,ibeam+1)
           if datatype(cat3)<>'NUM' then do
              parse var ares . '_' . '_' ares1 '=' .
              interpret ares1||'=" " '
              if verbose>3 then foo=pmprintf_sr('SRE-http Monitor: clearing: ' ares1)
           end          /* got a host specific entry ; ie. fix_expire.host2= */
         end  /* got a . ed entry */
      end
   end     /* an sref entry */
end     /* envlist empty */

call default_initfilt           /* default values */

ause=sref_fileread(get_file,'filelines',,'E')
If (ause<=0) then  do               /*no such file,*/
      CALL pmprintf("SRE-http Monitor: FATAL ERROR. INITFILT file unusable")
      call pmprintf('      File read: ' get_file)
      call pmprintf('      fileread response: 'ause)
      call pmprintf('      filelines.0:' filelines.0)
      call pmprintf('      filelines.1:' filelines.1)
      argz=stream(get_file,'c','query size')
      call pmprintf('     Stream query size= ' argz)
      call gosexit "INITFILT file unusable"
end


/* add  auxillary INITFILT.nnnn files? */
foa=add_auxillary('INITFILT','INITFILT.80',serverport,1)
If (foa=0) then  do               /*missing file,*/
      CALL pmprintf("SRE-http Monitor: FATAL ERROR. Missing auxillary INITFILT file")
      call gosexit "Missing AUXILLARY INITFILT file"
end

/*Allow for gratuitous coding calamity by clumsy users */

mm=0 ; nerrs=0

iat1: nop

ok=0            /* assume an error */
/* exit here when entire file read. Before exiting, cleanup and save results */

if mm>=filelines.0 then do    /* nothing more to interpret... SAVE and exit */
   if nerrs>0 then do
     signal off syntax ;   signal off error
     signal on error name yipes ; signal on syntax name yipes ;
     if  nerrs>0 then do
        if verbose>0 then foo=pmprintf_sr(' SRE-http Monitor:' nerrs ' errors in initfil.')
         return  -nerrs               /* any error is fatal */
      end  /* Do */
   end
   call initfilt_checkup

   call save_envstuff

/* check on status of counter files (create if necessary ) */

   if counter_file<>'' then do
       hitmeter_file=filespec('d',counter_file)||filespec('p',counter_file)
       hitmeter_file=strip(hitmeter_file,'t','\')||'\HITMETER.CNT'
   end /* do */
   else do
      hitmeter_file='HITMETER.CNT'
   end 
   res1=sref_init_counter(counter_file, upload_log , ,
                         record_all_file , record_option,hitmeter_file)
   parse var res1 counter_file  upload_log  record_all_file  record_option hitmeter_file
   call value envadd||'COUNTER_FILE',counter_file,'os2environment'
   call value envadd||'UPLOAD_LOG',upload_log,'os2environment'
   call value envadd||'RECORD_OPTION',record_option,'os2environment'
   call value envadd||'RECORD_ALL_FILE',record_all_file,'os2environment'
   call value 'SREF_HITMETER_FILE',hitmeter_file,'os2environment'

   call value envadd||'SERVERPORT',serverport,'os2environment'
   call value 'SREF_SERVERPORT',serverport,'os2environment'

   foo=pmprintf_sr(" SRE-http Monitor: INITFILT file loaded, "||get_file)

   return 1
end


/* --- IF here, there is more stuff to INTERPET */
mm=mm+1
signal off syntax ;   signal off error
signal on syntax name foobar1
signal on error name foobar1
signal on failure name foobar1
signal on halt name foobar1
filelines.mm=fix_me(filelines.mm)  /* convert from foo.host.n to foo.n.host */

goo=strip(filelines.mm)
if goo="" | left(goo,1)=";" then  signal iat1

if abbrev(goo,'$')=1 then do    /* is it machine_Id specific */ 
   parse var goo anid goo ; goo=strip(goo)
   anid=substr(upper(strip(anid)),2)
   if anid<>machine_id then signal iat1  /* not for this "machine" -- so skip it */
end /* do */



/* convert PUBLIC_FILES to PUBLC_URLS */
if abbrev(upper(goo),'PUBLIC_FILES')=1 then
   goo='PUBLIC_URLS'||delstr(goo,1,12)

/* convert PUBLIC_URL. to PUBLC_URLS. */
if abbrev(upper(goo),'PUBLIC_URL.')=1 then
   goo='PUBLIC_URLS'||delstr(goo,1,10)

 if abbrev(upper(goo),'SERVDIR')=1 then do
     foo=pmprintf_sr(' SRE-http Monitor WARNING: INITFILT not allowed to change SERVDIR variable ')
     nop /* don't let it be changed! */
 end
 else do                        /* THIS does the ACTUAL work */
    interpret goo
 end

ok=1

foobar1:                /* here on error */
if ok=0 then do
   nerrs=nerrs+1
   call pmprintf(sigl" !!! WARNING: SRE-http Monitor: ERROR: in initfilt at ")
   call pmprintf("         "||goo)
end


signal iat1

/* ============ END of main  ==================== */



/**********************************/
/* Add entries to repstrgs filelines. variable, from the defrealm_file_Temp.
  Note that this file only has the appropriate port entries
  in it */
add_defrealm_rep:procedure expose defrealm_file_temp filelines.

defrealm=defrealm_file_temp
parse upper arg atype
atype=strip(atype)
crlf='0d0a'x

if defrealm='' then return 0
aa=sref_open_read(defrealm,15,'READ')
if aa<=0 then return 0

ii=stream(defrealm,'c','query size')
if ii=0 | ii='' then return 0

stuff=charin(defrealm,1,ii)
foo=stream(defrealm,'c','close')

do forever
  if stuff="" then return 1
  parse var stuff aline (crlf) stuff
  if abbrev(aline,';')=1 then iterate
  parse var aline btype ':' aline
  if btype<>atype then iterate
  ii=filelines.0+1
  filelines.ii=aline
  filelines.0=ii
end



/* ---------------------------------------------- */
/* read auxillary INITFILT and repstrgs files */
add_auxillary:procedure expose filelines. cfglist_file cfgs_dir
parse upper arg atype,dfile,sport,numeric_tails


if cfglist_file='' then return  1       /* nothing to do */

/* look for files */
foo=translate(stream(cfglist_file,'c','open read'))
if abbrev(foo,'READY')<>1 then do
  call pmprintf('SRE-http Monitor: Unable to open 'cfglist_file ' ('foo)
  return 1            /* unable to open */
end
inj=stream(cfglist_file,'c','query size')
if inj=0 | inj='' then return   1        /* empty file */
astuff=charin(cfglist_file,1,inj)
foo=stream(cfglist_file,'c','close')

crlf='0d0a'x
astuff=astuff||crlf||' '        /* place an elephant in cairo */

/* determine which atype apply to this port, by readling CFGLIST.CFG */
mm=0

/* note: file is organized in blocks */
curport=80              /* defaults port and host */
curhost=''
curfile=''

do forever              /* for all blocks in file */
  if astuff='' then leave       /* all done  (note we always put an elephant in cairo */
  parse var astuff aline (crlf) astuff
  if abbrev(aline,';')=1 then iterate   /* ignore comments */
  if aline='' then do           /* block end */
     if curport<>sport | curfile='' then do     /* different port, or  file not specified */ 
        nop 
     end
     else do        /* otherwise, add this entry to filelist */
        mm=mm+1
        ufiles.mm.!host=curhost
        ufiles.mm.!file=curfile
     end
     curport=80 ; curhost='' ; curfile=''  /* clear block */
     iterate
  end

/* process an entry in this block */
  parse upper var aline ltype ':' lstuff ;ltype=strip(ltype) ; lstuff=strip(lstuff)

  select
    when ltype='PORT' then curport=lstuff
    when ltype='HOST' then curhost=lstuff
    when ltype=atype  then do
       curfile=strip(translate(lstuff,'\','/'),'l','\')
       if pos(':',curfile)=0 then curfile=cfgs_dir||'\'||curfile
    end
    when ltype='*'  then do
       curfile=strip(translate(lstuff,'\','/'),,'\')
       if pos(':',curfile)=0 then curfile=cfgs_dir||'\'||curfile
       curfile=stream(curfile'\'dfile,'c','query exists')
    end

    otherwise nop
  end

end

/* done reading cfglist; add entries from appropriate files */
if mm=0 then return 1     /* no auxillary files of this type */

ufiles.0=mm

do mm=1 to filelines.0              /* retain old fileline */
  ulisttmp.mm=filelines.mm
end
ulisttmp.0=filelines.0


do mm=1 to ufiles.0
  afile=ufiles.mm.!file
  ahost=ufiles.mm.!host

  a=sref_fileread(afile,'ulines',,'E')   /* read it to a stem variable */

  if a=0 | ulines.0=0 then do
      call pmprintf(' SRE-http Monitor WARNING: ** bad auxillary '||atype||': '||afile)
      iterate
  end
   
   call pmprintf('SRE-http Monitor: adding from 'AHOST ' specific 'atype' 'afile ',' ulines.0)

   do ii=1 to ulines.0
        aline=strip(ulines.ii)
        if ALINE=' ' then iterate
        aline=translate(aline,' ','0009'x)
        if  abbrev(strip(aline),';')=1 then iterate
        if atype='REPSTRGS' then
          parse var aline avar aval
        else
            parse var aline avar '=' aval
        ilp=lastpos('.',avar)
        if ilp>0 & numeric_tails=1 then do    /* numeric_tails=1 means "last tail must be a number */
            llstem=substr(avar,ilp+1)
            if datatype(llstem)<>'NUM' then do
                call pmprintf('SRE-http Monitor WARNING: disallowed auxillary entry: 'aline)
               iterate
            end
        end
        if ahost<>'' then  avar=strip(avar)||'.'||strip(ahost)
        ii2=ulisttmp.0+1
        if atype='REPSTRGS' then
           ulisttmp.ii2=avar||' '||aval
        else
            ulisttmp.ii2=avar||'='||aval
        ulisttmp.0=ii2
   end
end

do mm=1 to ulisttmp.0
   filelines.mm=ulisttmp.mm
end
filelines.0=ulisttmp.0
drop ulisttmp.
return 1

/* initfilt repstrgs */


/* ---------------------------------------------- */
/* read ATTRIBs from cfglist_File */
add_attribs:procedure expose  cfglist_file cfgs_dir 
parse upper arg sport

if cfglist_file='' then return  ''       /* nothing to do */

/* look for files */
foo=translate(stream(cfglist_file,'c','open read'))
if abbrev(foo,'READY')<>1 then do
  call pmprintf('SRE-http Monitor: Unable to open: 'cfglist_file' ('foo)
  return ''            /* unable to open */
end
inj=stream(cfglist_file,'c','query size')
if inj=0 | inj='' then return   ''        /* empty file, nothing to add */
astuff=charin(cfglist_file,1,inj)
foo=stream(cfglist_file,'c','close')

crlf='0d0a'x
astuff=astuff||crlf||' '        /* place an elephant in cairo */
nustuff=''

/* determine if any entries (ATTRIBS:), for this port, by readling CFGLIST.CFG */
mm=0

/* note: file is organized in blocks */
aport=80              /* defaults port and host */
ahost='' ; afile=''

do forever              /* for all blocks in file */
  if astuff='' then leave       /* all done  (note we always put an elephant in cairo */
  parse var astuff aline (crlf) astuff
  if abbrev(aline,';')=1 then iterate   /* ignore comments */
  if aline='' then do           /* block end */
     if afile<>''  then do
        if aport=sport then
            nustuff=nustuff||crlf||'Host: 'ahost||crlf||'Include: 'afile||crlf
     end /* a defrealm entry */
     ahost=''
     afile=''
     aport=80
     iterate
   end

/* else, info to store? */
   parse upper var aline ltype ':' lstuff ;
   ltype=strip(ltype) ; lstuff=strip(lstuff)

   select
       when ltype='PORT' then aport=lstuff
       when ltype='HOST' then ahost=lstuff
       when abbrev(ltype,'ATTR')=1 then afile=lstuff
       otherwise nop
   end /* select */

end

return nustuff



/* ---------------------------------------------- */
/* Clean up parameters in initfilt */
/* ---------------------------------------------- */
initfilt_checkup:

checklog=STRIP(translate(checklog))
IF CHECKLOG='YES' then CHECKLOG='ALWAYS'
  t1=wordpos(checklog,'NO ALWAYS INHOUSE')
  if t1=0 then checklog='NO'

if auto_Name=0 then auto_name=" "
   auto_name=translate(auto_name)

/* include html for backward compataability */
check_alias=is_true(check_alias,'Y YES 1 HTM HTML ')

accept_range=is_true(accept_range,'Y YES 1')
no_include=is_true(no_include,'Y YES 1')
no_interpret_code=is_true(no_interpret_code,'Y YES 1')
no_processing=is_true(no_processing,'Y YES 1')
use_stdout=is_true(use_stdout,'Y YES 1')
add_user_name=is_true(add_user_name,'Y YES 1')
add_resource_name=is_true(add_resource_name,'Y YES 1')

check_add_privs=is_true(check_add_privs,'Y YES 1')

if logon_fail_file=' '  then logon_fail_file=0
if access_fail_file=' ' then access_fail_file=0

DEFAULT=STRIP(DEFAULT)
   if default=' ' then default='INDEX.HTM'



/* check for existnce of varouse directories */
mailbox_dir=translate(mailbox_dir,'\','/')
   mailbox_dir=strip(mailbox_dir,'t','\')
if dosisdir(mailbox_dir)=0 then do
     call pmprintf(' SRE-http Monitor WARNING: could not find mailbox_dir: 'mailbox_dir)
     mailbox_dir=""
end  /* Do */

messbox_dir=translate(messbox_dir,'\','/')
   messbox_dir=strip(messbox_dir,'t','\')
if dosisdir(messbox_dir)=0 then do
     call pmprintf(' SRE-http Monitor WARNING: could not find messbox_dir: 'messbox_dir)
     messbox_dir=""
end  /* Do */

config_dir=translate(config_dir,'\','/')
   config_dir=strip(config_dir,'t','\')
if dosisdir(config_dir)=0 then do
     call pmprintf(' SRE-http Monitor WARNING: could not find config_dir: 'config_dir)
     config_dir=datadir()
end  /* Do */



workdata_dir=translate(workdata_dir,'\','/')
   workdata_dir=strip(workdata_dir,'t','\')
if dosisdir(workdata_dir)=0 then do
     call pmprintf(' SRE-http Monitor WARNING: could not find workdata_dir: 'workdata_dir)
     workdata_dir=servdir
end

tempdata_dir=translate(tempdata_dir,'\','/')
   if length(tempdata_dir)>3 then tempdata_dir=strip(tempdata_dir,'t','\')
if dosisdir(tempdata_dir)=0 then do
     foo=tempdata_dir
     tempdata_dir=strip(translate(datadir(),'\','/'),'t','\')
     call pmprintf(' SRE-http Monitor WARNING: could not find tempdata_dir: 'foo', (using 'tempdata_dir)
end


userinfo_dir=translate(userinfo_dir,'\','/')
   userinfo_dir=strip(userinfo_dir,'t','\')
if dosisdir(userinfo_dir)=0 then do
     call pmprintf(' SRE-http Monitor WARNING: could not find userinfo_dir: 'userinfo_dir)
     userinfo_dir=tempdata_dir
end

tempfile_dir=translate(tempfile_dir,'\','/')
   tempfile_dir=strip(tempfile_dir,'t','\')
if dosisdir(tempfile_dir)=0 then do
     call pmprintf(' SRE-http Monitor WARNING: could not find tempfile_dir: 'tempfile_dir)
     tempfile_dir=servdir
end

cgi_bin_dir=translate(cgi_bin_dir,'\','/')
   cgi_bin_dir=strip(cgi_bin_dir,'t','\')
   if cgi_bin_dir="" then cgi_bin_dir=0
if dosisdir(cgi_bin_dir)=0 then do
     call pmprintf(' SRE-http Monitor WARNING: could not find cgi-bin-dir: 'cgi_bin_dir)
     cgi_bin_dir=' '
end  /* Do */


addon_dir=translate(addon_dir,'\','/')
   addon_dir=strip(addon_dir,'t','\')
   if addon_dir="" then addon_dir=0
if dosisdir(addon_dir)=0 then do
     call pmprintf(' SRE-http Monitor WARNING: could not find addon-dir, 'addon_dir ', using : 'servdir)
     addon_dir=servdir
end  /* Do */


/* chek other stuff */

HOME_DIR=STRIP(HOME_DIR)
inhouse_privs=translate(inhouse_privs)
   if inhouse_privs=0 then inhouse_privs=" "
public_privs=translate(public_privs)
   if public_privs=0 then public_privs=" "
user_privs=translate(user_privs)
   if user_privs=0 then user_privs=" "


virtual_file=strip(virtual_file)

ALLOW_ACCESS=TRANSLATE(STRIP(ALLOW_ACCESS))
if allow_access="Y" | allow_access=1 then allow_access="YES"

do_Htaccess=is_true(do_htaccess,'Y YES 1')


ssi_cache_on=is_true(ssi_cache_on,'Y YES 1 ')

ssi_shtml_only=is_true(ssi_shtml_only,'Y YES 1')
DNS_CHECK=translate(dns_check)
if upload_log="" then upload_log=0
if datatype(upload_maxsize)<>'NUM' then
    upload_maxsize=50
if datatype(upload_minfree)<>'NUM' then
    upload_minfree=20000

if datatype(ssi_cache_size)<>'NUM' then
   ssi_cache_size=5000

if datatype(ssi_cache_duration)<>'NUM' then ssi_cache_duration=1
if ssi_cache_duration=0 then ssi_cache_duration=1000000 /* infiinte*/

if wordpos(ssi_cache_stamp,'TIME DATE TIMEDATE DATETIME SIZE ALL')=0 then
   ssi_cache_stamp='ALL'


pre_filter=translate(pre_filter)
post_filter=is_true(post_filter,'Y YES 1')

if smtp_gateway=" " then smtp_gateway=0

hit_owner_suppress=is_true(hit_owner_suppress,'Y YES 1')
hit_superuser_suppress=is_true(hit_superuser_suppress,'Y YES 1')

write_logs=is_true(write_logs,'Y YES 1')

if upper(hit_cache_len)="FILE" then do
   nop
end  /* Do */

else do
  if datatype(hit_cache_len)<>'NUM' then do 
     hit_cache_len=0
  end
  else do
    hit_cache_len=min(hit_cache_len,50)  /* 50 k max */
  end  /* Do */
end

if datatype(hit_cache_DURATION)<>'NUM' then do
     hit_cache_DURATION=15
END
ELSE DO
   HIT_cache_DURATION=MAX(1,HIT_cache_DURATION)
end  /* Do */


if the_realm=0 then do
  if  symbol('inhouse_name')<>"VAR"  then
        the_realm=inhouse_name
  else
       the_realm="OUR WEB SITE"           /* name we call "ourselves" */
end


RECORD_OPTION=TRANSLATE(RECORD_OPTION)
if wordpos(record_option,'YES YES_ALL FILE ')=0 then
     record_option="NO"              /* recording option on?*/

gots=0

hosts.0=0
do m=1 to 100000
   if symbol('hosts.m')<>"VAR" then leave
   if hosts.m=0 then leave
   hosts.0=m
end /* do */


/* add entries from cfgs/cfglist.cfg */

hostfile=cfglist_file
inj=stream(hostfile,'c','query size')
hstuff=''
if inj<>'' & inj<>0 then do
  foo=translate(stream(hostfile,'c','open read'))
  if abbrev(foo,'READY')<>1 then do
     call pmprintf('SRE-http Monitor WARNING: unable to read 'hostfile)
  end /* do */
  else do
     hstuff=charin(hostfile,1,inj)
     foo=stream(hostfile,'c','close')
  end
end /* do */
if hstuff<>'' then do           /* process the hostfile */
  crlf='0d0a'x
  hstuff=hstuff||crlf||' '
  defdata=strip(translate(datadir(),'\','/'),'t','\')
  ahost='' ; adata='' ; anickname=''
  ahitcount='' ; acounter_rxx='' ; asendfile='' ; arecordall=''
  do forever  
     if hstuff="" then leave
     parse var hstuff aline (crlf) hstuff
     aline=translate(strip(aline))
     if abbrev(aline,';')=1 then iterate
     if aline='' then do                /* end of block */
        if ahost<>'' & anickname<>'' then do
          if adata='' then adata=defdata
          alin2=ahost','anickname','adata','ahitcount','acounter_rxx','asendfile','arecordall
          ih=hosts.0+1
          hosts.ih=alin2
          hosts.0=ih
        end
        ahost='' ; anickname='' ; adata=''
        iterate
     end
/* else, process an entry */
     parse var  aline avar ':' avalue ; avar=strip(translate(avar)); avalue=strip(translate(avalue))
     select
        when abbrev(avar,'IP')=1 then ahost=avalue
        when abbrev(avar,'NICK')=1 | avar="HOST" then anickname=avalue
        when abbrev(avar,'DATA')=1 then adata=avalue
        when abbrev(avar,'SEND')=1 then do
          if pos(':',avalue)>0 then
             asendfile=avalue
          else
             call pmprintf("SRE-http Monitor: Ignoring: must use fully qualifed name ("avalue)
        end
        when abbrev(avar,'RECORD')=1 then do
          if pos(':',avalue)>0 then
             arecordall=avalue
         else
             call pmprintf("SRE-http Monitor: Ignoring: must use fully qualifed name ("avalue)
 
        end
        when abbrev(avar,'HIT')=1 then  do
          if pos(':',avalue)>0 then
            ahitcount=avalue
         else
             call pmprintf("SRE-http Monitor: Ignoring: must use fully qualifed name ("avalue)
 
        end
        when abbrev(avar,'COUNTER')=1 then do
          if pos(':',avalue)>0 then
            acounter_rxx=avalue
         else
             call pmprintf("SRE-http Monitor: Ignoring: must use fully qualifed name ("avalue)
 
        end
        otherwise nop
     end
  end                   /* forever scan */
end                     /* hstuff exsits */
        

ralphie=cvtails('DELIM_1',dlist)

delims=0
do m=1 to ralphie

   a1=dlist.m
   a2=translate(a1,' ','.')
   if words(a2)=1 then do
        if datatype(a1)='NUM' then do
           tmp1=DELIM_1.a1
           if tmp1='0' then iterate
           delims=max(delims,a1)
        end  /* Do */
    end  /* Do */
   if words(a2)=2 then do
        if datatype(word(a2,1))='NUM' then do
           ahost=word(a2,2)
           tmp1=DELIM_1.a1
           if tmp1='0' then iterate
           if symbol('DELIMS.'||ahost)='VAR' then
                delims.ahost=max(delims.ahost,word(a2,1))
           else
                delims.ahost=word(a2,1)
        end  /* Do */
    end  /* Do */
end



crlf='0d0a'x
FPO=MAKE_HEAD_FOOT()

/* creates HEADERS FOOTERS HEADERS. FOOTERS. HEADLIST. FOOTLIST. NHEADS NFOOTS */

auto_header=upper(auto_header)

suppress_alias=0 ; suppress_virtual=0 ; suppress_access=0
suppress_user=0 ; check_doq=0
if (alias_file=" " | alias_file=0)  then
        suppress_alias=1
if virtual_file=" " | virtual_file=0 then
        suppress_virtual=1
if (user_file=" " | user_file=0 ) then
        suppress_user=1
if access_file=" "| access_file=0  then
        suppress_access=1

if (suppress_alias+suppress_user+suppress_access+suppress_virtual+never_publicurls)>0 then
   check_doq=1

return 0


/* ------------------------------------------------- */
/* routine to set default initfilt.80  */
/* ------------------------------------------------- */
default_initfilt:

/* variables that can be changed by configure */

display_env=0
checklog='NO'           /* Free entry */
the_realm=0           /* name we call "ourselves" , 0 will be replaced generically*/
home_name=" "              /* The colloquial (not necessrily ip) domain name */
auto_header="NO"        /* no, always, head */
AUTO_NAME=0         /* 0=none, or a list with *.HTM, !CREATE, file.nam */
CHECK_alias="YES"   /* : YES=yes, NO=None, HTML=.HTM (or .HTML)  */
not_found_url='<a href="/"> Visit the home_name home page? </a> '   /* Message that is sent with no such url  */
pre_filter="NO"         /* no  yes first */
post_filter="NO"
noext_type="HTM"  /* NONE DIR HTM or HTML REDIR */
record_option="NO"   /* YES, YES_ALL */
allow_access="YES"  /* access control on file transfers (YES=none) */
default='index.htm'     /* use if default home page selected */
add_privs_prefix='!'
inhouse_privs=" INHOUSE "    /* additional privs for inhouseips and owners */
public_privs=" PUBLIC "    /* additional privs for veryone */
user_privs=' USER '
inhouse.1=" (INHOUSE User) "   /* Used with REPLACE:INHOUSE1, etc. */
suPEruser.1="(Super User)"
replace_rules.0=0                /* no replace rules */
headers.1=0  /* stuff to put at beginning / end of */
footers.1=0  /* all htm documents. 0= nothing */
OPTION_hit_line=":: still access # "
webmaster=' (no contact available) '
owners   = 'none'  /* Owners are automatically superusers (seperate with spaces) */
inhouse_privs="INHOUSE"
smtp_gateway=" "    /* smtp_gateway, used by post-filter "e-mail alert" facility */

/* note: Directories and files  do NOT have defaults!*/

logon_fail_file=0
access_fail_file=0

htaccess_file=0
do_htaccess=0

accept_range="NO"
check_add_privs='NO'
use_stdout="YES"
add_user_name='YES'
add_resource_name='NO'

/* variables not changed by configure */
max_pointdist=50     /* max distance acceptable for a "assign to point" in ncsa map */
ssi_shtml_only='NO'    /* yes no, ssi on .sht or .shtml only */
ssi_cache_on='YES'    /* use ssi-caching (no, yes) */

fix_expire=0    /* set to non zero to redo response headers */
content_md5=0    /* add a content-md5 header */
no_include="NO"   /* yes no , disallow all ssi */
no_processing="NO"   /* if yes, then no server side processing allowed */
no_interpret_code='NO'
delim_1.1='<!--'     /* the left and right side "keyphrase" delimeters */
delim_2.1='-->'      /* can be any string combo */
upload_maxsize=50             /* max size that a uploaded file can be, in k */
upload_minfree=20000        /* minimum free in K, in dowload_dir, AFTER file upload */
postfilter_name="POSTFILT"
prefilter_name="PREFILTR"

interpret_types=' PL=PERL5 '  /* used by CGI-BIN to invoke alternate interpeters */

dir_exclusion='HTACCESS. /PRIVATE *.CNT '
DIR_OPTIONS='  notime auto_describe describe=describe.txt no_recurse_dir  '


dir_access=' PRIVATE/* SYSTEM* ' 
dir_access_privs='SUPERUSER '


check_doq=0
verbose=1

hit_cache_len=0        /* not on (otherwise, # of k) */
hit_cache_duration=15     /* # of minutes */
hit_cache=' '
hit_owner_suppress='YES'
write_logs='YES'


return 0


/* ----------------------------- */
/* save some initfilt varibles to the environment */
/* ----------------------------- */
save_envstuff:

ALIST='CHECKLOG AUTO_HEADER VERBOSE DNS_CHECK ALLOW_ACCESS '
do mm=1 to words(alist)
  call save_em(word(alist,mm))
end
foo=value('SREF_VERBOSE',verbose,'os2environment')


call value enVadd||'SUPPRESS_ALIAS',suppress_alias,'os2environment'
call value enVadd||'NEVER_PUBLICURLS',never_publicurls,'os2environment'

call value 'SREF_DIGEST_AUTH',digest_auth,'os2environment'
call value 'SREF_SUPPRESS_GZIP_TE',suppress_gzip_te,'os2environment'
call value 'SREF_PROXY_CACHE',proxy_cache,'os2environment'

call value enVadd||'suppress_virtual',suppress_virtual,'os2environment'
call value enVadd||'suppress_access',suppress_access,'os2environment'
call value enVadd||'suppress_user',suppress_user,'os2environment'
call value enVadd||'CHECK_DOQ',CHECK_DOQ,'os2environment'
call value enVadd||'LOADTHRESHOLD',loadthreshold,'os2environment'
foo=value('SREF_KEY_PREFACE',key_preface,'os2environment')
call value enVadd||'BACKUPSERVERLIST',backupserverlist,'os2environment'
call value enVadd||'CGI_POST_LONG_GET',cgi_post_long_get,'os2environment'
call value enVadd||'GET_DECODE_OPTIONS',get_decode_options,'os2environment'

call value enVadd||'NO_NO_RECORD',no_no_record,'os2environment'
call value enVadd||'MESSAGE_SCRAMBLE',MESSAGE_SCRAMBLE,'os2environment'
CALL VALUE 'SREF_NO_REMOTE_CONFIG',NO_REMOTE_CONFIG,'OS2ENVIRONMENT'
call value enVadd||'SSI_EXTENSIONS',ssi_extensions,'os2environment'


ALIST='AUTO_NAME DEFAULT CHECK_ALIAS NOEXT_TYPE ADD_PRIVS_PREFIX INTERPRET_TYPES DIR_OPTIONS DIR_EXCLUSION DIR_ACCESS DIR_ACCESS_PRIVS'
do mm=1 to words(alist)
  call save_em(word(alist,mm))
end

ALIST='PRE_FILTER PREFILTER_NAME POST_FILTER POSTFILTER_NAME  '
do mm=1 to words(alist)
  call save_em(word(alist,mm))
end

call value envadd||'HEADERS',headers,'os2environment'
call value envadd||'FOOTERS',footers,'os2environment'

do mm=1 to nheads
   foo=strip(headlist.mm)
   aval0=aheaders.foo
   tty=strip(envadd||'HEADERS.'||foo)
   call value tty,aval0,'os2environment'
end /* do */
do mm=1 to nfoots
   foo=strip(footlist.mm)
   aval0=afooters.foo
   call value envadd||'FOOTERS.'||foo,aval0,'os2environment'
end /* do */

alist='THE_REALM HOME_NAME NOT_FOUND_URL USER_PRIVS PUBLIC_PRIVS INHOUSE_PRIVS OPTION_HIT_LINE LOGON_FAIL_FILE ACCESS_FAIL_FILE'
do mm=1 to words(alist)
  call save_em(word(alist,mm))
end

alist='WEBMASTER OWNERS SMTP_GATEWAY ACCEPT_RANGE USE_STDOUT ADD_USER_NAME ADD_RESOURCE_NAME '
do mm=1 to words(alist)
  call save_em(word(alist,mm))
end


call value envadd||'HOSTS.0',hosts.0,'os2environment'

select
   when wordpos(upper(content_md5),'1 Y YES')>0 then content_md5=1
   when wordpos(content_md5,'2 MD5.EXE')>0 then content_md5=2
   otherwise  content_md5=0
end

ALIST='MAX_POINTDIST NO_INCLUDE NO_INTERPRET_CODE NO_PROCESSING CONTENT_MD5 FIX_EXPIRE SSI_SHTML_ONLY CHECK_ADD_PRIVS SSI_CACHE_ON '
do mm=1 to words(alist)
  call save_em(word(alist,mm))
end

ALIST='UPLOAD_MINFREE UPLOAD_MAXSIZE HOME_DIR HIT_CACHE_LEN HIT_CACHE_DURATION HIT_CACHE WRITE_LOGS HIT_OWNER_SUPPRESS SSI_CACHE_SIZE SSI_CACHE_DURATION SSI_CACHE_STAMP '
do mm=1 to words(alist)
  call save_em(word(alist,mm))
end

call value envadd||'cgi_bin_dir',cgi_bin_dir,'os2environment'
call value envadd||'addon_dir',addon_dir,'os2environment'

tempfile_dir=upper(strip(tempfile_dir))
call value envadd||'tempfile_dir',tempfile_dir,'os2environment'

tempdata_dir=upper(strip(tempdata_dir))
call value envadd||'tempdata_dir',tempdata_dir,'os2environment'
call value 'sref_temp_data_dir',tempdata_dir,'os2environment'

userinfo_dir=upper(strip(userinfo_dir))
call value envadd||'userinfo_dir',userinfo_dir,'os2environment'


upload_dir=upper(strip(upload_dir))
call value envadd||'upload_dir',upload_dir,'os2environment'

messbox_dir=upper(strip(messbox_dir))
call value envadd||'messbox_dir',messbox_dir,'os2environment'

config_dir=upper(strip(config_dir))
call value envadd||'config_dir',config_dir,'os2environment'

workdata_dir=upper(strip(workdata_dir))
call value envadd||'workdata_dir',workdata_dir,'os2environment'


mailbox_dir=upper(strip(mailbox_dir))
call value envadd||'mailbox_dir',mailbox_dir,'os2environment'


call value envadd||'SERVDIR',servdir,'os2environment'
call value 'SREF_PREFIX',envadd,'os2environment'

call value envadd||'INITFILT_FILE',INIT_file,'os2environment'
call value envadd||'USER_FILE',user_file,'os2environment'
call value envadd||'ACCESS_FILE',access_file,'os2environment'
call value envadd||'VIRTUAL_FILE',virtual_file,'os2environment'
call value envadd||'ALIAS_FILE',alias_file,'os2environment'
call value envadd||'PUBURL_FILE',puburl_file,'os2environment'

call value envadd||'REPSTRGS_FILE',repstrgs_file,'os2environment'

call value envadd||'INTERPRET_FILE',interpret_file,'os2environment'
call value envadd||'SENDFILE_FILE',sendfile_file,'os2environment'


IF DACALL=0 then do
   call lineout error_log,' ==== The SRE-http error log. '||time('n')' 'date('n')
   call lineout error_log
end
ELSE  do
   if verbose>1 then do 
      call lineout error_log,' ==== (parameter reset '||time('n')' 'date('n')
      call lineout error_log
   end /* do */
end

if stream(error_log,'c','query exists')="" then do
    foo=pmprintf_sr(' SRE-http Monitor: could not initialize error log: 'error_log)
    error_log=''
end /* do */
else do
   foo=pmprintf_sr(" SRE-http Monitor: using error log: " error_log)
   xaa=stream(error_log,'c','query size')
   if xaa>100000 then foo=pmprintf_sr(' SRE-http Monitor WARNING: error log file is getting large ('xaa' bytes)')
end /* do */
call value envadd||'ERROR_LOG',error_log,'os2environment'

call value envadd||'HTACCESS_FILE',htaccess_file,'os2environment'
call value envadd||'DO_HTACCESS',DO_htaccess,'os2environment'

/* create a HOST listing, stored in sref_value environment */
/*  IP_address,  host_nickname,  default_directory */
foo=pmprintf_sr(' SRE-http Monitor: looking up '||hosts.0||' HOST IP addresses')
hostlist=''

do m=1 to hosts.0
   aah=upper(hosts.m)

   parse upper var aah  sname ','  hn ',' adir ','ahitcount','acounter_rxx','asendfile','arecordall
   SNAME=STRIP(SNAME); adir=strip(adir)
   hostlist=hostlist' 'sname
   hn=upper(hn)
   adir=translate(strip(adir),'\','/'); adir=strip(adir,'t','\')||'\'
   tmp.m=sname','hn','adir
   tmp.m.!name=sname
   foo=sref_value('$HOSTS.'||sname,tmp.m,'USER',,serverport)

   fpp=value(envadd||'COUNTER_FILE.'||hn,ahitcount,'OS2ENVIRONMENT')
   fpp=value(envadd||'COUNTER_RXX_DIR.'||hn,acounter_rxx,'OS2ENVIRONMENT')
   fpp=value(envadd||'SENDFILE_FILE.'||hn,asendfile,'OS2ENVIRONMENT')
   fpp=value(envadd||'RECORD_ALL_FILE.'||hn,arecordall,'OS2ENVIRONMENT')


end

/*  -- HOSTS. ENTRIES MUST BE COMPLETE -- WE NO LONGER FILL IN
   PROBABLE VALUES 
do aa=1 to words(hostlist)   
   sname=tmp.aa.!name
   isnumip=verify(sname,'1234567890.')  
   if isnumip=0 then iterate  
   astat=sockgethostbyname(sname,'stuff.!')
   if astat<>1 then iterate      
   sname=stuff.!addr
   if wordpos(sname,hostlist)>0 then iterate 
   foo=sref_value('$HOSTS.'||sname,tmp.aa,'USER',,serverport)
   hostlist=hostlist' 'sname
end
*/
foo=sref_value('$HOSTS.0',hostlist' ','USER',,serverport)

/* end of hosts. section */

call save_em('inhouseips.')
do m=1 to plist.0            /* fix and save INHOUSEIPS */
  t1=plist.m
  anval=inhouseips.t1
  w1=word(anval,1)   /* look for host nickname */
  if right(w1,2)='//' then do
       geti=2
  end
  else do
     geti=1
  end
  call value envadd||'inhouseips.'||t1,anval,'os2environment'
end

call save_em('unallowedips.')
isu=0
do m=1 to plist.0            /* fix and save unallowedIPS */
  t1=plist.m
  anval=unallowedips.t1
  w1=word(anval,1)   /* look for host nickname */
  if right(w1,2)='//' then do
       geti=2
  end
  else do
     geti=1
  end
  if verify(word(anval,geti),'1234567890.')<>0 then do  /* convert numeric ip */
      astat=sockgethostbyname(word(anval,geti),'stuff.!')
      if astat=1 then do
           if geti=1 then do
              parse var anval vv anval
              anval=stuff.!addr||' '||anval
            end
            else do
               parse var anval vv1 vv2  anval
               anval=vv1||' '||stuff.!addr||' '||anval
            end  /* Do */
      end  /* Do */
  end
  call value envadd||'unallowedips.'||t1,anval,'os2environment'
  if anval<>'' & anval<>0 then isu=1
end
if isu>0 then 
  call value envadd||'UNALLOWEDIPS',1,'os2environment'
else
  call value envadd||'UNALLOWEDIPS',0,'os2environment'


do m=1 to delims
  if symbol('DELIM_1.'||m)<>'VAR' then iterate
  call value envadd||'DELIM_1.'||m,delim_1.m,'os2environment'
  if symbol('DELIM_2.'||m)<>'VAR' then iterate
  call value envadd||'DELIM_2.'||m,delim_2.m,'os2environment'
end
call value envadd||'DELIMS',delims,'os2environment'

ralphie=cvtails('DELIMS',dlist)
do mm=1 to ralphie
   booboo=dlist.mm
   call value envadd||'DELIMS.'||booboo,delims.booboo,'os2environment'
   do m=1 to delims.booboo
    if symbol('DELIM_1.'||m||'.'||booboo)<>'VAR' then iterate
     call value envadd||'DELIM_1.'||m||'.'||booboo,delim_1.m.booboo,'os2environment'
    if symbol('DELIM_2.'||m||'.'||booboo)<>'VAR' then iterate
     call value envadd||'DELIM_2.'||m||'.'||booboo,delim_2.m.booboo,'os2environment'
   end
end /* do */


CALL SAVE_EM('SUPERUSER')
CALL SAVE_EM('INHOUSE')
call save_em('REPLACE_RULES')

foo=pmprintf_sr(' SRE-http Monitor: number of hosts= 'hosts.0 )
return 0


/* ----------------------------------------------------------------------- */
/* -- create temporary sel-specific-options file  -- */
/* ----------------------------------------------------------------------- */
make_DEFREALM_FILE_temp:

/* 
1) parse defrealm file into an array of entries. Each entry (numbered 1...n)
   can have several fields. One of these MUST be a REALM, and one of these
   must be a RULE
2) Fill in a  stem (using REALM as tails) using values from the above array
3) Fill in missing values in each "REALM tail"  -- this means using
   higher order realms to fill in values for subrealms.
Values that can be filled are:
   REQUIRES and PERMISSIONS. 
REQUIRES can NOT be subrealm specific -- the same REQUIRES
must be used in all subrealms (or a realm).
*/

blocks.='01'x
wasline='' ; nthblock=1
blocks.nthblock.!useit=1
blocks.0=0

if stream(defrealm_file_temp,'c','query exists')<>'' then do
  foo=sysfiledelete(DEFREALM_FILE_temp)  /* delete temporary defrealm_file */
  if foo<>0 then do
    call pmprintf("SRE-http Monitor WARNING: ("foo") unable to delete "defrealm_file_temp)
    return 0   
  end
end

/* look for files */
foo=translate(stream(DEFREALM_FILE,'c','open read'))
if abbrev(foo,'READY')<>1 then do
  call pmprintf('SRE-http Monitor: ... unable to open 'DEFREALM_FILE ' ('foo)
  return 1            /* unable to open */
end
inj=stream(DEFREALM_FILE,'c','query size')
if inj=0 | inj='' then return   1        /* empty file */
astuff=charin(DEFREALM_FILE,1,inj)
foo=stream(DEFREALM_FILE,'c','close')
crlf='0d0a'x

/* add host/port specific files (from cfglist.cfg?) */
rr=add_attribs(serverport)
astuff=astuff||crlf||crlf||rr

astuff=astuff||crlf||' '        /* place an elephant in cairo */

/* look for entry blocks (each block is delimited by a blank line */
do forever
   if astuff='' then leave
   parse var astuff aline (crlf) astuff
   aline=strip(aline)
   if abbrev(aline,';')=1 then iterate   /* skip comment lines */
   if aline='' & wasline='' then iterate /* skip multiple blank lines */

   if aline=''  then do          /* first blank line signals end of entry*/
      foo=add_include_nthblock(nthblock)    /* "INCLUDE" (to astuff)? */
      if blocks.nthblock.!INCLUDE<>'01'x then do
           blocks.nthblock.!useit=0         /* don't use this block */
      end
      blocks.0=blocks.0+1  /* actual # of entries */
      nthblock=nthblock+1               /* initialize for next entry */
      blocks.nthblock.!useit=1
      wasline=''
      iterate
   end
   if pos(':',aline)>0 then
     parse var aline action ':' options
   else
      parse var aline action options 
   wasline=aline
   action=strip(translate(translate(action),' ',':='))
   options=strip(options)
   select
      when action='PORT' then do
        if options='' then options=80
        if options<>serverport then blocks.nthblock.!useit=0  /* this entry does not apply */
      end
      when action='REALM' then do
         if options='' then iterate
         parse var options drealm iscomplete 
         blocks.nthblock.!REALM=strip(translate(drealm))
         blocks.nthblock.!REALM.!C=strip(translate(iscomplete))
      end 
      when abbrev(action,'REPL')=1 then do 
          blocks.nthblock.!REPLACE=strip(translate(options))
      end 
      when abbrev(action,'WITH')=1 then do 
          blocks.nthblock.!RULES=options
      end 

      when abbrev(action,'USER')=1 then do 
          blocks.nthblock.!USER=strip(translate(options))
      end 
      when abbrev(action,'PWD')+abbrev(action,'PASS')>0 then do 
          blocks.nthblock.!RULES=strip(options)
      end 
      when abbrev(action,'PRIV')>0 then do 
          blocks.nthblock.!PRIVS=strip(options)
      end 

      when action='INCLUDE' then do
         if options='' then iterate
         blocks.nthblock.!INCLUDE=options
      end 
      when action='HOST' then do
          blocks.nthblock.!HOST=translate(options)
      end 
      when abbrev(action,'REQ')=1 then do 
          blocks.nthblock.!REQUIRES=translate(options)
      end 
      when abbrev(action,'PERM')=1 then do 
          blocks.nthblock.!permissions=translate(options)
      end 
      when abbrev(action,'RUL')=1 then do
        blocks.nthblock.!RULES=blocks.nthblock.!rules' 'options
      end
      when abbrev(action,'ADV')=1 then do
        blocks.nthblock.!ADVOPTS=options
      end /* do */
      when abbrev(action,'OPT')=1 then do
        blocks.nthblock.!OPTS=options' |#| 'blocks.nthblock.!opts 
      end /* do */

     when abbrev(action,'FAIL')=1 then do
        blocks.nthblock.!FAILURE=options
      end /* do */
     when abbrev(action,'LIMIT')=1 then do
        blocks.nthblock.!LIMITLIST=options
     end /* do */

      when wordpos(action,'REDIRECT  NEGOTIATE LITERAL ALIAS VIRTUAL MOVE TEMP MOVED TEMPMOVE PERMMOVE')>0 then do
         options2=translate(options,' ','=')
         parse var options2 a1  a2 
         if words(options2)=1 & translate(a1)<>'LITERAL' & translate(a1)<>'NEGOTIATE' then
             a2=a1  /* action=alias, etc */
         a1=strip(translate(a1))
         select   
           when action='ALIAS' then do
               blocks.nthblock.!RTYPE='ALIAS'
               blocks.nthblock.!DEST=options
           end /* do */
           when abbrev(a1,"SEL")+abbrev(a1,'INTERN')+abbrev(a1,'ALIAS')>0 then do
             blocks.nthblock.!RTYPE='ALIAS'
             blocks.nthblock.!DEST=a2
           end 
           when action="LITERAL"  then do
             blocks.nthblock.!RTYPE='LITERAL'
             blocks.nthblock.!DEST=options
           end
           when  a1="LITERAL" then do
             blocks.nthblock.!RTYPE='LITERAL'
             blocks.nthblock.!DEST=a2
           end
           when action="NEGOTIATE" then do
             blocks.nthblock.!RTYPE='NEGOTIATE'
             blocks.nthblock.!DEST=options
           end
           when a1="NEGOTIATE" then do
             blocks.nthblock.!RTYPE='NEGOTIATE'
             blocks.nthblock.!DEST=a2
           end

           when action="VIRTUAL" then do
             blocks.nthblock.!RTYPE='VIRTUAL'
             blocks.nthblock.!DEST=options
           end
           when a1="DIR" then do
             blocks.nthblock.!RTYPE='VIRTUAL'
             blocks.nthblock.!DEST=a2
           end 
           when abbrev(action,"MOVE")=1 then do
             blocks.nthblock.!RTYPE='PERM'
             blocks.nthblock.!DEST=options
           end
           when abbrev(a1,"PERM")+abbrev(a1,'MOVE')>0 then do
             blocks.nthblock.!RTYPE='PERM'
             blocks.nthblock.!DEST=a2
           end 
           when abbrev(action,"TEMP")=1 then do
              blocks.nthblock.!RTYPE='TEMP'
              blocks.nthblock.!DEST=options
           end
           when abbrev(a1,"TEMP")=1  then do
              blocks.nthblock.!RTYPE='TEMP'
              blocks.nthblock.!DEST=a2
           end 
           otherwise  do
             call pmprintf(' SRE-http Monitor: unsupported REDIRECT action = 'action ','options)
           end
         end               /* which kind of redirect */
      end               /* action=redirect */
      otherwise  do
            call pmprintf(' SRE-http Monitor: unsupported ATTRIBS action = 'action ','options)
      end
  end                /* action */
   
end             /* do forever */
 
  
if verbose>0 then call pmprintf('SRE-http Monitor: # of ATTRIBS.CFG entries: 'blocks.0)

if blocks.0=0 then return 1     /* nothing to write to */

/* clean up entries */
do nn=1 to blocks.0
   if blocks.nn.!useit=0 then iterate /* not for this port */

   if blocks.nn.!REPLACE<>'01'x then do
      blocks.nn.!realm='##REPLACE'
      iterate
   end
   if blocks.nn.!USER<>'01'x then do
      blocks.nn.!realm='##USER'
      iterate
   end
   if blocks.nn.!REALM='01'x then do
         call pmprintf(" SRE-http Monitor: ERROR missing REALM: in ATTRIBS block #"nn)
         blocks.nn.!useit=0    /* don't use this one */
         iterate
   end /* do */

   if blocks.nn.!RULES='01'x then do
         call pmprintf(" SRE-http Monitor: ERROR: missing RULE, PWD or WITH: in ATTRIBS block #"nn)
         blocks.nn.!useit=0    /* don't use this one */
         iterate
   end /* do */

/* create an idenfitying stem (using realm and host */
    trealm='!'||blocks.nn.!realm
    if blocks.nn.!host<>'01'x  & blocks.nn.!Host<>'' then do
            trealm=trealm||'.!!'||blocks.nn.!host
    end /* do */

/* is this a main realm -- if so, then check on REQUIRES: */
    if pos('.',blocks.nn.!realm)=0 then do
           if blocks.nn.!REQUIRES='01'x | blocks.nn.!requires='' then blocks.nn.!requires='*'
            blocks.nn.!ismain=1
     end
     blocks.nn.!stem=trealm
end

requires.='' ; permissions.=''


/* set REQUIRES. PERMISSIONS. stem arrays */
do nn=1 to blocks.0
   if blocks.nn.!useit=0 then iterate /* this entry not for this port, or missing info */

/* no realm for user and replace entries */
   if blocks.nn.!realm='##USER' | blocks.nn.!realm='##REPLACE' then iterate

   trealm=blocks.nn.!stem
   if blocks.nn.!ismain=1 then do        /* this is a main realm? then save requires */
       REQUIRES.trealm=blocks.nn.!requires
   end
/* save permissions (if they were set ) */
   if blocks.nn.!permissions<>'01'x then do
        permissions.trealm=blocks.nn.!permissions
   end /* do */

end


/* set the "requires" and "permissions" of subrealms */
do nn=1 to blocks.0
   if blocks.nn.!useit=0 then iterate
   if blocks.nn.!ismain=1 then iterate /* no super realms to check */

/* no requires or permissions for user and replace entries */
   if blocks.nn.!realm='##USER' | blocks.nn.!realm='##REPLACE' then iterate

   trealm=blocks.nn.!stem
   parse var trealm '!' arealm '.!!' ahost
   parse var arealm mrealm '.' .
/* fix up REQUIRES */
   mrealm2='!'||mrealm
   if ahost<>'' then mrealm2=mrealm2||'.!!'||ahost


   if requires.mrealm2='' & mrealm<>'PUBLIC' then do
         call pmprintf(" SRE-http Monitor: error: no main realm for subrealm: "arealm' ('mrealm2)
         blocks.nn.!useit=0
         iterate
    end
    blocks.nn.!requires=requires.mrealm2  /* subrealm MUST have main realm rules */


/* fill in with "superrealm's" PERMISSIONS, if need be */
   if permissions.trealm<>'' then iterate  /* explicit-- no need to fill in */
   do forever           /* look in higher "superealms" */
       iip=lastpos('.',arealm)
       if iip>0 then arealm=left(arealm,iip-1)
       urealm='!'||arealm
       if ahost<>'' then urealm=urealm||'.!!'||ahost
       if permissions.urealm<>'' then do
          blocks.nn.!permissions=permissions.urealm
         leave
       end
       if iip=0 then leave
   end
      
end

/* write results */
/*call pmprintf(' ---- writing to 'defrealm_file_temp) */
call lineout defrealm_file_temp,'; Do NOT edit this transient "realm definitions" file (created: 'date('n')' 'time('n')

do mm=1 to blocks.0
 if blocks.mm.!useit=0 then iterate /* skip this block */

 ahost=strip(translate(blocks.mm.!Host,' ','01'x))
 arealm=translate(blocks.mm.!realm)
 parse upper var arealm mainrealm '.' .
 rulist=strip(translate(blocks.mm.!rules,' ','01'x))
 adest=translate(blocks.mm.!dest,' ','01'x)
 do ii=1 to words(rulist)
    arule=strip(word(rulist,ii))

    call lineout defrealm_file_temp,' '
    if wordpos(blocks.mm.!REALM.!C,'1 C COMPLETE')>0 then
      call lineout defrealm_file_temp,';C_REALM:' arealm ', rule='arule
    else
      call lineout defrealm_file_temp,';REALM:' arealm ', rule='arule

   if arealm='##REPLACE' then do
       if ahost<>'' then
          aline='REPLACE: 'blocks.mm.!replace||'.'||ahost||' '||blocks.mm.!rules
       else
          aline='REPLACE: 'blocks.mm.!replace' '||blocks.mm.!rules

      call lineout defrealm_file_temp,aline    
      leave             
    end

   if arealm='##USER' then do
       if ahost<>'' then
          aline='USER: '||ahost||'// 'blocks.mm.!user
       else
          aline='USER: '||blocks.mm.!user
       aline=aline||' 'blocks.mm.!rules 
       if blocks.mm.!privs<>'01'x then
          aline=aline||' 'blocks.mm.!privs
      call lineout defrealm_file_temp,aline    
      leave
    end

/* is this a public url? */
    if mainrealm='PUBLIC' then do
       if ahost<>'' then
          aline='PUBURLS: '||ahost||'// 'arule
       else
          aline='PUBURLS: 'arule
       select
             when blocks.mm.!rtype='LITERAL' & pos('NO_POSTFILTER',blocks.mm.!permissions)>0 then 
                   aat=' LITERAL_NORECORD  '||blocks.mm.!dest
             when blocks.mm.!rtype='LITERAL'  then 
                   aat=' LITERAL '||blocks.mm.!dest
             when pos('NO_POSTFILTER',blocks.mm.!permissions)>0 then 
                   aat=' NORECORD '
             otherwise
                  aat=''
       end
       call lineout defrealm_file_temp,aline||aat  
       if blocks.mm.!rtype='LITERAL' then blocks.mm.!rtype='' /* suppres below */
       blocks.mm.!requires='*'          /* force open access */
    end /* do */

/* generate an access.in entry */
    if ahost<>'' then
       aline='ACCESS: '||ahost||'// 'arule
    else
       aline='ACCESS: 'arule
    aline=aline' '||translate(blocks.mm.!requires,' ','01'x)
    aline=aline','||translate(blocks.mm.!permissions,' ','01'x)
    aline=aline','||mainrealm
    aline=aline','||translate(blocks.mm.!failure,' ','01'x)
    aline=aline','||translate(blocks.mm.!advopts,' ','01'x)
    aline=aline','||translate(blocks.mm.!opts,' ','01'x)
    call lineout defrealm_file_temp,aline    

/* generate a virtual ? */
   if blocks.mm.!RTYPE='VIRTUAL' then do
      jj=pos('*',arule)
      if jj>0 then
         isit=left(arule,jj-1)
      else
         isit=arule

      bb=strip(strip(translate(isit,'/','\')),'t','/')||'/'

      if ahost<>'' then
         aline='VIRTUAL: '||ahost||'// 'bb
      else
         aline='VIRTUAL: 'bb
      bb2=blocks.mm.!dest
      if abbrev(translate(bb2),'HTTP://')=0 then do
          bb2=translate(bb2)
          bb2=strip(translate(bb2,'\','/'))
         if right(bb2,1)<>'*' then bb2=strip(bb2,'t','\')||'\'
      end
      aline=aline' 'bb2' '||translate(blocks.mm.!limitlist,' ','01'x)
      call lineout defrealm_file_temp,aline    
   end     


   if blocks.mm.!RTYPE='ALIAS' then do
      if ahost<>'' then
         aline='ALIAS: '||ahost||'// 'ARULE
      else
         aline='ALIAS: 'ARULE
      aline=aline' 'blocks.mm.!dest
      call lineout defrealm_file_temp,aline    
   end     

   if blocks.mm.!RTYPE='LITERAL' then do   /* note : not done with public realm */
      if ahost<>'' then
         aline='ALIAS: '||ahost||'// 'ARULE
      else
         aline='ALIAS: 'ARULE
      aline=aline' !TRANSFER='||strip(blocks.mm.!dest)
      call lineout defrealm_file_temp,aline    
   end

   if blocks.mm.!RTYPE='NEGOTIATE' then do   
      if ahost<>'' then
         aline='ALIAS: '||ahost||'// 'ARULE
      else
         aline='ALIAS: 'ARULE
      aline=aline' !NEGOTIATE '||translate(blocks.mm.!dest,' ','01'x)
      call lineout defrealm_file_temp,aline    
   end


   if blocks.mm.!RTYPE='PERM' then do
      jj=pos('*',blocks.mm.!dest)
      if jj>0 then
         isit=left(arule,jj-1)
      else
         isit=arule

      if ahost<>'' then
         aline='ALIAS: '||ahost||'// 'ARULE
      else
         aline='ALIAS: 'ARULE
      aline=aline' !MOVED='||STRIP(blocks.mm.!dest)
      call lineout defrealm_file_temp,aline    
   end     


   if blocks.mm.!RTYPE='TEMP' then do
      jj=pos('*',blocks.mm.!dest)
      if jj>0 then
         isit=left(arule,jj-1)
      else
         isit=arule

      if ahost<>'' then
         aline='ALIAS: '||ahost||'// 'ARULE
      else
         aline='ALIAS: 'ARULE
      aline=aline' !TEMP='||STRIP(blocks.mm.!dest)
      call lineout defrealm_file_temp,aline    
   end     
  end         /* this rule */

  if verbose<3  then iterate /* don't write background info */

end
call lineout defrealm_file_temp

return 1


/***************/
/* add an INCLUDE: file to astuff? If so,
possibly reset all HOST and PORT actions */

add_include_nthblock:procedure expose blocks. astuff crlf cfgs_dir
parse arg nthb

if blocks.nthb.!INCLUDE='01'x then return 0        /* no INCLUDE */

ill=stream(blocks.nthb.!INCLUDE,'c','query size')
if ill=0 | ill='' then do  /* try looking in cfgsdir */
  baa=cfgs_dir'\'blocks.nthb.!include
  ill=stream(baa,'c','query size')
  if ill<>0 & ill<>'' then blocks.nthb.!include=baa
end /* do */

if ill=0 | ill='' then do
    call pmprintf('SRE-http Monitor WARNING: bad ATTRIBS INCLUDE = 'blocks.nthb.!include)
    return 0
end /* do */
foo=stream(blocks.nthb.!include,'c','open read')
if abbrev(translate(foo),'READY')<>1 then do
    call pmprintf('SRE-http Monitor WARNING: 'foo' ATTRIBS INCLUDE = 'blocks.nthb.!include)
    return 0
end
aget=charin(blocks.nthb.!include,1,ill)  /* read in the INCLUDE file */
foo=stream(blocks.nthb.!include,'c','close')
aget=aget||crlf

/* now parse it, adding a PORT and HOST to each entry, and removing
any existing PORT and HOST actions */
if verbose>1 then call pmprintf('SRE-http Monitor: including ATTRIBS file='blocks.nthb.!include) 
ngot=0
astuff=astuff||crlf||crlf
do forever
   if aget='' then return ngot
   parse var aget aline (crlf) aget
   aline=strip(aline);taline=translate(aline)
   if aline=';' then iterate  /* ignore comments */

   if abbrev(taline,'REALM')+abbrev(taline,'USER')+abbrev(taline,'REPL')>0 then do   /* all entries MUST have a REALM, USER or REPLACE */
      astuff=astuff||aline||crlf     /* WITH CURRENT HOST AND PORT */
      if blocks.nthb.!HOST<>'01'x then do
          astufF=astuff||'HOST: 'blocks.nthb.!host||crlf
      end
      if blocks.nthb.!PORT<>'01'x then do
          astufF=astuff||'PORT: 'blocks.nthb.!port||crlf
      end
      iterate
   end
/* suppress HOST and PORT -- always use this "blocks" host and port */
   if abbrev(taline,'HOST')+abbrev(taline,'PORT')>0 then iterate
/* else, add this line */
   astuff=astuff||aline||crlf
end


/* ----------------------------------------------------------------------- */
/* --  update mediatype temporary file */
/* ----------------------------------------------------------------------- */

chk_mediatyp:

if stream(mediatyp_file,'c','query exists')='' then do
   foo=' '
   aa=sysfiledelete(mediatyp_tfile)
   if aa<>0 then do
      call pmprintf(" SRE-http Monitor ERROR: could not delete MEDIATYP.TMP ("aa)
      return 0
   end /* do */
   afoo=charout(mediatyp_tfile,foo,1)
   afoo=stream(mediatyp_tfile,'c','close')
   call pmprintf('SRE-http Monitor: no mediatyp.rxx file ')
   return 0
end /* do */

/* else, a mediatype file. Process, converting new style entries to 
old style entries*/

jin=stream(mediatyp_file,'c','query size')
iin=charin(mediatyp_file,1,jin)
oo=stream(mediatyp_file,'c','close')
/* remove comments (between /* and */ */
iin0=''
do forever
   parse var iin a1 '/*' ac '*/' iin
   iin0=iin0' 'a1
   if iin='' then leave
end
/* Look for type= entries, and convert 'em */
iin1=''; crlf='0d0a'x
do forever
  parse var iin0 a1 (crlf) iin0
  isnew1=0
  parse upper var a1 fa1  .  /* check for bad syntax of new style entries */
  if abbrev(strip(fa1),'TYPE')=1 then do  /* this is a new style entry */
    isnew1=1
    if pos('=',a1)=0 then do 
     call pmprintf('SRE-http monitor WARNING: Ignoring bad mediatyp.rxx entry: 'a1)
     iterate
   end 
  end
  if isnew1=0 then do
      iin1=iin1||a1||'; '
  end
  else do               /* convert new style entry */
      parse  var a1 . '=' amtype . '=' extlist
/* host specific? */
      nohh=1
      if pos('.',fa1)>0 then do
         parse var fa1 . '.' bhost '=';bhost=translate(strip(bhost))
         iin1=iin1||' if translate(host_nickname)="'bhost'" then do ;' 
         nohh=0
      end /* do */
      extlist=translate(extlist,' ',','||'09'x)
      do forever
         parse upper var extlist aext extlist ; aext=strip(aext)
         iin1=iin1||"GARG='"||aext||"' ; KNOWN.GARG='"||amtype||"'; "
         if extlist='' then leave  /* done with this entry */
      end
      if nohh=0 then iin1=iin1||' ; end ;' 
  end
  if iin0='' then leave         /* done processing mediatyp file */
end
afoo=sysfiledelete(mediatyp_tfile)
afoo=charout(mediatyp_tfile,iin1,1)
afoo=stream(mediatyp_tfile,'c','close')
foo=pmprintf_sr(' SRE-http Monitor: updated MEDIATYP.RXX file ')

return 1
  

/* ----------------------------------------------------------------------- */
/* --  copy repstrgs file to environment */
/* ----------------------------------------------------------------------- */

chk_repstrgs:
parse arg resetit

if repstrgs_file=" " then
  return 0
oy=stream(repstrgs_file,'c','query exists')
if oy="" then do
   foo=pmprintf_sr("SRE-http Monitor: Replacement strings file not found, "|| get_file)
   return -1
end

/* yep, reinitialize repstrgs file (set semaphore first */
ause=sref_fileread(repstrgs_file,'filelines',,'E')

aa=add_auxillary('REPSTRGS','REPSTRGS.IN',serverport,0)

foo=add_defrealm_rep('REPLACE')

If (ause<=0) then  do               /*no such file,*/
      foo=pmprintf_sr("SRE-http Monitor: error " ause " when reading replacement strings file, "|| repstrgs_file)
      return -1
end

crlf='0d0a'x
j=0
/* zap current list of repstrings variables */
do rr=1 to repsvars.0
  call value repsvars.rr,' ','os2environment'
end
repsvars.0=0
do mm=1 to filelines.0
  goo=strip(filelines.mm)
  if goo="" | left(goo,1)=";" then  iterate
  parse var goo aname avalue
  aname=envadd||upper(aname)
  t1=value(aname,,'os2environment')
  if t1=' ' then do
      t1=avalue
      j=j+1
      repsvars.j=aname
      repsvars.0=j
  end
  else do
        t1=t1||crlf||avalue
  end
  call value aname,t1,'os2environment'
end
foo=pmprintf_sr(' SRE-http Monitor: loaded replacements strings: 'j)
return j


/* ----------------------------------------------------------------------- */
/* -- See if a "generic" YES answer. If so, return 1 */
/* ----------------------------------------------------------------------- */
is_true:procedure
parse upper arg ans,anslist
if wordpos(ans,anslist)>0 then
 return 1
else
 return 0



/*=========     Start various threads   ===================== */


/* ------------------------------------------------------------ */
/* start access processor thread */
start_access:
parse arg resetit

if access_file= ' ' | SUPPRESS_ACCESS=1 then
      return 0
oy=stream(access_file,'c','query exists')
if oy="" then do
   foo=pmprintf_sr("SRE-http Monitor: access file not found, "|| access_file)
   access_file=' '
   return -1
end

arxx=servdir||'\acceschk.rxx'
usequeue='SREF_'||serverport||'_ACCESS'
usesem='\SEM32\SREF_'||serverport||'_ACCESS'
badt=value('SREF_ACCESS_BAD',,'os2environment')

if  badt=1 | resetit=1 then do            /* already opened --just send a *RESET* */
   foo=eventsem_query(usesem)   /* is it still alive? */
   if foo<0 then do
       call pmprintf("SRE-http Monitor: relaunching access daemon (semaphore was:"foo)
   end /* do */
   else do   
      a=rxqueue('s',usequeue)
      push '1, 1, 2, *RESET* ' access_file
      return 1
   end                  /* otherwise, relaunch it */
end

/* if here, first time, or a relaunch */

a=rxqueue('d',usequeue)
a=rxqueue('c',usequeue)
if a<>usequeue then do
  bb=rxqueue('d',a)
  a=rxqueue('s',usequeue)
  do queued()
       pull
  end /* do */
end



a=eventsem_close(usesem)
A=EVENTSEM_CREATE(USESEM)
IF A<>0 then DO
    foo=pmprintf_sr(' SRE-http Monitor ERROR: creating access semaphore: 'A' 'usesem)
    access_file=' '
    return -1
end

badt=value('SREF_ACCESS_BAD',0,'os2environment')

access_tid=rexxthread('f',arxx,access_file,usequeue,USESEM,max_semwait,serverport)
if access_tid=0 then do
   foo=pmprintf_sr(' SRE-http Monitor: Could not open access thread 'arxx)
    access_file=' '
   return -1
end

return 1

/* ---------------- */
/* start alias processor thread */
start_alias:
parse arg resetit

if alias_file= ' ' | SUPPRESS_ALIAS=1 then
      return 0
oy=stream(alias_file,'c','query exists')

if oy="" then do
   foo=pmprintf_sr("SRE-http Monitor: alias file not found, "|| alias_file)
   alias_file=' '
   return -1
end

arxx=servdir||'\aliaschk.rxx'
usequeue='SREF_'||serverport||'_ALIAS'
usesem='\SEM32\SREF_'||serverport||'_ALIAS'
badt=value('SREF_ALIAS_BAD',,'os2environment')

if  badt=1 | resetit=1 then do            /* already opened --just send a *RESET* */
   foo=eventsem_query(usesem)   /* is it still alive? */
   if foo<0 then do
       call pmprintf("SRE-http Monitor: relaunching aliases daemon (semaphore was:"foo)
   end /* do */
   else do   
      a=rxqueue('s',usequeue)
      push '1,1,2,*RESET* ' alias_file
      foo=eventsem_post(usesem)
      return 1
   end
end

/* if here, first time */

a=rxqueue('d',usequeue)
a=rxqueue('c',usequeue)
if a<>usequeue then do
  bb=rxqueue('d',a)
  a=rxqueue('s',usequeue)
  do queued()
       pull
  end /* do */
end

a=eventsem_close(usesem)
A=EVENTSEM_CREATE(USESEM)
IF A<>0 then DO
    foo=pmprintf_sr(' SRE-http Monitor ERROR: creating alias semaphore: 'A' 'usesem)
    return 0
end

badt=value('SREF_ALIAS_BAD',0,'os2environment')


alias_tid=rexxthread('f',arxx,alias_file,usequeue,USESEM,max_semwait,serverport)
if alias_tid=0 then do
   foo=pmprintf_sr(' SRE-http Monitor: Could not open alias thread 'arxx)
   return 0
end

return 1


/* ---------------- */
/* start public-urls processor thread */
start_puburl:
parse arg resetit

if puburl_file= ' ' | never_publicurls=1 then do
    puburl_file=''
    call value envadd||'PUBURL_FILE',puburl_file,'os2environment'
   return 0
end /* do */

oy=stream(puburl_file,'c','query exists')
if oy="" then do
   foo=pmprintf_sr("SRE-http Monitor WARNING: public urls file not found, "|| puburl_file)
   puburl_file=' '
   call value envadd||'PUBURL_FILE',puburl_file,'os2environment'
   return -1
end

arxx=servdir||'\puburchk.rxx'
usequeue='SREF_'||serverport||'_PUBURL'
usesem='\SEM32\SREF_'||serverport||'_PUBURL'
badt=value('SREF_PUBURL_BAD',,'os2environment')


if  badt=1 | resetit=1 then do            /* already opened --just send a *RESET* */
   foo=eventsem_query(usesem)   /* is it still alive? */
   if foo<0 then do
       call pmprintf("SRE-http Monitor: relaunching puburls daemon (semaphore was:"foo)
   end /* do */
   else do   
      a=rxqueue('s',usequeue)
      push '1,1,2,*RESET* ' puburl_file
      foo=eventsem_post(usesem)
      return 1
   end
end

/* if here, first time */

a=rxqueue('d',usequeue)
a=rxqueue('c',usequeue)
if a<>usequeue then do
  bb=rxqueue('d',a)
  a=rxqueue('s',usequeue)
  do queued()
       pull
  end /* do */
end


a=eventsem_close(usesem)
A=EVENTSEM_CREATE(USESEM)
IF A<>0 then DO
    foo=pmprintf_sr(' SRE-http Monitor ERROR: creating puburl semaphore: 'A' 'usesem)
    return 0
end

badt=value('SREF_PUBURL_BAD',0,'os2environment')


puburl_tid=rexxthread('f',arxx,puburl_file,usequeue,USESEM,max_semwait,serverport)
if puburl_tid=0 then do
   foo=pmprintf_sr(' SRE-http Monitor: Could not open puburl thread 'arxx)
   return 0
end

return 1



/* ---------------- */
/* start virtual dir processor thread */
start_virtual:
parse arg resetit

IF VIRTUAL_FILE="" | SUPPRESS_VIRTUAL=1 then RETURN 0

dlistx=upload_dir||' '||cgi_bin_dir||'  '||addon_dir||' '
dlistx=dlistx||translate(datadir(),'\','/')

arxx=servdir||'\virtchk.rxx'
usequeue='SREF_'||serverport||'_VIRTUAL'
usesem='\SEM32\SREF_'||serverport||'_VIRTUAL'
badt=value('SREF_VIRTUAL_BAD',,'os2environment')

if  badt=1 |  resetit=1 then do            /* already opened --just send a *RESET* */
   foo=eventsem_query(usesem)   /* is it still alive? */
   if foo<0 then do
       call pmprintf("SRE-http Monitor: relaunching virtual_Dir daemon (semaphore was:"foo)
   end /* do */
   else do   
      a=rxqueue('s',usequeue)
      push '1,1,2, *RESET* ' virtual_file
      foo=eventsem_post(usesem)
      return 1
   end
end

if virtual_file= ' ' then
      return 0
oy=stream(virtual_file,'c','query exists')
if oy="" then do
   foo=pmprintf_sr("SRE-http Monitor: virtual file not found, "|| virtual_file)
   virtual_file=' '
   return 0
end

/* if here, first time */

a=rxqueue('d',usequeue)
a=rxqueue('c',usequeue)
if a<>usequeue then do
  bb=rxqueue('d',a)
  a=rxqueue('s',usequeue)
  do queued()
       pull
  end /* do */
end

a=eventsem_close(usesem)
A=EVENTSEM_CREATE(USESEM)
IF A<>0 then DO
    foo=pmprintf_sr(' SRE-http Monitor ERROR: creating virtual semaphore: 'A' 'usesem)
    return 0
end

badt=value('SREF_VIRTUAL_BAD',0,'os2environment')


mm1=max_semwait
virtual_tid=rexxthread('f',arxx,virtual_file||' '||dlistx,usequeue,USESEM,mm1,serverport)
if virtual_tid=0 then do
   foo=pmprintf_sr(' SRE-http Monitor:Could not open virtual thread 'arxx)
   return 0
end

return 1



/* ---------------- */
/* start variable storage thread */
start_varstore:
parse arg addme

arxx=servdir||'\varstore.rxx'
usequeue='SREF_'||serverport||'_VARSTORE'||addme
usesem='\SEM32\SREF_'||serverport||'_VARSTORE'||addme
a=rxqueue('d',usequeue)
a=rxqueue('c',usequeue)
if a<>usequeue then do
  bb=rxqueue('d',a)
  a=rxqueue('s',usequeue)
  do queued()
       pull
  end /* do */
end

a=eventsem_close(usesem)
A=EVENTSEM_CREATE(USESEM)
IF A<>0 then DO
    call pmprintf(' SRE-http Monitor ERROR: creating variable storage semaphore:'usesem)
    return 0
end
mm1=max_semwait
v_tid=rexxthread('f',arxx,usequeue,USESEM,mm1,serverport,x_limitclients)
if v_tid=0 then do
   call pmprintf(' SRE-http Monitor:Could not start variable storage thread 'arxx)
   return 0
end

return 1




/* ---------------- */
/* start superceding realm  thread */
start_srealm:
parse arg resetit

if no_superceding_realm=1 then return 0

arxx=servdir||'\srealm.rxx'
usequeue='SREF_'||serverport||'_SREALM'
usesem='\SEM32\SREF_'||serverport||'_SREALM'
badt=value('SREF_SREALM_BAD',,'os2environment')

if  badt=1 |  resetit=1 then do            /* already opened --just send a *RESET* */
   foo=eventsem_query(usesem)   /* is it still alive? */
   if foo<0 then do
       call pmprintf("SRE-http Monitor: relaunching superceding_realms daemon (semaphore was:"foo)
   end /* do */
   else do   
      a=rxqueue('s',usequeue)
      push '1,1,2, *RESET* ' 
      foo=eventsem_post(usesem)
      return 1
   end
end


a=rxqueue('d',usequeue)
a=rxqueue('c',usequeue)
if a<>usequeue then do
  bb=rxqueue('d',a)
  a=rxqueue('s',usequeue)
  do queued()
       pull
  end /* do */
end

a=eventsem_close(usesem)
A=EVENTSEM_CREATE(USESEM)
IF A<>0 then DO
    foo=pmprintf_sr(' SRE-http Monitor ERROR: creating superceding realm semaphore:'usesem)
    return 0
end
mm1=max_semwait

badt=value('SREF_SREALM_BAD',0,'os2environment')


ssicache_tid=rexxthread('f',arxx,defrealm_file_temp,usequeue,USESEM,mm1,serverport)
if ssicache_tid=0 then do
   foo=pmprintf_sr(' SRE-http Monitor:Could not open superceding realm thread 'arxx)
   return 0
end

return 1





/* ---------------- */
/* start virtual dir processor thread */
start_ssicache:
if ssi_cache_size="" then return 0

arxx=servdir||'\ssicache.rxx'
usequeue='SREF_'||serverport||'_SSICACHE'
usesem='\SEM32\SREF_'||serverport||'_SSICACHE'


a=rxqueue('d',usequeue)
a=rxqueue('c',usequeue)
if a<>usequeue then do
  bb=rxqueue('d',a)
  a=rxqueue('s',usequeue)
  do queued()
       pull
  end /* do */
end

a=eventsem_close(usesem)
A=EVENTSEM_CREATE(USESEM)
IF A<>0 then DO
    foo=pmprintf_sr(' SRE-http Monitor ERROR: creating ssi-cache semaphore:'usesem)
    return 0
end
mm1=max_semwait
ssicache_tid=rexxthread('f',arxx,tempdata_dir,usequeue,USESEM,mm1,serverport,ssi_cache_size,ssi_cache_duration,ssi_cache_stamp,serverport)
if ssicache_tid=0 then do
   foo=pmprintf_sr(' SRE-http Monitor:Could not open ssi-cache thread 'arxx)
   return 0
end

return 1



/* ---------------- */
/* start virtual dir processor thread */
start_sreproxy:
parse arg resetit

oo=value('SREF_PROXY',,'os2environment')
if oo='' | oo=0 then return 0

arxx=servdir||'\sreproxy.rxx'
afilter=servdir||'\SREFILTR.'||serverport
usequeue='SREF_SREPROXY'
usesem='\SEM32\SREF_SREPROXY'
badt=value('SREF_SREPROXY_BAD',,'os2environment')

if  badt=1 | resetit=1 then do            /* already opened --just send a *RESET* */
   foo=eventsem_query(usesem)   /* is it still alive? */
   if foo<0 then do
       call pmprintf("SRE-http Monitor: relaunching SRE_Proxy daemon (semaphore was:"foo)
   end /* do */
   else do   
      a=rxqueue('s',usequeue)
      push '1,1,2,RESET'
      foo=eventsem_post(usesem)
      return 1
   end
end

a=rxqueue('d',usequeue)
a=rxqueue('c',usequeue)
if a<>usequeue then do
  bb=rxqueue('d',a)
  a=rxqueue('s',usequeue)
  do queued()
       pull
  end /* do */
end

a=eventsem_close(usesem)
A=EVENTSEM_CREATE(USESEM)
IF A<>0 then DO
    foo=pmprintf_sr(' SRE-http Monitor ERROR: creating sreproxy:'usesem)
    return -1
end

badt=value('SREF_SREPROXY_BAD',0,'os2environment')


mm1=max_semwait
sreproxy_tid=rexxthread('f',arxx,tempdata_dir,usequeue,USESEM,mm1,serverport,afilter)
if sreproxy_tid=0 then do
   foo=pmprintf_sr(' SRE-http Monitor: Could not open sre-proxy thread 'arxx)
   return -1
end

return 1


/* ---------------- */
/* start user check processor thread */
start_user:
parse arg resetit
if user_file= ' ' | SUPPRESS_USER=1 then
      return 0

oy=stream(user_File,'c','query exists')
if oy="" then do
   foo=pmprintf_sr("SRE-http Monitor: userl file not found, "||user_file)
    user_file=' '
   return -1
end

arxx=servdir||'\userchk.rxx'
usequeue='SREF_'||serverport||'_USER'
usesem='\SEM32\SREF_'||serverport||'_USER'
badt=value('SREF_USER_BAD',,'os2environment')

if badt=1 | resetit=1 then do            /* already opened --just send a *RESET* */
   foo=eventsem_query(usesem)   /* is it still alive? */
   if badt=1 |  foo<0 then do
       call pmprintf("SRE-http Monitor: relaunching users daemon (semaphore was:"foo)
   end /* do */
   else do   
      a=rxqueue('s',usequeue)
      push '1,1,2, *RESET* ' user_File
      foo=eventsem_post(usesem)
      return 1
   end
end

/* if here, first time */
a=rxqueue('d',usequeue)
a=rxqueue('c',usequeue)
if a<>usequeue then do
  bb=rxqueue('d',a)
  a=rxqueue('s',usequeue)
  do queued()
       pull
  end /* do */
end

a=eventsem_close(usesem)
A=EVENTSEM_CREATE(USESEM)
IF A<>0 then DO
     if a=285  then do
        foo=pmprintf_sr(' SRE-http Monitor WARNING:  user semaphore exists: 'A' 'usesem)
     end /* do */
     else do
         foo=pmprintf_sr(' SRE-http Monitor ERROR: creating user semaphore: 'A' 'usesem)
          return 0
     end
end

badt=value('SREF_USER_BAD',0,'os2environment')

user_tid=rexxthread('f',arxx,user_file,usequeue,USESEM,max_semwait,logon_limit,serverport)
if user_tid=0 then do
   foo=pmprintf_sr(' SRE-http Monitor:Could not open user thread 'arxx)
   return 0
end


return 1


/* ---------------- */
/* start postfilter / recordall processor thread */
start_postf:
parse arg resetit

arxx=servdir||'\postfchk.rxx'
usequeue='SREF_'||serverport||'_POSTF'
usesem='\SEM32\SREF_'||serverport||'_POSTF'
badt=value('SREF_POSTF_BAD',,'os2environment')

if  badt=1 | resetit=1 then do                /* check that everything is okay */
   foo=eventsem_query(usesem)   /* is it still alive? */
   if foo<0 then do
       call pmprintf("SRE-http Monitor: relaunching postfilter daemon (semaphore was:"foo)
   end /* do */
   else do
     return 0             /* otherwise, it's okay */ 
   end
end /* do */


a=rxqueue('d',usequeue)
a=rxqueue('c',usequeue)
if a<>usequeue then do
  bb=rxqueue('d',a)
  a=rxqueue('s',usequeue)
  do queued()
       pull
  end /* do */
end


a=eventsem_close(usesem)
A=EVENTSEM_CREATE(USESEM)
IF A<>0 then DO
    foo=pmprintf_sr('SRE-http Monitor ERROR: creating postfilter semaphore: 'A' 'usesem)
    return 0
end

badt=value('SREF_POSTF_BAD',0,'os2environment')

mm1=max_semwait*1.5
postf_tid=rexxthread('f',arxx,usequeue,USESEM,thesem,mm1,record_cache_lines' 'workdata_dir,serverport,logfile_maxsize)
if postf_tid=0 then do
   foo=pmprintf_sr(' SRE-http Monitor:Could not open postfilter thread 'arxx)
   return 0
end

return 1



/* ----  */
/* make headers and footers, host specific possibly */
make_head_foot:procedure expose aheaders. afooters. headlist. footlist. ,
        headers footers  nheads nfoots headers. footers. serverport

foo=cvtails('headers.','b')
joe=arraysort('b')
crlf=' '
headers=' ' ; nheads=0 ; HDDONE=0
do mm=1 to b.0
    a1=b.mm
    a2=headers.a1
    if a2=" " then a2=0
    IF A2=0 then HDDONE=1
    if pos('.',a1)=0  then do
       if HDDONE=0 then  headers=headers||a2||crlf
    end  /* Do */
    else do             /* headers.hn */
       parse var a1 aval '.' ahost ; ahost=strip(ahost) ; aval=strip(aval)
       if strip(a2)=0 then do
             headstops.ahost=1
       end  /* Do */
       else do          /* not a stop */
         if aval=1 then  do
             nheads=nheads+1
              headlist.nheads=ahost
              aheaders.ahost=a2||crlf
             headstops.ahost=0
         end
         else do
           if headstops.ahost<>1 then
              aheaders.ahost=aheaders.ahost||a2||crlf
         end
       end              /* headstop */
    end                 /* .hn */
end
foo=cvtails('footers.','b')
joe=arraysort('b')
footers=' ' ; nfoots=0 ; FTDONE=0
do mm=1 to b.0
    a1=b.mm
    a2=footers.a1
    if a2=" " then a2=0
    IF A2=0 then FTDONE=1
    if pos('.',a1)=0  then do
       if FTDONE=0 then footers=footers||a2||crlf
    end  /* Do */
    else do             /* footers.hn */
       parse var a1 aval '.' ahost ; ahost=strip(ahost) ; aval=strip(aval)
       if strip(a2)=0 then do
             footstops.ahost=1
       end  /* Do */
       else do          /* not a stop */
         if aval=1 then  do
             nfoots=nfoots+1
              footlist.nfoots=ahost
              afooters.ahost=a2||crlf
             footstops.ahost=0
         end
         else do
           if footstops.ahost<>1 then
              afooters.ahost=afooters.ahost||a2||crlf
         end
       end              /* footstop */
    end                 /* .hn */
end

return 0


/*----------------------*/
save_em:
parse arg avar ;avar=strip(avar)

igot=0
drop plist

avar0=strip(avar,'t','.')
avar=avar0||'.'
rr=cvtails(avar,'plist')
do r1=1 to rr
   atail=plist.r1
   interpret 't1='||avar||atail
   call value envadd||avar||atail,t1,'os2environment'
   igot=igot+1
end

/* save the default (non hostname) version */
   if upper(symbol(avar0))="VAR" then do
      interpret 't1='||avar0
      call value envadd||avar0,t1,'os2environment'
      igot=igot+1
   end

return igot


/* --- variable names of convert foo.bar.1 to foo.1.bar */
fix_me:procedure
parse arg a1

if a1=' '  then return a1
a1=strip(a1)
if abbrev(a1,';') then return a1

parse var a1  aname '=' avalue
if pos('.',aname)=0 then return a1

foo=translate(aname,' ','.')
if words(foo)<>3 then return a1

/* if here, array.x.y (3 elements) */
if datatype(word(foo,3))='NUM' & datatype(word(foo,2))<>'NUM' then do  /* rearrange */
   foo2=word(foo,1)||'.'||word(foo,3)||'.'||word(foo,2)||' = '||avalue
   return foo2
end  /* Do */
else do
   return a1
end  /* Do */




/***************/
/* update addon's to macrospace. */
update_addons:procedure expose keep_addons. verbose envadd serverport
if symbol('KEEP_ADDONS.0')<>'VAR' then return  0 /* none specified*/
if datatype(keep_addons.0)<>'NUM'  then return 0

do iy=1 to keep_addons.0
   if symbol('KEEP_ADDONS.'||iy)<>'VAR' then iterate
   parse var keep_addons.iy asel afile . ; afile=strip(afile); asel=strip(asel)
   IF AFILE="" then DO          /* REMOVE ASEL */
      asel=strip(translate(asel,'/','\'),,'/')          
      tt=envadd||'ADDON_'||translate(asel,'__','/\')    
      FOO=MACROdROP(TT)
      ITERATE
   END
   if stream(afile,'c','query exists')="" then do
        if verbose>0 then foo=pmprintf_sr(" SRE-http Monitor WARNING: bad file in KEEP_ADDON entry: " asel ',' afile)
        iterate
   end  /* Do */
   asel=strip(translate(asel,'/','\'),,'/')
   tt=envadd||'ADDON_'||translate(asel,'__','/\')
   foo=macroadd(tt,afile,'B')
   if foo=0 then do
      if verbose>0 then foo=pmprintf_sr(" SRE-http Monitor WARNING: problem with KEEP_ADDON entry: " keep_addons.iy)
       iterate
   end  /* Do */
   if verbose>1 then foo=pmprintf_sr(' SRE-http Monitor: Okay ADDON entry: ' tt ' : ' afile)
end /* do */
return 0


/****************/
/* start the pmprintf thread 
itype: 1= use pmprintf, but check line lengths
       2= use pmprintf, and write to afile
       3= just write to afile
*/

start_pmprintf:
parse arg itype, ilen, afile,goo

arxx=servdir||'\pmprintf.rxx'
usequeue='SREF_'||serverport||'_PMPRINTF'
usesem='\SEM32\SREF_'||serverport||'_PMPRINTF'
badt=value('SREF_PMPRINTF_BAD',,'os2environment')

if badt=1 |  goo=1 then do                /* check that everything is okay */
   foo=eventsem_query(usesem)   /* is it still alive? */
   if foo<0 then do
       call pmprintf("SRE-http Monitor: relaunching pmprintf daemon (semaphore was:"foo)
   end /* do */
   else do
     return 0             /* otherwise, it's okay */ 
   end
end /* do */

if ilen<2 then ilen=80

/* check variables */
if itype=3 then ilen=0
if itype=1 then 
  afile=' '
else
  afile=servdir||'\'||strip(afile,,'\')

if itype>1 then do
  call lineout afile,' -- SRE-http log file: '||time('n')||' '||date('n')
  call lineout afile
end


/* start thread */
a=rxqueue('d',usequeue)
a=rxqueue('c',usequeue)
if a<>usequeue then do
  bb=rxqueue('d',a)
  a=rxqueue('s',usequeue)
  do queued()
       pull
  end /* do */
end

a=eventsem_close(usesem)
A=EVENTSEM_CREATE(USESEM)
IF A<>0 then DO
    call pmprintf(' SRE-http Monitor ERROR: creating PMPRINTF semaphore:'usesem)
    return 0
end

badt=value('SREF_PMPRINTF_BAD',0,'os2environment')


mm1=max_semwait
v_tid=rexxthread('f',arxx,usequeue,USESEM,mm1,ilen,itype,afile)
if v_tid=0 then do
   call pmprintf(' SRE-http Monitor:Could not start PMPRINTF thread 'arxx)
   return 0
end

return 1




/***************/
pmprintf_sr:procedure expose serverport
parse arg amess
foo=pmprintf_sref(amess,,serverport)
return 0


/*********************/
/* call the procedures listed in custom_inits */
call_custom_inits:procedure expose serverport
parse arg alist
signal off error ; signal off syntax ;
signal on error name yipes2 ; signal on syntax name yipes2 ;
if alist=0 then alist=""

if alist="" then do
    call pmprintf(' SRE-http Monitor: no custom initialization procedures specified')
   return 1
end /* do */

do until alist=""
    parse var alist aproc ',' alist
    if aproc="" then leave
    parse var aproc aname anarg
    call pmprintf('SRE-http Monitor: executing initialization procedure 'aproc)
    dog='okay='||aname||'("'anarg'")'
    interpret dog
end /* do */


signal on error name yipes ; signal on syntax name yipes ;

return 1

yipes2:
call pmprintf(' SRE-http Monitor ERROR: running external initialization procedure: 'aproc)
call pmprintf(dog)
return 0

/******************/
/* call rexxlib date conversion, but check y2k first */
dateconv_3:procedure 
parse upper arg aval,t1,t2
hh=''
select 
 when t1='O' | t1='U' | t1='E' then do
   if t1='O' then      parse var aval yy '/' mo '/' dd '/' hh '/' mm .
   if t1='U' then     parse var aval mo '/' dd '/' yy
   if t1='E' then     parse var aval dd '/' mo '/' yy
   if yy<78 then 
       yy=2000+yy 
   else
      yy=yy+1900
    yip=strip(yy)||strip(mo)||strip(dd)
    adatef=dateconv(yip,'S',t2)
 end
 otherwise do
    adatef=dateconv(aval,t1,t2)
 end
end

if hh<>'' then do
     adatef=adatef+(((hh*60)+mm)/1440)
end /* do */

return adatef



/******/
/* set an error flag, wake up srefilter, exit */
gosexit:
PARSE ARG AA
foo1=value('SREF_WAIT_FLAG',-2,'os2environment')
FOO2=VALUE('SREF_WAIT_FLAG_ERROR',AA,'OS2ENVIRONMENT')
foo3=eventsem_create(thesem)
foo2=eventsem_post(thesem)

exit  


