* Copyright 2019 Huawei Technologies Co.,Ltd.
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use
* this file except in compliance with the License. You may obtain a copy of the
* License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
**********************************************************************************
*/
#ifdef WIN32
#include <windows.h>
#include <Wincrypt.h>
#include <Shlwapi.h>
#pragma comment(lib, "shlwapi.lib")
#endif
#include "eSDKTool.h"
#include "eSDKLogDataType.h"
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include "securec.h"
#include <sstream>
eSDKTool::eSDKTool(void)
{
}
eSDKTool::~eSDKTool(void)
{
}
std::string eSDKTool::GetDllPath()
{
#ifdef WIN32
HMODULE hModule = GetModuleHandle("eSDKLogAPI.dll");
char path[MAX_PATH] = {0};
GetModuleFileName(hModule, path, MAX_PATH);
std::string strPath(path);
strPath = strPath.substr(0, strPath.rfind("\\")+1);
return strPath;
#elif defined(TARGET_OS_IPHONE)||defined(TARGET_OS_MAC)
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
return [documentsDirectory UTF8String];
#else
const char separator = '/';
char buf[1024] = {0};
int nRet = -1;
nRet = GetModuleFilePath("libeSDKLogAPI.so", buf, sizeof(buf));
if(0 != nRet)
{
return "";
}
strcat_s(buf, 1024, "/");
char* pch = strrchr(buf, separator);
if(NULL == pch)
{
return "";
}
if(pch == buf)
{
return "";
}
std::string strPath(buf);
if ('/' != strPath[strPath.size()-1])
{
strPath += "/";
}
return strPath;
;
#endif
}
std::string eSDKTool::GetAppPath()
{
#ifdef WIN32
char path[MAX_PATH] = {0};
GetModuleFileName(NULL, path, MAX_PATH);
std::string strPath(path);
strPath = strPath.substr(0, strPath.rfind("\\")+1);
return strPath;
#elif defined(TARGET_OS_IPHONE)||defined(TARGET_OS_MAC)
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
return [documentsDirectory UTF8String];
#else
return "";
#endif
}
bool eSDKTool::IsPathFileExist(const std::string& path)
{
#ifdef WIN32
if (PathFileExists(path.c_str()))
{
return true;
}
#elif defined(TARGET_OS_IPHONE)||defined(TARGET_OS_MAC)
NSFileManager *manager = [NSFileManager defaultManager];
BOOL isDir;
if ([manager fileExistsAtPath:[NSString stringWithUTF8String:path.c_str()] isDirectory:&isDir])
{
return true;
}
#else
if (0 == access(path.c_str(), 0))
{
return true;
}
#endif
return false;
}
bool eSDKTool::IsRelativePath(const std::string& path)
{
#ifdef WIN32
return (PathIsRelative(path.c_str()) ? true : false);
#elif defined(TARGET_OS_IPHONE)||defined(TARGET_OS_MAC)
NSString* strPath = [[NSString alloc] initWithUTF8String:path.c_str()];
BOOL bAbsPath = [strPath isAbsolutePath];
return !bAbsPath;
#else
char temp = path.at(0);
if ('/' == temp ) {
return false;
}
return true;
#endif
}
bool eSDKTool::CreateMultipleDirectory(const std::string& path)
{
#ifdef WIN32
std::string strPath(path);
if (strPath.empty())
{
return false;
}
if (IsPathFileExist(strPath.c_str()))
{
if (!IsDir(path))
{
return false;
}
return true;
}
else
{
while ('\\' == strPath.back())
{
strPath = strPath.substr(0, strPath.rfind("\\"));
}
std::string prePath = strPath.substr(0, strPath.rfind("\\"));
if (prePath == strPath)
{
return false;
}
if (IsPathFileExist(prePath.c_str()))
{
BOOL bRet = CreateDirectoryA(strPath.c_str(), NULL);
if (bRet == TRUE)
{
return true;
}
else
{
return false;
}
}
else
{
if (CreateMultipleDirectory(prePath))
{
return CreateMultipleDirectory(strPath);
}
return false;
}
}
#elif defined(TARGET_MAC_OS)||defined(TARGET_OS_IPHONE)
std::string strPath(path);
if (strPath.empty())
{
return false;
}
NSError *error;
NSFileManager *manager = [NSFileManager defaultManager];
if (IsPathFileExist(strPath.c_str()))
{
return true;
}
return [manager createDirectoryAtPath:[NSString stringWithUTF8String:strPath.c_str()] withIntermediateDirectories:YES attributes:nil error:&error];
#else
std::string strPath(path);
if (strPath.empty())
{
return false;
}
if (IsPathFileExist(strPath.c_str()))
{
return true;
}
else
{
while ('/' == strPath[strPath.length()-1])
{
strPath = strPath.substr(0, strPath.rfind("/"));
}
std::string prePath = strPath.substr(0, strPath.rfind("/"));
if (prePath == strPath)
{
return false;
}
if (IsPathFileExist(prePath.c_str()))
{
int makeID = mkdir(strPath.c_str(), S_IRWXU | S_IRGRP | S_IXGRP);
if (0 == makeID)
{
return true;
}
else
{
return false;
}
}
else
{
if (CreateMultipleDirectory(prePath))
{
return CreateMultipleDirectory(strPath);
}
return false;
}
}
#endif
}
void eSDKTool::getCurrentPath(std::string& strPath)
{
#ifdef WIN32
HMODULE hModule = GetModuleHandle("eSDKLogAPI.dll");
char path[MAX_PATH+1] = {0};
::GetModuleFileNameA(hModule, path, MAX_PATH);
std::string strModulePath = path;
unsigned int loc = strModulePath.find_last_of("\\");
if( loc != string::npos )
{
strPath = strModulePath.substr(0,loc);
}
#else
const char separator = '/';
char buf[1024] = {0};
int nRet = RET_INVALID_PARA;
nRet = GetModuleFilePath("libeSDKLogAPI.so", buf, sizeof(buf));
if(RET_SUCCESS != nRet)
{
return ;
}
strcat_s(buf, 1024, "/");
char* pch = strrchr(buf, separator);
if(NULL == pch)
{
return ;
}
if(pch == buf)
{
return ;
}
*pch = '\0';
strPath = buf;
return ;
#endif
}
void eSDKTool::GetIPPort(const std::string& server,std::string& ip,unsigned short& port)
{
ip.clear();
std::string instr = server;
string::size_type pos = instr.find(':');
if( pos != string::npos )
{
ip = instr.substr(0,pos);
std::string outPort = instr.substr(pos+1);
port = (unsigned short)atoi(outPort.c_str());
}
else
{
ip = "";
port = 0;
}
return;
}
bool eSDKTool::CheckIP4Valid(const std::string &ip)
{
if (ip.empty())
{
return false;
}
const unsigned int DOT_NUM = 3;
const unsigned int MAX_IP = 255;
unsigned int auIpTemp[4] = {0};
unsigned int iNum = 0;
int iValue = 0;
bool bFlag = false;
unsigned int iIndex = 0;
for (;;)
{
iValue = ip[iIndex];
iIndex++;
if ((iValue >= '0') && (iValue <= '9'))
{
bFlag = true;
auIpTemp[iNum] = auIpTemp[iNum] * 10 + (unsigned int)iValue - '0';
if (auIpTemp[iNum] > MAX_IP)
{
return false;
}
}
else if ('.' == iValue)
{
if (!bFlag)
{
return false;
}
if (DOT_NUM == iNum)
{
return false;
}
iNum++;
bFlag = false;
}
else if (('\0' == iValue) && (DOT_NUM == iNum) && bFlag)
{
break;
}
else
{
return false;
}
}
return true;
}
void eSDKTool::GetFileNameByPath(const std::string& strPath,std::string& strFileName)
{
strFileName.clear();
std::string instr = strPath;
#ifdef WIN32
string::size_type pos = instr.rfind('\\');
#else
string::size_type pos = instr.rfind('/');
#endif
if( pos != string::npos )
{
strFileName = instr.substr(pos+1);
}
else
{
strFileName = strPath;
}
}
#if defined ANDROID
void eSDKTool::GetIniSectionItem(const char* Section, const char* Item, const char* FileInfo, std::string& iniValue)
{
const int LENGTH = 1024;
char* tchValue = new char[LENGTH];
memset_s(tchValue, LENGTH, 0, LENGTH*sizeof(char));
char* iniItem = NULL;
char Sect[30] = {0};
char posChar = ' ';
char linebuf[LENGTH] = {0};
char oldline[LENGTH] = {0};
if (NULL == FileInfo)
{
delete[] tchValue;
tchValue = NULL;
return;
}
std::stringstream fileStream(FileInfo);
memcpy_s(Sect, 30, "[", sizeof("["));
strcat_s(Sect, 30, Section);
strcat_s(Sect, 30, "]");
while(fileStream.get(posChar))
{
if('[' == posChar)
{
fileStream.unget();
fileStream.getline(linebuf, LENGTH);
if(strstr(linebuf, Sect))
{
while(fileStream.get(posChar))
{
if ('[' == posChar)
{
break;
}
if (';' == posChar)
{
fileStream.unget();
fileStream.getline(linebuf, LENGTH);
continue;
}
fileStream.unget();
fileStream.getline(linebuf, LENGTH);
if(strstr(linebuf, Item))
{
std::string strTmp(Item);
if(iniItem = strchr(linebuf, '='))
{
iniItem++;
if((*iniItem) == '\n')
{
delete[] tchValue;
tchValue = NULL;
return ;
}
iniItem[strlen(iniItem)] = 0;
memcpy_s(tchValue, LENGTH, iniItem, strlen(iniItem));
iniValue = std::string(tchValue);
delete[] tchValue;
tchValue = NULL;
return ;
}
}
}
}
}
else
{
fileStream.unget();
fileStream.getline(linebuf, LENGTH);
}
}
delete[] tchValue;
tchValue = NULL;
return ;
}
#else
void eSDKTool::GetIniSectionItem(const char* Section, const char* Item, const char* FileName, std::string& iniValue)
{
const int LENGTH = 1024;
char* tchValue = new char[LENGTH];
memset_s(tchValue, LENGTH, 0, LENGTH*sizeof(char));
#ifdef WIN32
(void)::GetPrivateProfileString(Section, Item, "", tchValue, LENGTH-1, FileName);
iniValue = tchValue;
#elif defined(TARGET_MAC_OS)||defined(TARGET_OS_IPHONE)
NSMutableDictionary* dict = [ [ NSMutableDictionary alloc ] initWithContentsOfFile:[NSString stringWithUTF8String:FileName]];
NSString* value = [ dict objectForKey:[NSString stringWithUTF8String:Item]];
iniValue = [value UTF8String];
#else
char* iniItem = NULL;
char Sect[30] = {0};
char posChar = ' ';
char linebuf[LENGTH] = {0};
char oldline[LENGTH] = {0};
FILE* inifp;
memcpy_s(Sect, 30, "[", sizeof("["));
strcat_s(Sect, 30, Section);
strcat_s(Sect, 30, "]");
inifp = fopen(FileName, "rb");
if(NULL == inifp)
{
delete[] tchValue;
tchValue = NULL;
return ;
}
while((posChar = fgetc(inifp))!=EOF)
{
if('[' == posChar)
{
ungetc(posChar, inifp);
fgets(linebuf,LENGTH, inifp);
if(strstr(linebuf, Sect))
{
while((posChar = fgetc(inifp))!='[' && posChar != EOF)
{
if (';' == posChar)
{
ungetc(posChar, inifp);
fgets(linebuf, LENGTH, inifp);
continue;
}
ungetc(posChar, inifp);
fgets(linebuf, LENGTH, inifp);
if(strstr(linebuf, Item))
{
if(iniItem= strchr(linebuf, '='))
{
iniItem++;
fclose(inifp);
if((*iniItem) == '\n')
{
delete[] tchValue;
tchValue = NULL;
return ;
}
iniItem[strlen(iniItem)-1] = 0;
memcpy_s(tchValue, LENGTH, iniItem, strlen(iniItem));
iniValue = std::string(tchValue);
delete[] tchValue;
tchValue = NULL;
return ;
}
}
}
if(EOF == posChar)
{
break;
}
ungetc(posChar, inifp);
}
}
else
{
ungetc(posChar, inifp);
fgets(linebuf, LENGTH, inifp);
}
}
fclose(inifp);
#endif
delete[] tchValue;
tchValue = NULL;
return ;
}
#endif
#ifndef WIN32
int eSDKTool::GetModuleFilePath(const char* sModuleName, char* sPath, unsigned int unSize)
{
int iRet = RET_INVALID_PARA;
char sLine[1024] = {0};
FILE *fp = NULL;
char *pTmpFullDir = NULL;
char *pTmpModuleDir = NULL;
fp = fopen ("/proc/self/maps", "r");
if (NULL == fp)
{
return iRet;
}
while (0 == feof(fp))
{
if (NULL == fgets(sLine, sizeof(sLine), fp))
{
continue;
}
pTmpFullDir = strchr(sLine, '/');
if (NULL == strstr(sLine, "r-xp") || NULL == pTmpFullDir || NULL == strstr(sLine, sModuleName))
{
continue;
}
pTmpModuleDir = strrchr(pTmpFullDir, '/');
if (pTmpModuleDir == pTmpFullDir)
{
break;
}
*pTmpModuleDir = '\0';
if (strlen(pTmpFullDir) >= unSize)
{
break;
}
iRet = RET_SUCCESS;
strncpy_s(sPath, unSize, pTmpFullDir, strlen(pTmpFullDir) + 1);
break;
}
fclose(fp);
return iRet;
}
#endif
void eSDKTool::GetSrandNum(std::string& sRandNum)
{
#ifdef WIN32
DWORD dSrandNum = 0;
void *lpGoop =&dSrandNum;
DWORD cbGoop = sizeof(dSrandNum);
HCRYPTPROV hCryptProv = NULL ;
CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
if (!CryptGenRandom(hCryptProv, cbGoop, reinterpret_cast <LPBYTE>(lpGoop)) )
{
CryptReleaseContext(hCryptProv,0);
return ;
}
else
{
char* tempStr = new char[256];
memset_s(tempStr, 256, 0, 256*sizeof(char));
_ultoa_s(dSrandNum, tempStr, 255, 10);
sRandNum = std::string(tempStr);
delete[] tempStr;
tempStr = NULL;
CryptReleaseContext(hCryptProv, 0);
return ;
}
#else
unsigned long dSrandNum = 0;
int fd = 0;
fd = open("/dev/random", O_RDONLY);
if(fd > 0)
{
read(fd, &dSrandNum, sizeof(unsigned long));
close(fd);
char* tempStr = new char[256];
memset_s(tempStr, 256, 0, 256*sizeof(char));
sprintf_s(tempStr, 256, "%ld", dSrandNum);
sRandNum = std::string(tempStr);
delete[] tempStr;
tempStr = NULL;
return ;
}
else
{
close(fd);
return ;
}
#endif
}
#if defined(ANDROID) || defined(TARGET_MAC_OS) || defined(TARGET_OS_IPHONE)
int eSDKTool::gzcompress(Bytef *data, uLong ndata, Bytef *zdata, uLong *nzdata)
{
z_stream c_stream;
int err = 0;
if(data && ndata > 0)
{
c_stream.zalloc = NULL;
c_stream.zfree = NULL;
c_stream.opaque = NULL;
if(deflateInit2(&c_stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED,
MAX_WBITS + 16, 8, Z_DEFAULT_STRATEGY) != Z_OK)
{
return -1;
}
c_stream.next_in = data;
c_stream.avail_in = ndata;
c_stream.next_out = zdata;
c_stream.avail_out = *nzdata;
while(c_stream.avail_in != 0 && c_stream.total_out < *nzdata)
{
if(deflate(&c_stream, Z_NO_FLUSH) != Z_OK)
{
return -1;
}
}
if(c_stream.avail_in != 0) return c_stream.avail_in;
for(;;)
{
if((err = deflate(&c_stream, Z_FINISH)) == Z_STREAM_END)
{
break;
}
if(err != Z_OK)
{
return -1;
}
}
if(deflateEnd(&c_stream) != Z_OK)
{
return -1;
}
*nzdata = c_stream.total_out;
return 0;
}
return -1;
}
#endif
bool eSDKTool::IsDir(const std::string& path)
{
bool bRet = false;
#ifdef WIN32
if (FILE_ATTRIBUTE_DIRECTORY == PathIsDirectory(path.c_str()))
{
bRet = true;
}
#else
struct stat sb;
if (stat(path.c_str(), &sb) == -1)
{
return bRet;
}
if (S_IFDIR == (sb.st_mode & S_IFMT))
{
bRet = true;
}
#endif
return bRet;
}
unsigned int eSDKTool::StringToOCT(const std::string& strNumber)
{
unsigned int nRet = 0;
for (unsigned int i=0; i<strNumber.length(); ++i)
{
if (strNumber[i] < '0' || strNumber[i] > '9')
{
return 0;
}
nRet = 8 * nRet + (strNumber[i] - '0');
}
return nRet;
}