home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Spezial / SPEZIAL2_97.zip / SPEZIAL2_97.iso / ANWEND / ONLINE / SREFV12J / POSTFCHK.RXX < prev    next >
Text File  |  1997-09-19  |  39KB  |  1,334 lines

  1. /* Recording and postfilter module for sre-filter */
  2.  
  3. /* Some comments on the "record_all_file" cache algorithim:
  4.    To speed up performance, SRE-Filter caches all writes
  5.    to the record_all_file.  This saves disk i/o (and repetitive
  6.    parsing of the entries).
  7.  
  8.    There are a few points worth considering in regards to this caching:
  9.       1) More memory is required to store the cache.  One
  10.          can limit the size of the cache by changing the record_cache_lines
  11.          variable, with smaller values yielding smaller caches.
  12.          For example, the default value of 1000 means "1000 entries".
  13.          At an average size of 50 bytes, that's around
  14.          5000 bytes total storage.
  15.  
  16.       2) If you have a lot of files being requested, with each having
  17.          their own entry  (that is, few if any wildcards), you may fill up
  18.          this cache. When this happens, SRE-Filter will write the
  19.          current cache to an archive file (with name .1 to .999),
  20.          and reset all values. "Reset" means:
  21.                 a) Set "counter" values on wildcards to 0
  22.                 b) Remove non-wildcard entries
  23.         Of course, this new file could also fill up quickly, yielding
  24.         a multiplicity of archive files.
  25.         Should this happen, you should probably increase the size of the cache.
  26.  
  27.       3) As a safety measure, the cache will be written to the record_all_file
  28.          every 5 minutes. When doing this, the current record_all_file
  29.          is given the name .bak (overwriting a preexisting .bak file).
  30.  
  31.       4) If you should change the record_all_file by hand (you add
  32.          a wildcard entry), SRE-Filter will detect the change and
  33.          re-read the file into the cache.  This will ERASE
  34.          all "recorded in cache but not written to file" entries --
  35.          that is, everything in the (up to) last 5 minutes.
  36.          If this minor inaccuracy (assuming that adding entries to
  37.          the Record_all_file is a rare event) can be avoided by:
  38.                 1) Turning off caching (set RECORD_CACHE_LINES=0)
  39.                 2) Setting a very fast update rate (set UPDATE_RATE=0.2,
  40.                    see below for details)
  41.                 3) Issue a !WRITE_CACHE request just prior to editing
  42.                    the record_all_file (though this any changes that
  43.                    occur whilst editing the file will be missed).
  44.          Only method #1 is guaranteed to work, but it also is the slowest.
  45.          Then again, absolute accuracy in this type of general audit
  46.          file is usually not a priority (you should use SENDFILE
  47.          for greater precision)
  48.  
  49.      5) When writing the cache, SRE-Filter will
  50.            a)put ALL comments at the top
  51.            b)write the list of "wildcard entries" (if any)
  52.            c)write the "non-wildcard entries" (if any)
  53.         Thus, placements of comments in between entries will be
  54.         lost (sorry, if that's really a problem contact us
  55.         and we'll consider keeping track of placement so as
  56.         to preserve order on writes).
  57.  
  58.         In fact, the most frequent "non-wildcard" entries will
  59.         be written first!
  60.  
  61.       6) If active, the HIT_CACHE will be examined before
  62.          recording an entry.
  63.  
  64. */
  65.  
  66. /* -----------------------------------------*/
  67. /* Some user configurable parameters -- you have to restart goserve
  68. for them to take effect*/
  69.  
  70. /* enter frequency, in minutes, for writing record_all cache to file (0.2 < x < 60)
  71. Note: to suppress caching, set record_cache_lines=0 in srefiltr.80
  72. */
  73. update_rate=5
  74.  
  75.  
  76. /* enter lazy_write time for common log cache, in seconds */
  77. lazy_clog=22
  78.  
  79.  
  80. /* warn (via pmprintf) when log file gets over this size (in kbytes) */
  81. /* to suppress this check, set log_toobig=0 (not checking saves a little bit of time)*/
  82. /* hint: consider use of RENLOGS.CMD and the SCHED. option */
  83. log_toobig=1000
  84.  
  85. /* starting verbosity level */
  86. verbose=1
  87.  
  88.  
  89. /* ---- Do NOT change code below here ---------------------------*/
  90.  
  91. parse upper arg   usequeue , USESEM,basesem,max_semwait, stuff
  92. parse var stuff record_cache_lines workdir
  93. workdir=strip(workdir,'t','\')
  94.  
  95. call pmprintf_sref(' SRE-FILTER postfilter thread: queue='||usequeue)
  96. call pmprintf_sref(' SRE-FILTER postfilter thread: semaphore='||usesem)
  97.  
  98.  
  99.  
  100. mytid=dostid()
  101. call pmprintf_sref(' SRE-FILTER postfilter thread: thread id='||mytid)
  102.  
  103. myqueue=usequeue||'_X'
  104. mysem=usesem||'_X'
  105. a=rxqueue('d',myqueue)
  106. a=rxqueue('c',myqueue)
  107. if a<>myqueue then do
  108.   bb=rxqueue('d','a')
  109.   a=rxqueue('s',myqueue)
  110.   do queued()
  111.        pull
  112.   end /* do */
  113. end
  114.  
  115. a=eventsem_close(mysem)
  116. A=EVENTSEM_CREATE(mySEM)
  117. IF A<>0 then DO
  118.     call pmprintf_sref('SRE-Filter post filter thread:: Error creating own semaphore: 'A' 'mysem)
  119.     return 0
  120. end
  121.  
  122.  
  123. if  usequeue="" | USESEM="" then do
  124.    call pmprintf_sref('SRE-FILTER postfilter thread: initialization ERROR: '||accessfile||','||usequeue)
  125.    exit
  126. end
  127.  
  128. signal on error name iserror
  129. signal on syntax name iserror
  130.  
  131. comments.filestamp=0
  132. if datatype(update_rate)<>'NUM' then update_rate=5
  133. update_rate=max(min(update_rate,60),0.2)
  134. update_rate=update_rate/(24*60)
  135.  
  136. if datatype(lazy_clog)<>'NUM' then lazy_clog=30
  137. if lazy_clog>1000 then lazy_clog=1000   /* in case some on messes up */
  138.  
  139. if datatype(log_toobig)<>'NUM' then log_toobig=1000
  140.  
  141. /* get sreflogs.ini from workdir */
  142. afl=workdir||'\SREFLOGS.INI'
  143. logini=stream(afl,'c','query exists')
  144. got_log=1
  145. if logini="" then got_log=0   /* no .ini file -- no log writing */
  146. if got_log=1 then 
  147.   call pmprintf_sref(' SRE-FILTER postfilter thread: common-log configuration file='logini)
  148. else
  149.   call pmprintf_sref(' SRE-FILTER postfilter thread:  ERROR, no common-log configuration file='afl)
  150.  
  151. foo=GET_sreflogs()
  152. blog.0=0; clog.0=0 ; rlog.0=0 ; alllog.0=0
  153. lasttime=time('s') ; THISTIME=LASTTIME
  154. do_write_cache=0 
  155. last_hour_checked=-1
  156.  
  157. /* loop forevvefeerrrererere ...... */
  158. bakme:
  159.  
  160.  thistime=time('s')
  161. /* write common log, and perhaps update the .ini file */
  162.  eekit=10000
  163.  if datatype(thistime)='NUM' & datatype('LASTTIME')='NUM' then eekit=thistime-lasttime
  164.  if ( abs(eekit)>lazy_clog  | do_wRITE_CACHE=1) & got_log=1 then do
  165.        do_write_cache=0
  166.        foo=write_clog(thistime,lasttime,log_toobig)
  167.        foo=write_blog()
  168.        foo=write_rlog()
  169.        foo=write_alllog()
  170.        if (write_logs<>0) & ( (verbose>2 & clog.0>0) | verbose>3 |  (abbrev(upper(seloriginal),'!WRITE_CACHE')=1) ) then
  171.           call pmprintf_sref(' Writing common-log entries: 'clog.0','blog.0','rlog.0','alllog.0)
  172.        ostamp=sysfiletree(logini,'FOO','F');OSTAMP=FOO.1
  173.        if  ostamp<>stuff.!stamp then do
  174.          if verbose>1 then call pmprintf_sref(' SRE-FILTER postfilter thread: updating 'logini)
  175.          foo=GET_sreflogs()
  176.        end
  177.  
  178.        lasttime=thistime
  179.        blog.0=0; clog.0=0 ; rlog.0=0 ; alllog.0=0
  180.  end
  181.  
  182.  foo=do_scheduler()   /* take this opportunity to run scheduled events */
  183.  signal on error name iserror
  184.  signal on syntax name iserror
  185.  
  186.  a=rxqueue('s',usequeue)
  187.  goo=queued()
  188.  if goo=0 then do
  189.     WOW=EVENTSEM_WAIT(USESEM,max_semwait)
  190.  
  191.     if wow=640 then do
  192.         signal bakme
  193.     end
  194.     IF WOW<>0 THEN do         /* FATAL ERROR */
  195.         EXIT
  196.     end
  197.  end
  198.  wow=EVENTSEM_RESET(usesem)
  199.  if queued()<1 then signal bakme
  200.  parse pull isit0
  201.  isit0=translate(isit0,' ','000d0a09'x)
  202.  
  203.  if isit0=" " then signal bakme
  204.  
  205.  if abbrev(strip(translate(isit0)),'*DIE*')=1 then do
  206.      call pmprintf_sref('SRE-FILTER postfilter thread: terminating ')
  207.      exit
  208.  end
  209.  if isit0="" then do
  210.       call pmprintf_sref('SRE-FILTER postfilter thread: bad message ')
  211.      signal bakme
  212. end
  213.  
  214. parse var isit0 record_option ',' record_all_file ',' post_filter ',' postfilter_name ',' serverport ',' ,
  215.                  post_filter_message ',' source0 ',' request0a ',' ,
  216.                sel0 ',' tempfile ','  servername ',' host_nickname ',' used_file ',' who  ',' ,
  217.                enmadd ',' thereferer ',' tcache ',' REcord2 ',' write_logs ',' clientname0 ',' user ','  browser ',' verbose
  218.  
  219. parse var record2 record_status record_bytes
  220. write_logs=strip(write_logs) ; clientname0=upper(strip(clientname0))
  221. if got_Log=0 then write_logs=0
  222. browser=strip(browser) ; user=strip(user)
  223. if user=' ' then user='-'
  224. verbose=strip(verbose)
  225.  
  226.  record_option=strip(record_option) ; post_filter=strip(post_filter)
  227.  postfilter_name=strip(postfilter_name) ; record_all_file=strip(record_all_file)
  228. serverport=strip(serverport) ; servername=strip(servername)
  229. host_Nickname=strip(Host_nickname) ; used_file=strip(used_file)
  230. parse var sel0 doorig sel0
  231. seloriginal=packur(strip(sel0)) 
  232.  
  233. who=strip(who)
  234. request0=strip(request0a)
  235. post_filter_message=packur(post_filter_message)
  236. enmadd=strip(enmadd) ; tcache=strip(tcache)
  237. thereferer=strip(thereferer)
  238.  
  239. parse var seloriginal doit '?' .
  240.  
  241. if abbrev(upper(seloriginal),'!WRITE_CACHE')=1 then do_write_cache=1
  242.  
  243.  
  244.  if record_option<>"NO" then do
  245.      select
  246.         when record_option="YES" then
  247.                 parse var seloriginal doit '?' .
  248.         when record_option='YES_ALL' then
  249.                 doit=seloriginal
  250.         otherwise                       /* file */
  251.               doit=used_File
  252.      end
  253.  
  254.      doit=strip(strip(doit),'l','/')
  255.      if host_Nickname<>"" & record_option<>'FILE' then
  256.                doit=host_Nickname'//'doit
  257.       njust=' '
  258.       if do_write_cache<>1 then   njust=look_hit_cache('P',doit,who,enmadd)
  259.  
  260.       if njust=' ' then do      /* not in cache, so record */
  261.          zfoo=0                   /* do we use a recordall file cache? */
  262.          if record_cache_lines>0 then do
  263.             zfoo=do_cache_record(record_all_file,doit,seloriginal)
  264.          end
  265.          if zfoo=0 then do
  266.              foo=sref_lookup_count(record_all_file,doit,'ADD','OK',2)
  267.          end
  268.          foo=add_hit_cache("P",doit,who,enmadd,zfoo)
  269.       end               /* not just hit */
  270.   end                   /* record option */
  271.  
  272. /* log this one (uses stuff. */
  273.  iik=is_logok(seloriginal,doorig,clientname0,record_status,write_logs,user)
  274.  if iik=1 then do               /* write to the common log file */
  275.       d1=space(strip(date('n'))); 
  276.       parse var d1 d1a d1b d1c
  277.       if d1a<10 then d1a='0'||d1a
  278.       d1=d1a||'/'||d1b||'/'||d1c
  279.       t1=time('n')
  280.       d1t1=d1||':'||t1
  281.       agmt=gmtoffset() ; if datatype(agmt)<>'NUM' then agmt=0
  282.  
  283.       if datatype(agmt)='NUM' then do
  284.          agmt=agmt/36
  285.          if abs(agmt)<1000 then do
  286.              if agmt>0 then
  287.                  agmt='0'||agmt
  288.              else
  289.                  agmt='-0'||abs(agmt)
  290.          end
  291.       end
  292.       d1t1_0=d1t1
  293.       d1t1=d1t1||' '||agmt
  294.       parse var request0 mkme a2a a3
  295.       thereq=strip(a2a)
  296.       if stuff.!nooptions=1 then parse var thereq thereq '?' .
  297.       mkme=mkme||' '||thereq
  298.       if stuff.!nohttp=0 then mkme=mkme||' '||a3
  299.       d1t1='['||d1t1||']'
  300.       d1t1_0='['||d1t1_0||']'
  301. /* this is the output to the common-log file */
  302.       ii=clog.0+1
  303.       clogq=clientname0||' - '||user||' '||d1t1||' "'||mkme||'" '||strip(record2)
  304.  
  305.       clog.ii=clogq
  306.       clog.ii.!file=which_logs(serverport,host_nickname,'COMMONLOG')
  307.       clog.0=ii
  308.  
  309. /* the browser log */
  310.       ii=blog.0+1
  311.       blog.ii.!file=which_logs(serverport,host_nickname,'BROWSERLOG')
  312.       if stuff.!apache_mode=1 then
  313.          blogq=d1t1_0||' '||browser
  314.       else
  315.          blogq=d1t1||' '||clientname0||' '||browser
  316.       blog.ii=blogq
  317.       blog.0=ii
  318.  
  319. /* the referer log */
  320.       if stuff.!force_referer=1 & thereferer=' ' then thereferer=' - '
  321.       if thereferer<>" " then do
  322.           parse var thereferer . '//' refip '/' .
  323.           iik=is_logok(-1,,refip)
  324.           if iik=1 then do
  325.              ii=rlog.0+1
  326.              if stuff.!apache_mode=1 then
  327.                 rlogq=d1t1_0||' '||thereferer||' -> '||thereq
  328.              else
  329.                 rlogq=d1t1||' "'||thereq||'" '||thereferer
  330.              rlog.ii.!file=which_logs(serverport,host_nickname,'REFERERLOG')
  331.              rlog.ii=rlogq
  332.              rlog.0=ii
  333.           end
  334.       end
  335.  
  336. /* the combined log */
  337. /* eg: (all on one line) :
  338. lion.statslab.cam.ac.uk - - [18/Jan/1996:12:04:23 +0000]
  339. "GET /~sret1/analog/ HTTP/1.0" 200 578 
  340. "http://www.statslab.cam.ac.uk/~sret1/"
  341. "Mozilla/2.0 (X11; I; HP-UX A.09.05 9000/735)"
  342. */
  343.      ii=alllog.0+1
  344.      alllog.ii=clogq||' "'||thereferer||'" "'||browser||'"'
  345.      alllog.ii.!file=which_logs(serverport,host_nickname,'COMBINEDLOG')
  346.      alllog.0=ii
  347.      if verbose>0 then  foo=pmprintf_sref(clogq,1)  /* do NOT write to srefiltr.log */
  348.  
  349.   end
  350.  
  351.  IF POST_FILTER="NO" | post_filter=0 THEN do
  352.     if tcache<>' ' then foo=sysfiledelete(tcache)
  353.     signal bakme
  354.   end
  355.  
  356.  tookie=postfilter_name
  357.  do mm=1 to words(tookie)
  358.    postfilter_name=word(tookie,mm)
  359.    if pos('.',postfilter_name)=0 then
  360.         postfilter_name=postfilter_name||'.'||serverport
  361.  
  362.    signal on syntax name bad2
  363.    signal on error name bad2
  364.     yow='foo3='||postfilter_name||'(post_filter_message,source0,request0a,sel0,tempfile,servername,HOST_NICKNAME,used_file,thereferer,tcache,record2)'
  365.  
  366.    interpret yow
  367.  
  368.    signal off syntax;  signal off error
  369.  end
  370.  
  371.  if tcache<>' ' then foo=sysfiledelete(tcache)
  372.  signal bakme
  373.  
  374. bad2:
  375.   signal off syntax; signal off error
  376.   call pmprintf_sref(" SRE-Filter Postfilter Thread: Problem in post_filter routine " postfilter_name " ("seloriginal)
  377.   if tcache<>' ' then foo=sysfiledelete(tcache)
  378.   signal bakme
  379.  
  380.  
  381. iserror:
  382. signal off error ; signal off syntax
  383. call pmprintf_sref(' error in postfilter : resetting 'sigl' (rc='rc)
  384. a=rxqueue('d',usequeue)
  385. a=rxqueue('c',usequeue)
  386. a=eventsem_close(usesem)
  387. a=eventsem_create(usesem)
  388. call pmprintf_sref(' done resetting postfilter ')
  389. signal on error name iserror
  390. signal on syntax name iserror
  391. signal bakme
  392.  
  393.  
  394. /* ========================================================== */
  395. /* --- handle "cached recordall_file -----*/
  396. do_cache_record:procedure expose record_cache_lines wilds. comments. simples. ,
  397.                 update_rate verbose
  398.  
  399. parse arg record_all_file,doit,doit0
  400.  
  401. numeric digits 15
  402.  
  403. /* no cache -- then get one */
  404. if comments.filestamp=0 then do
  405.     nrecs=open_record_cache(record_all_file)
  406.    if verbose>0 then call pmprintf_sref(" First read of RECORD_ALL_FILE: " nrecs)
  407.     if nrecs=0 then return 0
  408. end
  409. else do
  410.     nrecs=comments.0+simples.0+wilds.0
  411. end  /* Do */
  412.  
  413. /* cache too big? */
  414. if nrecs>record_cache_lines then do
  415.     nrecs=reset_cache(record_all_file,record_cache_lines)
  416. end
  417.  
  418. /* add current hit,  or re-read file  */
  419. foo=update_cache(doit)
  420.  
  421. /* do a timed updated to disk */
  422. d1=date('b')
  423. t1=time('s')/(24*60*60)
  424. nowtime=d1+t1
  425. yeeks=comments.istime+update_rate
  426. if (yeeks<nowtime) | strip(upper(doit0))="!WRITE_CACHE" then do
  427.    foo=save_cache(record_all_file)
  428. end
  429.  
  430.  
  431. return 1
  432.  
  433.  
  434. /* ---------------- read recordall file into cache */
  435. open_record_cache:procedure expose wilds. comments. simples. verbose
  436. parse arg record_all_file
  437.  
  438. aa=sref_fileread(record_all_file,thelines,,'E')
  439. if aa<0 then return 0                /* error, use default method */
  440.  
  441. drop wilds. comments. simples.
  442.  
  443. nsimples=0 ; ncomments=0 ; nwilds=0
  444. simples.0=0 ; comments.0=0 ; wilds.0=0
  445. do mm=1 to thelines.0
  446.    aline=strip(thelines.mm)
  447.    if abbrev(aline,';')=1 | aline=' '  then do
  448.         if aline=' ' then iterate
  449.         ncomments=ncomments+1
  450.         comments.ncomments=aline
  451.         comments.0=ncomments
  452.    end
  453.    else do
  454.        parse  var aline aname act amess
  455.        if pos('*',aname)>0 then do
  456.            aname=strip(aname)
  457.            aname=translate(aname,'/','\')
  458.            aname=strip(aname,'l','/')
  459.            if act="" | datatype(act)<>'NUM' then act=0
  460.            nwilds=nwilds+1
  461.            wilds.nwilds.qname=aname ; wilds.nwilds.qct=act
  462.            wilds.nwilds.qmess=amess
  463.            wilds.0=nwilds
  464.        end
  465.        else do
  466.             nsimples=nsimples+1
  467.             if act="" | datatype(act)<>'NUM' then act=0
  468.             simples.nsimples.qname=aname; simples.nsimples.qct=act
  469.             simples.nsimples.qmess=amess
  470.             simples.0=nsimples
  471.        end
  472.    end
  473. end
  474.  
  475. /* get time stamp */
  476. d1=date('b')
  477. t1=time('s')/(24*60*60)
  478. comments.istime=d1+t1
  479.  
  480. /* get file stamp */
  481. oo=sysfiletree(record_all_file,'yow')
  482. comments.filestamp=strip(upper(yow.1))
  483.  
  484.  
  485. return nwilds+ncomments+nsimples
  486.  
  487.  
  488. /* ------------------- Write cache---------------*/
  489. write_cache:procedure expose comments. wilds. simples. verbose
  490. parse arg rfile,addtimestamp
  491.  
  492.  
  493. nj=0
  494. if addtimestamp=1 then do
  495.    nj=1
  496.    alines.nj="; File reset on: "||time('N')||' '||date('N')
  497. end  /* Do */
  498.  
  499. do mm=1 to comments.0
  500.   nj=nj+1
  501.   alines.nj=comments.mm
  502. end
  503. do mm=1 to wilds.0
  504.   nj=nj+1
  505.   alines.nj=wilds.mm.qname||' '||wilds.mm.qct||' '||wilds.mm.qmess
  506. end
  507.  
  508.  
  509. /* sort simples in descending order, by frequency */
  510. do iy=1 to simples.0
  511.    foobar.iy=simples.iy.qct'         'iy
  512. end
  513. if simples.0>0 then wow=arraysort(foobar,1,simples.0,1,8,'D','N')
  514.  
  515. do mm=1 to simples.0
  516.     parse var foobar.mm act indx ; indx=strip(indx)
  517.     nj=nj+1
  518.     alines.nj=simples.indx.qname||' '||simples.indx.qct||' '||simples.indx.qmess
  519. end
  520.  
  521. alines.0=nj
  522.  
  523.  
  524.  
  525. wow=filewrite(rfile,alines)
  526.  
  527. /* get time stamp */
  528. d1=date('b')
  529. t1=time('s')/(24*60*60)
  530. comments.istime=d1+t1
  531.  
  532. /* get file stamp */
  533. oo=sysfiletree(rfile,'yow')
  534. comments.filestamp=strip(upper(yow.1))
  535.  
  536.  
  537. if wow=0 then return 0
  538.  
  539. return nj
  540.  
  541.  
  542. /* ------------- Reset the cache: --------------------- */
  543. /*     Save current cache to a backup recordall file, delete current
  544.      cache file, and rewrite minimal (just wildcards and comments)
  545.      set
  546. */
  547.  
  548. reset_cache:procedure expose comments. wilds. simples. verbose
  549. parse arg rfile,maxlines
  550.  
  551. /* but update if external changes occured  (might obviate need to shrink cache) */
  552. isold=cache_unsync(rfile,comments.filestamp)
  553. if isold=1 then do
  554.      nrecs=open_record_cache(rfile)
  555.      if verbose>0 then call pmprintf_sref(' External change, reread RECORD_ALL_FILE into cache ')
  556.      return nrecs
  557. end
  558.  
  559. rfile2=rfile
  560. /* rename recordallfile to record.nnn (nnn=01 .. 999) */
  561. foofoo=lastpos('.',rfile)
  562. if foofoo>0 then
  563.    rfile2=delstr(rfile,foofoo)
  564.  
  565. useme=' '
  566. do mm=1 to 999
  567.    if stream(rfile2||'.'||mm,'c','query exists')=' ' then do
  568.        useme=rfile2||'.'||mm
  569.        leave
  570.    end
  571. end
  572. if useme=' ' then useme=dostempname(rfile2||'.???') /* should never happen ..*/
  573. foo=dosrename(rfile,useme)
  574. if foo=0 then return 0
  575. if verbose>0 then call pmprintf_sref('RECORD_ALL_FILE too big; reset (old file renamed to '||useme)
  576.  
  577. if wilds.0+comments.0> maxlines then do
  578.    if verbose>0 then call pmprintf_sref(" Warning: truncating comments in (RECORD_ALL_FILE) " rfile)
  579.    comments.0=trunc(maxlines/2)
  580. end
  581.  
  582. /* reset counts */
  583. simples.0=0
  584. do mm=1 to wilds.0
  585.    wilds.mm.qct=0
  586. end
  587.  
  588. nrec=write_cache(rfile,1)
  589. if verbose>0 then call pmprintf_sref(" Write RECORD_ALL_FILE cache: " nrec)
  590.  
  591. return wilds.0
  592.  
  593.  
  594.  
  595.  
  596.  
  597. /* --------------------- update cache ---------*/
  598. /* match an entry to existing cache -- augment the match
  599. or add a new entry */
  600.  
  601. update_cache:procedure expose wilds. simples. verbose
  602.  
  603. parse arg doit
  604.  
  605. /* fix up doit */
  606. doit=translate(strip(doit),'/','\')
  607. doit=strip(doit,'l','/')
  608.  
  609. nsimples=simples.0
  610. do mm=1 to nsimples
  611.    if upper(simples.mm.qname)=upper(doit) then do
  612.         simples.mm.qct=simples.mm.qct+1
  613.         simples.mm.qmess=date('o')
  614.         return 1
  615.    end
  616. end
  617.  
  618.  
  619. nwilds=wilds.0
  620. asterat=0 ; afterstar=0 ; gotit=0
  621. do mm=1 to nwilds
  622.     ares=sref_wildcard(upper(doit),upper(wilds.mm.qname),0)
  623.     parse var ares astat "," aurl ;  astat=strip(astat)
  624.     if astat=0 then iterate   /* no match */
  625.  
  626.    foo1=pos('*',wilds.mm.qname)
  627.    if foo1 >= asterat then do
  628.        tmp1=length(wilds.mm.qname)-foo1
  629.        if foo1>asterat | tmp1>afteraster then  do
  630.           asterat=foo1 ; afteraster=tmp1
  631.           gotit=mm
  632.        end              /* either condition */
  633.     end
  634. end
  635.  
  636. if gotit>0 then do
  637.     wilds.gotit.qct=wilds.gotit.qct+1
  638.     wilds.gotit.qmess=date('O')
  639.     return 1
  640. end
  641.  
  642.  
  643. nsimples=nsimples+1 ;simples.0=nsimples
  644. simples.nsimples.qname=doit
  645. simples.nsimples.qct=1
  646. simples.nsimples.qmess=date('o')
  647.  
  648.  
  649. return 1
  650.  
  651.  
  652. /* ------------- save the cache: --------------------- */
  653. /*     Save current cache to recordall file, rename current
  654.       file to .bak
  655. */
  656.  
  657. save_cache:procedure expose comments. wilds. simples. verbose
  658. parse arg rfile
  659.  
  660.  
  661. /* but update if external changes occured  */
  662. isold=cache_unsync(rfile,comments.filestamp)
  663. if isold=1 then do
  664.      nrecs=open_record_cache(rfile)
  665.      if verbose>0 then call pmprintf_sref(' RECORD_ALL_FILE changed, did not write cache (reread RECORD_ALL_FILE instead ')
  666.      return nrecs
  667. end
  668.  
  669.  
  670.  
  671. rfile2=rfile
  672. /* rename recordallfile to record.nnn (nnn=01 .. 999) */
  673. foofoo=lastpos('.',rfile)
  674. if foofoo>0 then
  675.    rfile2=delstr(rfile,foofoo)
  676. useme=rfile2||'.bak'
  677. a=sysfiledelete(useme)
  678. a=dosrename(rfile,useme)
  679. if verbose>1 then  call pmprintf_sref(' Writing current RECORD_ALL_FILE cache ')
  680.  
  681. nrec=write_cache(rfile,0)
  682.  
  683. return nrec
  684.  
  685.  
  686. /* --- return 1 if filestamp has changed */
  687. cache_unsync:procedure expose verbose
  688. parse arg record_all_file,thestamp
  689.  
  690. /* get file stamp */
  691.  
  692. oo=sysfiletree(record_all_file,'yow')
  693. afilestamp=strip(upper(yow.1))
  694.  
  695. if afilestamp=thestamp then return 0
  696. return 1
  697.  
  698.  
  699. /* -------- get julian date/time of file ----*/
  700. file_jul_date:procedure
  701. parse arg afile
  702.  
  703. how0=dosfileinfo(afile,'W')
  704. parse var how0 how hh ':' mm ':' ss
  705. nsec=((hh*60*60) + (mm*60) + ss)/(24*60*60)
  706. ndays=dateconv(how,'U','B')
  707. return ndays+nsec
  708.  
  709.  
  710. /***************************/
  711. /* check for log suppression condition */
  712. is_logok:procedure expose stuff.
  713. parse upper arg sel1,doorig,clientname0,record_status,write_logs,user
  714.  
  715.  
  716. if sel1=-1 then do
  717.     aa=stuff.!noreferer
  718.     if aa=' ' then return 1
  719. end
  720. else do
  721.     if write_logs=0 then return 0
  722.  /* check status */
  723.     aa=stuff.!nocodes
  724.    if wordpos(strip(record_status),aa)>0 then return 0
  725.  
  726. /* check clientname */
  727.  
  728.     aa=stuff.!nouser
  729. /* is it a direct match to the "user" */
  730.     if wordpos(upper(user),aa)>0 then return 0
  731. end
  732.  
  733. /* nope, so now check ip addresses  (possibly noreferer) */
  734. c1=translate(clientname0,' ','.')
  735. do ll=1 to words(aa)
  736.    aa1=upper(strip(word(aa,ll)))  /* for each entry in the nouser list */
  737.    if clientname0=aa1 then return 0       /* exact match */
  738.    if user=aa1 then return 0       /* exact match */
  739.  
  740.    if pos('*',aa1)>0 then do     /* possible wild card match */
  741.         aa1=translate(aa1,' ','.')
  742.         if words(aa1) <> words(c1) then iterate /* can't be a match */
  743.         die=1
  744.         do ll2=1 to words(c1)
  745.              c1q=strip(word(c1,ll2)) ; aa1q=strip(word(aa1,ll2))
  746.              if aa1q='*' then iterate
  747.              if c1q=aa1q then iterate
  748.              die=0 ; leave              /* if here, segment did not match */
  749.         end /* do */
  750.         if die=1 then return 0  /* all segments matched */
  751.    end  /* Do wildcard  */
  752. end /* do */
  753.  
  754. if sel=-1 then return 1         /* noreferer did NOT match */
  755.  
  756. /* check urls */
  757. theurl=strip(sel1)
  758. if doorig=1 then theurl=' '
  759. ido=stuff.!nourl.0
  760. starat=0 ; afterstar=0
  761.  
  762. do mm=1 to ido
  763.     aurl0=stuff.!nourl.mm
  764.     ares=sref_wildcard(theurl,aurl0,0)
  765.     parse var ares astat  .
  766.     astat=strip(astat)
  767.     if astat=0 then iterate   /* no match */
  768.     return 0  /* match, so it's dead */
  769. end
  770. return 1
  771.  
  772.  
  773.  
  774. /***************************/
  775. /* read sreflogs.ini file, return stuff in stuff. */
  776. get_sreflogs:procedure expose stuff. workdir verbose
  777. parse arg afl
  778. /* possible varialbes */
  779.   varlist="COMMONLOG BROWSERLOG REFERERLOG COMBINEDLOG NOOPTIONS FORCE_REFERER APACHE_MODE NOHTTP NOCODES NOUSER NOREFERER NOURL "
  780.   stemlist="COMMONLOG BROWSERLOG REFERERLOG COMBINEDLOG NOURL SCHED "
  781.  
  782. /* default values */
  783.  stuff.!nooptions=0 ; stuff.!nohttp=0
  784.  stuff.!nourl.0=0 ; stuff.!noreferer=' '
  785.  stuff.!nocodes=' ' ; stuff.!nouser=' '
  786.  stuff.!commonlog=workdir||'\COMMON.LOG'
  787.  stuff.!browserlog=workdir||'\BROWSER.LOG'
  788.  stuff.!refererlog=workdir||'\REFEFER.LOG'
  789.  stuff.!combinedlog=workdir||'\COMBINED.LOG'
  790.  
  791.  stuff.!list='COMMONLOG BROWSERLOG REFERERLOG COMBINEDLOG'
  792.  stuff.!stamp=' '
  793.  stuff.!sched.0=0
  794.  
  795. /* look in sreflogs.ini for info */
  796. afl=workdir||'\SREFLOGS.INI'
  797. foo=sref_fileread(afl,logsl,,'E')
  798. if foo<0 then do 
  799.    if verbose >2 then call pmprintf_sref(' SRE-Filter Post-Filter Thread: ' foo ' problem in sreflogs.ini file: 'afl)
  800.    return 1
  801. end
  802. if logsl.0=0 then return 1       /* use the defaults */
  803.  
  804.  
  805. stuff.!stamp=sysfiletree(afl,'FOO','f')
  806. STUFF.!STAMP=FOO.1
  807.  
  808.  
  809. do mm=1 to logsl.0
  810.    aline=strip(upper(logsl.mm))
  811.    if aline="" | abbrev(aline,';')=1 then iterate
  812.    parse upper var aline avar '=' aval
  813.    aval=strip(translate(aval,' ','"'||"'"))
  814.    avar0=strip(avar)
  815.    avar=translate(avar0,' ','.')
  816.    avar1=strip(word(avar,1))
  817.    if words(avar)=1 then do      /* check the 1 word opts */
  818.       if wordpos(avar1,varlist)=0 then iterate  /* not a valid variable */
  819.       if wordpos(avar1,'COMMONLOG BROWSERLOG REFERERLOG COMBINEDLOG')>0 then do /* check validity */
  820.           aval=chk_file(workdir,aval)
  821.       end
  822.  
  823.       exx='!'||avar1
  824.       stuff.exx=aval
  825.  
  826.       iterate
  827.    end
  828. /* else, one of the stem boys */
  829.  
  830.   if wordpos(avar1,stemlist)=0 then iterate  /* not valid stem var */
  831.   select
  832.        when avar1="NOURL" then do
  833.           inq=stuff.!nourl.0+1
  834.           if pos('?',aval)>0 then do
  835.                parse var aval a1 '?' a2
  836.                a1=strip(translate(a1,'/','\'),'l','/')
  837.                aval=a1||'?'||a2
  838.           end
  839.           else do
  840.              aval=strip(translate(aval,'/','\'),'l','/')
  841.           end
  842.           stuff.!nourl.inq=aval
  843.           stuff.!nourl.0=inq
  844.         end
  845.        when avar1="SCHED" then do
  846.           if aval<>0 then do
  847.              inq=stuff.!sched.0+1
  848.              stuff.!sched.inq=aval
  849.              stuff.!sched.0=inq
  850.           end
  851.         end
  852.  
  853.         otherwise  do      /* check for allowables */
  854.             useme=chk_file(workdir,aval)
  855.             if useme=0 then iterate
  856.             exx=avar1||'.!'||word(avar,2)
  857.             if words(avar)>2 then exx=exx||'.!'||word(avar,3)
  858.              exx2='!'||exx
  859.             stuff.exx2=useme
  860.             stuff.!list=stuff.!list||' '||exx
  861.         end             /*otherwise */
  862.   end                /* select */
  863.  
  864. end          /* logsl */
  865.  
  866. if verbose >2 then call pmprintf_sref(' SRE-Filter Post-Filter Thread: Log file list:loglist 'stuff.!list)
  867. return 1
  868.  
  869. /************/
  870. /* check for valid file name, and return it. Return 0 if no good */
  871. chk_file:procedure
  872. parse arg workdir, aval
  873.  
  874.   fn1=translate(strip(upper(aval)),'\','/')  /* the filename */
  875.   if fn1=0 then return 0
  876.  
  877.   fn1=strip(translate(fn1,' ',"'"||'"'))
  878.   if abbrev(fn1,'\')=1 | pos(':',fn1)>0 then
  879.        fuse=fn1
  880.    else
  881.        fuse=workdir||'\'||fn1
  882.    foo=strip(filespec('d',fuse)||filespec('p',fuse),'t','\')
  883.    if right(foo,1)=':' then foo=foo||'\'
  884.  
  885.    if dosisdir(foo)=0 then return 0  /* no such dir--error, so ignore */
  886.  
  887.    return fuse
  888.  
  889.  
  890.  
  891. /***************/
  892. /* write to the log files */
  893. write_clog:procedure expose clog.
  894. parse arg ttime,ltime,lbig
  895.  
  896. if clog.0=0 then return 0
  897.  
  898. /* are they all to the same file? */
  899. bname=clog.1.!file
  900. idid=1
  901. do mm=2 to clog.0
  902.       if clog.mm.!file<>bname then leave
  903.       idid=mm
  904. end
  905. if idid=clog.0  then do  /* all same name, dump the bunch */
  906.  
  907.    if bname=0 then return 0 /* all suppressed */
  908.     do nn=1 to clog.0
  909.        tt.nn=clog.nn
  910.     end
  911.     tt.0=clog.0
  912.     foo=filewrite(bname,tt,'A')
  913.     cfoo=jeepers(bname,lbig)
  914. end
  915. else do         /* several files (multi host system */
  916.   tt.0=1
  917.   do nn=1 to clog.0
  918.     if clog.nn.!file=0 then iterate
  919.     tt.1=clog.nn
  920.     foo=filewrite(clog.nn.!file,tt,'A')
  921.     foo=jeepers(clog.nn.!file,lbig)
  922.  end
  923. end
  924.  
  925. return 1
  926.  
  927. /********/
  928. /* is log file too big (check every 4th time? */
  929. jeepers:procedure
  930. parse arg bname0,toob
  931.  
  932. if toob=0 then return 1
  933. foo1=random(1,5)
  934. if foo1<5 then return 0   /* every 5th write */
  935.  
  936. foo=sysfiletree(bname0,'boo','F')
  937.  
  938. if boo.0>0 then do
  939.   ih=strip(word(boo.1,3))
  940.   if ih>(1000*toob) then do
  941.       call pmprintf_sref(' ')
  942.       call pmprintf_sref(' ******             WARNING                  ****** ')
  943.       call pmprintf_sref(' Your log file ('bname0') is becoming large ('ih)
  944.       call pmprintf_sref(' ******             WARNING                  ****** ')
  945.       call pmprintf_sref(' ')
  946.  
  947.   end
  948. end
  949. return 0
  950.  
  951.  
  952.  
  953.  
  954.  
  955. /***************/
  956. /* this is sort of a stupid algorithim, but it's probably adequate
  957. (given rexx's problems with passing stem variables */
  958.  
  959. /* write to the common log files */
  960. write_blog:procedure expose blog.
  961.  
  962. if blog.0=0 then return 0
  963.  
  964. /* are they all to the same file? */
  965. bname=blog.1.!file
  966. idid=1
  967. do mm=2 to blog.0
  968.       if blog.mm.!file<>bname then leave
  969.       idid=mm
  970. end
  971. if idid=blog.0  then do  /* all same name, dump the bunch */
  972.    if bname=0 then return 0 /* all suppressed */
  973.     do nn=1 to blog.0
  974.        tt.nn=blog.nn
  975.     end
  976.     tt.0=blog.0
  977.     foo=filewrite(bname,tt,'A')
  978. end
  979. else do         /* several files (multi host system */
  980.   tt.0=1
  981.   do nn=1 to blog.0
  982.     if blog.nn.!file=0 then iterate
  983.     tt.1=blog.nn
  984.     foo=filewrite(blog.nn.!file,tt,'A')
  985.  end
  986. end
  987. return 1
  988.  
  989.  
  990. /***************/
  991. /* write to the refeerer log files */
  992. write_rlog:procedure expose rlog.
  993.  
  994. if rlog.0=0 then return 0
  995.  
  996. /* are they all to the same file? */
  997. bname=rlog.1.!file
  998. idid=1
  999. do mm=2 to rlog.0
  1000.       if rlog.mm.!file<>bname then leave
  1001.       idid=mm
  1002. end
  1003. if idid=rlog.0  then do  /* all same name, dump the bunch */
  1004.    if bname=0 then return 0 /* all suppressed */
  1005.     do nn=1 to rlog.0
  1006.        tt.nn=rlog.nn
  1007.     end
  1008.     tt.0=rlog.0
  1009.     foo=filewrite(bname,tt,'A')
  1010. end
  1011. else do         /* several files (multi host system */
  1012.   tt.0=1
  1013.   do nn=1 to rlog.0
  1014.     if rlog.nn.!file=0 then iterate
  1015.     tt.1=rlog.nn
  1016.     foo=filewrite(rlog.nn.!file,tt,'A')
  1017.  end
  1018. end
  1019. return 1
  1020.  
  1021.  
  1022. /***************/
  1023. /* write to the common log files */
  1024. write_alllog:procedure expose alllog.
  1025.  
  1026. if alllog.0=0 then return 0
  1027.  
  1028. /* are they all to the same file? */
  1029. bname=alllog.1.!file
  1030. idid=1
  1031. do mm=2 to alllog.0
  1032.       if alllog.mm.!file<>bname then leave
  1033.       idid=mm
  1034. end
  1035. if idid=alllog.0  then do  /* all same name, dump the bunch */
  1036.    if bname=0 then return 0 /* all suppressed */
  1037.     do nn=1 to alllog.0
  1038.        tt.nn=alllog.nn
  1039.     end
  1040.     tt.0=alllog.0
  1041.     foo=filewrite(bname,tt,'A')
  1042. end
  1043. else do         /* several files (multi host system */
  1044.   tt.0=1
  1045.   do nn=1 to alllog.0
  1046.     if alllog.nn.!file=0 then iterate
  1047.     tt.1=alllog.nn
  1048.     foo=filewrite(alllog.nn.!file,tt,'A')
  1049.  end
  1050. end
  1051. return 1
  1052.  
  1053.  
  1054.  
  1055. /************/
  1056. /* which log file to use */
  1057. which_logs:procedure expose stuff.
  1058. parse arg sport,hname,dalog
  1059. if hname<>' ' then do
  1060.   alist=dalog||'.!'||hname||'.!'||sport
  1061.   alist=alist||' '||dalog||'.!'||hname||' '||dalog
  1062. end
  1063. else do
  1064.     alist=dalog||'.!'||sport||' '||dalog
  1065. end
  1066. alist=upper(alist)
  1067. do li=1 to words(alist)
  1068.    a1=strip(word(alist,li))
  1069.    if wordpos(a1,stuff.!list)>0 then do
  1070.        axe='!'||a1
  1071.        return stuff.axe
  1072.     end
  1073. end
  1074. return 0
  1075.  
  1076.  
  1077. /*************/
  1078. /* The scheduler */
  1079.  
  1080. do_scheduler:procedure expose stuff. last_hour_checked verbose
  1081.  
  1082. if verbose>3 & stuff.!sched.0>0 then call pmprintf_sref(' Checking ' stuff.!sched.0' SCHED. entries')
  1083.  
  1084. if stuff.!sched.0=0  | datatype(stuff.!sched.0)<>'NUM'then return 0   /* no scheduled programs to run */
  1085.  
  1086. atime=time('n')
  1087. parse var atime ahr ':' amin ':' asec
  1088. if ahr=last_hour_checked then return 0
  1089. adate=date('n')
  1090. parse var adate mday .
  1091. aweekday=upper(date('w'))
  1092.  
  1093. /* else, check scheduled programs */
  1094. do ii=1 to stuff.!sched.0
  1095.   parse upper var stuff.!sched.ii  afreq aprog stuff ; aprog=strip(aprog); afreq=strip(afreq)
  1096.   doit=0
  1097.   select
  1098.      when abbrev(afreq,'HOUR')=1 then   doit=1
  1099.      when abbrev(afreq,'DA')=1 & ahr=0 then doit=1
  1100.      when abbrev(afreq,'WE')=1 & aweekday="SUNDAY" then doit=1
  1101.      when abbrev(afreq,'MO')=1 & mday=1 then doit=1
  1102.      otherwise doit=0
  1103.    end
  1104.    signal off error  ; signal off syntax
  1105.    signal on error name hoy1
  1106.    signal on syntax name  hoy1
  1107.    if doit =1 then do
  1108.         astat=rexxrun('f',aprog,,stuff)
  1109.         if verbose>1 & astat<>0 then call pmprintf_sref(' REXXLIB REXXRUN error code = ' astat ' on scheduled event: 'aprog)
  1110.    end
  1111. end
  1112.  
  1113. last_hour_checked=ahr
  1114.  
  1115. signal off error ; signal off syntax
  1116. return 0
  1117.  
  1118. hoy1:
  1119. call pmprintf_sref(' Error: could not execute scheduled program: 'aprog)
  1120. signal off error ; signal off syntax
  1121. return 0
  1122.  
  1123.  
  1124. /******************************/
  1125. /* Add entry to the hit cache*/        
  1126.  
  1127. add_hit_cache:procedure expose myqueue basesem mysem mytid
  1128. parse arg  thetype, theurl0, who , enmadd,stuff
  1129. theurl0=upper(theurl0) ; thetype=upper(thetype)
  1130.  
  1131. nogi=digits()
  1132.  
  1133. lenc=value(enmadd||'HIT_CACHE_LEN',,'OS2ENVIRONMENT')
  1134.  
  1135. if lenc=0 then return ' '               /* suppressed */
  1136. transaction=mytid
  1137.  
  1138. numeric digits 11
  1139. ttc=value(enmadd||'HIT_CACHE_DURATION',,'OS2ENVIRONMENT')
  1140. ttc=ttc/(60*24)
  1141. d1=date('b')
  1142. t1=time('m')/(24*60)
  1143. nowtime=d1+t1
  1144. endtime=nowtime+ttc
  1145. theurl0=translate(theurl0,'/','\')
  1146. moo=lenc||' '||thetype||' '||theurl0||' '||who||' '||endtime||' '||stuff
  1147.  
  1148. if lenc='FILE' then do          /* add to cache file */
  1149.   itis=file_addhitc(moo,nowtime)
  1150.   numeric digits nogi
  1151.   return 0
  1152. end
  1153.  
  1154. /* or use VARSTORE thread  */
  1155. goober=enmadd||'VARSTORE'
  1156. a=rxqueue('s',goober)
  1157.     queue  transaction ' ' host_nickname ',' myqueue ',' mysem ',' 'PUT_HIT, '||moo
  1158. dothread=basesem||'VARSTORE'
  1159. a=eventsem_post(dothread)  /* no return expected */
  1160. return 0
  1161.  
  1162.  
  1163. /* --------------- */
  1164. /* add to the  .stem  file (slower, but perhaps better for huge numbers of hits */
  1165. file_addhitc:procedure expose enmadd 
  1166. parse arg  moo,nowtime
  1167.  
  1168. arf=extract('serverport')
  1169.  
  1170. adir=strip(value(enmadd||'TEMPDATA_DIR',,'os2environment'),'t','\')||'\'
  1171.  
  1172. cfile=adir||'_HITCACH.'||arf
  1173. if stream(cfile,'c','query exists')=' ' then do
  1174.    call pmprintf_sref(" Creating hit-cache file " cfile)
  1175.    eek.1=";The sre-filter hit cache file-- do NOT edit ! "
  1176.    foo=filewrite(cfile,'eek','R',1,1)
  1177.    if foo=0 then do
  1178.         call pmprintf_sref( " Error creating hit-cache file: " cfile)
  1179.         return
  1180.    end
  1181. end
  1182.  
  1183. /* wait for it to be unlocked */
  1184. isnow=time('r')
  1185. do until twait>30
  1186.   twait=time('e')
  1187.   aa=sref_fileread(cfile,'yy',,'E')
  1188.   if aa>=0 then leave
  1189.   ddt=syssleep(0.2)
  1190. end
  1191. if aa<0 then do
  1192.    call pmprintf_sref(" Hit cache file could not be opened for augmentation: " cfile)
  1193.    return ' '
  1194. end
  1195.  
  1196. /* now lock it! We'll clean it up, and add current hit to beginning */
  1197. aa=sref_open_read(cfile,10,'write')
  1198. if aa<0 then do
  1199.    call pmprintf_sref(" Hit cache file could not be opened for augmentation: " cfile)
  1200.    return ' '
  1201. end
  1202.  
  1203.  
  1204. newl.1=moo
  1205. i1=1
  1206. /* remove expired entries */
  1207. do iu=1 to yy.0
  1208.    aline=yy.iu
  1209.    if aline=' ' then iterate
  1210.    if abbrev(strip(aline),';')=1 then do
  1211.        i1=i1+1
  1212.        newl.i1=aline
  1213.        iterate
  1214.     end
  1215.     parse var aline atype aurl aip  aendtime .
  1216.     aendtime=strip(aendtime)
  1217.     if aendtime >= nowtime then do
  1218.         i1=i1+1
  1219.         newl.i1=aline
  1220.     end
  1221.     else do
  1222.     end
  1223.     if i1>10000 then leave   /* prevent too big */
  1224. end
  1225. newl.0=i1
  1226. aa=stream(cfile,'c','close')
  1227. foo=filewrite(cfile,'newl','R',i1,1)
  1228. if foo=0 | foo<=0 then
  1229.   call pmprintf_sref( " Could not augment&update hit-cache file ")
  1230. return ' '              
  1231.  
  1232.  
  1233. /*****************************/
  1234. /* see if url is in the  "hit cache"  */
  1235. look_hit_cache:procedure expose basesem mysem myqueue mytid
  1236. parse upper arg thetype, theurl, who , enmadd
  1237.  
  1238. theurl=translate(theurl,'/','\')
  1239.  
  1240. lenc=value(enmadd||'HIT_CACHE_LEN',,'OS2ENVIRONMENT')
  1241. if lenc=0 then return ' '               /* suppresed */
  1242. transaction=mytid
  1243. nogi=digits()
  1244.  
  1245. numeric digits 12
  1246. d1=date('b')
  1247. t1=time('m')/(24*60)
  1248. nowtime=d1+t1
  1249.  
  1250. if lenc='FILE' then do
  1251.   itis=file_lenhitc(thetype,theurl,who,enmadd,nowtime)
  1252.    numeric digits nogi
  1253.   return itis
  1254. end
  1255.  
  1256.  
  1257. /* here to read from VARSTORE thread */
  1258. /* or use VARSTORE thread  */
  1259. goober=enmadd||'VARSTORE'
  1260. moo=thetype||' '||who||' '||theurl
  1261. a=eventsem_reset(mysem)
  1262. a=rxqueue('s',goober)
  1263.     queue  transaction ' ' host_nickname ',' myqueue ',' mysem ',' 'GET_HIT, '||moo
  1264. dothread=basesem||'VARSTORE'
  1265. a=eventsem_post(dothread)  
  1266.  
  1267. a=eventsem_wait(mysem) /* wait for answer */
  1268.  
  1269. if a<>0 then do
  1270.    call pmprintf_sref(' A Fatal Semaphore failure in POSTF-Look_hit_cache: 'a)
  1271.    return ' '
  1272. end
  1273. a=rxqueue('s',myqueue)
  1274.  
  1275. parse pull aline
  1276.  
  1277. PARSE VAR ALINE idnum ',' aline
  1278.  
  1279. idnum=strip(translate(idnum,' ','000d0a'x));TRANSACTION=STRIP(TRANSACTION)
  1280. if idnum<>transaction then  do /*wierd error: got someone else's message, give up */
  1281.       say ' Read odd id from VARSTORE queue :' transaction ',' idnum
  1282.       return ' '
  1283. end
  1284. return strip(aline)
  1285.  
  1286.  
  1287. /* --------------- */
  1288. /* read from cachelist from an .idx file,, slower but perhaps better for huge number of hits */
  1289.  
  1290. file_lenhitc:procedure 
  1291. parse arg thetype,theurl,who,enmadd,nowtime
  1292.  
  1293. arf=extract('serverport')
  1294. adir=strip(value(enmadd||'TEMPDATA_DIR',,'os2environment'),'t','\')||'\'
  1295. theurl=strip(translate(theurl,'/','\'))
  1296.  
  1297. cfile=adir||'_HITCACH.'||arf
  1298. if stream(cfile,'c','query exists')=' ' then do
  1299.    say "  No hit cache file " cfile
  1300.    return ' '
  1301. end
  1302.  
  1303. /* wait for it to be unlocked */
  1304. isnow=time('r')
  1305. do until twait>30
  1306.   twait=time('e')
  1307.   aa=sref_fileread(cfile,'yy')
  1308.   if aa>=0 then leave
  1309.   ddt=syssleep(0.2)
  1310. end
  1311. if aa<0 then do
  1312.    say " Hit cache file could not be opened: " cfile
  1313.    return ' '
  1314. end
  1315.  
  1316. /* see if a match exists */
  1317. do iu=1 to aa
  1318.    aline=yy.iu
  1319.    if aline=' ' then iterate
  1320.    if abbrev(strip(aline),';')=1 then iterate
  1321.     parse var aline atype aurl aip  aendtime stuff
  1322.     atype=strip(atype) ; aurl=strip(aurl) ; aip=strip(aip)
  1323.     aendtime=strip(aendtime)
  1324.    if theurl<>aurl | aip<>who | atype<>thetype then iterate
  1325.    if aendtime >= nowtime then do
  1326.         return stuff
  1327.    end
  1328. end
  1329. return ' '              /* no match */
  1330.  
  1331.  
  1332.  
  1333.  
  1334.