# pop3-lib.rb -*- ruby -*- # # Copyright (C) 1998 by Takaaki Tateishi # License: GNU General Public License version 2 (GPL2) # Require: ruby-1.3 # Modified at: <1999/4/23 23:26:45 by ttate> # Changes: # 1999/3/27 last_get,last_put was added # # Note: # This library don't use the timeout. If you need, do "require 'timeout'". # (example) # require 'timeout' # begin # timeout(5){ # pop = POP3.open("yourhost") # } # rescue TimeoutError # .... # end require "socket" class POP3Error < StandardError; end class POP3 PORT = 110 CRLF = "\r\n" EOL = "\n" attr_reader :last_get, :last_put # initialize # host: POP3 Host Name # port: POP3 Port Number def initialize(host,port=PORT) @last_get = '' @last_put = '' @socket = TCPsocket.open(host,port) ans = gets if( ! ok?(ans) ) raise(POP3Error,"can't initialize") end end # open(=new) def POP3.open(host,port=PORT) new(host,port) end def puts(message) @socket.write(message+CRLF) @socket.flush @last_put = message 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) end if( message[0,1] == "." ) if( message[1,2] != CRLF ) message = message[1,message.length-1] else message = nil end end if( message ) if( message[-1,1] == "\n" ) message.chop! end if( message[-1,1] == "\r" ) message.chop! end end @last_get = message message end private :gets def gets2 loop = true messages = [] while( line = gets ) messages.push(line) end return messages end private :gets2 def ok?(answer) result = false if( answer[0,3] == "+OK" ) result = true else result = false end return result end private :ok? def login(user, passwd) result = false puts("USER "+user) ans = gets if( ok?(ans) ) puts("PASS "+passwd) ans = gets if( ok?(ans) ) result = true end end return result end def close result = false puts("QUIT") ans = gets if( ok?(ans) ) result = true end @socket.close return result end # get_count: get the count of mails def get_count count = nil puts("STAT") ans = gets if( ok?(ans) ) anslist = ans.split(/ +/) count = anslist[1].to_i end return count end # get_list: Get the mail number which is not marked for deleting def get_list maillist = [] puts("LIST") ans = gets if( ok?(ans) ) if ( msg = gets2 ) msg.each{|line| linelist = line.split(/ +/) if( linelist[0] != nil ) maillist.push(linelist[0]) end } end else maillist = nil end return maillist end def get_mail_as_list(num) contents = nil puts("RETR "+num.to_s) ans = gets if( ok?(ans) ) contents = gets2 else contents = nil end return contents end # get_mail: Get the mail body(if fault,return nil) # num: mail number def get_mail(num, eol=EOL) contents = nil if( contents = get_mail_as_list(num) ) contents = contents.join(eol) end return contents end # delete: Mark the mail for deleting # num: mail number def delete(num) result = false puts("DELE "+num.to_s) ans = gets if( ok?(ans) ) result = true end return result end # reset: reset the mark def reset result = false puts("RSET") ans = gets if( ok?(ans) ) result = true end return result end end