def filter_in(str)
return "" if str.nil? || str.empty?
buf = ""
@sc ? @sc.concat(str) : @sc = StringScanner.new(str)
while b = @sc.get_byte
if @pstack.urgent_on || b[0] == DM
log.debug("(#{@pstack.conn.object_id}) Sync mode on")
@pstack.urgent_on = false
@synch = true
break
end
case mode?
when :normal
case b[0]
when CR
next if @synch
set_mode(:cr) if !@pstack.binary_on
when LF
next if @synch
set_mode(:lf) if !@pstack.binary_on
buf << LF.chr
echo(CR.chr + LF.chr)
when IAC
set_mode(:cmd)
when NUL
next if @synch
if @pstack.binary_on
buf << b
echo(b)
else
log.debug("(#{@pstack.conn.object_id}) unexpected NUL found in stream")
end
when BS, DEL
next if @synch
buf << b
echo(BS.chr)
else
next if @synch
buf << b
echo(b)
end
when :cr
case b[0]
when LF
buf << LF.chr
echo(CR.chr + LF.chr)
when NUL
if @server.service_type == :client
buf << CR.chr
echo(CR.chr)
else
buf << LF.chr
echo(CR.chr + LF.chr)
end
else
buf << b
echo(b)
end
set_mode(:normal)
when :lf
case b[0]
when CR
else
buf << b
echo(b)
end
set_mode(:normal)
when :cmd
case b[0]
when IAC
buf << IAC.chr
set_mode(:normal)
when AYT
log.debug("(#{@pstack.conn.object_id}) AYT sent - Msg returned")
@pstack.conn.sock.send("TeensyMUD is here.\n",0)
set_mode(:normal)
when AO
log.debug("(#{@pstack.conn.object_id}) AO sent - Synch returned")
@pstack.conn.sockio.write_flush
@pstack.conn.sock.send(IAC.chr + DM.chr, 0)
@pstack.conn.sockio.write_urgent(DM.chr)
set_mode(:normal)
when IP
@pstack.conn.sockio.read_flush
@pstack.conn.sockio.write_flush
log.debug("(#{@pstack.conn.object_id}) IP sent")
set_mode(:normal)
when GA, NOP, BRK
log.debug("(#{@pstack.conn.object_id}) GA, NOP or BRK sent")
set_mode(:normal)
when DM
log.debug("(#{@pstack.conn.object_id}) Synch mode off")
@synch = false
set_mode(:normal)
when EC
next if @synch
log.debug("(#{@pstack.conn.object_id}) EC sent")
if buf.size > 1
buf.slice!(-1)
elsif @pstack.conn.inbuffer.size > 0
@pstack.conn.inbuffer.slice(-1)
end
set_mode(:normal)
when EL
next if @synch
log.debug("(#{@pstack.conn.object_id}) EL sent")
p = buf.rindex("\n")
if p
buf.slice!(p+1..-1)
else
buf = ""
p = @pstack.conn.inbuffer.rindex("\n")
if p
@pstack.conn.inbuffer.slice!(p+1..-1)
end
end
set_mode(:normal)
when DO, DONT, WILL, WONT
if @sc.eos?
@sc.unscan
break
end
opt = @sc.get_byte
case b[0]
when WILL
replies_him(opt[0],true)
when WONT
replies_him(opt[0],false)
when DO
requests_us(opt[0],true)
when DONT
requests_us(opt[0],false)
end
case opt[0]
when ECHO
@pstack.echo_on = enabled?(ECHO, :us)
when BINARY
@pstack.binary_on = enabled?(BINARY, :us)
when ZMP
@pstack.zmp_on = enabled?(ZMP, :us)
end
set_mode(:normal)
when SB
@sc.unscan
break if @sc.check_until(/#{IAC.chr}#{SE.chr}/).nil?
@sc.get_byte
opt = @sc.get_byte
data = @sc.scan_until(/#{IAC.chr}#{SE.chr}/).chop.chop
parse_subneg(opt[0],data)
set_mode(:normal)
else
log.debug("(#{@pstack.conn.object_id}) Unknown Telnet command - #{b[0]}")
set_mode(:normal)
end
end
end
@sc = nil if @sc.eos?
buf
end