TelnetInputStream.java 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. package kawa; // For now
  2. import java.io.*;
  3. /**
  4. * An input stream that handles the telnet protocol.
  5. * It handles the special telnet sequences starting with the
  6. * "Interpret As Command".(IAC==255) byte.
  7. */
  8. public class TelnetInputStream extends FilterInputStream
  9. {
  10. Telnet connection;
  11. public TelnetInputStream (InputStream in, Telnet conn)
  12. throws IOException
  13. {
  14. super(in);
  15. buf = new byte[512];
  16. this.connection = conn;
  17. }
  18. protected byte[] buf;
  19. int pos;
  20. int count;
  21. /** The state of control bytes we have seen. */
  22. int state = 0;
  23. int subCommandLength = 0;
  24. static final int SB_IAC = 400;
  25. public int read () throws IOException
  26. {
  27. for (;;)
  28. {
  29. if (pos >= count)
  30. {
  31. int avail = in.available();
  32. if (avail <= 0)
  33. avail = 1;
  34. else if (avail > buf.length - subCommandLength)
  35. {
  36. avail = buf.length - subCommandLength; // FIXME
  37. }
  38. avail = in.read(buf, subCommandLength, avail);
  39. pos = subCommandLength;
  40. count = avail;
  41. if (avail <= 0)
  42. return -1;
  43. }
  44. int ch = buf[pos++] & 0xff;
  45. if (state == 0)
  46. {
  47. if (ch != Telnet.IAC)
  48. return ch;
  49. state = Telnet.IAC;
  50. continue;
  51. }
  52. else if (state == Telnet.IAC)
  53. {
  54. if (ch == Telnet.IAC)
  55. {
  56. state = 0;
  57. return Telnet.IAC;
  58. }
  59. else if (ch == Telnet.WILL
  60. || ch == Telnet.WONT
  61. || ch == Telnet.DO
  62. || ch == Telnet.DONT
  63. || ch == Telnet.SB)
  64. {
  65. state = ch;
  66. }
  67. else if (ch == Telnet.IP)
  68. {
  69. System.err.println("Interrupt Process");
  70. state = 0;
  71. }
  72. else if (ch == Telnet.EOF)
  73. {
  74. return -1;
  75. }
  76. else
  77. {
  78. state = 0; // ???
  79. }
  80. }
  81. else if (state == Telnet.WILL || state == Telnet.WONT
  82. || state == Telnet.DO || state == Telnet.DONT)
  83. {
  84. connection.handle (state, ch);
  85. state = 0;
  86. }
  87. else if (state == Telnet.SB)
  88. {
  89. if (ch == Telnet.IAC)
  90. state = SB_IAC;
  91. else
  92. buf[subCommandLength++] = (byte) ch;
  93. }
  94. else if (state == SB_IAC)
  95. {
  96. if (ch == Telnet.IAC)
  97. {
  98. buf[subCommandLength++] = (byte) ch;
  99. state = Telnet.SB;
  100. }
  101. else if (ch == Telnet.SE)
  102. {
  103. connection.subCommand(buf, 0, subCommandLength);
  104. state = 0;
  105. subCommandLength = 0;
  106. }
  107. else // Error?
  108. {
  109. state = 0;
  110. subCommandLength = 0;
  111. }
  112. }
  113. else
  114. System.err.println("Bad state "+state);
  115. }
  116. }
  117. public int read (byte[] b, int offset, int length) throws IOException
  118. {
  119. if (length <= 0)
  120. return 0;
  121. int done = 0;
  122. if (state != 0 || pos >= count)
  123. {
  124. int ch = read();
  125. if (ch < 0)
  126. return ch;
  127. b[offset++] = (byte) ch;
  128. done++;
  129. }
  130. if (state == 0)
  131. {
  132. while (pos < count && done < length)
  133. {
  134. byte ch = buf[pos];
  135. if (ch == (byte) Telnet.IAC)
  136. break;
  137. b[offset++] = ch;
  138. done++;
  139. pos++;
  140. }
  141. }
  142. return done;
  143. }
  144. }