upload.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591
  1. #include "stdafx.h"
  2. #include "SpBase.h"
  3. #include "SpIni.h"
  4. #include "upload.h"
  5. #include <memutil.h>
  6. #include <fileutil.h>
  7. #include <array.h>
  8. #include "XZip.h"
  9. #include <tchar.h>
  10. #include <string>
  11. #include "sstream"
  12. #include "ZipZilb.h"
  13. #include "stdio.h"
  14. using namespace std;
  15. //获取文件夹实际路径
  16. static ErrorCodeEnum expand_dir(IEntityFunction *pEntityFunc, const char *str, CSimpleStringA &out)
  17. {
  18. ErrorCodeEnum Error = Error_Unexpect;
  19. if (str) {
  20. const char *p = str;
  21. const char *sfirst;
  22. int first = 0;
  23. char tmp[1024];
  24. int k = 0;
  25. while (*p) {
  26. if (first) {
  27. if (*p == ')') {
  28. char key[MAX_PATH];
  29. key[0] = 0;
  30. CSimpleStringA strKeyPath;;
  31. memcpy(key, sfirst, p - sfirst);
  32. key[p-sfirst] = 0;
  33. Error = pEntityFunc->GetPath(key, strKeyPath);
  34. if (Error != Error_Succeed) {
  35. Dbg("sys path $(%s)$ cannot evaluate!", key);
  36. return Error;
  37. }
  38. strcpy(&tmp[k], (LPCSTR)strKeyPath);\
  39. k += strKeyPath.GetLength();
  40. first = 0;
  41. }
  42. } else {
  43. if (*p == '$' && *(p+1) == '(') {
  44. p++;
  45. first = 1;
  46. sfirst = p+1;
  47. } else {
  48. tmp[k++] = *p;
  49. }
  50. }
  51. p++;
  52. }
  53. if (k != 0) {
  54. tmp[k] = 0;
  55. out = tmp;
  56. return Error_Succeed;
  57. }
  58. } else {
  59. return Error_Param;
  60. }
  61. return Error;
  62. }
  63. static upload_dir_t *upload_dir_load(IEntityFunction *pEntityFunc, IConfigInfo *pConfig, const char *dir, int default_silent_time, int default_limitation)
  64. {
  65. upload_dir_t *updir = ZALLOC_T(upload_dir_t);
  66. if (updir)
  67. {
  68. char tmp[MAX_PATH];
  69. CSimpleStringA str;
  70. ErrorCodeEnum Error = pConfig->ReadConfigValue(dir, "Path", str);
  71. if (Error == Error_Succeed)
  72. {
  73. INIT_LIST_HEAD(&updir->candidate_list);
  74. CSimpleStringA strRealPath;
  75. Error = expand_dir(pEntityFunc, (LPCSTR)str, strRealPath);
  76. if (Error == Error_Succeed)
  77. {
  78. INIT_LIST_HEAD(&updir->candidate_list);
  79. updir->name = _strdup(dir);
  80. updir->path = _strdup(strRealPath);
  81. pConfig->ReadConfigValue(dir, "MovePath", str);
  82. if (str.GetLength() > 0)
  83. {
  84. updir->flags |= UPLOAD_FLAG_MOVEPATH;
  85. Error = expand_dir(pEntityFunc, str, strRealPath);
  86. if (Error != Error_Succeed)
  87. {
  88. return NULL;
  89. }
  90. updir->movepath = _strdup(strRealPath);
  91. } else {
  92. pConfig->ReadConfigValue(dir, "AutoDelete", str);
  93. if (_stricmp(str, "true") == 0)
  94. {
  95. updir->flags |= UPLOAD_FLAG_AUTODELETE;
  96. }
  97. }
  98. pConfig->ReadConfigValue(dir, "Zip", str);
  99. if (_stricmp(str, "true") == 0)
  100. {
  101. updir->flags |= UPLOAD_FLAG_ZIP;
  102. }
  103. pConfig->ReadConfigValueInt(dir, "SilentTime", updir->silent_time);
  104. if (updir->silent_time == 0)
  105. {
  106. updir->silent_time = default_silent_time;
  107. }
  108. pConfig->ReadConfigValueInt(dir, "Limitation", updir->child_count_limitation);
  109. if (updir->child_count_limitation == 0)
  110. {
  111. updir->child_count_limitation = default_limitation;
  112. }
  113. updir->fileCount=0;//初始化设置为0
  114. updir->fileLenSum=0;//初始化设置为0
  115. }
  116. }
  117. }
  118. return updir;
  119. }
  120. static void upload_dir_clear_candidate_list(upload_dir_t *updir);
  121. static void file_destroy(file_t *file)
  122. {
  123. free(file->name);
  124. free(file->path);
  125. free(file);
  126. }
  127. void upload_file_destroy(file_t *file)
  128. {
  129. file_destroy(file);
  130. }
  131. void updir_del_file(file_t *file)
  132. {
  133. (file->owner->fileCount)--;//文件夹文件个数减1
  134. file->owner->fileLenSum=file->owner->fileLenSum-file->length/1024;//减去文件长度
  135. list_del(&file->entry);//从链表删除文件
  136. upload_file_destroy(file);//删除文件内存
  137. }
  138. //初始化要上传的文件夹配置
  139. int upload_create(struct list_head *list, IEntityFunction *pEntityFunc, IConfigInfo *pConfig, CSimpleStringA &checkDir)
  140. {
  141. assert(list_empty(list));
  142. assert(pConfig);
  143. ErrorCodeEnum Error;
  144. char type_str[1024];
  145. char *p, *c;
  146. int default_silent_time = 0;
  147. int default_limitation = 0;
  148. {
  149. CSimpleStringA str;
  150. Error = pConfig->ReadConfigValue("Main", "Type", str);
  151. if (Error == Error_Succeed)
  152. {
  153. strcpy(type_str, (LPCSTR)str);
  154. }
  155. else
  156. {
  157. return Error;
  158. }
  159. //添加lwt,读入日结时需要检查的文件类型参数
  160. Error = pConfig->ReadConfigValue("Main", "CheckType", str);
  161. if (Error == Error_Succeed)
  162. {
  163. checkDir = str;
  164. }
  165. else
  166. {
  167. return Error;
  168. }
  169. pConfig->ReadConfigValueInt("Main", "SilentTime", default_silent_time);//间隔时间
  170. pConfig->ReadConfigValueInt("Main", "Limitation", default_limitation);//最大文件数
  171. if (default_limitation == 0)
  172. {
  173. default_limitation = INT_MAX;
  174. }
  175. }
  176. p = strtok_s(type_str, ", ", &c);
  177. while (p) {
  178. upload_dir_t *dir = upload_dir_load(pEntityFunc, pConfig, p, default_silent_time, default_limitation);
  179. if (!dir)
  180. {
  181. return Error_Unexpect;
  182. }
  183. Dbg("load %s ok", p);
  184. list_add_tail(&dir->entry, list);
  185. p = strtok_s(NULL, ", ", &c);
  186. }
  187. return 0;
  188. }
  189. static int updir_exist_file(upload_dir_t *dir, const char *path)
  190. {
  191. file_t *pos;
  192. list_for_each_entry(pos, &dir->candidate_list, file_t, entry) {
  193. if (_stricmp(pos->path, path) == 0)
  194. return TRUE;
  195. }
  196. return FALSE;
  197. }
  198. #define FT_2000_1_1_0_0_0 125911584000000000UL
  199. static int check_zero_ref(const char *path)
  200. {
  201. HANDLE hFile = CreateFileA(path,
  202. GENERIC_READ, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); // try open
  203. if (hFile != INVALID_HANDLE_VALUE) {
  204. CloseHandle(hFile);
  205. return TRUE;
  206. } else {
  207. DWORD dwRet = GetLastError();
  208. return FALSE;
  209. }
  210. }
  211. static void updir_add_file(upload_dir_t *dir, const char *path)
  212. {
  213. WIN32_FILE_ATTRIBUTE_DATA attr;
  214. if (GetFileAttributesExA(path, GetFileExInfoStandard, &attr))
  215. {
  216. file_t *f = ZALLOC_T(file_t);
  217. if (f)
  218. {
  219. int offset = strlen(dir->path);
  220. if (dir->path[offset-1] != '\\')
  221. offset++;
  222. f->path = _strdup(path);
  223. f->name = _strdup(path + offset);
  224. f->owner = dir;
  225. char *p = f->name;
  226. while (p = strchr(p, '\\'))
  227. {
  228. *p = '$';
  229. }
  230. union
  231. {
  232. FILETIME ft;
  233. unsigned __int64 v;
  234. }u;
  235. u.ft.dwHighDateTime = attr.ftCreationTime.dwHighDateTime;
  236. u.ft.dwLowDateTime = attr.ftCreationTime.dwLowDateTime;
  237. f->create_time = (unsigned int)((u.v - FT_2000_1_1_0_0_0) / 10000000UL);
  238. f->length = attr.nFileSizeLow;
  239. if (strcmp(dir->name,"Debug") == 0)
  240. {
  241. string str(f->path);
  242. if ( str.substr(str.find_last_of('.')+1,str.length())!="zip")
  243. {
  244. if(attr.nFileSizeHigh>0||attr.nFileSizeLow>200*1024*1024)
  245. {
  246. //删文件
  247. Dbg("file %s name(%s) lenth (nFileSizeHigh=%d,nFileSizeLow=%d) is over 200m,prepare delete!", f->path, f->name,attr.nFileSizeHigh,attr.nFileSizeLow);
  248. WORD dwAttr = GetFileAttributesA(f->path);
  249. dwAttr &= ~FILE_ATTRIBUTE_READONLY;
  250. SetFileAttributesA(f->path, dwAttr);
  251. DeleteFileA(f->path);
  252. Dbg("file %s name(%s) lenth is over 200m,delete !", f->path, f->name);
  253. return;
  254. }
  255. string createtime;
  256. ostringstream oss;
  257. oss<<f->create_time;
  258. createtime = oss.str();
  259. str = str.substr(0,str.find_last_of('.'))+"&"+createtime+"."+"zip";
  260. if (ZipData((LPCTSTR)str.c_str(),(LPCTSTR)f->path))
  261. {
  262. //delete source file
  263. WORD dwAttr = GetFileAttributesA(f->path);
  264. dwAttr &= ~FILE_ATTRIBUTE_READONLY;
  265. SetFileAttributesA(f->path, dwAttr);
  266. DeleteFileA(f->path);
  267. //insert zip file info
  268. string name(f->name);
  269. name = name.substr(0,name.find_last_of('.')+1)+"zip";
  270. f->name = _strdup(name.c_str());
  271. f->path = _strdup(str.c_str());
  272. WIN32_FILE_ATTRIBUTE_DATA attr;
  273. if (GetFileAttributesExA(f->path, GetFileExInfoStandard, &attr))
  274. {
  275. f->length = attr.nFileSizeLow;
  276. }
  277. }
  278. }
  279. else
  280. {
  281. string createdata(f->path);
  282. std::size_t found = createdata.find('&');
  283. if (found!=std::string::npos)
  284. {
  285. int index0 = createdata.find_last_of('\\')+1;
  286. int index = createdata.find_last_of('&');
  287. int index2 = createdata.find_last_of('.');
  288. string filetime = createdata.substr(index0,index-index0);
  289. createdata = createdata.substr(index+1,index2-index);
  290. string fullname(f->name);
  291. //Dbg("get full name = %s",fullname.c_str());
  292. string name = fullname.substr(0,fullname.find_last_of('$')+1)+filetime+"."+"zip";
  293. //Dbg("upload name = %s",name.c_str());
  294. f->name = _strdup(name.c_str());
  295. f->create_time = atoi(createdata.c_str());
  296. }
  297. }
  298. }
  299. //把文件按照时间从小到大排序放置
  300. file_t *pos;
  301. list_for_each_entry(pos, &dir->candidate_list, file_t, entry)
  302. {
  303. if (f->create_time < pos->create_time)
  304. {
  305. __list_add(&f->entry, pos->entry.prev, &pos->entry);
  306. (dir->fileCount)++;//文件夹文件个数加1
  307. dir->fileLenSum=dir->fileLenSum+f->length/1024; //统计传送文件长度
  308. Dbg("::file %s name(%s) added!", f->path, f->name);
  309. return;
  310. }
  311. }
  312. Dbg("file %s name(%s) added!", f->path, f->name);
  313. list_add_tail(&f->entry, &dir->candidate_list);//把文件加入要上传的列表
  314. (dir->fileCount)++;//文件夹文件个数加1
  315. dir->fileLenSum=dir->fileLenSum+f->length/1024; //统计传送文件长度
  316. }
  317. }
  318. }
  319. static void dir_fresh(upload_dir_t *dir, const char *path)
  320. {
  321. array_header_t *arr_files = fileutil_get_sub_files2_a(path, dir->child_count_limitation);
  322. if (arr_files) {
  323. int i;
  324. for (i = 0; i < arr_files->nelts; ++i)
  325. {
  326. char *file_path = ARRAY_IDX(arr_files, i, char*);
  327. WIN32_FILE_ATTRIBUTE_DATA attr;
  328. if (GetFileAttributesExA(file_path, GetFileExInfoStandard, &attr))
  329. {
  330. SYSTEMTIME st;
  331. SYSTEMTIME filest;
  332. FILETIME ft;
  333. FILETIME fttmp;
  334. GetLocalTime(&st);
  335. SystemTimeToFileTime(&st, &ft);
  336. if (CompareFileTime(&ft, &attr.ftLastWriteTime) > 0)
  337. {
  338. //LARGE_INTEGER *p1 = (LARGE_INTEGER *)&attr.ftLastWriteTime;
  339. FileTimeToLocalFileTime(&attr.ftLastWriteTime,&fttmp);
  340. FileTimeToSystemTime(&fttmp,&filest);
  341. LARGE_INTEGER *p2 = (LARGE_INTEGER *)&ft;
  342. LARGE_INTEGER *p1 = (LARGE_INTEGER *)&fttmp;
  343. LONGLONG diff = p2->QuadPart - p1->QuadPart;
  344. diff = diff / 10000000L; // convert to seconds FILETIME是以100纳秒(ns)为单位
  345. //if silent_time == 1 days
  346. if (dir->silent_time >= 86400)
  347. {
  348. int nsecondsInterval = (st.wYear-filest.wYear)*32140800+(st.wMonth-filest.wMonth)*2678400+(st.wDay-filest.wDay)*86400;
  349. if((nsecondsInterval>=dir->silent_time))
  350. {
  351. if (check_zero_ref(file_path))
  352. {
  353. if (!updir_exist_file(dir, file_path))
  354. {
  355. updir_add_file(dir, file_path);
  356. }
  357. }
  358. //Dbg("addfile %s added! diff:%d", file_path,nsecondsInterval);
  359. }
  360. }
  361. else
  362. {
  363. if (diff >= dir->silent_time)
  364. {
  365. if (check_zero_ref(file_path))
  366. {
  367. if (!updir_exist_file(dir, file_path))
  368. {
  369. updir_add_file(dir, file_path);
  370. }
  371. }
  372. //Dbg("addfile %s added! diff:%d", file_path,diff);
  373. }
  374. }
  375. }
  376. else
  377. {
  378. Dbg("the time error!");
  379. }
  380. }
  381. }
  382. toolkit_array_free2(arr_files);
  383. }
  384. array_header_t *arr_dir = fileutil_get_sub_dirs_a(path);
  385. if (arr_dir) {
  386. int i;
  387. for (i = 0; i < arr_dir->nelts; ++i) {
  388. char *dir_path = ARRAY_IDX(arr_dir, i, char*);
  389. dir_fresh(dir, dir_path);
  390. }
  391. }
  392. }
  393. int upload_fresh(struct list_head *list)
  394. {
  395. upload_dir_t *pos;
  396. list_for_each_entry(pos, list, upload_dir_t, entry)
  397. {
  398. dir_fresh(pos, pos->path);
  399. }
  400. return 0;
  401. }
  402. int check_dir_fresh(const char *path,int limitation,int silentTime,int &fileSumlen){
  403. int count=0;//当前文件夹下面的文件个数
  404. int sum = 0;//当前文件夹下面的子文件夹下面的文件个数
  405. array_header_t *arr_files = fileutil_get_sub_files2_a(path, limitation);
  406. if (arr_files) {
  407. int i;
  408. for (i = 0; i < arr_files->nelts; ++i)
  409. {
  410. char *file_path = ARRAY_IDX(arr_files, i, char*);
  411. WIN32_FILE_ATTRIBUTE_DATA attr;
  412. if (GetFileAttributesExA(file_path, GetFileExInfoStandard, &attr))
  413. {
  414. SYSTEMTIME st;
  415. SYSTEMTIME filest;
  416. FILETIME ft;
  417. FILETIME fttmp;
  418. GetLocalTime(&st);
  419. SystemTimeToFileTime(&st, &ft);
  420. if (CompareFileTime(&ft, &attr.ftLastWriteTime) > 0)
  421. {
  422. //LARGE_INTEGER *p1 = (LARGE_INTEGER *)&attr.ftLastWriteTime;
  423. FileTimeToLocalFileTime(&attr.ftLastWriteTime,&fttmp);
  424. FileTimeToSystemTime(&fttmp,&filest);
  425. LARGE_INTEGER *p2 = (LARGE_INTEGER *)&ft;
  426. LARGE_INTEGER *p1 = (LARGE_INTEGER *)&fttmp;
  427. LONGLONG diff = p2->QuadPart - p1->QuadPart;
  428. diff = diff / 10000000L; // convert to seconds FILETIME是以100纳秒(ns)为单位
  429. //增加特殊文件不计入上传处理
  430. char* p=strstr(file_path,"SystemInitial.log");
  431. if(p!=NULL){
  432. continue;
  433. }
  434. p=strstr(file_path,"G_");
  435. if(p!=NULL){
  436. continue;
  437. }
  438. if (silentTime >= 86400)
  439. {
  440. int nsecondsInterval = (st.wYear-filest.wYear)*32140800+(st.wMonth-filest.wMonth)*2678400+(st.wDay-filest.wDay)*86400;
  441. if((nsecondsInterval>=silentTime))
  442. {
  443. //个数加1
  444. count++;
  445. //获取文件长度
  446. WIN32_FILE_ATTRIBUTE_DATA attr;
  447. if (GetFileAttributesExA(file_path, GetFileExInfoStandard, &attr))
  448. {
  449. int fileSize = attr.nFileSizeLow/1024;//单位为k
  450. fileSumlen+=fileSize;
  451. }else{
  452. }
  453. Dbg("checkfile %s ! diff:%d", file_path,nsecondsInterval);
  454. }
  455. }
  456. else
  457. {
  458. if (diff >= silentTime)
  459. {
  460. //个数加1
  461. count++;
  462. //获取文件长度
  463. WIN32_FILE_ATTRIBUTE_DATA attr;
  464. if (GetFileAttributesExA(file_path, GetFileExInfoStandard, &attr))
  465. {
  466. int fileSize = attr.nFileSizeLow/1024;//单位为k
  467. fileSumlen+=fileSize;
  468. }else{
  469. }
  470. Dbg("checkfile %s ! diff:%d", file_path,diff);
  471. }
  472. }
  473. }
  474. else
  475. {
  476. Dbg("the time error!");
  477. }
  478. }
  479. }
  480. toolkit_array_free2(arr_files);
  481. }
  482. array_header_t *arr_dir = fileutil_get_sub_dirs_a(path);
  483. if (arr_dir) {
  484. int i;
  485. for (i = 0; i < arr_dir->nelts; ++i) {
  486. char *dir_path = ARRAY_IDX(arr_dir, i, char*);
  487. int fileLen=0;
  488. sum += check_dir_fresh(dir_path,limitation,silentTime,fileLen);
  489. fileSumlen=fileSumlen+fileLen;
  490. }
  491. }
  492. count = sum+count;
  493. return count;
  494. }
  495. bool ZipData(LPCTSTR lpszZipArchive, LPCTSTR lpszSrcFile)
  496. {
  497. BOOL bResult = TRUE;
  498. if (!lpszZipArchive)
  499. {
  500. Dbg("lpszZipArchive is NULL");
  501. return false;
  502. }
  503. if (!lpszSrcFile )
  504. {
  505. Dbg("lpszSrcFile is NULL");
  506. return false;
  507. }
  508. // does zip source file exist?
  509. //if (_waccess((wchar_t *)lpszSrcFile, 0) == -1)
  510. //{
  511. // Dbg("WARNING: zip source file '%s' cannot be found,operation aborted",lpszSrcFile);
  512. // return false;
  513. //}
  514. // use only the file name for zip file entry
  515. TCHAR * cp = (TCHAR *)_tcsrchr(lpszSrcFile, _T('\\'));
  516. if (cp == NULL)
  517. cp = (TCHAR *) lpszSrcFile;
  518. else
  519. cp++;
  520. HZIP hz = CreateZip((void *)lpszZipArchive, 0, ZIP_FILENAME);
  521. if (hz)
  522. {
  523. ZRESULT zr = ZipAdd(hz, cp, (void *)lpszSrcFile, 0, ZIP_FILENAME);
  524. CloseZip(hz);
  525. // did add work?
  526. if (zr == ZR_OK)
  527. {
  528. //Dbg("added '%s' to zip file '%s'",lpszSrcFile, lpszZipArchive);
  529. bResult = true;
  530. }
  531. else
  532. {
  533. Dbg("WARNING: failed to add zip source file '%s'",lpszSrcFile);
  534. bResult = false;
  535. }
  536. }
  537. else
  538. {
  539. Dbg("ERROR: failed to create zip file '%s'",lpszZipArchive);
  540. bResult = false;
  541. }
  542. return bResult;
  543. }