mod_ResourceWatcher.cpp 43 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181
  1. // mod_ResourceWatcher.cpp : 定义 DLL 应用程序的导出函数。
  2. //
  3. #include "stdafx.h"
  4. #include "mod_ResourceWatcher.h"
  5. #include "CommEntityUtil.hpp"
  6. #include "array.h"
  7. #include "fileutil.h"
  8. #include "iniutil.h"
  9. #include "toolkit.h"
  10. #include "osutil.h"
  11. #if defined(RVC_OS_LINUX)
  12. #include "SogouVersion.h"
  13. #include <winpr/sysinfo.h>
  14. #endif //RVC_OS_LINUX
  15. #include "publicFunExport.h"
  16. #include <map>
  17. #include <regex.h>
  18. struct SogouRunVersionInfo
  19. {
  20. CSimpleStringA strInstallDir;
  21. CSimpleStringA strVersion;
  22. SogouRunVersionInfo():strInstallDir(true),strVersion(true){}
  23. CSimpleStringA ToString() const {
  24. CSimpleStringA result(true);
  25. if(!strInstallDir.IsNullOrEmpty()) {
  26. result += strInstallDir;
  27. result += "#";
  28. }
  29. if(!strVersion.IsNullOrEmpty()) {
  30. result += strVersion;
  31. }
  32. return result;
  33. }
  34. };
  35. struct SogouInstallStateInfo
  36. {
  37. DWORD dwInstalledStatus;
  38. CSimpleStringA strInstallDate;
  39. SogouInstallStateInfo():dwInstalledStatus(-1),strInstallDate(true){}
  40. CSimpleStringA ToString() const {
  41. CSimpleStringA result(true);
  42. if(!strInstallDate.IsNullOrEmpty()) {
  43. //result += strInstallDate;
  44. result += GetInstallTime().ToTimeString();
  45. result += "#";
  46. }
  47. result += CSimpleStringA::Format("%u", dwInstalledStatus);
  48. return result;
  49. }
  50. CSmallDateTime GetInstallTime() const {
  51. if(!strInstallDate.IsNullOrEmpty()) {
  52. DWORD dwSecsSince1970(0);
  53. sscanf_s(strInstallDate.GetData(), "%u", &dwSecsSince1970);
  54. dwSecsSince1970 -= 946656000; // 2000-1970
  55. return CSmallDateTime(dwSecsSince1970);
  56. }
  57. return CSmallDateTime::BeginTime;
  58. }
  59. };
  60. struct SogouInstallInfo
  61. {
  62. SogouInstallStateInfo state;
  63. SogouRunVersionInfo program;
  64. CSimpleStringA Stringfy() const
  65. {
  66. return (state.ToString() + "||" + program.ToString());
  67. }
  68. bool IsInstalledSuccess() const {
  69. return (state.dwInstalledStatus == 0);
  70. }
  71. };
  72. void ResourceWatcherServiceSession::Handle_Fetch(
  73. SpReqAnsContext<ResourceWatcherService_Fetch_Req, ResourceWatcherService_Fetch_Ans>::Pointer ctx)
  74. {
  75. m_pEntity->Fetch(ctx);
  76. }
  77. void ResourceWatcherServiceSession::Handle_GetDevInfo(
  78. SpReqAnsContext<ResourceWatcherService_GetDevInfo_Req, ResourceWatcherService_GetDevInfo_Ans>::Pointer ctx)
  79. {
  80. LOG_FUNCTION();
  81. m_pEntity->GetDevInfo(ctx);
  82. }
  83. void ResourceWatcherServiceSession::Handle_GetCardSwiper(SpReqAnsContext<ResourceWatcherService_GetCardSwiper_Req, ResourceWatcherService_GetCardSwiper_Ans>::Pointer ctx)
  84. {
  85. LOG_FUNCTION();
  86. m_pEntity->GetCSwiperStatus(ctx);
  87. }
  88. void ResourceWatcherServiceSession::Handle_GetCpuType(SpReqAnsContext<ResourceWatcherService_GetCpuType_Req, ResourceWatcherService_GetCpuType_Ans>::Pointer ctx)
  89. {
  90. LOG_FUNCTION();
  91. m_pEntity->GetCPUType(ctx);
  92. }
  93. void ResourceWatcherServiceSession::Handle_OperateFile
  94. (SpReqAnsContext<ResourceWatcherService_OperateFile_Req,
  95. ResourceWatcherService_OperateFile_Ans>::Pointer ctx)
  96. {
  97. LOG_FUNCTION();
  98. m_pEntity->OperateFile(ctx);
  99. }
  100. void ResourceWatcherServiceSession::Handle_ExtractEventLog(
  101. SpReqAnsContext<ResourceWatcherService_ExtractEventLog_Req, ResourceWatcherService_ExtractEventLog_Ans>::Pointer ctx)
  102. {
  103. LOG_FUNCTION();
  104. m_pEntity->RetrieveEventLog(ctx);
  105. }
  106. void ResourceWatcherServiceSession::Handle_UpdateDNS(SpReqAnsContext<ResourceWatcherService_UpdateDNS_Req, ResourceWatcherService_UpdateDNS_Ans>::Pointer ctx)
  107. {
  108. LOG_FUNCTION();
  109. m_pEntity->UpdateDNS(ctx);
  110. }
  111. void ResourceWatcherServiceSession::Handle_GetNetworkInfo(SpReqAnsContext<ResourceWatcherService_GetNetworkInfo_Req, ResourceWatcherService_GetNetworkInfo_Ans>::Pointer ctx)
  112. {
  113. LOG_FUNCTION();
  114. m_pEntity->GetNetworkInfo(ctx);
  115. }
  116. void ResourceWatcherServiceSession::Handle_GetThirdPartyInstallState(SpReqAnsContext<ResourceWatcherService_GetThirdPartyInstallState_Req, ResourceWatcherService_GetThirdPartyInstallState_Ans>::Pointer ctx)
  117. {
  118. LOG_FUNCTION();
  119. m_pEntity->GetThirdPartyInstallState(ctx);
  120. }
  121. void ResourceWatcherServiceSession::Handle_InstallThirdPartyProgram(SpReqAnsContext<ResourceWatcherService_InstallThirdPartyProgram_Req, ResourceWatcherService_InstallThirdPartyProgram_Ans>::Pointer ctx)
  122. {
  123. LOG_FUNCTION();
  124. m_pEntity->InstallThirdPartyProgram(ctx);
  125. }
  126. void ResourceWatcherServiceSession::Handle_BizLinkDetect(SpReqAnsContext<ResourceWatcherService_BizLinkDetect_Req, ResourceWatcherService_BizLinkDetect_Ans>::Pointer ctx)
  127. {
  128. LOG_FUNCTION();
  129. m_pEntity->BizLinkDetect(ctx);
  130. }
  131. void ResourceWatcherServiceSession::Handle_CheckNetType(SpReqAnsContext<ResourceWatcherService_CheckNetType_Req, ResourceWatcherService_CheckNetType_Ans>::Pointer ctx)
  132. {
  133. LOG_FUNCTION();
  134. m_pEntity->CheckNetType(ctx);
  135. }
  136. void ResourceWatcherServiceSession::Handle_GetBizLinks(SpReqAnsContext<ResourceWatcherService_GetBizLinks_Req, ResourceWatcherService_GetBizLinks_Ans>::Pointer ctx)
  137. {
  138. LOG_FUNCTION();
  139. m_pEntity->GetBizLinks(ctx);
  140. }
  141. void ResourceWatcherServiceSession::Handle_GetTerminalVersionList(SpReqAnsContext<ResourceWatcherService_GetTerminalVersionList_Req, ResourceWatcherService_GetTerminalVersionList_Ans>::Pointer ctx)
  142. {
  143. LOG_FUNCTION();
  144. m_pEntity->GetTerminalVersionList(ctx);
  145. }
  146. void ResourceWatcherServiceSession::Handle_ManipulateVersion(SpReqAnsContext<ResourceWatcherService_ManipulateVersion_Req, ResourceWatcherService_ManipulateVersion_Ans>::Pointer ctx)
  147. {
  148. LOG_FUNCTION();
  149. m_pEntity->ManipulateVersion(ctx);
  150. }
  151. void ResourceWatcherEntity::UpdateDNS(SpReqAnsContext<ResourceWatcherService_UpdateDNS_Req, ResourceWatcherService_UpdateDNS_Ans>::Pointer ctx)
  152. {
  153. ctx->Answer(Error_NotImpl);
  154. }
  155. void ResourceWatcherEntity::GetNetworkInfo(SpReqAnsContext<ResourceWatcherService_GetNetworkInfo_Req, ResourceWatcherService_GetNetworkInfo_Ans>::Pointer ctx)
  156. {
  157. char buf[512];
  158. toolkit_interface_address_t* info;
  159. int count, i;
  160. toolkit_interface_addresses(&info, &count);
  161. i = count;
  162. Dbg("Number of interfaces: %d", count);
  163. if (count <= 0) {
  164. ctx->Answer(Error_NotExist);
  165. return;
  166. }
  167. int realCount = 0;
  168. while (i--) {
  169. toolkit_interface_address_t& interface = info[i];
  170. if (interface.address.address4.sin_family == AF_INET/* && !interface.is_internal*/) {
  171. realCount++;
  172. }
  173. }
  174. if (realCount <= 0) {
  175. ctx->Answer(Error_NotExist);
  176. return;
  177. }
  178. ctx->Ans.status = 0;
  179. ctx->Ans.current = "";
  180. ctx->Ans.ips.Init(realCount);
  181. ctx->Ans.names.Init(realCount);
  182. ctx->Ans.macs.Init(realCount);
  183. ctx->Ans.masks.Init(realCount);
  184. ctx->Ans.gateways.Init(realCount);
  185. ctx->Ans.dns.Init(realCount);
  186. int cnt = 0, active = -1;
  187. for (i = 0; i < count; ++i) {
  188. toolkit_interface_address_t& interface = info[i];
  189. if (interface.address.address4.sin_family == AF_INET) {
  190. ctx->Ans.names[cnt] = interface.name;
  191. toolkit_ip4_name(&interface.address.address4, buf, sizeof(buf));
  192. if (strcmp(buf, "127.0.0.1") != 0) active = cnt;
  193. ctx->Ans.ips[cnt] = buf;
  194. ctx->Ans.macs[cnt] = "";
  195. ctx->Ans.masks[cnt] = "";
  196. ctx->Ans.gateways[cnt] = "";
  197. ctx->Ans.dns[cnt] = "";
  198. cnt++;
  199. }
  200. }
  201. toolkit_free_interface_addresses(info, count);
  202. const char* parent = "/etc/NetworkManager/system-connections";
  203. array_header_t* subs;
  204. subs = fileutil_get_sub_files_a(parent);
  205. if (subs) {
  206. for (i = 0; i < subs->nelts; ++i) {
  207. char path[256] = { 0 };
  208. char* dir = ARRAY_IDX(subs, i, char*);
  209. char value[128];
  210. inifile_read_str_s("connection", "interface-name", "", value, 127, dir);
  211. if (strlen(value) == 0) continue;
  212. for (int j = 0; j < realCount; ++j) {
  213. if (ctx->Ans.names[j].Compare(value) == 0) {
  214. memset(value, 0, sizeof(value));
  215. inifile_read_str_s("connection", "id", "", value, 127, dir);
  216. if (strlen(value) > 0) {
  217. ctx->Ans.names[j] = CSimpleStringA::Format("%s#%s", value, ctx->Ans.names[j].GetData());
  218. }
  219. if (active == j) {
  220. ctx->Ans.current = ctx->Ans.names[j];
  221. }
  222. memset(value, 0, sizeof(value));
  223. inifile_read_str_s("ethernet", "mac-address", "", value, 127, dir);
  224. ctx->Ans.macs[j] = value;
  225. memset(value, 0, sizeof(value));
  226. inifile_read_str_s("ipv4", "dns", "", value, 127, dir);
  227. ctx->Ans.dns[j] = value;
  228. break;
  229. }
  230. }
  231. }
  232. toolkit_array_free2(subs);
  233. }
  234. ctx->Answer(Error_Succeed);
  235. }
  236. void ResourceWatcherEntity::GetThirdPartyInstallState(SpReqAnsContext<ResourceWatcherService_GetThirdPartyInstallState_Req, ResourceWatcherService_GetThirdPartyInstallState_Ans>::Pointer ctx)
  237. {
  238. ErrorCodeEnum result(Error_Succeed);
  239. if (ctx->Req.mode == 1) {//查看搜狗输入法安装状态
  240. SogouInstallInfo info;
  241. info.state.dwInstalledStatus = Sogou_GetInstallStatus();
  242. info.state.strInstallDate = Sogou_GetInstallTime();
  243. info.program.strInstallDir = Sogou_GetInstallPath();
  244. info.program.strVersion = Sogou_GetVersion();
  245. Dbg("%d, %s, %s, %s"
  246. , info.state.dwInstalledStatus, info.state.strInstallDate.GetData()
  247. , info.program.strInstallDir.GetData(), info.program.strVersion.GetData());
  248. Dbg("InstallTime: %s", info.state.GetInstallTime().ToTimeString().GetData());
  249. ctx->Ans.status = info.IsInstalledSuccess() ? 1 : 0;
  250. ctx->Ans.reserverd1 = info.state.GetInstallTime().ToTimeString();
  251. ctx->Ans.path = info.program.strInstallDir;
  252. ctx->Ans.version = info.program.strVersion;
  253. } else if (ctx->Req.mode == 2) { //检测字体的安装状态
  254. CSimpleStringA strFontDir("/usr/share/fonts/truetype");
  255. CSimpleStringA strRVCTTFsDir(strFontDir + SPLIT_SLASH_STR + "RVCTTFs");
  256. if (!ExistsDirA(strRVCTTFsDir)) {
  257. ctx->Ans.status = 0;
  258. ctx->Ans.reserverd1 = CSimpleStringA::Format("%s 文件夹不存在", (LPCTSTR)strRVCTTFsDir);
  259. } else {
  260. CSimpleStringA ttf1 = strRVCTTFsDir + SPLIT_SLASH_STR + "HYQiHei-55S.ttf";
  261. CSimpleStringA ttf2 = strRVCTTFsDir + SPLIT_SLASH_STR + "HYQiHei-65S.ttf";
  262. CSimpleStringA ttfdir = strRVCTTFsDir + SPLIT_SLASH_STR + "fonts.dir";
  263. CSimpleStringA ttfscale = strRVCTTFsDir + SPLIT_SLASH_STR + "fonts.scale";
  264. CSimpleStringA ttfuuid = strRVCTTFsDir + SPLIT_SLASH_STR + ".uuid";
  265. int existCheck = 0;
  266. if (!ExistsFileA(ttf1)) {
  267. existCheck |= 1;
  268. }
  269. if (!ExistsFileA(ttf2)) {
  270. existCheck |= 2;
  271. }
  272. if (!ExistsFileA(ttfdir)) {
  273. existCheck |= 4;
  274. }
  275. if (!ExistsFileA(ttfscale)) {
  276. existCheck |= 8;
  277. }
  278. if (!ExistsFileA(ttfuuid)) {
  279. existCheck |= 16;
  280. }
  281. if (existCheck != 0) {
  282. ctx->Ans.status = 0;
  283. ctx->Ans.reserverd1 = CSimpleStringA::Format("安装文件不存在:0x%X", existCheck);
  284. } else {
  285. ctx->Ans.status = 1;
  286. ctx->Ans.reserverd1 = "";
  287. ctx->Ans.path = strRVCTTFsDir;
  288. ctx->Ans.version = "";
  289. }
  290. }
  291. } else {
  292. result = Error_NotSupport;
  293. }
  294. ctx->Answer(result);
  295. return;
  296. }
  297. ErrorCodeEnum SetFileExecutePriviledge(LPCTSTR lpcszDirOrFilePath)
  298. {
  299. ErrorCodeEnum result(Error_Succeed);
  300. if (ExistsDirA(lpcszDirOrFilePath)) {
  301. do
  302. {
  303. array_header_t* subs;
  304. subs = fileutil_get_sub_dirs_a(lpcszDirOrFilePath);
  305. if (subs) {
  306. for (int i = 0; i < subs->nelts; ++i) {
  307. char* dir = ARRAY_IDX(subs, i, char*);
  308. const char* dirname = &dir[strlen(lpcszDirOrFilePath) + 1];
  309. ErrorCodeEnum tmpResult = SetFileExecutePriviledge(dir);
  310. if (tmpResult != Error_Succeed) {
  311. toolkit_array_free2(subs);
  312. return tmpResult;
  313. }
  314. }
  315. }
  316. } while (false);
  317. do {
  318. array_header_t* subs;
  319. subs = fileutil_get_sub_files_a(lpcszDirOrFilePath);
  320. if (subs) {
  321. for (int i = 0; i < subs->nelts; ++i) {
  322. char* path = ARRAY_IDX(subs, i, char*);
  323. mode_t f_attrib = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IXOTH;
  324. if (chmod(path, f_attrib) != 0) {
  325. Dbg("chmod file priviledge failed, %s, %d", path, errno);
  326. toolkit_array_free2(subs);
  327. return Error_Unexpect;
  328. }
  329. }
  330. toolkit_array_free2(subs);
  331. }
  332. } while (false);
  333. } else if(ExistsFileA(lpcszDirOrFilePath)) {
  334. mode_t f_attrib = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IXOTH;
  335. if (chmod(lpcszDirOrFilePath, f_attrib) != 0) {
  336. Dbg("chmod file priviledge failed, %s, %d", lpcszDirOrFilePath, errno);
  337. return Error_Unexpect;
  338. }
  339. } else {
  340. result = Error_InvalidState;
  341. }
  342. return result;
  343. }
  344. void ResourceWatcherEntity::InstallThirdPartyProgram(SpReqAnsContext<ResourceWatcherService_InstallThirdPartyProgram_Req, ResourceWatcherService_InstallThirdPartyProgram_Ans>::Pointer ctx)
  345. {
  346. ErrorCodeEnum result(Error_Succeed);
  347. ErrorCodeEnum tmpResult(Error_Succeed);
  348. CSimpleStringA tmpMsg(true);
  349. if (ctx->Req.type == 1) {//安装搜狗输入法
  350. Dbg("to install sogou input...");
  351. CSimpleStringA strInstallPkgPath;
  352. CSimpleStringA strAdDataDirPath(true);
  353. tmpResult = GetFunction()->GetPath("Ad", strAdDataDirPath);
  354. if (strAdDataDirPath.IsNullOrEmpty() && m_bInitMode) {
  355. strAdDataDirPath = "/opt/rvc/adData";
  356. }
  357. if (strAdDataDirPath.IsNullOrEmpty()) {
  358. tmpResult = Error_Unexpect;
  359. tmpMsg = "获取安装包路径Ad失败";
  360. } else {
  361. array_header_t* subs;
  362. subs = fileutil_get_sub_dirs_a(strAdDataDirPath);
  363. if (subs) {
  364. for (int i = 0; i < subs->nelts; ++i) {
  365. char* dir = ARRAY_IDX(subs, i, char*);
  366. const char* dirname = &dir[strAdDataDirPath.GetLength() + 1];
  367. if (CSimpleStringA(dirname).IsStartWith("sogou", true)) {
  368. if (strInstallPkgPath.IsNullOrEmpty()) {
  369. Dbg("found it: %s", dir);
  370. strInstallPkgPath = dir;
  371. } else if(strInstallPkgPath.Compare(dir) < 0) {
  372. Dbg("replace %s with %s", (LPCTSTR)strInstallPkgPath, dir);
  373. strInstallPkgPath = dir;
  374. }
  375. //break;
  376. }
  377. }
  378. toolkit_array_free2(subs);
  379. }
  380. if (strInstallPkgPath.IsNullOrEmpty()) {
  381. tmpMsg = CSimpleStringA::Format("%s 路径下找不到输入法安装包文件夹", strAdDataDirPath.GetData());
  382. tmpResult = Error_NotExist;
  383. } else {
  384. tmpResult = SetFileExecutePriviledge(strInstallPkgPath);
  385. if (tmpResult != Error_Succeed) {
  386. tmpMsg = CSimpleStringA::Format("%s 修改文件夹权限失败", strInstallPkgPath.GetData());
  387. tmpResult = Error_NotExist;
  388. } else {
  389. CSimpleStringA strRunIniFilePath = strInstallPkgPath + SPLIT_SLASH_STR + "Run.ini";
  390. if (ExistsFileA(strRunIniFilePath)) {
  391. char* p = inifile_read_str(strRunIniFilePath, "Action", "ToRun", "");
  392. CSimpleStringA strInstallScriptFile(strInstallPkgPath + SPLIT_SLASH_STR + p);
  393. toolkit_free(p);
  394. Dbg("install script file: %s", strInstallScriptFile.GetData());
  395. if (ExistsFileA(strInstallScriptFile)) {
  396. do {
  397. char app[MAX_PATH] = { '\0' };
  398. tk_process_t* process = NULL;
  399. tk_process_option_t option;
  400. option.exit_cb = NULL;
  401. option.file = NULL;
  402. option.flags = 0;
  403. sprintf(app, "bash %s", strInstallScriptFile.GetData());
  404. option.params = app;
  405. const int res = process_spawn(&option, &process);
  406. if (0 == res) {
  407. FREE(process);
  408. Dbg("execute {%s} suc", strInstallScriptFile.GetData());
  409. } else {
  410. tmpMsg = CSimpleStringA::Format("执行 %s 失败:%s", strInstallScriptFile.GetData(), toolkit_strerror(res));
  411. tmpResult = Error_Process;
  412. }
  413. } while (false);
  414. CSimpleStringA strStartupScriptFile(strInstallPkgPath + SPLIT_SLASH_STR + "startup_service.sh");
  415. Dbg("startup script file: %s", strStartupScriptFile.GetData());
  416. if (!ExistsFileA(strStartupScriptFile)) {
  417. tmpMsg = CSimpleStringA::Format("%s 启动脚本文件不存在,需重启设备后触发", strStartupScriptFile.GetData());
  418. tmpResult = Error_NotExist;
  419. } else {
  420. Sleep(1000);
  421. do {
  422. char app[MAX_PATH] = { '\0' };
  423. tk_process_t* process = NULL;
  424. tk_process_option_t option;
  425. option.exit_cb = NULL;
  426. option.file = NULL;
  427. option.flags = 0;
  428. #if 0
  429. auto users = GetUserNameList(true);
  430. if (users.size() == 1) {
  431. sprintf(app, "su -m -p -c \"bash %s\" %s", strStartupScriptFile.GetData(), users[0].c_str());
  432. } else {
  433. for (auto it = users.cbegin(); it != users.cend(); ++it) {
  434. Dbg("user:%s", it->c_str());
  435. }
  436. sprintf(app, "bash %s", strStartupScriptFile.GetData());
  437. }
  438. #else
  439. sprintf(app, "bash %s", strStartupScriptFile.GetData());
  440. #endif
  441. option.params = app;
  442. const int res = process_spawn(&option, &process);
  443. if (0 == res) {
  444. FREE(process);
  445. Dbg("execute {%s} suc", app);
  446. } else {
  447. tmpMsg = CSimpleStringA::Format("执行 %s 失败:%s", app, toolkit_strerror(res));
  448. tmpResult = Error_Process;
  449. }
  450. } while (false);
  451. }
  452. } else {
  453. tmpMsg = CSimpleStringA::Format("%s 执行文件不存在", strInstallScriptFile.GetData());
  454. tmpResult = Error_NotExist;
  455. }
  456. } else {
  457. tmpMsg = CSimpleStringA::Format("%s 文件不存在", strRunIniFilePath.GetData());
  458. tmpResult = Error_NotExist;
  459. }
  460. }
  461. }
  462. }
  463. if (tmpResult == Error_Succeed) {
  464. SogouInstallInfo info;
  465. Sleep(1500);
  466. info.program.strVersion = Sogou_GetVersion();
  467. const int maxTimes = 5;
  468. int curTimes = 0;
  469. while (info.program.strVersion.IsNullOrEmpty() && curTimes < maxTimes) {
  470. Sleep(2000);
  471. info.program.strVersion = Sogou_GetVersion();
  472. curTimes++;
  473. }
  474. if (info.program.strVersion.IsNullOrEmpty()) {
  475. tmpResult = Error_Unexpect;
  476. tmpMsg = CSimpleStringA::Format("服务启动失败,获取安装版本信息失败");
  477. info.program.strVersion = "重启设备后生效!";
  478. tmpResult = Error_Succeed;
  479. tmpMsg = "重启设备后生效!";
  480. } else {
  481. //TODO:
  482. }
  483. info.state.dwInstalledStatus = Sogou_GetInstallStatus();
  484. info.state.strInstallDate = Sogou_GetInstallTime();
  485. info.program.strInstallDir = Sogou_GetInstallPath();
  486. Dbg("%d, %s, %s, %s"
  487. , info.state.dwInstalledStatus, info.state.strInstallDate.GetData()
  488. , info.program.strInstallDir.GetData(), info.program.strVersion.GetData());
  489. Dbg("InstallTime: %s", info.state.GetInstallTime().ToTimeString().GetData());
  490. if (!info.IsInstalledSuccess()) {
  491. tmpResult = Error_FailVerify;
  492. tmpMsg = CSimpleStringA::Format("安装成功,但检测版本信息失败!");
  493. } else {
  494. ctx->Ans.path = info.program.strInstallDir;
  495. ctx->Ans.reserverd1 = info.program.strVersion;
  496. ctx->Ans.reserverd2 = info.state.GetInstallTime().ToTimeString();
  497. }
  498. }
  499. } else if (ctx->Req.type == 2) {//安装花了钱的字体
  500. Dbg("to install cmb font input...%d", m_bInitMode);
  501. CSimpleStringA strAdDataDirPath(true);
  502. tmpResult = GetFunction()->GetPath("Ad", strAdDataDirPath);
  503. if (strAdDataDirPath.IsNullOrEmpty() && m_bInitMode) {
  504. strAdDataDirPath = "/opt/rvc/adData";
  505. }
  506. if (strAdDataDirPath.IsNullOrEmpty()) {
  507. tmpResult = Error_Unexpect;
  508. tmpMsg = "获取安装包路径Ad失败";
  509. } else {
  510. CSimpleStringA strInstallPkgPath = strAdDataDirPath + SPLIT_SLASH_STR "HYQiHei";
  511. if (!ExistsDirA(strInstallPkgPath)) {
  512. tmpMsg = CSimpleStringA::Format("%s 文件夹不存在", strInstallPkgPath.GetData());
  513. tmpResult = Error_NotExist;
  514. } else {
  515. CSimpleStringA strRunIniFilePath = strInstallPkgPath + SPLIT_SLASH_STR + "Run.ini";
  516. if (ExistsFileA(strRunIniFilePath)) {
  517. char* p = inifile_read_str(strRunIniFilePath, "Action", "ToRun", "");
  518. CSimpleStringA strInstallScriptFile(strInstallPkgPath + SPLIT_SLASH_STR + p);
  519. toolkit_free(p);
  520. Dbg("RunScript file: %s", strInstallScriptFile.GetData());
  521. if (ExistsFileA(strInstallScriptFile)) {
  522. do {
  523. char app[MAX_PATH] = { '\0' };
  524. tk_process_t* process = NULL;
  525. tk_process_option_t option;
  526. option.exit_cb = NULL;
  527. option.file = NULL;
  528. option.flags = 0;
  529. sprintf(app, "bash %s", strInstallScriptFile.GetData());
  530. option.params = app;
  531. const int res = process_spawn(&option, &process);
  532. if (0 == res) {
  533. FREE(process);
  534. Dbg("execute {%s} suc", strInstallScriptFile.GetData());
  535. } else {
  536. tmpMsg = CSimpleStringA::Format("执行 %s 失败:%s", strInstallScriptFile.GetData(), toolkit_strerror(res));
  537. tmpResult = Error_Process;
  538. }
  539. } while (false);
  540. } else {
  541. tmpMsg = CSimpleStringA::Format("%s 执行文件不存在", strInstallScriptFile.GetData());
  542. tmpResult = Error_NotExist;
  543. }
  544. } else {
  545. tmpMsg = CSimpleStringA::Format("%s 文件不存在", strRunIniFilePath.GetData());
  546. tmpResult = Error_NotExist;
  547. }
  548. }
  549. }
  550. if (tmpResult == Error_Succeed) {
  551. ///**TODO(Gifur@10/21/2021): 二次校验 */
  552. }
  553. } else {
  554. result = Error_NotSupport;
  555. }
  556. ctx->Ans.result = tmpResult;
  557. ctx->Ans.msg = tmpMsg;
  558. ctx->Answer(result);
  559. return;
  560. }
  561. void ResourceWatcherEntity::GetTerminalVersionList(SpReqAnsContext<ResourceWatcherService_GetTerminalVersionList_Req, ResourceWatcherService_GetTerminalVersionList_Ans>::Pointer ctx)
  562. {
  563. CSimpleStringA strVersionBaseDir(true);
  564. GetFunction()->GetPath("RootVer", strVersionBaseDir);
  565. const CSimpleStringA strActiveFile = strVersionBaseDir + SPLIT_SLASH_STR + "active.txt";
  566. CSystemStaticInfo staticInfo;
  567. GetFunction()->GetSystemStaticInfo(staticInfo);
  568. CSimpleStringA strCurrVer = staticInfo.InstallVersion.ToString();
  569. Dbg("get current version [%s]", (LPCTSTR)strCurrVer);
  570. std::vector<std::string> verlist;
  571. array_header_t* arr;
  572. arr = fileutil_get_sub_dirs_a(strVersionBaseDir);
  573. if (arr) {
  574. do {
  575. regex_t reg;
  576. CSimpleStringA strPattern("^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+[\(\)A-Za-z_-]*$");
  577. int ret = regcomp(&reg, strPattern, REG_EXTENDED | REG_NOSUB);
  578. if (ret) {
  579. char ebuff[256];
  580. regerror(ret, &reg, ebuff, 256);
  581. Dbg("regex failed: %s", ebuff);
  582. ctx->Ans.msg = CSimpleStringA::Format("内部错误:REGEX %s", ebuff);
  583. ctx->Ans.current = -1;
  584. break;
  585. } else {
  586. for (int i = 0; i < arr->nelts; ++i) {
  587. char* versionDir = ARRAY_IDX(arr, i, char*);
  588. char* versionDirName = &versionDir[strVersionBaseDir.GetLength() + 1];
  589. ret = regexec(&reg, versionDirName, 0, NULL, 0);
  590. if (0 == ret) {
  591. Dbg("filename %s matched!", versionDirName);
  592. verlist.push_back(std::string(versionDirName));
  593. }
  594. }
  595. }
  596. } while (false);
  597. toolkit_array_free2(arr);
  598. }
  599. if (!verlist.empty()) {
  600. const int count = verlist.size();
  601. ctx->Ans.index.Init(count);
  602. ctx->Ans.version.Init(count);
  603. ctx->Ans.remark.Init(count);
  604. ctx->Ans.type.Init(count);
  605. ctx->Ans.status.Init(count);
  606. for (int i = 0; i < count; ++i) {
  607. ctx->Ans.index[i] = i;
  608. ctx->Ans.version[i] = verlist[i].c_str();
  609. if (verlist[i].compare(strCurrVer.GetData()) == 0) {
  610. ctx->Ans.current = i;
  611. }
  612. ctx->Ans.remark[i] = "";
  613. ctx->Ans.type[i] = ctx->Ans.status[i] = 0;
  614. }
  615. }
  616. ctx->Answer(Error_Succeed);
  617. }
  618. namespace
  619. {
  620. bool UpdateCurrentVersionName(LPCTSTR filePath, LPCTSTR versionStr, LPCTSTR backupPath)
  621. {
  622. if (fileutil_copy_file(backupPath, filePath) != 0) {
  623. return false;
  624. }
  625. FILE* fp = fopen(filePath, "wb+");
  626. if (fp == NULL) {
  627. return false;
  628. }
  629. bool result(false);
  630. do
  631. {
  632. int ret = fwrite(versionStr, strlen(versionStr), 1, fp);
  633. if (ret != 1) {
  634. Dbg("fwrite failed: %d", ret);
  635. break;
  636. }
  637. fflush(fp);
  638. fclose(fp);
  639. fp = fopen(filePath, "rb");
  640. if (fp != NULL) {
  641. char value[32] = { 0 };
  642. int ret2 = fread(value, strlen(versionStr), 1, fp);
  643. if (ret2 == 1) {
  644. if (strcmp(value, versionStr) == 0)
  645. Dbg("read agagin the value is the same!");
  646. else {
  647. break;
  648. }
  649. }
  650. }
  651. result = true;
  652. } while (false);
  653. fclose(fp);
  654. if (!result && backupPath) {
  655. fileutil_copy_file(filePath, backupPath);
  656. fileutil_delete_file(backupPath);
  657. }
  658. if (result && backupPath) {
  659. fileutil_delete_file(backupPath);
  660. }
  661. return result;
  662. }
  663. }
  664. void ResourceWatcherEntity::ManipulateVersion(SpReqAnsContext<ResourceWatcherService_ManipulateVersion_Req, ResourceWatcherService_ManipulateVersion_Ans>::Pointer ctx)
  665. {
  666. ErrorCodeEnum result(Error_Succeed);
  667. int tmpResult(0);
  668. CSimpleStringA tmpMsg(true);
  669. switch (ctx->Req.operation) {
  670. case 1: //设置为此版本为当前版本
  671. {
  672. CSimpleStringA strVersionBaseDir(true);
  673. GetFunction()->GetPath("RootVer", strVersionBaseDir);
  674. const CSimpleStringA strActiveFile = strVersionBaseDir + SPLIT_SLASH_STR + "active.txt";
  675. const CSimpleStringA strActiveFileBackup = strActiveFile + "activebak.txt";
  676. CSystemStaticInfo staticInfo;
  677. GetFunction()->GetSystemStaticInfo(staticInfo);
  678. CSimpleStringA strCurrVer = staticInfo.InstallVersion.ToString();
  679. Dbg("get current version [%s]", (LPCTSTR)strCurrVer);
  680. if (!UpdateCurrentVersionName(strActiveFile, ctx->Req.value, strActiveFileBackup)) {
  681. tmpResult = Error_Unexpect;
  682. tmpMsg = "切换版本失败";
  683. }
  684. }
  685. break;
  686. case 2: //删除此版本
  687. {
  688. CSimpleStringA strVersionBaseDir(true);
  689. GetFunction()->GetPath("RootVer", strVersionBaseDir);
  690. const CSimpleStringA strVersionDirPath = strVersionBaseDir + SPLIT_SLASH_STR + ctx->Req.value;
  691. if (ExistsDirA(strVersionDirPath)) {
  692. if (!RemoveDirRecursiveA(strVersionDirPath)) {
  693. tmpResult = Error_Unexpect;
  694. tmpMsg = "删除版本失败";
  695. }
  696. }
  697. }
  698. break;
  699. default:
  700. result = Error_NotSupport;
  701. break;
  702. }
  703. ctx->Ans.result = tmpResult;
  704. ctx->Ans.msg = tmpMsg;
  705. ctx->Answer(result);
  706. }
  707. #if defined(RVC_OS_WIN)
  708. //1: 32bit process running at 64bit platform
  709. //0:
  710. static int Is32R64Platform()
  711. {
  712. static int isWow64 = -1;
  713. typedef BOOL(WINAPI* LPFN_ISWOW64PROCESS)(HANDLE, PBOOL);
  714. if (isWow64 == -1) {
  715. BOOL bIsWow64 = FALSE;
  716. LPFN_ISWOW64PROCESS fnIsWow64Process =
  717. (LPFN_ISWOW64PROCESS)GetProcAddress(GetModuleHandle("kernel32"), "IsWow64Process");
  718. if (NULL != fnIsWow64Process) {
  719. if (!fnIsWow64Process(GetCurrentProcess(), &bIsWow64)) {
  720. Dbg("detect is running with 64bit or not failed: %u", GetLastError());
  721. return -1;
  722. } else {
  723. isWow64 = bIsWow64 ? 1 : 0;
  724. }
  725. }
  726. }
  727. return isWow64;
  728. }
  729. static bool GetRegistValue(HKEY hKey, LPCTSTR lpcszParam,
  730. DWORD* pDwValue, CHAR* pSzValue, const DWORD* pDwSizeOfSz)
  731. {
  732. if (pDwValue != NULL) {
  733. DWORD dwType = REG_DWORD;
  734. DWORD dwValue = 0;
  735. DWORD dwSize = sizeof(DWORD);
  736. LONG lResult = RegQueryValueExA(hKey, lpcszParam, NULL, &dwType, (LPBYTE)&dwValue, &dwSize);
  737. if (lResult == ERROR_SUCCESS) {
  738. Dbg("Value of \"%s\": %d", lpcszParam, dwValue);
  739. *pDwValue = dwValue;
  740. return true;
  741. } else {
  742. Dbg("RegQueryValueEx for \"%s\" error, result=%ld.", lpcszParam, lResult);
  743. return false;
  744. }
  745. } else if (pSzValue != NULL) {
  746. DWORD dwType = REG_SZ;
  747. DWORD dwSize = MAX_PATH * sizeof(CHAR);
  748. TCHAR szValue[MAX_PATH + 1] = { 0 };
  749. LONG lResult = RegQueryValueEx(hKey, lpcszParam, NULL, &dwType, (LPBYTE)szValue, &dwSize);
  750. if (lResult == ERROR_SUCCESS) {
  751. Dbg("Value of \"%s\": %s", lpcszParam, szValue);
  752. strcpy_s(pSzValue, *pDwSizeOfSz, szValue);
  753. return true;
  754. } else {
  755. Dbg("RegQueryValueEx for \"InstallTime\" error, result=%ld.", lResult);
  756. return false;
  757. }
  758. }
  759. Dbg("invalid param for \"%s\"", lpcszParam);
  760. return false;
  761. }
  762. static LONG GetSogouInstallState(SogouInstallStateInfo& info)
  763. {
  764. HKEY hKey;
  765. LONG lResult = -1;
  766. DWORD dwFlag = KEY_READ | KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS;
  767. lResult = RegOpenKeyEx(HKEY_CURRENT_USER, "SOFTWARE\\SogouPCIme", 0, dwFlag, &hKey);
  768. if (lResult == ERROR_SUCCESS) {
  769. DWORD dwValue = (DWORD)-1;
  770. const bool res1 = GetRegistValue(hKey, "InstallFlag", &dwValue, NULL, NULL);
  771. if (res1) {
  772. info.dwInstalledStatus = dwValue;
  773. }
  774. TCHAR szValue[MAX_PATH + 1] = { 0 };
  775. DWORD dwLength = MAX_PATH;
  776. //1970 0x83AA7E80
  777. const bool res2 = GetRegistValue(hKey, "InstallTime", NULL, szValue, &dwLength);
  778. if (res2) {
  779. info.strInstallDate = szValue;
  780. Dbg("InstallTime: %s", info.GetInstallTime().ToTimeString().GetData());
  781. }
  782. if (res1 && res2) {
  783. lResult = 0;
  784. } else {
  785. lResult = -1;
  786. }
  787. } else {
  788. Dbg("%s::RegOpenKeyEx error, Result=%ld.", __FUNCTION__, lResult);
  789. }
  790. RegCloseKey(hKey);
  791. return lResult;
  792. }
  793. static LONG GetSogouExecuteInfo(SogouRunVersionInfo& info, BOOL f32bit = TRUE)
  794. {
  795. HKEY hKey;
  796. LONG lResult = -1;
  797. PVOID oldValue = NULL;
  798. Wow64DisableWow64FsRedirection(&oldValue);
  799. DWORD dwFlag = KEY_READ | KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS;
  800. lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  801. f32bit ? "SOFTWARE\\SogouPCIme" : "SOFTWARE\\WOW6432Node\\SogouPCIme", 0, dwFlag, &hKey);
  802. if (lResult == ERROR_SUCCESS) {
  803. TCHAR szVersion[MAX_PATH + 1] = { 0 }, szDefault[MAX_PATH + 1] = { 0 };
  804. DWORD dwLength = MAX_PATH;
  805. const bool res1 = GetRegistValue(hKey, "Version", NULL, szVersion, &dwLength);
  806. if (res1) info.strVersion = szVersion;
  807. const bool res2 = GetRegistValue(hKey, "", NULL, szDefault, &dwLength);
  808. if (res2) info.strInstallDir = szDefault;
  809. if (res1 && res2) {
  810. lResult = 0;
  811. } else {
  812. lResult = -1;
  813. }
  814. } else {
  815. Dbg("%s::RegOpenKeyEx(32bit=%d) error, Result=%ld.", __FUNCTION__, f32bit, lResult);
  816. }
  817. RegCloseKey(hKey);
  818. Wow64RevertWow64FsRedirection(oldValue);
  819. return lResult;
  820. }
  821. #endif //RVC_OS_WIN
  822. ErrorCodeEnum ResourceWatcherEntity::DoCheckInstallStateJob()
  823. {
  824. LOG_FUNCTION();
  825. CSmartPointer<IEntityFunction> spFunction = GetFunction();
  826. CSmartPointer<IConfigInfo> spConfig;
  827. ErrorCodeEnum err = spFunction->OpenConfig(Config_Run, spConfig);
  828. BOOL fNeedAlarm = TRUE;
  829. SogouInstallInfo info;
  830. #if defined(RVC_OS_WIN)
  831. GetSogouInstallState(info.state);
  832. BOOL is32Bit = Is64BitPlatform() ? FALSE : TRUE;
  833. if (ERROR_FILE_NOT_FOUND == GetSogouExecuteInfo(info.program, is32Bit))
  834. GetSogouExecuteInfo(info.program, !is32Bit);
  835. #else
  836. info.state.dwInstalledStatus = Sogou_GetInstallStatus();
  837. info.state.strInstallDate = Sogou_GetInstallTime();
  838. info.program.strInstallDir = Sogou_GetInstallPath();
  839. info.program.strVersion = Sogou_GetVersion();
  840. Dbg("%d, %s, %s, %s"
  841. , info.state.dwInstalledStatus, info.state.strInstallDate.GetData()
  842. , info.program.strInstallDir.GetData(), info.program.strVersion.GetData());
  843. Dbg("InstallTime: %s", info.state.GetInstallTime().ToTimeString().GetData());
  844. #endif //RVC_OS_WIN
  845. CSimpleStringA strLastRecord(true);
  846. err = spConfig->ReadConfigValue("SogouInput", "LastInstalledRecord", strLastRecord);
  847. if (strLastRecord.IsNullOrEmpty() || info.Stringfy().Compare(strLastRecord) != 0) {
  848. spConfig->WriteConfigValue("SogouInput", "LastInstalledRecord", info.Stringfy());
  849. fNeedAlarm = TRUE;
  850. } else {
  851. //Report info per day.
  852. int nLastRecordTime = 0;
  853. err = spConfig->ReadConfigValueInt("SogouInput", "LastReportTime", nLastRecordTime);
  854. SYSTEMTIME stTaskTime = CSmallDateTime(nLastRecordTime).ToSystemTime();
  855. Dbg("Last Sogou install check time: %04d-%02d-%02d %02d:%02d:%02d",
  856. stTaskTime.wYear, stTaskTime.wMonth, stTaskTime.wDay,
  857. stTaskTime.wHour, stTaskTime.wMinute, stTaskTime.wSecond);
  858. SYSTEMTIME stNow = {};
  859. GetLocalTime(&stNow);
  860. if (nLastRecordTime > 0 && stTaskTime.wYear == stNow.wYear
  861. && stTaskTime.wMonth == stNow.wMonth && stTaskTime.wDay == stNow.wDay) {
  862. //The Same Day
  863. fNeedAlarm = FALSE;
  864. } else {
  865. fNeedAlarm = TRUE;
  866. }
  867. }
  868. if (fNeedAlarm) {
  869. const DWORD dwUserCode = info.IsInstalledSuccess() ? LOG_ERR_SOGOU_INPUT_INSTALLED : LOG_ERR_SOGOU_INPUT_NOTINSTALLED;
  870. LogWarn(Severity_Middle, Error_DataCheck, dwUserCode, info.Stringfy());
  871. spConfig->WriteConfigValue("SogouInput", "LastReportTime",
  872. CSimpleStringA::Format("0x%08X", (DWORD)CSmallDateTime::GetNow()));
  873. } else {
  874. Dbg("Do not Report.");
  875. }
  876. return Error_Succeed;
  877. }
  878. void ResourceWatcherEntity::DoCheckSogouProcessStatus()
  879. {
  880. static int old_process_id[2] = { -1, -1 };
  881. char* relate_processes[2] = {"sogouImeWebSrv", "sogouImeService"};
  882. int count = 3;
  883. alive_process_info processes[3];
  884. memset(processes, 0, sizeof(processes));
  885. osutil_detect_unique_app(relate_processes, array_size(relate_processes), &count, processes);
  886. CAutoArray<CSimpleStringA> msgs(array_size(relate_processes));
  887. int cnt(0);
  888. for (int i = 0; i < array_size(relate_processes); ++i) {
  889. int k = -1;
  890. for (int j = 0; j < count; ++j) {
  891. if (strcmp(processes[j].name, relate_processes[i]) == 0) {
  892. k = j;
  893. break;
  894. }
  895. }
  896. if (k != -1 && old_process_id[i] == -1) {
  897. old_process_id[i] = processes[k].pid;
  898. } else if (k != -1 && (processes[k].pid != old_process_id[i])) {
  899. msgs[cnt++] = CSimpleStringA::Format("{\"name\":\"%s\", \"prev\":%d, \"pid\":%d}"
  900. , relate_processes[i], old_process_id[i], processes[k].pid);
  901. old_process_id[i] = processes[k].pid;
  902. } else if(k == -1 && old_process_id[i] != 0) {
  903. msgs[cnt++] = CSimpleStringA::Format("{\"name\":\"%s\", \"prev\":%d, \"pid\":%d}"
  904. , relate_processes[i], old_process_id[i], 0);
  905. old_process_id[i] = 0;
  906. }
  907. }
  908. if (cnt > 0) {
  909. std::string uploadInfo("");
  910. if (cnt > 1) {
  911. uploadInfo = "{";
  912. }
  913. for (int i = 0; i < cnt; ++i) {
  914. if (i != 0) {
  915. uploadInfo += ",";
  916. }
  917. uploadInfo += msgs[i].GetData();
  918. }
  919. if (cnt > 1) {
  920. uploadInfo += "}";
  921. }
  922. LogWarn(Severity_Middle, Error_Debug, LOG_RESOURCEWATCHER_SOGOU_PROCESS_STATUS_CHANGE, uploadInfo.c_str());
  923. }
  924. }
  925. //# all available outputs
  926. //OUTPUTS = $(xrandr | awk '$2 ~ /connected/ {print $1}')
  927. //echo outputs : $OUTPUTS
  928. //# get info from xrandr
  929. //XRANDR = `xrandr`
  930. //
  931. //connectedOutputs = $(echo "$XRANDR" | grep " connected" | sed - e "s/\([A-Z0-9]\+\) connected.*/\1/")
  932. //activeOutput = $(echo "$XRANDR" | grep - e " connected [^(]" | sed - e "s/\([A-Z0-9]\+\) connected.*/\1/")
  933. //connected = $(echo $connectedOutputs | wc - w)
  934. //echo connectedOutputs : ${ connectedOutputs }
  935. //echo activeOutput : ${ activeOutput }
  936. //echo connected : ${ connected }
  937. ErrorCodeEnum ResourceWatcherEntity::ConfigMonitorSetting(const UOS::MonitorInfo& config)
  938. {
  939. ErrorCodeEnum result(Error_Succeed);
  940. CSimpleStringA strExecute("xrandr");
  941. //Get monitor info
  942. do {
  943. std::string sucContent, failedContent;
  944. CSimpleStringA strCmd("xrandr | grep \" connected\" | sed -e \"s/\([A-Z0-9]\+\) connected.*/\1/\"");
  945. bool ret = SP::Module::Util::ShelllExecute(strCmd.GetData(), sucContent, failedContent);
  946. Dbg("{%s}:{%s}{%s}", strCmd.GetData(), sucContent.c_str(), failedContent.c_str());
  947. } while (false);
  948. do {
  949. std::string sucContent, failedContent;
  950. CSimpleStringA strCmd("xrandr |awk '$2 ~ /connected/ {print $1}'");
  951. bool ret = SP::Module::Util::ShelllExecute(strCmd.GetData(), sucContent, failedContent);
  952. Dbg("{%s}:{%s}{%s}", strCmd.GetData(), sucContent.c_str(), failedContent.c_str());
  953. } while (false);
  954. CSimpleStringA strCmd(strExecute);
  955. if (!config.name.empty()) {
  956. strCmd += CSimpleStringA::Format(" --output %s", config.name.c_str());
  957. //Set resolution
  958. if (config.nResolutionX != 0 && config.nResolutionY != 0) {
  959. CSimpleStringA tmp = CSimpleStringA::Format(" --mode %dx%d", config.nResolutionX, config.nResolutionY);
  960. strCmd += tmp;
  961. }
  962. if (config.refreshRate != 0) {
  963. CSimpleStringA tmp = CSimpleStringA::Format(" --rate %d", config.refreshRate);
  964. strCmd += tmp;
  965. }
  966. //set primary
  967. if (config.isPrimary) {
  968. strCmd += " --primary";
  969. } else if (config.posDirecttion != -1 && !config.other.empty()) {
  970. CSimpleStringA posDir(true);
  971. switch (config.posDirecttion) {
  972. case 0:
  973. posDir = "--same-as";
  974. case 1:
  975. posDir = "--above";
  976. break;
  977. case 2:
  978. posDir = "--right-of";
  979. break;
  980. case 3:
  981. posDir = "--above";
  982. break;
  983. case 4:
  984. posDir = "--left-of";
  985. break;
  986. default:
  987. result = Error_Param;
  988. break;
  989. }
  990. if (result == Error_Succeed) {
  991. CSimpleStringA tmp = CSimpleStringA::Format(" %s %s", posDir.GetData(), config.other.c_str());
  992. strCmd += tmp;
  993. }
  994. }
  995. }
  996. do
  997. {
  998. std::string sucContent, failedContent;
  999. bool ret = SP::Module::Util::ShelllExecute(strCmd.GetData(), sucContent, failedContent);
  1000. Dbg("{%s}:{%s}{%s}", strCmd.GetData(), sucContent.c_str(), failedContent.c_str());
  1001. } while (false);
  1002. do {
  1003. std::string sucContent, failedContent;
  1004. strCmd = strExecute;
  1005. bool ret = SP::Module::Util::ShelllExecute(strCmd.GetData(), sucContent, failedContent);
  1006. Dbg("{%s}:{%s}{%s}", strCmd.GetData(), sucContent.c_str(), failedContent.c_str());
  1007. } while (false);
  1008. return result;
  1009. }
  1010. std::vector<std::string> ResourceWatcherEntity::GetUserNameList(bool bExcludeRoot)
  1011. {
  1012. std::vector<std::string> results;
  1013. array_header_t* arr;
  1014. arr = fileutil_get_sub_dirs_a("/home");
  1015. if (arr) {
  1016. int i;
  1017. for (i = 0; i < arr->nelts; ++i) {
  1018. char szDestSubDir[256] = { 0 };
  1019. char* dir = ARRAY_IDX(arr, i, char*);
  1020. Dbg("sub dir: %s", dir);
  1021. strcpy(szDestSubDir, dir);
  1022. strcat(szDestSubDir, SPLIT_SLASH_STR);
  1023. strcat(szDestSubDir, ".config/kwinrc");
  1024. if (ExistsFileA(szDestSubDir)) {
  1025. std::string strUserName((const char*)&dir[strlen("/home/")]);
  1026. Dbg("username:%s", strUserName.c_str());
  1027. if (strUserName.compare("root") != 0 || !bExcludeRoot) {
  1028. results.push_back(strUserName);
  1029. }
  1030. }
  1031. }
  1032. toolkit_array_free2(arr);
  1033. }
  1034. return results;
  1035. }
  1036. SP_BEGIN_ENTITY_MAP()
  1037. SP_ENTITY(ResourceWatcherEntity)
  1038. SP_END_ENTITY_MAP()