1999-10-13 03:29:15 -04:00
|
|
|
=begin
|
|
|
|
|
2000-02-21 10:27:49 -05:00
|
|
|
= net/protocol.rb
|
1999-10-13 03:29:15 -04:00
|
|
|
|
1999-12-17 10:00:13 -05:00
|
|
|
written by Minero Aoki <aamine@dp.u-netsurf.ne.jp>
|
1999-10-13 03:29:15 -04:00
|
|
|
|
1999-12-29 06:14:04 -05:00
|
|
|
This library is distributed under the terms of the Ruby license.
|
|
|
|
You can freely distribute/modify this library.
|
1999-10-13 03:29:15 -04:00
|
|
|
|
|
|
|
=end
|
|
|
|
|
1999-09-22 03:32:33 -04:00
|
|
|
|
|
|
|
require 'socket'
|
|
|
|
|
|
|
|
|
1999-12-17 10:00:13 -05:00
|
|
|
module Net
|
1999-09-22 03:32:33 -04:00
|
|
|
|
2000-04-18 05:39:02 -04:00
|
|
|
Version = '1.1.14'
|
1999-09-22 03:32:33 -04:00
|
|
|
|
1999-10-13 03:29:15 -04:00
|
|
|
=begin
|
1999-09-22 03:32:33 -04:00
|
|
|
|
1999-12-29 06:14:04 -05:00
|
|
|
== Net::Protocol
|
1999-10-13 03:29:15 -04:00
|
|
|
|
1999-12-29 06:14:04 -05:00
|
|
|
the abstruct class for Internet protocol
|
1999-10-13 03:29:15 -04:00
|
|
|
|
|
|
|
=== Super Class
|
|
|
|
|
|
|
|
Object
|
|
|
|
|
|
|
|
=== Class Methods
|
|
|
|
|
|
|
|
: new( address = 'localhost', port = nil )
|
2000-02-21 10:27:49 -05:00
|
|
|
This method Creates a new protocol object.
|
1999-10-13 03:29:15 -04:00
|
|
|
|
|
|
|
: start( address = 'localhost', port = nil, *args )
|
2000-02-21 10:27:49 -05:00
|
|
|
: start( address = 'localhost', port = nil, *args ){|proto| .... }
|
|
|
|
This method creates a new Protocol object and start session.
|
|
|
|
If you call this method with block, Protocol object give itself
|
1999-10-13 03:29:15 -04:00
|
|
|
to block and finish session when block returns.
|
|
|
|
|
1999-12-29 06:14:04 -05:00
|
|
|
: Proxy( address, port )
|
|
|
|
This method creates a proxy class of its protocol.
|
|
|
|
Arguments are address/port of proxy host.
|
|
|
|
|
1999-10-13 03:29:15 -04:00
|
|
|
|
|
|
|
=== Methods
|
|
|
|
|
|
|
|
: address
|
|
|
|
the address of connecting server (FQDN).
|
|
|
|
|
|
|
|
: port
|
|
|
|
connecting port number
|
|
|
|
|
|
|
|
: start( *args )
|
1999-12-29 06:14:04 -05:00
|
|
|
This method start protocol. If you call this method when the protocol
|
1999-10-13 03:29:15 -04:00
|
|
|
is already started, this only returns false without doing anything.
|
|
|
|
|
|
|
|
'*args' are specified in subclasses.
|
|
|
|
|
|
|
|
: finish
|
1999-12-29 06:14:04 -05:00
|
|
|
This method ends protocol. If you call this method before protocol starts,
|
1999-10-13 03:29:15 -04:00
|
|
|
it only return false without doing anything.
|
|
|
|
|
|
|
|
: active?
|
|
|
|
true if session have been started
|
|
|
|
|
|
|
|
=end
|
|
|
|
|
1999-12-29 06:14:04 -05:00
|
|
|
class Protocol
|
1999-12-17 10:00:13 -05:00
|
|
|
|
2000-02-21 10:27:49 -05:00
|
|
|
Version = ::Net::Version
|
|
|
|
|
1999-12-17 10:00:13 -05:00
|
|
|
class << self
|
|
|
|
|
|
|
|
def start( address = 'localhost', port = nil, *args )
|
1999-12-29 06:14:04 -05:00
|
|
|
instance = new( address, port )
|
1999-12-17 10:00:13 -05:00
|
|
|
|
|
|
|
if iterator? then
|
1999-12-29 06:14:04 -05:00
|
|
|
instance.start( *args ) { yield instance }
|
1999-12-17 10:00:13 -05:00
|
|
|
else
|
1999-12-29 06:14:04 -05:00
|
|
|
instance.start *args
|
|
|
|
instance
|
1999-12-17 10:00:13 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
1999-12-22 08:49:13 -05:00
|
|
|
def Proxy( p_addr, p_port )
|
|
|
|
klass = Class.new( self )
|
|
|
|
klass.module_eval %-
|
|
|
|
|
|
|
|
def initialize( addr, port )
|
|
|
|
@proxyaddr = '#{p_addr}'
|
|
|
|
@proxyport = '#{p_port}'
|
|
|
|
super @proxyaddr, @proxyport
|
|
|
|
@address = addr
|
|
|
|
@port = port
|
|
|
|
end
|
|
|
|
|
2000-03-31 08:02:40 -05:00
|
|
|
def connect( addr = nil, port = nil )
|
1999-12-29 06:14:04 -05:00
|
|
|
super @proxyaddr, @proxyport
|
1999-12-22 08:49:13 -05:00
|
|
|
end
|
|
|
|
private :connect
|
|
|
|
|
2000-03-05 05:25:53 -05:00
|
|
|
attr_reader :proxyaddr, :proxyport
|
1999-12-22 08:49:13 -05:00
|
|
|
-
|
|
|
|
def klass.proxy?
|
|
|
|
true
|
|
|
|
end
|
|
|
|
|
|
|
|
klass
|
|
|
|
end
|
|
|
|
|
|
|
|
def proxy?
|
|
|
|
false
|
|
|
|
end
|
|
|
|
|
|
|
|
|
1999-12-17 10:00:13 -05:00
|
|
|
private
|
|
|
|
|
1999-12-29 06:14:04 -05:00
|
|
|
def protocol_param( name, val )
|
1999-12-17 10:00:13 -05:00
|
|
|
module_eval %-
|
|
|
|
def self.#{name.id2name}
|
|
|
|
#{val}
|
|
|
|
end
|
|
|
|
-
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
#
|
|
|
|
# sub-class requirements
|
|
|
|
#
|
1999-12-29 06:14:04 -05:00
|
|
|
# protocol_param command_type
|
|
|
|
# protocol_param port
|
1999-12-17 10:00:13 -05:00
|
|
|
#
|
|
|
|
# private method do_start (optional)
|
|
|
|
# private method do_finish (optional)
|
|
|
|
#
|
|
|
|
|
1999-12-29 06:14:04 -05:00
|
|
|
protocol_param :port, 'nil'
|
|
|
|
protocol_param :command_type, 'nil'
|
2000-02-21 10:27:49 -05:00
|
|
|
protocol_param :socket_type, '::Net::Socket'
|
1999-12-17 10:00:13 -05:00
|
|
|
|
|
|
|
|
1999-12-29 06:14:04 -05:00
|
|
|
def initialize( addr = nil, port = nil )
|
|
|
|
@address = addr || 'localhost'
|
2000-03-27 10:52:27 -05:00
|
|
|
@port = port || type.port
|
1999-12-17 10:00:13 -05:00
|
|
|
|
|
|
|
@active = false
|
|
|
|
@pipe = nil
|
|
|
|
|
1999-12-29 06:14:04 -05:00
|
|
|
@command = nil
|
1999-12-17 10:00:13 -05:00
|
|
|
@socket = nil
|
|
|
|
end
|
|
|
|
|
|
|
|
|
2000-03-05 05:25:53 -05:00
|
|
|
attr_reader :address, :port,
|
|
|
|
:command, :socket
|
1999-12-17 10:00:13 -05:00
|
|
|
|
|
|
|
|
1999-09-22 03:32:33 -04:00
|
|
|
def start( *args )
|
|
|
|
return false if active?
|
|
|
|
|
1999-12-17 10:00:13 -05:00
|
|
|
begin
|
2000-03-27 10:52:27 -05:00
|
|
|
connect
|
1999-12-17 10:00:13 -05:00
|
|
|
do_start *args
|
2000-03-27 10:52:27 -05:00
|
|
|
@active = true
|
1999-12-17 10:00:13 -05:00
|
|
|
yield if iterator?
|
|
|
|
ensure
|
|
|
|
finish if iterator?
|
1999-09-22 03:32:33 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def finish
|
2000-03-05 05:25:53 -05:00
|
|
|
ret = active?
|
1999-12-17 10:00:13 -05:00
|
|
|
|
2000-03-27 10:52:27 -05:00
|
|
|
do_finish
|
2000-03-05 05:25:53 -05:00
|
|
|
disconnect
|
|
|
|
@active = false
|
1999-09-22 03:32:33 -04:00
|
|
|
|
2000-03-05 05:25:53 -05:00
|
|
|
ret
|
1999-09-22 03:32:33 -04:00
|
|
|
end
|
|
|
|
|
1999-12-17 10:00:13 -05:00
|
|
|
def active?
|
|
|
|
@active
|
|
|
|
end
|
1999-09-22 03:32:33 -04:00
|
|
|
|
1999-12-17 10:00:13 -05:00
|
|
|
def set_pipe( arg ) # un-documented
|
1999-10-13 03:29:15 -04:00
|
|
|
@pipe = arg
|
|
|
|
end
|
|
|
|
|
1999-12-17 10:00:13 -05:00
|
|
|
|
|
|
|
private
|
|
|
|
|
|
|
|
|
|
|
|
def do_start
|
|
|
|
end
|
|
|
|
|
|
|
|
def do_finish
|
2000-03-05 05:25:53 -05:00
|
|
|
@command.quit
|
1999-12-17 10:00:13 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
|
2000-03-27 10:52:27 -05:00
|
|
|
def connect( addr = @address, port = @port )
|
|
|
|
@socket = type.socket_type.open( addr, port, @pipe )
|
|
|
|
@command = type.command_type.new( @socket )
|
1999-12-17 10:00:13 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def disconnect
|
1999-12-29 06:14:04 -05:00
|
|
|
@command = nil
|
2000-03-05 05:25:53 -05:00
|
|
|
if @socket and not @socket.closed? then
|
|
|
|
@socket.close
|
|
|
|
end
|
1999-12-29 06:14:04 -05:00
|
|
|
@socket = nil
|
1999-12-17 10:00:13 -05:00
|
|
|
end
|
2000-03-27 10:52:27 -05:00
|
|
|
|
1999-09-22 03:32:33 -04:00
|
|
|
end
|
|
|
|
|
1999-12-29 06:14:04 -05:00
|
|
|
Session = Protocol
|
|
|
|
|
1999-09-22 03:32:33 -04:00
|
|
|
|
|
|
|
|
|
|
|
class Command
|
|
|
|
|
|
|
|
def initialize( sock )
|
|
|
|
@socket = sock
|
2000-03-05 05:25:53 -05:00
|
|
|
@last_reply = nil
|
2000-03-27 10:52:27 -05:00
|
|
|
@critical = false
|
1999-09-22 03:32:33 -04:00
|
|
|
end
|
|
|
|
|
2000-04-18 05:39:02 -04:00
|
|
|
attr_accessor :socket
|
|
|
|
attr_reader :last_reply
|
1999-09-22 03:32:33 -04:00
|
|
|
|
2000-03-27 10:52:27 -05:00
|
|
|
# abstract quit
|
1999-09-22 03:32:33 -04:00
|
|
|
|
2000-03-05 05:25:53 -05:00
|
|
|
|
1999-09-22 03:32:33 -04:00
|
|
|
private
|
|
|
|
|
2000-03-05 05:25:53 -05:00
|
|
|
# abstract get_reply()
|
|
|
|
|
1999-09-22 03:32:33 -04:00
|
|
|
def check_reply( *oks )
|
2000-03-05 05:25:53 -05:00
|
|
|
@last_reply = get_reply
|
|
|
|
reply_must( @last_reply, *oks )
|
1999-12-22 08:49:13 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def reply_must( rep, *oks )
|
1999-09-22 03:32:33 -04:00
|
|
|
oks.each do |i|
|
|
|
|
if i === rep then
|
|
|
|
return rep
|
|
|
|
end
|
|
|
|
end
|
2000-04-18 05:39:02 -04:00
|
|
|
rep.error!
|
1999-09-22 03:32:33 -04:00
|
|
|
end
|
1999-12-29 06:14:04 -05:00
|
|
|
|
|
|
|
def getok( line, ok = SuccessCode )
|
|
|
|
@socket.writeline line
|
|
|
|
check_reply ok
|
|
|
|
end
|
2000-03-27 10:52:27 -05:00
|
|
|
|
|
|
|
|
|
|
|
def critical
|
|
|
|
return if @critical
|
|
|
|
@critical = true
|
|
|
|
r = yield
|
|
|
|
@critical = false
|
|
|
|
r
|
|
|
|
end
|
|
|
|
|
|
|
|
def critical?
|
|
|
|
@critical
|
|
|
|
end
|
|
|
|
|
|
|
|
def begin_critical
|
|
|
|
ret = @critical
|
|
|
|
@critical = true
|
|
|
|
not ret
|
|
|
|
end
|
|
|
|
|
|
|
|
def end_critical
|
|
|
|
@critical = false
|
|
|
|
end
|
|
|
|
|
1999-09-22 03:32:33 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
|
2000-03-31 08:02:40 -05:00
|
|
|
class Response
|
1999-09-22 03:32:33 -04:00
|
|
|
|
2000-03-31 08:02:40 -05:00
|
|
|
def initialize( ctype, cno, msg )
|
|
|
|
@code_type = ctype
|
|
|
|
@code = cno
|
|
|
|
@message = msg
|
|
|
|
super()
|
2000-03-26 03:48:15 -05:00
|
|
|
end
|
|
|
|
|
2000-03-31 08:02:40 -05:00
|
|
|
attr_reader :code_type, :code, :message
|
|
|
|
alias msg message
|
1999-09-22 03:32:33 -04:00
|
|
|
|
2000-04-18 05:39:02 -04:00
|
|
|
def error!
|
|
|
|
raise @code_type.error_type, @code + ' ' + Net.quote(@message)
|
1999-09-22 03:32:33 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
2000-03-31 08:02:40 -05:00
|
|
|
class ProtocolError < StandardError; end
|
|
|
|
class ProtoSyntaxError < ProtocolError; end
|
|
|
|
class ProtoFatalError < ProtocolError; end
|
|
|
|
class ProtoUnknownError < ProtocolError; end
|
|
|
|
class ProtoServerError < ProtocolError; end
|
|
|
|
class ProtoAuthError < ProtocolError; end
|
|
|
|
class ProtoCommandError < ProtocolError; end
|
|
|
|
class ProtoRetriableError < ProtocolError; end
|
|
|
|
ProtocRetryError = ProtoRetriableError
|
1999-12-17 10:00:13 -05:00
|
|
|
|
|
|
|
|
2000-03-31 08:02:40 -05:00
|
|
|
class Code
|
1999-12-17 10:00:13 -05:00
|
|
|
|
2000-03-31 08:02:40 -05:00
|
|
|
def initialize( paren, err )
|
|
|
|
@parents = paren
|
|
|
|
@err = err
|
1999-12-17 10:00:13 -05:00
|
|
|
|
2000-03-31 08:02:40 -05:00
|
|
|
@parents.push self
|
|
|
|
end
|
1999-12-17 10:00:13 -05:00
|
|
|
|
2000-03-31 08:02:40 -05:00
|
|
|
attr_reader :parents
|
|
|
|
|
|
|
|
def error_type
|
|
|
|
@err
|
|
|
|
end
|
|
|
|
|
|
|
|
def ===( response )
|
|
|
|
response.code_type.parents.reverse_each {|i| return true if i == self }
|
|
|
|
false
|
|
|
|
end
|
1999-12-22 08:49:13 -05:00
|
|
|
|
2000-03-31 08:02:40 -05:00
|
|
|
def mkchild( err = nil )
|
|
|
|
type.new( @parents + [self], err || @err )
|
|
|
|
end
|
|
|
|
|
1999-09-22 03:32:33 -04:00
|
|
|
end
|
2000-03-31 08:02:40 -05:00
|
|
|
|
|
|
|
ReplyCode = Code.new( [], ProtoUnknownError )
|
|
|
|
SuccessCode = ReplyCode.mkchild( ProtoUnknownError )
|
|
|
|
ContinueCode = ReplyCode.mkchild( ProtoUnknownError )
|
|
|
|
ErrorCode = ReplyCode.mkchild( ProtocolError )
|
|
|
|
SyntaxErrorCode = ErrorCode.mkchild( ProtoSyntaxError )
|
|
|
|
FatalErrorCode = ErrorCode.mkchild( ProtoFatalError )
|
|
|
|
ServerErrorCode = ErrorCode.mkchild( ProtoServerError )
|
|
|
|
RetriableCode = ReplyCode.mkchild( ProtoRetriableError )
|
|
|
|
UnknownCode = ReplyCode.mkchild( ProtoUnknownError )
|
1999-09-22 03:32:33 -04:00
|
|
|
|
|
|
|
|
2000-02-21 10:27:49 -05:00
|
|
|
|
|
|
|
class WriteAdapter
|
|
|
|
|
|
|
|
def initialize( sock, mid )
|
|
|
|
@sock = sock
|
|
|
|
@mid = mid
|
|
|
|
end
|
|
|
|
|
|
|
|
def write( str )
|
|
|
|
@sock.__send__ @mid, str
|
|
|
|
end
|
|
|
|
alias << write
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
class ReadAdapter
|
|
|
|
|
|
|
|
def initialize( block )
|
|
|
|
@block = block
|
|
|
|
end
|
|
|
|
|
|
|
|
def <<( str )
|
|
|
|
@block.call str
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
class Socket
|
1999-12-17 10:00:13 -05:00
|
|
|
|
|
|
|
def initialize( addr, port, pipe = nil )
|
|
|
|
@addr = addr
|
|
|
|
@port = port
|
|
|
|
@pipe = pipe
|
2000-03-31 08:02:40 -05:00
|
|
|
@prepipe = nil
|
1999-12-17 10:00:13 -05:00
|
|
|
|
|
|
|
@closed = true
|
|
|
|
@ipaddr = ''
|
|
|
|
@sending = ''
|
|
|
|
@buffer = ''
|
|
|
|
|
|
|
|
@socket = TCPsocket.new( addr, port )
|
|
|
|
@closed = false
|
|
|
|
@ipaddr = @socket.addr[3]
|
|
|
|
end
|
|
|
|
|
|
|
|
attr :pipe, true
|
|
|
|
|
|
|
|
class << self
|
|
|
|
alias open new
|
|
|
|
end
|
|
|
|
|
|
|
|
def reopen
|
|
|
|
unless closed? then
|
|
|
|
@socket.close
|
2000-01-21 07:52:24 -05:00
|
|
|
@buffer = ''
|
1999-12-17 10:00:13 -05:00
|
|
|
end
|
|
|
|
@socket = TCPsocket.new( @addr, @port )
|
|
|
|
end
|
|
|
|
|
|
|
|
attr :socket, true
|
|
|
|
|
|
|
|
def close
|
|
|
|
@socket.close
|
|
|
|
@closed = true
|
|
|
|
end
|
|
|
|
|
|
|
|
def closed?
|
|
|
|
@closed
|
|
|
|
end
|
|
|
|
|
|
|
|
def address
|
|
|
|
@addr.dup
|
|
|
|
end
|
|
|
|
alias addr address
|
|
|
|
|
2000-03-05 05:25:53 -05:00
|
|
|
attr_reader :port
|
1999-12-17 10:00:13 -05:00
|
|
|
|
|
|
|
def ip_address
|
|
|
|
@ipaddr.dup
|
|
|
|
end
|
|
|
|
alias ipaddr ip_address
|
|
|
|
|
2000-03-05 05:25:53 -05:00
|
|
|
attr_reader :sending
|
1999-12-17 10:00:13 -05:00
|
|
|
|
|
|
|
|
|
|
|
CRLF = "\r\n"
|
|
|
|
D_CRLF = ".\r\n"
|
|
|
|
TERMEXP = /\n|\r\n|\r/o
|
|
|
|
|
|
|
|
|
2000-03-31 08:02:40 -05:00
|
|
|
def read( len, dest = '' )
|
|
|
|
@pipe << "reading #{len} bytes...\n" if @pipe; pipeoff
|
1999-12-17 10:00:13 -05:00
|
|
|
|
1999-09-22 03:32:33 -04:00
|
|
|
rsize = 0
|
|
|
|
while rsize + @buffer.size < len do
|
2000-03-31 08:02:40 -05:00
|
|
|
rsize += writeinto( dest, @buffer.size )
|
1999-09-22 03:32:33 -04:00
|
|
|
fill_rbuf
|
|
|
|
end
|
2000-03-31 08:02:40 -05:00
|
|
|
writeinto( dest, len - rsize )
|
1999-09-22 03:32:33 -04:00
|
|
|
|
2000-03-31 08:02:40 -05:00
|
|
|
@pipe << "read #{len} bytes\n" if pipeon
|
|
|
|
dest
|
1999-09-22 03:32:33 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
|
2000-03-31 08:02:40 -05:00
|
|
|
def read_all( dest = '' )
|
|
|
|
@pipe << "reading all...\n" if @pipe; pipeoff
|
2000-01-21 07:52:24 -05:00
|
|
|
|
|
|
|
rsize = 0
|
|
|
|
begin
|
|
|
|
while true do
|
2000-03-31 08:02:40 -05:00
|
|
|
rsize += writeinto( dest, @buffer.size )
|
2000-01-21 07:52:24 -05:00
|
|
|
fill_rbuf
|
|
|
|
end
|
|
|
|
rescue EOFError
|
|
|
|
;
|
|
|
|
end
|
|
|
|
|
2000-03-31 08:02:40 -05:00
|
|
|
@pipe << "read #{rsize} bytes\n" if pipeon
|
|
|
|
dest
|
2000-01-21 07:52:24 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
|
1999-09-22 03:32:33 -04:00
|
|
|
def readuntil( target )
|
2000-03-31 08:02:40 -05:00
|
|
|
while true do
|
|
|
|
idx = @buffer.index( target )
|
|
|
|
break if idx
|
1999-09-22 03:32:33 -04:00
|
|
|
fill_rbuf
|
|
|
|
end
|
|
|
|
|
2000-03-31 08:02:40 -05:00
|
|
|
dest = ''
|
|
|
|
writeinto( dest, idx + target.size )
|
|
|
|
dest
|
1999-09-22 03:32:33 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
def readline
|
|
|
|
ret = readuntil( CRLF )
|
|
|
|
ret.chop!
|
1999-12-17 10:00:13 -05:00
|
|
|
ret
|
1999-09-22 03:32:33 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
|
2000-03-31 08:02:40 -05:00
|
|
|
def read_pendstr( dest )
|
|
|
|
@pipe << "reading text...\n" if @pipe; pipeoff
|
1999-09-22 03:32:33 -04:00
|
|
|
|
|
|
|
rsize = 0
|
|
|
|
|
|
|
|
while (str = readuntil( CRLF )) != D_CRLF do
|
|
|
|
rsize += str.size
|
|
|
|
str.gsub!( /\A\./o, '' )
|
|
|
|
dest << str
|
|
|
|
end
|
|
|
|
|
2000-03-31 08:02:40 -05:00
|
|
|
@pipe << "read #{rsize} bytes\n" if pipeon
|
1999-12-17 10:00:13 -05:00
|
|
|
dest
|
1999-09-22 03:32:33 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
def read_pendlist
|
2000-03-31 08:02:40 -05:00
|
|
|
@pipe << "reading list...\n" if @pipe; pipeoff
|
1999-10-13 03:29:15 -04:00
|
|
|
|
1999-09-22 03:32:33 -04:00
|
|
|
arr = []
|
|
|
|
str = nil
|
|
|
|
|
|
|
|
while (str = readuntil( CRLF )) != D_CRLF do
|
|
|
|
str.chop!
|
|
|
|
arr.push str
|
|
|
|
yield str if iterator?
|
|
|
|
end
|
|
|
|
|
2000-03-31 08:02:40 -05:00
|
|
|
@pipe << "read #{arr.size} lines\n" if pipeon
|
1999-12-17 10:00:13 -05:00
|
|
|
arr
|
1999-09-22 03:32:33 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
private
|
|
|
|
|
|
|
|
|
|
|
|
READ_BLOCK = 1024 * 8
|
|
|
|
|
|
|
|
def fill_rbuf
|
|
|
|
@buffer << @socket.sysread( READ_BLOCK )
|
|
|
|
end
|
|
|
|
|
2000-03-31 08:02:40 -05:00
|
|
|
def writeinto( dest, len )
|
1999-09-22 03:32:33 -04:00
|
|
|
bsi = @buffer.size
|
2000-03-31 08:02:40 -05:00
|
|
|
dest << @buffer[ 0, len ]
|
1999-09-22 03:32:33 -04:00
|
|
|
@buffer = @buffer[ len, bsi - len ]
|
|
|
|
|
2000-03-31 08:02:40 -05:00
|
|
|
@pipe << %{read "#{Net.quote dest}"\n} if @pipe
|
2000-01-21 07:52:24 -05:00
|
|
|
len
|
1999-12-17 10:00:13 -05:00
|
|
|
end
|
1999-09-22 03:32:33 -04:00
|
|
|
|
|
|
|
|
|
|
|
public
|
|
|
|
|
|
|
|
|
2000-03-26 03:48:15 -05:00
|
|
|
def write( str )
|
1999-09-22 03:32:33 -04:00
|
|
|
do_write_beg
|
2000-02-21 10:27:49 -05:00
|
|
|
do_write_do str
|
1999-12-17 10:00:13 -05:00
|
|
|
do_write_fin
|
1999-09-22 03:32:33 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
|
2000-03-26 03:48:15 -05:00
|
|
|
def writeline( str )
|
1999-09-22 03:32:33 -04:00
|
|
|
do_write_beg
|
2000-03-26 03:48:15 -05:00
|
|
|
do_write_do str
|
|
|
|
do_write_do CRLF
|
1999-12-17 10:00:13 -05:00
|
|
|
do_write_fin
|
1999-09-22 03:32:33 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
|
2000-03-31 08:02:40 -05:00
|
|
|
def write_bin( src, block )
|
1999-09-22 03:32:33 -04:00
|
|
|
do_write_beg
|
2000-03-26 03:48:15 -05:00
|
|
|
if block then
|
|
|
|
block.call WriteAdapter.new( self, :do_write_do )
|
2000-02-21 10:27:49 -05:00
|
|
|
else
|
2000-03-26 03:48:15 -05:00
|
|
|
src.each do |bin|
|
|
|
|
do_write_do bin
|
|
|
|
end
|
2000-02-21 10:27:49 -05:00
|
|
|
end
|
1999-12-17 10:00:13 -05:00
|
|
|
do_write_fin
|
1999-09-22 03:32:33 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
|
2000-03-31 08:02:40 -05:00
|
|
|
def write_pendstr( src, block )
|
|
|
|
@pipe << "writing text from #{src.type}\n" if @pipe; pipeoff
|
1999-09-22 03:32:33 -04:00
|
|
|
|
|
|
|
do_write_beg
|
2000-03-31 08:02:40 -05:00
|
|
|
if block then
|
|
|
|
block.call WriteAdapter.new( self, :write_pendstr_inner )
|
2000-02-21 10:27:49 -05:00
|
|
|
else
|
|
|
|
write_pendstr_inner src
|
1999-09-22 03:32:33 -04:00
|
|
|
end
|
2000-02-21 10:27:49 -05:00
|
|
|
each_crlf_line2( :i_w_pend )
|
1999-09-22 03:32:33 -04:00
|
|
|
do_write_do D_CRLF
|
|
|
|
wsize = do_write_fin
|
|
|
|
|
2000-03-31 08:02:40 -05:00
|
|
|
@pipe << "wrote #{wsize} bytes text" if pipeon
|
1999-12-17 10:00:13 -05:00
|
|
|
wsize
|
1999-09-22 03:32:33 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
private
|
|
|
|
|
|
|
|
|
2000-02-21 10:27:49 -05:00
|
|
|
def write_inner( src )
|
|
|
|
each_crlf_line( src, :do_write_do )
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
def write_pendstr_inner( src )
|
|
|
|
each_crlf_line src, :i_w_pend
|
|
|
|
end
|
|
|
|
|
|
|
|
def i_w_pend( line )
|
|
|
|
do_write_do '.' if line[0] == ?.
|
|
|
|
do_write_do line
|
|
|
|
end
|
|
|
|
|
1999-09-22 03:32:33 -04:00
|
|
|
|
2000-02-21 10:27:49 -05:00
|
|
|
def each_crlf_line( src, mid )
|
|
|
|
beg = 0
|
|
|
|
buf = pos = s = bin = nil
|
1999-09-22 03:32:33 -04:00
|
|
|
|
2000-02-21 10:27:49 -05:00
|
|
|
adding( src ) do
|
1999-09-22 03:32:33 -04:00
|
|
|
beg = 0
|
2000-02-21 10:27:49 -05:00
|
|
|
buf = @wbuf
|
2000-03-31 08:02:40 -05:00
|
|
|
while true do
|
|
|
|
pos = buf.index( TERMEXP, beg )
|
|
|
|
break unless pos
|
1999-12-22 08:49:13 -05:00
|
|
|
s = $&.size
|
|
|
|
break if pos + s == buf.size - 1 and buf[-1] == ?\r
|
|
|
|
|
2000-03-31 08:02:40 -05:00
|
|
|
__send__ mid, buf[ beg, pos - beg ] << CRLF
|
1999-12-22 08:49:13 -05:00
|
|
|
beg = pos + s
|
1999-09-22 03:32:33 -04:00
|
|
|
end
|
2000-02-21 10:27:49 -05:00
|
|
|
@wbuf = buf[ beg, buf.size - beg ] if beg != 0
|
1999-09-22 03:32:33 -04:00
|
|
|
end
|
2000-02-21 10:27:49 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def adding( src )
|
|
|
|
i = nil
|
|
|
|
|
|
|
|
case src
|
|
|
|
when String
|
|
|
|
0.step( src.size, 512 ) do |i|
|
|
|
|
@wbuf << src[ i, 512 ]
|
|
|
|
yield
|
|
|
|
end
|
|
|
|
|
|
|
|
when File
|
2000-03-31 08:02:40 -05:00
|
|
|
while true do
|
|
|
|
i = src.read( 512 )
|
|
|
|
break unless i
|
2000-02-21 10:27:49 -05:00
|
|
|
@wbuf << i
|
|
|
|
yield
|
|
|
|
end
|
|
|
|
|
|
|
|
else
|
|
|
|
src.each do |bin|
|
|
|
|
@wbuf << bin
|
|
|
|
yield if @wbuf.size > 512
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def each_crlf_line2( mid )
|
|
|
|
buf = @wbuf
|
|
|
|
beg = pos = nil
|
1999-09-22 03:32:33 -04:00
|
|
|
|
|
|
|
buf << "\n" unless /\n|\r/o === buf[-1,1]
|
|
|
|
|
|
|
|
beg = 0
|
2000-03-31 08:02:40 -05:00
|
|
|
while true do
|
|
|
|
pos = buf.index( TERMEXP, beg )
|
|
|
|
break unless pos
|
|
|
|
__send__ mid, buf[ beg, pos - beg ] << CRLF
|
1999-12-22 08:49:13 -05:00
|
|
|
beg = pos + $&.size
|
1999-09-22 03:32:33 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
def do_write_beg
|
|
|
|
@writtensize = 0
|
|
|
|
@sending = ''
|
2000-02-21 10:27:49 -05:00
|
|
|
@wbuf = ''
|
1999-09-22 03:32:33 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def do_write_do( arg )
|
1999-12-17 10:00:13 -05:00
|
|
|
if @pipe or @sending.size < 128 then
|
|
|
|
@sending << Net.quote( arg )
|
1999-09-22 03:32:33 -04:00
|
|
|
else
|
|
|
|
@sending << '...' unless @sending[-1] == ?.
|
|
|
|
end
|
1999-10-13 03:29:15 -04:00
|
|
|
|
1999-09-22 03:32:33 -04:00
|
|
|
s = @socket.write( arg )
|
|
|
|
@writtensize += s
|
1999-12-17 10:00:13 -05:00
|
|
|
s
|
1999-09-22 03:32:33 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def do_write_fin
|
1999-10-13 03:29:15 -04:00
|
|
|
if @pipe then
|
1999-12-17 10:00:13 -05:00
|
|
|
@pipe << 'write "'
|
|
|
|
@pipe << @sending
|
|
|
|
@pipe << "\"\n"
|
1999-10-13 03:29:15 -04:00
|
|
|
end
|
1999-09-22 03:32:33 -04:00
|
|
|
|
|
|
|
@socket.flush
|
1999-12-17 10:00:13 -05:00
|
|
|
@writtensize
|
1999-09-22 03:32:33 -04:00
|
|
|
end
|
|
|
|
|
2000-03-31 08:02:40 -05:00
|
|
|
|
|
|
|
def pipeoff
|
|
|
|
@prepipe = @pipe
|
|
|
|
@pipe = nil
|
|
|
|
@prepipe
|
|
|
|
end
|
|
|
|
|
|
|
|
def pipeon
|
|
|
|
@pipe = @prepipe
|
|
|
|
@prepipe = nil
|
|
|
|
@pipe
|
|
|
|
end
|
|
|
|
|
1999-12-17 10:00:13 -05:00
|
|
|
end
|
1999-09-22 03:32:33 -04:00
|
|
|
|
|
|
|
|
1999-12-17 10:00:13 -05:00
|
|
|
def Net.quote( str )
|
|
|
|
str = str.gsub( "\n", '\\n' )
|
|
|
|
str.gsub!( "\r", '\\r' )
|
|
|
|
str.gsub!( "\t", '\\t' )
|
|
|
|
str
|
1999-09-22 03:32:33 -04:00
|
|
|
end
|
|
|
|
|
1999-12-17 10:00:13 -05:00
|
|
|
end # module Net
|