Telnet.cpp
上传用户:zhangwei01
上传日期:2007-01-09
资源大小:25k
文件大小:8k
源码类别:

Telnet服务器

开发平台:

Visual C++

  1. ///////////////////////////////////////////////////////////////////////
  2. // Filename: telnet.cpp
  3. //
  4. // Date    : 27-May-2001
  5. // Author  : J.Hogendoorn ( jeroenhog@gmx.net )
  6. //
  7. // Note    : this code may be used anywhere as long
  8. //         : as this comment remains. 
  9. //
  10. ///////////////////////////////////////////////////////////////////////
  11. #include "stdafx.h"
  12. #include "telnet.h"
  13. //////////////////////////////////////////////////////////////////////
  14. // Method  : constructor
  15. // In      : basic values needed for telnet service
  16. // Out     : none
  17. // Purpose : 
  18. // Note    : when userid or password are not filled in, no check will
  19. //           be performed for them
  20. CTelnet::CTelnet( const CString& sIntroScreen
  21. , const CString& sUserId
  22. , const CString& sUserIdPrompt
  23. , const CString& sPassword
  24. , const CString& sPasswordPrompt
  25. , const CString& sPrompt
  26. , DWORD          dwPortNumber
  27. )
  28. {
  29. m_sIntroScreen            = sIntroScreen;
  30. m_sUserId                 = sUserId;
  31. m_sPassword               = sPassword;
  32. m_sUserIdPrompt           = sUserIdPrompt;
  33. m_sPasswordPrompt         = sPasswordPrompt;
  34. m_dwPortNumber            = dwPortNumber;
  35. m_sPrompt                 = sPrompt;
  36. m_hThread                 = NULL;
  37. m_bIsRunning              = false;
  38. m_sLastError              = "";
  39. m_function                = NULL;
  40. m_telnetSock              = new CTelnetSocket();
  41. // events needed for checking if the start of the telnetThread succeeds
  42. m_threadStartupSuccceeded = CreateEvent( NULL , TRUE , FALSE , "threadStartUpSuccceeded" );
  43. m_threadStartupFailed     = CreateEvent( NULL , TRUE , FALSE , "threadStartUpFailed" );
  44. // critical section is needed, because some attributes of this class are
  45. // shared between telnetThread and the main thread
  46. InitializeCriticalSection( &m_critSection );
  47. // not logged on yet
  48. setNotLoggedOn();
  49. }
  50. //////////////////////////////////////////////////////////////////////
  51. // Method  : destructor
  52. // In      : none
  53. // Out     : none
  54. // Purpose : stops the telnet service
  55. // Note    : 
  56. CTelnet::~CTelnet()
  57. {
  58. cleanUp();
  59. delete m_telnetSock;
  60. }
  61. //////////////////////////////////////////////////////////////////////
  62. // Method  : setPrompt
  63. // In      : the new prompt
  64. // Out     : none
  65. // Purpose : sets the new prompt to be used
  66. // Note    : 
  67. void CTelnet::setPrompt(const CString& sPrompt )
  68. {
  69. EnterCriticalSection( &m_critSection );
  70. m_sPrompt = sPrompt;
  71. LeaveCriticalSection( &m_critSection );
  72. }
  73. //////////////////////////////////////////////////////////////////////
  74. // Method  : setLoggedOn
  75. // In      : none
  76. // Out     : none
  77. // Purpose : sets the indication that a cliennt is logged on
  78. // Note    : 
  79. void CTelnet::setLoggedOn()
  80. {
  81. EnterCriticalSection( &m_critSection );
  82. m_bLoggedOn = true;
  83. LeaveCriticalSection( &m_critSection );
  84. }
  85. //////////////////////////////////////////////////////////////////////
  86. // Method  : setNotLoggedOn
  87. // In      : none
  88. // Out     : none
  89. // Purpose : sets the indication that a cliennt is Not logged on
  90. // Note    : 
  91. void CTelnet::setNotLoggedOn()
  92. {
  93. EnterCriticalSection( &m_critSection );
  94. m_bLoggedOn = false;
  95. LeaveCriticalSection( &m_critSection );
  96. }
  97. //////////////////////////////////////////////////////////////////////
  98. // Method  : getLoggedOn
  99. // In      : none
  100. // Out     : true if logged on, false if not
  101. // Purpose : 
  102. // Note    : 
  103. bool CTelnet::getLoggedOn()
  104. {
  105. bool bRetval;
  106. EnterCriticalSection( &m_critSection );
  107. bRetval = m_bLoggedOn;
  108. LeaveCriticalSection( &m_critSection );
  109. return bRetval;
  110. }
  111. //////////////////////////////////////////////////////////////////////
  112. // Method  : write
  113. // In      : data to write
  114. // Out     : true if succeeded, else if not
  115. // Purpose : 
  116. // Note    : client must be logged on before data can be send to the client
  117. //           call getLastError to find out what went wrong
  118. bool CTelnet::write( const CString& sData )
  119. {
  120. // no critical sections are needed here Winsock is threadSafe
  121. if ( getLoggedOn() )
  122. {
  123. if ( m_bIsRunning )
  124. {
  125. if ( !m_telnetSock->sendData( sData ) )
  126. {
  127. m_sLastError = m_telnetSock->getLastError();
  128. return false;
  129. }
  130. }
  131. else
  132. {
  133. m_sLastError = "Telnet server is not running";
  134. return false;
  135. }
  136. }
  137. return true;
  138. }
  139. //////////////////////////////////////////////////////////////////////
  140. // Method  : start
  141. // In      : none
  142. // Out     : true if succeeded, else if not
  143. // Purpose : basically starts up the telnetThread
  144. // Note    : 
  145. bool CTelnet::start()
  146. {
  147. ResetEvent( m_threadStartupSuccceeded );
  148. ResetEvent( m_threadStartupFailed );
  149. // start up the telnetThread
  150. m_hThread = CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)TelnetThread, this , NULL, NULL);
  151. if ( m_hThread == NULL )
  152. {
  153. m_sLastError = "Starting the telnetWorkerThread failed";
  154. return false;
  155. }
  156. else
  157. {
  158. // wait for signal from the telnetWorkerThread
  159. HANDLE hArray[2] = { m_threadStartupSuccceeded , m_threadStartupFailed };
  160. DWORD dwResult = WaitForMultipleObjects( 2 , hArray , FALSE , INFINITE );
  161. if ( dwResult == WAIT_OBJECT_0 )
  162. {
  163. m_bIsRunning = true;
  164. }
  165. else
  166. {
  167. // startup failed
  168. return false;
  169. }
  170. }
  171. return true;
  172. }
  173. //////////////////////////////////////////////////////////////////////
  174. // Method  : stop
  175. // In      : none
  176. // Out     : none
  177. // Purpose : basically stops the telnetThread
  178. // Note    :
  179. void CTelnet::stop()
  180. {
  181. cleanUp();
  182. }
  183. //////////////////////////////////////////////////////////////////////
  184. // Method  : cleanUp
  185. // In      : none
  186. // Out     : none
  187. // Purpose : basically stops the telnetThread, and closes the open sockets
  188. // Note    :
  189. void CTelnet::cleanUp()
  190. {
  191. if ( m_bIsRunning )
  192. {
  193. // close client and server socket
  194. m_telnetSock->closeClientSocket();
  195. m_telnetSock->closeServerSocket();
  196. // brutely kill the thread
  197. if ( m_hThread )
  198. {
  199. DWORD dummy = 0;
  200. TerminateThread( m_hThread , dummy );
  201. }
  202. }
  203. }
  204. //////////////////////////////////////////////////////////////////////
  205. // Method  : registerFunction
  206. // In      : address of the callback function
  207. // Out     : true if succeeded, false if not
  208. // Purpose : registers a function that should be called whe a user
  209. //           enters a command
  210. // Note    : can only be called if the telnet server is NOT running already
  211. bool CTelnet::registerFunction( CString (*func)(const CString&) , const CString& sCommand )
  212. {
  213. if ( !m_bIsRunning )
  214. {
  215. callBackFunction fu;
  216. fu.function = func;
  217. fu.sCommand = sCommand;
  218. fu.sCommand.MakeLower();
  219. // add to the vector
  220. m_callBackList.push_back( fu );
  221. }
  222. else
  223. {
  224. m_sLastError = "Cannot register callback function when Telnet server is running";
  225. return false;
  226. }
  227. return true;
  228. }
  229. //////////////////////////////////////////////////////////////////////
  230. // Method  : matchFunction
  231. // In      : the command to match
  232. // Out     : adress of matched callback function
  233. // Purpose : finds a callback function based on the command that
  234. //           the user issued
  235. // Note    : 
  236. callback CTelnet::matchFunction( const CString& sCommand , CString& sArgs )
  237. {
  238. callbackVector::iterator pFun;
  239.     
  240.     for ( pFun = m_callBackList.begin() ; pFun != m_callBackList.end() ; pFun++ )
  241.     {
  242. int iLenCommand = pFun->sCommand.GetLength();
  243. CString sCopCommand = sCommand;
  244. sCopCommand.MakeLower();
  245. if ( sCopCommand.Left( iLenCommand ) == pFun->sCommand )
  246. {
  247. if ( iLenCommand < sCommand.GetLength() )
  248. {
  249. sArgs = sCommand.Mid( iLenCommand );
  250. }
  251. return pFun->function;
  252. }
  253.     }
  254. return NULL;
  255. }