# = net/pop.rb
#
# Copyright (c) 1999-2007 Yukihiro Matsumoto.
#
# Copyright (c) 1999-2007 Minero Aoki.
#
# Written & maintained by Minero Aoki <aamine@loveruby.net>.
#
# Documented by William Webber and Minero Aoki.
#
# This program is free software. You can re-distribute and/or
# modify this program under the same terms as Ruby itself,
# Ruby Distribute License.
#
# NOTE: You can find Japanese version of this document at:
# http://www.ruby-lang.org/ja/man/html/net_pop.html
#
# $Id$
#
# See Net::POP3 for documentation.
#
require 'net/protocol'
require 'digest/md5'
require 'timeout'
begin
require "openssl"
rescue LoadError
end
module Net
# Non-authentication POP3 protocol error
# (reply code "-ERR", except authentication).
class POPError < ProtocolError; end
# POP3 authentication error.
class POPAuthenticationError < ProtoAuthError; end
# Unexpected response from the server.
class POPBadResponse < POPError; end
#
# = Net::POP3
#
# == What is This Library?
#
# This library provides functionality for retrieving
# email via POP3, the Post Office Protocol version 3. For details
# of POP3, see [RFC1939] (http://www.ietf.org/rfc/rfc1939.txt).
#
# == Examples
#
# === Retrieving Messages
#
# This example retrieves messages from the server and deletes them
# on the server.
#
# Messages are written to files named 'inbox/1', 'inbox/2', ....
# Replace 'pop.example.com' with your POP3 server address, and
# 'YourAccount' and 'YourPassword' with the appropriate account
# details.
#
# require 'net/pop'
#
# pop = Net::POP3.new('pop.example.com')
# pop.start('YourAccount', 'YourPassword') # (1)
# if pop.mails.empty?
# puts 'No mail.'
# else
# i = 0
# pop.each_mail do |m| # or "pop.mails.each ..." # (2)
# File.open("inbox/#{i}", 'w') do |f|
# f.write m.pop
# end
# m.delete
# i += 1
# end
# puts "#{pop.mails.size} mails popped."
# end
# pop.finish # (3)
#
# 1. Call Net::POP3#start and start POP session.
# 2. Access messages by using POP3#each_mail and/or POP3#mails.
# 3. Close POP session by calling POP3#finish or use the block form of #start.
#
# === Shortened Code
#
# The example above is very verbose. You can shorten the code by using
# some utility methods. First, the block form of Net::POP3.start can
# be used instead of POP3.new, POP3#start and POP3#finish.
#
# require 'net/pop'
#
# Net::POP3.start('pop.example.com', 110,
# 'YourAccount', 'YourPassword') do |pop|
# if pop.mails.empty?
# puts 'No mail.'
# else
# i = 0
# pop.each_mail do |m| # or "pop.mails.each ..."
# File.open("inbox/#{i}", 'w') do |f|
# f.write m.pop
# end
# m.delete
# i += 1
# end
# puts "#{pop.mails.size} mails popped."
# end
# end
#
# POP3#delete_all is an alternative for #each_mail and #delete.
#
# require 'net/pop'
#
# Net::POP3.start('pop.example.com', 110,
# 'YourAccount', 'YourPassword') do |pop|
# if pop.mails.empty?
# puts 'No mail.'
# else
# i = 1
# pop.delete_all do |m|
# File.open("inbox/#{i}", 'w') do |f|
# f.write m.pop
# end
# i += 1
# end
# end
# end
#
# And here is an even shorter example.
#
# require 'net/pop'
#
# i = 0
# Net::POP3.delete_all('pop.example.com', 110,
# 'YourAccount', 'YourPassword') do |m|
# File.open("inbox/#{i}", 'w') do |f|
# f.write m.pop
# end
# i += 1
# end
#
# === Memory Space Issues
#
# All the examples above get each message as one big string.
# This example avoids this.
#
# require 'net/pop'
#
# i = 1
# Net::POP3.delete_all('pop.example.com', 110,
# 'YourAccount', 'YourPassword') do |m|
# File.open("inbox/#{i}", 'w') do |f|
# m.pop do |chunk| # get a message little by little.
# f.write chunk
# end
# i += 1
# end
# end
#
# === Using APOP
#
# The net/pop library supports APOP authentication.
# To use APOP, use the Net::APOP class instead of the Net::POP3 class.
# You can use the utility method, Net::POP3.APOP(). For example:
#
# require 'net/pop'
#
# # Use APOP authentication if $isapop == true
# pop = Net::POP3.APOP($is_apop).new('apop.example.com', 110)
# pop.start(YourAccount', 'YourPassword') do |pop|
# # Rest of the code is the same.
# end
#
# === Fetch Only Selected Mail Using 'UIDL' POP Command
#
# If your POP server provides UIDL functionality,
# you can grab only selected mails from the POP server.
# e.g.
#
# def need_pop?( id )
# # determine if we need pop this mail...
# end
#
# Net::POP3.start('pop.example.com', 110,
# 'Your account', 'Your password') do |pop|
# pop.mails.select { |m| need_pop?(m.unique_id) }.each do |m|
# do_something(m.pop)
# end
# end
#
# The POPMail#unique_id() method returns the unique-id of the message as a
# String. Normally the unique-id is a hash of the message.
#
class POP3 < Protocol
# svn revision of this library
Revision = %q$Revision$.split[1]
#
# Class Parameters
#
# returns the port for POP3
def POP3.default_port
default_pop3_port()
end
# The default port for POP3 connections, port 110
def POP3.default_pop3_port
110
end
# The default port for POP3S connections, port 995
def POP3.default_pop3s_port
995
end
def POP3.socket_type #:nodoc: obsolete
Net::InternetMessageIO
end
#
# Utilities
#
# Returns the APOP class if +isapop+ is true; otherwise, returns
# the POP class. For example:
#
# # Example 1
# pop = Net::POP3::APOP($is_apop).new(addr, port)
#
# # Example 2
# Net::POP3::APOP($is_apop).start(addr, port) do |pop|
# ....
# end
#
def POP3.APOP(isapop)
isapop ? APOP : POP3
end
# Starts a POP3 session and iterates over each POPMail object,
# yielding it to the +block+.
# This method is equivalent to:
#
# Net::POP3.start(address, port, account, password) do |pop|
# pop.each_mail do |m|
# yield m
# end
# end
#
# This method raises a POPAuthenticationError if authentication fails.
#
# === Example
#
# Net::POP3.foreach('pop.example.com', 110,
# 'YourAccount', 'YourPassword') do |m|
# file.write m.pop
# m.delete if $DELETE
# end
#
def POP3.foreach(address, port = nil,
account = nil, password = nil,
isapop = false, &block) # :yields: message
start(address, port, account, password, isapop) {|pop|
pop.each_mail(&block)
}
end
# Starts a POP3 session and deletes all messages on the server.
# If a block is given, each POPMail object is yielded to it before
# being deleted.
#
# This method raises a POPAuthenticationError if authentication fails.
#
# === Example
#
# Net::POP3.delete_all('pop.example.com', 110,
# 'YourAccount', 'YourPassword') do |m|
# file.write m.pop
# end
#
def POP3.delete_all(address, port = nil,
account = nil, password = nil,
isapop = false, &block)
start(address, port, account, password, isapop) {|pop|
pop.delete_all(&block)
}
end
# Opens a POP3 session, attempts authentication, and quits.
#
# This method raises POPAuthenticationError if authentication fails.
#
# === Example: normal POP3
#
# Net::POP3.auth_only('pop.example.com', 110,
# 'YourAccount', 'YourPassword')
#
# === Example: APOP
#
# Net::POP3.auth_only('pop.example.com', 110,
# 'YourAccount', 'YourPassword', true)
#
def POP3.auth_only(address, port = nil,
account = nil, password = nil,
isapop = false)
new(address, port, isapop).auth_only account, password
end
# Starts a pop3 session, attempts authentication, and quits.
# This method must not be called while POP3 session is opened.
# This method raises POPAuthenticationError if authentication fails.
def auth_only(account, password)
raise IOError, 'opening previously opened POP session' if started?
start(account, password) {
;
}
end
#
# SSL
#
@ssl_params = nil
# call-seq:
# Net::POP.enable_ssl(params = {})
#
# Enable SSL for all new instances.
# +params+ is passed to OpenSSL::SSLContext#set_params.
def POP3.enable_ssl(*args)
@ssl_params = create_ssl_params(*args)
end
# Constructs proper parameters from arguments
def POP3.create_ssl_params(verify_or_params = {}, certs = nil)
begin
params = verify_or_params.to_hash
rescue NoMethodError
params = {}
params[:verify_mode] = verify_or_params
if certs
Loading ...