1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* lib/net/ftp.rb: ported documentation improvement from 1.8 branch

* lib/net/imap.rb:   ditto
 * lib/net/pop.rb:    ditto
 * lib/net/smtp.rb:   ditto
 * lib/net/telnet.rb: ditto


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@6284 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
gsinclair 2004-05-09 14:42:43 +00:00
parent 0603e040b2
commit d9c41de9cc
6 changed files with 522 additions and 480 deletions

View file

@ -1,3 +1,11 @@
Sun May 9 23:38:00 2004 Gavin Sinclair <gsinclair@soyabean.com.au>
* lib/net/ftp.rb: ported documentation improvement from 1.8 branch
* lib/net/imap.rb: ditto
* lib/net/pop.rb: ditto
* lib/net/smtp.rb: ditto
* lib/net/telnet.rb: ditto
Sun May 9 23:34:51 2004 NAKAMURA, Hiroshi <nakahiro@sarion.co.jp>
* test/ruby/test_float.rb: added test_strtod to test Float("0").

View file

@ -1,5 +1,5 @@
#
# = net/ftp.rb
# = net/ftp.rb - FTP Client Library
#
# Written by Shugo Maeda <shugo@ruby-lang.org>.
#
@ -17,7 +17,7 @@
require "socket"
require "monitor"
module Net # :nodoc:
module Net
# :stopdoc:
class FTPError < StandardError; end
@ -58,7 +58,7 @@ module Net # :nodoc:
# == Major Methods
#
# The following are the methods most likely to be useful to users:
# - FTP::open
# - FTP.open
# - #getbinaryfile
# - #gettextfile
# - #putbinaryfile
@ -81,7 +81,7 @@ module Net # :nodoc:
# When +true+, transfers are performed in binary mode. Default: +true+.
attr_accessor :binary
# When +true+, the connection is in passive mode. Default: false.
# When +true+, the connection is in passive mode. Default: +false+.
attr_accessor :passive
# When +true+, all traffic to and from the server is written
@ -103,7 +103,7 @@ module Net # :nodoc:
attr_reader :last_response
#
# A synonym for +FTP.new+, but with a mandatory host parameter.
# A synonym for <tt>FTP.new</tt>, but with a mandatory host parameter.
#
# If a block is given, it is passed the +FTP+ object, which will be closed
# when the block finishes, or when an exception is raised.
@ -165,7 +165,7 @@ module Net # :nodoc:
# Establishes an FTP connection to host, optionally overriding the default
# port. If the environment variable +SOCKS_SERVER+ is set, sets up the
# connection through a SOCKS proxy. Raises an exception (typically
# +Errno::ECONNREFUSED+) if the connection cannot be established.
# <tt>Errno::ECONNREFUSED</tt>) if the connection cannot be established.
#
def connect(host, port = FTP_PORT)
if @debug_mode

View file

@ -7,7 +7,9 @@
# You can freely distribute/modify this library.
#
# Documentation: Shugo Maeda, with RDoc conversion and overview by William
# Webber.
# Webber.
#
# See Net::IMAP for documentation.
#
@ -19,13 +21,13 @@ begin
rescue LoadError
end
module Net # :nodoc:
module Net
#
# Net::IMAP implements Internet Message Access Protocol (IMAP) client
# functionality. The protocol is described in [IMAP].
#
# == IMAP OVERVIEW
# == IMAP Overview
#
# An IMAP client connects to a server, and then authenticates
# itself using either #authenticate() or #login(). Having
@ -63,7 +65,7 @@ module Net # :nodoc:
# UIDs have to be reassigned. An IMAP client cannot thus
# rearrange message orders.
#
# == EXAMPLES OF USAGE
# == Examples of Usage
#
# === List sender and subject of all recent messages in the default mailbox
#
@ -89,7 +91,7 @@ module Net # :nodoc:
# end
# imap.expunge
#
# == THREAD-SAFENESS
# == Thread Safety
#
# Net::IMAP supports concurrent threads. For example,
#
@ -103,7 +105,7 @@ module Net # :nodoc:
#
# This script invokes the FETCH command and the SEARCH command concurrently.
#
# == ERRORS
# == Errors
#
# An IMAP server can send three different types of responses to indicate
# failure:

View file

