Edit File by line
/home/barbar84/public_h.../wp-conte.../plugins/sujqvwi/AnonR/anonr.TX.../opt/alt/ruby27/share/ruby/net
File: ftp.rb
# frozen_string_literal: true
[0] Fix | Delete
#
[1] Fix | Delete
# = net/ftp.rb - FTP Client Library
[2] Fix | Delete
#
[3] Fix | Delete
# Written by Shugo Maeda <shugo@ruby-lang.org>.
[4] Fix | Delete
#
[5] Fix | Delete
# Documentation by Gavin Sinclair, sourced from "Programming Ruby" (Hunt/Thomas)
[6] Fix | Delete
# and "Ruby In a Nutshell" (Matsumoto), used with permission.
[7] Fix | Delete
#
[8] Fix | Delete
# This library is distributed under the terms of the Ruby license.
[9] Fix | Delete
# You can freely distribute/modify this library.
[10] Fix | Delete
#
[11] Fix | Delete
# It is included in the Ruby standard library.
[12] Fix | Delete
#
[13] Fix | Delete
# See the Net::FTP class for an overview.
[14] Fix | Delete
#
[15] Fix | Delete
[16] Fix | Delete
require "socket"
[17] Fix | Delete
require "monitor"
[18] Fix | Delete
require_relative "protocol"
[19] Fix | Delete
require "time"
[20] Fix | Delete
begin
[21] Fix | Delete
require "openssl"
[22] Fix | Delete
rescue LoadError
[23] Fix | Delete
end
[24] Fix | Delete
[25] Fix | Delete
module Net
[26] Fix | Delete
[27] Fix | Delete
# :stopdoc:
[28] Fix | Delete
class FTPError < StandardError; end
[29] Fix | Delete
class FTPReplyError < FTPError; end
[30] Fix | Delete
class FTPTempError < FTPError; end
[31] Fix | Delete
class FTPPermError < FTPError; end
[32] Fix | Delete
class FTPProtoError < FTPError; end
[33] Fix | Delete
class FTPConnectionError < FTPError; end
[34] Fix | Delete
# :startdoc:
[35] Fix | Delete
[36] Fix | Delete
#
[37] Fix | Delete
# This class implements the File Transfer Protocol. If you have used a
[38] Fix | Delete
# command-line FTP program, and are familiar with the commands, you will be
[39] Fix | Delete
# able to use this class easily. Some extra features are included to take
[40] Fix | Delete
# advantage of Ruby's style and strengths.
[41] Fix | Delete
#
[42] Fix | Delete
# == Example
[43] Fix | Delete
#
[44] Fix | Delete
# require 'net/ftp'
[45] Fix | Delete
#
[46] Fix | Delete
# === Example 1
[47] Fix | Delete
#
[48] Fix | Delete
# ftp = Net::FTP.new('example.com')
[49] Fix | Delete
# ftp.login
[50] Fix | Delete
# files = ftp.chdir('pub/lang/ruby/contrib')
[51] Fix | Delete
# files = ftp.list('n*')
[52] Fix | Delete
# ftp.getbinaryfile('nif.rb-0.91.gz', 'nif.gz', 1024)
[53] Fix | Delete
# ftp.close
[54] Fix | Delete
#
[55] Fix | Delete
# === Example 2
[56] Fix | Delete
#
[57] Fix | Delete
# Net::FTP.open('example.com') do |ftp|
[58] Fix | Delete
# ftp.login
[59] Fix | Delete
# files = ftp.chdir('pub/lang/ruby/contrib')
[60] Fix | Delete
# files = ftp.list('n*')
[61] Fix | Delete
# ftp.getbinaryfile('nif.rb-0.91.gz', 'nif.gz', 1024)
[62] Fix | Delete
# end
[63] Fix | Delete
#
[64] Fix | Delete
# == Major Methods
[65] Fix | Delete
#
[66] Fix | Delete
# The following are the methods most likely to be useful to users:
[67] Fix | Delete
# - FTP.open
[68] Fix | Delete
# - #getbinaryfile
[69] Fix | Delete
# - #gettextfile
[70] Fix | Delete
# - #putbinaryfile
[71] Fix | Delete
# - #puttextfile
[72] Fix | Delete
# - #chdir
[73] Fix | Delete
# - #nlst
[74] Fix | Delete
# - #size
[75] Fix | Delete
# - #rename
[76] Fix | Delete
# - #delete
[77] Fix | Delete
#
[78] Fix | Delete
class FTP < Protocol
[79] Fix | Delete
include MonitorMixin
[80] Fix | Delete
if defined?(OpenSSL::SSL)
[81] Fix | Delete
include OpenSSL
[82] Fix | Delete
include SSL
[83] Fix | Delete
end
[84] Fix | Delete
[85] Fix | Delete
# :stopdoc:
[86] Fix | Delete
FTP_PORT = 21
[87] Fix | Delete
CRLF = "\r\n"
[88] Fix | Delete
DEFAULT_BLOCKSIZE = BufferedIO::BUFSIZE
[89] Fix | Delete
@@default_passive = true
[90] Fix | Delete
# :startdoc:
[91] Fix | Delete
[92] Fix | Delete
# When +true+, transfers are performed in binary mode. Default: +true+.
[93] Fix | Delete
attr_reader :binary
[94] Fix | Delete
[95] Fix | Delete
# When +true+, the connection is in passive mode. Default: +true+.
[96] Fix | Delete
attr_accessor :passive
[97] Fix | Delete
[98] Fix | Delete
# When +true+, use the IP address in PASV responses. Otherwise, it uses
[99] Fix | Delete
# the same IP address for the control connection. Default: +false+.
[100] Fix | Delete
attr_accessor :use_pasv_ip
[101] Fix | Delete
[102] Fix | Delete
# When +true+, all traffic to and from the server is written
[103] Fix | Delete
# to +$stdout+. Default: +false+.
[104] Fix | Delete
attr_accessor :debug_mode
[105] Fix | Delete
[106] Fix | Delete
# Sets or retrieves the +resume+ status, which decides whether incomplete
[107] Fix | Delete
# transfers are resumed or restarted. Default: +false+.
[108] Fix | Delete
attr_accessor :resume
[109] Fix | Delete
[110] Fix | Delete
# Number of seconds to wait for the connection to open. Any number
[111] Fix | Delete
# may be used, including Floats for fractional seconds. If the FTP
[112] Fix | Delete
# object cannot open a connection in this many seconds, it raises a
[113] Fix | Delete
# Net::OpenTimeout exception. The default value is +nil+.
[114] Fix | Delete
attr_accessor :open_timeout
[115] Fix | Delete
[116] Fix | Delete
# Number of seconds to wait for the TLS handshake. Any number
[117] Fix | Delete
# may be used, including Floats for fractional seconds. If the FTP
[118] Fix | Delete
# object cannot complete the TLS handshake in this many seconds, it
[119] Fix | Delete
# raises a Net::OpenTimeout exception. The default value is +nil+.
[120] Fix | Delete
# If +ssl_handshake_timeout+ is +nil+, +open_timeout+ is used instead.
[121] Fix | Delete
attr_accessor :ssl_handshake_timeout
[122] Fix | Delete
[123] Fix | Delete
# Number of seconds to wait for one block to be read (via one read(2)
[124] Fix | Delete
# call). Any number may be used, including Floats for fractional
[125] Fix | Delete
# seconds. If the FTP object cannot read data in this many seconds,
[126] Fix | Delete
# it raises a Timeout::Error exception. The default value is 60 seconds.
[127] Fix | Delete
attr_reader :read_timeout
[128] Fix | Delete
[129] Fix | Delete
# Setter for the read_timeout attribute.
[130] Fix | Delete
def read_timeout=(sec)
[131] Fix | Delete
@sock.read_timeout = sec
[132] Fix | Delete
@read_timeout = sec
[133] Fix | Delete
end
[134] Fix | Delete
[135] Fix | Delete
# The server's welcome message.
[136] Fix | Delete
attr_reader :welcome
[137] Fix | Delete
[138] Fix | Delete
# The server's last response code.
[139] Fix | Delete
attr_reader :last_response_code
[140] Fix | Delete
alias lastresp last_response_code
[141] Fix | Delete
[142] Fix | Delete
# The server's last response.
[143] Fix | Delete
attr_reader :last_response
[144] Fix | Delete
[145] Fix | Delete
# When +true+, connections are in passive mode per default.
[146] Fix | Delete
# Default: +true+.
[147] Fix | Delete
def self.default_passive=(value)
[148] Fix | Delete
@@default_passive = value
[149] Fix | Delete
end
[150] Fix | Delete
[151] Fix | Delete
# When +true+, connections are in passive mode per default.
[152] Fix | Delete
# Default: +true+.
[153] Fix | Delete
def self.default_passive
[154] Fix | Delete
@@default_passive
[155] Fix | Delete
end
[156] Fix | Delete
[157] Fix | Delete
#
[158] Fix | Delete
# A synonym for <tt>FTP.new</tt>, but with a mandatory host parameter.
[159] Fix | Delete
#
[160] Fix | Delete
# If a block is given, it is passed the +FTP+ object, which will be closed
[161] Fix | Delete
# when the block finishes, or when an exception is raised.
[162] Fix | Delete
#
[163] Fix | Delete
def FTP.open(host, *args)
[164] Fix | Delete
if block_given?
[165] Fix | Delete
ftp = new(host, *args)
[166] Fix | Delete
begin
[167] Fix | Delete
yield ftp
[168] Fix | Delete
ensure
[169] Fix | Delete
ftp.close
[170] Fix | Delete
end
[171] Fix | Delete
else
[172] Fix | Delete
new(host, *args)
[173] Fix | Delete
end
[174] Fix | Delete
end
[175] Fix | Delete
[176] Fix | Delete
# :call-seq:
[177] Fix | Delete
# Net::FTP.new(host = nil, options = {})
[178] Fix | Delete
#
[179] Fix | Delete
# Creates and returns a new +FTP+ object. If a +host+ is given, a connection
[180] Fix | Delete
# is made.
[181] Fix | Delete
#
[182] Fix | Delete
# +options+ is an option hash, each key of which is a symbol.
[183] Fix | Delete
#
[184] Fix | Delete
# The available options are:
[185] Fix | Delete
#
[186] Fix | Delete
# port:: Port number (default value is 21)
[187] Fix | Delete
# ssl:: If options[:ssl] is true, then an attempt will be made
[188] Fix | Delete
# to use SSL (now TLS) to connect to the server. For this
[189] Fix | Delete
# to work OpenSSL [OSSL] and the Ruby OpenSSL [RSSL]
[190] Fix | Delete
# extensions need to be installed. If options[:ssl] is a
[191] Fix | Delete
# hash, it's passed to OpenSSL::SSL::SSLContext#set_params
[192] Fix | Delete
# as parameters.
[193] Fix | Delete
# private_data_connection:: If true, TLS is used for data connections.
[194] Fix | Delete
# Default: +true+ when options[:ssl] is true.
[195] Fix | Delete
# username:: Username for login. If options[:username] is the string
[196] Fix | Delete
# "anonymous" and the options[:password] is +nil+,
[197] Fix | Delete
# "anonymous@" is used as a password.
[198] Fix | Delete
# password:: Password for login.
[199] Fix | Delete
# account:: Account information for ACCT.
[200] Fix | Delete
# passive:: When +true+, the connection is in passive mode. Default:
[201] Fix | Delete
# +true+.
[202] Fix | Delete
# open_timeout:: Number of seconds to wait for the connection to open.
[203] Fix | Delete
# See Net::FTP#open_timeout for details. Default: +nil+.
[204] Fix | Delete
# read_timeout:: Number of seconds to wait for one block to be read.
[205] Fix | Delete
# See Net::FTP#read_timeout for details. Default: +60+.
[206] Fix | Delete
# ssl_handshake_timeout:: Number of seconds to wait for the TLS
[207] Fix | Delete
# handshake.
[208] Fix | Delete
# See Net::FTP#ssl_handshake_timeout for
[209] Fix | Delete
# details. Default: +nil+.
[210] Fix | Delete
# use_pasv_ip:: When +true+, use the IP address in PASV responses.
[211] Fix | Delete
# Otherwise, it uses the same IP address for the control
[212] Fix | Delete
# connection. Default: +false+.
[213] Fix | Delete
# debug_mode:: When +true+, all traffic to and from the server is
[214] Fix | Delete
# written to +$stdout+. Default: +false+.
[215] Fix | Delete
#
[216] Fix | Delete
def initialize(host = nil, user_or_options = {}, passwd = nil, acct = nil)
[217] Fix | Delete
super()
[218] Fix | Delete
begin
[219] Fix | Delete
options = user_or_options.to_hash
[220] Fix | Delete
rescue NoMethodError
[221] Fix | Delete
# for backward compatibility
[222] Fix | Delete
options = {}
[223] Fix | Delete
options[:username] = user_or_options
[224] Fix | Delete
options[:password] = passwd
[225] Fix | Delete
options[:account] = acct
[226] Fix | Delete
end
[227] Fix | Delete
@host = nil
[228] Fix | Delete
if options[:ssl]
[229] Fix | Delete
unless defined?(OpenSSL::SSL)
[230] Fix | Delete
raise "SSL extension not installed"
[231] Fix | Delete
end
[232] Fix | Delete
ssl_params = options[:ssl] == true ? {} : options[:ssl]
[233] Fix | Delete
@ssl_context = SSLContext.new
[234] Fix | Delete
@ssl_context.set_params(ssl_params)
[235] Fix | Delete
if defined?(VerifyCallbackProc)
[236] Fix | Delete
@ssl_context.verify_callback = VerifyCallbackProc
[237] Fix | Delete
end
[238] Fix | Delete
@ssl_context.session_cache_mode =
[239] Fix | Delete
OpenSSL::SSL::SSLContext::SESSION_CACHE_CLIENT |
[240] Fix | Delete
OpenSSL::SSL::SSLContext::SESSION_CACHE_NO_INTERNAL_STORE
[241] Fix | Delete
@ssl_context.session_new_cb = proc {|sock, sess| @ssl_session = sess }
[242] Fix | Delete
@ssl_session = nil
[243] Fix | Delete
if options[:private_data_connection].nil?
[244] Fix | Delete
@private_data_connection = true
[245] Fix | Delete
else
[246] Fix | Delete
@private_data_connection = options[:private_data_connection]
[247] Fix | Delete
end
[248] Fix | Delete
else
[249] Fix | Delete
@ssl_context = nil
[250] Fix | Delete
if options[:private_data_connection]
[251] Fix | Delete
raise ArgumentError,
[252] Fix | Delete
"private_data_connection can be set to true only when ssl is enabled"
[253] Fix | Delete
end
[254] Fix | Delete
@private_data_connection = false
[255] Fix | Delete
end
[256] Fix | Delete
@binary = true
[257] Fix | Delete
if options[:passive].nil?
[258] Fix | Delete
@passive = @@default_passive
[259] Fix | Delete
else
[260] Fix | Delete
@passive = options[:passive]
[261] Fix | Delete
end
[262] Fix | Delete
if options[:debug_mode].nil?
[263] Fix | Delete
@debug_mode = false
[264] Fix | Delete
else
[265] Fix | Delete
@debug_mode = options[:debug_mode]
[266] Fix | Delete
end
[267] Fix | Delete
@resume = false
[268] Fix | Delete
@bare_sock = @sock = NullSocket.new
[269] Fix | Delete
@logged_in = false
[270] Fix | Delete
@open_timeout = options[:open_timeout]
[271] Fix | Delete
@ssl_handshake_timeout = options[:ssl_handshake_timeout]
[272] Fix | Delete
@read_timeout = options[:read_timeout] || 60
[273] Fix | Delete
@use_pasv_ip = options[:use_pasv_ip] || false
[274] Fix | Delete
if host
[275] Fix | Delete
connect(host, options[:port] || FTP_PORT)
[276] Fix | Delete
if options[:username]
[277] Fix | Delete
login(options[:username], options[:password], options[:account])
[278] Fix | Delete
end
[279] Fix | Delete
end
[280] Fix | Delete
end
[281] Fix | Delete
[282] Fix | Delete
# A setter to toggle transfers in binary mode.
[283] Fix | Delete
# +newmode+ is either +true+ or +false+
[284] Fix | Delete
def binary=(newmode)
[285] Fix | Delete
if newmode != @binary
[286] Fix | Delete
@binary = newmode
[287] Fix | Delete
send_type_command if @logged_in
[288] Fix | Delete
end
[289] Fix | Delete
end
[290] Fix | Delete
[291] Fix | Delete
# Sends a command to destination host, with the current binary sendmode
[292] Fix | Delete
# type.
[293] Fix | Delete
#
[294] Fix | Delete
# If binary mode is +true+, then "TYPE I" (image) is sent, otherwise "TYPE
[295] Fix | Delete
# A" (ascii) is sent.
[296] Fix | Delete
def send_type_command # :nodoc:
[297] Fix | Delete
if @binary
[298] Fix | Delete
voidcmd("TYPE I")
[299] Fix | Delete
else
[300] Fix | Delete
voidcmd("TYPE A")
[301] Fix | Delete
end
[302] Fix | Delete
end
[303] Fix | Delete
private :send_type_command
[304] Fix | Delete
[305] Fix | Delete
# Toggles transfers in binary mode and yields to a block.
[306] Fix | Delete
# This preserves your current binary send mode, but allows a temporary
[307] Fix | Delete
# transaction with binary sendmode of +newmode+.
[308] Fix | Delete
#
[309] Fix | Delete
# +newmode+ is either +true+ or +false+
[310] Fix | Delete
def with_binary(newmode) # :nodoc:
[311] Fix | Delete
oldmode = binary
[312] Fix | Delete
self.binary = newmode
[313] Fix | Delete
begin
[314] Fix | Delete
yield
[315] Fix | Delete
ensure
[316] Fix | Delete
self.binary = oldmode
[317] Fix | Delete
end
[318] Fix | Delete
end
[319] Fix | Delete
private :with_binary
[320] Fix | Delete
[321] Fix | Delete
# Obsolete
[322] Fix | Delete
def return_code # :nodoc:
[323] Fix | Delete
warn("Net::FTP#return_code is obsolete and do nothing", uplevel: 1)
[324] Fix | Delete
return "\n"
[325] Fix | Delete
end
[326] Fix | Delete
[327] Fix | Delete
# Obsolete
[328] Fix | Delete
def return_code=(s) # :nodoc:
[329] Fix | Delete
warn("Net::FTP#return_code= is obsolete and do nothing", uplevel: 1)
[330] Fix | Delete
end
[331] Fix | Delete
[332] Fix | Delete
# Constructs a socket with +host+ and +port+.
[333] Fix | Delete
#
[334] Fix | Delete
# If SOCKSSocket is defined and the environment (ENV) defines
[335] Fix | Delete
# SOCKS_SERVER, then a SOCKSSocket is returned, else a Socket is
[336] Fix | Delete
# returned.
[337] Fix | Delete
def open_socket(host, port) # :nodoc:
[338] Fix | Delete
return Timeout.timeout(@open_timeout, OpenTimeout) {
[339] Fix | Delete
if defined? SOCKSSocket and ENV["SOCKS_SERVER"]
[340] Fix | Delete
@passive = true
[341] Fix | Delete
SOCKSSocket.open(host, port)
[342] Fix | Delete
else
[343] Fix | Delete
Socket.tcp(host, port)
[344] Fix | Delete
end
[345] Fix | Delete
}
[346] Fix | Delete
end
[347] Fix | Delete
private :open_socket
[348] Fix | Delete
[349] Fix | Delete
def start_tls_session(sock)
[350] Fix | Delete
ssl_sock = SSLSocket.new(sock, @ssl_context)
[351] Fix | Delete
ssl_sock.sync_close = true
[352] Fix | Delete
ssl_sock.hostname = @host if ssl_sock.respond_to? :hostname=
[353] Fix | Delete
if @ssl_session &&
[354] Fix | Delete
Process.clock_gettime(Process::CLOCK_REALTIME) < @ssl_session.time.to_f + @ssl_session.timeout
[355] Fix | Delete
# ProFTPD returns 425 for data connections if session is not reused.
[356] Fix | Delete
ssl_sock.session = @ssl_session
[357] Fix | Delete
end
[358] Fix | Delete
ssl_socket_connect(ssl_sock, @ssl_handshake_timeout || @open_timeout)
[359] Fix | Delete
if @ssl_context.verify_mode != VERIFY_NONE
[360] Fix | Delete
ssl_sock.post_connection_check(@host)
[361] Fix | Delete
end
[362] Fix | Delete
return ssl_sock
[363] Fix | Delete
end
[364] Fix | Delete
private :start_tls_session
[365] Fix | Delete
[366] Fix | Delete
#
[367] Fix | Delete
# Establishes an FTP connection to host, optionally overriding the default
[368] Fix | Delete
# port. If the environment variable +SOCKS_SERVER+ is set, sets up the
[369] Fix | Delete
# connection through a SOCKS proxy. Raises an exception (typically
[370] Fix | Delete
# <tt>Errno::ECONNREFUSED</tt>) if the connection cannot be established.
[371] Fix | Delete
#
[372] Fix | Delete
def connect(host, port = FTP_PORT)
[373] Fix | Delete
if @debug_mode
[374] Fix | Delete
print "connect: ", host, ", ", port, "\n"
[375] Fix | Delete
end
[376] Fix | Delete
synchronize do
[377] Fix | Delete
@host = host
[378] Fix | Delete
@bare_sock = open_socket(host, port)
[379] Fix | Delete
@sock = BufferedSocket.new(@bare_sock, read_timeout: @read_timeout)
[380] Fix | Delete
voidresp
[381] Fix | Delete
if @ssl_context
[382] Fix | Delete
begin
[383] Fix | Delete
voidcmd("AUTH TLS")
[384] Fix | Delete
ssl_sock = start_tls_session(@bare_sock)
[385] Fix | Delete
@sock = BufferedSSLSocket.new(ssl_sock, read_timeout: @read_timeout)
[386] Fix | Delete
if @private_data_connection
[387] Fix | Delete
voidcmd("PBSZ 0")
[388] Fix | Delete
voidcmd("PROT P")
[389] Fix | Delete
end
[390] Fix | Delete
rescue OpenSSL::SSL::SSLError, OpenTimeout
[391] Fix | Delete
@sock.close
[392] Fix | Delete
raise
[393] Fix | Delete
end
[394] Fix | Delete
end
[395] Fix | Delete
end
[396] Fix | Delete
end
[397] Fix | Delete
[398] Fix | Delete
#
[399] Fix | Delete
# Set the socket used to connect to the FTP server.
[400] Fix | Delete
#
[401] Fix | Delete
# May raise FTPReplyError if +get_greeting+ is false.
[402] Fix | Delete
def set_socket(sock, get_greeting = true)
[403] Fix | Delete
synchronize do
[404] Fix | Delete
@sock = sock
[405] Fix | Delete
if get_greeting
[406] Fix | Delete
voidresp
[407] Fix | Delete
end
[408] Fix | Delete
end
[409] Fix | Delete
end
[410] Fix | Delete
[411] Fix | Delete
# If string +s+ includes the PASS command (password), then the contents of
[412] Fix | Delete
# the password are cleaned from the string using "*"
[413] Fix | Delete
def sanitize(s) # :nodoc:
[414] Fix | Delete
if s =~ /^PASS /i
[415] Fix | Delete
return s[0, 5] + "*" * (s.length - 5)
[416] Fix | Delete
else
[417] Fix | Delete
return s
[418] Fix | Delete
end
[419] Fix | Delete
end
[420] Fix | Delete
private :sanitize
[421] Fix | Delete
[422] Fix | Delete
# Ensures that +line+ has a control return / line feed (CRLF) and writes
[423] Fix | Delete
# it to the socket.
[424] Fix | Delete
def putline(line) # :nodoc:
[425] Fix | Delete
if @debug_mode
[426] Fix | Delete
print "put: ", sanitize(line), "\n"
[427] Fix | Delete
end
[428] Fix | Delete
if /[\r\n]/ =~ line
[429] Fix | Delete
raise ArgumentError, "A line must not contain CR or LF"
[430] Fix | Delete
end
[431] Fix | Delete
line = line + CRLF
[432] Fix | Delete
@sock.write(line)
[433] Fix | Delete
end
[434] Fix | Delete
private :putline
[435] Fix | Delete
[436] Fix | Delete
# Reads a line from the sock. If EOF, then it will raise EOFError
[437] Fix | Delete
def getline # :nodoc:
[438] Fix | Delete
line = @sock.readline # if get EOF, raise EOFError
[439] Fix | Delete
line.sub!(/(\r\n|\n|\r)\z/n, "")
[440] Fix | Delete
if @debug_mode
[441] Fix | Delete
print "get: ", sanitize(line), "\n"
[442] Fix | Delete
end
[443] Fix | Delete
return line
[444] Fix | Delete
end
[445] Fix | Delete
private :getline
[446] Fix | Delete
[447] Fix | Delete
# Receive a section of lines until the response code's match.
[448] Fix | Delete
def getmultiline # :nodoc:
[449] Fix | Delete
lines = []
[450] Fix | Delete
lines << getline
[451] Fix | Delete
code = lines.last.slice(/\A([0-9a-zA-Z]{3})-/, 1)
[452] Fix | Delete
if code
[453] Fix | Delete
delimiter = code + " "
[454] Fix | Delete
begin
[455] Fix | Delete
lines << getline
[456] Fix | Delete
end until lines.last.start_with?(delimiter)
[457] Fix | Delete
end
[458] Fix | Delete
return lines.join("\n") + "\n"
[459] Fix | Delete
end
[460] Fix | Delete
private :getmultiline
[461] Fix | Delete
[462] Fix | Delete
# Receives a response from the destination host.
[463] Fix | Delete
#
[464] Fix | Delete
# Returns the response code or raises FTPTempError, FTPPermError, or
[465] Fix | Delete
# FTPProtoError
[466] Fix | Delete
def getresp # :nodoc:
[467] Fix | Delete
@last_response = getmultiline
[468] Fix | Delete
@last_response_code = @last_response[0, 3]
[469] Fix | Delete
case @last_response_code
[470] Fix | Delete
when /\A[123]/
[471] Fix | Delete
return @last_response
[472] Fix | Delete
when /\A4/
[473] Fix | Delete
raise FTPTempError, @last_response
[474] Fix | Delete
when /\A5/
[475] Fix | Delete
raise FTPPermError, @last_response
[476] Fix | Delete
else
[477] Fix | Delete
raise FTPProtoError, @last_response
[478] Fix | Delete
end
[479] Fix | Delete
end
[480] Fix | Delete
private :getresp
[481] Fix | Delete
[482] Fix | Delete
# Receives a response.
[483] Fix | Delete
#
[484] Fix | Delete
# Raises FTPReplyError if the first position of the response code is not
[485] Fix | Delete
# equal 2.
[486] Fix | Delete
def voidresp # :nodoc:
[487] Fix | Delete
resp = getresp
[488] Fix | Delete
if !resp.start_with?("2")
[489] Fix | Delete
raise FTPReplyError, resp
[490] Fix | Delete
end
[491] Fix | Delete
end
[492] Fix | Delete
private :voidresp
[493] Fix | Delete
[494] Fix | Delete
#
[495] Fix | Delete
# Sends a command and returns the response.
[496] Fix | Delete
#
[497] Fix | Delete
def sendcmd(cmd)
[498] Fix | Delete
synchronize do
[499] Fix | Delete
It is recommended that you Edit text format, this type of Fix handles quite a lot in one request
Function