001: package kawa; // For now
002:
003: import java.io.*;
004:
005: /**
006: * An input stream that handles the telnet protocol.
007: * It handles the special telnet sequences starting with the
008: * "Interpret As Command".(IAC==255) byte.
009: */
010:
011: public class TelnetInputStream extends FilterInputStream {
012: Telnet connection;
013:
014: public TelnetInputStream(InputStream in, Telnet conn)
015: throws IOException {
016: super (in);
017: buf = new byte[512];
018: this .connection = conn;
019: }
020:
021: protected byte[] buf;
022:
023: int pos;
024: int count;
025:
026: /** The state of control bytes we have seen. */
027: int state = 0;
028:
029: int subCommandLength = 0;
030:
031: static final int SB_IAC = 400;
032:
033: public int read() throws IOException {
034: for (;;) {
035: if (pos >= count) {
036: int avail = in.available();
037: if (avail <= 0)
038: avail = 1;
039: else if (avail > buf.length - subCommandLength) {
040: avail = buf.length - subCommandLength; // FIXME
041: }
042: avail = in.read(buf, subCommandLength, avail);
043: pos = subCommandLength;
044: count = avail;
045: if (avail <= 0)
046: return -1;
047: }
048: int ch = buf[pos++] & 0xff;
049: if (state == 0) {
050: if (ch != Telnet.IAC)
051: return ch;
052: state = Telnet.IAC;
053: continue;
054: } else if (state == Telnet.IAC) {
055: if (ch == Telnet.IAC) {
056: state = 0;
057: return Telnet.IAC;
058: } else if (ch == Telnet.WILL || ch == Telnet.WONT
059: || ch == Telnet.DO || ch == Telnet.DONT
060: || ch == Telnet.SB) {
061: state = ch;
062: } else if (ch == Telnet.IP) {
063: System.err.println("Interrupt Process");
064: state = 0;
065: } else if (ch == Telnet.EOF) {
066: return -1;
067: } else {
068: state = 0; // ???
069: }
070: } else if (state == Telnet.WILL || state == Telnet.WONT
071: || state == Telnet.DO || state == Telnet.DONT) {
072: connection.handle(state, ch);
073: state = 0;
074: } else if (state == Telnet.SB) {
075: if (ch == Telnet.IAC)
076: state = SB_IAC;
077: else
078: buf[subCommandLength++] = (byte) ch;
079: } else if (state == SB_IAC) {
080: if (ch == Telnet.IAC) {
081: buf[subCommandLength++] = (byte) ch;
082: state = Telnet.SB;
083: } else if (ch == Telnet.SE) {
084: connection.subCommand(buf, 0, subCommandLength);
085: state = 0;
086: subCommandLength = 0;
087: } else // Error?
088: {
089: state = 0;
090: subCommandLength = 0;
091: }
092: } else
093: System.err.println("Bad state " + state);
094: }
095: }
096:
097: public int read(byte[] b, int offset, int length)
098: throws IOException {
099: if (length <= 0)
100: return 0;
101: int done = 0;
102: if (state != 0 || pos >= count) {
103: int ch = read();
104: if (ch < 0)
105: return ch;
106: b[offset++] = (byte) ch;
107: done++;
108: }
109: if (state == 0) {
110: while (pos < count && done < length) {
111: byte ch = buf[pos];
112: if (ch == (byte) Telnet.IAC)
113: break;
114: b[offset++] = ch;
115: done++;
116: pos++;
117: }
118: }
119: return done;
120: }
121: }
|