@ -1,10 +1,12 @@
# = net/pop.rb
#
#--
# Copyright (c) 1999-2004 Yukihiro Matsumoto
# Copyright (c) 1999-2004 Minero Aoki
# Copyright (c) 1999-2003 Yukihiro Matsumoto.
#
# Copyright (c) 1999-2003 Minero Aoki.
#
# written and maintained by Minero Aoki <aamine@loveruby.net>
# 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,
@ -13,181 +15,10 @@
# NOTE: You can find Japanese version of this document at:
# http://www.ruby-lang.org/ja/man/index.cgi?cmd=view;name=net%2Fpop.rb
#
# $Id$
#++
# $Id$
#
# See Net::POP3 for documentation.
#
# == 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 = pop.enable_ssl(verify, certs) if $use_ssl # (1)
# pop.start('YourAccount', 'YourPassword') # (2)
# if pop.mails.empty?
# puts 'no mail.'
# else
# i = 0
# pop.each_mail do |m| # or "pop.mails.each ..." # (3)
# File.open("inbox/#{i}", 'w') {|f|
# f.write m.pop
# }
# m.delete
# i += 1
# end
# puts "#{pop.mails.size} mails popped."
# end
# pop.finish # (4)
#
# 1. optionally enable SSL for this POP connection
# 2. call Net::POP3#start and start POP session
# 3. access messages by using POP3#each_mail and/or POP3#mails
# 4. 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') {|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') {|f|
# f.write m.pop
# }
# m.delete
# i += 1
# end
# puts "#{pop.mails.size} mails popped."
# end
# }
#
# POP3#delete_all alternates #each_mail and m.delete.
#
# require 'net/pop'
#
# Net::POP3.start('pop.example.com', 110,
# 'YourAccount', 'YourPassword') {|pop|
# if pop.mails.empty?
# puts 'no mail.'
# else
# i = 1
# pop.delete_all do |m|
# File.open("inbox/#{i}", 'w') {|f|
# f.write m.pop
# }
# i += 1
# 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') {|f|
# f.write m.pop
# }
# 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') {|f|
# m.pop do |chunk| # get a message little by little.
# f.write chunk
# end
# i += 1
# }
# 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') {|pop|
# # Rest code is same.
# }
#
# === Using SSL
# The net/pop library supports POP3 over SSL.
# To use SSL:
#
# Example 1:
# require 'net/pop'
#
# pop = Net::POP3.APOP($is_apop)
# pop = pop.enable_ssl if $use_ssl
# pop.start(server, port, account, password) do |pop|
# ...
# end
#
# Example 2:
# require 'net/pop'
# pop = Net::POP3.new('pop.example.com').enable_ssl
# pop.start(username, password) do |pop|
# ...
# 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') {|pop|
# pop.mails.select {|m| need_pop?(m.unique_id) }.each do |m|
# do_something(m.pop)
# 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.
#
require 'net/protocol'
require 'digest/md5'
@ -210,12 +41,159 @@ module Net
# Unexpected response from the server.
class POPBadResponse < POPError; end
#
# Class providing POP3 client functionality.
# = Net::POP3
#
# See documentation for the file pop.rb for examples of usage.
# == 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
Revision = %q$Revision$.split[1]
@ -253,9 +231,9 @@ module Net
# pop = Net::POP3::APOP($is_apop).new(addr, port)
#
# # Example 2
# Net::POP3::APOP($is_apop).start(addr, port) {|pop|
# Net::POP3::APOP($is_apop).start(addr, port) do |pop|
# ....
# }
# end
#
def POP3.APOP(isapop)
isapop ? APOP : POP3
@ -265,15 +243,16 @@ module Net
# yielding it to the +block+.
# This method is equivalent to:
#
# Net::POP3.start(address, port, account, password) {|pop|
# 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.
#
# # Typical usage
# === Example
#
# Net::POP3.foreach('pop.example.com', 110,
# 'YourAccount', 'YourPassword') do |m|
# file.write m.pop
@ -294,7 +273,8 @@ module Net
#
# This method raises a POPAuthenticationError if authentication fails.
#
# # Example
# === Example
#
# Net::POP3.delete_all('pop.example.com', 110,
# 'YourAccount', 'YourPassword') do |m|
# file.write m.pop
@ -312,11 +292,13 @@ module Net
#
# This method raises POPAuthenticationError if authentication fails.
#
# # Example 1: normal POP3
# === Example: normal POP3
#
# Net::POP3.auth_only('pop.example.com', 110,
# 'YourAccount', 'YourPassword')
#
# # Example 2: APOP
# === Example: APOP
#
# Net::POP3.auth_only('pop.example.com', 110,
# 'YourAccount', 'YourPassword', true)
#
@ -379,19 +361,20 @@ module Net
#
# Creates a new POP3 object and open the connection. Equivalent to
# Net::POP3.new(address, port, isapop).start(account, password)
#
# Net::POP3.new(address, port, isapop).start(account, password)
#
# If +block+ is provided, yields the newly-opened POP3 object to it,
# and automatically closes it at the end of the session.
#
# Typical usage:
# === Example
#
# Net::POP3.start(addr, port, account, password) {|pop|
# Net::POP3.start(addr, port, account, password) do |pop|
# pop.each_mail do |m|
# file.write m.pop
# m.delete
# end
# }
# end
#
def POP3.start(address, port = nil,
account = nil, password = nil,
@ -400,10 +383,14 @@ module Net
end
# Creates a new POP3 object.
# +addr+ is the hostname or ip address of your POP3 server.
#
# +address+ is the hostname or ip address of your POP3 server.
#
# The optional +port+ is the port to connect to.
#
# The optional +isapop+ specifies whether this connection is going
# to use APOP authentication; it defaults to +false+.
#
# This method does *not* open the TCP connection.
def initialize(addr, port = nil, isapop = false)
@address = addr
@ -466,12 +453,13 @@ module Net
#
# Set an output stream for debugging.
#
# # Example
# === Example
#
# pop = Net::POP.new(addr, port)
# pop.set_debug_output $stderr
# pop.start(account, passwd) {
# pop.start(account, passwd) do |pop|
# ....
# }
# end
#
def set_debug_output(arg)
@debug_output = arg
@ -652,17 +640,19 @@ module Net
#
# If called with a block, yields each message in turn before deleting it.
#
# # Example
# === Example
#
# n = 1
# pop.delete_all do |m|
# File.open("inbox/#{n}") {|f|
# File.open("inbox/#{n}") do |f|
# f.write m.pop
# }
# end
# n += 1
# end
#
# This method raises a POPError if an error occurs.
def delete_all # :yield: message
#
def delete_all # :yield: message
mails().each do |m|
yield m if block_given?
m.delete unless m.deleted?
@ -739,42 +729,45 @@ module Net
"#<#{self.class} #{@number}#{@deleted ? ' deleted' : ''}>"
end
#
# This method fetches the message. If called with a block, the
# message is yielded to the block one chunk at a time. If called
# without a block, the message is returned as a String. The optional
# +dest+ argument will be prepended to the returned String; this
# argument is essentially obsolete.
#
# This method raises a POPError if an error occurs.
# === Example without block
#
# # Example without block
# POP3.start('pop.example.com', 110,
# 'YourAccount, 'YourPassword') {|pop|
# 'YourAccount, 'YourPassword') do |pop|
# n = 1
# pop.mails.each do |popmail|
# File.open("inbox/#{n}", 'w') {|f|
# File.open("inbox/#{n}", 'w') do |f|
# f.write popmail.pop
# }
# end
# popmail.delete
# n += 1
# end
# }
# end
#
# === Example with block
#
# # Example with block
# POP3.start('pop.example.com', 110,
# 'YourAccount, 'YourPassword') {|pop|
# 'YourAccount, 'YourPassword') do |pop|
# n = 1
# pop.mails.each do |popmail|
# File.open("inbox/#{n}", 'w') {|f|
# File.open("inbox/#{n}", 'w') do |f|
# popmail.pop do |chunk| ####
# f.write chunk
# end
# }
# end
# n += 1
# end
# }
# end
#
def pop(dest = '', &block) # :yield: message_chunk
# This method raises a POPError if an error occurs.
#
def pop( dest = '', &block ) # :yield: message_chunk
if block_given?
@command.retr(@number, &block)
nil
@ -790,6 +783,7 @@ module Net
alias mail pop #:nodoc: obsolete
# Fetches the message header and +lines+ lines of body.
#
# The optional +dest+ argument is obsolete.
#
# This method raises a POPError if an error occurs.
@ -801,6 +795,7 @@ module Net
end
# Fetches the message header.
#
# The optional +dest+ argument is obsolete.
#
# This method raises a POPError if an error occurs.
@ -814,18 +809,19 @@ module Net
#
# This method raises a POPError if an error occurs.
#
# # Example
# === Example
#
# POP3.start('pop.example.com', 110,
# 'YourAccount, 'YourPassword') {|pop|
# 'YourAccount, 'YourPassword') do |pop|
# n = 1
# pop.mails.each do |popmail|
# File.open("inbox/#{n}", 'w') {|f|
# File.open("inbox/#{n}", 'w') do |f|
# f.write popmail.pop
# }
# end
# popmail.delete ####
# n += 1
# end
# }
# end
#
def delete
@command.dele @number

View file

@ -1,10 +1,12 @@
# = net/smtp.rb
#
#--
# Copyright (C) 1999-2004 Yukihiro Matsumoto
# Copyright (C) 1999-2004 Minero Aoki
#
# written and maintained by Minero Aoki <aamine@loveruby.net>
# Copyright (c) 1999-2004 Yukihiro Matsumoto.
#
# Copyright (c) 1999-2004 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.
@ -13,140 +15,8 @@
# http://www.ruby-lang.org/ja/man/index.cgi?cmd=view;name=net%2Fsmtp.rb
#
# $Id$
#++
#
# == What is This Library?
#
# This library provides functionality to send internet
# mail via SMTP, the Simple Mail Transfer Protocol. For details of
# SMTP itself, see [RFC2821] (http://www.ietf.org/rfc/rfc2821.txt).
#
# == What is This Library NOT?
#
# This library does NOT provide functions to compose internet mails.
# You must create them by yourself. If you want better mail support,
# try RubyMail or TMail. You can get both libraries from RAA.
# (http://www.ruby-lang.org/en/raa.html)
#
# FYI: the official documentation on internet mail is: [RFC2822] (http://www.ietf.org/rfc/rfc2822.txt).
#
# == Examples
#
# === Sending Messages
#
# You must open a connection to an SMTP server before sending messages.
# The first argument is the address of your SMTP server, and the second
# argument is the port number. Using SMTP.start with a block is the simplest
# way to do this. This way, the SMTP connection is closed automatically
# after the block is executed.
#
# require 'net/smtp'
# Net::SMTP.start('your.smtp.server', 25) {|smtp|
# # use the SMTP object smtp only in this block
# }
#
# Replace 'your.smtp.server' with your SMTP server. Normally
# your system manager or internet provider supplies a server
# for you.
#
# Then you can send messages.
#
# msgstr = <<END_OF_MESSAGE
# From: Your Name <your@mail.address>
# To: Destination Address <someone@example.com>
# Subject: test message
# Date: Sat, 23 Jun 2001 16:26:43 +0900
# Message-Id: <unique.message.id.string@example.com>
#
# This is a test message.
# END_OF_MESSAGE
#
# require 'net/smtp'
# Net::SMTP.start('your.smtp.server', 25) {|smtp|
# smtp.send_message msgstr,
# 'your@mail.address',
# 'his_addess@example.com'
# }
#
# === Closing the Session
#
# You MUST close the SMTP session after sending messages, by calling
# the #finish method:
#
# # using SMTP#finish
# smtp = Net::SMTP.start('your.smtp.server', 25)
# smtp.send_message msgstr, 'from@address', 'to@address'
# smtp.finish
#
# You can also use the block form of SMTP.start/SMTP#start. This closes
# the SMTP session automatically:
#
# # using block form of SMTP.start
# Net::SMTP.start('your.smtp.server', 25) {|smtp|
# smtp.send_message msgstr, 'from@address', 'to@address'
# }
#
# I strongly recommend this scheme. This form is simpler and more robust.
#
# === HELO domain
#
# In almost all situations, you must provide a third argument
# to SMTP.start/SMTP#start. This is the domain name which you are on
# (the host to send mail from). It is called the "HELO domain".
# The SMTP server will judge whether it should send or reject
# the SMTP session by inspecting the HELO domain.
#
# Net::SMTP.start('your.smtp.server', 25,
# 'mail.from.domain') {|smtp| ... }
#
# === SMTP Authentication
#
# The Net::SMTP class supports three authentication schemes;
# PLAIN, LOGIN and CRAM MD5. (SMTP Authentication: [RFC2554])
# To use SMTP authentication, pass extra arguments to
# SMTP.start/SMTP#start. Use in conjunction with STARTTLS to
# prevent authentication information passing in the clear.
#
# # PLAIN
# Net::SMTP.start('your.smtp.server', 25, 'mail.from,domain',
# 'Your Account', 'Your Password', :plain)
# # LOGIN
# Net::SMTP.start('your.smtp.server', 25, 'mail.from,domain',
# 'Your Account', 'Your Password', :login)
#
# # CRAM MD5
# Net::SMTP.start('your.smtp.server', 25, 'mail.from,domain',
# 'Your Account', 'Your Password', :cram_md5)
#
# === STARTTLS support
#
# The Net::SMTP class supports STARTTLS.
#
# # Per Instance STARTTLS
# smtp = Net::SMTP.new('smtp.example.com',25)
# smtp.enable_tls(verify, certs) if $use_tls #(1)
# smtp.start('your host','username','password') { |s|
# s.send_message msgstr,
# 'your@mail.address',
# 'recipient@example.com'
# }
# smtp.finish
#
# 1. +verify+ tells the openssl library how to verify the server
# certificate. Defaults to OpenSSL::SSL::VERIFY_PEER
# +certs+ is a file or directory holding CA certs to use to verify the
# server cert; Defaults to nil.
#
#
# # USE STARTTLS for all subsequent instances
# Net::SMTP.enable_tls
# # We will now use starttls for all connections.
# Net::SMTP.start('your.smtp.server', 25, 'mail.from,domain',
# 'Your Account', 'Your Password', :plain) {|smtp|
# smtp.send_message msgstr,
# 'your@mail.address',
# 'his_addess@example.com'
# }
# See Net::SMTP for documentation.
#
require 'net/protocol'
@ -157,7 +27,7 @@ begin
rescue LoadError
end
module Net # :nodoc:
module Net
# Module mixed in to all SMTP error classes
module SMTPError
@ -191,14 +61,114 @@ module Net # :nodoc:
end
#
# Class providing SMTP client functionality.
# = Net::SMTP
#
# See documentation for the file smtp.rb for examples of usage.
# == What is This Library?
#
# This library provides functionality to send internet
# mail via SMTP, the Simple Mail Transfer Protocol. For details of
# SMTP itself, see [RFC2821] (http://www.ietf.org/rfc/rfc2821.txt).
#
# == What is This Library NOT?
#
# This library does NOT provide functions to compose internet mails.
# You must create them by yourself. If you want better mail support,
# try RubyMail or TMail. You can get both libraries from RAA.
# (http://www.ruby-lang.org/en/raa.html)
#
# FYI: the official documentation on internet mail is: [RFC2822] (http://www.ietf.org/rfc/rfc2822.txt).
#
# == Examples
#
# === Sending Messages
#
# You must open a connection to an SMTP server before sending messages.
# The first argument is the address of your SMTP server, and the second
# argument is the port number. Using SMTP.start with a block is the simplest
# way to do this. This way, the SMTP connection is closed automatically
# after the block is executed.
#
# require 'net/smtp'
# Net::SMTP.start('your.smtp.server', 25) do |smtp|
# # Use the SMTP object smtp only in this block.
# end
#
# Replace 'your.smtp.server' with your SMTP server. Normally
# your system manager or internet provider supplies a server
# for you.
#
# Then you can send messages.
#
# msgstr = <<END_OF_MESSAGE
# From: Your Name <your@mail.address>
# To: Destination Address <someone@example.com>
# Subject: test message
# Date: Sat, 23 Jun 2001 16:26:43 +0900
# Message-Id: <unique.message.id.string@example.com>
#
# This is a test message.
# END_OF_MESSAGE
#
# require 'net/smtp'
# Net::SMTP.start('your.smtp.server', 25) do |smtp|
# smtp.send_message msgstr,
# 'your@mail.address',
# 'his_addess@example.com'
# end
#
# === Closing the Session
#
# You MUST close the SMTP session after sending messages, by calling
# the #finish method:
#
# # using SMTP#finish
# smtp = Net::SMTP.start('your.smtp.server', 25)
# smtp.send_message msgstr, 'from@address', 'to@address'
# smtp.finish
#
# You can also use the block form of SMTP.start/SMTP#start. This closes
# the SMTP session automatically:
#
# # using block form of SMTP.start
# Net::SMTP.start('your.smtp.server', 25) do |smtp|
# smtp.send_message msgstr, 'from@address', 'to@address'
# end
#
# I strongly recommend this scheme. This form is simpler and more robust.
#
# === HELO domain
#
# In almost all situations, you must provide a third argument
# to SMTP.start/SMTP#start. This is the domain name which you are on
# (the host to send mail from). It is called the "HELO domain".
# The SMTP server will judge whether it should send or reject
# the SMTP session by inspecting the HELO domain.
#
# Net::SMTP.start('your.smtp.server', 25,
# 'mail.from.domain') { |smtp| ... }
#
# === SMTP Authentication
#
# The Net::SMTP class supports three authentication schemes;
# PLAIN, LOGIN and CRAM MD5. (SMTP Authentication: [RFC2554])
# To use SMTP authentication, pass extra arguments to
# SMTP.start/SMTP#start.
#
# # PLAIN
# Net::SMTP.start('your.smtp.server', 25, 'mail.from.domain',
# 'Your Account', 'Your Password', :plain)
# # LOGIN
# Net::SMTP.start('your.smtp.server', 25, 'mail.from.domain',
# 'Your Account', 'Your Password', :login)
#
# # CRAM MD5
# Net::SMTP.start('your.smtp.server', 25, 'mail.from.domain',
# 'Your Account', 'Your Password', :cram_md5)
#
class SMTP
Revision = %q$Revision$.split[1]
# The default SMTP port, port 25.
def SMTP.default_port
25
@ -238,10 +208,17 @@ module Net # :nodoc:
@certs
end
# Creates a new Net::SMTP object. +address+ is the hostname
# or ip address of your SMTP server. +port+ is the port to
# connect to; it defaults to port 25.
# This method does not open the TCP connection.
#
# Creates a new Net::SMTP object.
#
# +address+ is the hostname or ip address of your SMTP
# server. +port+ is the port to connect to; it defaults to
# port 25.
#
# This method does not open the TCP connection. You can use
# SMTP.start instead of SMTP.new if you want to do everything
# at once. Otherwise, follow SMTP.new with SMTP#start.
#
def initialize(address, port = nil)
@address = address
@port = (port || SMTP.default_port)
@ -267,11 +244,13 @@ module Net # :nodoc:
@esmtp
end
#
# Set whether to use ESMTP or not. This should be done before
# calling #start. Note that if #start is called in ESMTP mode,
# and the connection fails due to a ProtocolError, the SMTP
# object will automatically switch to plain SMTP mode and
# retry (but not vice versa).
#
def esmtp=(bool)
@esmtp = bool
end
@ -323,6 +302,7 @@ module Net # :nodoc:
@read_timeout = sec
end
#
# WARNING: This method causes serious security holes.
# Use this method for only debugging.
#
@ -332,9 +312,10 @@ module Net # :nodoc:
# # example
# smtp = Net::SMTP.new(addr, port)
# smtp.set_debug_output $stderr
# smtp.start {
# smtp.start do |smtp|
# ....
# }
# end
#
def set_debug_output(arg)
@debug_output = arg
end
@ -343,16 +324,20 @@ module Net # :nodoc:
# SMTP session control
#
#
# Creates a new Net::SMTP object and connects to the server.
#
# This method is equivalent to:
#
# Net::SMTP.new(address,port).start(helo_domain,account,password,authtype)
# Net::SMTP.new(address, port).start(helo_domain, account, password, authtype)
#
# # example
# Net::SMTP.start('your.smtp.server') {
# smtp.send_message msgstr, 'from@example.com', ['dest@example.com']
# }
# === Example
#
# Net::SMTP.start('your.smtp.server') do |smtp|
# smtp.send_message msgstr, 'from@example.com', ['dest@example.com']
# end
#
# === Block Usage
#
# If called with a block, the newly-opened Net::SMTP object is yielded
# to the block, and automatically closed when the block finishes. If called
@ -360,16 +345,23 @@ module Net # :nodoc:
# the caller, and it is the caller's responsibility to close it when
# finished.
#
# === Parameters
#
# +address+ is the hostname or ip address of your smtp server.
#
# +port+ is the port to connect to; it defaults to port 25.
#
# +helo+ is the _HELO_ _domain_ provided by the client to the
# server (see overview comments); it defaults to 'localhost.localdomain'.
#
# The remaining arguments are used for SMTP authentication, if required
# or desired. +user+ is the account name; +secret+ is your password
# or other authentication token; and +authtype+ is the authentication
# type, one of :plain, :login, or :cram_md5. See the discussion of
# SMTP Authentication in the overview notes.
#
# === Errors
#
# This method may raise:
#
# * Net::SMTPAuthenticationError
@ -379,6 +371,7 @@ module Net # :nodoc:
# * Net::SMTPUnknownError
# * IOError
# * TimeoutError
#
def SMTP.start(address, port = nil, helo = 'localhost.localdomain',
user = nil, secret = nil, authtype = nil,
&block) # :yield: smtp
@ -390,21 +383,43 @@ module Net # :nodoc:
@started
end
#
# Opens a TCP connection and starts the SMTP session.
#
# === Parameters
#
# +helo+ is the _HELO_ _domain_ that you'll dispatch mails from; see
# the discussion in the overview notes.
#
# If both of +user+ and +secret+ are given, SMTP authentication
# will be attempted using the AUTH command. +authtype+ specifies
# the type of authentication to attempt; it must be one of
# :login, :plain, and :cram_md5. See the notes on SMTP Authentication
# in the overview.
#
# === Block Usage
#
# When this methods is called with a block, the newly-started SMTP
# object is yielded to the block, and automatically closed after
# the block call finishes. Otherwise, it is the caller's
# responsibility to close the session when finished.
#
# If both of +user+ and +secret+ are given, SMTP authentication
# will be attempted using the AUTH command. +authtype+ specifies
# the type of authentication to attempt; it must be one of
# :login, :plain, and :cram_md5. See the notes on SMTP Authentication
# in the overview.
# === Example
#
# This is very similar to the class method SMTP.start.
#
# require 'net/smtp'
# smtp = Net::SMTP.new('smtp.mail.server', 25)
# smtp.start(helo_domain, account, password, authtype) do |smtp|
# smtp.send_message msgstr, 'from@example.com', ['dest@example.com']
# end
#
# The primary use of this method (as opposed to SMTP.start)
# is probably to set debugging (#set_debug_output) or ESMTP
# (#esmtp=), which must be done before the session is
# started.
#
# === Errors
#
# If session has already been started, an IOError will be raised.
#
@ -417,8 +432,9 @@ module Net # :nodoc:
# * Net::SMTPUnknownError
# * IOError
# * TimeoutError
#
def start(helo = 'localhost.localdomain',
user = nil, secret = nil, authtype = nil) #:yield: smtp
user = nil, secret = nil, authtype = nil) # :yield: smtp
if block_given?
begin
do_start(helo, user, secret, authtype)
@ -524,21 +540,26 @@ module Net # :nodoc:
public
#
# Sends +msgstr+ as a message. Single CR ("\r") and LF ("\n") found
# in the +msgstr+, are converted into the CR LF pair. You cannot send a
# binary message with this method. +msgstr+ should include both
# the message headers and body.
#
# +from_addr+ is a String representing the source mail address.
#
# +to_addr+ is a String or Strings or Array of Strings, representing
# the destination mail address or addresses.
#
# # example
# Net::SMTP.start('smtp.example.com') {|smtp|
# === Example
#
# Net::SMTP.start('smtp.example.com') do |smtp|
# smtp.send_message msgstr,
# 'from@example.com',
# ['dest@example.com', 'dest2@example.com']
# }
# end
#
# === Errors
#
# This method may raise:
#
@ -548,6 +569,7 @@ module Net # :nodoc:
# * Net::SMTPUnknownError
# * IOError
# * TimeoutError
#
def send_message(msgstr, from_addr, *to_addrs)
send0(from_addr, to_addrs.flatten) {
@socket.write_message msgstr
@ -557,33 +579,40 @@ module Net # :nodoc:
alias send_mail send_message
alias sendmail send_message # obsolete
#
# Opens a message writer stream and gives it to the block.
# The stream is valid only in the block, and has these methods:
#
# puts(str = ''):: outputs STR and CR LF.
# print(str):: outputs STR.
# printf(fmt, *args):: outputs sprintf(fmt,*args).
# write(str):: outputs STR and returns the length of written bytes.
# <<(str):: outputs STR and returns self.
# print(str):: outputs STR.
# printf(fmt, *args):: outputs sprintf(fmt,*args).
# write(str):: outputs STR and returns the length of written bytes.
# <<(str):: outputs STR and returns self.
#
# If a single CR ("\r") or LF ("\n") is found in the message,
# it is converted to the CR LF pair. You cannot send a binary
# message with this method.
#
# === Parameters
#
# +from_addr+ is a String representing the source mail address.
#
# +to_addr+ is a String or Strings or Array of Strings, representing
# the destination mail address or addresses.
#
# # example
# Net::SMTP.start('smtp.example.com', 25) {|smtp|
# smtp.open_message_stream('from@example.com', ['dest@example.com']) {|f|
# === Example
#
# Net::SMTP.start('smtp.example.com', 25) do |smtp|
# smtp.open_message_stream('from@example.com', ['dest@example.com']) do |f|
# f.puts 'From: from@example.com'
# f.puts 'To: dest@example.com'
# f.puts 'Subject: test message'
# f.puts
# f.puts 'This is a test message.'
# }
# }
# end
# end
#
# === Errors
#
# This method may raise:
#
@ -593,7 +622,8 @@ module Net # :nodoc:
# * Net::SMTPUnknownError
# * IOError
# * TimeoutError
def open_message_stream(from_addr, *to_addrs, &block) #:yield: stream
#
def open_message_stream(from_addr, *to_addrs, &block) # :yield: stream
send0(from_addr, to_addrs.flatten) {
@socket.write_message_by_block(&block)
}

View file

@ -1,94 +1,98 @@
# = net/telnet.rb - simple telnet client library
# = net/telnet.rb - Simple Telnet Client Library
#
# Wakou Aoyama <wakou@ruby-lang.org>
#
# == Overview
# Author:: Wakou Aoyama <wakou@ruby-lang.org>
# Documentation:: William Webber and Wakou Aoyama
#
# This file holds the class Net::Telnet, which provides client-side
# telnet functionality.
#
# The telnet protocol allows a client to login remotely to a user
# account on a server and execute commands via a shell. The equivalent
# is done by creating a Net::Telnet class with the Host option
# set to your host, calling #login() with your user and password,
# issuing one or more #cmd() calls, and then calling #close()
# to end the session. The #waitfor(), #print(), #puts(), and
# #write() methods, which #cmd() is implemented on top of, are
# only needed if you are doing something more complicated.
# For documentation, see Net::Telnet.
#
# A Net::Telnet object can also be used to connect to non-telnet
# services, such as SMTP or HTTP. In this case, you normally
# want to provide the Port option to specify the port to
# connect to, and set the Telnetmode option to false to prevent
# the client from attempting to interpret telnet command sequences.
# Generally, #login() will not work with other protocols, and you
# have to handle authentication yourself.
# For some protocols, it will be possible to specify the Prompt
# option once when you create the Telnet object and use #cmd() calls;
# for others, you will have to specify the response sequence to
# look for as the Match option to every #cmd() call, or call
# #puts() and #waitfor() directly; for yet others, you will have
# to use #sysread() instead of #waitfor() and parse server
# responses yourself.
#
# It is worth noting that when you create a new Net::Telnet object,
# you can supply a proxy IO channel via the Proxy option. This
# can be used to attach the Telnet object to other Telnet objects,
# to already open sockets, or to any read-write IO object. This
# can be useful, for instance, for setting up a test fixture for
# unit testing.
#
# == Examples of use.
#
# === Log in and send a command, echoing all output to stdout.
#
# localhost = Net::Telnet::new({"Host" => "localhost",
# "Timeout" => 10,
# "Prompt" => /[$%#>] \z/n})
# localhost.login("username", "password"){|c| print c }
# localhost.cmd("command"){|c| print c }
# localhost.close
#
#
# === Check a POP server to see if you have mail.
#
# pop = Net::Telnet::new({"Host" => "your_destination_host_here",
# "Port" => 110,
# "Telnetmode" => false,
# "Prompt" => /^\+OK/n})
# pop.cmd("user " + "your_username_here"){|c| print c}
# pop.cmd("pass " + "your_password_here"){|c| print c}
# pop.cmd("list"){|c| print c}
#
# == References.
#
# There are a large number of RFCs relevant to the Telnet protocol.
# RFCs 854-861 define the base protocol. For a complete listing
# of relevant RFCs, see
# http://www.omnifarious.org/~hopper/technical/telnet-rfc.html
require "socket"
require "delegate"
require "timeout"
require "English"
module Net
module Net # :nodoc:
#
# == Net::Telnet
#
# Provides telnet client functionality.
#
# This class also has, through delegation, all the methods of
# a socket object (by default, a TCPSocket, but can be set
# by the Proxy option to new()). This provides methods
# such as #close() to end the session and #sysread() to
# read data directly from the host, instead of via the
# #waitfor() mechanism. Note that if you do use #sysread()
# directly when in telnet mode, you should probably pass
# the output through #preprocess() to extract telnet command
# sequences.
# This class also has, through delegation, all the methods of a
# socket object (by default, a +TCPSocket+, but can be set by the
# +Proxy+ option to <tt>new()</tt>). This provides methods such as
# <tt>close()</tt> to end the session and <tt>sysread()</tt> to read
# data directly from the host, instead of via the <tt>waitfor()</tt>
# mechanism. Note that if you do use <tt>sysread()</tt> directly
# when in telnet mode, you should probably pass the output through
# <tt>preprocess()</tt> to extract telnet command sequences.
#
# == Overview
#
# The telnet protocol allows a client to login remotely to a user
# account on a server and execute commands via a shell. The equivalent
# is done by creating a Net::Telnet class with the +Host+ option
# set to your host, calling #login() with your user and password,
# issuing one or more #cmd() calls, and then calling #close()
# to end the session. The #waitfor(), #print(), #puts(), and
# #write() methods, which #cmd() is implemented on top of, are
# only needed if you are doing something more complicated.
#
# A Net::Telnet object can also be used to connect to non-telnet
# services, such as SMTP or HTTP. In this case, you normally
# want to provide the +Port+ option to specify the port to
# connect to, and set the +Telnetmode+ option to false to prevent
# the client from attempting to interpret telnet command sequences.
# Generally, #login() will not work with other protocols, and you
# have to handle authentication yourself.
#
# For some protocols, it will be possible to specify the +Prompt+
# option once when you create the Telnet object and use #cmd() calls;
# for others, you will have to specify the response sequence to
# look for as the Match option to every #cmd() call, or call
# #puts() and #waitfor() directly; for yet others, you will have
# to use #sysread() instead of #waitfor() and parse server
# responses yourself.
#
# It is worth noting that when you create a new Net::Telnet object,
# you can supply a proxy IO channel via the Proxy option. This
# can be used to attach the Telnet object to other Telnet objects,
# to already open sockets, or to any read-write IO object. This
# can be useful, for instance, for setting up a test fixture for
# unit testing.
#
# == Examples
#
# === Log in and send a command, echoing all output to stdout
#
# localhost = Net::Telnet::new("Host" => "localhost",
# "Timeout" => 10,
# "Prompt" => /[$%#>] \z/n)
# localhost.login("username", "password") { |c| print c }
# localhost.cmd("command") { |c| print c }
# localhost.close
#
#
# === Check a POP server to see if you have mail
#
# pop = Net::Telnet::new("Host" => "your_destination_host_here",
# "Port" => 110,
# "Telnetmode" => false,
# "Prompt" => /^\+OK/n)
# pop.cmd("user " + "your_username_here") { |c| print c }
# pop.cmd("pass " + "your_password_here") { |c| print c }
# pop.cmd("list") { |c| print c }
#
# == References
#
# There are a large number of RFCs relevant to the Telnet protocol.
# RFCs 854-861 define the base protocol. For a complete listing
# of relevant RFCs, see
# http://www.omnifarious.org/~hopper/technical/telnet-rfc.html
#
# See the documentation to the telnet.rb file for an overview
# and examples of usage.
class Telnet < SimpleDelegator
# :stopdoc:
@ -163,6 +167,7 @@ module Net # :nodoc:
REVISION = '$Id$'
# :startdoc:
#
# Creates a new Net::Telnet object.
#
# Attempts to connect to the host (unless the Proxy option is
@ -176,7 +181,7 @@ module Net # :nodoc:
# +options+ is a hash of options. The following example lists
# all options and their default values.
#
# host = Net::Telnet::new({
# host = Net::Telnet::new(
# "Host" => "localhost", # default: "localhost"
# "Port" => 23, # default: 23
# "Binmode" => false, # default: false
@ -189,7 +194,7 @@ module Net # :nodoc:
# "Waittime" => 0, # default: 0
# "Proxy" => proxy # default: nil
# # proxy is Net::Telnet or IO object
# })
# )
#
# The options have the following meanings:
#
@ -266,6 +271,7 @@ module Net # :nodoc:
# instance will use that one's socket for communication. If an
# IO object, it is used directly for communication. Any other
# kind of object will cause an error to be raised.
#
def initialize(options) # :yield: mesg
@options = options
@options["Host"] = "localhost" unless @options.has_key?("Host")