home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Spezial
/
SPEZIAL2_97.zip
/
SPEZIAL2_97.iso
/
ANWEND
/
ONLINE
/
SREFV12J
/
POSTMAIL.80
< prev
next >
Wrap
Text File
|
1997-06-30
|
23KB
|
716 lines
/* a sample of a SRE-FILTER "post-filter" -- 13 May 1997
This will mail a message to selected users, depending on the value
of the request selector, or the client's IP address.
For general notes on how POSTFILT is called, see the bottom of this file.
----------------------- A Mail Notification Facility ----------------
This will automatically send "e-mail alerts" to specified recipients given specified events.
It calls a local version of the SREF_MAILIT procedure.
It requires that a valid SMTP Gateway be available (the SMTP Gateway
is set by running SRE-FILTER's configurator and modifying the SMTP_GATEWAY variable)
Note that if you may be able to use OS/2's SENDMAIL program to use the server as
an SMTP gateway (see the TCP/IP command reference documentation).
To use this routine, you will need to set up an "event" list. The event list
should contain the following information:
a) What type of event to examine (client or request selector)
b) The value that triggers a "match" (i.e.; a client's address, or a request for a particular file)
c) The list of e-mail addresses to send "e-mail alerts" to
d) An optional message to include in these alerts.
e) An optional subject line
This routine uses the EVENTS.field.n stem variable to store this event list.
field should take one of 4 values
a)TYPE : Either CLIENT or REQUEST (REQUEST is the "request selector")
b)VALUE : An IP (name or numeric) address, or a target request selector.
Either may contain * characters;
(either as domain wildcards or as a wildcard)
c)RECIPIENTS: A space delimited list of e-mail addresses
d)MESSAGE : An optional message. It may contain CRLFs, and be quite long.
e)SUBJECT: An optional 1 line message to use as the SUBJECT.
n is an integer value (that should run from 1.. "# of events")
You also must set EVENTS.0 equal to the "# of events"
The algorithim works by:
From m=1.. to EVENTS.0
If EVENTS.TYPE.m=CLIENT, then see if client's numeric IP address
matches EVENTS.VALUE.m (with * acceptable as a wildcard)
If EVENTS.TYPE.m=REQUEST, see if the client's request selector matches EVENTS.VALUE.m,
(with * signalling that abbreviation matching should be used).
NOTE: The SEL variable contains the original request selector, before modifications
by SRE-FILTER. The match is against the entire request selector,
not just the Action! Thus, a SEL of FOO.HTM?this_one
will NOT match a target of FOO.HTM (but will match FOO.HTM*)
In comparision, exact matches (say,
in the access_file) compare the action to the target -- so
any ?xxx is ignored.
If either occurs
Create a note containing time,date, server name, client's name, SRE-FILTER status
message, and EVENTS.MESSAGE.m
Note that EVENTS.MESSAGE.m is optional.
If EVENTS.SUBJECT.j is missing, a generic subject line is used.
Sent this note to each e-mail addresss listed in EVENT.RECIPIENTS.m
If there is not SMTP_GATEWAY specified, or EVENTS.0=0, then nothing
is done.
Note that there may be multiple matches; so that several different e-mail alerts (to
different sets of e-mail addresses, some of which may contain common
addresses) may be generated by each call to this routine.
Example -- note that the numbering goes from 1 (first event) to 3 (third event):
EVENTS.0=3
EVENTS.TYPE.1="CLIENT"
EVENTS.VALUE.1="*.*.*.*"
EVENTS.RECIPIENTS.1="bob@hisorg.net jill@staff.agency.gov "
Note that EVENTS.MESSAGE.1 is not set
EVENTS.TYPE.2="REQUEST"
EVENTS.VALUE.2="PROJECTS/PROJ1.HTM"
EVENTS.RECIPIENTS.2="ANDREW@myorg.org"
EVENTS.MESSAGE.2="A request for PROJ1 was recieved "
events.subject.2=' PROJ1 Request '
EVENTS.TYPE.3="REQUEST"
EVENTS.VALUE.2="\PUT_FILE*"
EVENTS.RECIPIENTS.3="WEBMASTER@MYORG.ORG"
EVENTS.MESSAGE.3="A file upload has been recieved! "||crlf||" You may want to check it?"
Note the use of CRLF to add a line feed to the message.
Note when EVENTS.TYPE.m=REQUEST:
all / are converted to \ (in both the SEL and EV*ENTS.VALUE.n), and
leading and trailing \ are stripped
--------------------------------------------------
*/
postmail:
CRLF = '0d0a'x
signal on syntax name error2
signal on error name error2
/* ============== INSERT EVENTS list here ================ */
EVENTS.0=0
/* optional: set verbose=1 to echo status stuff, 2 more stuff, 0 for quiet operation */
verbose=1
/* optional: name of sender. If left blank, or =0, a generic name is used */
sender_name=' '
/* ============ DO NOT CHANGE BELOW HERE ===================== */
/* args sent here:
post_filter_message,source0,request0,seloriginal,tempfile,
servername,HOST_NICKNAME,used_file,thereferer,tcache
*/
parse arg amessage,source,request,sel,tempfile,servername,host_nickname,used_file,thereferer
parse var source serveraddr serverport transaction_number clientaddr clientport
GATEWAY=' '
AFF='SREF_'||SERVERPORT||'_SMTP_GATEWAY'
IF HOST_NICKNAME<>' ' THEN do
AFF2=AFF2||'.'||HOST_NICKNAME
GATEWAY=VALUE(AFF2,,'OS2ENVIRONMENT')
end
IF GATEWAY=' ' THEN
GATEWAY=VALUE(AFF,,'OS2ENVIRONMENT')
if symbol('VERBOSE')<>'VAR' then verbose=0
if symbol('sender_name')<>'VAR' then sender_name=' '
if sender_name=0 then sender_name=' '
if gateway=0 then do /* if no gateway specified, do nothing */
/* call say_stuff*/ /* enable this to get simple pmprintf output */
call pmprintf_sref(' POSTMAIL: No gateway specified ')
signal off error ; signal off syntax
return ' '
end
if events.0=0 then do
/* call say_stuff*/ /* enable this to get simple pmprintf output */
end
sname=servername
cname=clientaddr
alphapos=verify(cNAME,'1234567890.')
if alphapos=0 then do /* is numeric ip */
astat=sockgethostbyaddr(clientaddr,'stuff.!')
cname=upper(stuff.!name)
if abbrev(cname,'STUFF.!')=1 then cname=clientaddr
end
atime=time()
adate=date()
CRLF = '0d0a'x
/* loop through events list .. */
didit=0
do jj=1 to events.0
if symbol('EVENTS.TYPE.'||jj)<>'VAR' then do
if verbose>0 then call pmprintf_sref(" POSTMAIL warning: EVENTS.TYPE."jj" not specified. ")
iterate
end
if symbol('EVENTS.VALUE.'||jj)<>'VAR' then do
if verbose>0 then call pmprintf_sref(" POSTMAIL warning: EVENTS.VALUE."jj" not specified. ")
iterate
end
ok=0
if events.TYPE.jj="CLIENT" then do
ool=verify(events.value.jj,'1234567890*.')
if ool=0 then
ok=goodip(events.VALUE.jj,clientaddr)
else
ok=goodip(events.VALUE.jj,cname)
end
if events.type.jj='REQUEST' then do
if events.type.jj='REQUEST' then do
ok=goodsel(upper(events.value.jj),upper(sel))
end
end
if ok=0 then iterate
if didit=0 & verbose>0 then call pmprintf_sref(" Using gateway at " gateway)
didit=1
/* if here, a match occurred */
address_list=events.recipients.jj
if symbol('events.subject.jj')='VAR' then
asubject='Subject: '||events.subject.jj
else
asubject='Subject: Notification of WEB transaction '
themessage="Date: " || adate || ' ' ||atime
if sender_name=' ' then
themessage=themessage||crlf||'From: WebServer@'||sname
else
themessage=themessage||crlf||'From: 'sender_name
themessage=themessage||crlf||asubject
themessage=themessage||crlf||'To: '||address_list||crlf
themessage=themessage||crlf||'An e-mail alert from the Web Server at '||sname
themessage=themessage||crlf||" Date of occurrence: " || adate || ' ' ||atime
themessage=themessage||crlf||' Request by client: '|| cname
themessage=themessage||crlf||' Request selector: '|| sel
themessage=themessage||crlf||' Server status message: '|| amessage
if symbol('events.message.jj')='VAR' then /* check for a mess up */
themessage=themessage||crlf||"Notes:"||crlf||events.message.jj||crlf
else
themessage=themessage||crlf
foo=a_mailit(address_list,themessage, gateway,sender_name,verbose)
if verbose>0 then call pmprintf_sref(" Event " jj ", MAILIT status: "foo)
end /* try next event */
signal off error ; signal off syntax
return ' '
/* -----------------------------------------------------------------------*/
/* see if match (or abbreviation match) the sel */
/* -----------------------------------------------------------------------*/
goodsel: procedure
parse arg asel,thesel
asel=translate(asel) ; thesel=translate(thesel)
asel=translate(asel,'\','/') ; asel=strip(asel,,'\')
thesel=translate(thesel,'\','/') ; thesel=strip(thesel,,'\')
if asel=thesel then return 1 /* exact match */
return a_wildcard(thesel,asel)
/* -----------------------------------------------------------------------*/
/* see if matches one of a set of good ips (1 if yes)*/
/* -----------------------------------------------------------------------*/
goodip: procedure
parse upper arg anips,cip0
parse var anips ip.1 '.' ip.2 '.' ip.3 '.' ip.4
parse var cip0 cip.1 '.' cip.2 '.' cip.3 '.' cip.4
match=1
do mm2=1 to 4
if ip.mm2="*" then iterate
if ip.mm2=cip.mm2 then iterate
match=0 /*if here, not a match */
leave
end
return match
/* A simple transaction recorder (used if no SMTP_GATEWAY specified */
say_stuff:
call pmprintf_sref(" - - - - - ")
call pmprintf_sref(time() ' ' date())
call pmprintf_sref(" Message= " amessage)
call pmprintf_sref(" Source= " source)
call pmprintf_sref( " Request= " request)
call pmprintf_sref( " Sel = " sel)
return
/********************************/
/* see if needle matches haystack (* wildcards permitted) */
a_wildcard:procedure /* needle,haystack */
parse arg tn ,tc
tn=strip(tn); tc=strip(tc)
if tn=tc then return 1 /* exact match */
/* check for wildcard */
astc=pos('*',tc)
if astc=0 then return 0 /* not a wildcard candidate */
if astc=1 then do
tc1=""
tn1=tc1
len1=0
end
else do
tc1=substr(tc,1,astc-1)
len1=length(tc1)
tn1=left(tn,len1)
end
if astc=length(tc) then do
tn2=""
tc2=""
len2=0
end
else do
tc2=substr(tc,astc+1)
len2=length(tc2)
tn2=right(tn,len2)
end
if tn1<>tc1 | tn2<>tc2 then /* not a wildcard match */
return 0
return 1 /* have a wildcard match */
/******/
/* here on error */
error2:
signal off syntax ; signal off error
call pmprintf_sref(' Error in POSTMAIL at line ' sigl)
return 0
/*******************************************************************
*******************************************************************
*******************************************************************/
/*
---------------- General notes ------------------------
SRE-FILTER call this procedure when the POST_FILTER variable is set to YES.
6 arguments are passed here:
amessage
source
request
sel0
tempfile
params
Amessage
is generated by SRE-FILTER, and indicates what SRE-FILTER did with this request.
Source,request,and sel0 are generated by GoServe, and contain:
Source
serveraddr serverport transaction_number clientaddr clientport
Request
verb uri protocol
Sel0
action '?' awords (?awords may not be present
Tempfile is set in SRE-FILTER
Tempfile
A temporary file name. It may have been used to construct the response, so you probably should
delete it first (use SYSFILEDELETE(TEMPFILE) ).
Params
Are optional parameters sent by SRE-FILTER. Currently, it contains the name of the
SMTP gateway (set in the SMTP_GATEWAY variable of SRE-FILTER).
Example:
message HTML File sent:/INDEX.HTM
Source 151.121.65.143 80 3 219.134.78.12 1026
request GET /sampask2.htm HTTP/1.0
sel0 sampask2.htm
tempfile D:/GOHTTP/$10.80
params mail.myprovider.net
Note on Amessage:
The folllowing lists the "messages" that SRE-FILTER may send. Note that the ||varname
means the value of Varname is appended to the message. Also note that when varname=SEL,
the SEL may be different then SEL0 (say, if a ~ replacement occurred).
Pre-filter used
Cached file sent: ||sel0
Bad HTTP Protocol
Unauthorized access
No client name found, access denied
Logon denied to non-inhouse user
Pre-filter used
Alias invoked permanent redirect
Alias invoked temporary redirect
Transfered non-data directory file
Access to file denied: ||sel
Ping request
CONTROL Statistics request
Host request
Control Moveaudit
Control Reset all
Variable display
!Special request denied: ||sel
Message box access
Message box access denied
Message box viewing
Special request processing unknown:||sel
HEAD request: Document not found: ||sel0
Head request
Document not found
Server is busy
Non-HTML File sent:||file
HTML File sent:||file
HTML File sent (with ssi):||file
Mappable image request:'||foo
GET request:||action
Server busy
POST error: too much data
POST error: could not read data
POST request:||sel
POST problem:||sel
CGI-BIN access||sel
**************************************************************************/
/* This is MAILIT: an SRE-FILTER procedure */
/* ============================================================================
MAILIT: A REXX procedure to mail a note to several recipients.
.
. Called as: status=mailit(address_list,message_string,smtp_gateway,optional_sender_address)
.
. address_list: A space delimited list of addresses
. message_string: A message string, that may contain CRLFs (and may be rather long)
. smtp_gateway: The address of your SMTP server
. optional_senders_address: The sender's address (optional)
. If sender's address is not given, it will be generated using the servername() function.
.
. Example:
. status=mailit("BOB@HIS.NET" , "This is my message ", "MAIL.MY.ORG" )
. or
. status= mailit("BOB@HIS.NET JILL@HER.COM " , "This is my message ", ,
. "MAIL.MY.ORG", "HARRY@MY.ORG")
.
.NOTES:
. SMTP gateway addresses.
. If you are using an INTERNET provider, use the POP or SMTP gateway address.
.
. If no such address is available, you can try running the OS/2 SENDMAIL program, and
. use your hostname as the SMTP gateway address.
. For example, assuming that SENDMAIL.UML is in c:\mptn\etc,
. before starting GoServe you should start sendmail with:
. [C:]START SENDMAIL -bd -q30m -Cc:\mptn\etc\sendmail.uml
. Alternatively, you can use AUTOSTART sendmail using the TCPCFG program.
.
. Note on recipient addresses:
. The message will be sent to each address. Since the addresses are
. sent and then the message, this allows for fairly rapid mailing to multiple
. individuals.
.
. Acknowledgment:
. This is a modification of a routine written by Dave Briccetti (see acknowledgment at
. bottom of file)
. It was modified by Daniel Hellerstein for use in SRE-FILTER. 4/96
.
.
============================================================================ */
a_mailit:
parse arg whotos , themessage , smtpaddress , sender_address,verbose
smtpaddress=strip(smtpaddress)
sender_address=strip(sender_address)
/* set some constants */
CRLF = '0d0a'x
TRUE = 1
FALSE = 0
REPLYTYPE_OK = '2' /* SMTP reply code first byte */
REPLY_START_MAIL_INPUT = '354' /* SMTP reply code */
if sender_address="" then do
sendinghost=servername()
sendinguser="WebServer"
sender_address=sendinguser||'@'||sendinghost
end
MailServer = smtpaddress /* Mail server, leave blank if you are connected through a LAN */
if \RxFuncQuery("SockLoadFuncs") then nop
else do
call RxFuncAdd "SockLoadFuncs","rxSock","SockLoadFuncs"
call SockLoadFuncs
end
if EstablishProtocol() = FALSE then
return 0
/* The protocol initiated, we'll now send the message to each
recipient */
call SendMsgToEachRecipient
/* QUIT ends the protocol */
CmdReply = TransactSmtpCommand(socket, 'QUIT', 1)
/* Close the socket */
call SockSoClose socket
return isgood
/* ========================================================================= */
SetConstants:
/* ========================================================================= */
return
/* ========================================================================= */
EstablishProtocol:
/* ========================================================================= */
socket = ConnectToMailServer(MailServer)
if socket <= 0 then
do
if verbose>0 then
call pmprintf_sref( 'Could not connect to mail server')
return FALSE
end
CmdReply = GetCmdReply(socket)
if left(CmdReply, 1) \= REPLYTYPE_OK then
do
if verbose>0 then
call pmprintf_sref( 'Could not establish protocol')
return FALSE
end
/* Send the extended hello, in case this SMTP server supports
SMTP extensions */
CmdReply = TransactSmtpCommand(socket, 'EHLO', 1)
SizeExtensionSupported = 0
if left(CmdReply, 1) = REPLYTYPE_OK then do
/* That worked, so enable extended SMTP processing. If
the response to the EHLO indicates support for SIZE,
enable our use of that feature */
SmtpExtensionsSupported = TRUE
if pos('250 SIZE', CmdReply) > 0 | pos('250-SIZE', CmdReply) > 0 then
SizeExtensionSupported = 1
end
else do
/* The server didn't recognize the EHLO so we'll go with
the regular HELO */
SmtpExtensionsSupported = FALSE
SizeExtensionSupported = FALSE
CmdReply = TransactSmtpCommand(socket, 'HELO', 1)
end
if left(CmdReply, 1) = REPLYTYPE_OK then
return TRUE
else
return FALSE
/* ========================================================================= */
SendMsgBody:
/* ========================================================================= */
/* DATA tells the server that the body of the message is coming. It
should reply with a code meaning "go ahead." */
CmdReply = TransactSmtpCommand(socket, 'DATA', 1)
if substr(CmdReply, 1, 3) = REPLY_START_MAIL_INPUT then
do
/* Send the data, followed by a '.' on a line by itself to
indicate the end of the message */
CmdReply = TransactSmtpCommand(socket, MsgFileContents || CRLF || '.', 0)
end
return
/* ========================================================================= */
SendMsgToEachRecipient:
/* ========================================================================= */
/*
MsgFileContents = charin(MessageFile, 1, chars(MessageFile))
call stream MessageFile, 'c', 'close'
*/
msgfilecontents=themessage
MsgFileContents = strip(MsgFileContents, 't', '1a'x)
/* Strip EOF */
/* MAIL FROM identifies the sender. The SIZE= extension
provides the size of the message, to allow the
server to quickly refuse messages bigger than it wants. */
MailFromCmd = 'MAIL FROM:' ||sender_address
isgood=1
if SizeExtensionSupported then
MailFromCmd = MailFromCmd ' SIZE=' || length(MsgFileContents)
CmdReply = TransactSmtpCommand(socket, MailFromCmd, 1)
if left(CmdReply, 1) = REPLYTYPE_OK then do
whotos=translate(whotos,' ','000d0a1a09'x)
do while whotos<> ""
parse var whotos whoto whotos
RecipientEmailAddress = strip(whoto)
if RecipientEmailAddress \= '' then /* RCPT identifies the intended recipient of the message */
CmdReply = TransactSmtpCommand(socket,,
"RCPT TO:" || RecipientEmailAddress, 1)
/*say " cmdreply " cmdreply*/
end /* do */
call SendMsgBody
end
else do
isgood=0
end
return
/* ========================================================================= */
ConnectToMailServer: procedure
/* ========================================================================= */
parse arg MailServer
socket = 0
/* Open a socket to the mail server. (The Sock* functions are
documented in the REXX Socket book in the Information folder
in the OS/2 System folder */
call SockInit
if SockGetHostByName(MailServer, 'host.!') = 0 then do
if verbose>0 then
call pmprintf_sref( 'Could not get host by name' errno' ' h_errno)
end
else do
socket = SockSocket('AF_INET','SOCK_STREAM',0)
address.!family = 'AF_INET'
address.!port = 25 /* the standard SMTP port */
address.!addr = host.!addr
if SockConnect(socket, 'address.!') = -1 then do
if verbose>0 then
call pmprintf_sref( 'Could not connect socket' errno' ' h_errno)
end
end
return socket
/* ========================================================================= */
GetCmdReply: procedure
/* ========================================================================= */
parse arg socket
CRLF = '0d0a'x
/* Receive the response to the SMTP command into a variable. Use
more than one socket read if necessary to collect the whole
response. */
if SockRecv(socket, 'CmdReply', 200) < 0 then do
if verbose>0 then
call pmprintf_sref('Error reading from socket' errno' ' h_errno)
exit 0
end
ReadCount = 1
MaxParts = 10
do while ReadCount < MaxParts & right(CmdReply, 2) \= CRLF
if SockRecv(socket, 'CmdReplyExtra', 200) < 0 then do
if verbose>0 then
call pmprintf_sref('Error reading from socket')
exit 0
end
CmdReply = CmdReply || CmdReplyExtra
ReadCount = ReadCount + 1
end
return CmdReply
/* ========================================================================= */
TransactSmtpCommand:
/* ========================================================================= */
parse arg socket, Cmd, SayCmd
/* Send a command to the SMTP server, echoing it to the display
if requested */
if SayCmd then
if verbose>0 then
call pmprintf_sref(" Command is " Cmd)
rc = SockSend(socket, Cmd || CRLF)
op=GetCmdReply(socket)
return op
/* ------------- Acknowledgement ------------------------------
Most of this e-mail routine was obtained from:
Send Email Message to a Mailing List Via SMTP, Using the REXX Socket Interface
Written by a novice REXX programmer
Dave Briccetti, November 1995
daveb@davebsoft.com, http://www.davebsoft.com
May be used for any purpose
Thanks to REXX expert <a href=http://www.quercus-sys.com>Charles Daney</a>
and internet expert David Singer for looking over the code
---------------------------------------------------------- */