X-Git-Url: https://mudpy.org/gitweb?p=mudpy.git;a=blobdiff_plain;f=mudpy%2Ftelnet.py;h=ec18f70a64e0881671f1880da6ddbe61c2732d7b;hp=e483c13deecccbe2bc54f540a361fbf1444e2582;hb=29041014a531835bf9b6a80ca9d7ed414a929432;hpb=c01384b805b4b52135264015e35011431710a659 diff --git a/mudpy/telnet.py b/mudpy/telnet.py index e483c13..ec18f70 100644 --- a/mudpy/telnet.py +++ b/mudpy/telnet.py @@ -1,6 +1,6 @@ """Telnet functions and constants for the mudpy engine.""" -# Copyright (c) 2004-2019 mudpy authors. Permission to use, copy, +# Copyright (c) 2004-2020 mudpy authors. Permission to use, copy, # modify, and distribute this software is granted under terms # provided in the LICENSE file distributed with this software. @@ -24,11 +24,11 @@ option_names = { TELOPT_LINEMODE: "line mode", } -# TODO(fungi): implement support for RFC 1091 terminal type information supported = ( TELOPT_BINARY, TELOPT_ECHO, TELOPT_SGA, + TELOPT_TTYPE, TELOPT_EOR, TELOPT_NAWS, TELOPT_LINEMODE @@ -80,6 +80,14 @@ party_names = { US: "us", } +# RFC 1091 commands +IS = 0 +SEND = 1 +ttype_command_names = { + IS: "is", + SEND: "send", +} + def log(message, user): """Log debugging info for Telnet client/server interactions.""" @@ -163,13 +171,24 @@ def disable(user, telopt, party): user.telopts[(telopt, party)] = WANTNO +def request_ttype(user): + """Clear and request the terminal type.""" + + # only actually request if the corresponding telopt is enabled + if is_enabled(user, TELOPT_TTYPE, HIM): + # set to the empty string to indicate it's been requested + user.ttype = "" + user.send(telnet_proto(IAC, SB, TELOPT_TTYPE, SEND, IAC, SE), raw=True) + log('Sent terminal type request to', user) + + def negotiate_telnet_options(user): """Reply to and remove telnet negotiation options from partial_input.""" # make a local copy to play with text = user.partial_input - # start at the begining of the input + # start at the beginning of the input position = 0 # as long as we haven't checked it all @@ -245,11 +264,16 @@ def negotiate_telnet_options(user): # subnegotiation options elif len_text > position + 4 and command is SB: telopt = text[position + 2] - if telopt is TELOPT_NAWS: - user.columns = ( - text[position + 3] * 256 + text[position + 4]) end_subnegotiation = text.find(telnet_proto(IAC, SE), position) if end_subnegotiation > 0: + if telopt is TELOPT_NAWS: + user.columns = ( + text[position + 3] * 256 + text[position + 4]) + user.rows = ( + text[position + 5] * 256 + text[position + 6]) + elif telopt is TELOPT_TTYPE and text[position + 3] is IS: + user.ttype = ( + text[position + 4:end_subnegotiation]).decode("ascii") text = text[:position] + text[end_subnegotiation + 2:] else: position += 1 @@ -259,7 +283,7 @@ def negotiate_telnet_options(user): log("Ignored unknown command %s from" % command, user) text = text[:position] + text[position + 2:] - # and this means we got the begining of an IAC + # and this means we got the beginning of an IAC else: position += 1