123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216 |
- #include "TelnetServer.h"
- #include <time.h>
- #include <SimpleString.h>
- #if defined(_MSC_VER)
- struct CTelnetServer::SessionContext
- {
- int nConnectionID;
- string strInput;
- };
- #endif /*RVC_OS_WIN*/
- CTelnetServer::CTelnetServer(void)
- : CIOCPSocketServer(2)
- #if defined(_MSC_VER)
- ,m_bIgnoreArrowKey(true)
- #endif /*RVC_OS_WIN*/
- {
- }
- CTelnetServer::~CTelnetServer(void)
- {
-
- }
- #if defined(_MSC_VER)
- string CTelnetServer::GetLocalTimeString(bool bShort)
- {
- __time64_t now;
- _time64(&now);
- struct tm when;
- _localtime64_s(&when, &now);
- char buf[80];
- if (bShort)
- sprintf_s(buf, 80, "%02d:%02d:%02d", when.tm_hour, when.tm_min, when.tm_sec);
- else
- sprintf_s(buf, 80, "%04d-%02d-%02d %02d:%02d:%02d", when.tm_year + 1900, when.tm_mon+1, when.tm_mday,
- when.tm_hour, when.tm_min, when.tm_sec);
-
- return buf;
- }
- void CTelnetServer::OnEvent(const char *pFormat, ...)
- {
- va_list arg;
- va_start(arg, pFormat);
- OnConsoleOutput(false, pFormat, arg);
- }
- void CTelnetServer::OnError(const char *pFormat, ...)
- {
- va_list arg;
- va_start(arg, pFormat);
- OnConsoleOutput(true, pFormat, arg);
- }
- void CTelnetServer::OnConsoleOutput(bool bError, const char *pFormat, va_list arg)
- {
- _CrtSetDebugFillThreshold(0);
- char *buf = (char*)_alloca(1024);
- sprintf_s(buf, 24, "[%s] [%s] ", GetLocalTimeString().c_str(), bError?"Error":"Event");
- vsprintf_s(buf + strlen(buf), 1000, pFormat, arg);
- printf(buf);
- }
- void CTelnetServer::OnAccepte(int nConnectionID, const char *pRemoteAddr, int nPort)
- {
- OnEvent("accept connection from %s:%d\r\n", pRemoteAddr, nPort);
- {
- CAutoLock lock(&m_LockObject);
- auto pSessoinContext = new SessionContext();
- pSessoinContext->nConnectionID = nConnectionID;
- m_SessionContext[nConnectionID] = pSessoinContext;
- }
-
- string strReply = GetHelloString()+ GetPromptString();
- AsyncSend(nConnectionID, (char*)strReply.c_str(), strReply.size());
- }
- void CTelnetServer::OnSend(int nConnectionID, int nSendLen)
- {
- }
- void CTelnetServer::OnReceive(int nConnectionID, char *pData, int nRecvLen)
- {
- string strCmd;
- {
- CAutoLock lock(&m_LockObject);
- auto it = m_SessionContext.find(nConnectionID);
- if (it == m_SessionContext.end())
- {
- OnError("invalid connection id: %d\r\n", nConnectionID);
- return;
- }
- auto pSessionContext = (*it).second;
-
- // handle arrow keys
- if (nRecvLen >= 3 && pData[0] == 0x1b && pData[1] == 0x5b)
- return;
- // handle backspace char
- for(int i=0; i<nRecvLen; i++)
- {
- if (pData[i] == '\b')
- {
- if (pSessionContext->strInput.size() > 0)
- pSessionContext->strInput.erase(pSessionContext->strInput.size()-1, 1);
- }
- else
- pSessionContext->strInput += pData[i];
- }
- int nIndex = pSessionContext->strInput.find("\r\n");
- if (nIndex <0)
- return;
- strCmd = pSessionContext->strInput.substr(0, nIndex);
- pSessionContext->strInput.erase(0, nIndex+2);
- }
- if (strCmd.size() == 0) // press enter key
- {
- string strReply = GetPromptString();
- AsyncSend(nConnectionID, (char*)strReply.c_str(), strReply.size());
- return;
- }
- string strReplyMsg;
- if (!ParseCmdLine(nConnectionID, strCmd.c_str(), strReplyMsg))
- {
- OnError("parse command {%s} error, %s", strCmd.c_str(), strReplyMsg.c_str());
- strReplyMsg += GetHelloString();
- }
- strReplyMsg = CSimpleStringA::Format("\r\n%s\r\n%s", strReplyMsg.c_str(), GetPromptString().c_str());
- AsyncSend(nConnectionID, (char*)strReplyMsg.c_str(), strReplyMsg.size());
- }
- void CTelnetServer::OnClose(int nConnectionID)
- {
- {
- CAutoLock lock(&m_LockObject);
- auto it = m_SessionContext.find(nConnectionID);
- if (it == m_SessionContext.end())
- return;
- auto pSessionContext = (*it).second;
- m_SessionContext.erase(nConnectionID);
- delete pSessionContext;
- }
- OnEvent("connection [%d] closed\r\n", nConnectionID);
- }
- string CTelnetServer::GetErrorReplyString(string errMsg)
- {
- string strReplyMsg = "command parse error, ";
- strReplyMsg += errMsg;
- strReplyMsg += "\r\n";
- strReplyMsg += GetHelloString() + GetPromptString();
- return strReplyMsg;
- }
- bool CTelnetServer::IsCharIncluded(char ch, char chars[])
- {
- if (chars == NULL)
- return false;
- for(int i=0; i<sizeof(chars) / sizeof(chars[0]); i++)
- {
- if (chars[i] == ch)
- return true;
- }
- return false;
- }
- // default split char is: all chars exclude char & number
- vector<string> CTelnetServer::SplitString(const char *pLine, char notDelimiterChars[])
- {
- vector<string> list;
- char *p1 = (char*)pLine;
- char *p2 = p1;
- while(*p1)
- {
- while(*p2 && (IsCharAlphaNumeric(*p2) || IsCharIncluded(*p2, notDelimiterChars)))
- p2++;
- if (p2 != p1)
- list.push_back(string(p1, p2-p1));
-
- // skip blankspace
- while(*p2 && !IsCharAlphaNumeric(*p2) && !IsCharIncluded(*p2, notDelimiterChars))
- p2++;
- p1 = p2;
- }
- return list;
- }
- #endif /*RVC_OS_WIN*/
|