home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 35 Internet / 35-Internet.zip / srev13g.zip / srefprc.doc < prev    next >
Text File  |  1999-06-26  |  74KB  |  1,830 lines

  1. 27 June 1999
  2.  
  3.      SRE-http ver 1.3g Documentation: SRE-http's procedure library. 
  4.  
  5.  
  6. SRE-http version 1.3 uses uses OS/2 "macrospace" to store many of
  7. it's procedures.  In addition, as a multi-threaded program, it uses the
  8. environment, queues, and semaphores to transfer information between threads.
  9. This document discusses both these aspects of SRE-http.
  10.  
  11. In the first section, we discuss procedures that competent REXX programmers 
  12. may find useful when writing addons for SRE-http.
  13. These procedures are stored in a "dynamic macrospace library file" called 
  14. SREFPRC.RXL.  When SRE-http is first run (that is, when GoServe is 
  15. started, and the first request arrives), SRE-http will load this 
  16. library into macrospace.
  17.  
  18. The second section discusses SRE-http use of the environment, threads and
  19. semaphores for inter-thread communication. 
  20.  
  21. Note that several of these procedures may not be needed on your site.  If so,
  22. you can save a little bit of space by "removing them from macrospace".
  23. For details, see the discussion of the REMOVE_PROCS variable in INITFILT.DOC.
  24.  
  25. Please note that SRE-http uses REXXLIB for various purposes. 
  26. REXXLIB is found at 
  27.      http://www.quercus-sys.com/rexxlib.htm.
  28. Our licence with Quercus allows users of SRE-http to freely use REXXLIB 
  29. (you do not need to  register it) as part of SRE-http.  
  30. However, if you use REXXLIB for your own programs, you are supposed to 
  31. pay for it (the license is only for use with programs we distribute). 
  32. If you write "addons" for SRE-http that use REXXLIB, I'm not sure where 
  33. that falls; but to be safe, I assume that you are supposed to register  
  34. (it's only $25.00).
  35.  
  36.  
  37. -------         ----------          ---------          ------------
  38. -------          SECTION 1: Using SRE-http's macrospace library.
  39. -------         ----------          ---------          ------------
  40.  
  41. The following describes many of the procedures contained in the
  42. SRE-http macrospace library.
  43.  
  44. If you are a serious REXX programmer, you may want to look at the source
  45. code (contained in  various .SRF files) for further descriptions. Note
  46. that there are some procedures placed into macrospace by SRE-http that
  47. are not intended for general use; these are not described in this document.
  48.  
  49. Some preliminary notes:
  50.  
  51. 1) What is  macrospace?
  52.     Macrospace can be thought of as a system-wide dynamic link library.
  53.     That is, procedures stored in macrospace are available 
  54.     to all REXX programs, not just SRE-http.  Thus, if some other
  55.     program "clears" macrospace, SRE-http may fail -- and
  56.     vice versa!
  57.  
  58. 2) Where's the source code?
  59.      The source code for these procedures consists of a number of files with
  60.      the extension .SRF; all stored in the SRE-http "library" directory
  61.      (perhaps \GOSERVE\LIB).
  62.  
  63. 3) What do we need to work with macrospace procedures?
  64.      Nothing -- just call them the way you call any external OS/2
  65.      procedure. Note that SRE-http uses procedures in REXXLIB.DLL 
  66.      to "load" SREFPRC.RXL into macrospace.  For simple manipulations of
  67.      macrospace, you can use MSPACE.CMD (look for it in the library
  68.      directory).
  69.  
  70.  
  71. 4) A caution on using these procedures:
  72.  
  73.   There are four general cases where one might use these procedues:
  74.     1) In an SRE-http addon (or a pre-filter, or mid-filter, procedure)
  75.     2) In a CGI-BIN script
  76.     3) In a post-filter procedure
  77.     4) In a stand-alone program (that is NOT running in the same process as 
  78.        SRE-http)
  79.  
  80.   Several of these procedures use GoServe to provide information,
  81.   or use "request specific" information. These procedures will not
  82.   work if called from one of the "higher numbered" cases. 
  83.  
  84.   For example, several of these procedures use the GoServe EXTRACT function,
  85.   typically to determine the current serverport. Extract will NOT work in 
  86.   a CGI-BIN script, or in a stand alone program.  
  87.  
  88.   Where appropriate, the "cases" where the procedure can/cannot be used
  89.   are noted in the Restrictions: portion of the following descriptions.
  90.  
  91.  5) Another Caution
  92.     In some cases, inappropriate use of these procedures can
  93.     CRASH GOSERVE -- so do pay attention to the "restrictions"!
  94.  
  95.  6) On the use of "dynamic macrospace procedures".
  96.     As of version 1.2N, SRE-http  uses "dynamic macrospace".
  97.     Dynamic macrospace means that many of the procedures are not
  98.     loaded until they are needed; which helps save space, and
  99.     facilitates minor upgrades.
  100.  
  101.     There is one "gotcha" -- if you call one of 
  102.     these procedures from an external program (that's not in the GoServe
  103.     process), it is possible that you will get a "could not find
  104.     SRE_LIBDIR error".  If this occurs, you just need to 
  105.     SET SRE_LIBDIR=goserve_lib_directory (say, SET SRE_LIBDIR=D:\GOSERVE\LIB).
  106.  
  107.          Make sure you do this SET from the same OS/2 session you are runnning 
  108.          this external procedure from,or put it in your config.sys file.
  109.  
  110. -------         ----------          ---------          ------------
  111.             Description of general purpose macrospace procedures
  112. -------         ----------          ---------          ------------
  113.  
  114. Calling Syntax:
  115.  
  116. File/url-resolution related procedures:
  117.     status  =SREF_GOS(acmd,varname,dorange,hdrs)
  118.    open_time=SREF_OPEN_READ(afile ,seconds_to_try_for , howopen )
  119. afile_string=SREF_GRAB_FILE(afile,seconds_to_try_for)
  120. newfiles=SREF_CONJUREF(basedir,basenames,extlist,minfree,mintime)
  121.        newct=SREF_LOOKUP_COUNT(ctfile, needle, augment , substring , noadd)
  122.     filename=SREF_DO_VIRTUAL(defdir,aurl,envstring,docheck,trans,homedir,hnick)
  123.     mimetype=SREF_MEDIATYPE(filename,port)
  124.       newurl=SREF_FIX_URL(local_url,servername,serverport)
  125.  
  126.  
  127. String related procedures:
  128.    newstring=SREF_REPLACESTRG(haystack,needle,replacement, type , exactmatch)
  129.    newstring=SREF_WILDCARD(original, needle replacement,doexact)
  130.    matchinfo=SREF_WILD_MATCH(needle,haystack,old_matchinfo,suppress_noslash)
  131.       ablock=SREF_EXTRACT_BLOCK(haystack ,alabel ,delim1, delim2, delim3)
  132.       newval=SREF_INSERT_BLOCK(haystack,alabel,add_string,after,delim1,delim2)
  133.      astring=SREF_PACK64(packed_64_string)
  134. stg_packd_64=SREF_MKPACK64(astring)
  135.     md5_hash=SREF_MD5(astring,isfile)
  136.      astring=SREF_UNCHUNK(chunked_string,trailers)
  137.  stg_chunked=SREF_CHUNK(astring,trailers)
  138.      astring=SREF_UNGZIP(gziped_string)
  139.  stg_gzipped=SREF_GZIP(astring)
  140.    img_elems=SREF_DIGITS(astring,digname,ndigits,frame,nobr,options)
  141.        score=SREF_COMPWORD(needle,haystack)
  142.        rcode=SREF_DYNAMIC_PWD(respfile,appname,newlocation,who,tstamp,message)
  143.  
  144.  
  145. Variable/time/version lookup procedures:
  146.        value=SREF_VALUE(varname,newval,env,optinfo)
  147.        value=SREF_QUEUE(queuename,action,aval,port)
  148.         aval=SREF_CGIVARS(cgi_bin_variable)
  149.      timestr=sref_gmt(offset,basetime,outtype,gmtoffset)
  150.  
  151.      juldate=SREF_JULDATE(mode, time_string)
  152.  filter_name=SREF_VERSION(port)
  153.     errmess=SREF_ERROR(amessage,do_pmprintf)
  154.  
  155. Internet info & retrieval procedures
  156.      aresult=SREF_HOST(ipaddress)
  157.         aval=SREF_BROWSER_INFO(field,browser,envstring)
  158.        stuff=SREF_GET_URL(url,maxchar,verbose,headers)
  159.        stuff=SREF_HOST_INFO(myaddr0,nhosts,envstring)
  160. cookie_value=SREF_GET_COOKIE(cookie_name,nth)
  161.          res=sref_dynamic_pwd(appname,newlocation,privset2,duration,respfile,clientaddr)
  162.  
  163.  
  164. Daemon related procedures
  165.        status=SREF_DMN_LAUNCH(daemon_name,file_name,optional_arg)
  166.        status=SREF_DMN_EXIST(daemon_name)
  167.         value=SREF_DMN_ASK(daemon_name,an_argument,max_wait)
  168.  request_info=SREF_DMN_WAIT(daemon_name,max_wait)
  169.   an_argument=SREF_DMN_VALUE(request_info)
  170.        status=SREF_DMN_REPLY(request_info,reply_stuff)
  171.        status=SREF_DMN_KILL(daemon_name)
  172.  
  173. Miscellaneous
  174.      status=SREF_MAILIT(address_list,message,smtp_gateway,sender_address)
  175.        rcode=SREF_MULTI_SEND(message,mime_type,howsend,file_flag,verbose)
  176.          foo=SREF_EXPIRE_RESPONSE(aoffset,alength,atype,noauto)
  177.        CALL  PMPRINTF_SREF(astring,nofile,port)
  178.        results=SREF_FIND_INDEX(target,qname,varname,nth,loc_only,timeout)
  179.  
  180.  
  181. Short descriptions:
  182.  
  183. SREF_GOS: Send information to client in a http/1.1 compatible way.
  184. SREF_OPEN_READ: Open a file, with waiting if the file is currently locked
  185. SREF_GRAB_FILE: Open file (with waiting), and then read it in to a string variable
  186. SREF_CONJUREF: Cleanup temporary directory, and then derive new filenames
  187. SREF_SEARCH_FIXED: Binary (or wildcard) search of fixed-length record file
  188. SREF_LOOKUP_COUNT: Lookup and increment an SRE counter file
  189. SREF_DO_VIRTUAL: Map a URL to a virtual directory
  190. SREF_MEDIATYPE: Determine mime type of a file
  191. SREF_FIX_URL: Create fully qualified URL from local URL
  192.  
  193. SREF_REPLACESTRG: Replace occurences of needle, in haystack, with replacement
  194. SREF_WILDCARD: Deterimine if needle is a "wildcard" match of haystack
  195. SREF_EXTRACT_BLOCK:  Extract a delimited block of text from a string
  196. SREF_INSERT_BLOCK: Insert block of text between delimiters
  197. SREF_PACK64: Convert a "pack64" format string to original characters
  198. SREF_MKPACK64: Convert a string to it's "pack64" equivalent
  199. SREF_MD5: Make an MD5 "digest" of a string, or of a file
  200. SREF_UNCHUNK: Unchunk a "chunked" string
  201. SREF_CHUNK: Create a chunked string
  202. SREF_UNGZIP: Unzip a "gzip" compressed string 
  203. SREF_GZIP: Create a "gzip" compressed string
  204. SREF_DIGITS: Returns a list of IMG elements that point to digit .GIFs
  205. SREF_COMPWORD: Matches a "needle" to a "haystack" -- return a 1-100 score.
  206.  
  207. SREF_VALUE: Value of a variable from an OS/2 or SRE-http "environment"
  208. SREF_QUEUE: Read,write, and manipulate an SRE-http "queue"
  209. SREF_CGIVARS: Get the value of one of the CGI-BIN environment variables
  210. SREF_GMT: Compute a new GMT time, given an offset in fractional days
  211. SREF_JULDATE: Return absolute fractional date (since 0/0/1)
  212. SREF_VERSION: Return version of SRE-http
  213. SREF_ERRROR: Read/record an error message
  214.  
  215. SREF_HOST: Return IP address given name (or vice versa)
  216. SREF_BROWSER_INFO: Get spec-info on a browser
  217. SREF_GET_URL: Go to a web server and GET a URL (the complete contents)
  218. SREF_HOST_INFO: Return the "host nickname", given a servername
  219. SREF_GET_COOKIE: Get value of a cookie
  220. SREF_DYNAMIC_PWD: Prompt the client for a "dynamic password"
  221.  
  222. SREF_DMN_LAUNCH: Launch a daemon
  223. SREF_DMN_EXIST: Check if daemon's queue and semaphore are open
  224. SREF_DMN_ASK: Query the daemon for some information, wait for reply
  225. SREF_DMN_WAIT: Daemon uses this to listen for queries
  226. SREF_DMN_VALUE: Used by daemon to parse queries
  227. SREF_DMN_REPLY: Used by daemon (to reply to SREF_DMN_ASK)
  228. SREF_DMN_KILL: Kill a daemon's queue and semaphore
  229.  
  230. SREF_MULTI_SEND: Send a sequence of documents 
  231. SREF_MAILIT: Send mail via an SMTP server
  232. SREF_EXPIRE_RESPONSE: Modify the automatically generated expiry response header
  233. PMPRINTF_SREF: A front-end (with error checking)for PMPRINTF
  234. SREF_FIND_INDEX: Find a match in an SRE-Data file (requires SRE-Data addon)
  235.  
  236.       ---------------------------------------------------------
  237.                      Longer Descriptions (alphabetically sorted)
  238.       =========================================================
  239.  
  240.  
  241. -------         ----------          ---------          ------------
  242. PMPRINTF_SREF:  A pre-process for the REXXLIB PMPRINTF routine.
  243.  
  244. PMPRINTF_SREF is used throughout SRE-http as a means of reporting run-time
  245. status information.  PMPRINTF_SREF typically calls the PMPRINTF procedure,
  246. which will then display results in a PMPRINTF window.  PMPRINTF_SREF will
  247. check for a few overflow conditions, thereby avoiding sys3175 errors.
  248.  
  249. In addition, PMPRINTF_SREF checks the SREF_PMPRINTF_LINE_LENGTH
  250. and SREF_PMPRINTF_LOG_FILE environment variables.  These variables, set
  251. in SREFMON.CMD, control the maximum line length to be displayed (longer lines will wrap),
  252. and whether or not to log results to an SRE-http audit file
  253.  
  254. Usage:
  255.   CALL  PMPRINTF_SREF(astring,nofile,port)
  256. where
  257.   astring : the string to write
  258.   nofile : optional. If 1, then suppress writing to the PMPRINTF_LOG_FILE.
  259.   port: optional, the port of the server
  260.  
  261.  
  262. Restrictions: If called from a non-addon, you MUST include the port.
  263.  
  264.  
  265.  
  266. -------         ----------          ---------          ------------
  267.  
  268. SREF_BROWSER_INFO
  269.  
  270. Return information about a browser. 
  271.  
  272. Usage: 
  273.   aval=sref_browser_info(field,browser,envstring)
  274. where 
  275.    field:  the field to get information on:
  276.    browser:  optional: a "user-agent" identifying string.
  277.          If this is not included, then the user-agent request header
  278.          is used.
  279.    envstring: only needed if called from non-addon (see restrictions)
  280.  
  281. Output: The result
  282.  
  283.  
  284. The following fields are supported, with possible values noted. 
  285. Note that if no information is available for an item. Or, a number
  286. < 0 is returned to signify an error:
  287.    -1 = BROWSERS.IDX file unreadabld
  288.    -2 = Can not find entry for this user-agent
  289.    -3 = No value for this field, for this user-agent
  290.    -4 = BROWSERS.IDX file not found
  291.  
  292.   user_agent = User-agent of browser
  293.   browser = Vendor of the Browser
  294.   cookies =Cookie capable? YES or NO.
  295.   security = Type of security. NO, SHTTP, or SSL.
  296.   tables = Understands tables (YES NO)
  297.   date = The date this table entry was entered or most recently 
  298.           modified. YY/MM/DD
  299.   redirectlimit = Maximum length of redirection string.
  300.                  Integer between 255 and 8000
  301.   maxlinklen = Maximum characters in url
  302.                  Integer between 255 and 8000
  303.  
  304.  
  305. Citation: This procedure uses browser.idx, which is based on information from:
  306. http://website-1.openmarket.com:80/browsertest/prob/bt-maker.cgi?DataFile
  307.  
  308. Hint: Since browsers are coming and going, you may want to check the
  309.       SRE-http home page for new versions of BROWSERS.IDX. Or,
  310.       you can generate a new version of BROWSERS.IDX with 
  311.       BROWSERS.CMD (run it from an OS/2 command prompt).
  312.  
  313.       BROWSERS.CMD can also be called as an SRE-http addon.  It
  314.       will read BROWSERS.IDX and display information about your
  315.       browser's capabilities.
  316.       
  317. Examples:
  318.      tableok=sref_browser_info('TABLES')
  319.      docook=sref_browser_info('COOKIES')
  320.      security1=sref_browser_info('security','IBM WebExplorer DLL /v1.03')
  321.  
  322.  
  323. Restrictions: if called from a non-addon, you must supply an "environment
  324. string". This will have the form  SREF_nn_, where nn is the current
  325. port (i.e.; nn=80).
  326.  
  327.  
  328.  
  329. -------         ----------          ---------          ------------
  330.  
  331. SREF_CGIVARS(Varname)
  332.  
  333. Usage: aval=sref_cgivars(cgi_bin_variable)
  334.  
  335. Returns: value of the CGI_BIN variable (if available)
  336.  
  337. Note that:SCRIPT_NAME, PATH_INFO, PATH_TRANSLATED, and REMOTE_IDENT,
  338. PATH_INFO, PATH_TRANSLATED, and QUERY_STRING are not available. When
  339. one of these variables is requested, a ' ' is returned
  340.  
  341. Note that this will NOT look in environment, but will determine the
  342. values each time.  In other words, this not designed for use
  343. in cgi-bin scripts (you should use x=value(varname,,'os2environment)
  344. instead); it is designed for use in INTERPRET includes and in
  345. directly called REXX server side programs).
  346.  
  347. Example:   aval=sref_cgivars('server_software')
  348.  
  349. Restrictions: should ONLY be called from an SRE-http addon. 
  350.  
  351. -------         ----------          ---------          ------------
  352. SREF_CHUNK: Chunk a string
  353.  
  354. Usage: chunked_string=sref_chunk(astring,final,trailers)
  355.  
  356. Create a "chunked" string; which is suitable for http/1.1 transfer.
  357.  
  358. FINAL  should be 1 if this is the last of a sequence of chunked strings
  359. (or if this is the "first of one").  
  360.  
  361.    *** Failure to include a "final" chunked sequence is an error! ***
  362.  
  363. The trailers argument is optional. When present (at it should only
  364. be included when final=1) the value of trailer (typically crlf'ed
  365. delimited set of trailers) is added to the end of the chunked
  366. message.
  367.  
  368.  
  369. Restrictions: none
  370.  
  371.  
  372. -------         ----------          ---------          ------------
  373. SREF_COMPWORD: Compare two words and return a score
  374.  
  375. Usage: 
  376.  
  377.     score=sref_compword(needle,haystack)
  378.  
  379. where:
  380.    needle : the word to compare 
  381.  haystack : the word to compare against
  382.  
  383. SREF_COMPWORD will compare the needle against the haystack and return a 
  384. score that indicates how closely they match.  A score of 100 means "perfect
  385. match", while a score of 0 means "no match". 
  386.  
  387. SREF_COMPWORD uses a simple pattern matching algorithim (based on 
  388. looking for many possible substrings of the needle in the haystack).
  389. The greater the number of substrings, and the closer they are
  390. in letter position, the better the match.
  391.  
  392. Note that the definition of which word is the needle and which is the 
  393. haystack is somewhat arbitrary. However, it can make a difference in
  394. the score!
  395.  
  396.  
  397. Examples: ascore=sref_compword("FORIM1","FORMULA")
  398.           ascore=sref_compword("FORIM1","THEMR1")
  399.           ascore=sref_compword("FORIM1","EXACT1")
  400.      would yield scores of 0.170, 0.034, and 0.016  (respectively)
  401.      In contrase:
  402.           ascore=sref_compword("FORMULA","FORIM1")
  403.           ascore=sref_compword("THEMR1","FORIM1")
  404.           ascore=sref_compword("EXACT1","FORIM1")
  405.      would yield scores of 0.124, 0.037, and 0.016  (respectively)
  406.  
  407.  
  408. Restrictions: none
  409.  
  410.  
  411. -------         ----------          ---------          ------------
  412.  
  413. SREF_CONJUREF : Create/delete temporary files
  414. Usage: newfiles=sref_conjuref(basedir,basenames,extlist,minfree,mintime)
  415.  
  416.         basedir: directory to clean up (if > 10 files,
  417.               remove all files > mintime hours old)
  418.         basenames: list of (up to 4-char) file-stems to be used
  419.                  (a random element will be added)
  420.         extlist: list of up to 10 extension to be added to this file-stems
  421.  
  422.      So, if base= ZDOG,ZMOM and EXTLIST is FOO,CAT,001 then this will create
  423.      ZDOGxxxx.FOO, ZMOMxxxx.CAT and ZMOMxxxx.001, where xxxx is some 4 digit
  424.     random # (guaranteed to cause unique file names to be selected) 
  425.     (note replication to generate as many names as longest list)
  426.  
  427.        minfree: Try to get this much space free by deleting files 
  428.                 from basedir (in kb)
  429.        mintime: But don't delete anything less than this hours old
  430.  
  431. Return:   If newfiles=0, then could not create (say, minfree was violated)
  432.           Else, comma delimited list of file names 
  433.                 that can be used as temporary files.
  434.  
  435. CAUTION: Be careful what you choose as your basedir (you could automatically
  436. delete important stuff if your basedir is not strictly a "temporary files"
  437. directory).
  438.  
  439. Restrictions: none
  440.  
  441. -------         ----------          ---------          ------------
  442.  
  443. SREF_DMN_LAUNCH, SREF_DMN_EXIST, SREF_DMN_ASK, SREF_DMN_WAIT,
  444. SREF_DMN_VALUE, SREF_DMN_REPLY, SREF_DMN_KILL: A set of procedures to
  445. use with daemons.
  446.  
  447. The several SREF_DMN_ procedures are used to launch, communicate with,
  448. and kill deamons.  Daemons are semi-permanent threads running
  449. under the GoServe process. Among other advantages, they offer a 
  450. convenient means of storing data for quick retrieval, provide 
  451. system monitoring capabilities, and allow one to perform 
  452. non-time sensitive actions efficiently.  Section II of this
  453. document discusses daemons in greater detail.
  454.  
  455. For a complete description of how to use these SREF_DMN_ procedures,
  456. please see DAEMONS.DOC.
  457.  
  458.  
  459. -------         ----------          ---------          ------------
  460. SREF_DIGITS
  461.  
  462. Usage: 
  463.  
  464.     txtstring=SREF_DIGITS(amess,digit_name,nd,useframe,nobr,opts,imgdir)
  465.  
  466. where:
  467.   txtstring :  a text string containing a sequence of <IMG elements, that
  468.                point to the appropriate graphical digits
  469.  
  470.       amess : a string of characters, typically-but-not-always digits,
  471.                   to display 
  472.  digit_name : the name of the subdirectory containing the digit, 
  473.               and/or character-image, .GIF files.  
  474.               This subdirectory must be relative to the
  475.               imgdir directory (as specified below).
  476.  
  477.               If digit_name is not specified, WHITBLAK is used.  
  478.  
  479. The remaining arguments are optional.
  480.  
  481.          nd : the number of characters to display. 
  482.               If nd is longer then the number of characters in amess...
  483.                 a) if amess only contains digits, then 0's will be
  484.                    used as a padding character 
  485.                 b) if amess contains non digit charcters, the "default"
  486.                    character (specified in the "match file") is used
  487.                    as a padding character
  488.    useframe : if 1, then include a "left and right" frame
  489.               around the characters (see the "frame" option above for details)
  490.        nobr : if 0, then do NOT put a <NOBR> and </NOBR> around the
  491.               IMG elements (that comprise the message)
  492.      opts   : a string to be included in the IMG elements. 
  493.               For example:
  494.                 ' ALIGN=CENTER VALIGN=TOP'
  495.                 ' VALIGN=MIDDLE WIDTH=12 HEIGHT=12 '
  496.               In other words, opts can be a list of any IMG element
  497.               modifers.
  498.               Note that this "opts" list is included in all IMG elements,
  499.               including "frame" elements.
  500.      imgsel : the "counter_image_dir" selector.
  501.               If not specified, a value of "DIGITS" is assumed.
  502.      imgdir : Absolute path pointed to by the imgsel. If not specified, 
  503.               the DIGITS subdirectory of the GoServe data directory
  504.               is used.
  505.         
  506.   
  507. For details on how to use SREF_DIGITS, see COUNTER.DOC
  508.  
  509.  
  510. -------         ----------          ---------          ------------
  511.  
  512. SREF_DO_VIRTUAL: Convert a url into an fully qualified file name.
  513.  
  514. Usage: 
  515.      filename=sref_do_virtual(defdir,aurl,envstring,docheck,trans,homedir,hnick)
  516.  
  517. where:
  518.         defdir: Default drive&directory to use. If not supplied,
  519.                 the default data directory is used (see restrictions below)
  520.         aurl :  A url (of the form /A1/A1/FILE.EXT) to
  521.                 convert to an fully qualified file name.
  522.     envstring: An "environment variable prefix".  If
  523.                 not supplied, one will be built (based on
  524.                 the current http port, as supplied by GoServe) --
  525.                 but see restrictions below.
  526.        docheck: If 1, then check to see if the file exists.
  527.                 If it doesn't, return 0.
  528.         trans: A unique transaction number.  If not supplied,
  529.                the current transaction number is used (as
  530.                supplied by GoServe).
  531.        homedir: The "home directory" replacement string for 
  532.                the ~ character (may be host specific)
  533.                If no homedir argument, the home_dir environment
  534.                variable is used.
  535.        hnick  : Host nickname -- used to identify the "host".  It is
  536.                 used to identify "host sensitive" virtual directory 
  537.                 entries.
  538.  
  539.      If docheck=0, or if docheck=1 and a file with the constructed name 
  540.      exists. returns a  fully pathed file name based on the url and 
  541.      either defdir or a match between aurl and the virtual file list.
  542.      If docheck=1 and this match does not exist, returns a 0.
  543.  
  544. Examples:
  545.     * newfile=sref_do_virtual(,'/herfiles/wedding1.jpg)
  546.       If "herfiles" does not match a virtual directory, then
  547.       newfile=ddir/herfiles/wedding1.jpg
  548.  
  549.    *  giants=sref_do_virtual('d:\teams','/stars/willymays.html')
  550.       If no virtual directory match to "stars", then 
  551.       giants=d:\teams\stars\willymays.html
  552.  
  553.      filename=sref_do_virtual(defdir,aurl,envstring,docheck,trans,homedir,hnick)
  554.  
  555.    *  mymad=sref_do_virtual('d:\journals','fun/mad.doc',,1,,,'SITE2A')
  556.       First useentries for the SITE2A  host, and then "generic entries".
  557.       If mad.doc does not exist, return a 0.
  558.  
  559.    * realdir=sref_do_virtual(,'WWW2/')
  560.      The virtual directory corresponding to "selectors" under WWW2/
  561.    
  562.  
  563. Caution: the virtual file list may contain http://xxx.yyy.zzz/abc entries.  
  564.           These are understood by the main SRE-http routine, but NOT by 
  565.           this procedure.
  566.           If such a match occurs, SREF_DO_VIRTUAL will return a 0.
  567.  
  568. Caution2: as illustrated in the fourth example,
  569.           if you wish to match a directory to a virtual directory
  570.           (without matching any specific filename), you MUST end
  571.           the "aurl" argument with a /.
  572.  
  573. Restrictions: if not called from an addon, you MUST supply ENVSTRING
  574. (i.e.; if the server is running on port 80, then ENVSTRING='SREF_80_').
  575. If called from a post-filter procedure or an stand alone program, you
  576. must supply (in addition to envstring) the defdir, the trans (you can use
  577. an arbitrary number), and the homedir. You do not need to supply
  578. the host_nickname (if not supplied, host-specific entries will not
  579. be used).
  580.  
  581.  
  582.  
  583. ------         ----------          ---------          ------------
  584. SREF_DYNAMIC_PWD
  585.  
  586. Usage:
  587.   res=sref_dynamic_pwd(appname,newlocation,privset2,duration,respfile,clientaddr)
  588. where
  589.   appname: recommended. the "application" calling this. Used to identify 
  590.            a "shared secret". If not specified, a value DYNPWD is used.
  591.            Note that APPNAME is also used in responses.
  592.   newlocation: recommended. The uri to invoke when client hits the submit
  593.                button. Default value is "/"
  594.   privset2 : REQUIRED. the space delimited list of "secret" privileges. 
  595.              It should contain an entry of the form APPNAME:shared_secret
  596.   duration: optional. duration of a timestamp, in days (and fractions of day)
  597.              (default value is 1 day)
  598.   respfile: optional.the "response file" containing the md5 procedure. If not
  599.             specified, DYNPWD.RSP, in the datadir(), is used.
  600.   clientaddr: client's numeric ip address. Optional, if missing, will get if
  601.             with a GOSERVE extract 
  602. and
  603.   resp='' 
  604.          if a valid password is found
  605. or 
  606.   resp='200 '||length(response) 
  607.         if no valid password is found, 
  608.         sref_dynamic_pwd asks the client to supply one -- this is the
  609.         response code for this "response"
  610.  
  611.  
  612. To enable dynamic passwords, you must write an "sre-http" addon that
  613. calls the SREF_DYNAMIC_PWD procedure (SREF_DYNAMIC_PWD is loaded 
  614. into macrospace when needed).  
  615.  
  616. For further details, please see DYNPWD.DOC.
  617.  
  618.  
  619.  
  620. ------         ----------          ---------          ------------
  621. SREF_ERROR: Read/record a request specific  error message.
  622. Usage:
  623.    errmess=sref_error(amessage,do_pmprintf)
  624. where:
  625.    amessage= Optional. If supplied, amessage will be recorded.
  626.   do_pmprintf= Optional. If greater then or equal to 0, amessage will also 
  627.                 be written to the pmprintf window (using pmprintf_sref)
  628.  
  629. Return: The current error message for this request (possibly an empty string)
  630.  
  631. Each request has a "error-message" variable associated with it, which
  632. is initialized to an empty string when the request arrives.  SREF_ERROR
  633. can read from, or write to, this variable.  When no arguments are given
  634. (i.e.; errmess=SREF_ERROR()), then the current value is returned; if there
  635. have been no errors or warnings (that is, no calls to SREF_ERROR by SRE-http)
  636. a null string is returned.
  637.  
  638. When amessage is specified, the current value of the error-message variable
  639. is returned, and it is then set to be amessage.  In addition, amessage will
  640. be written to the SRE-http error log (i.e.; D:\GOSERVE\DATA\ERROR.LOG).
  641.  
  642. Lastly, if do_pmprintf is greater then or equal to 0, amessage will be written
  643. to the pmprintf window (pmprintf_sref is used).
  644.  
  645. Restriction: can only be called from an addon.
  646.  
  647. ------         ----------          ---------          ------------
  648.  
  649. SREF_EXPIRE_RESPONSE: Build a response header that does not have an
  650. immediate expiration.
  651.  
  652.  ***   USE OF SREF_EXPIRE_RESPONSE IS NO LONGER RECOMMENDED --   ***
  653.  ***                    USE SREF_GOS instead!                    ***
  654.  
  655. Usage: foo=sref_expire_response(aoffset,alength,atype,noauto,pragvalue)
  656.    aoffset is fraction of day to add to current date/time. This will
  657.      be converted to gmt (assuming gmt variables have been set, as described
  658.      in goserve.doc). If aoffset<0, then an "expires" header will Not
  659.      be written.  Default is 0.04
  660.  
  661.    alength is the size of the document being sent. Default is 0
  662.    atype is the mime type. Default is text/html
  663.    noauto= Y or N: If Y, or if missing, then suppress auto - headers.
  664.    pragvalue=value to use in a Pragma: header.
  665.              If 0, suppress Pragma header.              
  666.              If not specified, a Pragma: no-cache header is added.
  667.            
  668.  
  669. Restriction: can ONLY be called from an addon.
  670.  
  671.  
  672. ------         ----------          ---------          ------------
  673.  
  674.  
  675. SREF_EXTRACT_BLOCK : Extract a "labeled block" from a string.
  676. Usage: ablock=sref_extract_block(haystack , alabel , delim1  , delim2  , delim3)
  677.  
  678.  Extract a block from haystack, defined by a Labeled block,
  679.   where the label has the form delim1 label delim2 multi-line_string delim3  xxx
  680.  Default values of delim1={,  2=}  3={
  681.  Note that labels must have NO embedded spaces.
  682.  
  683.  
  684. Example: if haystack= <!-- SELECT --> this is text to select <!-- END_SELECT -->
  685. and label=SELECT, delim1='<!--', delim2='-->, and delim3='<!--', 
  686. then ablock would be "this is text to select".  Note that the END_SELECT
  687. is ignored.  
  688.  
  689.  
  690. Restrictions: none 
  691.  
  692. -------         ----------          ---------          ------------
  693. SREF_FIND_INDEX  : Query an SRE-data daemon for a match
  694.  
  695. Usage
  696.    results=SREF_FIND_INDEX(target,qname,varname,nth,loc_only,timeout)
  697. where:
  698.    results = a 2 part response, seperated by a comma. The first part
  699.             is the "record # of the matching record", or a 0 if no
  700.             match, or less then 0 if an error. The second part is 
  701.             what was matched (i.e.; the record containing the targeted 
  702.             identifier); or a blank if no match (or error) occured.
  703.   target = the string to search for>
  704.   qname  = the "name" used when sredata was invoked 
  705.   varname = (optional) Search by varname, not by "identifier"
  706.             Or, invoke a special command
  707.    nth    = (optional) return nth match
  708.   loc_only = (optional) Return location, do not return a "value"
  709.   timeout=   (optional)  max seconds to wait on daemon
  710.  
  711. SRE_FIND_INDEX is designed to work with the SRE-Data addon.
  712.  
  713.  
  714. -------         ----------          ---------          ------------
  715.  
  716. SREF_FIX_URL  : Creates a proper HTTP URL.
  717.  
  718. Usage:  
  719.    newurl=sref_fix_url(local_url,servername,serverport)
  720.  
  721. Servername and serverport are optional; if not supplied the 
  722. current (canonical) servername and port are used (but see restrictions
  723. for a proviso). Local_url can either be a (local) selector, or it can be 
  724. a fully qualified URL.
  725.  
  726. The newurl will contain the http://, servername and port, and selector;
  727. where the selector may be a substring of the local_url.
  728.  
  729. Note that SREF_FIX_URL will NOT add servername and serverport information
  730. if the local_url already contains it
  731.  
  732. Also not that this may not work if the local_url contains periods
  733. in subdirectory names.
  734.  
  735.  
  736. Examples (assuming the server's address is foo.bar.net on port 80):
  737.  
  738.  *   newurl=sref_fix_url('dir1/prices.htm')
  739.         will return http://foo.bar.net/dir1/prices.htm
  740.  
  741.  *   newurl=sref_fix_url('dir2/quality.shtml','joes.store.com')
  742.         will return http://joes.store.com/dir2/quality.shtml
  743.  
  744. Restrictions: if called from a non-addon, you MUST provide the servername
  745. and serverport. If are using a multi-host server and want to redirect
  746. back to your own server, you SHOULD provide the appropriate servername
  747. (it is risky to assume that the "canonical" servername is appropriate).
  748.  
  749.  
  750.  
  751. -------         ----------          ---------          ------------
  752.  
  753. SREF_GET_COOKIE:  Check for a cookie
  754. Usage: cookie_value=sref_get_cookie(cookie_name,nth)
  755.  
  756. SREF_GET_COOKIE will check the request header for the "nth" cookie with
  757. the name given in cookie_name. If found, it's value will be returned.
  758. If not found, an empty string will be returned.  Note that if nth is
  759. not included, the first matching cookie is used.
  760.  
  761. For example, if the request header contains:
  762.    cookie:  customer=wiley_coyote
  763. then
  764.    sref_get_cookie('customer') will return "wiley_coyote"
  765.  
  766. Alternatively:
  767.    cookie:  customer=wiley_coyote ; item=bazooka ; customer=roadrunner 
  768. then sref_get_cookie('customer',2) will return "roadrunner"
  769.  
  770. Note: cookie_name is case insensitive, but cookie_value is not
  771.  
  772. Restictions: can ONLY be called from an addon. In cgi-bin scripts, use 
  773. value('http_cookie',,'os2environment') instead.
  774.  
  775. -------         ----------          ---------          ------------
  776.  
  777. SREF_GET_URL  : Retrieves a resource, given a  URL to an HTTP server.
  778.  
  779. Usage:  stuff=sref_get_url(url,maxchar,verbose,headers)
  780.  
  781. Will do socket calls to do an http/1.1 style  "GET" of  a URL from an 
  782. http server.
  783.  
  784. Returns the resource sent by the server (without response headers).
  785.  
  786. Returns "0" (without the quotes) if any problem occurred (will also
  787. write a message to the SRE-http error log)
  788.  
  789. URL : The "URL" to request.  You can specify a fully qualified URL (such as
  790.       http://www.census.gov/index.htm), or a "local selector" (such as
  791.       /files/listing.htm).  In the latter case, the local server (and port)
  792.       is used).
  793.  
  794. MAXCHAR:  Will get first MAXCHAR characters; if MAXCHAR is missing, get 
  795.            first 10 million (presumably you'll never ask for more then that!)
  796.  
  797. VERBOSE:  If 1, PMPRINTF some stuff
  798. HEADERS:  Optional request headers to add. Each request header should be seperated by a
  799.           CRLF ('0d0a'x). For example:
  800.              headers='Referer:me@someplace'||'0d0a'x||'User-Agent: Mozilla 2.0 (emulating)'
  801.                 
  802.  
  803. CITATION: SREF_GET_URL is adapted from MOVEAUD.CMD, that comes with GoServe.
  804.  
  805. Restrictions: none
  806.  
  807.  
  808. -------         ----------          ---------          ------------
  809.  
  810. SREF_GRAB_FILE: Read a file, and return it (and wait if it's currently locked)
  811. Usage:   afile_string=sref_grab_file(afile,seconds_to_try_for)
  812.                (see descriptions above)
  813.  
  814. Returns:
  815.    If file exists/is accessible, returns the file (complete with all
  816. CRLF's etc.). If file does not exist/ is not accessible, returns a 0.
  817.  
  818. Caution: If the file just contains a 0, then the afile_string will
  819.          equal 0.  In these cases,the use of 0 as an "error" code
  820.          is obviously misleading.
  821.  
  822. Restrictions:none
  823.  
  824. -------         ----------          ---------          ------------
  825. SREF_GOS: Send information to a client in an http/1.1 compatible way
  826.  
  827. Usage: 
  828.  
  829.   status  =SREF_GOS(acmd,varname,dorange,hdrs)
  830. where
  831.    acmd = A content transfer command. ACMD has two modes: FILE and VAR
  832.  varname= When a VAR type of acmd, the stuff to send
  833.  dorange= If 1, then check for range requests
  834.  hdrs   = CRLF delimited list of extra response headers. I.e.; the contents
  835.           of an advanced-options file.
  836.  
  837. Typically, you won't need to specify dorange and hdrs. 
  838.  
  839. Basically, using SREF_GOS is like issuing a GoServe completion code --
  840. but instead of issuing the completion code by itself, you use it as the
  841. acmd argument.
  842.  
  843. For example, instead of:
  844.    'FILE type text/html name d:\www\bar.htm'
  845. you should use a FILE mode call of:
  846.    stat=sref_gos('FILE type text/html name d:\www\bar.htm')
  847.  
  848. Similarly, instead of:
  849.     'VAR type text/plain name make_stuff'
  850. you should use a VAR mode call of:
  851.     stat=sref_gos('VAR type text/plain name make_stuff',make_stuff)
  852. (the 'name make_stuff' portion of the acmd argument is optional).
  853.  
  854. The following elements are permitted in both the FILE and VAR versions of
  855. the acmd argument.  Note that most of these are the same as in the native
  856. GoServe calls; with some additional meanings.
  857.  
  858.  NAME 
  859.    Used in FILE mode calls -- the next word is the file to
  860.    send to the client.
  861.    Example: 'FILE type text/html NAME D:\WWW\FOO.HTM'
  862.  
  863.  TYPE   
  864.    The mime type of the content (used to create content-type header)
  865.  
  866.  ENCRYPT enctype
  867.    Instruct SREF_GOS to encrypt the response.
  868.    Enctype should have the following structure:
  869.       method:epwd
  870.    where
  871.       method = the encryption method. SRE-http provides SRE_A and SRE_B
  872.                methods.
  873.       epwd   = the "shared-secret" encryption password. This is typically
  874.                found in a client's ?ENCRYPT:epwd "server privilege".
  875.    For example:         
  876.                 ENCRYPT SRE_A:foorab
  877.  
  878.    Note the encryption may be disabled, or overridden, by other SRE-http
  879.    parameters.    For further discussion of encryption, see ENCRYPT.DOC.
  880.  
  881.  ERASE      
  882.    Temporary response -- set the max-age header to 0.
  883.    Also: If FILE mode, then delete the NAMEd file after sending it. 
  884.    If VAR, ERASE is the default (but nothing actually get's erased). 
  885.  
  886.  ETAG an_etag
  887.    The ETAG to use. If not specified, SREF_GOS will compute one.
  888.  
  889.  MAXAGE nnn
  890.     Set the max-age cache-control option; where max-age nn should be
  891.     number of days (decimal values are allowed). Or, you
  892.     can specify Hours, Minutes, or Seconds.
  893.     For example:
  894.         MAXAGE .04  
  895.         MAXAGE 0.04D
  896.         MAXAGE  1H
  897.         MAXAGE 45M
  898.         MAXAGE 1800S
  899.  
  900.     Note that if ERASE is used, then MAXAGE nnn is ignored
  901.  
  902.  NOERASE
  903.    Non-temporary response. This is ignored in FILE mode, but suppresses
  904.    the max-age=0 if used with VAR.
  905.  
  906.  NOCACHE  
  907.    Suppress public caching (private caching is allowed)
  908.  
  909.  NOCACHE* 
  910.    Suppress all caching (public, private, and sreproxy caching is NOT done).
  911.  
  912.  NOIF
  913.    If NOIF appears, then SRE-http will not check the various If-
  914.    conditions (such as If-Modified-Since)
  915.  
  916.  CACHE  
  917.    Enables public caching.
  918.  
  919.  RESPONSE    
  920.    Change the http response code. If not specified, SREF_GOS determines
  921.    the response (typically, 200 Ok).
  922.    The word following RESPONSE should be the response line -- 
  923.    which should consist of a number and a short description.  
  924.    The number and the description should be seperated by url-encoded
  925.    spaces (%20).
  926.    Example: 
  927.       'FILE type text/html NAME D:\WWW\FOO.HTM RESPONSE 201%20Content%20Created'
  928.  
  929.  CLOSE
  930.    Force an immediate close of the connection 
  931.    (normally, http/1.1 clients are  maintained).
  932.    Example: 'FILE close type text/html NAME D:\WWW\ERROR.HTM'
  933.  
  934. Notes:
  935.   * By using SREF_GOS, you can ensure that appropriate http/1.1 
  936.     style headers are added to the response.  
  937.   * Furthermore, SREPROXY only knows about responses returned via SREF_GOS.
  938.  
  939.  
  940. Restrictions: can only be called from SRE-http addons.
  941.  
  942. -------         ----------          ---------          ------------
  943.  
  944. SREF_GZIP: Create a "gzip" compressed string
  945.  
  946.   usage: string_gzipped=sref_gzip(astring)
  947.  
  948. The inverse of SREF_UNGZIP.
  949.  
  950. Typically, string_gzipped with be written to a .GZ file.
  951.  
  952. Restrictions: uses the GZIP.EXE program that comes with SRE-http -- make sure
  953.              that GZIP is in a PATHed directory.
  954.       
  955.  
  956. -------         ----------          ---------          ------------
  957.  
  958.  
  959. SREF_HOST: A "host lookup"
  960. Usage:  aresult=sref_host(ipaddress)
  961.         IPaddress can be numeric or character (with appropriate periods)
  962. Aresult is a sentence noting the ipaddress and the name associated with it.
  963.  
  964. Restrictions: none
  965.  
  966.  
  967.  
  968. -------         ----------          ---------          ------------
  969.  
  970. SREF_HOST_INFO: Return "host specific" information.
  971.  
  972. SREF_HOST_INFO uses the server's ip address, and any HOST: header, to
  973. find a matching entry in the HOSTS. variables.
  974.  
  975. Usage  stuff=sref_host_info(myaddr0,nhosts,envstring)
  976.  
  977.    where: myaddr0 = the ip address of the server (to whom the request was sent)
  978.           nhosts = the number of hosts defined in the HOSTS. variables
  979.        envstring = environment variable preface
  980. and stuff will contain
  981.   0 = No match in HOSTS variables
  982.      or
  983.   parse var stuff servername ',' nickname ',' ddir 
  984.     where
  985.       servername : the servername for this request (possibly pulled from
  986.                    a HOST: request header)
  987.       nickname : SRE-http nickname for this servername 
  988.       ddir     : Default data directory
  989.  
  990. If myaddr0,nhosts, and envstring are not specified, sref_host_info will
  991. figure them out.
  992.  
  993. Restrictions: can  ONLY be called from an ADDON (uses the GoServe REQFIELD function)
  994.  
  995. -------         ----------          ---------          ------------
  996.  
  997.  
  998. SREF_INSERT_BLOCK : Insert a block into a string, at a "labeled" location.
  999. Usage: 
  1000.   newhaystack=sref_insert_block(haystack,alabel,add_string,after,delim1,delim2)
  1001.  
  1002.    Insert a add_string into haystack, right  after or before aLabel.
  1003.      where the alabel has the form delim1 label delim2
  1004.    Insertion is immediately after delim2, or before delim1
  1005.    (if after=1, then after)
  1006.    Default values of delim1={,  2=}
  1007.    Note that labels must have NO embedded spaces.
  1008.  
  1009. Returns the added to (or not added to) haystack
  1010.  
  1011. Restrictions:none
  1012.  
  1013.  
  1014. -------         ----------          ---------          ------------
  1015.  
  1016.  
  1017. SREF_JULDATE  : Returns julian date (since  1/1/0000) and fractional time
  1018.  
  1019. Usage: 
  1020.    juldate=sref_juldate(mode, time_string)
  1021. where:
  1022.       mode: F: Date/time is: yy/mm/dd/hh/mm/ss mode 
  1023.                as returned by sysfiletree(afile,'stem','FT')
  1024.             T: Date/time is: yyyymmdd hr : mm : sec
  1025.                as returned by: adate=date('S')|| ' '||time()
  1026.   time_string: The time string (using one of the above modes)
  1027.                If time_string not specified, use current date & time.
  1028.  
  1029. Typical return: 729152.125451 ; with the fraction accurate to about 
  1030.                 a second.
  1031.  
  1032. Caution: we recommend using a rexx statement of "numeric digits 11"
  1033. before calling (otherwise, accuracy will be only good to a minute).
  1034. Example:
  1035.    numeric digits 11
  1036.    adate=word(sysfiletree(afile,'stem','FT'),1)
  1037.   jdate=juldate(adate,'F')
  1038.  
  1039.  
  1040. Restrictions: none
  1041.  
  1042.  
  1043. -------         ----------          ---------          ------------
  1044.  
  1045. SREF_LOOKUP_COUNT : Augment a SRE-http "counter file"
  1046. usage: 
  1047.    newcount=sref_lookup_count(ctfile, needle, augment , substring , noadd)
  1048. where:
  1049.        ctfile: Name of the "counter file" to examine 
  1050.                Should contain entries that have the format:
  1051.                Aurl  ACount  optional_info
  1052.        needle: The target of the search. Typically a URL.
  1053.       augment:  YES: augment the count
  1054.                 ADD: augment the count, or if needle can not be found,
  1055.                     add new entry with count=1
  1056.     substring: EXACT: Exact match only
  1057.                    *: Use wildcard match if no exact match
  1058.                           ABBREV: Use abbreviation match if no exact match
  1059.         noadd:     1: just return matching filename and message
  1060.                       (do NOT lookup count or augment)
  1061.                    2: set optional_info equal to the current date,
  1062.                       and augment the value of acount
  1063.  
  1064. Returns a space delimited list containing STATUS COUNT optional_info
  1065.      If status=0, then some failure, 1 then success,
  1066.      2 then no match, but we added it (only possible if AUGMENT =  ADD)
  1067.  
  1068.  
  1069. Restrictions: none
  1070.  
  1071.  
  1072. -------         ----------          ---------          ------------
  1073.  
  1074. SREF_MAILIT :  Use REXX socket calls to send e-mail
  1075. Usage: 
  1076.     status=sref_mailit(address_list,message,smtp_gateway,sender_address)
  1077.  
  1078. where:
  1079.     address_list: A space delimited list of addresses
  1080.          message: A message string, that may contain CRLFs
  1081.                  (and may be rather long)
  1082.     smtp_gateway: The IP address of your SMTP server
  1083.   sender_address: The sender's address (optional)
  1084.                  If sender's address  is not given, it will be generated using
  1085.                 GoServe's servername() function.
  1086.  
  1087.   Status: 0 if failure to connect, 1 if success
  1088.  
  1089.   Examples:
  1090.        status=mailit("BOB@HIS.NET" , "This is my message ", "MAIL.MY.ORG" )
  1091.        status= mailit("BOB@HIS.NET JILL@HER.COM " , "This is my message ", ,
  1092.                     "MAIL.MY.ORG", "HARRY@MY.ORG")
  1093.  
  1094.   Note on recipient addresses:
  1095.      The message will be sent to each address.  Since the addresses are
  1096.      sent and then the message, this allows for fairly rapid mailing to multiple
  1097.      individuals.
  1098.  
  1099.  
  1100. Notes:
  1101.    *  The POSTMAIL.80 "post-filter" uses a local version of SREF_MAILIT
  1102.    *  POSTMAIL.80 contains a useful discussion of some of the limitations of
  1103.       the OS/2 SENDMAIL 
  1104.    *  CITATION: SREF_MAILIT is a modification of a routine written by Dave Briccetti.  
  1105.                                                                                  
  1106.  
  1107. Restrictions: if NOT called from an addon, you MUST specify the sender_address.
  1108.  
  1109.  
  1110. -------         ----------          ---------          ------------
  1111.  
  1112. SREF_MAKE_BLOCK  : Replaces substrings with other substrings.
  1113. Usage: newhaystack=sref_make_block(needle, haystack, delim1 , delim2, check_case)
  1114.  
  1115.       Replace all occurences of NEEDLE in HAYSTACK with delim1 needle delim2.
  1116.       If delim1 and delim2 not given, then { AND } are used.
  1117.       Example: make_block('boys',' there are wild boys out there','<b>',' </b>')
  1118.            returns 'there are wild <b>boys </b> out  there'
  1119.            (note that spaces are all retained).
  1120.       IF check_case=1, then cases must match (between needle and haystack)
  1121.  
  1122. Restrictions: none 
  1123.  
  1124. -------         ----------          ---------          ------------
  1125.  
  1126. SREF_WILD_MATCH : Performs a wildcard match, with "is this better" check
  1127.  
  1128. usage:
  1129.     matchinfo=sref_wild_match(needle,haystack,old_matchinfo,suppress_noslash)
  1130. where:
  1131.     needle : the string to search for
  1132.   haystack : the string to search in, it can contain * wildcard characters
  1133.  old_matchinfo: matchinfo from prior calls to sref_wild_match using same needle
  1134.  suppress_noslash: if 1, then suppress the trailing-| "noslash" feature
  1135.  
  1136. SREF_WILD_MATCH returns information on the quality of the match, information
  1137. which can be used in subsequent calls to SREF_WILD_MATCH to treat "worse"
  1138. wildcard matches as non-matches. Thus, you can use a a series of calls to 
  1139. SREF_WILD_MATCH to find the "best match" of a needle against a set of 
  1140. haystacks that may contain wildcards.
  1141.  
  1142. Returns (note that all comparisions are case insensitive):
  1143.         Situation                          Returns
  1144.         ------------                       ----------
  1145.   If needle is exact match to haystack      -1
  1146.  
  1147.   If needle does not match haystack          0
  1148.   (even with wild card checking) 
  1149.  
  1150.   If needle wildcard matches haystack,       match information
  1151.    and oldresu='' (or if oldresu is not      (a list of numbers signifying
  1152.    specified                                 matching characters in needle)   
  1153.  
  1154.   If needle wildcard matches haystack,       match information
  1155.      and oldresu<>''    
  1156.      and the current match is a "better"
  1157.      match then the "oldresu" match 
  1158.  
  1159.   Same as above, but if the current          0
  1160.    match is NOT a better match          
  1161.  
  1162. Basically,
  1163.   -1 means "exact match",
  1164.    0 means "no match" or "not better match" (if oldresu not specified, 
  1165.        0 always means "no match"), 
  1166.    and everything else means "wild card match" (that's better then prior
  1167.        "best" wildcard match).
  1168.  
  1169. Example of usage:
  1170.    /* Example of  use of sref_wild_match */
  1171.    a.1='This is *'
  1172.    a.2='This is a *'
  1173.    a.3='This is a funny * story'
  1174.    a.4='* is * '
  1175.    a.5='Th* fun*'
  1176.    a.6='This is funny *'
  1177.  
  1178.   say "Enter string : " ; parse pull ans
  1179.   oldresu=''; isit=0
  1180.   do mm=1 to 6
  1181.      resu=sref_wild_match(ans,a.mm,oldresu)
  1182.      if resu=-1 then do
  1183.        isit=mm
  1184.        leave
  1185.      end
  1186.      if resu=0 then iterate
  1187.      isit=mm
  1188.      oldresu=resu
  1189.   end
  1190.   matchingvar=isit
  1191.  
  1192. Thus, if you entered ..... then MATCHINGVAR would be equal to:
  1193.     That is silly                  4
  1194.     This is a man                  2
  1195.     This is not mine               1
  1196.     This is a funny but sad story  3  
  1197.     This is funny today            6
  1198.     That may be                    0  (no match)
  1199.     This is a *                    2  (exact match)
  1200.  
  1201. Caution: You MUST set oldresu='' before the first call in a series of calls
  1202.        
  1203. SPECIAL FEATURE:
  1204.   If haystack ends with a |, then no "slash" is allowed in the
  1205.   final wildcarded portion of the needle.  That is, the portion of the needle
  1206.   "covered" by the final (or only, if there is just one *) in the haystack
  1207.   can NOT contain a / or a \. If it does, it's a NO MATCH 
  1208.  
  1209.   Note that this feature is suppressed when suppress_noslash=1
  1210.  
  1211.  Examples:
  1212.     using a needle of: 
  1213.        animal/cats/food.1
  1214.   The follwing haystacks yield:
  1215.        animal/*candy  --  no match
  1216.        anim*/*.1      --  match
  1217.        animal/*.1|    --  no match (* covers cats/food, which contains a /)
  1218.        anim*/food*|   --  match (final * covers ".1")
  1219.        */cats*|       --  no match (final * covers "/food.1:"
  1220.  
  1221.   The primary purpose of this feature is to "limit" wildcard matches to a 
  1222.   single subdirectory (that is, to prevent matches to items in deeper 
  1223.   portions of the directory tree)
  1224.   
  1225. Hint: if you don't care about "best matches", use 
  1226.             ismatch=sref_wild_match(needle,haystack)
  1227.       and treat any non-0 value of ismatch as signifying a match.
  1228.  
  1229. Restrictions: none
  1230.  
  1231. -------         ----------          ---------          ------------
  1232.  
  1233. SREF_MEDIATYPE :  Returns mime type of a file
  1234.     Usage: mimetype=sref_mediatype(filename,port)
  1235.  
  1236. filename: name of file to deduce mime type of
  1237. port: optional, used when caleld from non-addons
  1238.  
  1239. Uses the extension of filename to determine the mime type.
  1240. For example, AA.HTM would yield "text/html".
  1241.  
  1242. SREF_MEDIATYPE will check the MEDIATYP.RXX file (of custom media types),
  1243. that is located in the GoServe working directory.
  1244.  
  1245. Restrictions:
  1246.   if called from something other then an SRE-http addon, you MUST
  1247.   include a port. If called from a stand-alone, the mediatyp.rxx file
  1248.   will not be available.
  1249.   
  1250.  
  1251. -------         ----------          ---------          ------------
  1252.  
  1253. SREF_MD5 : Create a "MD5" digest
  1254.  
  1255.   usage    md5_digest=sref_md5(astring,isfile)
  1256.  
  1257. where:
  1258.    astring: the string to "digest", or a fully qualified file name
  1259.    isfile: If 1, then atring is a filename (the contents of the
  1260.            file will be md5'ized; not the filename itself.
  1261.  
  1262. MD5 is used in various cryptograhic settings. SRE-http uses MD5 to 
  1263. return content-md5 response headers (which provides an integrity check),
  1264. and in digest authentication (which sends an md5 encrypted password).
  1265.  
  1266. Restrictions: uses MD5.EXE, so should only be called from an addon (assuming
  1267. MD5.EXE is only installed in the GoServe working directory).
  1268.  
  1269.  
  1270. -------         ----------          ---------          ------------
  1271.  
  1272. SREF_MKPACK64 : Create a "base64" string.
  1273.  
  1274.    usage:  string_packed_64=sref_mkpack64(astring)
  1275.  
  1276. The inverse of SREF_PACK64.
  1277.  
  1278. Note that  astring=sref_pack64(sref_mkpack64(astring))
  1279.  
  1280. Caution: this is NOT very efficient for long string (say, greater
  1281.           then 3000 bytes).
  1282.  
  1283. Restrictions: none
  1284.  
  1285.  
  1286.  
  1287.  
  1288. -------         ----------          ---------          ------------
  1289. -------         ----------          ---------          ------------
  1290. -------         ----------          ---------          ------------
  1291.  
  1292.  
  1293.  
  1294. -------         ----------          ---------          ------------
  1295. SREF_MULTI_SEND : Facilitates creation of "multi-part" documents.
  1296.  
  1297. SREF_MULTI_SEND is used to create multi-part document. It can also
  1298. be used to "send pieces" of a document as it becomes available.
  1299.  
  1300.   usage:
  1301.     rcode=sref_multi_send(message,mime_type,howsend,file_flag,verbose,wname,optheaders)
  1302. where:
  1303.    message:  either contains the "message" to be send (either a text string or
  1304.              binary value); OR it contains a fully qualified file name.
  1305.    mime_type : A mime type; such as text/html or image/gif
  1306.    howsend : A flag that tells SRE-http "where in the multi-send process
  1307.              we are".  There are basically four vallues (with 
  1308.              possible modifiers):
  1309.               '1' == Single part document to "send in pieces" (requires
  1310.                      a modifier)
  1311.               'S' == Start the multipart send (i.e.; the first image)
  1312.               'M' == A middle piece -- more will follow
  1313.               'E' == End piece -- send this "message" and close the connection.
  1314.                
  1315.              In addition, you can "build" a long message, and display 
  1316.              each portion as soon as they are added.  To do this, use the
  1317.              following HowSend codes:
  1318.                 '1S' and '1E' -- Start and end a "sent in pieces" single part
  1319.                                  document
  1320.                 'SS' and 'SE' -- Start and end the first "part"
  1321.                 'MS' and 'ME' -- Start and end the middle "part(s)"
  1322.                 'ES' and 'EE' -- Start and end the final "part"
  1323.                 'A'  and '1A' -- Add stuff (between 1S-1E; SS-SE ; MS-ME; or ES-EE)
  1324.    fileflag: If equal to 1, then "message" is to be treated as a
  1325.               fully-qualified file name (Optional)
  1326.    verbose : If > 2, some status info will be displayed (optional)
  1327.    wname    : Name to use when writing to GoServe audit file (for future 
  1328.              implementation)
  1329.    optheaders: optional response headers (crlf delimited)
  1330.  
  1331. The return code (rcode) is the RC from the 'SEND' command: you can
  1332. check for negative values which  indicate a broken connection.
  1333.  
  1334. For further details on SREF_MULTI_SEND, see MULTSEND.DOC
  1335.  
  1336.  
  1337. Advanced users note:
  1338.    To force "connection close", you need to modify the howsend argument of
  1339.    1, S, SE, E, EE, and 1E by adding a ' 1'.   That is, use
  1340.    1 1 and 1E 1 (or S 1 and E 1).
  1341.    Examples:
  1342.         foo=sref_multi_send('hello','text/plain','1 1',0)
  1343.         foo=sref_multi_send('stuff here',,'1A',0)
  1344.         foo=sref_multi_send('goodbye',,'1A 1',0)
  1345.    or
  1346.         foo=sref_multi_send('pic1.gif','image/gif','S 1',0)
  1347.         foo=sref_multi_send('pic2.gif','image/gif','A',0)
  1348.         foo=sref_multi_send('pic3.gif','image/gif','E 1',0)
  1349.  
  1350. Restriction: this can ONLY be called by an addon (it makes heavy use
  1351.              of the GoServe API).
  1352.  
  1353.  
  1354.  
  1355. -------         ----------          ---------          ------------
  1356.  
  1357. SREF_GMT: Compute a new GMT time, given a date,time,and offset
  1358.  
  1359.  
  1360.  Usage:  newtime=sref_gmt(offset,basetime,outtype,gmtoffset)
  1361.    where:
  1362.         offset  -- offest in days, hours, seconds, or minutes
  1363.         basetime -- in several formats
  1364.         outtype --- format of output
  1365.         gmtoffsett   --- size of gmt offset
  1366.  
  1367.    Returns
  1368.         Time (including GMT offset and "user supplied" offset) in desired format
  1369.  
  1370.  More Details:
  1371.  
  1372.    Offset: Add an offset to the "current time". Format can be:
  1373.       days : use a real number. i.e.;  1.3  (1.3 days), or 0.05 (1/20 day)
  1374.                 (or you can add a d; say, 1.3d)
  1375.       hours:  use an integer followed by an h. i.e.; 1h.
  1376.       minutes: an integer followed by an m.  i.e.;  60m
  1377.       seconds: an integer followed by a s. i.e.; 3600s
  1378.  
  1379.       Default is 0 (no offset)
  1380.  
  1381.   Basetime: The time to add the offset to. The format can be (SRE_GMT
  1382.             will recognize the format)
  1383.       julian     ---  728882.887731  
  1384.                                 (days since 0/0/00 . fraction of day)
  1385.       internet ---  Sat, 12 Aug 1996 21:18:20 GMT
  1386.   old internet ---  Saturday, 12-Aug-96 21:18:20 GMT
  1387.    ansi c      ---  Sat Aug 12 21:18:20 1996   
  1388.   sysfiletree  ---  96/08/12/21/18 or 96/09/12/21/18/22
  1389.  
  1390.   The Default is the current time
  1391.  
  1392. Outtype
  1393.    I       --- internet
  1394.    J       --- julian   
  1395.    C       --- cookie -- similar to internet, but use 12-Aug-1994 
  1396.                     (suitable for expires field of set-cookie)
  1397.    F       --- sysfiletree  
  1398.  
  1399.    Default is I
  1400.  
  1401. GMT_OFFSET
  1402.    If 0, do NOT offset (do NOT add the GMT to I or C outtype)
  1403.    If >0, then use this as the GMT offset (in SECONDS)
  1404.    Default: use the TZ environment variable (via the GoServe gmtoffset function)
  1405.  
  1406. Examples:
  1407.   say sref_gmt()
  1408.   say sref_gmt(,728882.88773)
  1409.   say sref_gmt(.12,'Sat, 12 Aug 1996 21:18:20 GMT','J')
  1410.   say sref_gmt('18000s','Saturday, 12-Aug-96 21:18:20 GMT')
  1411.   say sref_gmt('300m','Sat Aug 12 21:18:20 1996 ')
  1412.   say sref_gmt('5h','96/08/12/21/18','C',0)
  1413.   say sref_gmt(,,'F',0)
  1414. yields ....
  1415.    the current I style date/time-- say Wed, 24 Feb 1999 00:04:36 GMT
  1416.    Tue, 13 Aug 1996 02:18:19 GMT
  1417.    728883.216064
  1418.    Tue, 13 Aug 1996 07:18:19 GMT
  1419.    Tue, 13 Aug 1996 07:18:19 GMT
  1420.    Tue, 13-Aug-1996 02:17:59
  1421.    98/03/26/22/55
  1422.  
  1423. Restrictons: can ONLY be called from an addon.
  1424.  
  1425.  
  1426. -------         ----------          ---------          ------------
  1427.  
  1428. SREF_OPEN_READ: Open a file for read/write (and wait if it's currently locked)
  1429. SREF_OPEN_READ simulates a "write protected semaphore" -- it delays 
  1430. returning until the file is no longer locked by a writing process.
  1431.  
  1432. Usage: open_time=sref_open_read(afile ,seconds_to_try_for , howopen )
  1433.         afile: file to open
  1434.      seconds_to_try_for : seconds to try for
  1435.         howopen: BOTH= open as read/write
  1436.                  WRITE= open as write
  1437.                  NEW = open as write, must not already exist
  1438.                  READ = open as read (the default)
  1439. Returns:
  1440.  -2 : Timed out
  1441.  -1 : File does not exist, or does exist (if howopen=WRITE)
  1442.  >0 : Seconds it took (minimum value of 0.01) to open
  1443.  
  1444. Restrictions: none
  1445.  
  1446.  
  1447. -------         ----------          ---------          ------------
  1448. SREF_PACK64 : Convert a "base64" string.
  1449.  
  1450.    usage:  astring=sref_pack64(packed_64_string)
  1451.  
  1452. This is a rexx version of the GoServe pack64 function.  Quoting
  1453. from GoServe.doc:
  1454.    Takes a single string, expressed according to the MIME "Base64"
  1455.    specification (in RFC 1521), as an argument and returns the decoded
  1456.    (packed) string.  Each four bytes in 'string' is packed to three bytes
  1457.    in the result (except possibly for the last four bytes); 'string' must
  1458.    be a multiple of 4 bytes.  If any deviation from these specifications
  1459.    (or from the RFC 1521 "Base64" character set) is found, the null string
  1460.    is returned.
  1461.  
  1462.   PACK64 is useful for processing the incoming user/password data encoded
  1463.   for the HTTP 'basic access authentication scheme' -- see the HTTP
  1464.   documentation for details.
  1465.  
  1466. We provide this function, as well as SREF_MKPACK64 for CGI-BIN and
  1467. other "non-goserve" processes.
  1468.  
  1469. Caution: this is NOT very efficient for long string (say, greater
  1470.           then 3000 bytes) -- use the GoServe PACK64 if you can!
  1471.  
  1472.  
  1473. Restrictions: none
  1474.  
  1475. -------         ----------          ---------          ------------
  1476.  
  1477. SREF_REPLACESTRG: Replace substrings
  1478. Usage: 
  1479.     newstring=sref_replacestrg(haystack,needle,replacement, type , exactmatch)
  1480. where:
  1481.         haystack: The string to search in
  1482.         needle: The string to search for
  1483.      replacement: Replace occurences of "needle" with "replacement"
  1484.           type: 
  1485.                 FORWARD: Replace first occurence
  1486.                BACKWARD: Start from end, replace "last" occurence.
  1487.                     ALL: Replace all occurences
  1488.     exactmatch:  if YES, then cases must match (NO=case is ignored).
  1489.              Note that the case of the "replacement" is retained, as
  1490.              well as the non-replaced portion of the haystack, regardless
  1491.              of the value of exactmatch.
  1492.  
  1493. Returns:
  1494.      The haystack,with the replacements (if no replacements, return the
  1495.      original value of haystack)
  1496.  
  1497. Restrictions:none
  1498.  
  1499. -------         ----------          ---------          ------------
  1500. SREF_SEARCH_FIXED: Search a fixed-length record file for a match
  1501. Usage:
  1502.   match_record=sref_search_fixed(string,filename,numrec,reclen,recoff,idat,idlen,type)
  1503. where:
  1504.   string : The string to look for
  1505.   filename: A fixed-length record file to look in
  1506.   numrec:  # records in filename
  1507.   reclen: length of each record (must include possible crlf's at end of line)
  1508.   recoff: number of header records (offset from start of file) --- they will
  1509.           be skipped when searching
  1510.   idat:  Character (in a record) that identifier variable (to be searched) 
  1511.          1 is the first character
  1512.   idlen: length, in characters, of identifier
  1513.   type: Type of search
  1514.         1 = Exact match (no space stripping, case sensitive)
  1515.         2 = Wildcard match (string can have * wildcards)
  1516.         2 n = Same as 2, but return nth match (i.e.; 2 and 2 1 are the same)
  1517.         otherwise: strip spaces, case insensitive match.
  1518.  
  1519.   Wildcard matches are attempted "one record at a time" -- it's much slower
  1520.   then the binary searches used for exact and non-exact matches.
  1521.  
  1522.   Note that if you use one of the binary match types, be sure the sort order
  1523.   is appropriate (i.e.; if exact is used, then pay attention to case)
  1524.  
  1525. Returns:
  1526.   If a match is found, the matching record is returned.
  1527.   If no match is found, a '' is returned.
  1528.     
  1529. Restrictions: none
  1530.  
  1531.  
  1532. -------         ----------          ---------          ------------
  1533.        
  1534. SREF_VERSION  : Returns string listing the SRE-http version
  1535. Usage:
  1536.    filter_name=sref_version(port)
  1537. or  
  1538.   filter_number=sref_version(port,1)
  1539.  
  1540. where port is optional.
  1541.  
  1542. When a second argument of 1 is used, then a "numeric" version number is returned.
  1543. Otherwise, a descriptive string is returned.
  1544.  
  1545. Sample descriptive string return: SRE-http Ver 1.3c.0299.a 
  1546. Or, as a  numeric return: 130301.2 
  1547.     ver 1.3, subversion 3 , build  number 1; 
  1548.     the .2 signfies that SREPROXY is being used
  1549.  
  1550. The numeric return provides a convenient way of comparing the revision to
  1551. some 'minimal value'.
  1552.  
  1553. The (~proxy), or (std), refer to the "proxy" (SREPROXY) or standard (SREFILTR)
  1554. versions of SRE-http.
  1555.  
  1556. Restrictons: if called from a non-addon, you should include the 
  1557. port of the server (if not included, a default value of 80 is used).
  1558.  
  1559.  
  1560.  
  1561.  
  1562. -------         ----------          ---------          ------------
  1563.  
  1564. SREF_VALUE: Get value from the OS/2, or SRE-http, environment.
  1565.  
  1566.  
  1567. SREF_VALUE is a general purpose "value of a variable" procedure.
  1568.  
  1569. SREF_VALUE is able to extract and set variables that 
  1570. reside in  four different "environments". These four
  1571. environments are:
  1572.  
  1573.    i) OS2 : the  os/2 environment variables
  1574.   ii) INI : the SRE-http initialization parameters
  1575.  iii) REQ : request specific variables 
  1576.   iv) USE : semi-permanent user defined variables
  1577.  
  1578.  
  1579. Calling syntax:
  1580.      value=SREF_VALUE(varname,newval,env,optinfo,port,prefix)
  1581. where:
  1582.     varname : the name of the variable to look up
  1583.     newval: a new value for this variable. If not specified, or if set
  1584.             equal to a zero-length string (i.e.; newval="")
  1585.             a new value will NOT be set
  1586.      env: The "environment" to look in; either OS2,INI, REQ, or USE.
  1587.   optinfo: Optional: information: used if env=REQ  or env=USE.
  1588.   port : Optional: the port (that goserve is running under)
  1589.   prefix: Optional: the "sre" prefix (typically, SREF_80_)
  1590.  
  1591. If prefix is specified, port is ignored.
  1592. If sref_value is called from a GoServe thread, port and prefix are
  1593. unnecessary.
  1594.  
  1595. In any case, the current value of the variable will be returned; and if NEWVAL
  1596. is specified, the variable's value will then be changed to this NEWVAL.
  1597.  
  1598. ENV specific notes:
  1599.  
  1600.   * For all values of ENV, setting VARNAME='*' will cause a space 
  1601.     delimited list of "currently available variables" to be returned.
  1602.  
  1603.   * env=OS2 is equivalent to the use of OS/2's value function, with 
  1604.     the added bonus of the * "list variables" option. Note that when *
  1605.     is used with env=OS2, INI variables will be detected and NOT displayed.
  1606.  
  1607.     Note: in a multi-host environment, you can obtain a "host" specific
  1608.           value of a variable by including a .HOST_NICKNAME to the
  1609.           VARNAME (seperated by a space). 
  1610.           For example,
  1611.              if you've defined a HOST with a host nickname of "SITE2",
  1612.              and want the "host specific version of THE_REALM", 
  1613.              then enter VARANAME='THE_REALM SITE2'.  
  1614.           Note that if there is no "host-specific" value, the "generic"
  1615.           value will be used.  
  1616.  
  1617.   * env=INI is equivalent to using OS/2's value function on variables that
  1618.     begin with SREF_nn, where nn is the "current port" (port 80 if 
  1619.     no current port can be determined).
  1620.  
  1621.   * When using SREF_VALUE in a stand-alone process (not under GoServe/SRE),
  1622.     to use the REQ "environment" you MUST first issue a
  1623.           call sref_value('!INI',,'REQ',,,'SREF_80_')  
  1624.     (assuming that GoServe/SRE is running on port 80).
  1625.  
  1626.   * When using env=REQ, and calling from a post-filter procedure, or from a 
  1627.     stand alone program, OPTINFO should contain the appropriate request id (as
  1628.     assigned by GoServe).
  1629.     SRE-http provides this name to post-filter procedures. For stand-alones,
  1630.     you'll have to figure it out (sorry, we do not provide a mechanism for 
  1631.     doing this figuring out).
  1632.  
  1633.   * env=USE is the only way (short of writing your own code) of reading/writing
  1634.     "user defined, semi-permanent" variables.
  1635.  
  1636.     These variables are constant (unless explicitily modified) across
  1637.     requests -- they belong to the GoServe process (and NOT to
  1638.     a specific request). 
  1639.  
  1640.     Although specific to a GoServe process, these variables can be
  1641.     accessed from any other process. To do this, you must set the
  1642.     OPTINFO variable to be the "port number" (i.e.; miscinfo=8080) 
  1643.     of the GoServe process (if OPTINFO is not specifed, a port number 
  1644.     of 80 is assumed).
  1645.   
  1646.   * env=USE and env=REQ both use the SRE-http "variable storage daemon". 
  1647.    This daemon can handle any kind of string, of any (reasonable) length. 
  1648.  
  1649.     Thus, using SREF_VALUE('USE',...)is much more flexible than 
  1650.     using the REXX VALUE(,,'os2environment') function; since the OS/2 
  1651.     environment does  NOT like  binary strings, and gets  flakey when a string
  1652.     of any size (say, greater then 1024 bytes) appears.
  1653.  
  1654.     Of course, this also means that to use USE and REQ, GoServe/SRE
  1655.     MUST be running in some currently active process.
  1656.  
  1657.  
  1658. Note: SRE-http comes with a simple demo of SREF_VALUE --TESTVALU.SHT
  1659.       and TESTVALU.CMD.
  1660.     
  1661. Restrictions: can be called from anywhere, given the above concerns.
  1662.  
  1663. -------         ----------          ---------          ------------
  1664. SREF_QUEUE
  1665.  
  1666. SRE-http supports a flexible form of "queue". The primary purpose of these 
  1667. SRE-http queues is to store and retrieve information in a globally accessible, 
  1668. semi-permanent location. In many ways, they are functionally similar to REXX 
  1669. queues, but are much more easily manipulated.
  1670.  
  1671. SREF_QUEUE is called as:
  1672.     
  1673.       retvalue=SREF_QUEUE(QueueName,action,value,port)
  1674.  
  1675. where:
  1676.       queuename: The name of a queue; it can be any REXX-style, variable name
  1677.       value: Either the value to be added to the queue, or instructions on
  1678.              how to read from the queue
  1679.       action: Type of action (PUT, QUEUE, POP, READ, etc.)
  1680.       port: Optional:: required if SREF_QUEUE is not called from an addon. 
  1681.             If called from an external process (such as a CGI-BIN script),
  1682.             this should be the port that SRE-http is running under (typically,
  1683.             80).
  1684.  
  1685.  
  1686. For details on how to use SREF_QUEUE, see SREFQUE.DOC
  1687.  
  1688. Restrictions: same as sref_value -- can be called from anywhere, but you
  1689. might need to supply the port.
  1690.  
  1691. -------         ----------          ---------          ------------
  1692.  
  1693. SREF_UNGZIP: Uncompress a "gzip" string
  1694.  
  1695.   usage: astring=sref_gzip(gzipped_string)
  1696.  
  1697. The inverse of SREF_GZIP.
  1698.  
  1699. Typically, gzipped_string will be the contents of a .GZ (or .Z) compressed file.
  1700.  
  1701. Restrictions: uses the GZIP.EXE program that comes with SRE-http -- make sure
  1702.              that GZIP is in a PATHed directory.
  1703.       
  1704. -------         ----------          ---------          ------------
  1705.  
  1706. SREF_WILDCARD  : Do a wildcard match (with substitution)
  1707.  
  1708. Usage:  
  1709.     newstring=sref_wildcard(needle,haystack replacement,doexact)
  1710. where:
  1711.       needle: String to search for
  1712.     haystack: String to compare needle to
  1713.  replacement: Return this string, after (possibly) inserting
  1714.               wildcarded portions of needle into wildcarded portions
  1715.               of replacement
  1716.              (note there is no comma between haystack and replacement)
  1717.    doexact: Exact match flag. If doexact=1, then do NOT do wildcard matching.
  1718.  
  1719. returns:  
  1720.    code , match
  1721. where
  1722.    code: 0= none, 1=exact match, 2=replacement match
  1723.  
  1724. See if  needle matches haystack.  Haystack can contain *, which are
  1725. used as wildcard characters (as with matching file names in OS/2).
  1726. If a match occurs, the replacement is returned, possibly with
  1727. "substitution" matches  -- i.e.; the part of needle "covered by" the
  1728. * in the haystack is placed into the replacement (at the position of the
  1729. * in the replacement)
  1730.  
  1731. Example:  newstring=sref_wildcard('1234567','12*67 abcde*f',0)
  1732.           yields:  newstring= 2 ,abcde345f
  1733.  
  1734. Note: Needle and replacement should not contain "real" * characters.
  1735.  
  1736.  
  1737. Restrictions: none
  1738.  
  1739.  
  1740.  
  1741. -------         ----------          ---------          ------------
  1742. -------     SECTION 2: Inter-thread communications in SRE-http
  1743. -------         ----------          ---------          ------------
  1744.  
  1745.  
  1746. In order to improve throughput, SRE-http has been written as a multi-threaded
  1747. program.  The basic goal is to keep the size of the basic "filter" down.
  1748. The multi-threaded nature of GoServe makes this important: since every
  1749. "request" that arrives run's in a seperate thread. If you
  1750. only get 1 request at a time, that may not be much of a problem.  However,
  1751. when many requests arrive simultaneously, the multiplicity of
  1752. "large threads" can bog the machine down.  Since image rich documents will
  1753. generate many requests, such occurences of "many simultaneous
  1754. requests" may actually be fairly typical (even for a lightly visited site)!
  1755.  
  1756. For this and other reasons, SRE-http uses a number of "daemons".
  1757. As with "loading the library of macrospace procedures", these daemons are
  1758. launched when SRE-http is first run.  Note that unlike the "request
  1759. specific threads" launched by GoServe, the daemons stay active as long as
  1760. GoServe is running.  In contrast, "request specific threads" are
  1761. constantly being generated and killed, as GoServe recieves and responds 
  1762. to tcp/ip requests.
  1763.  
  1764. Note that launching a thread simply means running a REXX program 
  1765. simultaneously. However, in contrast to running programs in different
  1766. processes (say, with the DETACH command), REXX threads share a single 
  1767. environment.
  1768.  
  1769. This "shared environment" feature motivates SRE-http's extensive use of
  1770. the environment to store configuration information.  Basically, one of 
  1771. SRE-http's daemons  (the SREFMON.CMD thread) loads the 
  1772. variables set in INITFILT.80 (as well as variables set in
  1773. REPSTRGS.IN) into the environment (SREFMON.CMD also keeps track
  1774. of these files, and re-initializes the environment should you change them
  1775. "on-the-fly").
  1776.  
  1777. If you need the values of these variables, you can use the SREF_VALUE
  1778. comamnd to retrieve them. For  example, to retrieve the value of the
  1779. CHECKLOG variable, you can use
  1780.     check_log=sref_value('CHECKLOG',,'INI')
  1781.  
  1782.  
  1783. Technical Note:
  1784.     For historical reasons, SRE-http stores these "initialization" 
  1785.     variables with a prefix of SREF_port_. For example, if you 
  1786.     are running on port 80 (the default http port), and you want the
  1787.     value of the CHECKLOG variable, you could extract it using: 
  1788.         avalue=VALUE('SREF_80_CHECKLOG',,'os2environment')
  1789.  
  1790. Although used by SRE-http, the limitations of the enviroment preclude
  1791. it's use for many important purposes. Instead, a number of special
  1792. "SRE-http daemons" are used. These include:
  1793.  
  1794.     USERCHK.RXX:  Used to lookup usernames stored in the USERS.IN file.
  1795.     ALIASCHK.RXX: Used for alias matching, it uses the ALIASES.IN file.
  1796.     ACCESCHK.RXX: Used for finding access rights and permissions, it
  1797.                   uses ACCESS.IN
  1798.     VIRTCHK.RXX:  Used for virtual directory lookup, it uses VIRTUAL.IN.
  1799.     VARSTORE.RXX: Used for storing semi-permanent variables, clientnames,
  1800.                   and recent requests.
  1801.  
  1802. These daemons store their data files in memory.  For example, USERCHK 
  1803. does not re-read USERS.IN everytime it needs to look up a username/password
  1804. combination.  Instead, it examines a "copy" of USERS.IN that it's read 
  1805. into memory.
  1806.  
  1807. In addition to providing semi-permanent data storage, daemons are also
  1808. useful in providing non-time sensitive processing. For example: 
  1809.     POSTFCHK.RXX: Used for "recording requests" and for "a custom written
  1810.                   post-filter".  Uses RECRDALL.IN.
  1811.     PMPRINTF.RXX: Used as a front-end to the PMPRINTF procedure.
  1812.  
  1813. In addition to these core SRE-http functions, daemon's can be used
  1814. in addons.  For example, the SRE-Data addon (a simple web-aware database
  1815. addon) uses a daemon to search databases.  Similarly, the SRE_BLNC addon
  1816. uses a daemon to provide load balancing.
  1817.  
  1818. Ambitious programmers interested in writing addon's that are partially
  1819. run as daemons can make good use of a simple set of "SREF_DMN_" 
  1820. procedures supplied with SRE-http. These procedures greatly 
  1821. facilitate the use of daemons, relieving the need for the programmer 
  1822. to deal with most of the myriad details.  The DAEMONS.DOC file
  1823. describes these procedures in detail.
  1824.  
  1825.  
  1826. -------         ----------          ---------          ------------
  1827. -------     SECTION 3: A short discussion of OS/2 SendMail
  1828. -------         ----------          ---------          ------------
  1829.  
  1830.