📄 telnetio.java
字号:
rawWrite(triple[0]); rawWrite(triple[1] | LM_SLC_ACK); rawWrite(triple[2]); while (readTriple(triple)) { rawWrite(triple[0]); rawWrite(triple[1] | LM_SLC_ACK); rawWrite(triple[2]); } rawWrite(IAC); rawWrite(SE); flush(); } }//handleLMSLC public void handleLMForwardMask(int WHAT) throws IOException { switch (WHAT) { case WONT: if (WAIT_LM_DO_REPLY_FORWARDMASK) { WAIT_LM_DO_REPLY_FORWARDMASK = false; } break; } skipToSE(); }//handleLMForward public void handleNEWENV() throws IOException { log.debug("handleNEWENV()"); int c = rawread(); switch (c) { case IS: handleNEIs(); break; case NE_INFO: handleNEInfo(); break; default: //skip to (including) SE skipToSE(); } }//handleNEWENV /* The characters following a "type" up to the next "type" or VALUE specify the variable name. If a "type" is not followed by a VALUE (e.g., by another VAR, USERVAR, or IAC SE) then that variable is undefined. */ private int readNEVariableName(StringBuffer sbuf) throws IOException { log.debug("readNEVariableName()"); int i = -1; do { i = rawread(); if (i == -1) { return NE_IN_ERROR; } else if (i == IAC) { i = rawread(); if (i == IAC) { //duplicated IAC sbuf.append((char) i); } else if (i == SE) { return NE_IN_END; } else { //Error should have been duplicated return NE_IN_ERROR; } } else if (i == NE_ESC) { i = rawread(); if (i == NE_ESC || i == NE_VAR || i == NE_USERVAR || i == NE_VALUE) { sbuf.append((char) i); } else { return NE_IN_ERROR; } } else if (i == NE_VAR || i == NE_USERVAR) { return NE_VAR_UNDEFINED; } else if (i == NE_VALUE) { return NE_VAR_DEFINED; } else { //check maximum length to prevent overflow if (sbuf.length() >= NE_VAR_NAME_MAXLENGTH) { //TODO: Log Overflow return NE_IN_ERROR; } else { sbuf.append((char) i); } } } while (true); }//readNEVariableName /* The characters following a VALUE up to the next "type" specify the value of the variable. If a VALUE is immediately followed by a "type" or IAC, then the variable is defined, but has no value. If an IAC is contained between the IS and the IAC SE, it must be sent as IAC IAC. */ private int readNEVariableValue(StringBuffer sbuf) throws IOException { log.debug("readNEVariableValue()"); //check conditions for first character after VALUE int i = rawread(); if (i == -1) { return NE_IN_ERROR; } else if (i == IAC) { i = rawread(); if (i == IAC) { //Double IAC return NE_VAR_DEFINED_EMPTY; } else if (i == SE) { return NE_IN_END; } else { //according to rule IAC has to be duplicated return NE_IN_ERROR; } } else if (i == NE_VAR || i == NE_USERVAR) { return NE_VAR_DEFINED_EMPTY; } else if (i == NE_ESC) { //escaped value i = rawread(); if (i == NE_ESC || i == NE_VAR || i == NE_USERVAR || i == NE_VALUE) { sbuf.append((char) i); } else { return NE_IN_ERROR; } } else { //character sbuf.append((char) i); } //loop until end of value (IAC SE or TYPE) do { i = rawread(); if (i == -1) { return NE_IN_ERROR; } else if (i == IAC) { i = rawread(); if (i == IAC) { //duplicated IAC sbuf.append((char) i); } else if (i == SE) { return NE_IN_END; } else { //Error should have been duplicated return NE_IN_ERROR; } } else if (i == NE_ESC) { i = rawread(); if (i == NE_ESC || i == NE_VAR || i == NE_USERVAR || i == NE_VALUE) { sbuf.append((char) i); } else { return NE_IN_ERROR; } } else if (i == NE_VAR || i == NE_USERVAR) { return NE_VAR_OK; } else { //check maximum length to prevent overflow if (sbuf.length() > NE_VAR_VALUE_MAXLENGTH) { //TODO: LOG Overflow return NE_IN_ERROR; } else { sbuf.append((char) i); } } } while (true); }//readNEVariableValue public void readNEVariables() throws IOException { log.debug("readNEVariables()"); StringBuffer sbuf = new StringBuffer(50); int i = rawread(); if (i == IAC) { //invalid or empty response skipToSE(); log.debug("readNEVariables()::INVALID VARIABLE"); return; } boolean cont = true; if (i == NE_VAR || i == NE_USERVAR) { do { switch (readNEVariableName(sbuf)) { case NE_IN_ERROR: log.debug("readNEVariables()::NE_IN_ERROR"); return; case NE_IN_END: log.debug("readNEVariables()::NE_IN_END"); return; case NE_VAR_DEFINED: log.debug("readNEVariables()::NE_VAR_DEFINED"); String str = sbuf.toString(); sbuf.delete(0, sbuf.length()); switch (readNEVariableValue(sbuf)) { case NE_IN_ERROR: log.debug("readNEVariables()::NE_IN_ERROR"); return; case NE_IN_END: log.debug("readNEVariables()::NE_IN_END"); return; case NE_VAR_DEFINED_EMPTY: log.debug("readNEVariables()::NE_VAR_DEFINED_EMPTY"); break; case NE_VAR_OK: //add variable log.debug("readNEVariables()::NE_VAR_OK:VAR=" + str + " VAL=" + sbuf.toString()); TelnetIO.this.m_ConnectionData.getEnvironment().put(str, sbuf.toString()); sbuf.delete(0, sbuf.length()); break; } break; case NE_VAR_UNDEFINED: log.debug("readNEVariables()::NE_VAR_UNDEFINED"); break; } } while (cont); } }//readVariables public void handleNEIs() throws IOException { log.debug("handleNEIs()"); if (isEnabled(NEWENV)) { readNEVariables(); } }//handleNEIs public void handleNEInfo() throws IOException { log.debug("handleNEInfo()"); if (isEnabled(NEWENV)) { readNEVariables(); } }//handleNEInfo /** * Method that sends a TTYPE Subnegotiation Request. * IAC SB TERMINAL-TYPE SEND */ public void getTTYPE() throws IOException { if (isEnabled(TTYPE)) { rawWrite(IAC); rawWrite(SB); rawWrite(TTYPE); rawWrite(SEND); rawWrite(IAC); rawWrite(SE); flush(); } }//getTTYPE /** * Method that sends a LINEMODE MODE Subnegotiation request. * IAC LINEMODE MODE MASK SE */ public void negotiateLineMode() throws IOException { if (isEnabled(LINEMODE)) { rawWrite(IAC); rawWrite(SB); rawWrite(LINEMODE); rawWrite(LM_MODE); rawWrite(LM_EDIT | LM_TRAPSIG); rawWrite(IAC); rawWrite(SE); WAIT_LM_MODE_ACK = true; //dont forwardmask rawWrite(IAC); rawWrite(SB); rawWrite(LINEMODE); rawWrite(DONT); rawWrite(LM_FORWARDMASK); rawWrite(IAC); rawWrite(SE); WAIT_LM_DO_REPLY_FORWARDMASK = true; flush(); } }//negotiateLineMode /** * Method that sends a NEW-ENVIRON SEND subnegotiation request * for default variables and user variables. * IAC SB NEW-ENVIRON SEND VAR USERVAR IAC SE */ private void negotiateEnvironment() throws IOException { //log.debug("negotiateEnvironment()"); if (isEnabled(NEWENV)) { rawWrite(IAC); rawWrite(SB); rawWrite(NEWENV); rawWrite(SEND); rawWrite(NE_VAR); rawWrite(NE_USERVAR); rawWrite(IAC); rawWrite(SE); WAIT_NE_SEND_REPLY = true; flush(); } }//negotiateEnvironment /** * Method that skips a subnegotiation response. */ private void skipToSE() throws IOException { while (rawread() != SE) ; }//skipSubnegotiation private boolean readTriple(int[] triple) throws IOException { triple[0] = rawread(); triple[1] = rawread(); if ((triple[0] == IAC) && (triple[1] == SE)) { return false; } else { triple[2] = rawread(); return true; } }//readTriple /** * Method that reads a subnegotiation String, * one of those that end with a IAC SE combination. * A maximum length is observed to prevent overflow. * * @return IAC SE terminated String */ private String readIACSETerminatedString(int maxlength) throws IOException { int where = 0; char[] cbuf = new char[maxlength]; char b = ' '; boolean cont = true; do { int i; i = rawread(); switch (i) { case IAC: i = rawread(); if (i == SE) { cont = false; } break; case -1: return (new String("default")); default: } if (cont) { b = (char) i; //Fix for overflow wimpi (10/06/2004) if (b == '\n' || b == '\r' || where == maxlength) { cont = false; } else { cbuf[where++] = b; } } } while (cont); return (new String(cbuf, 0, where)); }//readIACSETerminatedString /** * Method that informs internally about the supported Negotiation Options * * @param i int that represents requested the Option * @return Boolean that represents support status */ private boolean supported(int i) { switch (i) { case SUPGA: case ECHO: case NAWS: case TTYPE: case NEWENV: return true; case LINEMODE: return m_ConnectionData.isLineMode(); default: return false; } }//supported /** * Method that sends a Telnet IAC String with TelnetIO.write(byte b) method. * * @param i int that represents requested Command Type (DO,DONT,WILL,WONT) * @param j int that represents the Option itself (e.g. ECHO, NAWS) */ private void sendCommand(int i, int j, boolean westarted) throws IOException { rawWrite(IAC); rawWrite(i); rawWrite(j); // we started with DO OPTION and now wait for reply if ((i == DO) && westarted) setWait(DO, j, true); // we started with WILL OPTION and now wait for reply if ((i == WILL) && westarted) setWait(WILL, j, true); flush(); }//sendCommand /** * Method enables or disables a supported Option * * @param i int that represents the Option */ private void enable(int i) throws IOException { switch (i) { case SUPGA: if (DO_SUPGA) { DO_SUPGA = false; } else { DO_SUPGA = true; } break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -