1. 修正:SSH连接后,超时断开后,客户端可能会反复重连,最终导致核心服务假死;

2. 修正:后台配置超时无操作自动断开时,配置为0,即永不超时,选项不生效。
dev
Apex Liu 2021-03-04 01:25:23 +08:00
parent f6cc313f87
commit 47c2fdcff4
20 changed files with 1041 additions and 673 deletions

View File

@ -8,9 +8,10 @@
<file url="file://$PROJECT_DIR$/common/libex/src/ex_ini.cpp" charset="GBK" /> <file url="file://$PROJECT_DIR$/common/libex/src/ex_ini.cpp" charset="GBK" />
<file url="file://$PROJECT_DIR$/common/libex/src/ex_log.cpp" charset="GBK" /> <file url="file://$PROJECT_DIR$/common/libex/src/ex_log.cpp" charset="GBK" />
<file url="file://$PROJECT_DIR$/common/libex/src/ex_util.cpp" charset="GBK" /> <file url="file://$PROJECT_DIR$/common/libex/src/ex_util.cpp" charset="GBK" />
<file url="file://$PROJECT_DIR$/common/pyshell/include/pys.h" charset="GBK" /> <file url="file://$PROJECT_DIR$/common/pyshell/include/pys.h" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/common/pyshell/src/pys_api.cpp" charset="GBK" /> <file url="file://$PROJECT_DIR$/common/pyshell/src/pys_api.cpp" charset="GBK" />
<file url="file://$PROJECT_DIR$/common/pyshell/src/pys_core.cpp" charset="GBK" /> <file url="file://$PROJECT_DIR$/common/pyshell/src/pys_core.cpp" charset="GBK" />
<file url="file://$PROJECT_DIR$/common/pyshell/src/pys_core.h" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/common/teleport/teleport_const.h" charset="GBK" /> <file url="file://$PROJECT_DIR$/common/teleport/teleport_const.h" charset="GBK" />
<file url="file://$PROJECT_DIR$/server/tp_core/common/base_env.h" charset="GBK" /> <file url="file://$PROJECT_DIR$/server/tp_core/common/base_env.h" charset="GBK" />
<file url="file://$PROJECT_DIR$/server/tp_core/common/base_record.cpp" charset="GBK" /> <file url="file://$PROJECT_DIR$/server/tp_core/common/base_record.cpp" charset="GBK" />
@ -46,7 +47,7 @@
<file url="file://$PROJECT_DIR$/server/tp_core/protocol/telnet/telnet_recorder.h" charset="UTF-8" /> <file url="file://$PROJECT_DIR$/server/tp_core/protocol/telnet/telnet_recorder.h" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/server/tp_core/protocol/telnet/telnet_session.cpp" charset="GBK" /> <file url="file://$PROJECT_DIR$/server/tp_core/protocol/telnet/telnet_session.cpp" charset="GBK" />
<file url="file://$PROJECT_DIR$/server/tp_core/protocol/telnet/telnet_session.h" charset="GBK" /> <file url="file://$PROJECT_DIR$/server/tp_core/protocol/telnet/telnet_session.h" charset="GBK" />
<file url="file://$PROJECT_DIR$/server/tp_web/src/main.cpp" charset="GBK" /> <file url="file://$PROJECT_DIR$/server/tp_web/src/main.cpp" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/server/tp_web/src/ts_env.cpp" charset="GBK" /> <file url="file://$PROJECT_DIR$/server/tp_web/src/ts_env.cpp" charset="GBK" />
</component> </component>
</project> </project>

View File

@ -3,9 +3,11 @@ project(teleport)
include(CMakeCfg.txt) include(CMakeCfg.txt)
if (OS_LINUX) #if (OS_LINUX)
add_subdirectory(server/tp_web/src) # add_subdirectory(server/tp_web/src)
endif() #endif()
add_subdirectory(server/tp_web/src)
add_subdirectory(server/tp_core/core) add_subdirectory(server/tp_core/core)
add_subdirectory(server/tp_core/protocol/ssh) add_subdirectory(server/tp_core/protocol/ssh)

View File

@ -102,7 +102,7 @@
"name": "FreeRDP", "name": "FreeRDP",
"display": "FreeRDP", "display": "FreeRDP",
"app": "", "app": "",
"cmdline": "/u:{user_name} /v:{host_ip} /port:{host_port}", "cmdline": "/u:{user_name} /v:{host_ip} /port:{host_port} +glyph-cache /relax-order-checks",
"desc": [ "desc": [
"建议使用homebrew安装freerdp安装后freerdp默认路径在/usr/local/Cellar/freerdp/x.y.z/bin/xfreerdp", "建议使用homebrew安装freerdp安装后freerdp默认路径在/usr/local/Cellar/freerdp/x.y.z/bin/xfreerdp",
"首次安装freerdp后需要重新启动计算机" "首次安装freerdp后需要重新启动计算机"

View File

@ -19,42 +19,49 @@ typedef std::map<ex_wstr, ex_wstr> ex_ini_kvs;
class ExIniSection class ExIniSection
{ {
public: public:
ExIniSection(); ExIniSection();
ExIniSection(const ex_wstr& strSectionName);
~ExIniSection();
void ClearUp(void); explicit ExIniSection(const ex_wstr& strSectionName);
ex_wstr Name(void) { return m_strName; } ~ExIniSection();
void GetStr(const ex_wstr& strKey, ex_wstr& strValue, const ex_wstr& strDefault); void ClearUp();
bool GetStr(const ex_wstr& strKey, ex_wstr& strValue);
void GetInt(const ex_wstr& strKey, int& iValue, int iDefault); ex_wstr Name() { return m_strName; }
bool GetInt(const ex_wstr& strKey, int& iValue);
void GetBool(const ex_wstr& strKey, bool& bValue, bool bDefault); void GetStr(const ex_wstr& strKey, ex_wstr& strValue, const ex_wstr& strDefault);
bool GetBool(const ex_wstr& strKey, bool& bValue);
bool SetValue(const ex_wstr& strKey, const ex_wstr& strValue, bool bAddIfNotExists = false);
ex_ini_kvs& GetKeyValues(void) { return m_kvs; } bool GetStr(const ex_wstr& strKey, ex_wstr& strValue);
void GetInt(const ex_wstr& strKey, int& iValue, int iDefault);
bool GetInt(const ex_wstr& strKey, int& iValue);
void GetBool(const ex_wstr& strKey, bool& bValue, bool bDefault);
bool GetBool(const ex_wstr& strKey, bool& bValue);
bool SetValue(const ex_wstr& strKey, const ex_wstr& strValue, bool bAddIfNotExists = false);
ex_ini_kvs& GetKeyValues() { return m_kvs; }
int Count() const
{
return (int) m_kvs.size();
}
void Save(FILE* file, int codepage);
int Count(void) const
{
return (int)m_kvs.size();
}
void Save(FILE* file, int codepage);
#ifdef EX_DEBUG #ifdef EX_DEBUG
void Dump(void); void Dump(void);
#endif #endif
protected: protected:
bool _IsKeyExists(const ex_wstr& strKey); bool _IsKeyExists(const ex_wstr& strKey);
private: private:
ex_wstr m_strName; ex_wstr m_strName;
ex_ini_kvs m_kvs; ex_ini_kvs m_kvs;
}; };
@ -64,49 +71,55 @@ typedef std::map<ex_wstr, ExIniSection*> ex_ini_sections;
class ExIniFile class ExIniFile
{ {
public: public:
enum PARSE_RV enum PARSE_RV
{ {
PARSE_ERROR, PARSE_ERROR,
PARSE_SECTION, PARSE_SECTION,
PARSE_KEYVALUE, PARSE_KEYVALUE,
PARSE_COMMENT, PARSE_COMMENT,
PARSE_OTHER PARSE_OTHER
}; };
public: public:
ExIniFile(); ExIniFile();
~ExIniFile();
const ex_wstr& get_filename(void){return m_file_path;} ~ExIniFile();
void ClearUp(void); const ex_wstr& get_filename() { return m_file_path; }
// Read and parse special file. void ClearUp();
bool LoadFromFile(const ex_wstr& strFileName, bool bClearOld = true);
bool LoadFromMemory(const ex_wstr& strData, bool bClearOld = true);
ex_ini_sections& GetAllSections(void) { return m_secs; } // Read and parse special file.
bool LoadFromFile(const ex_wstr& strFileName, bool bClearOld = true);
ExIniSection* GetSection(const ex_wstr& strName, bool bCreateIfNotExists = false); bool LoadFromMemory(const ex_wstr& strData, bool bClearOld = true);
ExIniSection* GetDumySection(void) { return &m_dumy_sec; }
ex_ini_sections& GetAllSections() { return m_secs; }
ExIniSection* GetSection(const ex_wstr& strName, bool bCreateIfNotExists = false);
ExIniSection* GetDumySection() { return &m_dumy_sec; }
int Count() const
{
return (int) (m_secs.size());
}
void Save(int codepage = EX_CODEPAGE_UTF8);
int Count(void) const
{
return (int)(m_secs.size());
}
void Save(int codepage = EX_CODEPAGE_UTF8);
#ifdef EX_DEBUG #ifdef EX_DEBUG
void Dump(void); void Dump(void);
#endif #endif
protected: protected:
static PARSE_RV _ParseLine(const ex_wstr& strLine, ex_wstr& strKey, ex_wstr& strValue); static PARSE_RV parse_line_(const ex_wstr& strLine, ex_wstr& strKey, ex_wstr& strValue);
bool _ProcessLine(const ex_wstr strLine, ExIniSection** pCurSection);
bool process_line_(const ex_wstr& strLine, ExIniSection** pCurSection);
private: private:
ex_ini_sections m_secs; ex_ini_sections m_secs;
ExIniSection m_dumy_sec; ExIniSection m_dumy_sec;
ex_wstr m_file_path; ex_wstr m_file_path;
}; };
#endif // __EX_INI_H__ #endif // __EX_INI_H__

View File

@ -66,11 +66,11 @@ void EXLOG_FILE(const wchar_t *log_file, const wchar_t *log_path = nullptr, ex_u
void EXLOG_CONSOLE(bool output_to_console); void EXLOG_CONSOLE(bool output_to_console);
#define EXLOGD ex_printf_d
#define EXLOGV ex_printf_v #define EXLOGV ex_printf_v
#define EXLOGI ex_printf_i #define EXLOGI ex_printf_i
#define EXLOGW ex_printf_w #define EXLOGW ex_printf_w
#define EXLOGE ex_printf_e #define EXLOGE ex_printf_e
#define EXLOGD ex_printf_d
#define EXLOG_BIN ex_printf_bin #define EXLOG_BIN ex_printf_bin
#ifdef EX_OS_WIN32 #ifdef EX_OS_WIN32

View File

@ -4,524 +4,493 @@
ExIniSection::ExIniSection(const ex_wstr& strSectionName) ExIniSection::ExIniSection(const ex_wstr& strSectionName)
{ {
m_kvs.clear(); m_kvs.clear();
m_strName = strSectionName; m_strName = strSectionName;
} }
ExIniSection::ExIniSection() ExIniSection::ExIniSection()
{ {
m_kvs.clear(); m_kvs.clear();
m_strName = L"N/A"; m_strName = L"N/A";
} }
ExIniSection::~ExIniSection() ExIniSection::~ExIniSection()
{ {
m_kvs.clear(); m_kvs.clear();
} }
bool ExIniSection::_IsKeyExists(const ex_wstr& strKey) bool ExIniSection::_IsKeyExists(const ex_wstr& strKey)
{ {
return (m_kvs.end() != m_kvs.find(strKey)); return (m_kvs.end() != m_kvs.find(strKey));
} }
void ExIniSection::GetStr(const ex_wstr& strKey, ex_wstr& strValue, const ex_wstr& strDefault) void ExIniSection::GetStr(const ex_wstr& strKey, ex_wstr& strValue, const ex_wstr& strDefault)
{ {
ex_ini_kvs::iterator it = m_kvs.find(strKey); ex_ini_kvs::iterator it = m_kvs.find(strKey);
if (m_kvs.end() == it) if (m_kvs.end() == it)
strValue = strDefault; strValue = strDefault;
else else
strValue = (*it).second; strValue = (*it).second;
} }
bool ExIniSection::GetStr(const ex_wstr& strKey, ex_wstr& strValue) bool ExIniSection::GetStr(const ex_wstr& strKey, ex_wstr& strValue)
{ {
ex_ini_kvs::iterator it = m_kvs.find(strKey); ex_ini_kvs::iterator it = m_kvs.find(strKey);
if (m_kvs.end() == it) if (m_kvs.end() == it)
return false; return false;
strValue = (*it).second; strValue = (*it).second;
return true; return true;
} }
void ExIniSection::GetInt(const ex_wstr& strKey, int& iValue, int iDefault) void ExIniSection::GetInt(const ex_wstr& strKey, int& iValue, int iDefault)
{ {
ex_ini_kvs::iterator it = m_kvs.find(strKey); ex_ini_kvs::iterator it = m_kvs.find(strKey);
if (m_kvs.end() == it) if (m_kvs.end() == it)
{ {
iValue = iDefault; iValue = iDefault;
return; return;
} }
#ifdef EX_OS_WIN32 #ifdef EX_OS_WIN32
iValue = _wtoi(it->second.c_str()); iValue = _wtoi(it->second.c_str());
#else #else
ex_astr tmp; ex_astr tmp;
ex_wstr2astr(it->second, tmp); ex_wstr2astr(it->second, tmp);
iValue = atoi(tmp.c_str()); iValue = atoi(tmp.c_str());
#endif #endif
} }
bool ExIniSection::GetInt(const ex_wstr& strKey, int& iValue) bool ExIniSection::GetInt(const ex_wstr& strKey, int& iValue)
{ {
ex_ini_kvs::iterator it = m_kvs.find(strKey); ex_ini_kvs::iterator it = m_kvs.find(strKey);
if (m_kvs.end() == it) if (m_kvs.end() == it)
return false; return false;
#ifdef EX_OS_WIN32 #ifdef EX_OS_WIN32
iValue = _wtoi(it->second.c_str()); iValue = _wtoi(it->second.c_str());
#else #else
ex_astr tmp; ex_astr tmp;
ex_wstr2astr(it->second, tmp); ex_wstr2astr(it->second, tmp);
iValue = atoi(tmp.c_str()); iValue = atoi(tmp.c_str());
#endif #endif
return true; return true;
} }
void ExIniSection::GetBool(const ex_wstr& strKey, bool& bValue, bool bDefault) void ExIniSection::GetBool(const ex_wstr& strKey, bool& bValue, bool bDefault)
{ {
ex_ini_kvs::iterator it = m_kvs.find(strKey); ex_ini_kvs::iterator it = m_kvs.find(strKey);
if (m_kvs.end() == it) if (m_kvs.end() == it)
{ {
bValue = bDefault; bValue = bDefault;
return; return;
} }
if ( if (
it->second == L"1" it->second == L"1"
#ifdef EX_OS_WIN32 #ifdef EX_OS_WIN32
|| 0 == _wcsicmp(it->second.c_str(), L"true") || 0 == _wcsicmp(it->second.c_str(), L"true")
#else #else
|| 0 == wcscasecmp(it->second.c_str(), L"true") || 0 == wcscasecmp(it->second.c_str(), L"true")
#endif #endif
) )
bValue = true; bValue = true;
else else
bValue = false; bValue = false;
} }
bool ExIniSection::GetBool(const ex_wstr& strKey, bool& bValue) bool ExIniSection::GetBool(const ex_wstr& strKey, bool& bValue)
{ {
ex_ini_kvs::iterator it = m_kvs.find(strKey); ex_ini_kvs::iterator it = m_kvs.find(strKey);
if (m_kvs.end() == it) if (m_kvs.end() == it)
return false; return false;
if ( if (
it->second == L"1" it->second == L"1"
#ifdef EX_OS_WIN32 #ifdef EX_OS_WIN32
|| 0 == _wcsicmp(it->second.c_str(), _T("true")) || 0 == _wcsicmp(it->second.c_str(), _T("true"))
#else #else
|| 0 == wcscasecmp(it->second.c_str(), L"true") || 0 == wcscasecmp(it->second.c_str(), L"true")
#endif #endif
) )
bValue = true; bValue = true;
else else
bValue = false; bValue = false;
return true; return true;
} }
bool ExIniSection::SetValue(const ex_wstr& strKey, const ex_wstr& strValue, bool bAddIfNotExists) bool ExIniSection::SetValue(const ex_wstr& strKey, const ex_wstr& strValue, bool bAddIfNotExists)
{ {
ex_ini_kvs::iterator it = m_kvs.find(strKey); ex_ini_kvs::iterator it = m_kvs.find(strKey);
if (it != m_kvs.end()) if (it != m_kvs.end())
{ {
it->second = strValue; it->second = strValue;
return true; return true;
} }
if (bAddIfNotExists) if (bAddIfNotExists)
{ {
m_kvs.insert(std::make_pair(strKey, strValue)); m_kvs.insert(std::make_pair(strKey, strValue));
return true; return true;
} }
return false; return false;
} }
void ExIniSection::ClearUp(void) void ExIniSection::ClearUp(void)
{ {
m_kvs.clear(); m_kvs.clear();
} }
void ExIniSection::Save(FILE* file, int codepage) void ExIniSection::Save(FILE* file, int codepage)
{ {
ex_ini_kvs::iterator it = m_kvs.begin(); for (auto it = m_kvs.begin(); it != m_kvs.end(); ++it)
for (; it != m_kvs.end(); ++it) {
{ ex_wstr temp;
ex_wstr temp; temp += it->first;
temp += it->first.c_str(); temp += L'=';
temp += L"="; temp += it->second;
temp += it->second.c_str(); temp += L'\n';
temp += L"\n"; ex_astr temp2;
ex_astr temp2; ex_wstr2astr(temp, temp2, codepage);
ex_wstr2astr(temp, temp2, codepage); fwrite(temp2.c_str(), temp2.size(), 1, file);
fwrite(temp2.c_str(), temp2.size(), 1, file); }
}
return;
} }
#ifdef EX_DEBUG #ifdef EX_DEBUG
void ExIniSection::Dump(void) void ExIniSection::Dump(void)
{ {
ex_ini_kvs::iterator it = m_kvs.begin(); for (auto it = m_kvs.begin(); it != m_kvs.end(); ++it)
for (; it != m_kvs.end(); ++it) {
{ EXLOGD(_T(" [%s]=[%s]\n"), it->first.c_str(), it->second.c_str());
EXLOGD(_T(" [%s]=[%s]\n"), it->first.c_str(), it->second.c_str()); }
}
} }
#endif #endif
ExIniFile::ExIniFile() ExIniFile::ExIniFile() = default;
{
}
ExIniFile::~ExIniFile() ExIniFile::~ExIniFile()
{ {
ClearUp(); ClearUp();
} }
bool ExIniFile::LoadFromFile(const ex_wstr& strFileName, bool bClearOld) bool ExIniFile::LoadFromFile(const ex_wstr& strFileName, bool bClearOld)
{ {
#ifdef EX_OS_WIN32 #ifdef EX_OS_WIN32
HANDLE hFile = ::CreateFileW(strFileName.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); HANDLE hFile = ::CreateFileW(strFileName.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (INVALID_HANDLE_VALUE == hFile) if (INVALID_HANDLE_VALUE == hFile)
return false; return false;
ULONG ulFileSize = GetFileSize(hFile, NULL); ULONG ulFileSize = GetFileSize(hFile, NULL);
if (INVALID_FILE_SIZE == ulFileSize) if (INVALID_FILE_SIZE == ulFileSize)
{ {
CloseHandle(hFile); CloseHandle(hFile);
return false; return false;
} }
std::vector<char> vFile; std::vector<char> vFile;
vFile.resize(ulFileSize + 1); vFile.resize(ulFileSize + 1);
ZeroMemory(&vFile[0], ulFileSize + 1); ZeroMemory(&vFile[0], ulFileSize + 1);
DWORD dwRead = 0; DWORD dwRead = 0;
if (!ReadFile(hFile, &vFile[0], ulFileSize, &dwRead, NULL) || ulFileSize != dwRead) if (!ReadFile(hFile, &vFile[0], ulFileSize, &dwRead, NULL) || ulFileSize != dwRead)
{ {
CloseHandle(hFile); CloseHandle(hFile);
return false; return false;
} }
CloseHandle(hFile); CloseHandle(hFile);
m_file_path = strFileName; m_file_path = strFileName;
#else #else
FILE* f = NULL; FILE* f = nullptr;
ex_astr _fname; ex_astr _fname;
ex_wstr2astr(strFileName, _fname); ex_wstr2astr(strFileName, _fname);
f = fopen(_fname.c_str(), "rb"); f = fopen(_fname.c_str(), "rb");
if(f == NULL) if (!f)
return false; return false;
fseek(f, 0L, SEEK_END); fseek(f, 0L, SEEK_END);
unsigned long ulFileSize = (unsigned long)ftell(f); auto ulFileSize = static_cast<unsigned long>(ftell(f));
if(-1 == ulFileSize) if (-1 == ulFileSize)
{ {
fclose(f); fclose(f);
return false; return false;
} }
std::vector<char> vFile; std::vector<char> vFile;
vFile.resize(ulFileSize + 1); vFile.resize(ulFileSize + 1);
memset(&vFile[0], 0, ulFileSize + 1); memset(&vFile[0], 0, ulFileSize + 1);
fseek(f, 0L, SEEK_SET); fseek(f, 0L, SEEK_SET);
fread(&vFile[0], 1, ulFileSize, f); fread(&vFile[0], 1, ulFileSize, f);
fclose(f); fclose(f);
m_file_path = strFileName; m_file_path = strFileName;
#endif #endif
char *pOffset = &vFile[0]; char* pOffset = &vFile[0];
if ((ulFileSize > 3) && (0 == memcmp(pOffset, "\xEF\xBB\xBF", 3))) if ((ulFileSize > 3) && (0 == memcmp(pOffset, "\xEF\xBB\xBF", 3)))
{ {
pOffset += 3; pOffset += 3;
} }
// 配置文件均使用UTF8编码 // 配置文件均使用UTF8编码
ex_wstr fileData; ex_wstr fileData;
if (!ex_astr2wstr(pOffset, fileData, EX_CODEPAGE_UTF8)) if (!ex_astr2wstr(pOffset, fileData, EX_CODEPAGE_UTF8))
return false; return false;
return LoadFromMemory(fileData, bClearOld); return LoadFromMemory(fileData, bClearOld);
} }
bool ExIniFile::LoadFromMemory(const ex_wstr& strData, bool bClearOld) bool ExIniFile::LoadFromMemory(const ex_wstr& strData, bool bClearOld)
{ {
if (strData.empty()) if (strData.empty())
return false; return false;
ex_wstr strAll(strData); ex_wstr strAll(strData);
bool bRet = true; bool bRet = true;
ExIniSection* pCurSection = NULL; ExIniSection* pCurSection = nullptr;
do { do
// Clear old data. {
if (bClearOld) // Clear old data.
ClearUp(); if (bClearOld)
ClearUp();
ex_wstr strKey(L""); ex_wstr strKey;
ex_wstr strValue(L""); ex_wstr strValue;
ex_wstr strLine(L""); ex_wstr strLine;
ex_wstr::size_type posCR = ex_wstr::npos; ex_wstr::size_type posCR = ex_wstr::npos;
ex_wstr::size_type posLF = ex_wstr::npos; ex_wstr::size_type posLF = ex_wstr::npos;
for (;;) for (;;)
{ {
posCR = ex_wstr::npos; posCR = strAll.find(L'\r');
posLF = ex_wstr::npos; posLF = strAll.find(L'\n');
posCR = strAll.find(L"\r");
posLF = strAll.find(L"\n");
if(posCR == ex_wstr::npos && posLF == ex_wstr::npos) { if (posCR == ex_wstr::npos && posLF == ex_wstr::npos)
if (strAll.empty()) {
break; if (strAll.empty())
strLine = strAll; break;
strAll.clear(); strLine = strAll;
} else if(posCR != ex_wstr::npos && posLF != ex_wstr::npos) { strAll.clear();
if(posLF != posCR + 1) { }
if(posLF < posCR) { else if (posCR != ex_wstr::npos && posLF != ex_wstr::npos)
strLine.assign(strAll, 0, posLF); {
strAll.erase(0, posLF + 1); if (posLF != posCR + 1)
} else { {
strLine.assign(strAll, 0, posCR); if (posLF < posCR)
strAll.erase(0, posCR + 1); {
} strLine.assign(strAll, 0, posLF);
} else { strAll.erase(0, posLF + 1);
strLine.assign(strAll, 0, posCR); }
strAll.erase(0, posCR + 2); else
} {
} else { strLine.assign(strAll, 0, posCR);
if(posCR != ex_wstr::npos) { strAll.erase(0, posCR + 1);
strLine.assign(strAll, 0, posCR); }
strAll.erase(0, posCR + 1); }
} else { else
strLine.assign(strAll, 0, posLF); {
strAll.erase(0, posLF + 1); strLine.assign(strAll, 0, posCR);
} strAll.erase(0, posCR + 2);
} }
}
else
{
if (posCR != ex_wstr::npos)
{
strLine.assign(strAll, 0, posCR);
strAll.erase(0, posCR + 1);
}
else
{
strLine.assign(strAll, 0, posLF);
strAll.erase(0, posLF + 1);
}
}
// if (ex_wstr::npos == pos) if (ex_only_white_space(strLine))
// { continue;
// pos = strAll.find(L'\n');
// if (ex_wstr::npos == pos)
// {
// if (strAll.empty())
// break;
//
// strLine = strAll;
// strAll.clear();
// }
// else
// {
// strLine.assign(strAll, 0, pos);
// strAll.erase(0, pos + 1);
// }
// }
// else
// {
// strLine.assign(strAll, 0, pos);
// strAll.erase(0, pos + 2);
// }
if (ex_only_white_space(strLine)) if (!process_line_(strLine, &pCurSection))
continue; {
bRet = false;
break;
}
}
if (!_ProcessLine(strLine, &pCurSection)) } while (false);
{
bRet = false;
break;
}
}
} while (false); return bRet;
return bRet;
} }
void ExIniFile::Save(int codepage/* = EX_CODEPAGE_UTF8*/) void ExIniFile::Save(int codepage/* = EX_CODEPAGE_UTF8*/)
{ {
//ex_astr temp;
//ex_wstr2astr(m_file_path, temp);
//FILE* file = NULL;
//fopen(temp.c_str(), "wt");
//fopen_s(&file, temp.c_str(), "wt");
FILE* file = ex_fopen(m_file_path, L"wt"); FILE* file = ex_fopen(m_file_path, L"wt");
if (!file)
return;
if (file == NULL) // 如果有不属于任何小节的值对,先保存之
{ if (m_dumy_sec.Count() > 0)
return; m_dumy_sec.Save(file, codepage);
}
// 如果有不属于任何小节的值对,先保存之 for (auto it = m_secs.begin(); it != m_secs.end(); ++it)
if (m_dumy_sec.Count() > 0) {
m_dumy_sec.Save(file, codepage); EXLOGD(L"{%s}\n", it->first.c_str());
ex_wstr temp;
temp += L"[";
temp += it->first;
temp += L"]\n";
ex_astr temp2;
ex_wstr2astr(temp, temp2, codepage);
fwrite(temp2.c_str(), temp2.size(), 1, file);
ex_ini_sections::iterator it = m_secs.begin(); it->second->Save(file, codepage);
for (; it != m_secs.end(); ++it) }
{ fclose(file);
EXLOGD(L"{%s}\n", it->first.c_str());
ex_wstr temp;
temp += L"[";
temp += it->first.c_str();
temp += L"]\n";
ex_astr temp2;
ex_wstr2astr(temp, temp2, codepage);
fwrite(temp2.c_str(), temp2.size(), 1, file);
it->second->Save(file, codepage);
}
fclose(file);
} }
#ifdef EX_DEBUG #ifdef EX_DEBUG
void ExIniFile::Dump(void) void ExIniFile::Dump(void)
{ {
ex_ini_sections::iterator it = m_secs.begin(); for (auto it = m_secs.begin(); it != m_secs.end(); ++it)
for (; it != m_secs.end(); ++it) {
{ EXLOGD(_T("{%s}\n"), it->first.c_str());
EXLOGD(_T("{%s}\n"), it->first.c_str()); it->second->Dump();
it->second->Dump(); }
}
} }
#endif #endif
void ExIniFile::ClearUp(void) void ExIniFile::ClearUp()
{ {
ex_ini_sections::iterator it = m_secs.begin(); for (auto it = m_secs.begin(); it != m_secs.end(); ++it)
for (; it != m_secs.end(); ++it) {
{ delete it->second;
delete it->second; }
} m_secs.clear();
m_secs.clear();
} }
ExIniSection* ExIniFile::GetSection(const ex_wstr& strName, bool bCreateIfNotExists) ExIniSection* ExIniFile::GetSection(const ex_wstr& strName, bool bCreateIfNotExists)
{ {
ex_ini_sections::iterator it = m_secs.find(strName); auto it = m_secs.find(strName);
if (it != m_secs.end()) if (it != m_secs.end())
return it->second; return it->second;
if (!bCreateIfNotExists) if (!bCreateIfNotExists)
return NULL; return nullptr;
ExIniSection* pSec = new ExIniSection(strName); auto pSec = new ExIniSection(strName);
m_secs.insert(std::make_pair(strName, pSec)); m_secs.insert(std::make_pair(strName, pSec));
return pSec; return pSec;
} }
// static function. // static function.
// 解析一行,返回值为 [节名/值对/注释/什么也不是/出错了] // 解析一行,返回值为 [节名/值对/注释/什么也不是/出错了]
// 节名 => strKey = [section_name] // 节名 => strKey = [section_name]
// 值对 => strKey = strValue // 值对 => strKey = strValue
ExIniFile::PARSE_RV ExIniFile::_ParseLine(const ex_wstr& strOrigLine, ex_wstr& strKey, ex_wstr& strValue) ExIniFile::PARSE_RV ExIniFile::parse_line_(const ex_wstr& strLine, ex_wstr& strKey, ex_wstr& strValue)
{ {
// 首先去掉行首的空格或者 TAB 控制 // 首先去掉行首的空格或者 TAB 控制
ex_wstr strLine(strOrigLine); ex_wstr line(strLine);
ex_remove_white_space(strLine, EX_RSC_BEGIN); ex_remove_white_space(line, EX_RSC_BEGIN);
// 判断是否为注释。 .ini 文件以 分号';'/'#' 作为注释行的第一个字符 // 判断是否为注释。 .ini 文件以 分号';'/'#' 作为注释行的第一个字符
if (';' == strLine[0] || '#' == strLine[0]) if (';' == line[0] || '#' == line[0])
{ {
return PARSE_COMMENT; return PARSE_COMMENT;
} }
if ('[' == strLine[0]) if ('[' == line[0])
{ {
// 这是一个节(section) // 这是一个节(section)
ex_wstr::size_type startPos = strLine.find('['); ex_wstr::size_type startPos = line.find('[');
ex_wstr::size_type endPos = strLine.rfind(']'); ex_wstr::size_type endPos = line.rfind(']');
strLine.erase(endPos); line.erase(endPos);
strLine.erase(startPos, 1); line.erase(startPos, 1);
strKey = strLine; strKey = line;
return PARSE_SECTION; return PARSE_SECTION;
} }
else else
{ {
// 看看能否找到等号(=),这是 key=value 的判别方法 // 看看能否找到等号(=),这是 key=value 的判别方法
ex_wstr::size_type pos = strLine.find('='); // 如果没有等号,则整个视作 keyvalue为 NULL这样。
if (ex_wstr::npos == pos) ex_wstr::size_type pos = line.find('=');
{ if (ex_wstr::npos == pos)
//return PARSE_OTHER; // 没有等号 {
ex_remove_white_space(strLine); //return PARSE_OTHER; // 没有等号
strKey = strLine; ex_remove_white_space(line);
strValue.clear(); strKey = line;
return PARSE_KEYVALUE; strValue.clear();
} return PARSE_KEYVALUE;
}
// 将等号前面的与等号后面的分割 // 将等号前面的与等号后面的分割
strKey.assign(strLine, 0, pos); strKey.assign(line, 0, pos);
strValue.assign(strLine, pos + 1, strLine.length() - pos); strValue.assign(line, pos + 1, line.length() - pos);
ex_remove_white_space(strKey); ex_remove_white_space(line);
// 等号后面的应该原封不动,不应该移除空白字符 // 等号后面的应该原封不动,不应该移除空白字符
ex_remove_white_space(strValue, EX_RSC_BEGIN); ex_remove_white_space(strValue, EX_RSC_BEGIN);
return PARSE_KEYVALUE; return PARSE_KEYVALUE;
} }
return PARSE_OTHER; // return PARSE_OTHER;
} }
bool ExIniFile::_ProcessLine(const ex_wstr strLine, ExIniSection** pCurSection) bool ExIniFile::process_line_(const ex_wstr& strLine, ExIniSection** pCurSection)
{ {
if (strLine.empty()) if (strLine.empty())
return true; return true;
ex_wstr strKey;//(_T("")); ex_wstr strKey;
ex_wstr strValue;//(_T("")); ex_wstr strValue;
auto parse_rv = parse_line_(strLine, strKey, strValue);
PARSE_RV parse_rv = PARSE_ERROR; bool bError = false;
parse_rv = _ParseLine(strLine, strKey, strValue); switch (parse_rv)
{
case PARSE_ERROR:
bError = true;
break;
case PARSE_SECTION:
{
// 创建一个节
auto pSection = GetSection(strKey, true);
if (!pSection)
{
bError = true;
break;
}
bool bError = false; *pCurSection = pSection;
}
break;
case PARSE_KEYVALUE:
if (!pCurSection || !*pCurSection)
{
*pCurSection = &m_dumy_sec;
}
switch (parse_rv) // 创建一个值对
{ if (!(*pCurSection)->SetValue(strKey, strValue, true))
case PARSE_ERROR: {
bError = true; bError = true;
break; break;
case PARSE_SECTION: }
{
// 创建一个节
ExIniSection* pSection = GetSection(strKey, true);
if (NULL == pSection)
{
bError = true;
break;
}
*pCurSection = pSection; break;
}
break;
case PARSE_KEYVALUE:
if (NULL == pCurSection || NULL == *pCurSection)
{
//bError = true;
//break;
*pCurSection = &m_dumy_sec;
}
// 创建一个值对 case PARSE_COMMENT:
if (!(*pCurSection)->SetValue(strKey, strValue, true)) case PARSE_OTHER:
{ default:
bError = true; break;
break; }
}
break; return (!bError);
case PARSE_COMMENT:
case PARSE_OTHER:
default:
break;
}
return (!bError);
} }

View File

@ -26,6 +26,9 @@ extern "C" {
#elif defined(EX_OS_LINUX) #elif defined(EX_OS_LINUX)
# define PYS_USE_PYLIB_STATIC # define PYS_USE_PYLIB_STATIC
# include <Python.h> # include <Python.h>
#elif defined(EX_OS_MACOS)
# define PYS_USE_PYLIB_SHARED
# include <Python.h>
#else #else
# error This platform not supported yet. # error This platform not supported yet.
#endif #endif
@ -200,73 +203,73 @@ extern "C" {
typedef void* PYS_HANDLE; typedef void* PYS_HANDLE;
// 创建一个PyShell句柄所有操作均对应此句柄进行一个进程仅有一个句柄 // 创建一个PyShell句柄所有操作均对应此句柄进行一个进程仅有一个句柄
PYS_HANDLE pys_create(void); PYS_HANDLE pys_create(void);
// 销毁一个PyShell句柄 // 销毁一个PyShell句柄
void pys_destroy(PYS_HANDLE* pysh); void pys_destroy(PYS_HANDLE* pysh);
// 使用指定的运行时路径进行初始化运行时路径中包含pythonXX.dll/python.zip/modules等等 // 使用指定的运行时路径进行初始化运行时路径中包含pythonXX.dll/python.zip/modules等等
PYS_BOOL pys_init_runtime(PYS_HANDLE pysh, const wchar_t* exec_file, const wchar_t* runtime_path); PYS_BOOL pys_init_runtime(PYS_HANDLE pysh, const wchar_t* exec_file, const wchar_t* runtime_path);
// 设置python包搜索路径可多次调用进行追加可省略 // 设置python包搜索路径可多次调用进行追加可省略
PYS_BOOL pys_add_search_path(PYS_HANDLE pysh, const wchar_t* path); PYS_BOOL pys_add_search_path(PYS_HANDLE pysh, const wchar_t* path);
// 设置python运行时的命令行参数可省略 // 设置python运行时的命令行参数可省略
void pys_set_argv(PYS_HANDLE pysh, int argc, wchar_t** argv); void pys_set_argv(PYS_HANDLE pysh, int argc, wchar_t** argv);
// 追加python运行时的命令行参数可省略 // 追加python运行时的命令行参数可省略
void pys_add_arg(PYS_HANDLE pysh, const wchar_t* arg); void pys_add_arg(PYS_HANDLE pysh, const wchar_t* arg);
// 设置python解释器名称可省略默认为当前可执行程序文件名的绝对路径 // 设置python解释器名称可省略默认为当前可执行程序文件名的绝对路径
void pys_set_program(PYS_HANDLE pysh, const wchar_t* program_name); void pys_set_program(PYS_HANDLE pysh, const wchar_t* program_name);
// 设置入口脚本文件名,可以是一个.py文件也可以是一个.zip文件 // 设置入口脚本文件名,可以是一个.py文件也可以是一个.zip文件
void pys_set_startup_file(PYS_HANDLE pysh, const wchar_t* filename); void pys_set_startup_file(PYS_HANDLE pysh, const wchar_t* filename);
// 设置启动模块名和入口函数名func_name为NULL时默认执行指定模块中的main函数 // 设置启动模块名和入口函数名func_name为NULL时默认执行指定模块中的main函数
// 本函数可以省略,默认情况下: // 本函数可以省略,默认情况下:
// 如果startup_file是一个.py文件则默认module_name就是.py文件的文件名本身 // 如果startup_file是一个.py文件则默认module_name就是.py文件的文件名本身
// 如果startup_file是一个.zip文件则默认module_name是`pysmain`。 // 如果startup_file是一个.zip文件则默认module_name是`pysmain`。
void pys_set_bootstrap_module(PYS_HANDLE pysh, const char* module_name, const char* func_name); void pys_set_bootstrap_module(PYS_HANDLE pysh, const char* module_name, const char* func_name);
// 初始化模块的函数原型 // 初始化模块的函数原型
typedef PyObject* (*pys_init_module_func)(void); typedef PyObject* (*pys_init_module_func)(void);
typedef struct PYS_BUILTIN_FUNC typedef struct PYS_BUILTIN_FUNC
{ {
const char* py_func_name; // Python中调用时使用的函数名 const char* py_func_name; // Python中调用时使用的函数名
PyCFunction c_func_addr; // 对应的C的函数 PyCFunction c_func_addr; // 对应的C的函数
PYS_BOOL have_args; // 此函数是否需要参数 PYS_BOOL have_args; // 此函数是否需要参数
const char* py_func_desc; // 此函数的文档注释可以为NULL。 const char* py_func_desc; // 此函数的文档注释可以为NULL。
}PYS_BUILTIN_FUNC; }PYS_BUILTIN_FUNC;
typedef enum PYS_CONST_TYPE typedef enum PYS_CONST_TYPE
{ {
PYS_CONST_BOOL, // Python中得到 True/False 的值 PYS_CONST_BOOL, // Python中得到 True/False 的值
PYS_CONST_LONG, // Python中得到一个整数 PYS_CONST_LONG, // Python中得到一个整数
PYS_CONST_STRING, // Python中得到一个字符串 PYS_CONST_STRING, // Python中得到一个字符串
PYS_CONST_BYTES // Python中得到一个Bytes类型数据 PYS_CONST_BYTES // Python中得到一个Bytes类型数据
}PYS_CONST_TYPE; }PYS_CONST_TYPE;
typedef struct PYS_BUILTIN_CONST typedef struct PYS_BUILTIN_CONST
{ {
char* py_const_name; // Python中调用时使用的变量名 char* py_const_name; // Python中调用时使用的变量名
PYS_CONST_TYPE type; // 常量类型 PYS_CONST_TYPE type; // 常量类型
size_t size; // 常量数据的长度 size_t size; // 常量数据的长度
void* buffer; // 常量数据的内容 void* buffer; // 常量数据的内容
}PYS_BUILTIN_CONST; }PYS_BUILTIN_CONST;
// 增加一个内建模块其中如果没有函数或常量那么对应的funcs/consts可以为NULL。 // 增加一个内建模块其中如果没有函数或常量那么对应的funcs/consts可以为NULL。
// 可多次调用本函数来创建多个内建模块。如果多次调用时使用相同的模块名,则函数和常量会追加到此模块中 // 可多次调用本函数来创建多个内建模块。如果多次调用时使用相同的模块名,则函数和常量会追加到此模块中
// 同一个模块中,函数名和常量名不能重复(但可以通过大小写区分) // 同一个模块中,函数名和常量名不能重复(但可以通过大小写区分)
PYS_BOOL pys_add_builtin_module(PYS_HANDLE pysh, const char* module_name, pys_init_module_func init_func); PYS_BOOL pys_add_builtin_module(PYS_HANDLE pysh, const char* module_name, pys_init_module_func init_func);
PyObject* pys_create_module(const char* module_name, PYS_BUILTIN_FUNC* funcs); PyObject* pys_create_module(const char* module_name, PYS_BUILTIN_FUNC* funcs);
void pys_builtin_const_bool(PyObject* mod, const char* name, PYS_BOOL val); void pys_builtin_const_bool(PyObject* mod, const char* name, PYS_BOOL val);
void pys_builtin_const_long(PyObject* mod, const char* name, long val); void pys_builtin_const_long(PyObject* mod, const char* name, long val);
void pys_builtin_const_utf8(PyObject* mod, const char* name, const char* val); // val 必须是utf8编码的字符串 void pys_builtin_const_utf8(PyObject* mod, const char* name, const char* val); // val 必须是utf8编码的字符串
void pys_builtin_const_wcs(PyObject* mod, const char* name, const wchar_t* val); void pys_builtin_const_wcs(PyObject* mod, const char* name, const wchar_t* val);
void pys_builtin_const_bin(PyObject* mod, const char* name, const ex_u8* val, size_t size); void pys_builtin_const_bin(PyObject* mod, const char* name, const ex_u8* val, size_t size);
// 运行python解释器 // 运行python解释器
int pys_run(PYS_HANDLE pysh); int pys_run(PYS_HANDLE pysh);
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -3,6 +3,9 @@
#include "pys_util.h" #include "pys_util.h"
#ifdef PYS_USE_PYLIB_SHARED #ifdef PYS_USE_PYLIB_SHARED
#if defined(EX_OS_WIN32)
//======================================================== //========================================================
// WIN32 // WIN32
//======================================================== //========================================================
@ -30,6 +33,39 @@ if(!pylib_ ## name) { \
return -1; \ return -1; \
} }
#else
//========================================================
// Unix
//========================================================
#define DECLPROC(name) \
__PROC__ ## name pylib_ ## name = NULL;
#define GETPROCOPT(lib, name, sym) \
pylib_ ## name = (__PROC__ ## name)dlsym(lib, #sym)
#define GETPROC(lib, name) \
GETPROCOPT(lib, name, name); \
if(!pylib_ ## name) { \
EXLOGE("[pys] can not GetProcAddress for " #name "\n"); \
return -1;\
}
#pragma warning(disable:4054)
#define DECLVAR(name) \
__VAR__ ## name* pylib_ ## name = NULL;
#define GETVAR(lib, name) \
pylib_ ## name = (__VAR__ ## name*)dlsym(lib, #name); \
if (!pylib_ ## name) { \
EXLOGE("[pys] can not GetProcAddress for " #name "\n"); \
return -1; \
}
#endif
static int _pys_map_python_lib(DYLIB_HANDLE handle); static int _pys_map_python_lib(DYLIB_HANDLE handle);
static DYLIB_HANDLE _pys_dlopen(const wchar_t* dylib_path); static DYLIB_HANDLE _pys_dlopen(const wchar_t* dylib_path);
@ -70,7 +106,7 @@ DYLIB_HANDLE _pys_dlopen(const wchar_t* dylib_path)
return NULL; return NULL;
} }
EXLOGD("[pys] py-lib-a: %s\n", path); EXLOGD("[pys] py-lib-a: %s\n", path.c_str());
handle = dlopen(path.c_str(), RTLD_NOW | RTLD_GLOBAL); handle = dlopen(path.c_str(), RTLD_NOW | RTLD_GLOBAL);

View File

@ -18,10 +18,10 @@ namespace pys
Core(); Core();
~Core(); ~Core();
// 调用各个成员函数设置必要信息之后再运行 // 调用各个成员函数设置必要信息之后再运行
int run(void); int run();
// 初始化为默认设置 // 初始化为默认设置
bool init(const wchar_t* exec_file, const wchar_t* runtime_path); bool init(const wchar_t* exec_file, const wchar_t* runtime_path);
bool add_search_path(const wchar_t* wpath); bool add_search_path(const wchar_t* wpath);
@ -32,27 +32,27 @@ namespace pys
bool get_builtin_module_by_init_func(pys_init_module_func init_func, ex_astr& module_name); bool get_builtin_module_by_init_func(pys_init_module_func init_func, ex_astr& module_name);
private: private:
bool _load_dylib(void); bool _load_dylib();
bool _run_init_builtin_modules(void); bool _run_init_builtin_modules();
bool _run_prepare(void); bool _run_prepare();
void _run_set_program(void); void _run_set_program();
void _run_set_path(void); void _run_set_path();
void _run_set_argv(void); void _run_set_argv();
public: public:
ex_wstr m_prog_name; // 传递给Python解释器的如果没有设置此值则默认使用m_exec_file。 ex_wstr m_prog_name; // 传递给Python解释器的如果没有设置此值则默认使用m_exec_file。
ex_astr m_bootstrap_module; ex_astr m_bootstrap_module;
ex_astr m_bootstrap_func; ex_astr m_bootstrap_func;
pys_wstr_list m_py_args; // 传递给Python脚本的参数 pys_wstr_list m_py_args; // 传递给Python脚本的参数
private: private:
bool m_is_zipped_app; bool m_is_zipped_app;
ex_wstr m_exec_file; // 当前可执行程序的文件名(绝对路径) ex_wstr m_exec_file; // 当前可执行程序的文件名(绝对路径)
ex_wstr m_exec_path; // 当前可执行程序所在的路径(绝对路径) ex_wstr m_exec_path; // 当前可执行程序所在的路径(绝对路径)
ex_wstr m_runtime_path; // python运行环境路径默认为可执行程序所在路径下的 `pysrt` 目录。 ex_wstr m_runtime_path; // python运行环境路径默认为可执行程序所在路径下的 `pysrt` 目录。
ex_wstr m_start_file; ex_wstr m_start_file;
ex_wstr m_search_path_tmp; ex_wstr m_search_path_tmp;

Binary file not shown.

View File

@ -63,11 +63,10 @@ static bool _process_cmd_line(int argc, wchar_t** argv)
} }
g_run_type = RUN_UNKNOWN; g_run_type = RUN_UNKNOWN;
bool is_py_arg = false;
if (0 == wcscmp(argv[1], L"--version")) if (0 == wcscmp(argv[1], L"--version"))
{ {
EXLOGV("\nTeleport Server, version %ls.\n\n", TP_SERVER_VER); EXLOGI("\nTeleport Server, version %ls.\n\n", TP_SERVER_VER);
return false; return false;
} }
else if (0 == wcscmp(argv[1], L"-i")) else if (0 == wcscmp(argv[1], L"-i"))

View File

@ -143,7 +143,7 @@ bool ts_http_get(const ex_astr& url, ex_astr& body)
mg_mgr_init(&_mgr, NULL); mg_mgr_init(&_mgr, NULL);
mg_connection* nc = mg_connect_http(&_mgr, ev_handler, url.c_str(), NULL, NULL); mg_connection* nc = mg_connect_http(&_mgr, ev_handler, url.c_str(), NULL, NULL);
if (NULL == nc) { if (nc == nullptr) {
mg_mgr_free(&_mgr); mg_mgr_free(&_mgr);
return false; return false;
} }

View File

@ -205,6 +205,7 @@ void SshChannelPair::process_pty_data_from_server(const uint8_t* data, uint32_t
} }
// 处理输入回显,合成最终的命令行字符串 // 处理输入回显,合成最终的命令行字符串
// https://www.systutorials.com/docs/linux/man/4-console_codes/
int offset = 0; int offset = 0;
bool esc_mode = false; bool esc_mode = false;
int esc_arg = 0; int esc_arg = 0;

