# smtp-lib.rb -*- ruby -*- # # Copyright (C) 1998 by Takaaki Tateishi # License: GNU General Public License (GPL2) # Modified at: <1999/4/23 23:27:47 by ttate> # Require: ruby-1.3 # Changes: # 1999/03/27 last_get,last_put was added. # # Note: # This library don't use the timeout. If you need, do "require 'timeout'". # (e.g) # require 'timeout' # begin # timeout(5){ # smtp = SMTP.open("yourhost") # } # rescue TimeoutError # ... # end require "socket" class SMTPError < StandardError; end class SMTP PORT = 25 CRLF = "\r\n" EOL = "\n" attr_reader :last_get, :last_put # initialize: but not login # host: SMTP Server Host Name # port: SMTP Port Number def initialize(host,port=PORT) @last_get = "" @last_put = "" @socket = TCPsocket.open(host,port) ans = gets2 if( ! ok?(ans) ) @socket.close raise(SMTPError,"can't initialize.") end super end # open(=new) def SMTP.open(host,port=PORT) new(host,port) end def puts(message) if( ! message ) @socket.write("."+CRLF) @socket.flush @last_put = "." else if( message[0,1] == "." ) message = "." + message end @socket.write(message+CRLF) @socket.flush @last_put = message end if( $DEBUG ) STDERR.print("puts:"+message.to_s+EOL) end end private :puts def gets message = @socket.gets if( $DEBUG ) STDERR.print("gets:"+message.to_s+EOL) end message.chop! @last_get = message message end private :gets def gets2 message = "" line = gets message = line if( line[3,1] == '-' ) loop = true while( loop ) line = gets message = message + EOL + line if( line[3,1] != '-' ) loop = false end end end @last_get = message return message end private :gets2 def ok?(answer) result = true answer.each_line(EOL){|line| if( (line[0,1] != '2')&&(line[0,1] != '3') ) if( result == true ) result = false end end } return result end private :ok? # hello: =login def hello(host,address=nil) result = false puts("HELO "+host) ans = gets2 if( ok?(ans) ) if( address != nil ) puts("MAIL FROM:<"+address+">") ans = gets2 if( ok?(ans) ) result = true end else result = true end end return result end # login: login to the SMTP Server def login(host,address=nil) hello(host,address) end def from(address) result = false puts("MAIL FROM:<"+address+">") ans = gets2 if( ok?(ans) ) result = true end return result end def close result = false puts("QUIT") ans = gets2 if( ok?(ans) ) result = true end @socket.close return result end # rcpt: set the addresses to send # addresses: address list def rcpt(*addresses) result = true addresses.each{|address| puts("RCPT TO:<"+address+">") ans = gets2 if( ! ok?(ans) ) result = false end } return result end # mail: send a mail # header: mail header # body: mail body def mail(header,body) result = false if( (! header.is_a?(String)) or (! body.is_a?(String)) ) raise(SMTPError,"mail body must be a kind of String.") end puts("DATA") ans = gets2 if( ok?(ans) ) header.each_line{|line| if( line[-1,1] == "\n" ) line.chop! end if( line[-1,1] == "\r" ) line.chop! end puts(line) } puts("") body.each_line{|line| if( line[-1,1] == "\n" ) line.chop! end if( line[-1,1] == "\r" ) line.chop! end puts(line) } puts(nil) ans = gets2 if( ok?(ans) ) result = true end end return result end # data: =mail def data(header,body) mail(header,body) end end