common_api.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531
  1. // common_api.cpp
  2. #include <time.h>
  3. #include <sys/time.h>
  4. #include <pthread.h>
  5. #include <dlfcn.h>
  6. #include <unistd.h>
  7. #include <limits.h>
  8. #include "common_api.h"
  9. #include <iostream>
  10. // 全局互斥锁初始化
  11. common_api::common_api(void) {
  12. pthread_mutex_init(&m_NotifyMutex, NULL);
  13. }
  14. common_api::~common_api(void) {
  15. pthread_mutex_destroy(&m_NotifyMutex);
  16. }
  17. common_api g_common1_for_init;
  18. //=== 时间相关函数 ===//
  19. __time64_t GetCurrentRealTimeOfStk() {
  20. return time(NULL);
  21. }
  22. UINT64 GetDay(UINT64 TheTime) {
  23. struct tm tCur;
  24. gmtime_r((time_t*)&TheTime, &tCur);
  25. tCur.tm_sec = 0;
  26. tCur.tm_min = 0;
  27. tCur.tm_hour = 0;
  28. return mktime(&tCur);
  29. }
  30. int CompareTimeByDay(UINT64 Prev, UINT64 Cur) {
  31. return (Cur / (24 * 3600)) - (Prev / (24 * 3600));
  32. }
  33. //=== GUID转换 ===//
  34. bool string_2_guid(const char* pstr, GUID& stGuid) {
  35. return sscanf(pstr, "{%8lx-%4hx-%4hx-%2hhx%2hhx-%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx}",
  36. &stGuid.Data1, &stGuid.Data2, &stGuid.Data3,
  37. &stGuid.Data4[0], &stGuid.Data4[1], &stGuid.Data4[2], &stGuid.Data4[3],
  38. &stGuid.Data4[4], &stGuid.Data4[5], &stGuid.Data4[6], &stGuid.Data4[7]) == 11;
  39. }
  40. bool guid_2_string(GUID& stGuid, string& str) {
  41. char szBuff[128];
  42. snprintf(szBuff, sizeof(szBuff), "{%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
  43. stGuid.Data1, stGuid.Data2, stGuid.Data3,
  44. stGuid.Data4[0], stGuid.Data4[1], stGuid.Data4[2], stGuid.Data4[3],
  45. stGuid.Data4[4], stGuid.Data4[5], stGuid.Data4[6], stGuid.Data4[7]);
  46. str = szBuff;
  47. return true;
  48. }
  49. const char* secure_getenv_n(const char* name)
  50. {
  51. static char buffer[4096];
  52. if (name == nullptr) return nullptr;
  53. // 使用文件流读取/proc/self/environ
  54. FILE* f = fopen("/proc/self/environ", "r");
  55. if (!f) return nullptr;
  56. size_t name_len = strlen(name);
  57. while (fgets(buffer, sizeof(buffer), f)) {
  58. if (strncmp(buffer, name, name_len) == 0 && buffer[name_len] == '=') {
  59. fclose(f);
  60. return buffer + name_len + 1;
  61. }
  62. }
  63. fclose(f);
  64. return nullptr;
  65. }
  66. //=== 环境变量操作 ===//
  67. bool AddEnvPath(const char* pPath) {
  68. UNUSED(pPath);
  69. //// 1. 输入验证
  70. //if (!pPath || *pPath == '\0') {
  71. // std::cerr << "AddEnvPath: Invalid path" << std::endl;
  72. // return false;
  73. //}
  74. //// 2. 获取绝对路径
  75. //char absPath[PATH_MAX];
  76. //if (realpath(pPath, absPath) == nullptr) {
  77. // // 如果路径不存在,仍然使用原始路径(但警告)
  78. // std::cerr << "AddEnvPath: Warning - Path may not exist: " << pPath
  79. // << " (" << strerror(errno) << ")" << std::endl;
  80. // strncpy(absPath, pPath, PATH_MAX - 1);
  81. // absPath[PATH_MAX - 1] = '\0';
  82. //}
  83. //// 3. 获取当前环境变量值
  84. //const char* currentEnv = getenv("LD_LIBRARY_PATH");
  85. //std::vector<std::string> pathList;
  86. //// 4. 解析现有路径并去重
  87. //if (currentEnv && *currentEnv != '\0') {
  88. // std::istringstream iss(currentEnv);
  89. // std::string item;
  90. // while (std::getline(iss, item, ':')) {
  91. // if (!item.empty()) {
  92. // // 标准化现有路径
  93. // char resolved[PATH_MAX];
  94. // if (realpath(item.c_str(), resolved)) {
  95. // // 去重检查
  96. // if (strcmp(resolved, absPath) != 0) {
  97. // pathList.push_back(resolved);
  98. // }
  99. // }
  100. // else {
  101. // // 无法解析的路径保留原样
  102. // pathList.push_back(item);
  103. // }
  104. // }
  105. // }
  106. //}
  107. //// 5. 添加新路径到最前面(优先搜索)
  108. //pathList.insert(pathList.begin(), absPath);
  109. //// 6. 构建新环境变量字符串
  110. //std::ostringstream newEnvStream;
  111. //for (size_t i = 0; i < pathList.size(); ++i) {
  112. // if (i > 0) newEnvStream << ':';
  113. // newEnvStream << pathList[i];
  114. //}
  115. //std::string newEnv = newEnvStream.str();
  116. //// 7. 更新环境变量
  117. //if (setenv("LD_LIBRARY_PATH", newEnv.c_str(), 1) != 0) {
  118. // std::cerr << "AddEnvPath: Failed to set LD_LIBRARY_PATH ("
  119. // << strerror(errno) << ")" << std::endl;
  120. // return false;
  121. //}
  122. //// 8. 验证设置
  123. //const char* verify = getenv("LD_LIBRARY_PATH");
  124. //if (verify && std::string(verify).find(absPath) != std::string::npos) {
  125. // std::cout << "AddEnvPath: Successfully updated LD_LIBRARY_PATH to: "
  126. // << newEnv << std::endl;
  127. // return true;
  128. //}
  129. //else {
  130. // std::cerr << "AddEnvPath: Verification failed - path not found in LD_LIBRARY_PATH"
  131. // << std::endl;
  132. // return false;
  133. //}
  134. return true;
  135. }
  136. bool DelEnvPath(const char* pPath) {
  137. UNUSED(pPath);
  138. return false;
  139. }
  140. static bool SplitStringSub(string& Path, char key, vector<string>& nodes) {
  141. string node;
  142. string::size_type firstHit = Path.find_first_of(key);
  143. if (firstHit == string::npos) {
  144. if (Path.size() > 0) {
  145. nodes.push_back(Path);
  146. }
  147. return true;
  148. }
  149. if (firstHit > 0) {
  150. node = Path.substr(0, firstHit);
  151. if (node.size() > 0) {
  152. nodes.push_back(node);
  153. }
  154. }
  155. while (firstHit < Path.size()) {
  156. firstHit += 1;
  157. if (firstHit >= Path.size()) break;
  158. string::size_type SecondHit = Path.find_first_of(key, firstHit);
  159. if (SecondHit == string::npos) {
  160. node = Path.substr(firstHit, Path.size() - firstHit);
  161. if (node.size() > 0) {
  162. nodes.push_back(node);
  163. }
  164. break;
  165. }
  166. node = Path.substr(firstHit, SecondHit - firstHit);
  167. if (node.size() > 0) {
  168. nodes.push_back(node);
  169. }
  170. firstHit = SecondHit;
  171. }
  172. return (nodes.size() > 0);
  173. }
  174. //=== 字符串处理 ===//
  175. bool SplitString(const char* pString, string args, vector<string>& nodes) {
  176. vector<string> req;
  177. vector<string> res;
  178. req.push_back(string(pString));
  179. for (size_t i = 0; i < args.size(); i++)
  180. {
  181. //cut all req by key
  182. for (size_t j = 0; j < req.size(); j++)
  183. {
  184. SplitStringSub(req[j], args[i], res);
  185. }
  186. //clear and reset
  187. req.clear();
  188. req = res;
  189. res.clear();
  190. }
  191. nodes = req;
  192. return true;
  193. }
  194. bool SplitTo84422222222String(const char* pString, vector<string>& nodes) {
  195. string total;
  196. vector<string> thelist;
  197. SplitString(pString, string("{}-"), thelist);
  198. for (size_t i = 0; i < thelist.size(); i++)
  199. {
  200. total += thelist[i];
  201. }
  202. if (total.size() != 32)
  203. {
  204. return false;
  205. }
  206. string temp;
  207. temp = total.substr(0, 8);//8
  208. nodes.push_back(temp);
  209. temp = total.substr(8, 4);//4
  210. nodes.push_back(temp);
  211. temp = total.substr(12, 4);//4
  212. nodes.push_back(temp);
  213. temp = total.substr(16, 2);//2
  214. nodes.push_back(temp);
  215. temp = total.substr(18, 2);//2
  216. nodes.push_back(temp);
  217. temp = total.substr(20, 2);//2
  218. nodes.push_back(temp);
  219. temp = total.substr(22, 2);//2
  220. nodes.push_back(temp);
  221. temp = total.substr(24, 2);//2
  222. nodes.push_back(temp);
  223. temp = total.substr(26, 2);//2
  224. nodes.push_back(temp);
  225. temp = total.substr(28, 2);//2
  226. nodes.push_back(temp);
  227. temp = total.substr(30, 2);//2
  228. nodes.push_back(temp);
  229. return true;
  230. }
  231. string FormatstdString(const char* fmt, ...) {
  232. va_list args;
  233. va_start(args, fmt);
  234. char buffer[1024];
  235. vsnprintf(buffer, sizeof(buffer), fmt, args);
  236. va_end(args);
  237. return string(buffer);
  238. }
  239. bool getBusIdFromFilePath(const char* pFilePath, string& BusId)
  240. {
  241. string Path = pFilePath;
  242. size_t firstHit = Path.find_first_of('/');
  243. if (firstHit == string::npos || firstHit != 0)
  244. {
  245. return false;
  246. }
  247. size_t SecondHit = Path.find_first_of('/', 1);
  248. if (SecondHit == string::npos)
  249. {
  250. BusId = Path.substr(1, Path.size() - 1);
  251. }
  252. else
  253. {
  254. BusId = Path.substr(1, SecondHit - 1);
  255. }
  256. if (BusId.size() == 0)
  257. {
  258. return false;
  259. }
  260. return true;
  261. }
  262. bool SplitDevicePath(const char* pDevicePath, vector<string>& nodes)
  263. {
  264. string node;
  265. string Path = pDevicePath;
  266. nodes.clear();
  267. string::size_type firstHit = Path.find_first_of('/');
  268. if (firstHit == string::npos || firstHit != 0)
  269. {
  270. return false;
  271. }
  272. while (firstHit < Path.size())
  273. {
  274. firstHit += 1;
  275. string::size_type SecondHit = Path.find_first_of('/', firstHit);
  276. if (SecondHit == string::npos)
  277. {
  278. node = Path.substr(firstHit, Path.size() - firstHit);
  279. if (node.size() > 0)
  280. {
  281. nodes.push_back(node);
  282. }
  283. return true;
  284. }
  285. node = Path.substr(firstHit, SecondHit - (firstHit));
  286. if (node.size() > 0)
  287. {
  288. nodes.push_back(node);
  289. }
  290. firstHit = SecondHit;
  291. }
  292. return (nodes.size() > 0);
  293. }
  294. void SplitDeviceList(const char* deviceList, std::vector<std::string>& result)
  295. {
  296. result.clear();
  297. // 处理空输入情况
  298. if (deviceList == nullptr || *deviceList == '\0') return;
  299. // 创建可修改副本(strtok会破坏原字符串)
  300. char* buffer = new char[strlen(deviceList) + 1];
  301. strcpy(buffer, deviceList);
  302. // 使用strtok分割字符串
  303. const char* delimiter = ";";
  304. char* token = strtok(buffer, delimiter);
  305. while (token != nullptr) {
  306. // 过滤空字符串(避免连续分号产生空项)
  307. if (strlen(token) > 0) {
  308. result.push_back(token);
  309. }
  310. token = strtok(nullptr, delimiter);
  311. }
  312. delete[] buffer; // 释放临时内存
  313. }
  314. //=== 文件路径操作 ===//
  315. std::string GetProcessDirectory() {
  316. char path[PATH_MAX];
  317. ssize_t len = readlink("/proc/self/exe", path, sizeof(path) - 1);
  318. if (len == -1) {
  319. std::cerr << "[ERROR] GetProcessDirectory failed to read /proc/self/exe" << std::endl;
  320. return "";
  321. }
  322. // 确保字符串正确终止
  323. path[len] = '\0';
  324. // 现在可以安全地打印
  325. std::cout << "[DEBUG] GetProcessDirectory() len: " << len << " path: " << path << std::endl;
  326. // 找到最后一个斜杠并截断路径
  327. char* last_slash = strrchr(path, '/');
  328. if (last_slash) {
  329. *last_slash = '\0';
  330. }
  331. else {
  332. std::cerr << "[WARNING] GetProcessDirectory: No directory separator found" << std::endl;
  333. }
  334. // 返回一个新的字符串副本,而不是局部数组的指针
  335. return std::string(path);
  336. }
  337. string GetFileDirectory(string& fullpath) {
  338. size_t pos = fullpath.find_last_of('/');
  339. return (pos != string::npos) ? fullpath.substr(0, pos) : "";
  340. }
  341. bool FindSubVersionDirs(string rootDir, map<string, vector<string>>& dirlist)
  342. {
  343. UNUSED(rootDir);
  344. UNUSED(dirlist);
  345. return false;
  346. }
  347. string GetFileName(string& fullpath) {
  348. size_t pos = fullpath.find_last_of('/');
  349. return (pos != string::npos) ? fullpath.substr(pos + 1) : fullpath;
  350. }
  351. string GetFileTitle(string& fullpath) {
  352. string filename = GetFileName(fullpath);
  353. size_t dot = filename.find_last_of('.');
  354. return (dot != string::npos) ? filename.substr(0, dot) : filename;
  355. }
  356. bool CreateFileDirectory(string& FullFilePath) {
  357. string dir = GetFileDirectory(FullFilePath);
  358. if (dir.empty()) return false;
  359. string command = "mkdir -p " + dir;
  360. return system(command.c_str()) == 0;
  361. }
  362. //=== 文件系统遍历 ===//
  363. bool FindSubFiles(string rootDir, vector<string>& filelist, bool Recursive, string strWildcard) {
  364. DIR* dir = opendir(rootDir.c_str());
  365. if (!dir) return false;
  366. struct dirent* entry;
  367. while ((entry = readdir(dir)) != nullptr) {
  368. string name = entry->d_name;
  369. if (name == "." || name == "..") continue;
  370. string fullpath = rootDir + "/" + name;
  371. if (entry->d_type == DT_DIR && Recursive) {
  372. FindSubFiles(fullpath, filelist, Recursive, strWildcard);
  373. }
  374. else if (entry->d_type == DT_REG) {
  375. filelist.push_back(fullpath);
  376. }
  377. }
  378. closedir(dir);
  379. return !filelist.empty();
  380. }
  381. //=== 其他辅助函数 ===//
  382. void RawToHex(const char* pRaw, DWORD RawLen, string& Hex) {
  383. Hex.reserve(RawLen * 3);
  384. for (DWORD i = 0; i < RawLen; i++) {
  385. char buf[4];
  386. snprintf(buf, sizeof(buf), "%02X ", pRaw[i] & 0xFF);
  387. Hex.append(buf);
  388. }
  389. }
  390. string ReplaceSubString(string org, string& keystr, string& replacestr) {
  391. size_t pos = 0;
  392. while ((pos = org.find(keystr, pos)) != string::npos) {
  393. org.replace(pos, keystr.length(), replacestr);
  394. pos += replacestr.length();
  395. }
  396. return org;
  397. }
  398. //=== 动态库函数信息 ===//
  399. std::vector<export_functions> GetDllFunctionInfo(const char* moduleName) {
  400. void* handle = dlopen(moduleName, RTLD_LAZY);
  401. if (!handle) return {};
  402. // 获取动态库信息
  403. Dl_info info;
  404. if (dladdr(handle, &info) == 0) {
  405. dlclose(handle);
  406. return {};
  407. }
  408. // 简化实现:仅获取动态库路径
  409. std::vector<export_functions> result;
  410. result.push_back(make_tuple(info.dli_fname, 0, 0));
  411. dlclose(handle);
  412. return result;
  413. }
  414. void TransferModuleJosnConfig2DriverConfig(ResDataObject& config)
  415. {
  416. for (size_t x = 0; x < config.size(); x++)
  417. {
  418. if (config[x].GetKeyCount("Value") > 0)
  419. {
  420. if (config[x]["Value"].size() <= 0)
  421. {
  422. string va = (const char*)config[x]["Value"];
  423. config[x] = va.c_str();
  424. }
  425. else
  426. {
  427. ResDataObject rest = config[x]["Value"];
  428. config[x] = rest;
  429. }
  430. }
  431. }
  432. }
  433. // 将time_t类型时间转换为"YYYY-MM-DD HH:MM:SS"格式的字符串
  434. std::string DatetimeToString(time_t timeVal)
  435. {
  436. // 将time_t转换为本地时间的tm结构体
  437. struct tm* localTime = localtime(&timeVal);
  438. if (localTime == nullptr)
  439. {
  440. // 处理转换失败的情况,返回空字符串或错误标识
  441. return "";
  442. }
  443. // 缓冲区,足够容纳格式化后的时间字符串(包含终止符)
  444. char timeStr[32] = {0};
  445. // 格式化时间字符串:年-月-日 时:分:秒
  446. // %Y:四位年份,%m:两位月份,%d:两位日期
  447. // %H:24小时制小时,%M:分钟,%S:秒
  448. strftime(timeStr, sizeof(timeStr), "%Y-%m-%d %H:%M:%S", localTime);
  449. return std::string(timeStr);
  450. }