File diff suppressed because it is too large Load Diff

View File

@ -80,7 +80,7 @@ public:
// -------------------------- // --------------------------
// 通道管理 // 通道管理
// -------------------------- // --------------------------
void set_channel_tp2srv_callbacks(ssh_channel ch_tp2srv); // void set_channel_tp2srv_callbacks(ssh_channel ch_tp2srv);
bool make_channel_pair(ssh_channel ch_tp2cli, ssh_channel ch_tp2srv); bool make_channel_pair(ssh_channel ch_tp2cli, ssh_channel ch_tp2srv);
@ -156,6 +156,8 @@ private:
bool m_first_auth; bool m_first_auth;
// 远程主机认证是否通过 // 远程主机认证是否通过
bool m_auth_passed; bool m_auth_passed;
// 如果认证过程中发生了错误,记录错误提示,后续建立通道后可以发送给客户端进行提示
std::string m_auth_err_msg;
// 发生了不可逆的错误,需要关闭整个会话(包括所有的通道) // 发生了不可逆的错误,需要关闭整个会话(包括所有的通道)
bool m_fault; bool m_fault;

View File

@ -55,8 +55,8 @@ static ex_rv tpp_cmd_set_runtime_config(const char* param) {
return TPE_PARAM; return TPE_PARAM;
ex_u32 noop_timeout = jp["noop_timeout"].asUInt(); ex_u32 noop_timeout = jp["noop_timeout"].asUInt();
if (noop_timeout == 0) // if (noop_timeout == 0)
return TPE_PARAM; // return TPE_PARAM;
g_ssh_proxy.set_cfg(noop_timeout * 60); g_ssh_proxy.set_cfg(noop_timeout * 60);

View File

@ -49,8 +49,8 @@ static ex_rv tpp_cmd_set_runtime_config(const char* param) {
return TPE_PARAM; return TPE_PARAM;
ex_u32 noop_timeout = jp["noop_timeout"].asUInt(); ex_u32 noop_timeout = jp["noop_timeout"].asUInt();
if (noop_timeout == 0) // if (noop_timeout == 0)
return TPE_PARAM; // return TPE_PARAM;
g_telnet_proxy.set_cfg(noop_timeout * 60); g_telnet_proxy.set_cfg(noop_timeout * 60);

View File

@ -19,11 +19,23 @@ include_directories(
../../../common/pyshell/include ../../../common/pyshell/include
) )
include_directories( if (OS_LINUX)
${TP_EXTERNAL_RELEASE_DIR}/include include_directories(
${TP_EXTERNAL_RELEASE_DIR}/include/python3.7m ${TP_EXTERNAL_RELEASE_DIR}/include
) ${TP_EXTERNAL_RELEASE_DIR}/include/python3.7m
link_directories(${TP_EXTERNAL_RELEASE_DIR}/lib) )
link_directories(${TP_EXTERNAL_RELEASE_DIR}/lib)
add_executable(tp_web ${DIR_SRCS})
target_link_libraries(tp_web python3.7m ssl crypto dl pthread rt util)
elseif (OS_MACOS)
include_directories(
/usr/local/Cellar/python@3.9/3.9.0_1/Frameworks/Python.framework/Versions/3.9/include/python3.9
)
link_directories(
# /usr/local/Cellar/python@3.9/3.9.0_1/Frameworks/Python.framework/Versions/3.9/lib
/usr/local/opt/python@3.9/Frameworks/Python.framework/Versions/3.9/lib/python3.9/config-3.9-darwin
)
add_executable(tp_web ${DIR_SRCS})
target_link_libraries(tp_web python3.9 intl dl)
endif ()
add_executable(tp_web ${DIR_SRCS})
target_link_libraries(tp_web python3.7m ssl crypto dl pthread rt util)

View File

@ -4,28 +4,28 @@
#include <ex.h> #include <ex.h>
#include <pys.h> #include <pys.h>
// 命令行参数说明(不带参数运行则以服务方式启动) // 命令行参数说明(不带参数运行则以服务方式启动)
// tp_web [-i|-u|--version] [ [-d] start] [...] // tp_web [-i|-u|--version] [ [-d] start] [...]
// -d 启动程序并输出调试信息(不会运行为守护进程/服务模式) // -d 启动程序并输出调试信息(不会运行为守护进程/服务模式)
// -i 安装服务然后退出仅限Win平台 // -i 安装服务然后退出仅限Win平台
// -u 卸载服务然后退出仅限Win平台 // -u 卸载服务然后退出仅限Win平台
// --version 打印版本号然后退出 // --version 打印版本号然后退出
// start 以服务方式运行 // start 以服务方式运行
// ... 剩余的所有参数均传递给python脚本 // ... 剩余的所有参数均传递给python脚本
// //
// //
// 执行指定的Python脚本 // 执行指定的Python脚本
// tp_web --py [-f FuncName] script_file.py ... // tp_web --py [-f FuncName] script_file.py ...
// --py 必须为第一个参数,表示本次执行为执行指定脚本 // --py 必须为第一个参数,表示本次执行为执行指定脚本
// -f FuncName 指定入口函数默认为main。 // -f FuncName 指定入口函数默认为main。
// script-file.py 被执行的脚本文件 // script-file.py 被执行的脚本文件
// ... 剩余的所有参数均传递给Python脚本 // ... 剩余的所有参数均传递给Python脚本
ExLogger g_ex_logger; ExLogger g_ex_logger;
bool g_is_debug = false; bool g_is_debug = false;
static ex_wstrs g_py_args; static ex_wstrs g_py_args;
// 如果是执行指定脚本 // 如果是执行指定脚本
static ex_wstr g_py_script_file; static ex_wstr g_py_script_file;
static ex_wstr g_py_main_func; static ex_wstr g_py_main_func;
@ -40,8 +40,8 @@ static ex_u8 g_run_type = RUN_UNKNOWN;
static bool _run_daemon(void); static bool _run_daemon(void);
// 导出函数给Python脚本使用主要是为了记录日志 // 导出函数给Python脚本使用主要是为了记录日志
// Windows平台上tp_web程序打开日志文件写之后Python脚本尝试写入方式打开此日志文件时会失败。 // Windows平台上tp_web程序打开日志文件写之后Python脚本尝试写入方式打开此日志文件时会失败。
PyObject* init_web_builtin_module(void); PyObject* init_web_builtin_module(void);
#ifdef EX_OS_WIN32 #ifdef EX_OS_WIN32
@ -186,7 +186,7 @@ static int _main_loop(void)
return 1; return 1;
} }
// 设置web的路径 // 设置web的路径
ex_wstr sf_path; ex_wstr sf_path;
if (g_run_type == RUN_WEB) if (g_run_type == RUN_WEB)
{ {
@ -344,10 +344,10 @@ static DWORD WINAPI service_thread_func(LPVOID lpParam);
int main() int main()
{ {
int ret = 0; int ret = 0;
LPWSTR szCmdLine = (LPWSTR)::GetCommandLineW(); //获取命令行参数; LPWSTR szCmdLine = (LPWSTR)::GetCommandLineW(); //获取命令行参数;
int _argc = 0; int _argc = 0;
wchar_t** _argv = ::CommandLineToArgvW(szCmdLine, &_argc); //拆分命令行参数字符串; wchar_t** _argv = ::CommandLineToArgvW(szCmdLine, &_argc); //拆分命令行参数字符串;
ret = _app_main(_argc, _argv); ret = _app_main(_argc, _argv);
@ -379,7 +379,7 @@ static DWORD WINAPI service_thread_func(LPVOID lpParam)
{ {
int ret = _main_loop(); int ret = _main_loop();
// 更新服务状态(如果服务还在运行,将其设置为停止状态) // 更新服务状态(如果服务还在运行,将其设置为停止状态)
g_ServiceStatus.dwWin32ExitCode = 0; g_ServiceStatus.dwWin32ExitCode = 0;
g_ServiceStatus.dwCurrentState = SERVICE_STOPPED; g_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
g_ServiceStatus.dwCheckPoint = 0; g_ServiceStatus.dwCheckPoint = 0;
@ -552,7 +552,7 @@ static bool _run_daemon(void)
//=============================================================== //===============================================================
// 加入内建模块供脚本调用 // 加入内建模块供脚本调用
//=============================================================== //===============================================================
PyObject* _py_log_output(PyObject* self, PyObject* args) PyObject* _py_log_output(PyObject* self, PyObject* args)
{ {
@ -629,10 +629,10 @@ PyObject* _py_log_console(PyObject* self, PyObject* args)
PYS_BUILTIN_FUNC _demo_funcs[] = { PYS_BUILTIN_FUNC _demo_funcs[] = {
{ {
"log_output", // 脚本函数名,在脚本中使用 "log_output", // 脚本函数名,在脚本中使用
_py_log_output, // 对应的C代码函数名 _py_log_output, // 对应的C代码函数名
PYS_TRUE, // 函数的基本信息(是否需要参数,等等) PYS_TRUE, // 函数的基本信息(是否需要参数,等等)
"write log." // 函数的说明文档,可选(可以是空字符串) "write log." // 函数的说明文档,可选(可以是空字符串)
}, },
{ {
@ -649,7 +649,7 @@ PYS_BUILTIN_FUNC _demo_funcs[] = {
"set log to console or not." "set log to console or not."
}, },
// 最后一组,第一个成员为空指针,表示结束 // 最后一组,第一个成员为空指针,表示结束
{ NULL, NULL, 0, NULL } { NULL, NULL, 0, NULL }
}; };
@ -666,7 +666,7 @@ PyObject* init_web_builtin_module(void)
pys_builtin_const_long(mod, "EX_LOG_LEVEL_ERROR", EX_LOG_LEVEL_ERROR); pys_builtin_const_long(mod, "EX_LOG_LEVEL_ERROR", EX_LOG_LEVEL_ERROR);
// pys_builtin_const_bool(mod, "DEMO_CONST_2", PYS_TRUE); // pys_builtin_const_bool(mod, "DEMO_CONST_2", PYS_TRUE);
// //pys_builtin_const_wcs(mod, "DEMO_CONST_3", L"STRING 中文测试 this is string."); // //pys_builtin_const_wcs(mod, "DEMO_CONST_3", L"STRING 中文测试 this is string.");
// pys_builtin_const_wcs(mod, "DEMO_CONST_3", L"STRING this is string."); // pys_builtin_const_wcs(mod, "DEMO_CONST_3", L"STRING this is string.");
// pys_builtin_const_utf8(mod, "DEMO_CONST_4", "this is string."); // pys_builtin_const_utf8(mod, "DEMO_CONST_4", "this is string.");
// //

View File

@ -132,9 +132,9 @@ class WebApp:
if not tp_stats().init(): if not tp_stats().init():
log.e('can not initialize system status collector.\n') log.e('can not initialize system status collector.\n')
return 0 return 0
if not tp_host_alive().init(): # if not tp_host_alive().init():
log.e('can not initialize host state inspector.\n') # log.e('can not initialize host state inspector.\n')
return 0 # return 0
settings = { settings = {
# #
@ -189,7 +189,7 @@ class WebApp:
except: except:
log.e('\n') log.e('\n')
tp_host_alive().stop() # tp_host_alive().stop()
tp_cron().stop() tp_cron().stop()
return 0 return 0