home *** CD-ROM | disk | FTP | other *** search
- /* GoServe filter program for remote control, usually called from */
- /* GoFilter.80; requires GoServe 2.25 or later. */
- /* Authorization (which may be on either GET or POST track) should */
- /* be handled by the primary filter. */
-
- /* Arguments: */
- /* VERB -- the verb (GET or POST) from the HTTP request */
- /* URI -- the partial URI (after leading directory has been */
- /* removed). This must be of 'action' form (that is, */
- /* no file extension, even if a page request). */
- /* Returned is a GoServe command, as from a filter. */
-
- /* This routine is packaged as a single file for simplicity of */
- /* distribution. The code is generic, except for the form-specific */
- /* code at the bottom. */
- /* Form pages are held in the data directory, as usual; this code */
- /* lives in the GoServe directory tree. */
-
- parse arg verb, action
-
- /* Actions are one of two types: page requests and form responses. */
- /* The latter have a verb of POST. Page requests refer to files */
- /* in the datadir called xxxx'.htm' (where xxxx is the name of the */
- /* page, and the '.htm' is added by the PAGE function). */
-
- if verb='POST' then return form(action) /* form processing */
- return page(action) /* page fill and display */
-
- /* ---------------------------------------------------------------- */
- /* PAGE: return a page, dynamically modified */
- /* ---------------------------------------------------------------- */
- /* ACTION is name of the page */
- /* MESSAGE is passed as ARG(2) to EVAL */
- page: procedure
- parse arg action, message
- pagefile=datadir()action'.htm' /* map to file */
- if stream(pagefile, 'c', 'query exists')='' then /* not found */
- return response('notfound',,
- 'asked for remote action page "'action'", which could not be found')
- /* File exists. Now we do the 'server side includes' on the file; */
- /* each {zzzz} is replaced by the result of the expression zzzz */
- data=charin(pagefile, 1, chars(pagefile)) /* read whole file */
- out='' /* result */
- do forever
- parse var data pre '{' expr '}' data /* find expression */
- out=out''pre /* pre-stuff */
- if expr='' then if data='' then leave /* no more '{' */
- out=out''eval(expr, message) /* add evaluation */
- end
- 'VAR TYPE text/html AS' pagefile 'NAME out'/* send it */
- return '' /* [called as function] */
-
- /* ---------------------------------------------------------------- */
- /* EVAL: return an expression evaluation [protected] */
- /* ---------------------------------------------------------------- */
- /* ARG(1) is expression to evaluate */
- /* ARG(2) is passed from PAGE, usually an arbitrary text message */
- /* An expression starting with '?' is a direct EXTRACT, special- */
- /* cased for simplicity. ({?foo} == {extract(foo)}) */
- eval: procedure /* no variables visible */
- if left(strip(arg(1)),1)='?' then return extract(substr(strip(arg(1)),2))
- /* arbitrary expression expected -- assume CRLF and tabs are whitespace */
- signal on syntax name evaloops /* handle errors */
- interpret 'result='translate(arg(1),' ','0d0a09'x) /* evaluate */
- return result /* done */
-
- evaloops: return '[?]'
-
- /* ---------------------------------------------------------------- */
- /* IF: select string based on ARG(1) */
- /* ---------------------------------------------------------------- */
- /* Rather like C's "?" operation */
- if: if arg(1) then return arg(2); else return arg(3)
-
- /* ---------------------------------------------------------------- */
- /* QFLAG: return 'checked' for a flag that's ON, null otherwise */
- /* QFLAGN: return 'checked' for a flag that's OFF, null otherwise */
- /* ---------------------------------------------------------------- */
- qflag: if extract(arg(1))='ON' then return 'checked'; else return ''
- qflagn: if extract(arg(1))='OFF' then return 'checked'; else return ''
-
- /* ---------------------------------------------------------------- */
- /* GMTWARN: return warning if GMT unavailable, null otherwise */
- /* ---------------------------------------------------------------- */
- gmtwarn: if extract('GMTSET')='ON' then return ''
- return '[TZ was not set - GMT is <strong>not</strong> available]'
-
- /* ----------------------------------------------------------------------- */
- /* RESPONSE: Standard [mostly error] responses. */
- /* ----------------------------------------------------------------------- */
- /* This is the same as the one in the sample main filter file. */
- /* Arguments are: response type and extended message information. */
- /* It returns the GoServe command to handle the result file. */
- response: procedure
- parse arg request, message
- select
- when request='badreq' then use='400 Bad Request Syntax'
- when request='notfound' then use='404 Not found'
- when request='forbid' then use='403 Forbidden'
- when request='unauth' then use='401 Unauthorized'
- end /* Add others to this list as needed */
- /* Now set the response and build the response file */
- 'RESPONSE HTTP/1.0' use /* Set HTTP response line */
- parse var use code text
- crlf='0d0a'x; out=''
- out=out||'<!doctype html public "-//IETF//DTD HTML 2.0//EN">'crlf
- out=out||"<html><head><title>"text"</title></head>"crlf
- out=out||"<body><h2>Sorry...</h2>"crlf
- out=out||"<p>The request from your Web client" message"."crlf
- out=out||"<hr><em>HTTP response code:</em>" code '['text']'crlf
- out=out||"<br><em>From server at:</em>" servername()crlf
- out=out||"<br><em>Running:</em>" server()crlf
- out=out||"</body></html>"crlf
- 'VAR TYPE text/html AS Response NAME out' /* send it */
- return '' /* [called as function] */
-
- /* ---------------------------------------------------------------- */
- /* FORM: process a form action. Get here only if verb is POST. */
- /* ---------------------------------------------------------------- */
- form: procedure
- parse arg action
- 'read body var data' /* get the incoming data */
- if rc=-4 then /* body too large */
- return response('badreq', 'sent too much data')
- if rc<>0 then /* e.g., invalid HTTP header */
- return response('badreq', 'sent data that could not be read')
-
- /* set VAR.x variables from the incoming data stream */
- VAR.='' /* null string unless set */
- data=data'&' /* set end condition */
- do until data='' /* each value */
- parse var data assign '&' data /* split off name=value */
- parse var assign name '=' value /* separate */
- value=translate(value, ' ', '2b090a0d'x) /* handle '+', tabs, and CRLF */
- name='?'translate(packur(name)) /* caseless name, with leading '?' */
- var.name=packur(value) /* set, after URI decoding */
- end
-
- /* ----- The above is generic. Now get form-specific. ----- */
-
- /* There are several ways of handling various types of form */
- /* shown here. Compare with the various .HTM files to see */
- /* how they work. */
-
- message='Changes applied.' /* Default message */
- select
- when action='gormdata' then do
- dd=var.?datadir
- if right(dd,1)<>'/' then dd=dd'/' /* be nice */
- if dd='' then rc=1; else 'set datadir' dd
- if rc<>0 then
- return response('badreq', 'asked for "'dd'", which is not a directory')
- end
- when action='gormfilt' then do
- ff=var.?filter
- if pos('.',ff)=0 then ff=ff'.'extract('serverport')
- if ff='' then rc=1; else 'set filter' ff
- if rc<>0 then
- return response('badreq', 'asked for "'ff'", which cannot be a filter')
- end
- when action='gormtest' then do
- if var.?test='ON' then 'set test on'; else 'set test off'
- if var.?diag='ON' then 'set diag on'; else 'set diag off'
- if var.?diag2='ON' then 'set diag2 on'; else 'set diag2 off'
- if var.?trace='ON' then 'set trace on'; else 'set trace off'
- if var.?diagmsg='ON' then 'set diagmsg on'; else 'set diagmsg off'
- end
- when action='gormaudi' then do
- if var.?auditaccept ='ON' then 'set auditaccept on'
- else 'set auditaccept off'
- if var.?auditcomplete='ON' then 'set auditcomplete on'
- else 'set auditcomplete off'
- if var.?auditerror ='ON' then 'set auditerror on'
- else 'set auditerror off'
- if var.?auditfail ='ON' then 'set auditfail on'
- else 'set auditfail off'
- if var.?auditgmt ='ON' then 'set auditgmt on'
- else 'set auditgmt off'
- if var.?auditinfo ='ON' then 'set auditinfo on'
- else 'set auditinfo off'
- if var.?auditlimit ='ON' then 'set auditlimit on'
- else 'set auditlimit off'
- if var.?auditselect ='ON' then 'set auditselect on'
- else 'set auditselect off'
- if var.?audituser ='ON' then 'set audituser on'
- else 'set audituser off'
- end
- when action='gormlimi' then do
- err=''
- limits='LimitClients LimitWarning LimitFiles',
- 'LimitTimeInactive LimitTimeTotal LimitStartWait',
- 'LimitHeader LimitBody'
- 'extract' limits
- do until limits=''
- parse var limits limit limits
- value=value('var.?'limit)
- if value(limit)<>value then do; 'set' limit value
- if rc<>0 then err=err'"SET' limit value'" failed [rc='rc'].<br>'
- end
- end /* limits */
- if err<>'' then message=err
- end
- when action='gormgene' then do
- err=''
- flags='menubar surface hidden sounds soundall fastfile fastfilter'
- 'extract' flags
- do until flags=''
- parse var flags flag flags
- value=value('var.?'flag); if value='' then value='OFF'
- if value(flag)<>value then do; 'set' flag value
- if rc<>0 then err=err'"SET' flag value'" failed [rc='rc'].<br>'
- end
- end /* flags */
- if err<>'' then message=err
- end
- when action='gormresp' then do /* Mixed input and flags */
- err=''
- items='responsegoal responsegoalshow'
- 'extract' items
- do until items=''
- parse var items item items
- value=value('var.?'item); if value='' then value='OFF'
- if value(item)<>value then do; 'set' item value
- if rc<>0 then err=err'"SET' item value'" failed [rc='rc'].<br>'
- end
- end /* items */
- if err<>'' then message=err
- end
- when action='gormacts' then do
- n=0 /* actions count */
- if var.?moveaudit='ON' then do; n=n+1; 'CONTROL var s.n moveaudit'; end
- if var.?resetall ='ON' then do; n=n+1; 'CONTROL var s.n reset all'; end
- if var.?reseterr ='ON' then do; n=n+1; 'CONTROL var s.n reset errors'; end
- if var.?resetlim ='ON' then do; n=n+1; 'CONTROL var s.n reset limits'; end
- if var.?resettran='ON' then do; n=n+1; 'CONTROL var s.n reset transactions'; end
- if var.?resetbyte='ON' then do; n=n+1; 'CONTROL var s.n reset bytes'; end
- if var.?resetpeak='ON' then do; n=n+1; 'CONTROL var s.n reset peak'; end
- if var.?resetresp='ON' then do; n=n+1; 'CONTROL var s.n reset response'; end
- /* Build and return result string */
- if n=0 then message='No actions selected'
- else do
- message=''; do i=1 to n; message=message''s.i'<br>'; end
- end
- end
- otherwise
- return response('badreq', 'asked to process the form "'action'", which is unknown')
- end /* select */
-
- /* Return an 'OK' page here. Sophisticated users may prefer a
- re-display of the current page, or a direct return to the index page. */
- return page('gormok', message)
-
-