mirror of https://github.com/tp4a/teleport
parent
f6cc313f87
commit
47c2fdcff4
|
@ -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_log.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_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$/server/tp_core/common/base_env.h" 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_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_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" />
|
||||
</component>
|
||||
</project>
|
|
@ -3,9 +3,11 @@ project(teleport)
|
|||
|
||||
include(CMakeCfg.txt)
|
||||
|
||||
if (OS_LINUX)
|
||||
add_subdirectory(server/tp_web/src)
|
||||
endif()
|
||||
#if (OS_LINUX)
|
||||
# add_subdirectory(server/tp_web/src)
|
||||
#endif()
|
||||
|
||||
add_subdirectory(server/tp_web/src)
|
||||
|
||||
add_subdirectory(server/tp_core/core)
|
||||
add_subdirectory(server/tp_core/protocol/ssh)
|
||||
|
|
|
@ -102,7 +102,7 @@
|
|||
"name": "FreeRDP",
|
||||
"display": "FreeRDP",
|
||||
"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": [
|
||||
"建议使用homebrew安装freerdp,安装后freerdp默认路径在:/usr/local/Cellar/freerdp/x.y.z/bin/xfreerdp",
|
||||
"首次安装freerdp后需要重新启动计算机"
|
||||
|
|
|
@ -19,42 +19,49 @@ typedef std::map<ex_wstr, ex_wstr> ex_ini_kvs;
|
|||
class ExIniSection
|
||||
{
|
||||
public:
|
||||
ExIniSection();
|
||||
ExIniSection(const ex_wstr& strSectionName);
|
||||
~ExIniSection();
|
||||
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);
|
||||
bool GetStr(const ex_wstr& strKey, ex_wstr& strValue);
|
||||
void ClearUp();
|
||||
|
||||
void GetInt(const ex_wstr& strKey, int& iValue, int iDefault);
|
||||
bool GetInt(const ex_wstr& strKey, int& iValue);
|
||||
ex_wstr Name() { return m_strName; }
|
||||
|
||||
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);
|
||||
void GetStr(const ex_wstr& strKey, ex_wstr& strValue, const ex_wstr& strDefault);
|
||||
|
||||
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
|
||||
void Dump(void);
|
||||
void Dump(void);
|
||||
#endif
|
||||
|
||||
protected:
|
||||
bool _IsKeyExists(const ex_wstr& strKey);
|
||||
bool _IsKeyExists(const ex_wstr& strKey);
|
||||
|
||||
private:
|
||||
ex_wstr m_strName;
|
||||
ex_ini_kvs m_kvs;
|
||||
ex_wstr m_strName;
|
||||
ex_ini_kvs m_kvs;
|
||||
};
|
||||
|
||||
|
||||
|
@ -64,49 +71,55 @@ typedef std::map<ex_wstr, ExIniSection*> ex_ini_sections;
|
|||
class ExIniFile
|
||||
{
|
||||
public:
|
||||
enum PARSE_RV
|
||||
{
|
||||
PARSE_ERROR,
|
||||
PARSE_SECTION,
|
||||
PARSE_KEYVALUE,
|
||||
PARSE_COMMENT,
|
||||
PARSE_OTHER
|
||||
};
|
||||
enum PARSE_RV
|
||||
{
|
||||
PARSE_ERROR,
|
||||
PARSE_SECTION,
|
||||
PARSE_KEYVALUE,
|
||||
PARSE_COMMENT,
|
||||
PARSE_OTHER
|
||||
};
|
||||
|
||||
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.
|
||||
bool LoadFromFile(const ex_wstr& strFileName, bool bClearOld = true);
|
||||
bool LoadFromMemory(const ex_wstr& strData, bool bClearOld = true);
|
||||
void ClearUp();
|
||||
|
||||
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);
|
||||
ExIniSection* GetDumySection(void) { return &m_dumy_sec; }
|
||||
bool LoadFromMemory(const ex_wstr& strData, bool bClearOld = true);
|
||||
|
||||
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
|
||||
void Dump(void);
|
||||
void Dump(void);
|
||||
#endif
|
||||
|
||||
protected:
|
||||
static PARSE_RV _ParseLine(const ex_wstr& strLine, ex_wstr& strKey, ex_wstr& strValue);
|
||||
bool _ProcessLine(const ex_wstr strLine, ExIniSection** pCurSection);
|
||||
static PARSE_RV parse_line_(const ex_wstr& strLine, ex_wstr& strKey, ex_wstr& strValue);
|
||||
|
||||
bool process_line_(const ex_wstr& strLine, ExIniSection** pCurSection);
|
||||
|
||||
private:
|
||||
ex_ini_sections m_secs;
|
||||
ExIniSection m_dumy_sec;
|
||||
ex_wstr m_file_path;
|
||||
ex_ini_sections m_secs;
|
||||
ExIniSection m_dumy_sec;
|
||||
ex_wstr m_file_path;
|
||||
};
|
||||
|
||||
#endif // __EX_INI_H__
|
||||
|
|
|
@ -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);
|
||||
|
||||
#define EXLOGD ex_printf_d
|
||||
#define EXLOGV ex_printf_v
|
||||
#define EXLOGI ex_printf_i
|
||||
#define EXLOGW ex_printf_w
|
||||
#define EXLOGE ex_printf_e
|
||||
#define EXLOGD ex_printf_d
|
||||
#define EXLOG_BIN ex_printf_bin
|
||||
|
||||
#ifdef EX_OS_WIN32
|
||||
|
|
|
@ -4,524 +4,493 @@
|
|||
|
||||
ExIniSection::ExIniSection(const ex_wstr& strSectionName)
|
||||
{
|
||||
m_kvs.clear();
|
||||
m_strName = strSectionName;
|
||||
m_kvs.clear();
|
||||
m_strName = strSectionName;
|
||||
}
|
||||
|
||||
ExIniSection::ExIniSection()
|
||||
{
|
||||
m_kvs.clear();
|
||||
m_strName = L"N/A";
|
||||
m_kvs.clear();
|
||||
m_strName = L"N/A";
|
||||
}
|
||||
|
||||
ExIniSection::~ExIniSection()
|
||||
{
|
||||
m_kvs.clear();
|
||||
m_kvs.clear();
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
ex_ini_kvs::iterator it = m_kvs.find(strKey);
|
||||
if (m_kvs.end() == it)
|
||||
strValue = strDefault;
|
||||
else
|
||||
strValue = (*it).second;
|
||||
ex_ini_kvs::iterator it = m_kvs.find(strKey);
|
||||
if (m_kvs.end() == it)
|
||||
strValue = strDefault;
|
||||
else
|
||||
strValue = (*it).second;
|
||||
}
|
||||
|
||||
bool ExIniSection::GetStr(const ex_wstr& strKey, ex_wstr& strValue)
|
||||
{
|
||||
ex_ini_kvs::iterator it = m_kvs.find(strKey);
|
||||
if (m_kvs.end() == it)
|
||||
return false;
|
||||
ex_ini_kvs::iterator it = m_kvs.find(strKey);
|
||||
if (m_kvs.end() == it)
|
||||
return false;
|
||||
|
||||
strValue = (*it).second;
|
||||
return true;
|
||||
strValue = (*it).second;
|
||||
return true;
|
||||
}
|
||||
|
||||
void ExIniSection::GetInt(const ex_wstr& strKey, int& iValue, int iDefault)
|
||||
{
|
||||
ex_ini_kvs::iterator it = m_kvs.find(strKey);
|
||||
if (m_kvs.end() == it)
|
||||
{
|
||||
iValue = iDefault;
|
||||
return;
|
||||
}
|
||||
ex_ini_kvs::iterator it = m_kvs.find(strKey);
|
||||
if (m_kvs.end() == it)
|
||||
{
|
||||
iValue = iDefault;
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef EX_OS_WIN32
|
||||
iValue = _wtoi(it->second.c_str());
|
||||
iValue = _wtoi(it->second.c_str());
|
||||
#else
|
||||
ex_astr tmp;
|
||||
ex_wstr2astr(it->second, tmp);
|
||||
iValue = atoi(tmp.c_str());
|
||||
iValue = atoi(tmp.c_str());
|
||||
#endif
|
||||
}
|
||||
|
||||
bool ExIniSection::GetInt(const ex_wstr& strKey, int& iValue)
|
||||
{
|
||||
ex_ini_kvs::iterator it = m_kvs.find(strKey);
|
||||
if (m_kvs.end() == it)
|
||||
return false;
|
||||
ex_ini_kvs::iterator it = m_kvs.find(strKey);
|
||||
if (m_kvs.end() == it)
|
||||
return false;
|
||||
|
||||
#ifdef EX_OS_WIN32
|
||||
iValue = _wtoi(it->second.c_str());
|
||||
iValue = _wtoi(it->second.c_str());
|
||||
#else
|
||||
ex_astr tmp;
|
||||
ex_wstr2astr(it->second, tmp);
|
||||
iValue = atoi(tmp.c_str());
|
||||
iValue = atoi(tmp.c_str());
|
||||
#endif
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void ExIniSection::GetBool(const ex_wstr& strKey, bool& bValue, bool bDefault)
|
||||
{
|
||||
ex_ini_kvs::iterator it = m_kvs.find(strKey);
|
||||
if (m_kvs.end() == it)
|
||||
{
|
||||
bValue = bDefault;
|
||||
return;
|
||||
}
|
||||
ex_ini_kvs::iterator it = m_kvs.find(strKey);
|
||||
if (m_kvs.end() == it)
|
||||
{
|
||||
bValue = bDefault;
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
it->second == L"1"
|
||||
#ifdef EX_OS_WIN32
|
||||
|| 0 == _wcsicmp(it->second.c_str(), L"true")
|
||||
#else
|
||||
|| 0 == wcscasecmp(it->second.c_str(), L"true")
|
||||
if (
|
||||
it->second == L"1"
|
||||
#ifdef EX_OS_WIN32
|
||||
|| 0 == _wcsicmp(it->second.c_str(), L"true")
|
||||
#else
|
||||
|| 0 == wcscasecmp(it->second.c_str(), L"true")
|
||||
#endif
|
||||
)
|
||||
bValue = true;
|
||||
else
|
||||
bValue = false;
|
||||
)
|
||||
bValue = true;
|
||||
else
|
||||
bValue = false;
|
||||
}
|
||||
|
||||
bool ExIniSection::GetBool(const ex_wstr& strKey, bool& bValue)
|
||||
{
|
||||
ex_ini_kvs::iterator it = m_kvs.find(strKey);
|
||||
if (m_kvs.end() == it)
|
||||
return false;
|
||||
ex_ini_kvs::iterator it = m_kvs.find(strKey);
|
||||
if (m_kvs.end() == it)
|
||||
return false;
|
||||
|
||||
if (
|
||||
it->second == L"1"
|
||||
#ifdef EX_OS_WIN32
|
||||
|| 0 == _wcsicmp(it->second.c_str(), _T("true"))
|
||||
#else
|
||||
|| 0 == wcscasecmp(it->second.c_str(), L"true")
|
||||
if (
|
||||
it->second == L"1"
|
||||
#ifdef EX_OS_WIN32
|
||||
|| 0 == _wcsicmp(it->second.c_str(), _T("true"))
|
||||
#else
|
||||
|| 0 == wcscasecmp(it->second.c_str(), L"true")
|
||||
#endif
|
||||
)
|
||||
bValue = true;
|
||||
else
|
||||
bValue = false;
|
||||
)
|
||||
bValue = true;
|
||||
else
|
||||
bValue = false;
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool ExIniSection::SetValue(const ex_wstr& strKey, const ex_wstr& strValue, bool bAddIfNotExists)
|
||||
{
|
||||
ex_ini_kvs::iterator it = m_kvs.find(strKey);
|
||||
if (it != m_kvs.end())
|
||||
{
|
||||
it->second = strValue;
|
||||
return true;
|
||||
}
|
||||
ex_ini_kvs::iterator it = m_kvs.find(strKey);
|
||||
if (it != m_kvs.end())
|
||||
{
|
||||
it->second = strValue;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (bAddIfNotExists)
|
||||
{
|
||||
m_kvs.insert(std::make_pair(strKey, strValue));
|
||||
return true;
|
||||
}
|
||||
if (bAddIfNotExists)
|
||||
{
|
||||
m_kvs.insert(std::make_pair(strKey, strValue));
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
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 (; it != m_kvs.end(); ++it)
|
||||
{
|
||||
ex_wstr temp;
|
||||
temp += it->first.c_str();
|
||||
temp += L"=";
|
||||
temp += it->second.c_str();
|
||||
temp += L"\n";
|
||||
ex_astr temp2;
|
||||
ex_wstr2astr(temp, temp2, codepage);
|
||||
fwrite(temp2.c_str(), temp2.size(), 1, file);
|
||||
}
|
||||
return;
|
||||
for (auto it = m_kvs.begin(); it != m_kvs.end(); ++it)
|
||||
{
|
||||
ex_wstr temp;
|
||||
temp += it->first;
|
||||
temp += L'=';
|
||||
temp += it->second;
|
||||
temp += L'\n';
|
||||
ex_astr temp2;
|
||||
ex_wstr2astr(temp, temp2, codepage);
|
||||
fwrite(temp2.c_str(), temp2.size(), 1, file);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef EX_DEBUG
|
||||
void ExIniSection::Dump(void)
|
||||
{
|
||||
ex_ini_kvs::iterator it = m_kvs.begin();
|
||||
for (; it != m_kvs.end(); ++it)
|
||||
{
|
||||
EXLOGD(_T(" [%s]=[%s]\n"), it->first.c_str(), it->second.c_str());
|
||||
}
|
||||
for (auto it = m_kvs.begin(); it != m_kvs.end(); ++it)
|
||||
{
|
||||
EXLOGD(_T(" [%s]=[%s]\n"), it->first.c_str(), it->second.c_str());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
ExIniFile::ExIniFile()
|
||||
{
|
||||
}
|
||||
ExIniFile::ExIniFile() = default;
|
||||
|
||||
ExIniFile::~ExIniFile()
|
||||
{
|
||||
ClearUp();
|
||||
ClearUp();
|
||||
}
|
||||
|
||||
bool ExIniFile::LoadFromFile(const ex_wstr& strFileName, bool bClearOld)
|
||||
{
|
||||
#ifdef EX_OS_WIN32
|
||||
HANDLE hFile = ::CreateFileW(strFileName.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (INVALID_HANDLE_VALUE == hFile)
|
||||
return false;
|
||||
HANDLE hFile = ::CreateFileW(strFileName.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (INVALID_HANDLE_VALUE == hFile)
|
||||
return false;
|
||||
|
||||
ULONG ulFileSize = GetFileSize(hFile, NULL);
|
||||
if (INVALID_FILE_SIZE == ulFileSize)
|
||||
{
|
||||
CloseHandle(hFile);
|
||||
return false;
|
||||
}
|
||||
ULONG ulFileSize = GetFileSize(hFile, NULL);
|
||||
if (INVALID_FILE_SIZE == ulFileSize)
|
||||
{
|
||||
CloseHandle(hFile);
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<char> vFile;
|
||||
vFile.resize(ulFileSize + 1);
|
||||
ZeroMemory(&vFile[0], ulFileSize + 1);
|
||||
std::vector<char> vFile;
|
||||
vFile.resize(ulFileSize + 1);
|
||||
ZeroMemory(&vFile[0], ulFileSize + 1);
|
||||
|
||||
DWORD dwRead = 0;
|
||||
if (!ReadFile(hFile, &vFile[0], ulFileSize, &dwRead, NULL) || ulFileSize != dwRead)
|
||||
{
|
||||
CloseHandle(hFile);
|
||||
return false;
|
||||
}
|
||||
DWORD dwRead = 0;
|
||||
if (!ReadFile(hFile, &vFile[0], ulFileSize, &dwRead, NULL) || ulFileSize != dwRead)
|
||||
{
|
||||
CloseHandle(hFile);
|
||||
return false;
|
||||
}
|
||||
|
||||
CloseHandle(hFile);
|
||||
CloseHandle(hFile);
|
||||
|
||||
m_file_path = strFileName;
|
||||
m_file_path = strFileName;
|
||||
#else
|
||||
FILE* f = NULL;
|
||||
FILE* f = nullptr;
|
||||
ex_astr _fname;
|
||||
ex_wstr2astr(strFileName, _fname);
|
||||
f = fopen(_fname.c_str(), "rb");
|
||||
if(f == NULL)
|
||||
return false;
|
||||
fseek(f, 0L, SEEK_END);
|
||||
unsigned long ulFileSize = (unsigned long)ftell(f);
|
||||
if(-1 == ulFileSize)
|
||||
{
|
||||
fclose(f);
|
||||
return false;
|
||||
}
|
||||
f = fopen(_fname.c_str(), "rb");
|
||||
if (!f)
|
||||
return false;
|
||||
fseek(f, 0L, SEEK_END);
|
||||
auto ulFileSize = static_cast<unsigned long>(ftell(f));
|
||||
if (-1 == ulFileSize)
|
||||
{
|
||||
fclose(f);
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<char> vFile;
|
||||
vFile.resize(ulFileSize + 1);
|
||||
memset(&vFile[0], 0, ulFileSize + 1);
|
||||
std::vector<char> vFile;
|
||||
vFile.resize(ulFileSize + 1);
|
||||
memset(&vFile[0], 0, ulFileSize + 1);
|
||||
|
||||
fseek(f, 0L, SEEK_SET);
|
||||
fread(&vFile[0], 1, ulFileSize, f);
|
||||
fclose(f);
|
||||
fseek(f, 0L, SEEK_SET);
|
||||
fread(&vFile[0], 1, ulFileSize, f);
|
||||
fclose(f);
|
||||
|
||||
m_file_path = strFileName;
|
||||
m_file_path = strFileName;
|
||||
#endif
|
||||
|
||||
char *pOffset = &vFile[0];
|
||||
if ((ulFileSize > 3) && (0 == memcmp(pOffset, "\xEF\xBB\xBF", 3)))
|
||||
{
|
||||
pOffset += 3;
|
||||
}
|
||||
// 配置文件均使用UTF8编码
|
||||
ex_wstr fileData;
|
||||
if (!ex_astr2wstr(pOffset, fileData, EX_CODEPAGE_UTF8))
|
||||
return false;
|
||||
char* pOffset = &vFile[0];
|
||||
if ((ulFileSize > 3) && (0 == memcmp(pOffset, "\xEF\xBB\xBF", 3)))
|
||||
{
|
||||
pOffset += 3;
|
||||
}
|
||||
// 配置文件均使用UTF8编码
|
||||
ex_wstr fileData;
|
||||
if (!ex_astr2wstr(pOffset, fileData, EX_CODEPAGE_UTF8))
|
||||
return false;
|
||||
|
||||
return LoadFromMemory(fileData, bClearOld);
|
||||
return LoadFromMemory(fileData, bClearOld);
|
||||
}
|
||||
|
||||
bool ExIniFile::LoadFromMemory(const ex_wstr& strData, bool bClearOld)
|
||||
{
|
||||
if (strData.empty())
|
||||
return false;
|
||||
if (strData.empty())
|
||||
return false;
|
||||
|
||||
ex_wstr strAll(strData);
|
||||
bool bRet = true;
|
||||
ExIniSection* pCurSection = NULL;
|
||||
ex_wstr strAll(strData);
|
||||
bool bRet = true;
|
||||
ExIniSection* pCurSection = nullptr;
|
||||
|
||||
do {
|
||||
// Clear old data.
|
||||
if (bClearOld)
|
||||
ClearUp();
|
||||
do
|
||||
{
|
||||
// Clear old data.
|
||||
if (bClearOld)
|
||||
ClearUp();
|
||||
|
||||
ex_wstr strKey(L"");
|
||||
ex_wstr strValue(L"");
|
||||
ex_wstr strKey;
|
||||
ex_wstr strValue;
|
||||
|
||||
ex_wstr strLine(L"");
|
||||
ex_wstr::size_type posCR = ex_wstr::npos;
|
||||
ex_wstr::size_type posLF = ex_wstr::npos;
|
||||
for (;;)
|
||||
{
|
||||
posCR = ex_wstr::npos;
|
||||
posLF = ex_wstr::npos;
|
||||
posCR = strAll.find(L"\r");
|
||||
posLF = strAll.find(L"\n");
|
||||
ex_wstr strLine;
|
||||
ex_wstr::size_type posCR = ex_wstr::npos;
|
||||
ex_wstr::size_type posLF = ex_wstr::npos;
|
||||
for (;;)
|
||||
{
|
||||
posCR = strAll.find(L'\r');
|
||||
posLF = strAll.find(L'\n');
|
||||
|
||||
if(posCR == ex_wstr::npos && posLF == ex_wstr::npos) {
|
||||
if (strAll.empty())
|
||||
break;
|
||||
strLine = strAll;
|
||||
strAll.clear();
|
||||
} else if(posCR != ex_wstr::npos && posLF != ex_wstr::npos) {
|
||||
if(posLF != posCR + 1) {
|
||||
if(posLF < posCR) {
|
||||
strLine.assign(strAll, 0, posLF);
|
||||
strAll.erase(0, posLF + 1);
|
||||
} else {
|
||||
strLine.assign(strAll, 0, posCR);
|
||||
strAll.erase(0, posCR + 1);
|
||||
}
|
||||
} else {
|
||||
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 (posCR == ex_wstr::npos && posLF == ex_wstr::npos)
|
||||
{
|
||||
if (strAll.empty())
|
||||
break;
|
||||
strLine = strAll;
|
||||
strAll.clear();
|
||||
}
|
||||
else if (posCR != ex_wstr::npos && posLF != ex_wstr::npos)
|
||||
{
|
||||
if (posLF != posCR + 1)
|
||||
{
|
||||
if (posLF < posCR)
|
||||
{
|
||||
strLine.assign(strAll, 0, posLF);
|
||||
strAll.erase(0, posLF + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
strLine.assign(strAll, 0, posCR);
|
||||
strAll.erase(0, posCR + 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
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)
|
||||
// {
|
||||
// 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))
|
||||
continue;
|
||||
|
||||
if (ex_only_white_space(strLine))
|
||||
continue;
|
||||
if (!process_line_(strLine, &pCurSection))
|
||||
{
|
||||
bRet = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!_ProcessLine(strLine, &pCurSection))
|
||||
{
|
||||
bRet = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (false);
|
||||
|
||||
} while (false);
|
||||
|
||||
return bRet;
|
||||
return bRet;
|
||||
}
|
||||
|
||||
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");
|
||||
if (!file)
|
||||
return;
|
||||
|
||||
if (file == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// 如果有不属于任何小节的值对,先保存之
|
||||
if (m_dumy_sec.Count() > 0)
|
||||
m_dumy_sec.Save(file, codepage);
|
||||
|
||||
// 如果有不属于任何小节的值对,先保存之
|
||||
if (m_dumy_sec.Count() > 0)
|
||||
m_dumy_sec.Save(file, codepage);
|
||||
for (auto it = m_secs.begin(); it != m_secs.end(); ++it)
|
||||
{
|
||||
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();
|
||||
for (; it != m_secs.end(); ++it)
|
||||
{
|
||||
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);
|
||||
it->second->Save(file, codepage);
|
||||
}
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
#ifdef EX_DEBUG
|
||||
void ExIniFile::Dump(void)
|
||||
{
|
||||
ex_ini_sections::iterator it = m_secs.begin();
|
||||
for (; it != m_secs.end(); ++it)
|
||||
{
|
||||
EXLOGD(_T("{%s}\n"), it->first.c_str());
|
||||
it->second->Dump();
|
||||
}
|
||||
for (auto it = m_secs.begin(); it != m_secs.end(); ++it)
|
||||
{
|
||||
EXLOGD(_T("{%s}\n"), it->first.c_str());
|
||||
it->second->Dump();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void ExIniFile::ClearUp(void)
|
||||
void ExIniFile::ClearUp()
|
||||
{
|
||||
ex_ini_sections::iterator it = m_secs.begin();
|
||||
for (; it != m_secs.end(); ++it)
|
||||
{
|
||||
delete it->second;
|
||||
}
|
||||
m_secs.clear();
|
||||
for (auto it = m_secs.begin(); it != m_secs.end(); ++it)
|
||||
{
|
||||
delete it->second;
|
||||
}
|
||||
m_secs.clear();
|
||||
}
|
||||
|
||||
ExIniSection* ExIniFile::GetSection(const ex_wstr& strName, bool bCreateIfNotExists)
|
||||
{
|
||||
ex_ini_sections::iterator it = m_secs.find(strName);
|
||||
if (it != m_secs.end())
|
||||
return it->second;
|
||||
auto it = m_secs.find(strName);
|
||||
if (it != m_secs.end())
|
||||
return it->second;
|
||||
|
||||
if (!bCreateIfNotExists)
|
||||
return NULL;
|
||||
if (!bCreateIfNotExists)
|
||||
return nullptr;
|
||||
|
||||
ExIniSection* pSec = new ExIniSection(strName);
|
||||
m_secs.insert(std::make_pair(strName, pSec));
|
||||
return pSec;
|
||||
auto pSec = new ExIniSection(strName);
|
||||
m_secs.insert(std::make_pair(strName, pSec));
|
||||
return pSec;
|
||||
}
|
||||
|
||||
// static function.
|
||||
// 解析一行,返回值为 [节名/值对/注释/什么也不是/出错了]
|
||||
// 节名 => strKey = [section_name]
|
||||
// 值对 => 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 控制
|
||||
ex_wstr strLine(strOrigLine);
|
||||
ex_remove_white_space(strLine, EX_RSC_BEGIN);
|
||||
// 首先去掉行首的空格或者 TAB 控制
|
||||
ex_wstr line(strLine);
|
||||
ex_remove_white_space(line, EX_RSC_BEGIN);
|
||||
|
||||
// 判断是否为注释。 .ini 文件以 分号';'/'#' 作为注释行的第一个字符
|
||||
if (';' == strLine[0] || '#' == strLine[0])
|
||||
{
|
||||
return PARSE_COMMENT;
|
||||
}
|
||||
// 判断是否为注释。 .ini 文件以 分号';'/'#' 作为注释行的第一个字符
|
||||
if (';' == line[0] || '#' == line[0])
|
||||
{
|
||||
return PARSE_COMMENT;
|
||||
}
|
||||
|
||||
if ('[' == strLine[0])
|
||||
{
|
||||
// 这是一个节(section)
|
||||
ex_wstr::size_type startPos = strLine.find('[');
|
||||
ex_wstr::size_type endPos = strLine.rfind(']');
|
||||
strLine.erase(endPos);
|
||||
strLine.erase(startPos, 1);
|
||||
if ('[' == line[0])
|
||||
{
|
||||
// 这是一个节(section)
|
||||
ex_wstr::size_type startPos = line.find('[');
|
||||
ex_wstr::size_type endPos = line.rfind(']');
|
||||
line.erase(endPos);
|
||||
line.erase(startPos, 1);
|
||||
|
||||
strKey = strLine;
|
||||
return PARSE_SECTION;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 看看能否找到等号(=),这是 key=value 的判别方法
|
||||
ex_wstr::size_type pos = strLine.find('=');
|
||||
if (ex_wstr::npos == pos)
|
||||
{
|
||||
//return PARSE_OTHER; // 没有等号
|
||||
ex_remove_white_space(strLine);
|
||||
strKey = strLine;
|
||||
strValue.clear();
|
||||
return PARSE_KEYVALUE;
|
||||
}
|
||||
strKey = line;
|
||||
return PARSE_SECTION;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 看看能否找到等号(=),这是 key=value 的判别方法
|
||||
// 如果没有等号,则整个视作 key,value为 NULL这样。
|
||||
ex_wstr::size_type pos = line.find('=');
|
||||
if (ex_wstr::npos == pos)
|
||||
{
|
||||
//return PARSE_OTHER; // 没有等号
|
||||
ex_remove_white_space(line);
|
||||
strKey = line;
|
||||
strValue.clear();
|
||||
return PARSE_KEYVALUE;
|
||||
}
|
||||
|
||||
// 将等号前面的与等号后面的分割
|
||||
strKey.assign(strLine, 0, pos);
|
||||
strValue.assign(strLine, pos + 1, strLine.length() - pos);
|
||||
ex_remove_white_space(strKey);
|
||||
// 将等号前面的与等号后面的分割
|
||||
strKey.assign(line, 0, pos);
|
||||
strValue.assign(line, pos + 1, line.length() - pos);
|
||||
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())
|
||||
return true;
|
||||
if (strLine.empty())
|
||||
return true;
|
||||
|
||||
ex_wstr strKey;//(_T(""));
|
||||
ex_wstr strValue;//(_T(""));
|
||||
ex_wstr strKey;
|
||||
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)
|
||||
{
|
||||
case PARSE_ERROR:
|
||||
bError = true;
|
||||
break;
|
||||
case PARSE_SECTION:
|
||||
{
|
||||
// 创建一个节
|
||||
ExIniSection* pSection = GetSection(strKey, true);
|
||||
if (NULL == pSection)
|
||||
{
|
||||
bError = true;
|
||||
break;
|
||||
}
|
||||
// 创建一个值对
|
||||
if (!(*pCurSection)->SetValue(strKey, strValue, true))
|
||||
{
|
||||
bError = true;
|
||||
break;
|
||||
}
|
||||
|
||||
*pCurSection = pSection;
|
||||
}
|
||||
break;
|
||||
case PARSE_KEYVALUE:
|
||||
if (NULL == pCurSection || NULL == *pCurSection)
|
||||
{
|
||||
//bError = true;
|
||||
//break;
|
||||
*pCurSection = &m_dumy_sec;
|
||||
}
|
||||
break;
|
||||
|
||||
// 创建一个值对
|
||||
if (!(*pCurSection)->SetValue(strKey, strValue, true))
|
||||
{
|
||||
bError = true;
|
||||
break;
|
||||
}
|
||||
case PARSE_COMMENT:
|
||||
case PARSE_OTHER:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case PARSE_COMMENT:
|
||||
case PARSE_OTHER:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return (!bError);
|
||||
return (!bError);
|
||||
}
|
||||
|
|
|
@ -26,6 +26,9 @@ extern "C" {
|
|||
#elif defined(EX_OS_LINUX)
|
||||
# define PYS_USE_PYLIB_STATIC
|
||||
# include <Python.h>
|
||||
#elif defined(EX_OS_MACOS)
|
||||
# define PYS_USE_PYLIB_SHARED
|
||||
# include <Python.h>
|
||||
#else
|
||||
# error This platform not supported yet.
|
||||
#endif
|
||||
|
@ -200,73 +203,73 @@ extern "C" {
|
|||
|
||||
typedef void* PYS_HANDLE;
|
||||
|
||||
// 创建一个PyShell句柄,所有操作均对应此句柄进行(一个进程仅有一个句柄)
|
||||
// 创建一个PyShell句柄,所有操作均对应此句柄进行(一个进程仅有一个句柄)
|
||||
PYS_HANDLE pys_create(void);
|
||||
// 销毁一个PyShell句柄
|
||||
// 销毁一个PyShell句柄
|
||||
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);
|
||||
|
||||
// 设置python包搜索路径,可多次调用进行追加(可省略)
|
||||
// 设置python包搜索路径,可多次调用进行追加(可省略)
|
||||
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);
|
||||
// 追加python运行时的命令行参数(可省略)
|
||||
// 追加python运行时的命令行参数(可省略)
|
||||
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);
|
||||
|
||||
// 设置入口脚本文件名,可以是一个.py文件,也可以是一个.zip文件
|
||||
// 设置入口脚本文件名,可以是一个.py文件,也可以是一个.zip文件
|
||||
void pys_set_startup_file(PYS_HANDLE pysh, const wchar_t* filename);
|
||||
|
||||
// 设置启动模块名和入口函数名,func_name为NULL时默认执行指定模块中的main函数
|
||||
// 本函数可以省略,默认情况下:
|
||||
// 如果startup_file是一个.py文件,则默认module_name就是.py文件的文件名本身,
|
||||
// 如果startup_file是一个.zip文件,则默认module_name是`pysmain`。
|
||||
// 设置启动模块名和入口函数名,func_name为NULL时默认执行指定模块中的main函数
|
||||
// 本函数可以省略,默认情况下:
|
||||
// 如果startup_file是一个.py文件,则默认module_name就是.py文件的文件名本身,
|
||||
// 如果startup_file是一个.zip文件,则默认module_name是`pysmain`。
|
||||
void pys_set_bootstrap_module(PYS_HANDLE pysh, const char* module_name, const char* func_name);
|
||||
|
||||
// 初始化模块的函数原型
|
||||
// 初始化模块的函数原型
|
||||
typedef PyObject* (*pys_init_module_func)(void);
|
||||
|
||||
typedef struct PYS_BUILTIN_FUNC
|
||||
{
|
||||
const char* py_func_name; // Python中调用时使用的函数名
|
||||
PyCFunction c_func_addr; // 对应的C的函数
|
||||
PYS_BOOL have_args; // 此函数是否需要参数
|
||||
const char* py_func_desc; // 此函数的文档注释,可以为NULL。
|
||||
const char* py_func_name; // Python中调用时使用的函数名
|
||||
PyCFunction c_func_addr; // 对应的C的函数
|
||||
PYS_BOOL have_args; // 此函数是否需要参数
|
||||
const char* py_func_desc; // 此函数的文档注释,可以为NULL。
|
||||
}PYS_BUILTIN_FUNC;
|
||||
|
||||
typedef enum PYS_CONST_TYPE
|
||||
{
|
||||
PYS_CONST_BOOL, // Python中得到 True/False 的值
|
||||
PYS_CONST_LONG, // Python中得到一个整数
|
||||
PYS_CONST_STRING, // Python中得到一个字符串
|
||||
PYS_CONST_BYTES // Python中得到一个Bytes类型数据
|
||||
PYS_CONST_BOOL, // Python中得到 True/False 的值
|
||||
PYS_CONST_LONG, // Python中得到一个整数
|
||||
PYS_CONST_STRING, // Python中得到一个字符串
|
||||
PYS_CONST_BYTES // Python中得到一个Bytes类型数据
|
||||
}PYS_CONST_TYPE;
|
||||
|
||||
typedef struct PYS_BUILTIN_CONST
|
||||
{
|
||||
char* py_const_name; // Python中调用时使用的变量名
|
||||
PYS_CONST_TYPE type; // 常量类型
|
||||
size_t size; // 常量数据的长度
|
||||
void* buffer; // 常量数据的内容
|
||||
char* py_const_name; // Python中调用时使用的变量名
|
||||
PYS_CONST_TYPE type; // 常量类型
|
||||
size_t size; // 常量数据的长度
|
||||
void* buffer; // 常量数据的内容
|
||||
}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);
|
||||
|
||||
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_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_bin(PyObject* mod, const char* name, const ex_u8* val, size_t size);
|
||||
|
||||
// 运行python解释器
|
||||
// 运行python解释器
|
||||
int pys_run(PYS_HANDLE pysh);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -3,6 +3,9 @@
|
|||
#include "pys_util.h"
|
||||
|
||||
#ifdef PYS_USE_PYLIB_SHARED
|
||||
|
||||
#if defined(EX_OS_WIN32)
|
||||
|
||||
//========================================================
|
||||
// WIN32
|
||||
//========================================================
|
||||
|
@ -30,6 +33,39 @@ if(!pylib_ ## name) { \
|
|||
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 DYLIB_HANDLE _pys_dlopen(const wchar_t* dylib_path);
|
||||
|
@ -70,7 +106,7 @@ DYLIB_HANDLE _pys_dlopen(const wchar_t* dylib_path)
|
|||
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);
|
||||
|
||||
|
|
|
@ -18,10 +18,10 @@ namespace pys
|
|||
Core();
|
||||
~Core();
|
||||
|
||||
// 调用各个成员函数设置必要信息之后再运行
|
||||
int run(void);
|
||||
// 调用各个成员函数设置必要信息之后再运行
|
||||
int run();
|
||||
|
||||
// 初始化为默认设置
|
||||
// 初始化为默认设置
|
||||
bool init(const wchar_t* exec_file, const wchar_t* runtime_path);
|
||||
|
||||
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);
|
||||
|
||||
private:
|
||||
bool _load_dylib(void);
|
||||
bool _load_dylib();
|
||||
|
||||
bool _run_init_builtin_modules(void);
|
||||
bool _run_prepare(void);
|
||||
void _run_set_program(void);
|
||||
void _run_set_path(void);
|
||||
void _run_set_argv(void);
|
||||
bool _run_init_builtin_modules();
|
||||
bool _run_prepare();
|
||||
void _run_set_program();
|
||||
void _run_set_path();
|
||||
void _run_set_argv();
|
||||
|
||||
|
||||
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_func;
|
||||
pys_wstr_list m_py_args; // 传递给Python脚本的参数
|
||||
pys_wstr_list m_py_args; // 传递给Python脚本的参数
|
||||
|
||||
private:
|
||||
bool m_is_zipped_app;
|
||||
|
||||
ex_wstr m_exec_file; // 当前可执行程序的文件名(绝对路径)
|
||||
ex_wstr m_exec_path; // 当前可执行程序所在的路径(绝对路径)
|
||||
ex_wstr m_runtime_path; // python运行环境路径,默认为可执行程序所在路径下的 `pysrt` 目录。
|
||||
ex_wstr m_exec_file; // 当前可执行程序的文件名(绝对路径)
|
||||
ex_wstr m_exec_path; // 当前可执行程序所在的路径(绝对路径)
|
||||
ex_wstr m_runtime_path; // python运行环境路径,默认为可执行程序所在路径下的 `pysrt` 目录。
|
||||
ex_wstr m_start_file;
|
||||
ex_wstr m_search_path_tmp;
|
||||
|
||||
|
|
Binary file not shown.
|
@ -63,11 +63,10 @@ static bool _process_cmd_line(int argc, wchar_t** argv)
|
|||
}
|
||||
|
||||
g_run_type = RUN_UNKNOWN;
|
||||
bool is_py_arg = false;
|
||||
|
||||
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;
|
||||
}
|
||||
else if (0 == wcscmp(argv[1], L"-i"))
|
||||
|
|
|
@ -143,7 +143,7 @@ bool ts_http_get(const ex_astr& url, ex_astr& body)
|
|||
mg_mgr_init(&_mgr, 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);
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
bool esc_mode = false;
|
||||
int esc_arg = 0;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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);
|
||||
|
||||
|
@ -156,6 +156,8 @@ private:
|
|||
bool m_first_auth;
|
||||
// 远程主机认证是否通过
|
||||
bool m_auth_passed;
|
||||
// 如果认证过程中发生了错误,记录错误提示,后续建立通道后可以发送给客户端进行提示
|
||||
std::string m_auth_err_msg;
|
||||
// 发生了不可逆的错误,需要关闭整个会话(包括所有的通道)
|
||||
bool m_fault;
|
||||
|
||||
|
|
|
@ -55,8 +55,8 @@ static ex_rv tpp_cmd_set_runtime_config(const char* param) {
|
|||
return TPE_PARAM;
|
||||
|
||||
ex_u32 noop_timeout = jp["noop_timeout"].asUInt();
|
||||
if (noop_timeout == 0)
|
||||
return TPE_PARAM;
|
||||
// if (noop_timeout == 0)
|
||||
// return TPE_PARAM;
|
||||
|
||||
g_ssh_proxy.set_cfg(noop_timeout * 60);
|
||||
|
||||
|
|
|
@ -49,8 +49,8 @@ static ex_rv tpp_cmd_set_runtime_config(const char* param) {
|
|||
return TPE_PARAM;
|
||||
|
||||
ex_u32 noop_timeout = jp["noop_timeout"].asUInt();
|
||||
if (noop_timeout == 0)
|
||||
return TPE_PARAM;
|
||||
// if (noop_timeout == 0)
|
||||
// return TPE_PARAM;
|
||||
|
||||
g_telnet_proxy.set_cfg(noop_timeout * 60);
|
||||
|
||||
|
|
|
@ -19,11 +19,23 @@ include_directories(
|
|||
../../../common/pyshell/include
|
||||
)
|
||||
|
||||
include_directories(
|
||||
${TP_EXTERNAL_RELEASE_DIR}/include
|
||||
${TP_EXTERNAL_RELEASE_DIR}/include/python3.7m
|
||||
)
|
||||
link_directories(${TP_EXTERNAL_RELEASE_DIR}/lib)
|
||||
if (OS_LINUX)
|
||||
include_directories(
|
||||
${TP_EXTERNAL_RELEASE_DIR}/include
|
||||
${TP_EXTERNAL_RELEASE_DIR}/include/python3.7m
|
||||
)
|
||||
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)
|
||||
|
|
|
@ -4,28 +4,28 @@
|
|||
#include <ex.h>
|
||||
#include <pys.h>
|
||||
|
||||
// 命令行参数说明(不带参数运行则以服务方式启动)
|
||||
// 命令行参数说明(不带参数运行则以服务方式启动)
|
||||
// tp_web [-i|-u|--version] [ [-d] start] [...]
|
||||
// -d 启动程序并输出调试信息(不会运行为守护进程/服务模式)
|
||||
// -i 安装服务然后退出(仅限Win平台)
|
||||
// -u 卸载服务然后退出(仅限Win平台)
|
||||
// --version 打印版本号然后退出
|
||||
// start 以服务方式运行
|
||||
// ... 剩余的所有参数均传递给python脚本
|
||||
// -d 启动程序并输出调试信息(不会运行为守护进程/服务模式)
|
||||
// -i 安装服务然后退出(仅限Win平台)
|
||||
// -u 卸载服务然后退出(仅限Win平台)
|
||||
// --version 打印版本号然后退出
|
||||
// start 以服务方式运行
|
||||
// ... 剩余的所有参数均传递给python脚本
|
||||
//
|
||||
//
|
||||
// 执行指定的Python脚本:
|
||||
// 执行指定的Python脚本:
|
||||
// tp_web --py [-f FuncName] script_file.py ...
|
||||
// --py 必须为第一个参数,表示本次执行为执行指定脚本
|
||||
// -f FuncName 指定入口函数,默认为main。
|
||||
// script-file.py 被执行的脚本文件
|
||||
// ... 剩余的所有参数均传递给Python脚本
|
||||
// --py 必须为第一个参数,表示本次执行为执行指定脚本
|
||||
// -f FuncName 指定入口函数,默认为main。
|
||||
// script-file.py 被执行的脚本文件
|
||||
// ... 剩余的所有参数均传递给Python脚本
|
||||
|
||||
ExLogger g_ex_logger;
|
||||
bool g_is_debug = false;
|
||||
static ex_wstrs g_py_args;
|
||||
|
||||
// 如果是执行指定脚本
|
||||
// 如果是执行指定脚本
|
||||
static ex_wstr g_py_script_file;
|
||||
static ex_wstr g_py_main_func;
|
||||
|
||||
|
@ -40,8 +40,8 @@ static ex_u8 g_run_type = RUN_UNKNOWN;
|
|||
|
||||
static bool _run_daemon(void);
|
||||
|
||||
// 导出函数给Python脚本使用(主要是为了记录日志)
|
||||
// Windows平台上,tp_web程序打开日志文件写之后,Python脚本尝试写入方式打开此日志文件时会失败。
|
||||
// 导出函数给Python脚本使用(主要是为了记录日志)
|
||||
// Windows平台上,tp_web程序打开日志文件写之后,Python脚本尝试写入方式打开此日志文件时会失败。
|
||||
PyObject* init_web_builtin_module(void);
|
||||
|
||||
#ifdef EX_OS_WIN32
|
||||
|
@ -186,7 +186,7 @@ static int _main_loop(void)
|
|||
return 1;
|
||||
}
|
||||
|
||||
// 设置web的路径
|
||||
// 设置web的路径
|
||||
ex_wstr sf_path;
|
||||
if (g_run_type == RUN_WEB)
|
||||
{
|
||||
|
@ -344,10 +344,10 @@ static DWORD WINAPI service_thread_func(LPVOID lpParam);
|
|||
int main()
|
||||
{
|
||||
int ret = 0;
|
||||
LPWSTR szCmdLine = (LPWSTR)::GetCommandLineW(); //获取命令行参数;
|
||||
LPWSTR szCmdLine = (LPWSTR)::GetCommandLineW(); //获取命令行参数;
|
||||
|
||||
int _argc = 0;
|
||||
wchar_t** _argv = ::CommandLineToArgvW(szCmdLine, &_argc); //拆分命令行参数字符串;
|
||||
wchar_t** _argv = ::CommandLineToArgvW(szCmdLine, &_argc); //拆分命令行参数字符串;
|
||||
|
||||
ret = _app_main(_argc, _argv);
|
||||
|
||||
|
@ -379,7 +379,7 @@ static DWORD WINAPI service_thread_func(LPVOID lpParam)
|
|||
{
|
||||
int ret = _main_loop();
|
||||
|
||||
// 更新服务状态(如果服务还在运行,将其设置为停止状态)
|
||||
// 更新服务状态(如果服务还在运行,将其设置为停止状态)
|
||||
g_ServiceStatus.dwWin32ExitCode = 0;
|
||||
g_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
|
||||
g_ServiceStatus.dwCheckPoint = 0;
|
||||
|
@ -552,7 +552,7 @@ static bool _run_daemon(void)
|
|||
|
||||
|
||||
//===============================================================
|
||||
// 加入内建模块供脚本调用
|
||||
// 加入内建模块供脚本调用
|
||||
//===============================================================
|
||||
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[] = {
|
||||
{
|
||||
"log_output", // 脚本函数名,在脚本中使用
|
||||
_py_log_output, // 对应的C代码函数名
|
||||
PYS_TRUE, // 函数的基本信息(是否需要参数,等等)
|
||||
"write log." // 函数的说明文档,可选(可以是空字符串)
|
||||
"log_output", // 脚本函数名,在脚本中使用
|
||||
_py_log_output, // 对应的C代码函数名
|
||||
PYS_TRUE, // 函数的基本信息(是否需要参数,等等)
|
||||
"write log." // 函数的说明文档,可选(可以是空字符串)
|
||||
},
|
||||
|
||||
{
|
||||
|
@ -649,7 +649,7 @@ PYS_BUILTIN_FUNC _demo_funcs[] = {
|
|||
"set log to console or not."
|
||||
},
|
||||
|
||||
// 最后一组,第一个成员为空指针,表示结束
|
||||
// 最后一组,第一个成员为空指针,表示结束
|
||||
{ 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_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_utf8(mod, "DEMO_CONST_4", "this is string.");
|
||||
//
|
||||
|
|
|
@ -132,9 +132,9 @@ class WebApp:
|
|||
if not tp_stats().init():
|
||||
log.e('can not initialize system status collector.\n')
|
||||
return 0
|
||||
if not tp_host_alive().init():
|
||||
log.e('can not initialize host state inspector.\n')
|
||||
return 0
|
||||
# if not tp_host_alive().init():
|
||||
# log.e('can not initialize host state inspector.\n')
|
||||
# return 0
|
||||
|
||||
settings = {
|
||||
#
|
||||
|
@ -189,7 +189,7 @@ class WebApp:
|
|||
except:
|
||||
log.e('\n')
|
||||
|
||||
tp_host_alive().stop()
|
||||
# tp_host_alive().stop()
|
||||
tp_cron().stop()
|
||||
return 0
|
||||
|
||||
|
|
Loading…
Reference in New Issue