www.pudn.com > FTP.rar > FtpdPi.cpp
#include "stdafx.h"
#include "CFtpd.h"
#include "FtpdPi.h"
#define CRLF "\r\n"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
char sadr2[32];
bool canclePasvListenSocket(CFtpPasvSrv* sck)
{
try
{
sck->Close();
delete sck;
return true;
}
catch(...)
{
}
return false;
}
bool deleFtpPI(CFtpdPi* sck)
{
try
{
CFtpd* K = (CFtpd*) sck->pFtpd;
K->RemoveClient(sck);
}
catch(...)
{
}
return true;
}
UINT thFtpCmd( LPVOID pParam )
{
((CFtpdPi*)pParam)->ProcessMsg(((CFtpdPi*)pParam)->bufcmd);
return 1;
}
UINT thSendData( LPVOID pParam)
{
CFtpdPi* pFtpBind = (CFtpdPi*) pParam;
CFile* inFile = NULL;
try
{
char path[256] = "";
strcpy(path,pFtpBind->RemoveLeadingSpace(pFtpBind->curCmdth+5));
char srcPath[300] = "";
if(strcmp(pFtpBind->vCurrentDir,"/")==0)
wsprintf(srcPath,"%s%s%s",pFtpBind->vRealRoot,pFtpBind->vCurrentDir,path);
else
wsprintf(srcPath,"%s%s\\%s",pFtpBind->vRealRoot,pFtpBind->vCurrentDir,path);
pFtpBind->slashFix(srcPath);
if(pFtpBind->isFilePresent(path))
{
bool b_opened = true;
try
{
if(pFtpBind->type == 1)
inFile = new CFile(srcPath,CFile::modeRead|CFile::shareDenyNone|CFile::typeBinary);//CStdioFile(srcPath,CFile::modeRead|CFile::shareDenyNone|CFile::typeText);
else if(pFtpBind->type == 3)
inFile = new CFile(srcPath,CFile::modeRead|CFile::shareDenyNone|CFile::typeBinary);
}
catch(...)
{
b_opened = false;
}
if(b_opened)
{
long flen = inFile->GetLength();
if(pFtpBind->restart_marker > 0)
{
inFile->Seek(pFtpBind->restart_marker,CFile::begin);
pFtpBind->restart_marker = 0;
}
long nCount = 0;
if(pFtpBind->type == 1)
wsprintf(pFtpBind->str,"150 Sending %s (%u bytes). Mode STREAM Type ASCII%s",path,flen,CRLF);
else if(pFtpBind->type == 3)
wsprintf(pFtpBind->str,"150 Sending %s (%u bytes). Mode STREAM Type BINARY%s",path,flen,CRLF);
pFtpBind->Send(pFtpBind->str,strlen(pFtpBind->str),0);
if(flen)
{
long bytesent = 0;
long offset = 0;
DWORD start,end;
do
{
if(flen > pFtpBind->m_buf_length_out)
nCount = inFile->Read(pFtpBind->lpDataBuf_out,pFtpBind->m_buf_length_out);
else
nCount = inFile->Read(pFtpBind->lpDataBuf_out,flen);
flen = flen - nCount;
if(pFtpBind->b_speed_limit_out)
{
bytesent = 0;
offset = 0;
HANDLE h = CreateEvent(NULL,false,false,"noname");
do
{
start = GetTickCount();
if((nCount-offset) > pFtpBind->m_buf_length_out)
bytesent = pFtpBind->dbsocket->Send((char*)pFtpBind->lpDataBuf_out+offset,pFtpBind->m_buf_length_out,60);
else
bytesent = pFtpBind->dbsocket->Send((char*)pFtpBind->lpDataBuf_out+offset,nCount-offset,60);
offset = offset + bytesent;
end = GetTickCount();
if((end-start) < 1000)
{
int time = end-start;
WaitForSingleObject(h,1000-time);
}
}while(offset < nCount);
}
else
{
bytesent = 0;
offset = 0;
do
{
if((nCount-offset) > pFtpBind->m_buf_length_out)
bytesent = pFtpBind->dbsocket->Send((char*)pFtpBind->lpDataBuf_out+offset,pFtpBind->m_buf_length_out,60);
else
bytesent = pFtpBind->dbsocket->Send((char*)pFtpBind->lpDataBuf_out+offset,nCount-offset,60);
offset = offset + bytesent;
}while(offset < nCount);
if(pFtpBind->type == 1)
{
pFtpBind->dbsocket->Send(CRLF,2,60);
}
}
}while(flen != 0);
}
pFtpBind->dbsocket->Close();
if(pFtpBind->b_passive)
pFtpBind->svSocketSrv->Close();
delete inFile;
wsprintf(pFtpBind->str,"226 Transfer finished successfully. Data connection closed.%s",CRLF);
pFtpBind->Send(pFtpBind->str,strlen(pFtpBind->str),0);
SetEvent(pFtpBind->h_inprogress);
return true;
}else
{
pFtpBind->dbsocket->Close();
if(pFtpBind->b_passive)
pFtpBind->svSocketSrv->Close();
if(inFile != NULL)
delete inFile;
wsprintf(pFtpBind->str,"426 Connection closed , file opening failed%s",CRLF);
pFtpBind->Send(pFtpBind->str,strlen(pFtpBind->str),0);
SetEvent(pFtpBind->h_inprogress);
}
}
}catch(...)
{
inFile->Close();
pFtpBind->dbsocket->Close();
canclePasvListenSocket(pFtpBind->svSocketSrv);
delete inFile;
wsprintf(pFtpBind->str,"426 Connection closed; transfer aborted (transfer failed)%s",CRLF);
pFtpBind->Send(pFtpBind->str,strlen(pFtpBind->str),0);
SetEvent(pFtpBind->h_inprogress);
return false;
}
return true;
}
CFtpdPi::CFtpdPi()
{
clientIpCount = 0;
type = 3; //1 = ascii 2 = ebcdic 3 = binary
ipRoller = 0;
b_use_bsock = true;
b_verbose = true;
b_passive = false;
b_bell = false;
b_prompt = true;
b_globbing = true;
b_debugging = false;
b_hashmark = false;
bLOGINOK = false;
bUSER = false;
bPASS = false;
b_speed_limit_out = false;
b_speed_limit_in = false;
restart_marker = 0;
strcpy(vCurrentDir,"/");
strcpy(old_filename,"");
strcpy(new_filename,"");
strcpy(m_group,"nogroup");
m_buf_length_out = 32768;
m_buf_length_in = 32768;
lpDataBuf_out = (unsigned char*) malloc(m_buf_length_out);
memset(lpDataBuf_out,0,m_buf_length_out);
lpDataBuf_in = (unsigned char*) malloc(m_buf_length_in);
memset(lpDataBuf_in,0,m_buf_length_in);
strcpy(monthStr[1],"Jan");
strcpy(monthStr[2],"Feb");
strcpy(monthStr[3],"Mar");
strcpy(monthStr[4],"Apr");
strcpy(monthStr[5],"May");
strcpy(monthStr[6],"Jun");
strcpy(monthStr[7],"Jul");
strcpy(monthStr[8],"Aug");
strcpy(monthStr[9],"Sep");
strcpy(monthStr[10],"Oct");
strcpy(monthStr[11],"Dec");
strcpy(monthStr[12],"Nov");
sl = sizeof(SOCKADDR_IN);
GetLocalTime(&MyTime);
if(FileExists(ipfile))
LoadIpRange();
h_inprogress = CreateEvent(NULL,false,true,"in_progress");
h_dbsocket_ready_to_send = CreateEvent(NULL,false,false,"in_progress");
dbsocket = NULL;
svSocketSrv = NULL;
}
CFtpdPi::~CFtpdPi()
{
free(lpDataBuf_in);
free(lpDataBuf_out);
if(dbsocket != NULL)
{
dbsocket->Close();
delete dbsocket;
}
if(svSocketSrv != NULL)
{
svSocketSrv->Close();
delete svSocketSrv;
}
}
// Do not edit the following lines, which are needed by ClassWizard.
#if 0
BEGIN_MESSAGE_MAP(CFtpdPi, CSocket)
//{{AFX_MSG_MAP(CFtpdPi)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
#endif // 0
void CFtpdPi::OnReceive(int nErrorCode)
{
unsigned char* bufnow = (unsigned char*)malloc(256);
try
{
memset(bufnow,NULL,256);
result = Receive(bufnow,256,0);
bool cont = true;
int currentPos = 0;
if(*(bufnow+1)==0xf2)
currentPos = 1;
for(int i=0;i 500)
wsprintf(str,"503 current directory is too long.%s",CRLF);
else
wsprintf(str,"257 \"%s\" is current directory%s",vCurrentDir,CRLF);
SafeSend(str);
return;
}
else if(strncmp("CWD ",curCmd,4) == 0)
{
char path[512] = "";
strcpy(path,RemoveLeadingSpace(curCmd+4));
if(strcmp(path,"..")==0)
{
if(goParent(vCurrentDir))
wsprintf(str,"250 \"%s\" is current directory.%s",vCurrentDir,CRLF);
else
wsprintf(str,"550 Permission denied.%s",CRLF);
}else if(strcmp(path,".")==0)
wsprintf(str,"250 \"%s\" is current directory.%s",vCurrentDir,CRLF);
else
{
fixVpath(path);
if(isVpathPresent(path))
{
strcpy(vCurrentDir,path);
wsprintf(str,"250 \"%s\" is current directory.%s",vCurrentDir,CRLF);
}else
wsprintf(str,"550 Permission denied.%s",CRLF);
}
SafeSend(str);
return;
}
else if(strncmp("CDUP",curCmd,4) == 0)
{
if(goParent(vCurrentDir))
wsprintf(str,"250 \"%s\" is current directory.%s",vCurrentDir,CRLF);
else
wsprintf(str,"550 Permission denied.%s",CRLF);
SafeSend(str);
return;
}
else if(strcmp("REIN",curCmd) == 0)
{
bUSER = false;
bPASS = false;
bLOGINOK = false;
wsprintf(str,"550 Relogin required , connection reinitialized.%s",CRLF);
SafeSend(str);
return;
}
else if(strncmp("DELE ",curCmd,5) == 0)
{
char path[512] = "";
strcpy(path,RemoveLeadingSpace(curCmd+4));
if(vRemove(path))
wsprintf(str,"250 Requested file action ok , completed%s",CRLF);
else
{
char lpMsgBuf[128]="";
DWORD eRRR = GetLastError();
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,NULL,eRRR,0,lpMsgBuf,128,NULL);
wsprintf(str,"553 Requested action not taken , %s",lpMsgBuf);
}
SafeSend(str);
return;
}
else if(strncmp("XMKD ",curCmd,5) == 0)
{
char path[512] = "";
strcpy(path,RemoveLeadingSpace(curCmd+5));
if(vMkdir(path))
wsprintf(str,"257 \"%s\" created%s",path,CRLF);
else
{
char lpMsgBuf[128]="";
DWORD eRRR = GetLastError();
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,NULL,eRRR,0,lpMsgBuf,128,NULL);
wsprintf(str,"553 Requested action not taken , %s",lpMsgBuf);
}
SafeSend(str);
return;
}
else if(strncmp("RETR ",curCmd,5) == 0)
{
strcpy(curCmdth,curCmd);
AfxBeginThread(&thSendData,this,THREAD_PRIORITY_TIME_CRITICAL,0,0,NULL);
return;
}
else if(strcmp("ABOR",curCmd) == 0)
{
try
{
dbsocket->Close();
}
catch(...)
{
}
wsprintf(str,"426 Transfer aborted. Data connection closed.%s",CRLF);
SafeSend(str);
SetEvent(h_inprogress);
wsprintf(str,"226 Abort successful.%s",CRLF);
SafeSend(str);
return;
}
else if(strncmp("STOR ",curCmd,5) == 0 || strncmp("STOU ",curCmd,5) == 0)
{
CFile* outFile;
try
{
char path[256] = "";
strcpy(path,RemoveLeadingSpace(curCmd+5));
char srcPath[300] = "";
if(strcmp(vCurrentDir,"/")==0)
wsprintf(srcPath,"%s%s%s",vRealRoot,vCurrentDir,path);
else
wsprintf(srcPath,"%s%s\\%s",vRealRoot,vCurrentDir,path);
slashFix(srcPath);
if(isFilePresent(path) && strncmp("STOU ",curCmd,5) == 0)
{
dbsocket->Close();
wsprintf(str,"426 Connection closed; transfer aborted (target file already existed)%s",CRLF);
SafeSend(str);
}
else
{
bool b_opened = true;
try
{
if(type == 1)
outFile = new CStdioFile(srcPath,CFile::modeWrite|CFile::modeNoTruncate|CFile::typeText|CFile::modeCreate);
else if(type == 3)
outFile = new CFile(srcPath,CFile::modeWrite|CFile::modeNoTruncate|CFile::typeBinary|CFile::modeCreate);
}
catch(...)
{
b_opened = false;
}
if(b_opened)
{
long flen = 0;
long nCount = 0;
if(type == 1)
wsprintf(str,"150 Opening ASCII data connection for %s%s",path,CRLF);
else if(type == 3)
wsprintf(str,"150 Opening BINARY data connection for %s%s",path,CRLF);
SafeSend(str);
DWORD start,end;
HANDLE h = CreateEvent(NULL,false,false,"noname");
do
{
start = GetTickCount();
nCount = dbsocket->Receive((char*)lpDataBuf_in,m_buf_length_in,60);
outFile->Write(lpDataBuf_in,nCount);
end = GetTickCount();
if(b_speed_limit_in)
{
if((end-start) < 1000)
{
int time = end-start;
WaitForSingleObject(h,((1000-time)*nCount)/m_buf_length_in);
}
}
}while(nCount > 0);
dbsocket->Close();
if(b_passive)
svSocketSrv->Close();
delete outFile;
wsprintf(str,"226 Transfer finished successfully. Data connection closed.%s",CRLF);
SafeSend(str);
}else
{
outFile->Close();
dbsocket->Close();
if(b_passive)
svSocketSrv->Close();
delete outFile;
wsprintf(str,"426 Connection closed; file opening failed%s",CRLF);
SafeSend(str);
}
}
}
catch(...)
{
outFile->Close();
dbsocket->Close();
if(b_passive)
svSocketSrv->Close();
delete outFile;
wsprintf(str,"426 Connection closed; transfer aborted (transfer failed)%s",CRLF);
SafeSend(str);
}
SetEvent(h_inprogress);
return;
}
else if(strncmp("APPE ",curCmd,5) == 0)
{
CFile* outFile;
try
{
char path[256] = "";
strcpy(path,RemoveLeadingSpace(curCmd+5));
char srcPath[300] = "";
if(strcmp(vCurrentDir,"/")==0)
wsprintf(srcPath,"%s%s%s",vRealRoot,vCurrentDir,path);
else
wsprintf(srcPath,"%s%s\\%s",vRealRoot,vCurrentDir,path);
slashFix(srcPath);
bool b_opened = true;
try
{
if(type == 1)
outFile = new CStdioFile(srcPath,CFile::modeWrite|CFile::modeNoTruncate|CFile::typeText|CFile::modeCreate);
else if(type == 3)
outFile = new CFile(srcPath,CFile::modeWrite|CFile::modeNoTruncate|CFile::typeBinary|CFile::modeCreate);
}
catch(...)
{
b_opened = false;
}
if(b_opened)
{
outFile->Seek(0,CFile::end);
long nCount = 0;
if(type == 1)
wsprintf(str,"150 Opening ASCII data connection for %s%s",path,CRLF);
else if(type == 3)
wsprintf(str,"150 Opening BINARY data connection for %s%s",path,CRLF);
SafeSend(str);
DWORD start,end;
HANDLE h = CreateEvent(NULL,false,false,"noname");
do
{
start = GetTickCount();
nCount = dbsocket->Receive((char*)lpDataBuf_in,m_buf_length_in,60);
end = GetTickCount();
outFile->Write(lpDataBuf_in,nCount);
if(b_speed_limit_in)
{
if((end-start) < 1000)
{
int time = end-start;
WaitForSingleObject(h,1000-time);
}
}
}while(nCount > 0);
dbsocket->Close();
if(b_passive)
svSocketSrv->Close();
delete outFile;
wsprintf(str,"226 Transfer finished successfully. Data connection closed.%s",CRLF);
SafeSend(str);
}else
{
outFile->Close();
dbsocket->Close();
if(b_passive)
svSocketSrv->Close();
delete outFile;
wsprintf(str,"426 Connection closed file opening failed %s",CRLF);
SafeSend(str);
}
}catch(...)
{
outFile->Close();
dbsocket->Close();
if(b_passive)
svSocketSrv->Close();
delete outFile;
wsprintf(str,"426 Connection closed; transfer aborted (transfer failed)%s",CRLF);
SafeSend(str);
}
SetEvent(h_inprogress);
return;
}
else if(strncmp("SIZE ",curCmd,5) == 0)
{
try
{
char path[256] = "";
strcpy(path,RemoveLeadingSpace(curCmd+5));
char srcPath[300] = "";
if(strcmp(vCurrentDir,"/")==0)
wsprintf(srcPath,"%s%s%s",vRealRoot,vCurrentDir,path);
else
wsprintf(srcPath,"%s%s\\%s",vRealRoot,vCurrentDir,path);
slashFix(srcPath);
HANDLE Hfound;
WIN32_FIND_DATA FoundFile;
Hfound=FindFirstFile(srcPath,&FoundFile);
DWORD size_t = FoundFile.nFileSizeHigh*MAXDWORD+FoundFile.nFileSizeLow;
if(Hfound != INVALID_HANDLE_VALUE)
wsprintf(str,"213 %lu%s",size_t,CRLF);
else
wsprintf(str,"213 0%s",CRLF);
SafeSend(str);
FindClose(Hfound);
}catch(...)
{
wsprintf(str,"213 0%s",CRLF);
SafeSend(str);
}
return;
}
else if(strncmp("MDTM ",curCmd,5) == 0)
{
try
{
char path[256] = "";
strcpy(path,RemoveLeadingSpace(curCmd+5));
char srcPath[300] = "";
if(strcmp(vCurrentDir,"/")==0)
wsprintf(srcPath,"%s%s%s",vRealRoot,vCurrentDir,path);
else
wsprintf(srcPath,"%s%s\\%s",vRealRoot,vCurrentDir,path);
slashFix(srcPath);
HANDLE Hfound;
WIN32_FIND_DATA FoundFile;
FILETIME lft;
SYSTEMTIME st;
Hfound=FindFirstFile(srcPath,&FoundFile);
FileTimeToLocalFileTime(&FoundFile.ftLastWriteTime,&lft);
FileTimeToSystemTime(&lft,&st);
wsprintf(str,"213 %.4d%.2d%.2d%.2d%.2d%.2d%s",st.wYear,st.wMonth,st.wDay,st.wHour,st.wMinute,st.wSecond,CRLF);
SafeSend(str);
FindClose(Hfound);
}catch(...)
{
wsprintf(str,"213 0%s",CRLF);
SafeSend(str);
}
return;
}
else if(strncmp("MKD ",curCmd,4) == 0)
{
char path[512] = "";
strcpy(path,RemoveLeadingSpace(curCmd+4));
if(vMkdir(path))
wsprintf(str,"250 Requested file action ok , completed%s",CRLF);
else
{
char lpMsgBuf[128]="";
DWORD eRRR = GetLastError();
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,NULL,eRRR,0,lpMsgBuf,128,NULL);
wsprintf(str,"553 Requested action not taken , %s",lpMsgBuf);
}
SafeSend(str);
return;
}
else if(strncmp("RMD ",curCmd,4) == 0)
{
char path[512] = "";
strcpy(path,RemoveLeadingSpace(curCmd+4));
if(vRmdir(path))
wsprintf(str,"250 Requested file action ok , completed%s",CRLF);
else
{
char lpMsgBuf[128]="";
DWORD eRRR = GetLastError();
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,NULL,eRRR,0,lpMsgBuf,128,NULL);
wsprintf(str,"553 Requested action not taken , %s",lpMsgBuf);
}
SafeSend(str);
return;
}
else if(strncmp("TYPE ",curCmd,5) == 0)
{
char path[8] = "";
strcpy(path,RemoveLeadingSpace(curCmd+5));
if(strcmp("I",path)==0)
{
type = 3;
wsprintf(str,"200 Type set to IMAGE.%s",CRLF);
}else if(strcmp("A",path)==0)
{
type = 1;
wsprintf(str,"200 Type set to ASCII.%s",CRLF);
}
SafeSend(str);
return;
}
else if(stricmp("SYST",curCmd) == 0)
{
// wsprintf(str,"215 %s%s",sinfo.OSVER,CRLF);
wsprintf(str,"215 %s%s","UNIX",CRLF);
SafeSend(str);
return;
}
else if(stricmp("QUIT",curCmd) == 0)
{
wsprintf(str,"221 Goodbye.%s",CRLF);
SafeSend(str);
deleFtpPI(this);
return;
}
else if(stricmp("REST ",curCmd) == 0)
{
char marker[32] = "";
strcpy(marker,RemoveLeadingSpace(curCmd+5));
restart_marker = atol(marker);
wsprintf(str,"110 Command Ok , restarting position set to %u%s",restart_marker,CRLF);
SafeSend(str);
return;
}
else if(strncmp("RNFR ",curCmd,5) == 0)
{
strcpy(old_filename,RemoveLeadingSpace(curCmd+5));
wsprintf(str,"350 Requested file action pending further information.%s",CRLF);
SafeSend(str);
return;
}
else if(strncmp("PORT ",curCmd,5) == 0)
{
char path[32] = "";
int pHi=0;
int pLo=0;
int strOffset=0;
int portOffset=0;
int commaCnt=0;
char ipStr[32]="";
strcpy(path,RemoveLeadingSpace(curCmd+5));
for(unsigned int i=0;iClose();
delete dbsocket;
}
dbsocket = new CBlockingSocket();
if(!dbsocket->Create(SOCK_STREAM))
wsprintf(str,"425 Cannot open data connection (%s %d)%s",data_ip,data_port,CRLF);
else
{
CSockAddr tSockAdr(data_ip,data_port);
if(dbsocket->Connect(tSockAdr))
{
SetEvent(h_dbsocket_ready_to_send);
wsprintf(str,"200 Port command okay.%s",CRLF);
}
else
wsprintf(str,"425 Cannot open data connection (%s %d)%s",data_ip,data_port,CRLF);
}
}catch(...)
{
wsprintf(str,"425 Cannot open data connection (%s %d)%s",data_ip,data_port,CRLF);
}
SafeSend(str);
return;
}
else if(strcmp("NLST",curCmd) == 0)
{
ListEngine("*.*",false);
return;
}
else if(strcmp("LIST",curCmd) == 0)
{
ListEngine("*.*",true);
return;
}
else if(strncmp("NLST ",curCmd,5) == 0)
{
char path[256] = "";
strcpy(path,RemoveLeadingSpace(curCmd+5));
ListEngine(path,false);
return;
}
else if(strncmp("LIST ",curCmd,5) == 0)
{
char path[256] = "";
strcpy(path,RemoveLeadingSpace(curCmd+5));
ListEngine(path,true);
return;
}
else if(strncmp("RNTO ",curCmd,5) == 0)
{
strcpy(new_filename,RemoveLeadingSpace(curCmd+5));
if(vMoveFile(old_filename,new_filename))
wsprintf(str,"250 Requested file action ok , completed%s",CRLF);
else
{
char lpMsgBuf[128]="";
DWORD eRRR = GetLastError();
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,NULL,eRRR,0,lpMsgBuf,128,NULL);
wsprintf(str,"553 Requested action not taken , %s%s",lpMsgBuf,CRLF);
}
SafeSend(str);
return;
}
else if(stricmp("NOOP",curCmd) == 0)
{
wsprintf(str,"200 Command Ok , NOOP%s",CRLF);
SafeSend(str);
return;
}
else if(strcmp("PASV",curCmd) == 0)
{
try
{
int pHi=0;
int pLo=0;
char ipStr[32]="";
WaitForSingleObject(h_inprogress,10000);
ResetEvent(h_inprogress);
if(dbsocket != NULL)
{
dbsocket->Close();
delete dbsocket;
}
dbsocket = new CBlockingSocket();
if(svSocketSrv != NULL)
{
svSocketSrv->Close();
delete svSocketSrv;
}
svSocketSrv = new CFtpPasvSrv();
if(1)//dbsocket->Create(SOCK_STREAM))
{
svSocketSrv->Create(SOCK_STREAM);
m_port_from++;
if(m_port_from >= m_port_to)
m_port_from = m_port_from_preset;
for(UINT i=m_port_from;i<=m_port_to;i++)
{
CSockAddr tSockAdr(INADDR_ANY,i);
if(svSocketSrv->Bind(tSockAdr))
{
svSocketSrv->m_current_port = i;
i = 65536;
}
}
if(svSocketSrv->m_current_port && svSocketSrv->Listen())
{
pHi = (svSocketSrv->m_current_port-svSocketSrv->m_current_port%256)/256 ;
pLo = svSocketSrv->m_current_port%256;
b_passive = true;
CString ip;
if(!b_switch_pasv_ip)
ip = ipList.GetTail();
else
{
pos = ipList.GetHeadPosition();
for(int j=0;j<=ipRoller;j++)
{
ip = ipList.GetNext(pos);
}
if(ipRoller+1 < ipList.GetCount())
ipRoller++;
else
ipRoller=0;
}
for(int i=0;iAccept(*dbsocket,(SOCKADDR*)&lpsockftpd);
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);
if(!isAllowedIp(str))
{
#ifdef _TEST
MessageBox(NULL,"ERROR","ERROR_PASV_NOT_ALLOWED_IP",MB_OK);
#endif
canclePasvListenSocket(svSocketSrv);
wsprintf(str,"425 Cannot open data connection (client ip denied)%s",CRLF);
SafeSend(str);
}
else
SetEvent(h_dbsocket_ready_to_send);
return;
}
else
{
wsprintf(str,"425 Cannot open data connection (%s %d create failed)%s",(LPCSTR)ipList.GetTail(),svSocketSrv->m_current_port,CRLF);
SafeSend(str);
}
}else
{
wsprintf(str,"425 Cannot open data connection (%s %d create failed)%s",(LPCSTR)ipList.GetTail(),svSocketSrv->m_current_port,CRLF);
SafeSend(str);
}
}
catch(...)
{
#ifdef _TEST
MessageBox(NULL,"ERROR","ERROR_PASV",MB_OK);
#endif
}
return;
}
else
{
if(strcmp(curCmd,"") !=0)
{
wsprintf(str,"502 Command %s not implemented%s",curCmd,CRLF);
SafeSend(str);
}
return;
}
}
}
char* CFtpdPi::RemoveLeadingSpace(char *str)
{
try
{
int breakat = 0;
for(unsigned int i=0;i=0;i--)
{
if( *(path+i) == '/' && i != strlen(path)-1)
{
if(i>0)
{
*(path+i) = NULL;
i=0;
}else
*(path+1) = NULL;
return true;
}
}
return false;
}
bool CFtpdPi::vRemove(char *file)
{
char srcPath[512] = "";
if(strcmp(vCurrentDir,"/")==0)
wsprintf(srcPath,"%s%s%s",vRealRoot,vCurrentDir,file);
else
wsprintf(srcPath,"%s%s\\%s",vRealRoot,vCurrentDir,file);
slashFix(srcPath);
if(remove(srcPath)==0)
return true;
else
{
return false;
}
}
bool CFtpdPi::vMkdir(char *dir)
{
char srcPath[512] = "";
if(strcmp(vCurrentDir,"/")==0)
wsprintf(srcPath,"%s%s%s",vRealRoot,vCurrentDir,dir);
else
wsprintf(srcPath,"%s%s\\%s",vRealRoot,vCurrentDir,dir);
slashFix(srcPath);
if(CreateDirectory(srcPath,NULL))
return true;
else
{
return false;
}
}
void CFtpdPi::slashFix(char *path)
{
for(unsigned int i=0;iRemoveClient(this);
CSocket::OnClose(nErrorCode);
}
void CFtpdPi::SetOutStreamSpeed(int kbs)
{
free(lpDataBuf_out);
lpDataBuf_out = (unsigned char*) malloc(kbs*1024);
m_buf_length_out = kbs*1024;
b_speed_limit_out = true;
return;
}
void CFtpdPi::SetInStreamSpeed(int kbs)
{
free(lpDataBuf_in);
lpDataBuf_in = (unsigned char*) malloc(kbs*1024);
m_buf_length_in = kbs*1024;
b_speed_limit_in = true;
return;
}
void CFtpdPi::SafeSend(char *str)
{
int len = strlen(str);
try
{
int result = Send(str,len,0);
if(result < len)
{
#ifdef _TEST
MessageBox(NULL,"ERROR","ERROR_SEND_TWICE",MB_OK);
#endif
result = Send(str+result,len-result,0);
}
}catch(...)
{
#ifdef _TEST
MessageBox(NULL,"ERROR","ERROR_SEND_EXCEPTION",MB_OK);
#endif
}
}
bool CFtpdPi::isAllowedIp(char *ip)
{
for(int i = 0;i < clientIpCount;i++)
{
if(strncmp(ip,clientIp[i],strlen(clientIp[i]))==0)
return true;
}
return false;
}
void CFtpdPi::addClientIp(char *ip)
{
strcpy(clientIp[clientIpCount],ip);
if(clientIpCount < 32)
clientIpCount++;
return;
}
void CFtpdPi::LoadIpRange()
{
char buf[32] = "";
CStdioFile ifs(ipfile , CFile::modeRead);
if(ifs.ReadString(buf,32) != NULL)
{
do
{
int l = strlen(buf) - 1;
if(l >= 0)
{
if(*(buf+l) == '\n')
*(buf+l) = NULL;
}
addClientIp(buf);
}while(ifs.ReadString(buf,32) != NULL);
}
return;
}
void CFtpdPi::ListEngine(char *vpath, bool longList)
{
char path[256] = "";
HANDLE Hfound;
try
{
strcpy(path,vpath);
WaitForSingleObject(h_dbsocket_ready_to_send,5000);
ResetEvent(h_dbsocket_ready_to_send);
char pattern[256] = "";
if(strncmp(path,"-la",3)==0 || strncmp(path,"-l",2)==0 || strncmp(path,"-a",2)==0 || strcmp(path,"*")==0 || strcmp(path,".")==0)
strcpy(pattern,"*.*");
else if(strstr(path,"*.")!=NULL || strstr(path,"/*")!=NULL)
strcpy(pattern,path);
else
{
strcpy(pattern,path);
if(strcmp(pattern,"/")==0)
strcat(pattern,"*.*");
else
strcat(pattern,"/*.*");
}
fixVpath(pattern);
WIN32_FIND_DATA FoundFile;
char dbyte = '-';
char perm[4] = "rwx";
char temp1[300]="";
FILETIME lft;
SYSTEMTIME st;
strcpy(perm,"rwx");
if(strcmp(pattern,"/")==0)
wsprintf(temp1,"%s\\*.*",vRealRoot);
else
wsprintf(temp1,"%s%s",vRealRoot,pattern);
slashFix(temp1);
wsprintf(str,"150 Opening ASCII NO-PRINT mode data connection for ls -l.%s",CRLF);
SafeSend(str);
Hfound=FindFirstFile(temp1,&FoundFile);
if(FoundFile.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY)
dbyte = 'd';
else
dbyte = '-';
FileTimeToLocalFileTime(&FoundFile.ftLastWriteTime,&lft);
FileTimeToSystemTime(&lft,&st);
char timeStr2[16] = "";
if(st.wYear != MyTime.wYear)
wsprintf(timeStr2,"%5d",st.wYear);
else
wsprintf(timeStr2,"%.2d:%.2d",st.wHour,st.wMinute);
if(!longList)
{
if(strcmp(FoundFile.cFileName,".") !=0 && strcmp(FoundFile.cFileName,"..") !=0)
{
wsprintf(str,"%s%s",FoundFile.cFileName,CRLF);
dbsocket->Send(str,strlen(str),20);
}
}
else
{
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);
dbsocket->Send(str,strlen(str),20);
}
while(FindNextFile(Hfound,&FoundFile))
{
if(FoundFile.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY)
dbyte = 'd';
else
dbyte = '-';
FileTimeToLocalFileTime(&FoundFile.ftLastWriteTime,&lft);
FileTimeToSystemTime(&lft,&st);
if(st.wYear != MyTime.wYear)
wsprintf(timeStr2,"%5d",st.wYear);
else
wsprintf(timeStr2,"%.2d:%.2d",st.wHour,st.wMinute);
if(!longList)
{
if(strcmp(FoundFile.cFileName,".") !=0 && strcmp(FoundFile.cFileName,"..") !=0)
{
wsprintf(str,"%s%s",FoundFile.cFileName,CRLF);
dbsocket->Send(str,strlen(str),20);
}
}
else
{
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);
dbsocket->Send(str,strlen(str),20);
}
}
FindClose(Hfound);
dbsocket->Close();
if(b_passive)
svSocketSrv->Close();
wsprintf(str,"226 Transfer finished successfully. Data connection closed.%s",CRLF);
SafeSend(str);
SetEvent(h_inprogress);
}
catch(...)
{
FindClose(Hfound);
dbsocket->Close();
if(b_passive)
svSocketSrv->Close();
wsprintf(str,"426 Connection closed; transfer aborted (transfer failed)%s",CRLF);
SafeSend(str);
SetEvent(h_inprogress);
}
}