home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Spezial / SPEZIAL2_97.zip / SPEZIAL2_97.iso / ANWEND / ONLINE / SREFPRC1 / MAILIT.SRF < prev    next >
Text File  |  1997-05-15  |  9KB  |  307 lines

  1. /* This is MAILIT: an SRE-FILTER procedure */
  2. /* ============================================================================ 
  3. MAILIT: A  REXX procedure to mail a note to several recipients.
  4. .
  5. .  Called as:  status=mailit(address_list,message_string,smtp_gateway,optional_sender_address)
  6. .
  7. . address_list: A space delimited list of addresses
  8. . message_string: A message string, that may contain CRLFs (and may be rather long)
  9. . smtp_gateway: The address of your SMTP server 
  10. . optional_senders_address: The sender's address (optional)
  11. .        If sender's address is not given, it will be generated using the servername() function.
  12. .
  13. . Example:
  14. . status=mailit("BOB@HIS.NET" , "This is my message ", "MAIL.MY.ORG" )
  15. .    or
  16. . status= mailit("BOB@HIS.NET JILL@HER.COM " , "This is my message ", ,
  17. .             "MAIL.MY.ORG", "HARRY@MY.ORG")
  18. .
  19. .NOTES:
  20. . SMTP gateway addresses.
  21. .   If you are using an INTERNET provider, use the POP or SMTP gateway address.
  22. .
  23. .   If no such address is available, you can try running the OS/2 SENDMAIL program, and
  24. .   use your hostname as the SMTP gateway address.
  25. .   For example, assuming that SENDMAIL.UML is in c:\mptn\etc,
  26. .   before starting GoServe you should   start sendmail with:
  27. .       [C:]START SENDMAIL -bd -q30m -Cc:\mptn\etc\sendmail.uml
  28. .   Alternatively, you can use AUTOSTART sendmail using the TCPCFG program.
  29. .
  30. . Note on recipient addresses:
  31. .    The message will be sent to each address.  Since the addresses are
  32. .    sent and then the message, this allows for fairly rapid mailing to multiple
  33. .    individuals.
  34. .
  35. . Acknowledgment:
  36. .     This is a modification of a routine written by Dave Briccetti (see acknowledgment at
  37. .     bottom of file)
  38. .     It was modified by Daniel Hellerstein for use in SRE-FILTER. 4/96
  39. .
  40. .
  41. ============================================================================ */
  42.  
  43. sref_mailit:
  44. parse arg whotos , themessage  , smtpaddress , sender_address,verbose
  45.  
  46. smtpaddress=strip(smtpaddress)
  47. sender_address=strip(sender_address)
  48.  
  49. /* set some constants */
  50. CRLF                    = '0d0a'x
  51. TRUE                    = 1
  52. FALSE                   = 0
  53. REPLYTYPE_OK            = '2'   /* SMTP reply code first byte */
  54. REPLY_START_MAIL_INPUT  = '354' /* SMTP reply code */
  55.  
  56. if sender_address="" then do
  57.    sendinghost=servername()
  58.    sendinguser="WebServer"
  59.    sender_address=sendinguser||'@'||sendinghost
  60. end
  61.  
  62. MailServer  = smtpaddress  /* Mail server, leave blank if you are connected through a LAN */
  63.  
  64. if \RxFuncQuery("SockLoadFuncs") then nop
  65. else do
  66.        call RxFuncAdd "SockLoadFuncs","rxSock","SockLoadFuncs"
  67.        call SockLoadFuncs
  68. end
  69.  
  70.  
  71. if EstablishProtocol() = FALSE then
  72.     return 0
  73.  
  74. /* The protocol initiated, we'll now send the message to each
  75.    recipient */
  76.  
  77. call SendMsgToEachRecipient
  78.  
  79. /* QUIT ends the protocol */
  80.     
  81. CmdReply = TransactSmtpCommand(socket, 'QUIT', 1)
  82.  
  83. /* Close the socket */
  84.     
  85. call SockSoClose socket
  86.  
  87. return 1
  88.  
  89.  
  90. /* ========================================================================= */
  91. SetConstants:
  92. /* ========================================================================= */
  93.  
  94. return
  95.  
  96.  
  97. /* ========================================================================= */
  98. EstablishProtocol:
  99. /* ========================================================================= */
  100.  
  101. socket = ConnectToMailServer(MailServer)    
  102. if socket <= 0 then 
  103. do
  104.     if verbose>1 then 
  105.           say 'Could not connect to mail server'
  106.     return FALSE
  107. end
  108.  
  109. CmdReply = GetCmdReply(socket)
  110.  
  111. if left(CmdReply, 1) \= REPLYTYPE_OK then 
  112. do
  113.     if verbose>1 then 
  114.           say 'Could not establish protocol'
  115.     return FALSE
  116. end
  117.  
  118. /* Send the extended hello, in case this SMTP server supports
  119.    SMTP extensions */
  120.         
  121. CmdReply = TransactSmtpCommand(socket, 'EHLO', 1)
  122.         
  123. SizeExtensionSupported = 0
  124.  
  125. if left(CmdReply, 1) = REPLYTYPE_OK then 
  126. do
  127.     /* That worked, so enable extended SMTP processing.  If
  128.        the response to the EHLO indicates support for SIZE,
  129.        enable our use of that feature */
  130.               
  131.     SmtpExtensionsSupported = TRUE
  132.     if pos('250 SIZE', CmdReply) > 0 | pos('250-SIZE', CmdReply) > 0 then
  133.         SizeExtensionSupported = 1
  134. end
  135. else
  136. do
  137.     /* The server didn't recognize the EHLO so we'll go with
  138.        the regular HELO */
  139.               
  140.     SmtpExtensionsSupported = FALSE
  141.     SizeExtensionSupported  = FALSE
  142.     CmdReply = TransactSmtpCommand(socket, 'HELO', 1)
  143. end
  144.  
  145. if left(CmdReply, 1) = REPLYTYPE_OK then 
  146.     return TRUE
  147. else
  148.     return FALSE
  149.  
  150.  
  151. /* ========================================================================= */
  152. SendMsgBody: 
  153. /* ========================================================================= */
  154.  
  155. /* DATA tells the server that the body of the message is coming.  It
  156.    should reply with a code meaning "go ahead." */
  157.  
  158. CmdReply = TransactSmtpCommand(socket, 'DATA', 1)
  159. if substr(CmdReply, 1, 3) = REPLY_START_MAIL_INPUT then 
  160. do
  161.     /* Send the data, followed by a '.' on a line by itself to 
  162.        indicate the end of the message */
  163.     CmdReply = TransactSmtpCommand(socket, MsgFileContents || CRLF || '.', 0)
  164. end
  165.  
  166. return
  167.  
  168.  
  169. /* ========================================================================= */
  170. SendMsgToEachRecipient:
  171. /* ========================================================================= */
  172.  
  173. /*
  174. MsgFileContents = charin(MessageFile, 1, chars(MessageFile))
  175. call stream MessageFile, 'c', 'close'
  176. */
  177.  
  178. msgfilecontents=themessage
  179. MsgFileContents = strip(MsgFileContents, 't', '1a'x) 
  180.   /* Strip EOF */
  181.  
  182.         
  183. /* MAIL FROM identifies the sender.  The SIZE= extension
  184.    provides the size of the message, to allow the 
  185.    server to quickly refuse messages bigger than it wants. */
  186.            
  187. MailFromCmd = 'MAIL FROM:' ||sender_address
  188.  
  189. if SizeExtensionSupported then
  190.     MailFromCmd = MailFromCmd 'SIZE=' || length(MsgFileContents)
  191.     
  192. CmdReply = TransactSmtpCommand(socket, MailFromCmd, 1)
  193.  
  194.  
  195.  
  196. if left(CmdReply, 1) = REPLYTYPE_OK then
  197.   whotos=translate(whotos,' ','000d0a1a09'x)
  198.   do while whotos<> ""
  199.      parse var whotos whoto whotos
  200.  
  201.      RecipientEmailAddress = strip(whoto)
  202.      if RecipientEmailAddress \= '' then    /* RCPT identifies the intended recipient of the message */
  203.          CmdReply = TransactSmtpCommand(socket,,
  204.                          "RCPT TO:" || RecipientEmailAddress, 1)
  205. /*say " cmdreply " cmdreply*/
  206.   end /* do */
  207.  
  208. call SendMsgBody
  209.  
  210. return
  211.  
  212.  
  213. /* ========================================================================= */
  214. ConnectToMailServer: procedure
  215. /* ========================================================================= */
  216.  
  217. parse arg MailServer
  218. socket = 0
  219.  
  220. /* Open a socket to the mail server.  (The Sock* functions are
  221.    documented in the REXX Socket book in the Information folder
  222.    in the OS/2 System folder */
  223.  
  224. call SockInit
  225. if SockGetHostByName(MailServer, 'host.!') = 0 then do
  226.     if verbose>1 then 
  227.          say 'Could not get host by name' errno h_errno
  228. end
  229. else do
  230.     socket = SockSocket('AF_INET','SOCK_STREAM',0)
  231.     address.!family = 'AF_INET'
  232.     address.!port = 25          /* the standard SMTP port */
  233.     address.!addr = host.!addr
  234.     if SockConnect(socket, 'address.!') = -1 then  do
  235.       if verbose>1 then
  236.             say 'Could not connect socket' errno h_errno
  237.     end
  238. end
  239. return socket
  240.  
  241.  
  242. /* ========================================================================= */
  243. GetCmdReply: procedure
  244. /* ========================================================================= */
  245.  
  246. parse arg socket
  247.  
  248. CRLF = '0d0a'x
  249.  
  250. /* Receive the response to the SMTP command into a variable.  Use
  251.    more than one socket read if necessary to collect the whole 
  252.    response. */
  253.    
  254. if SockRecv(socket, 'CmdReply', 200) < 0 then do
  255.     if verbose>1 then 
  256.           say 'Error reading from socket' errno h_errno
  257.     exit 0
  258. end
  259.  
  260. ReadCount = 1
  261. MaxParts = 10
  262.  
  263. do while ReadCount < MaxParts & right(CmdReply, 2) \= CRLF  
  264.     if SockRecv(socket, 'CmdReplyExtra', 200) < 0 then do
  265.         if verbose>0 then 
  266.            say 'Error reading from socket'
  267.         exit 0
  268.     end
  269.     CmdReply = CmdReply || CmdReplyExtra
  270.     ReadCount = ReadCount + 1
  271. end
  272.  
  273. return CmdReply
  274.  
  275.  
  276. /* ========================================================================= */
  277. TransactSmtpCommand: 
  278. /* ========================================================================= */
  279.  
  280. parse arg socket, Cmd, SayCmd
  281.  
  282. /* Send a command to the SMTP server, echoing it to the display
  283.    if requested */
  284.  
  285. if SayCmd then 
  286.     if verbose>1 then 
  287.            say " Command is "  Cmd
  288. rc = SockSend(socket, Cmd || CRLF)
  289. return GetCmdReply(socket)
  290.  
  291.  
  292. /* ------------- Acknowledgement  ------------------------------
  293. Most of this e-mail routine was obtained from:
  294.  
  295. Send Email Message to a Mailing List Via SMTP, Using the REXX Socket Interface
  296. Written by a novice REXX programmer
  297.      Dave Briccetti, November 1995
  298.      daveb@davebsoft.com, http://www.davebsoft.com
  299.  
  300.   May be used for any purpose
  301.   Thanks to REXX expert <a href=http://www.quercus-sys.com>Charles Daney</a>
  302.   and internet expert David Singer for looking over the code
  303. ----------------------------------------------------------    */
  304.  
  305.  
  306.  
  307.