FtpdPi.cpp
上传用户:shengde
上传日期:2007-02-26
资源大小:117k
文件大小:36k
源码类别:

Ftp服务器

开发平台:

Visual C++

  1. #include "stdafx.h"
  2. #include "CFtpd.h"
  3. #include "FtpdPi.h"
  4. #define CRLF "rn"
  5. #ifdef _DEBUG
  6. #define new DEBUG_NEW
  7. #undef THIS_FILE
  8. static char THIS_FILE[] = __FILE__;
  9. #endif
  10. char sadr2[32];
  11. bool canclePasvListenSocket(CFtpPasvSrv* sck)
  12. {
  13. try
  14. {
  15. sck->Close();
  16. delete sck;
  17. return true;
  18. }
  19. catch(...)
  20. {
  21. }
  22. return false;
  23. }
  24. bool deleFtpPI(CFtpdPi* sck)
  25. {
  26. try
  27. {
  28. CFtpd* K = (CFtpd*) sck->pFtpd;
  29. K->RemoveClient(sck);
  30. }
  31. catch(...)
  32. {
  33. }
  34. return true;
  35. }
  36. UINT thFtpCmd( LPVOID pParam )
  37. {
  38. ((CFtpdPi*)pParam)->ProcessMsg(((CFtpdPi*)pParam)->bufcmd);
  39. return 1;
  40. }
  41. UINT thSendData( LPVOID pParam)
  42. {
  43. CFtpdPi* pFtpBind = (CFtpdPi*) pParam;
  44. CFile* inFile = NULL;
  45. try
  46. {
  47. char path[256] = "";
  48. strcpy(path,pFtpBind->RemoveLeadingSpace(pFtpBind->curCmdth+5));
  49. char srcPath[300] = "";
  50. if(strcmp(pFtpBind->vCurrentDir,"/")==0)
  51. wsprintf(srcPath,"%s%s%s",pFtpBind->vRealRoot,pFtpBind->vCurrentDir,path);
  52. else
  53. wsprintf(srcPath,"%s%s\%s",pFtpBind->vRealRoot,pFtpBind->vCurrentDir,path);
  54. pFtpBind->slashFix(srcPath);
  55. if(pFtpBind->isFilePresent(path))
  56. {
  57. bool b_opened = true;
  58. try
  59. {
  60. if(pFtpBind->type == 1)
  61. inFile = new CFile(srcPath,CFile::modeRead|CFile::shareDenyNone|CFile::typeBinary);//CStdioFile(srcPath,CFile::modeRead|CFile::shareDenyNone|CFile::typeText);
  62. else if(pFtpBind->type == 3)
  63. inFile = new CFile(srcPath,CFile::modeRead|CFile::shareDenyNone|CFile::typeBinary);
  64. }
  65. catch(...)
  66. {
  67. b_opened = false;
  68. }
  69. if(b_opened)
  70. {
  71. long flen = inFile->GetLength(); 
  72. if(pFtpBind->restart_marker > 0)
  73. {
  74. inFile->Seek(pFtpBind->restart_marker,CFile::begin);
  75. pFtpBind->restart_marker = 0;
  76. }
  77. long nCount = 0;
  78. if(pFtpBind->type == 1)
  79. wsprintf(pFtpBind->str,"150 Sending %s (%u bytes). Mode STREAM Type ASCII%s",path,flen,CRLF);
  80. else if(pFtpBind->type == 3)
  81. wsprintf(pFtpBind->str,"150 Sending %s (%u bytes). Mode STREAM Type BINARY%s",path,flen,CRLF);
  82. pFtpBind->Send(pFtpBind->str,strlen(pFtpBind->str),0);
  83. if(flen)
  84. {
  85. long bytesent = 0;
  86. long offset = 0;
  87. DWORD start,end;
  88. do
  89. {
  90. if(flen > pFtpBind->m_buf_length_out)
  91. nCount = inFile->Read(pFtpBind->lpDataBuf_out,pFtpBind->m_buf_length_out);
  92. else
  93. nCount = inFile->Read(pFtpBind->lpDataBuf_out,flen);
  94. flen = flen - nCount;
  95. if(pFtpBind->b_speed_limit_out)
  96. {
  97. bytesent = 0; 
  98. offset = 0;
  99. HANDLE h = CreateEvent(NULL,false,false,"noname");
  100. do
  101. {
  102. start = GetTickCount();
  103. if((nCount-offset) > pFtpBind->m_buf_length_out)
  104. bytesent = pFtpBind->dbsocket->Send((char*)pFtpBind->lpDataBuf_out+offset,pFtpBind->m_buf_length_out,60);
  105. else
  106. bytesent = pFtpBind->dbsocket->Send((char*)pFtpBind->lpDataBuf_out+offset,nCount-offset,60);
  107. offset = offset + bytesent;
  108. end = GetTickCount();
  109. if((end-start) < 1000)
  110. {
  111. int time = end-start;
  112. WaitForSingleObject(h,1000-time);
  113. }
  114. }while(offset < nCount);
  115. }
  116. else
  117. {
  118. bytesent = 0; 
  119. offset = 0;
  120. do
  121. {
  122. if((nCount-offset) > pFtpBind->m_buf_length_out)
  123. bytesent = pFtpBind->dbsocket->Send((char*)pFtpBind->lpDataBuf_out+offset,pFtpBind->m_buf_length_out,60);
  124. else
  125. bytesent = pFtpBind->dbsocket->Send((char*)pFtpBind->lpDataBuf_out+offset,nCount-offset,60);
  126. offset = offset + bytesent;
  127. }while(offset < nCount);
  128. if(pFtpBind->type == 1)
  129. {
  130. pFtpBind->dbsocket->Send(CRLF,2,60);
  131. }
  132. }
  133. }while(flen != 0);
  134. }
  135. pFtpBind->dbsocket->Close();
  136. if(pFtpBind->b_passive)
  137. pFtpBind->svSocketSrv->Close();
  138. delete inFile;
  139. wsprintf(pFtpBind->str,"226 Transfer finished successfully. Data connection closed.%s",CRLF);
  140. pFtpBind->Send(pFtpBind->str,strlen(pFtpBind->str),0);
  141. SetEvent(pFtpBind->h_inprogress);
  142. return true;
  143. }else
  144. {
  145. pFtpBind->dbsocket->Close();
  146. if(pFtpBind->b_passive)
  147. pFtpBind->svSocketSrv->Close();
  148. if(inFile != NULL)
  149. delete inFile;
  150. wsprintf(pFtpBind->str,"426 Connection closed , file opening failed%s",CRLF);
  151. pFtpBind->Send(pFtpBind->str,strlen(pFtpBind->str),0);
  152. SetEvent(pFtpBind->h_inprogress);
  153. }
  154. }
  155. }catch(...)
  156. {
  157. inFile->Close();
  158. pFtpBind->dbsocket->Close();
  159. canclePasvListenSocket(pFtpBind->svSocketSrv);
  160. delete inFile;
  161. wsprintf(pFtpBind->str,"426 Connection closed; transfer aborted (transfer failed)%s",CRLF);
  162. pFtpBind->Send(pFtpBind->str,strlen(pFtpBind->str),0);
  163. SetEvent(pFtpBind->h_inprogress);
  164. return false;
  165. }
  166. return true;
  167. }
  168. CFtpdPi::CFtpdPi()
  169. {
  170. clientIpCount = 0;
  171. type = 3; //1 = ascii 2 = ebcdic 3 = binary
  172. ipRoller = 0;
  173. b_use_bsock = true;
  174. b_verbose = true;
  175. b_passive = false;
  176. b_bell = false;
  177. b_prompt = true;
  178. b_globbing = true;
  179. b_debugging = false;
  180. b_hashmark = false;
  181. bLOGINOK = false;
  182. bUSER = false;
  183. bPASS = false;
  184. b_speed_limit_out = false;
  185. b_speed_limit_in = false;
  186. restart_marker = 0;
  187. strcpy(vCurrentDir,"/");
  188. strcpy(old_filename,"");
  189. strcpy(new_filename,"");
  190. strcpy(m_group,"nogroup");
  191. m_buf_length_out = 32768;
  192. m_buf_length_in = 32768;
  193. lpDataBuf_out = (unsigned char*) malloc(m_buf_length_out);
  194. memset(lpDataBuf_out,0,m_buf_length_out);
  195. lpDataBuf_in = (unsigned char*) malloc(m_buf_length_in);
  196. memset(lpDataBuf_in,0,m_buf_length_in);
  197. strcpy(monthStr[1],"Jan");
  198. strcpy(monthStr[2],"Feb");
  199. strcpy(monthStr[3],"Mar");
  200. strcpy(monthStr[4],"Apr");
  201. strcpy(monthStr[5],"May");
  202. strcpy(monthStr[6],"Jun");
  203. strcpy(monthStr[7],"Jul");
  204. strcpy(monthStr[8],"Aug");
  205. strcpy(monthStr[9],"Sep");
  206. strcpy(monthStr[10],"Oct");
  207. strcpy(monthStr[11],"Dec");
  208. strcpy(monthStr[12],"Nov");
  209. sl = sizeof(SOCKADDR_IN);
  210. GetLocalTime(&MyTime);
  211. if(FileExists(ipfile))
  212. LoadIpRange();
  213. h_inprogress = CreateEvent(NULL,false,true,"in_progress");
  214. h_dbsocket_ready_to_send = CreateEvent(NULL,false,false,"in_progress");
  215. dbsocket = NULL;
  216. svSocketSrv = NULL;
  217. }
  218. CFtpdPi::~CFtpdPi()
  219. {
  220. free(lpDataBuf_in);
  221. free(lpDataBuf_out);
  222. if(dbsocket != NULL)
  223. {
  224. dbsocket->Close();
  225. delete dbsocket;
  226. }
  227. if(svSocketSrv != NULL)
  228. {
  229. svSocketSrv->Close();
  230. delete svSocketSrv;
  231. }
  232. }
  233. // Do not edit the following lines, which are needed by ClassWizard.
  234. #if 0
  235. BEGIN_MESSAGE_MAP(CFtpdPi, CSocket)
  236. //{{AFX_MSG_MAP(CFtpdPi)
  237. //}}AFX_MSG_MAP
  238. END_MESSAGE_MAP()
  239. #endif // 0
  240. void CFtpdPi::OnReceive(int nErrorCode) 
  241. {
  242. unsigned char* bufnow = (unsigned char*)malloc(256);
  243. try
  244. {
  245. memset(bufnow,NULL,256);
  246. result = Receive(bufnow,256,0);
  247. bool cont = true;
  248. int currentPos = 0;
  249. if(*(bufnow+1)==0xf2)
  250. currentPos = 1;
  251. for(int i=0;i<result;i++)
  252. {
  253. if(*(bufnow+i)==0x0d&&*(bufnow+i+1)==0x0a)
  254. {
  255. strncpy(bufcmd,(char*)bufnow+currentPos,i-currentPos);
  256. *(bufcmd+i-currentPos) = NULL;
  257. strcpy(bufcmd_history,bufcmd);
  258. AfxBeginThread(&thFtpCmd,this,THREAD_PRIORITY_NORMAL,0,0,NULL);
  259. currentPos = i+2;
  260. i = i + 1;
  261. }
  262. }
  263. free(bufnow);
  264. }
  265. catch (...)
  266. {
  267. delete bufnow;
  268. char lpMsgBuf[128]="";
  269. DWORD eRRR = GetLastError();
  270. FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,NULL,eRRR,0,lpMsgBuf,128,NULL);
  271. char ecp[256]="";
  272. wsprintf(ecp,"%s\core.ftpd",AppDir);
  273. CStdioFile ofs((LPCTSTR) ecp ,CFile::modeWrite|CFile::modeCreate);
  274. ofs.WriteString("*---------------------------------------------------------------------------n");
  275. ofs.WriteString("Exception occurs while processing socket msgn");
  276. GetLocalTime(&MyTime);
  277. wsprintf(ecp,"Thread crashed at %.4d-%.2d-%.2d-%.2d-%.2dn",MyTime.wYear,MyTime.wMonth,MyTime.wDay,MyTime.wHour,MyTime.wMinute);
  278. ofs.WriteString(ecp);
  279. ofs.WriteString(lpMsgBuf);
  280. ofs.WriteString("*---------------------------------------------------------------------------n");
  281. ofs.Close();
  282. wsprintf(ecp,"Socket Exception occurs , aboarting current thread");
  283. }
  284. CSocket::OnReceive(nErrorCode);
  285. }
  286. void CFtpdPi::ProcessMsg(char *cmd)
  287. {
  288. char curCmd[256] = "";
  289. strcpy(curCmd,cmd);
  290. for(int k=0;k<=3;k++)
  291. {
  292. if(curCmd[k] != ' ')
  293. {
  294. curCmd[k] = toupper(curCmd[k]);
  295. }else
  296. k = 3;
  297. }
  298. if(!bLOGINOK)
  299. {
  300. if(strncmp("USER ",curCmd,5) == 0)
  301. {
  302. char username[256] = "";
  303. strcpy(username,RemoveLeadingSpace(curCmd+5));
  304. if(validuser(username) && strlen(username) <= 32)
  305. {
  306. strcpy(m_username,username);
  307. bUSER = true;
  308. wsprintf(str,"331 Password required for %s .%s",(LPCSTR)m_username,CRLF);
  309. SafeSend(str);
  310. }else
  311. {
  312. wsprintf(str,"530 Login incorrect for %s .%s",username,CRLF);
  313. SafeSend(str);
  314. }
  315. }else if(strncmp("PASS ",curCmd,5) == 0 && bUSER == true)
  316. {
  317. char password[256] = "";
  318. strcpy(password,RemoveLeadingSpace(curCmd+5));
  319. if(matchpass(password,(char*)(LPCSTR)m_username) && strlen(password) <= 32)
  320. {
  321. strcpy(m_password,password);
  322. bPASS = true;
  323. }else
  324. {
  325. wsprintf(str,"530 Password incorrect.%s",CRLF);
  326. SafeSend(str);
  327. }
  328. }
  329. if(bUSER && bPASS)
  330. {
  331. bLOGINOK = true;
  332. wsprintf(str,"230 User %s logged in , proceed%s",(LPCSTR)m_username,CRLF);
  333. SafeSend(str);
  334. }
  335. }else
  336. {
  337. if(stricmp("XPWD",curCmd) == 0 || stricmp("PWD",curCmd) == 0)
  338. {
  339. if(strlen(vCurrentDir) > 500)
  340. wsprintf(str,"503 current directory is too long.%s",CRLF);
  341. else
  342. wsprintf(str,"257 "%s" is current directory%s",vCurrentDir,CRLF);
  343. SafeSend(str);
  344. return;
  345. }
  346. else if(strncmp("CWD ",curCmd,4) == 0)
  347. {
  348. char path[512] = "";
  349. strcpy(path,RemoveLeadingSpace(curCmd+4));
  350. if(strcmp(path,"..")==0)
  351. {
  352. if(goParent(vCurrentDir))
  353. wsprintf(str,"250 "%s" is current directory.%s",vCurrentDir,CRLF);
  354. else
  355. wsprintf(str,"550 Permission denied.%s",CRLF);
  356. }else if(strcmp(path,".")==0)
  357. wsprintf(str,"250 "%s" is current directory.%s",vCurrentDir,CRLF);
  358. else
  359. {
  360. fixVpath(path);
  361. if(isVpathPresent(path))
  362. {
  363. strcpy(vCurrentDir,path);
  364. wsprintf(str,"250 "%s" is current directory.%s",vCurrentDir,CRLF);
  365. }else
  366. wsprintf(str,"550 Permission denied.%s",CRLF);
  367. }
  368. SafeSend(str);
  369. return;
  370. }
  371. else if(strncmp("CDUP",curCmd,4) == 0)
  372. {
  373. if(goParent(vCurrentDir))
  374. wsprintf(str,"250 "%s" is current directory.%s",vCurrentDir,CRLF);
  375. else
  376. wsprintf(str,"550 Permission denied.%s",CRLF);
  377. SafeSend(str);
  378. return;
  379. }
  380. else if(strcmp("REIN",curCmd) == 0)
  381. {
  382. bUSER = false;
  383. bPASS = false;
  384. bLOGINOK = false;
  385. wsprintf(str,"550 Relogin required , connection reinitialized.%s",CRLF);
  386. SafeSend(str);
  387. return;
  388. }
  389. else if(strncmp("DELE ",curCmd,5) == 0)
  390. {
  391. char path[512] = "";
  392. strcpy(path,RemoveLeadingSpace(curCmd+4));
  393. if(vRemove(path))
  394. wsprintf(str,"250 Requested file action ok , completed%s",CRLF);
  395. else
  396. {
  397. char lpMsgBuf[128]="";
  398. DWORD eRRR = GetLastError();
  399. FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,NULL,eRRR,0,lpMsgBuf,128,NULL);
  400. wsprintf(str,"553 Requested action not taken , %s",lpMsgBuf);
  401. }
  402. SafeSend(str);
  403. return;
  404. }
  405. else if(strncmp("XMKD ",curCmd,5) == 0)
  406. {
  407. char path[512] = "";
  408. strcpy(path,RemoveLeadingSpace(curCmd+5));
  409. if(vMkdir(path))
  410. wsprintf(str,"257 "%s" created%s",path,CRLF);
  411. else
  412. {
  413. char lpMsgBuf[128]="";
  414. DWORD eRRR = GetLastError();
  415. FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,NULL,eRRR,0,lpMsgBuf,128,NULL);
  416. wsprintf(str,"553 Requested action not taken , %s",lpMsgBuf);
  417. }
  418. SafeSend(str);
  419. return;
  420. }
  421. else if(strncmp("RETR ",curCmd,5) == 0)
  422. {
  423. strcpy(curCmdth,curCmd);
  424. AfxBeginThread(&thSendData,this,THREAD_PRIORITY_TIME_CRITICAL,0,0,NULL);
  425. return;
  426. }
  427. else if(strcmp("ABOR",curCmd) == 0)
  428. {
  429. try
  430. {
  431. dbsocket->Close();
  432. }
  433. catch(...)
  434. {
  435. }
  436. wsprintf(str,"426 Transfer aborted. Data connection closed.%s",CRLF);
  437. SafeSend(str);
  438. SetEvent(h_inprogress);
  439. wsprintf(str,"226 Abort successful.%s",CRLF);
  440. SafeSend(str);
  441. return;
  442. }
  443. else if(strncmp("STOR ",curCmd,5) == 0 || strncmp("STOU ",curCmd,5) == 0)
  444. {
  445. CFile* outFile;
  446. try
  447. {
  448. char path[256] = "";
  449. strcpy(path,RemoveLeadingSpace(curCmd+5));
  450. char srcPath[300] = "";
  451. if(strcmp(vCurrentDir,"/")==0)
  452. wsprintf(srcPath,"%s%s%s",vRealRoot,vCurrentDir,path);
  453. else
  454. wsprintf(srcPath,"%s%s\%s",vRealRoot,vCurrentDir,path);
  455. slashFix(srcPath);
  456. if(isFilePresent(path) && strncmp("STOU ",curCmd,5) == 0)
  457. {
  458. dbsocket->Close();
  459. wsprintf(str,"426 Connection closed; transfer aborted (target file already existed)%s",CRLF);
  460. SafeSend(str);
  461. }
  462. else
  463. {
  464. bool b_opened = true;
  465. try
  466. {
  467. if(type == 1)
  468. outFile = new CStdioFile(srcPath,CFile::modeWrite|CFile::modeNoTruncate|CFile::typeText|CFile::modeCreate);
  469. else if(type == 3)
  470. outFile = new CFile(srcPath,CFile::modeWrite|CFile::modeNoTruncate|CFile::typeBinary|CFile::modeCreate);
  471. }
  472. catch(...)
  473. {
  474. b_opened = false;
  475. }
  476. if(b_opened)
  477. {
  478. long flen = 0;
  479. long nCount = 0;
  480. if(type == 1)
  481. wsprintf(str,"150 Opening ASCII data connection for %s%s",path,CRLF);
  482. else if(type == 3)
  483. wsprintf(str,"150 Opening BINARY data connection for %s%s",path,CRLF);
  484. SafeSend(str);
  485. DWORD start,end;
  486. HANDLE h = CreateEvent(NULL,false,false,"noname");
  487. do
  488. {
  489. start = GetTickCount();
  490. nCount = dbsocket->Receive((char*)lpDataBuf_in,m_buf_length_in,60);
  491. outFile->Write(lpDataBuf_in,nCount);
  492. end = GetTickCount();
  493. if(b_speed_limit_in)
  494. {
  495. if((end-start) < 1000)
  496. {
  497. int time = end-start;
  498. WaitForSingleObject(h,((1000-time)*nCount)/m_buf_length_in);
  499. }
  500. }
  501. }while(nCount > 0);
  502. dbsocket->Close();
  503. if(b_passive)
  504. svSocketSrv->Close();
  505. delete outFile;
  506. wsprintf(str,"226 Transfer finished successfully. Data connection closed.%s",CRLF);
  507. SafeSend(str);
  508. }else
  509. {
  510. outFile->Close();
  511. dbsocket->Close();
  512. if(b_passive)
  513. svSocketSrv->Close();
  514. delete outFile;
  515. wsprintf(str,"426 Connection closed; file opening failed%s",CRLF);
  516. SafeSend(str);
  517. }
  518. }
  519. }
  520. catch(...)
  521. {
  522. outFile->Close();
  523. dbsocket->Close();
  524. if(b_passive)
  525. svSocketSrv->Close();
  526. delete outFile;
  527. wsprintf(str,"426 Connection closed; transfer aborted (transfer failed)%s",CRLF);
  528. SafeSend(str);
  529. }
  530. SetEvent(h_inprogress);
  531. return;
  532. }
  533. else if(strncmp("APPE ",curCmd,5) == 0)
  534. {
  535. CFile* outFile;
  536. try
  537. {
  538. char path[256] = "";
  539. strcpy(path,RemoveLeadingSpace(curCmd+5));
  540. char srcPath[300] = "";
  541. if(strcmp(vCurrentDir,"/")==0)
  542. wsprintf(srcPath,"%s%s%s",vRealRoot,vCurrentDir,path);
  543. else
  544. wsprintf(srcPath,"%s%s\%s",vRealRoot,vCurrentDir,path);
  545. slashFix(srcPath);
  546. bool b_opened = true;
  547. try
  548. {
  549. if(type == 1)
  550. outFile = new CStdioFile(srcPath,CFile::modeWrite|CFile::modeNoTruncate|CFile::typeText|CFile::modeCreate);
  551. else if(type == 3)
  552. outFile = new CFile(srcPath,CFile::modeWrite|CFile::modeNoTruncate|CFile::typeBinary|CFile::modeCreate);
  553. }
  554. catch(...)
  555. {
  556. b_opened = false;
  557. }
  558. if(b_opened)
  559. {
  560. outFile->Seek(0,CFile::end);
  561. long nCount = 0;
  562. if(type == 1)
  563. wsprintf(str,"150 Opening ASCII data connection for %s%s",path,CRLF);
  564. else if(type == 3)
  565. wsprintf(str,"150 Opening BINARY data connection for %s%s",path,CRLF);
  566. SafeSend(str);
  567. DWORD start,end;
  568. HANDLE h = CreateEvent(NULL,false,false,"noname");
  569. do
  570. {
  571. start = GetTickCount();
  572. nCount = dbsocket->Receive((char*)lpDataBuf_in,m_buf_length_in,60);
  573. end = GetTickCount();
  574. outFile->Write(lpDataBuf_in,nCount);
  575. if(b_speed_limit_in)
  576. {
  577. if((end-start) < 1000)
  578. {
  579. int time = end-start;
  580. WaitForSingleObject(h,1000-time);
  581. }
  582. }
  583. }while(nCount > 0);
  584. dbsocket->Close();
  585. if(b_passive)
  586. svSocketSrv->Close();
  587. delete outFile;
  588. wsprintf(str,"226 Transfer finished successfully. Data connection closed.%s",CRLF);
  589. SafeSend(str);
  590. }else
  591. {
  592. outFile->Close();
  593. dbsocket->Close();
  594. if(b_passive)
  595. svSocketSrv->Close();
  596. delete outFile;
  597. wsprintf(str,"426 Connection closed file opening failed %s",CRLF);
  598. SafeSend(str);
  599. }
  600. }catch(...)
  601. {
  602. outFile->Close();
  603. dbsocket->Close();
  604. if(b_passive)
  605. svSocketSrv->Close();
  606. delete outFile;
  607. wsprintf(str,"426 Connection closed; transfer aborted (transfer failed)%s",CRLF);
  608. SafeSend(str);
  609. }
  610. SetEvent(h_inprogress);
  611. return;
  612. }
  613. else if(strncmp("SIZE ",curCmd,5) == 0)
  614. {
  615. try
  616. {
  617. char path[256] = "";
  618. strcpy(path,RemoveLeadingSpace(curCmd+5));
  619. char srcPath[300] = "";
  620. if(strcmp(vCurrentDir,"/")==0)
  621. wsprintf(srcPath,"%s%s%s",vRealRoot,vCurrentDir,path);
  622. else
  623. wsprintf(srcPath,"%s%s\%s",vRealRoot,vCurrentDir,path);
  624. slashFix(srcPath);
  625. HANDLE Hfound;
  626. WIN32_FIND_DATA FoundFile;
  627. Hfound=FindFirstFile(srcPath,&FoundFile);
  628. DWORD size_t = FoundFile.nFileSizeHigh*MAXDWORD+FoundFile.nFileSizeLow;
  629. if(Hfound != INVALID_HANDLE_VALUE)
  630. wsprintf(str,"213 %lu%s",size_t,CRLF);
  631. else
  632. wsprintf(str,"213 0%s",CRLF);
  633. SafeSend(str);
  634. FindClose(Hfound);
  635. }catch(...)
  636. {
  637. wsprintf(str,"213 0%s",CRLF);
  638. SafeSend(str);
  639. }
  640. return;
  641. }
  642. else if(strncmp("MDTM ",curCmd,5) == 0)
  643. {
  644. try
  645. {
  646. char path[256] = "";
  647. strcpy(path,RemoveLeadingSpace(curCmd+5));
  648. char srcPath[300] = "";
  649. if(strcmp(vCurrentDir,"/")==0)
  650. wsprintf(srcPath,"%s%s%s",vRealRoot,vCurrentDir,path);
  651. else
  652. wsprintf(srcPath,"%s%s\%s",vRealRoot,vCurrentDir,path);
  653. slashFix(srcPath);
  654. HANDLE Hfound;
  655. WIN32_FIND_DATA FoundFile;
  656. FILETIME lft;
  657. SYSTEMTIME st;
  658. Hfound=FindFirstFile(srcPath,&FoundFile);
  659. FileTimeToLocalFileTime(&FoundFile.ftLastWriteTime,&lft);
  660. FileTimeToSystemTime(&lft,&st);
  661. wsprintf(str,"213 %.4d%.2d%.2d%.2d%.2d%.2d%s",st.wYear,st.wMonth,st.wDay,st.wHour,st.wMinute,st.wSecond,CRLF);
  662. SafeSend(str);
  663. FindClose(Hfound);
  664. }catch(...)
  665. {
  666. wsprintf(str,"213 0%s",CRLF);
  667. SafeSend(str);
  668. }
  669. return;
  670. }
  671. else if(strncmp("MKD ",curCmd,4) == 0)
  672. {
  673. char path[512] = "";
  674. strcpy(path,RemoveLeadingSpace(curCmd+4));
  675. if(vMkdir(path))
  676. wsprintf(str,"250 Requested file action ok , completed%s",CRLF);
  677. else
  678. {
  679. char lpMsgBuf[128]="";
  680. DWORD eRRR = GetLastError();
  681. FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,NULL,eRRR,0,lpMsgBuf,128,NULL);
  682. wsprintf(str,"553 Requested action not taken , %s",lpMsgBuf);
  683. }
  684. SafeSend(str);
  685. return;
  686. }
  687. else if(strncmp("RMD ",curCmd,4) == 0)
  688. {
  689. char path[512] = "";
  690. strcpy(path,RemoveLeadingSpace(curCmd+4));
  691. if(vRmdir(path))
  692. wsprintf(str,"250 Requested file action ok , completed%s",CRLF);
  693. else
  694. {
  695. char lpMsgBuf[128]="";
  696. DWORD eRRR = GetLastError();
  697. FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,NULL,eRRR,0,lpMsgBuf,128,NULL);
  698. wsprintf(str,"553 Requested action not taken , %s",lpMsgBuf);
  699. }
  700. SafeSend(str);
  701. return;
  702. }
  703. else if(strncmp("TYPE ",curCmd,5) == 0)
  704. {
  705. char path[8] = "";
  706. strcpy(path,RemoveLeadingSpace(curCmd+5));
  707. if(strcmp("I",path)==0)
  708. {
  709. type = 3;
  710. wsprintf(str,"200 Type set to IMAGE.%s",CRLF);
  711. }else if(strcmp("A",path)==0)
  712. {
  713. type = 1;
  714. wsprintf(str,"200 Type set to ASCII.%s",CRLF);
  715. }
  716. SafeSend(str);
  717. return;
  718. }
  719. else if(stricmp("SYST",curCmd) == 0)
  720. {
  721. // wsprintf(str,"215 %s%s",sinfo.OSVER,CRLF);
  722. wsprintf(str,"215 %s%s","UNIX",CRLF);
  723. SafeSend(str);
  724. return;
  725. }
  726. else if(stricmp("QUIT",curCmd) == 0)
  727. {
  728. wsprintf(str,"221 Goodbye.%s",CRLF);
  729. SafeSend(str);
  730. deleFtpPI(this);
  731. return;
  732. }
  733. else if(stricmp("REST ",curCmd) == 0)
  734. {
  735. char marker[32] = "";
  736. strcpy(marker,RemoveLeadingSpace(curCmd+5));
  737. restart_marker = atol(marker);
  738. wsprintf(str,"110 Command Ok , restarting position set to %u%s",restart_marker,CRLF);
  739. SafeSend(str);
  740. return;
  741. }
  742. else if(strncmp("RNFR ",curCmd,5) == 0)
  743. {
  744. strcpy(old_filename,RemoveLeadingSpace(curCmd+5));
  745. wsprintf(str,"350 Requested file action pending further information.%s",CRLF);
  746. SafeSend(str);
  747. return;
  748. }
  749. else if(strncmp("PORT ",curCmd,5) == 0)
  750. {
  751. char path[32] = "";
  752. int pHi=0;
  753. int pLo=0;
  754. int strOffset=0;
  755. int portOffset=0;
  756. int commaCnt=0;
  757. char ipStr[32]="";
  758. strcpy(path,RemoveLeadingSpace(curCmd+5));
  759. for(unsigned int i=0;i<strlen(path);i++)
  760. {
  761. if(path[i] == ',')
  762. {
  763. commaCnt++;
  764. path[i] = '.';
  765. }
  766. if(commaCnt == 4)
  767. {
  768. strOffset = i;
  769. i = strlen(path);
  770. }
  771. }
  772. strncpy(ipStr,path,strOffset);
  773. for(i=0;i<strlen(path+strOffset);i++)
  774. {
  775. if(path[strOffset+i] == ',')
  776. {
  777. portOffset = i;
  778. path[strOffset+i] = NULL;
  779. }
  780. }
  781. pHi = atoi(path+strOffset+1);
  782.             pLo = atoi(path+strOffset+portOffset+1);
  783. data_port = pHi*256 + pLo;
  784. strcpy(data_ip,ipStr);
  785. WaitForSingleObject(h_inprogress,10000);
  786. try
  787. {
  788. ResetEvent(h_inprogress);
  789. if(dbsocket != NULL)
  790. {
  791. dbsocket->Close();
  792. delete dbsocket;
  793. }
  794. dbsocket = new CBlockingSocket();
  795. if(!dbsocket->Create(SOCK_STREAM))
  796. wsprintf(str,"425 Cannot open data connection (%s %d)%s",data_ip,data_port,CRLF);
  797. else
  798. {
  799. CSockAddr tSockAdr(data_ip,data_port);
  800. if(dbsocket->Connect(tSockAdr))
  801. {
  802. SetEvent(h_dbsocket_ready_to_send);
  803. wsprintf(str,"200 Port command okay.%s",CRLF);
  804. }
  805. else
  806. wsprintf(str,"425 Cannot open data connection (%s %d)%s",data_ip,data_port,CRLF);
  807. }
  808. }catch(...)
  809. {
  810. wsprintf(str,"425 Cannot open data connection (%s %d)%s",data_ip,data_port,CRLF);
  811. }
  812. SafeSend(str);
  813. return;
  814. }
  815. else if(strcmp("NLST",curCmd) == 0)
  816. {
  817. ListEngine("*.*",false);
  818. return;
  819. }
  820. else if(strcmp("LIST",curCmd) == 0)
  821. {
  822. ListEngine("*.*",true);
  823. return;
  824. }
  825. else if(strncmp("NLST ",curCmd,5) == 0)
  826. {
  827. char path[256] = "";
  828. strcpy(path,RemoveLeadingSpace(curCmd+5));
  829. ListEngine(path,false);
  830. return;
  831. }
  832. else if(strncmp("LIST ",curCmd,5) == 0)
  833. {
  834. char path[256] = "";
  835. strcpy(path,RemoveLeadingSpace(curCmd+5));
  836. ListEngine(path,true);
  837. return;
  838. }
  839. else if(strncmp("RNTO ",curCmd,5) == 0)
  840. {
  841. strcpy(new_filename,RemoveLeadingSpace(curCmd+5));
  842. if(vMoveFile(old_filename,new_filename))
  843. wsprintf(str,"250 Requested file action ok , completed%s",CRLF);
  844. else
  845. {
  846. char lpMsgBuf[128]="";
  847. DWORD eRRR = GetLastError();
  848. FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,NULL,eRRR,0,lpMsgBuf,128,NULL);
  849. wsprintf(str,"553 Requested action not taken , %s%s",lpMsgBuf,CRLF);
  850. }
  851. SafeSend(str);
  852. return;
  853. }
  854. else if(stricmp("NOOP",curCmd) == 0)
  855. {
  856. wsprintf(str,"200 Command Ok , NOOP%s",CRLF);
  857. SafeSend(str);
  858. return;
  859. }
  860. else if(strcmp("PASV",curCmd) == 0)
  861. {
  862. try
  863. {
  864. int pHi=0;
  865. int pLo=0;
  866. char ipStr[32]="";
  867. WaitForSingleObject(h_inprogress,10000);
  868. ResetEvent(h_inprogress);
  869. if(dbsocket != NULL)
  870. {
  871. dbsocket->Close();
  872. delete dbsocket;
  873. }
  874. dbsocket = new CBlockingSocket();
  875. if(svSocketSrv != NULL)
  876. {
  877. svSocketSrv->Close();
  878. delete svSocketSrv;
  879. }
  880. svSocketSrv = new CFtpPasvSrv();
  881. if(1)//dbsocket->Create(SOCK_STREAM))
  882. {
  883. svSocketSrv->Create(SOCK_STREAM);
  884. m_port_from++;
  885. if(m_port_from >= m_port_to)
  886. m_port_from = m_port_from_preset;
  887. for(UINT i=m_port_from;i<=m_port_to;i++)
  888. {
  889. CSockAddr tSockAdr(INADDR_ANY,i);
  890. if(svSocketSrv->Bind(tSockAdr))
  891. {
  892. svSocketSrv->m_current_port = i;
  893. i = 65536;
  894. }
  895. if(svSocketSrv->m_current_port && svSocketSrv->Listen())
  896. {
  897. pHi = (svSocketSrv->m_current_port-svSocketSrv->m_current_port%256)/256 ;
  898. pLo = svSocketSrv->m_current_port%256;
  899. b_passive = true;
  900. CString ip;
  901. if(!b_switch_pasv_ip)
  902. ip = ipList.GetTail();
  903. else
  904. {
  905. pos = ipList.GetHeadPosition();
  906. for(int j=0;j<=ipRoller;j++)
  907. {
  908. ip = ipList.GetNext(pos);
  909. }
  910. if(ipRoller+1 < ipList.GetCount())
  911. ipRoller++;
  912. else
  913. ipRoller=0;
  914. }
  915. for(int i=0;i<ip.GetLength();i++)
  916. {
  917. if(ip.GetAt(i) == '.')
  918. ip.SetAt(i,',');
  919. }
  920. wsprintf(str,"227 Entering Passive Mode (%s,%d,%d)%s",(LPCSTR)ip,pHi,pLo,CRLF);
  921. SafeSend(str);
  922. svSocketSrv->Accept(*dbsocket,(SOCKADDR*)&lpsockftpd);
  923. wsprintf(str,"%d.%d.%d.%d",lpsockftpd.sin_addr.S_un.S_un_b.s_b1,lpsockftpd.sin_addr.S_un.S_un_b.s_b2,lpsockftpd.sin_addr.S_un.S_un_b.s_b3,lpsockftpd.sin_addr.S_un.S_un_b.s_b4);
  924. if(!isAllowedIp(str))
  925. {
  926. #ifdef _TEST
  927. MessageBox(NULL,"ERROR","ERROR_PASV_NOT_ALLOWED_IP",MB_OK);
  928. #endif
  929. canclePasvListenSocket(svSocketSrv);
  930. wsprintf(str,"425 Cannot open data connection (client ip denied)%s",CRLF);
  931. SafeSend(str);
  932. }
  933. else
  934. SetEvent(h_dbsocket_ready_to_send);
  935. return;
  936. }
  937. else
  938. {
  939. wsprintf(str,"425 Cannot open data connection (%s %d create failed)%s",(LPCSTR)ipList.GetTail(),svSocketSrv->m_current_port,CRLF);
  940. SafeSend(str);
  941. }
  942. }else
  943. {
  944. wsprintf(str,"425 Cannot open data connection (%s %d create failed)%s",(LPCSTR)ipList.GetTail(),svSocketSrv->m_current_port,CRLF);
  945. SafeSend(str);
  946. }
  947. }
  948. catch(...)
  949. {
  950. #ifdef _TEST
  951. MessageBox(NULL,"ERROR","ERROR_PASV",MB_OK);
  952. #endif
  953. }
  954. return;
  955. }
  956. else
  957. {
  958. if(strcmp(curCmd,"") !=0)
  959. {
  960. wsprintf(str,"502 Command %s not implemented%s",curCmd,CRLF);
  961. SafeSend(str);
  962. }
  963. return;
  964. }
  965. }
  966. }
  967. char* CFtpdPi::RemoveLeadingSpace(char *str)
  968. {
  969. try
  970. {
  971. int breakat = 0;
  972. for(unsigned int i=0;i<strlen(str);i++)
  973. {
  974. if(*(str+i) != ' ')
  975. {
  976. breakat = i;
  977. i = strlen(str);
  978. }
  979. }
  980. return str+breakat;
  981. }
  982. catch(...)
  983. {
  984. return "";
  985. }
  986. }
  987. bool CFtpdPi::vMoveFile(LPCTSTR lpExistingFileName, LPCTSTR lpNewFileName)
  988. {
  989. char srcPath[512] = "";
  990. char tgtPath[512] = "";
  991. if(strcmp(vCurrentDir,"/")==0)
  992. {
  993. wsprintf(srcPath,"%s%s%s",vRealRoot,vCurrentDir,lpExistingFileName);
  994. wsprintf(tgtPath,"%s%s%s",vRealRoot,vCurrentDir,lpNewFileName);
  995. }else
  996. {
  997. wsprintf(srcPath,"%s%s\%s",vRealRoot,vCurrentDir,lpExistingFileName);
  998. wsprintf(tgtPath,"%s%s\%s",vRealRoot,vCurrentDir,lpNewFileName);
  999. }
  1000. if(MoveFile(srcPath,tgtPath))
  1001. return true;
  1002. else
  1003. {
  1004. return false;
  1005. }
  1006. }
  1007. bool CFtpdPi::isFilePresent(char *path)
  1008. {
  1009. WIN32_FIND_DATA MyFoundFile;
  1010. char srcPath[512] = "";
  1011. if(strcmp(vCurrentDir,"/")==0)
  1012. wsprintf(srcPath,"%s\%s",vRealRoot,path);
  1013. else
  1014. wsprintf(srcPath,"%s%s\%s",vRealRoot,vCurrentDir,path);
  1015. slashFix(srcPath);
  1016. HANDLE Hfound=FindFirstFile(srcPath,&MyFoundFile);
  1017. if(Hfound == INVALID_HANDLE_VALUE)
  1018. {
  1019. FindClose(Hfound);
  1020. return false;
  1021. }else
  1022. {
  1023. if(MyFoundFile.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY)
  1024. {
  1025. FindClose(Hfound);
  1026. return false;
  1027. }else
  1028. FindClose(Hfound);
  1029. return true;
  1030. }
  1031. }
  1032. bool CFtpdPi::isVpathPresent(char *vpath)
  1033. {
  1034. WIN32_FIND_DATA MyFoundFile;
  1035. char srcPath[512] = "";
  1036. if(strcmp(vpath,"/")==0)
  1037. wsprintf(srcPath,"%s",vRealRoot);
  1038. else
  1039. wsprintf(srcPath,"%s%s",vRealRoot,vpath);
  1040. slashFix(srcPath);
  1041. HANDLE Hfound=FindFirstFile(srcPath,&MyFoundFile);
  1042. if(Hfound == INVALID_HANDLE_VALUE)
  1043. {
  1044. FindClose(Hfound);
  1045. return false;
  1046. }else
  1047. {
  1048. if(MyFoundFile.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY)
  1049. {
  1050. FindClose(Hfound);
  1051. return true;
  1052. }else
  1053. FindClose(Hfound);
  1054. return false;
  1055. }
  1056. }
  1057. char* CFtpdPi::fixVpath(char *vPath)
  1058. {
  1059. char retPath[512]="";
  1060. strcpy(retPath,replaceDotInVpath(vPath));
  1061. if(strncmp("/",retPath,1)==0)
  1062. {
  1063. return vPath;
  1064. }
  1065. else
  1066. {
  1067. if(strcmp("/",vCurrentDir) == 0)
  1068. {
  1069. wsprintf(vPath,"/%s",retPath);
  1070. return vPath;
  1071. }
  1072. else
  1073. {
  1074. wsprintf(vPath,"%s/%s",vCurrentDir,retPath);
  1075. return vPath;
  1076. }
  1077. }
  1078. }
  1079. char* CFtpdPi::replaceDotInVpath(char *vPath)
  1080. {
  1081. char vCurDirTmp[512] = "";
  1082. strcpy(vCurDirTmp,vCurrentDir);
  1083. char* outPut = (char*) malloc(512);
  1084. int outPos = 0;
  1085. bool dotAgain =  false;
  1086. memset(outPut,NULL,512);
  1087. for(unsigned int i =0;i<=strlen(vPath)-1;i++)
  1088. {
  1089. if(*(vPath+i) == '.')
  1090. {
  1091. if(*(vPath+i+1) == '/' || *(vPath+i+1) == NULL)
  1092. {
  1093. i=i+2;
  1094. }
  1095. else if(*(vPath+i+1) == '.' && (*(vPath+i+2) == '/' || *(vPath+i+2) == NULL))
  1096. {
  1097. if(dotAgain)
  1098. strcpy(vCurDirTmp,outPut);
  1099. if(!goParent(vCurDirTmp))
  1100. {
  1101. }else
  1102. {
  1103. strcpy(outPut,vCurDirTmp);
  1104. if(strcmp(outPut,"/") == 0)
  1105. {
  1106. outPos = 1;
  1107. i=i+2;
  1108. }else
  1109. {
  1110. i=i+2;
  1111. if(i <= strlen(vPath)-1)
  1112. {
  1113. int a = strlen(outPut);
  1114. *(outPut+a) = '/';
  1115. *(outPut+a+1) = NULL;
  1116. }
  1117. outPos = strlen(outPut);
  1118. }
  1119. dotAgain = true;
  1120. }
  1121. }
  1122. else
  1123. {
  1124. *(outPut+outPos) = *(vPath+i);
  1125. outPos++;
  1126. }
  1127. }else
  1128. {
  1129. *(outPut+outPos) = *(vPath+i);
  1130. outPos++;
  1131. }
  1132. }
  1133. *(outPut+outPos) = NULL;
  1134. strcpy(vPath,outPut);
  1135. free(outPut);
  1136. return vPath;
  1137. }
  1138. bool CFtpdPi::goParent(char *path)
  1139. {
  1140. for(unsigned int i=strlen(path)-1;i>=0;i--)
  1141. {
  1142. if( *(path+i) == '/' && i != strlen(path)-1)
  1143. {
  1144. if(i>0)
  1145. {
  1146. *(path+i) = NULL;
  1147. i=0;
  1148. }else
  1149. *(path+1) = NULL;
  1150. return true;
  1151. }
  1152. }
  1153. return false;
  1154. }
  1155. bool CFtpdPi::vRemove(char *file)
  1156. {
  1157. char srcPath[512] = "";
  1158. if(strcmp(vCurrentDir,"/")==0)
  1159. wsprintf(srcPath,"%s%s%s",vRealRoot,vCurrentDir,file);
  1160. else
  1161. wsprintf(srcPath,"%s%s\%s",vRealRoot,vCurrentDir,file);
  1162. slashFix(srcPath);
  1163. if(remove(srcPath)==0)
  1164. return true;
  1165. else
  1166. {
  1167. return false;
  1168. }
  1169. }
  1170. bool CFtpdPi::vMkdir(char *dir)
  1171. {
  1172. char srcPath[512] = "";
  1173. if(strcmp(vCurrentDir,"/")==0)
  1174. wsprintf(srcPath,"%s%s%s",vRealRoot,vCurrentDir,dir);
  1175. else
  1176. wsprintf(srcPath,"%s%s\%s",vRealRoot,vCurrentDir,dir);
  1177. slashFix(srcPath);
  1178. if(CreateDirectory(srcPath,NULL))
  1179. return true;
  1180. else
  1181. {
  1182. return false;
  1183. }
  1184. }
  1185. void CFtpdPi::slashFix(char *path)
  1186. {
  1187. for(unsigned int i=0;i<strlen(path);i++)
  1188. {
  1189. if(*(path+i) == '/')
  1190. *(path+i) = '\';
  1191. }
  1192. return;
  1193. }
  1194. bool CFtpdPi::vRmdir(char *path)
  1195. {
  1196. char srcPath[512] = "";
  1197. if(strcmp(vCurrentDir,"/")==0)
  1198. wsprintf(srcPath,"%s%s%s",vRealRoot,vCurrentDir,path);
  1199. else
  1200. wsprintf(srcPath,"%s%s\%s",vRealRoot,vCurrentDir,path);
  1201. slashFix(srcPath);
  1202. if(RemoveDirectory(srcPath))
  1203. return true;
  1204. else
  1205. {
  1206. return false;
  1207. }
  1208. }
  1209. void CFtpdPi::slashFixUnix(char *path)
  1210. {
  1211. for(unsigned int i=0;i<strlen(path);i++)
  1212. {
  1213. if(*(path+i) == '\')
  1214. *(path+i) = '/';
  1215. }
  1216. return;
  1217. }
  1218. bool CFtpdPi::validuser(char *buf)
  1219. {
  1220. return true;
  1221. }
  1222. bool CFtpdPi::matchpass(char *buf, char *uname)
  1223. {
  1224. return true;
  1225. }
  1226. void CFtpdPi::OnClose(int nErrorCode) 
  1227. {
  1228. // TODO: Add your specialized code here and/or call the base class
  1229. CFtpd* K = (CFtpd*) pFtpd;
  1230. K->RemoveClient(this);
  1231. CSocket::OnClose(nErrorCode);
  1232. }
  1233. void CFtpdPi::SetOutStreamSpeed(int kbs)
  1234. {
  1235. free(lpDataBuf_out);
  1236. lpDataBuf_out = (unsigned char*) malloc(kbs*1024);
  1237. m_buf_length_out = kbs*1024;
  1238. b_speed_limit_out = true;
  1239. return;
  1240. }
  1241. void CFtpdPi::SetInStreamSpeed(int kbs)
  1242. {
  1243. free(lpDataBuf_in);
  1244. lpDataBuf_in = (unsigned char*) malloc(kbs*1024);
  1245. m_buf_length_in = kbs*1024;
  1246. b_speed_limit_in = true;
  1247. return;
  1248. }
  1249. void CFtpdPi::SafeSend(char *str)
  1250. {
  1251. int len = strlen(str);
  1252. try
  1253. {
  1254. int result = Send(str,len,0);
  1255. if(result < len)
  1256. {
  1257. #ifdef _TEST
  1258. MessageBox(NULL,"ERROR","ERROR_SEND_TWICE",MB_OK);
  1259. #endif
  1260. result = Send(str+result,len-result,0);
  1261. }
  1262. }catch(...)
  1263. {
  1264. #ifdef _TEST
  1265. MessageBox(NULL,"ERROR","ERROR_SEND_EXCEPTION",MB_OK);
  1266. #endif
  1267. }
  1268. }
  1269. bool CFtpdPi::isAllowedIp(char *ip)
  1270. {
  1271. for(int i = 0;i < clientIpCount;i++)
  1272. {
  1273. if(strncmp(ip,clientIp[i],strlen(clientIp[i]))==0)
  1274. return true;
  1275. }
  1276. return false;
  1277. }
  1278. void CFtpdPi::addClientIp(char *ip)
  1279. {
  1280. strcpy(clientIp[clientIpCount],ip);
  1281. if(clientIpCount < 32)
  1282. clientIpCount++;
  1283. return;
  1284. }
  1285. void CFtpdPi::LoadIpRange()
  1286. {
  1287. char buf[32] = "";
  1288. CStdioFile ifs(ipfile , CFile::modeRead);
  1289. if(ifs.ReadString(buf,32) != NULL)
  1290. {
  1291. do
  1292. {
  1293. int l = strlen(buf) - 1;
  1294. if(l >= 0)
  1295. {
  1296. if(*(buf+l) == 'n')
  1297. *(buf+l) = NULL;
  1298. }
  1299. addClientIp(buf);
  1300. }while(ifs.ReadString(buf,32) != NULL);
  1301. }
  1302. return;
  1303. }
  1304. void CFtpdPi::ListEngine(char *vpath, bool longList)
  1305. {
  1306. char path[256] = "";
  1307. HANDLE Hfound;
  1308. try
  1309. {
  1310. strcpy(path,vpath);
  1311. WaitForSingleObject(h_dbsocket_ready_to_send,5000);
  1312. ResetEvent(h_dbsocket_ready_to_send);
  1313. char pattern[256] = "";
  1314. if(strncmp(path,"-la",3)==0 || strncmp(path,"-l",2)==0 || strncmp(path,"-a",2)==0 || strcmp(path,"*")==0 || strcmp(path,".")==0)
  1315. strcpy(pattern,"*.*");
  1316. else if(strstr(path,"*.")!=NULL || strstr(path,"/*")!=NULL)
  1317. strcpy(pattern,path);
  1318. else
  1319. {
  1320. strcpy(pattern,path);
  1321. if(strcmp(pattern,"/")==0)
  1322. strcat(pattern,"*.*");
  1323. else
  1324. strcat(pattern,"/*.*");
  1325. }
  1326. fixVpath(pattern);
  1327. WIN32_FIND_DATA FoundFile;
  1328. char dbyte = '-';
  1329. char perm[4] = "rwx";
  1330. char temp1[300]="";
  1331. FILETIME lft;
  1332. SYSTEMTIME st;
  1333. strcpy(perm,"rwx");
  1334. if(strcmp(pattern,"/")==0)
  1335. wsprintf(temp1,"%s\*.*",vRealRoot);
  1336. else
  1337. wsprintf(temp1,"%s%s",vRealRoot,pattern);
  1338. slashFix(temp1);
  1339. wsprintf(str,"150 Opening ASCII NO-PRINT mode data connection for ls -l.%s",CRLF);
  1340. SafeSend(str);
  1341. Hfound=FindFirstFile(temp1,&FoundFile);
  1342. if(FoundFile.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY)
  1343. dbyte = 'd';
  1344. else
  1345. dbyte = '-';
  1346. FileTimeToLocalFileTime(&FoundFile.ftLastWriteTime,&lft);
  1347. FileTimeToSystemTime(&lft,&st);
  1348. char timeStr2[16] = "";
  1349. if(st.wYear != MyTime.wYear)
  1350. wsprintf(timeStr2,"%5d",st.wYear);
  1351. else
  1352. wsprintf(timeStr2,"%.2d:%.2d",st.wHour,st.wMinute);
  1353. if(!longList)
  1354. {
  1355. if(strcmp(FoundFile.cFileName,".") !=0 && strcmp(FoundFile.cFileName,"..") !=0)
  1356. {
  1357. wsprintf(str,"%s%s",FoundFile.cFileName,CRLF);
  1358. dbsocket->Send(str,strlen(str),20);
  1359. }
  1360. }
  1361. else
  1362. {
  1363. wsprintf(str,"%c%s%s%s  1 %-9s %-9s %10u %s %d %s %s%s",dbyte,perm,perm,perm,(LPCSTR)m_username,(LPCSTR)m_group,(FoundFile.nFileSizeHigh*MAXDWORD)+FoundFile.nFileSizeLow,monthStr[st.wMonth],st.wDay,timeStr2,FoundFile.cFileName,CRLF);
  1364. dbsocket->Send(str,strlen(str),20);
  1365. }
  1366. while(FindNextFile(Hfound,&FoundFile))
  1367. {
  1368. if(FoundFile.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY)
  1369. dbyte = 'd';
  1370. else
  1371. dbyte = '-';
  1372. FileTimeToLocalFileTime(&FoundFile.ftLastWriteTime,&lft);
  1373. FileTimeToSystemTime(&lft,&st);
  1374. if(st.wYear != MyTime.wYear)
  1375. wsprintf(timeStr2,"%5d",st.wYear);
  1376. else
  1377. wsprintf(timeStr2,"%.2d:%.2d",st.wHour,st.wMinute);
  1378. if(!longList)
  1379. {
  1380. if(strcmp(FoundFile.cFileName,".") !=0 && strcmp(FoundFile.cFileName,"..") !=0)
  1381. {
  1382. wsprintf(str,"%s%s",FoundFile.cFileName,CRLF);
  1383. dbsocket->Send(str,strlen(str),20);
  1384. }
  1385. }
  1386. else
  1387. {
  1388. wsprintf(str,"%c%s%s%s  1 %-9s %-9s %10u %s %d %s %s%s",dbyte,perm,perm,perm,(LPCSTR)m_username,(LPCSTR)m_group,(FoundFile.nFileSizeHigh*MAXDWORD)+FoundFile.nFileSizeLow,monthStr[st.wMonth],st.wDay,timeStr2,FoundFile.cFileName,CRLF);
  1389. dbsocket->Send(str,strlen(str),20);
  1390. }
  1391. }
  1392. FindClose(Hfound);
  1393. dbsocket->Close();
  1394. if(b_passive)
  1395. svSocketSrv->Close();
  1396. wsprintf(str,"226 Transfer finished successfully. Data connection closed.%s",CRLF);
  1397. SafeSend(str);
  1398. SetEvent(h_inprogress);
  1399. }
  1400. catch(...)
  1401. {
  1402. FindClose(Hfound);
  1403. dbsocket->Close();
  1404. if(b_passive)
  1405. svSocketSrv->Close();
  1406. wsprintf(str,"426 Connection closed; transfer aborted (transfer failed)%s",CRLF);
  1407. SafeSend(str);
  1408. SetEvent(h_inprogress);
  1409. }
  1410. }