From 6f82a67fd0035fcd2802f1564165d5211bc98ea2 Mon Sep 17 00:00:00 2001 From: aamine Date: Mon, 21 Feb 2000 15:27:49 +0000 Subject: Version 1.1.5 o session.rb -> protocol.rb git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@623 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- lib/net/protocol.rb | 804 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 804 insertions(+) create mode 100644 lib/net/protocol.rb (limited to 'lib/net/protocol.rb') diff --git a/lib/net/protocol.rb b/lib/net/protocol.rb new file mode 100644 index 0000000000..aa8a007adf --- /dev/null +++ b/lib/net/protocol.rb @@ -0,0 +1,804 @@ +=begin + += net/protocol.rb + +written by Minero Aoki + +This library is distributed under the terms of the Ruby license. +You can freely distribute/modify this library. + +=end + + +require 'socket' + + +module Net + + Version = '1.1.5' + +=begin + +== Net::Protocol + +the abstruct class for Internet protocol + +=== Super Class + +Object + +=== Class Methods + +: new( address = 'localhost', port = nil ) + This method Creates a new protocol object. + +: start( address = 'localhost', port = nil, *args ) +: 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 + to block and finish session when block returns. + +: Proxy( address, port ) + This method creates a proxy class of its protocol. + Arguments are address/port of proxy host. + + +=== Methods + +: address + the address of connecting server (FQDN). + +: port + connecting port number + +: start( *args ) + This method start protocol. If you call this method when the protocol + is already started, this only returns false without doing anything. + + '*args' are specified in subclasses. + +: finish + This method ends protocol. If you call this method before protocol starts, + it only return false without doing anything. + +: active? + true if session have been started + +=end + + class Protocol + + Version = ::Net::Version + + class << self + + def start( address = 'localhost', port = nil, *args ) + instance = new( address, port ) + + if iterator? then + instance.start( *args ) { yield instance } + else + instance.start *args + instance + end + end + + 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 + + def connect( addr, port ) + super @proxyaddr, @proxyport + end + private :connect + + attr :proxyaddr + attr :proxyport + - + def klass.proxy? + true + end + + klass + end + + def proxy? + false + end + + + private + + def protocol_param( name, val ) + module_eval %- + def self.#{name.id2name} + #{val} + end + - + end + + end + + + # + # sub-class requirements + # + # protocol_param command_type + # protocol_param port + # + # private method do_start (optional) + # private method do_finish (optional) + # + + protocol_param :port, 'nil' + protocol_param :command_type, 'nil' + protocol_param :socket_type, '::Net::Socket' + + + def initialize( addr = nil, port = nil ) + @address = addr || 'localhost' + @port = port || self.type.port + + @active = false + @pipe = nil + + @command = nil + @socket = nil + end + + + attr :address + attr :port + + attr :command + attr :socket + + + def start( *args ) + return false if active? + @active = true + + begin + connect @address, @port + do_start *args + yield if iterator? + ensure + finish if iterator? + end + end + + def finish + if @command then + do_finish + disconnect + end + + if @socket and not @socket.closed? then + @socket.close + @socket = nil + end + + if active? then + @active = false + + return true + else + return false + end + end + + def active? + @active + end + + def set_pipe( arg ) # un-documented + @pipe = arg + end + + + private + + + def do_start + end + + def do_finish + end + + + def connect( addr, port ) + @socket = self.type.socket_type.open( addr, port, @pipe ) + @command = self.type.command_type.new( @socket ) + end + + def disconnect + @command.quit + @command = nil + @socket = nil + end + + end + + Session = Protocol + + +=begin + +== Net::Command + +=== Super Class + +Object + +=== Class Methods + +: new( socket ) + This method create new Command object. 'socket' must be ProtocolSocket. + This method is abstract class. + + +=== Methods + +: quit + This method dispatch command which ends the protocol. + +=end + + class Command + + def initialize( sock ) + @socket = sock + @error_occured = false + end + + attr :socket, true + attr :error_occured + + def quit + if @socket and not @socket.closed? then + begin + do_quit + ensure + @socket.close unless @socket.closed? + @socket = nil + end + @error_occured = false + end + end + + private + + def check_reply( *oks ) + reply_must( get_reply, *oks ) + end + + def reply_must( rep, *oks ) + oks.each do |i| + if i === rep then + return rep + end + end + + @error_occured = true + rep.error! @socket.sending + end + + def getok( line, ok = SuccessCode ) + @socket.writeline line + check_reply ok + end + + end + + + 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 ProtoRetryError < ProtocolError ; end + + class ReplyCode + + def initialize( cod, mes ) + @code = cod + @msg = mes + end + + attr :code + attr :msg + + def error!( sending ) + mes = < 512 + end + end + end + + def each_crlf_line2( mid ) + buf = @wbuf + beg = pos = nil + + buf << "\n" unless /\n|\r/o === buf[-1,1] + + beg = 0 + while pos = buf.index( TERMEXP, beg ) do + send mid, buf[ beg, pos - beg ] << CRLF + beg = pos + $&.size + end + end + + + def do_write_beg + @writtensize = 0 + @sending = '' + @wbuf = '' + end + + def do_write_do( arg ) + if @pipe or @sending.size < 128 then + @sending << Net.quote( arg ) + else + @sending << '...' unless @sending[-1] == ?. + end + + s = @socket.write( arg ) + @writtensize += s + s + end + + def do_write_fin + if @pipe then + @pipe << 'write "' + @pipe << @sending + @pipe << "\"\n" + end + + @socket.flush + @writtensize + end + + end + + + def Net.quote( str ) + str = str.gsub( "\n", '\\n' ) + str.gsub!( "\r", '\\r' ) + str.gsub!( "\t", '\\t' ) + str + end + +end # module Net -- cgit v1.2.3