| 
									
										
										
										
											2009-04-20 21:05:17 -04:00
										 |  |  | ! Copyright (C) 2007, 2009 Elie CHAFTARI, Dirk Vleugels, | 
					
						
							| 
									
										
										
										
											2009-04-17 18:52:41 -04:00
										 |  |  | ! Slava Pestov, Doug Coleman, Daniel Ehrenberg. | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | ! See http://factorcode.org/license.txt for BSD license. | 
					
						
							| 
									
										
										
										
											2009-04-20 21:05:17 -04:00
										 |  |  | USING: arrays namespaces make io io.encodings io.encodings.string | 
					
						
							|  |  |  | io.encodings.utf8 io.encodings.iana io.encodings.binary | 
					
						
							|  |  |  | io.encodings.ascii io.timeouts io.sockets io.sockets.secure io.crlf | 
					
						
							|  |  |  | kernel logging sequences combinators splitting assocs strings | 
					
						
							|  |  |  | math.order math.parser random system calendar summary calendar.format | 
					
						
							|  |  |  | accessors sets hashtables base64 debugger classes prettyprint words ;
 | 
					
						
							| 
									
										
										
										
											2010-02-26 16:28:38 -05:00
										 |  |  | FROM: namespaces => set ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | IN: smtp | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-07 02:03:27 -05:00
										 |  |  | SYMBOL: smtp-domain | 
					
						
							| 
									
										
										
										
											2008-11-30 11:12:08 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | SYMBOL: smtp-server | 
					
						
							|  |  |  | "localhost" 25 <inet> smtp-server set-global
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-11-30 14:53:13 -05:00
										 |  |  | SYMBOL: smtp-tls? | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-11-30 11:12:08 -05:00
										 |  |  | SYMBOL: smtp-read-timeout | 
					
						
							|  |  |  | 1 minutes smtp-read-timeout set-global
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | SINGLETON: no-auth | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TUPLE: plain-auth username password ;
 | 
					
						
							|  |  |  | C: <plain-auth> plain-auth | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | SYMBOL: smtp-auth | 
					
						
							|  |  |  | no-auth smtp-auth set-global
 | 
					
						
							| 
									
										
										
										
											2008-02-07 02:03:27 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-11 04:35:43 -04:00
										 |  |  | LOG: log-smtp-connection NOTICE ( addrspec -- )
 | 
					
						
							| 
									
										
										
										
											2008-02-07 02:03:27 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | : with-smtp-connection ( quot -- )
 | 
					
						
							| 
									
										
										
										
											2008-03-11 04:35:43 -04:00
										 |  |  |     smtp-server get
 | 
					
						
							|  |  |  |     dup log-smtp-connection | 
					
						
							| 
									
										
										
										
											2008-05-05 03:19:25 -04:00
										 |  |  |     ascii [ | 
					
						
							| 
									
										
										
										
											2008-02-07 18:07:43 -05:00
										 |  |  |         smtp-domain [ host-name or ] change
 | 
					
						
							| 
									
										
										
										
											2008-08-29 00:19:18 -04:00
										 |  |  |         smtp-read-timeout get timeouts | 
					
						
							| 
									
										
										
										
											2008-02-07 18:07:43 -05:00
										 |  |  |         call
 | 
					
						
							| 
									
										
										
										
											2008-05-05 03:19:25 -04:00
										 |  |  |     ] with-client ; inline
 | 
					
						
							| 
									
										
										
										
											2008-02-07 02:03:27 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-08-16 18:20:18 -04:00
										 |  |  | TUPLE: email | 
					
						
							|  |  |  |     { from string } | 
					
						
							|  |  |  |     { to array } | 
					
						
							| 
									
										
										
										
											2008-08-16 18:28:38 -04:00
										 |  |  |     { cc array } | 
					
						
							|  |  |  |     { bcc array } | 
					
						
							| 
									
										
										
										
											2008-08-16 18:20:18 -04:00
										 |  |  |     { subject string } | 
					
						
							| 
									
										
										
										
											2009-04-17 18:52:41 -04:00
										 |  |  |     { content-type string initial: "text/plain" } | 
					
						
							|  |  |  |     { encoding word initial: utf8 } | 
					
						
							| 
									
										
										
										
											2008-08-16 18:20:18 -04:00
										 |  |  |     { body string } ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-11-30 14:53:13 -05:00
										 |  |  | : <email> ( -- email ) email new ; inline
 | 
					
						
							| 
									
										
										
										
											2008-08-16 18:20:18 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-08-29 00:19:18 -04:00
										 |  |  | <PRIVATE
 | 
					
						
							| 
									
										
										
										
											2008-11-30 11:12:08 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-20 15:25:23 -04:00
										 |  |  | : command ( string -- ) write crlf flush ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-11-30 14:53:13 -05:00
										 |  |  | \ command DEBUG add-input-logging | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-11-30 11:12:08 -05:00
										 |  |  | : helo ( -- ) "EHLO " host-name append command ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-11-30 14:53:13 -05:00
										 |  |  | : start-tls ( -- ) "STARTTLS" command ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-08-16 15:20:13 -04:00
										 |  |  | ERROR: bad-email-address email ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-07 02:03:27 -05:00
										 |  |  | : validate-address ( string -- string' )
 | 
					
						
							|  |  |  |     #! Make sure we send funky stuff to the server by accident. | 
					
						
							| 
									
										
										
										
											2009-01-12 02:51:38 -05:00
										 |  |  |     dup "\r\n>" intersects? | 
					
						
							|  |  |  |     [ bad-email-address ] when ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-07 02:03:27 -05:00
										 |  |  | : mail-from ( fromaddr -- )
 | 
					
						
							| 
									
										
										
										
											2008-12-06 19:58:45 -05:00
										 |  |  |     validate-address | 
					
						
							|  |  |  |     "MAIL FROM:<" ">" surround command ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-07 02:03:27 -05:00
										 |  |  | : rcpt-to ( to -- )
 | 
					
						
							| 
									
										
										
										
											2008-12-06 19:58:45 -05:00
										 |  |  |     validate-address | 
					
						
							|  |  |  |     "RCPT TO:<" ">" surround command ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-07 02:03:27 -05:00
										 |  |  | : data ( -- )
 | 
					
						
							| 
									
										
										
										
											2008-03-20 15:25:23 -04:00
										 |  |  |     "DATA" command ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-08-16 15:20:13 -04:00
										 |  |  | ERROR: message-contains-dot message ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | M: message-contains-dot summary ( obj -- string )
 | 
					
						
							| 
									
										
										
										
											2008-11-30 11:12:08 -05:00
										 |  |  |     drop "Message cannot contain . on a line by itself" ;
 | 
					
						
							| 
									
										
										
										
											2008-08-16 15:20:13 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-07 02:03:27 -05:00
										 |  |  | : validate-message ( msg -- msg' )
 | 
					
						
							| 
									
										
										
										
											2008-08-16 15:20:13 -04:00
										 |  |  |     "." over member?
 | 
					
						
							|  |  |  |     [ message-contains-dot ] when ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-17 18:52:41 -04:00
										 |  |  | : send-body ( email -- )
 | 
					
						
							| 
									
										
										
										
											2009-04-20 21:05:17 -04:00
										 |  |  |     binary encode-output | 
					
						
							|  |  |  |     [ body>> ] [ encoding>> ] bi encode >base64-lines write
 | 
					
						
							|  |  |  |     ascii encode-output crlf | 
					
						
							| 
									
										
										
										
											2008-03-20 15:25:23 -04:00
										 |  |  |     "." command ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-07 02:03:27 -05:00
										 |  |  | : quit ( -- )
 | 
					
						
							| 
									
										
										
										
											2008-03-20 15:25:23 -04:00
										 |  |  |     "QUIT" command ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-07 18:07:43 -05:00
										 |  |  | LOG: smtp-response DEBUG | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-11 19:52:22 -05:00
										 |  |  | : multiline? ( response -- ? )
 | 
					
						
							| 
									
										
										
										
											2008-11-30 14:53:13 -05:00
										 |  |  |     3 swap ?nth CHAR: - = ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : (receive-response) ( -- )
 | 
					
						
							|  |  |  |     read-crlf | 
					
						
							|  |  |  |     [ , ] | 
					
						
							|  |  |  |     [ smtp-response ] | 
					
						
							|  |  |  |     [ multiline? [ (receive-response) ] when ] | 
					
						
							|  |  |  |     tri ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TUPLE: response code messages ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : <response> ( lines -- response )
 | 
					
						
							|  |  |  |     [ first 3 head string>number ] keep response boa ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : receive-response ( -- response )
 | 
					
						
							|  |  |  |     [ (receive-response) ] { } make <response> ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ERROR: smtp-error response ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | M: smtp-error error. | 
					
						
							|  |  |  |     "SMTP error (" write dup class pprint ")" print
 | 
					
						
							|  |  |  |     response>> messages>> [ print ] each ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-08-16 15:14:20 -04:00
										 |  |  | ERROR: smtp-server-busy < smtp-error ;
 | 
					
						
							|  |  |  | ERROR: smtp-syntax-error < smtp-error ;
 | 
					
						
							|  |  |  | ERROR: smtp-command-not-implemented < smtp-error ;
 | 
					
						
							|  |  |  | ERROR: smtp-bad-authentication < smtp-error ;
 | 
					
						
							|  |  |  | ERROR: smtp-mailbox-unavailable < smtp-error ;
 | 
					
						
							|  |  |  | ERROR: smtp-user-not-local < smtp-error ;
 | 
					
						
							|  |  |  | ERROR: smtp-exceeded-storage-allocation < smtp-error ;
 | 
					
						
							|  |  |  | ERROR: smtp-bad-mailbox-name < smtp-error ;
 | 
					
						
							|  |  |  | ERROR: smtp-transaction-failed < smtp-error ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | : check-response ( response -- )
 | 
					
						
							| 
									
										
										
										
											2008-11-30 14:53:13 -05:00
										 |  |  |     dup code>> { | 
					
						
							|  |  |  |         { [ dup { 220 235 250 221 354 } member? ] [ 2drop ] } | 
					
						
							|  |  |  |         { [ dup 400 499 between? ] [ drop smtp-server-busy ] } | 
					
						
							|  |  |  |         { [ dup 500 = ] [ drop smtp-syntax-error ] } | 
					
						
							|  |  |  |         { [ dup 501 = ] [ drop smtp-command-not-implemented ] } | 
					
						
							|  |  |  |         { [ dup 500 509 between? ] [ drop smtp-syntax-error ] } | 
					
						
							|  |  |  |         { [ dup 530 539 between? ] [ drop smtp-bad-authentication ] } | 
					
						
							|  |  |  |         { [ dup 550 = ] [ drop smtp-mailbox-unavailable ] } | 
					
						
							|  |  |  |         { [ dup 551 = ] [ drop smtp-user-not-local ] } | 
					
						
							|  |  |  |         { [ dup 552 = ] [ drop smtp-exceeded-storage-allocation ] } | 
					
						
							|  |  |  |         { [ dup 553 = ] [ drop smtp-bad-mailbox-name ] } | 
					
						
							|  |  |  |         { [ dup 554 = ] [ drop smtp-transaction-failed ] } | 
					
						
							|  |  |  |         [ drop smtp-error ] | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |     } cond ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-20 15:25:23 -04:00
										 |  |  | : get-ok ( -- ) receive-response check-response ;
 | 
					
						
							| 
									
										
										
										
											2008-02-07 02:03:27 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-11-30 11:12:08 -05:00
										 |  |  | GENERIC: send-auth ( auth -- )
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | M: no-auth send-auth drop ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-11-30 14:53:13 -05:00
										 |  |  | : plain-auth-string ( username password -- string )
 | 
					
						
							|  |  |  |     [ "\0" prepend ] bi@ append utf8 encode >base64 ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-11-30 11:12:08 -05:00
										 |  |  | M: plain-auth send-auth | 
					
						
							| 
									
										
										
										
											2008-11-30 14:53:13 -05:00
										 |  |  |     [ username>> ] [ password>> ] bi plain-auth-string | 
					
						
							|  |  |  |     "AUTH PLAIN " prepend command get-ok ;
 | 
					
						
							| 
									
										
										
										
											2008-11-30 11:12:08 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-11-30 14:53:13 -05:00
										 |  |  | : auth ( -- ) smtp-auth get send-auth ;
 | 
					
						
							| 
									
										
										
										
											2008-11-30 11:12:08 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-13 20:13:01 -05:00
										 |  |  | : encode-header ( string -- string' )
 | 
					
						
							|  |  |  |     dup aux>> [ | 
					
						
							| 
									
										
										
										
											2009-04-18 22:53:22 -04:00
										 |  |  |         utf8 encode >base64 | 
					
						
							|  |  |  |         "=?utf-8?B?" "?=" surround
 | 
					
						
							| 
									
										
										
										
											2009-01-13 20:13:01 -05:00
										 |  |  |     ] when ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-08-16 15:20:13 -04:00
										 |  |  | ERROR: invalid-header-string string ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-07 02:03:27 -05:00
										 |  |  | : validate-header ( string -- string' )
 | 
					
						
							| 
									
										
										
										
											2009-01-12 02:51:38 -05:00
										 |  |  |     dup "\r\n" intersects? | 
					
						
							|  |  |  |     [ invalid-header-string ] when ;
 | 
					
						
							| 
									
										
										
										
											2008-02-07 02:03:27 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-07 02:55:38 -05:00
										 |  |  | : write-header ( key value -- )
 | 
					
						
							| 
									
										
										
										
											2008-08-16 18:20:18 -04:00
										 |  |  |     [ validate-header write ] | 
					
						
							| 
									
										
										
										
											2009-01-13 20:13:01 -05:00
										 |  |  |     [ ": " write validate-header encode-header write ] bi* crlf ;
 | 
					
						
							| 
									
										
										
										
											2008-03-07 02:55:38 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | : write-headers ( assoc -- )
 | 
					
						
							|  |  |  |     [ write-header ] assoc-each ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-07 02:03:27 -05:00
										 |  |  | : message-id ( -- string )
 | 
					
						
							|  |  |  |     [ | 
					
						
							|  |  |  |         "<" % | 
					
						
							| 
									
										
										
										
											2008-03-20 00:29:35 -04:00
										 |  |  |         64 random-bits # | 
					
						
							| 
									
										
										
										
											2008-02-07 02:03:27 -05:00
										 |  |  |         "-" % | 
					
						
							| 
									
										
										
										
											2010-06-22 03:04:31 -04:00
										 |  |  |         gmt timestamp>micros # | 
					
						
							| 
									
										
										
										
											2008-02-07 02:03:27 -05:00
										 |  |  |         "@" % | 
					
						
							| 
									
										
										
										
											2008-04-24 21:13:18 -04:00
										 |  |  |         smtp-domain get [ host-name ] unless* % | 
					
						
							| 
									
										
										
										
											2008-02-07 02:03:27 -05:00
										 |  |  |         ">" % | 
					
						
							|  |  |  |     ] "" make ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-08-16 18:20:18 -04:00
										 |  |  | : extract-email ( recepient -- email )
 | 
					
						
							| 
									
										
										
										
											2008-08-29 00:19:18 -04:00
										 |  |  |     ! This could be much smarter. | 
					
						
							| 
									
										
										
										
											2008-11-22 21:00:37 -05:00
										 |  |  |     " " split1-last swap or "<" ?head drop ">" ?tail drop ;
 | 
					
						
							| 
									
										
										
										
											2008-02-07 02:03:27 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-17 18:52:41 -04:00
										 |  |  | : email-content-type ( email -- content-type )
 | 
					
						
							|  |  |  |     [ content-type>> ] [ encoding>> encoding>name ] bi "; charset=" glue ;
 | 
					
						
							| 
									
										
										
										
											2009-01-13 20:13:01 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-17 18:52:41 -04:00
										 |  |  | : email>headers ( email -- assoc )
 | 
					
						
							| 
									
										
										
										
											2008-08-16 18:20:18 -04:00
										 |  |  |     [ | 
					
						
							| 
									
										
										
										
											2009-04-17 18:52:41 -04:00
										 |  |  |         now timestamp>rfc822 "Date" set
 | 
					
						
							|  |  |  |         message-id "Message-Id" set
 | 
					
						
							|  |  |  |         "1.0" "MIME-Version" set
 | 
					
						
							| 
									
										
										
										
											2009-04-19 04:04:35 -04:00
										 |  |  |         "base64" "Content-Transfer-Encoding" set
 | 
					
						
							| 
									
										
										
										
											2008-08-16 18:28:38 -04:00
										 |  |  |         { | 
					
						
							|  |  |  |             [ from>> "From" set ] | 
					
						
							|  |  |  |             [ to>> ", " join "To" set ] | 
					
						
							| 
									
										
										
										
											2008-08-17 10:37:04 -04:00
										 |  |  |             [ cc>> ", " join [ "Cc" set ] unless-empty ] | 
					
						
							| 
									
										
										
										
											2008-08-16 18:28:38 -04:00
										 |  |  |             [ subject>> "Subject" set ] | 
					
						
							| 
									
										
										
										
											2009-04-17 18:52:41 -04:00
										 |  |  |             [ email-content-type "Content-Type" set ] | 
					
						
							| 
									
										
										
										
											2008-08-16 18:28:38 -04:00
										 |  |  |         } cleave
 | 
					
						
							| 
									
										
										
										
											2009-04-17 18:52:41 -04:00
										 |  |  |     ] { } make-assoc ;
 | 
					
						
							| 
									
										
										
										
											2008-08-16 18:20:18 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : (send-email) ( headers email -- )
 | 
					
						
							|  |  |  |     [ | 
					
						
							| 
									
										
										
										
											2008-11-30 14:53:13 -05:00
										 |  |  |         get-ok | 
					
						
							| 
									
										
										
										
											2008-08-16 18:20:18 -04:00
										 |  |  |         helo get-ok | 
					
						
							| 
									
										
										
										
											2008-11-30 14:53:13 -05:00
										 |  |  |         smtp-tls? get [ start-tls get-ok send-secure-handshake ] when
 | 
					
						
							| 
									
										
										
										
											2008-11-30 11:12:08 -05:00
										 |  |  |         auth | 
					
						
							| 
									
										
										
										
											2008-08-16 18:20:18 -04:00
										 |  |  |         dup from>> extract-email mail-from get-ok | 
					
						
							|  |  |  |         dup to>> [ extract-email rcpt-to get-ok ] each
 | 
					
						
							| 
									
										
										
										
											2008-08-16 18:28:38 -04:00
										 |  |  |         dup cc>> [ extract-email rcpt-to get-ok ] each
 | 
					
						
							|  |  |  |         dup bcc>> [ extract-email rcpt-to get-ok ] each
 | 
					
						
							| 
									
										
										
										
											2008-08-16 18:20:18 -04:00
										 |  |  |         data get-ok | 
					
						
							|  |  |  |         swap write-headers | 
					
						
							|  |  |  |         crlf | 
					
						
							| 
									
										
										
										
											2009-04-17 18:52:41 -04:00
										 |  |  |         send-body get-ok | 
					
						
							| 
									
										
										
										
											2008-08-16 18:20:18 -04:00
										 |  |  |         quit get-ok | 
					
						
							|  |  |  |     ] with-smtp-connection ;
 | 
					
						
							| 
									
										
										
										
											2008-11-30 11:12:08 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-08-29 00:19:18 -04:00
										 |  |  | PRIVATE>
 | 
					
						
							| 
									
										
										
										
											2008-02-07 02:03:27 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-11 04:35:43 -04:00
										 |  |  | : send-email ( email -- )
 | 
					
						
							| 
									
										
										
										
											2008-08-16 18:20:18 -04:00
										 |  |  |     [ email>headers ] keep (send-email) ;
 |