=begin = net/session.rb version 1.1.1 written by Minero Aoki This library is distributed under the terms of Ruby style license. You can freely distribute/modify this file. =end require 'socket' module Net =begin == Net::Session the abstruct class for Internet session === Super Class Object === Constants : Version The version of Session class. It is a string like "1.1.1". === Class Methods : new( address = 'localhost', port = nil ) This method Create a new Session object. : start( address = 'localhost', port = nil, *args ) : start( address = 'localhost', port = nil, *args ){|session| .... } This method create a new Session object and start session. If you call this method with block, Session object give itself to block and finish session when block returns. === Methods : address the address of connecting server (FQDN). : port connecting port number : start( *args ) This method start session. If you call this method when the session is already started, this only returns false without doing anything. '*args' are specified in subclasses. : finish This method finish session. If you call this method before session starts, it only return false without doing anything. : active? true if session have been started =end class Session Version = '1.1.1' class << self def start( address = 'localhost', port = nil, *args ) session = new( address, port ) if iterator? then session.start( *args ) { yield session } else session.start *args session end end private def session_setvar( name, val ) module_eval %- def self.#{name.id2name} #{val} end - end end # # sub-class requirements # # class method command_type # class method port # # private method proto_initialize # private method do_start (optional) # private method do_finish (optional) # session_setvar :port, 'nil' session_setvar :command_type, 'nil' session_setvar :socket_type, 'ProtocolSocket' def initialize( addr = 'localhost', port = nil ) @address = addr @port = port || self.type.port @active = false @pipe = nil @proto = nil @socket = nil end attr :address attr :port attr :socket def start( *args ) return false if active? @active = true begin connect do_start *args yield if iterator? ensure finish if iterator? end end def finish if @proto 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 @socket = self.type.socket_type.open( @address, @port, @pipe ) @proto = self.type.command_type.new( @socket ) end def disconnect @proto.quit @proto = nil @socket = nil end end =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 finishes protocol. =end class Command def initialize( sock ) @socket = sock end attr :socket, true def quit if @socket and not @socket.closed? then begin do_quit ensure @socket.close unless @socket.closed? @socket = nil end end end private def check_reply( *oks ) rep = get_reply oks.each do |i| if i === rep then return rep end end rep.error! @socket.sending 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 ReplyCode def initialize( cod, mes ) @code = cod @msg = mes end attr :code attr :msg def error!( sending ) mes = <