Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

232 lines
5.6 KiB

  1. // WatcherTelnetClient.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "WATCHER.h"
  5. #include "WatcherTelnetClient.h"
  6. #ifdef _DEBUG
  7. #define new DEBUG_NEW
  8. #undef THIS_FILE
  9. static char THIS_FILE[] = __FILE__;
  10. #endif
  11. #include "WATCHERView.h"
  12. /////////////////////////////////////////////////////////////////////////////
  13. // WatcherTelnetClient
  14. WatcherTelnetClient::WatcherTelnetClient(LPBYTE cmd, int cmdLen,
  15. LPBYTE lgn, int lgnLen)
  16. :CommandSequence(NO_COMMAND),
  17. lenLogin(lgnLen),
  18. Login(lgn),
  19. OptionIndex(0),
  20. PacketNumber(3),
  21. SentTermType(FALSE)
  22. {
  23. Command = cmd;
  24. DocView = NULL;
  25. lenCommand = cmdLen;
  26. }
  27. WatcherTelnetClient::~WatcherTelnetClient()
  28. {
  29. if (Login){
  30. delete [] Login;
  31. Login = NULL;
  32. }
  33. if (Command){
  34. delete [] Command;
  35. Command = NULL;
  36. }
  37. WatcherSocket::~WatcherSocket();
  38. }
  39. // Do not edit the following lines, which are needed by ClassWizard.
  40. #if 0
  41. BEGIN_MESSAGE_MAP(WatcherTelnetClient, WatcherSocket)
  42. //{{AFX_MSG_MAP(WatcherTelnetClient)
  43. //}}AFX_MSG_MAP
  44. END_MESSAGE_MAP()
  45. #endif // 0
  46. /////////////////////////////////////////////////////////////////////////////
  47. // WatcherTelnetClient member functions
  48. void WatcherTelnetClient::OnReceive(int nErrorCode)
  49. {
  50. BYTE Buffer[MAX_BUFFER_SIZE];
  51. int i,nRet,ret;
  52. if (nErrorCode != 0) {
  53. DocView->GetParent()->PostMessage(WM_CLOSE, 0,0);
  54. return;
  55. }
  56. nRet = Receive(Buffer, MAX_BUFFER_SIZE, 0);
  57. if(nRet <= 0) return;
  58. for(i=0;i<nRet;i++){
  59. ret = ProcessByte(Buffer[i]);
  60. }
  61. if (PacketNumber == 0){
  62. WatcherSocket::OnReceive(nErrorCode);
  63. return;
  64. }
  65. if(PacketNumber == 3){
  66. if(Login){
  67. Send(Login, lenLogin, 0);
  68. }
  69. PacketNumber --;
  70. WatcherSocket::OnReceive(nErrorCode);
  71. return;
  72. }
  73. if (SentTermType){
  74. if(PacketNumber == 1){
  75. if(Command){
  76. int ret = Send(Command, lenCommand, 0);
  77. }
  78. }
  79. PacketNumber --;
  80. }
  81. WatcherSocket::OnReceive(nErrorCode);
  82. return;
  83. }
  84. int WatcherTelnetClient::ProcessByte(BYTE byte)
  85. {
  86. // Watch in general for Telnet Sequences and
  87. // generate appropriate responses.
  88. // Otherwise pass on the character to the View
  89. // which will be configured for a particular console.
  90. if ((byte == 255)&&(CommandSequence == NO_COMMAND)){
  91. CommandSequence = IAC;
  92. return 0;
  93. }
  94. switch (CommandSequence){
  95. case NO_COMMAND:
  96. // Send the character to the document view
  97. ((CWatcherView *)DocView)->ProcessByte(byte);
  98. break;
  99. case IAC:
  100. // A Command Sequence is beginning
  101. CommandSequence = byte;
  102. break;
  103. case DO:
  104. // Options are here
  105. // Only one byte options allowed
  106. // So fall through
  107. case DONT:
  108. // Same as above;
  109. case WILL:
  110. // same
  111. case WONT:
  112. Options[OptionIndex] = byte;
  113. ProcessCommand(CommandSequence);
  114. CommandSequence=NO_COMMAND;
  115. OptionIndex = 0;
  116. break;
  117. case SB:
  118. // Might be a long list, so just go on
  119. // until a SE is encountered
  120. Options[OptionIndex]=byte;
  121. if (byte == SE){
  122. ProcessSBCommand(CommandSequence);
  123. OptionIndex = 0;
  124. CommandSequence = NO_COMMAND;
  125. }
  126. else{
  127. OptionIndex++;
  128. if (OptionIndex == MAX_BUFFER_SIZE){
  129. // Cant have such a long command, can we??
  130. OptionIndex = 0;
  131. CommandSequence = NO_COMMAND;
  132. }
  133. }
  134. break;
  135. default:
  136. // Cant recognize the command
  137. OptionIndex = 0;
  138. CommandSequence = NO_COMMAND;
  139. break;
  140. }
  141. return 0;
  142. }
  143. void WatcherTelnetClient::ProcessCommand(BYTE cmd)
  144. {
  145. BYTE sbuf[MAX_BUFFER_SIZE];
  146. switch(cmd){
  147. case DO:
  148. sbuf[0] = IAC;
  149. sbuf[1] = WONT;
  150. switch(Options[0]){
  151. case TO_NAWS:
  152. // terminal size is sent here.
  153. sbuf[1] = WILL;
  154. sbuf[2] = TO_NAWS;
  155. sbuf[3] = IAC;
  156. sbuf[4] = SB;
  157. sbuf[5] = TO_NAWS;
  158. sbuf[6] = 0;
  159. sbuf[7] = MAX_TERMINAL_WIDTH;
  160. sbuf[8] = 0;
  161. sbuf[9] = MAX_TERMINAL_HEIGHT;
  162. sbuf[10] = IAC;
  163. sbuf[11] = SE;
  164. Send(sbuf, 12, 0);
  165. break;
  166. case TO_TERM_TYPE:
  167. // will then subnegotiate the parameters.
  168. sbuf[1]=WILL;
  169. default:
  170. // just negate everything you dont understand :-)
  171. sbuf[2] = Options[0];
  172. Send(sbuf,3,0);
  173. break;
  174. }
  175. default:
  176. break;
  177. }
  178. }
  179. void WatcherTelnetClient::ProcessSBCommand(BYTE cmd)
  180. {
  181. BYTE sbuf[MAX_BUFFER_SIZE];
  182. switch(Options[0]){
  183. case TO_TERM_TYPE:
  184. sbuf[0] = IAC;
  185. sbuf[1] = SB;
  186. sbuf[2] = TO_TERM_TYPE;
  187. sbuf[3] = TT_IS;
  188. sbuf[4] = 'A';
  189. sbuf[5] = 'N';
  190. sbuf[6] = 'S';
  191. sbuf[7] = 'I';
  192. sbuf[8] = IAC;
  193. sbuf[9] = SE;
  194. Send(sbuf,10,0);
  195. // May have to renegotiate the terminal type.
  196. // If we connect to a real Terminal concentrator
  197. // do we have to do all this ??
  198. SentTermType = TRUE;
  199. break;
  200. default:
  201. break;
  202. }
  203. return;
  204. }
  205. void WatcherTelnetClient::OnClose(int nErrorCode)
  206. {
  207. // this was just for debug purposes.
  208. // If the error code is not zero, ie we
  209. // had fatal errors on send and receive.
  210. BOOL ret = (DocView->GetParent())->PostMessage(WM_CLOSE,0,0);
  211. WatcherSocket::OnClose(nErrorCode);
  212. return;
  213. }