📄 connectsocket.cpp
字号:
// found command ?
if (strCommand == commandList[nCommand].m_pszName)
{
// did we expect an argument ?
if (commandList[nCommand].m_bHasArguments && (strArguments == ""))
{
SendResponse("501 Syntax error");
return;
}
break;
}
}
if (nCommand == TOK_ERROR)
{
// command is not in our list
SendResponse("500 Syntax error, command unrecognized.");
return;
}
// no commands are excepted before successfull logged on
if (nCommand > TOK_PASS && !m_bLoggedon)
{
SendResponse("530 Please log in with USER and PASS first.");
return;
}
// proces command
switch(nCommand)
{
// specify username
case TOK_USER:
{
strArguments.MakeLower();
m_bLoggedon = FALSE;
m_strUserName = strArguments;
CString strPeerAddress;
UINT nPeerPort;
GetPeerName(strPeerAddress, nPeerPort);
// tell FTP server a new user has connected
CConnectThread *pThread = (CConnectThread *)m_pThread;
((CFTPServer *)pThread->m_pWndServer)->m_pEventSink->OnFTPUserConnected(m_pThread->m_nThreadID, m_strUserName, strPeerAddress);
SendResponse("331 Password required for " + strArguments);
}
break;
// specify password
case TOK_PASS:
{
// already logged on ?
if (m_bLoggedon)
{
SendResponse("503 Bad sequence of commands.");
}
else
{
// check user and password
CUser user;
if (theServer.m_UserManager.CheckUser(m_strUserName, strArguments, user))
{
// set home directory of user
m_strCurrentDir = "/";
// succesfully logged on
m_bLoggedon = TRUE;
SendResponse("230 Logged on");
}
else
SendResponse("530 Login or password incorrect!");
}
}
break;
// change current directory
case TOK_CWD:
{
int nResult = theServer.m_UserManager.ChangeDirectory(m_strUserName, m_strCurrentDir, strArguments);
CString str;
switch(nResult)
{
case 0:
str.Format("250 CWD successful. \"%s\" is current directory.", m_strCurrentDir);
SendResponse(str);
break;
case 1:
str.Format("550 CWD failed. \"%s\": Permission denied.", strArguments);
SendResponse(str);
break;
default:
str.Format("550 CWD failed. \"%s\": directory not found.", strArguments);
SendResponse(str);
break;
}
}
break;
// print current directory
case TOK_PWD:
{
CString str;
str.Format("257 \"%s\" is current directory.", m_strCurrentDir);
SendResponse(str);
}
break;
// specify IP and port (PORT a1,a2,a3,a4,p1,p2) -> IP address a1.a2.a3.a4, port p1*256+p2.
case TOK_PORT:
{
CString strSub;
int nCount=0;
while (AfxExtractSubString(strSub, strArguments, nCount++, ','))
{
switch(nCount)
{
case 1: // a1
m_TransferStatus.m_strRemoteHost = strSub;
m_TransferStatus.m_strRemoteHost += ".";
break;
case 2: // a2
m_TransferStatus.m_strRemoteHost += strSub;
m_TransferStatus.m_strRemoteHost += ".";
break;
case 3: // a3
m_TransferStatus.m_strRemoteHost += strSub;
m_TransferStatus.m_strRemoteHost += ".";
break;
case 4: // a4
m_TransferStatus.m_strRemoteHost += strSub;
break;
case 5: // p1
m_TransferStatus.m_nRemotePort = 256*atoi(strSub);
break;
case 6: // p2
m_TransferStatus.m_nRemotePort += atoi(strSub);
break;
}
}
m_TransferStatus.m_bPassiveMode = FALSE;
SendResponse("200 Port command successful");
break;
}
// switch to passive mode
case TOK_PASV:
{
// delete existing datasocket
DestroyDataSocket();
// create new data socket
m_TransferStatus.m_pDataSocket = new CDataSocket(this, -1);
if (!m_TransferStatus.m_pDataSocket->Create())
{
DestroyDataSocket();
SendResponse("421 Can't create socket");
break;
}
// start listening
m_TransferStatus.m_pDataSocket->Listen();
m_TransferStatus.m_pDataSocket->AsyncSelect();
CString strIP, strTmp;
UINT nPort;
// get our ip address
GetSockName(strIP, nPort);
// Now retrieve the port
m_TransferStatus.m_pDataSocket->GetSockName(strTmp, nPort);
// Reformat the ip
strIP.Replace(".",",");
// tell the client which address/port to connect to
CString str;
str.Format("227 Entering Passive Mode (%s,%d,%d)", strIP, nPort/256, nPort%256);
SendResponse(str);
m_TransferStatus.m_bPassiveMode = TRUE;
break;
}
case TOK_TYPE:
{
SendResponse("200 Type set to " + strArguments);
}
break;
// list current directory
case TOK_LIST:
{
if(!m_TransferStatus.m_bPassiveMode && (m_TransferStatus.m_strRemoteHost == "" || m_TransferStatus.m_nRemotePort == -1))
{
SendResponse("503 Bad sequence of commands.");
}
else
{
// if client did not specify a directory use current dir
if (strArguments == "")
{
strArguments = m_strCurrentDir;
}
else
{
// check if argument is file or directory
CString strResult;
int nResult = theServer.m_UserManager.GetFileName(m_strUserName, strArguments, m_strCurrentDir, FTP_LIST, strResult);
if (nResult == 0)
{
strArguments = strResult;
}
}
CString strListing;
int nResult = theServer.m_UserManager.GetDirectoryList(m_strUserName, strArguments, strListing);
switch(nResult)
{
case 1:
SendResponse("550 Permission denied");
break;
case 2:
SendResponse("550 Directory not found");
break;
default:
if (!m_TransferStatus.m_bPassiveMode)
{
CDataSocket *pDataSocket = new CDataSocket(this, 0);
pDataSocket->Create();
pDataSocket->SetData(strListing);
pDataSocket->AsyncSelect();
m_TransferStatus.m_pDataSocket = pDataSocket;
if (!pDataSocket->Connect(m_TransferStatus.m_strRemoteHost, m_TransferStatus.m_nRemotePort))
{
if (GetLastError() != WSAEWOULDBLOCK)
{
SendResponse("425 Can't open data connection");
break;
}
}
SendResponse("150 Opening data channel for directory list.");
}
else
{
m_TransferStatus.m_pDataSocket->SetData(strListing);
m_TransferStatus.m_pDataSocket->SetTransferType(0);
}
break;
}
}
break;
}
// change to parent directory
case TOK_CDUP:
{
CString strDirectory = "..";
CString str;
int nResult = theServer.m_UserManager.ChangeDirectory(m_strUserName, m_strCurrentDir, strDirectory);
switch(nResult)
{
case 0:
str.Format("250 CWD successful. \"%s\" is current directory.", m_strCurrentDir);
SendResponse(str);
break;
case 1:
str.Format("550 CWD failed. \"%s\": Permission denied.", strDirectory);
SendResponse(str);
break;
case 2:
str.Format("550 CWD failed. \"%s\": directory not found.", strDirectory);
SendResponse(str);
break;
}
}
break;
// retrieve file
case TOK_RETR:
{
if(!m_TransferStatus.m_bPassiveMode && (m_TransferStatus.m_strRemoteHost == "" || m_TransferStatus.m_nRemotePort == -1))
{
SendResponse("503 Bad sequence of commands.");
break;
}
CString strResult;
int nResult = theServer.m_UserManager.GetFileName(m_strUserName, strArguments, m_strCurrentDir, FTP_DOWNLOAD, strResult);
switch(nResult)
{
case 1:
SendResponse("550 Permission denied");
break;
case 2:
SendResponse("550 File not found");
break;
default:
if (!m_TransferStatus.m_bPassiveMode)
{
CDataSocket *pDataSocket = new CDataSocket(this, 1);
m_TransferStatus.m_pDataSocket = pDataSocket;
pDataSocket->Create();
pDataSocket->AsyncSelect();
pDataSocket->SetData(strResult);
if (pDataSocket->Connect(m_TransferStatus.m_strRemoteHost ,m_TransferStatus.m_nRemotePort) == 0)
{
if (GetLastError() != WSAEWOULDBLOCK)
{
SendResponse("425 Can't open data connection");
break;
}
}
SendResponse("150 Opening data channel for file transfer.");
}
else
{
m_TransferStatus.m_pDataSocket->SetData(strResult);
m_TransferStatus.m_pDataSocket->SetTransferType(1);
}
break;
}
break;
}
// client wants to upload file
case TOK_STOR:
{
if(m_TransferStatus.m_bPassiveMode == -1)
{
SendResponse("503 Bad sequence of commands.");
break;
}
if(!m_TransferStatus.m_bPassiveMode && (m_TransferStatus.m_strRemoteHost == "" || m_TransferStatus.m_nRemotePort == -1))
{
SendResponse("503 Bad sequence of commands.");
break;
}
CString strResult;
int nResult = theServer.m_UserManager.GetFileName(m_strUserName, strArguments, m_strCurrentDir, FTP_UPLOAD, strResult);
switch(nResult)
{
case 1:
SendResponse("550 Permission denied");
break;
case 2:
SendResponse("550 Filename invalid");
break;
default:
if (!m_TransferStatus.m_bPassiveMode)
{
CDataSocket *pDataSocket = new CDataSocket(this, 2);
m_TransferStatus.m_pDataSocket = pDataSocket;
pDataSocket->Create();
pDataSocket->AsyncSelect();
pDataSocket->SetData(strResult);
if (pDataSocket->Connect(m_TransferStatus.m_strRemoteHost, m_TransferStatus.m_nRemotePort) == 0)
{
if (GetLastError() != WSAEWOULDBLOCK)
{
SendResponse("425 Can't open data connection");
break;
}
}
SendResponse("150 Opening data channel for file transfer.");
}
else
{
m_TransferStatus.m_pDataSocket->SetData(strResult);
m_TransferStatus.m_pDataSocket->SetTransferType(2);
}
break;
}
}
break;
// get file size
case TOK_SIZE:
{
CString strResult;
int nResult = theServer.m_UserManager.GetFileName(m_strUserName, strArguments, m_strCurrentDir, FTP_DOWNLOAD, strResult);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -