1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120 |
- /********************************************************************/
- /* */
- /* CONNECTSOCKET.CPP */
- /* */
- /* Implementation of the Connect Socket. */
- /* This class is a part of the CConnectThread which handles */
- /* socket connections. Incomming data is processed in OnReceive */
- /* */
- /* Programmed by LYFZ van der Meer */
- /* Based partially on and inspired by FileZilla Server. */
- /* */
- /* http://www.LYFZvandermeer.nl */
- /* */
- /* Last updated: 15 july 2002 */
- /* */
- /********************************************************************/
- //在ConnectSocket.cpp文件中实现连接套接字的创建,该类是CConnectThread类的
- //一部分,收到数据由函数OnReceive()完成处理。
- #include "stdafx.h"
- #include "CPhotoFTPReceiveApp.h"
- #include "CPhotoFTPReceive.h"
- #include "ConnectSocket.h"
- #include "ConnectThread.h"
- #include "ApplicationDlg.h"
- #include "DataSocket.h"
- extern CCPhotoFTPReceive theServer;
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- /********************************************************************/
- /* */
- /* Function name : CConnectSocket::CConnectSocket */
- /* Description : Constructor */
- /* */
- /********************************************************************/
- CConnectSocket::CConnectSocket()
- {
- m_bLoggedon = FALSE;
- m_bRenameFile = FALSE;
- m_pDataSocket = NULL;
- m_strRemoteHost = "";
- m_nRemotePort = -1;
- m_dwRestartOffset = 0;
- m_bPassiveMode = FALSE;
- }
- /********************************************************************/
- /* */
- /* Function name : CConnectSocket::~CConnectSocket */
- /* Description : Destructor */
- /* */
- /********************************************************************/
- CConnectSocket::~CConnectSocket()
- {
- DestroyDataConnection();
- // tell our thread we have been closed
- AfxGetThread()->PostThreadMessage(WM_QUIT,0,0);
- TRACE0("CConnectSocket destroyed.\n");
- }
- // Do not edit the following lines, which are needed by ClassWizard.
- #if 0
- BEGIN_MESSAGE_MAP(CConnectSocket, CSocket)
- //{{AFX_MSG_MAP(CConnectSocket)
- //}}AFX_MSG_MAP
- END_MESSAGE_MAP()
- #endif // 0
- /********************************************************************/
- /* */
- /* Function name : OnClose */
- /* Description : Send WM_QUIT message to the thread containing */
- /* the socket to shutdown once the connection is */
- /* closed. */
- /* */
- /********************************************************************/
- void CConnectSocket::OnClose(int nErrorCode)
- {
- Close();
- // destroy connection
- m_pThread->PostThreadMessage(WM_THREADMSG, 1, 0);
- TRACE("CConnectSocket() OnClose()\n");
- CSocket::OnClose(nErrorCode);
- }
- #define BUFFERSIZE 4096
- /********************************************************************/
- /* */
- /* Function name : OnReceive */
- /* Description : Called by the framework to notify this socket */
- /* that there is data in the buffer. */
- /* */
- /********************************************************************/
- //由主窗口调用通知套接字缓冲区中有数据要接收
- void CConnectSocket::OnReceive(int nErrorCode)
- {
- TCHAR buff[BUFFERSIZE+1];
- //接收数据并放到缓冲区
- int nRead = Receive(buff, BUFFERSIZE);
- switch (nRead)
- {
- case 0:
- Close();
- break;
- case SOCKET_ERROR:
- if (GetLastError() != WSAEWOULDBLOCK)
- {
- TCHAR szError[256];
- wsprintf(szError, "OnReceive error: %d", GetLastError());
- // AfxMessageBox (szError);
- }
- break;
- default:
- if (nRead != SOCKET_ERROR && nRead != 0)
- {
- ((CConnectThread *)AfxGetThread())->IncReceivedBytes(nRead);
- // 结束字符串
- buff[nRead] = 0;
- m_RxBuffer += CString(buff);
- //获得命令行
- GetRxLine();
- }
- break;
- }
- CSocket::OnReceive(nErrorCode);
- }
- /********************************************************************/
- /* */
- /* Function name: GetRxCommand */
- /* Description : Get command from receiver buffer. */
- /* */
- /********************************************************************/
- //从接收缓冲区获得命令
- BOOL CConnectSocket::GetRxCommand(CString &strCommand, CString &strArguments)
- {
- if (!m_strCommands.IsEmpty())
- {
- CString strBuff = m_strCommands.RemoveHead();
- int nIndex = strBuff.Find(" ");
- if (nIndex != -1)
- {
- CString strPassword = strBuff;
- strPassword.MakeUpper();
- //使密码不可见
- if (strPassword.Left(5) == "PASS ")
- {
- for (int i=5; i < strPassword.GetLength(); i++)
- {
- strPassword.SetAt(i, '*');
- }
- FireStatusMessage(strPassword, 1);
- }
- else
- {
- FireStatusMessage(strBuff, 1);
- }
- strCommand = strBuff.Left(nIndex);
- strArguments = strBuff.Mid(nIndex+1);
- }
- else
- {
- FireStatusMessage(strBuff, 1);
- strCommand = strBuff;
- }
- if (strCommand != "")
- {
- strCommand.MakeUpper();
- // who screwed up ???
- if (strCommand.Right(4) == "ABOR")
- {
- strCommand = "ABOR";
- }
- TRACE2("COMMAND: %s, ARGS: %s\n", strCommand, strArguments);
- return TRUE;
- }
- }
- return FALSE;
- }
- /********************************************************************/
- /* */
- /* Function name: GetRxLine */
- /* Description : Parse complete command line */
- /* */
- /********************************************************************/
- //解析整个命令行
- void CConnectSocket::GetRxLine()
- {
- CString strTemp;
- int nIndex;
- while(!m_RxBuffer.IsEmpty())
- {
- //寻找换行符
- nIndex = m_RxBuffer.Find("\r\n");
- if (nIndex != -1)
- {
- strTemp = m_RxBuffer.Left(nIndex);
- m_RxBuffer = m_RxBuffer.Mid(nIndex + 2);
- if (!strTemp.IsEmpty())
- {
- m_strCommands.AddTail(strTemp);
- // 解析并执行命令
- ParseCommand();
- }
- }
- else
- break;
- }
- }
- /********************************************************************/
- /* */
- /* Function name: OnConnect */
- /* Description : Called by the framework to notify this connecting */
- /* socket that its connection attempt is completed. */
- /* */
- /********************************************************************/
- void CConnectSocket::OnConnect(int nErrorCode)
- {
- CSocket::OnConnect(nErrorCode);
- }
- /********************************************************************/
- /* */
- /* Function name: HasConnectionDropped */
- /* Description : Check if connection has been dropped. */
- /* Used to detect if client has crashed. */
- /* */
- /********************************************************************/
- BOOL CConnectSocket::HasConnectionDropped(void)
- {
- BOOL bConnDropped = FALSE;
- INT iRet = 0;
- BOOL bOK = TRUE;
- if (m_hSocket == INVALID_SOCKET)
- return TRUE;
- struct timeval timeout = { 0, 0 };
- fd_set readSocketSet;
- FD_ZERO(&readSocketSet);
- FD_SET(m_hSocket, &readSocketSet);
- iRet = ::select(0, &readSocketSet, NULL, NULL, &timeout);
- bOK = (iRet > 0);
- if(bOK)
- {
- bOK = FD_ISSET(m_hSocket, &readSocketSet);
- }
- if(bOK)
- {
- CHAR szBuffer[1] = "";
- iRet = ::recv(m_hSocket, szBuffer, 1, MSG_PEEK);
- bOK = (iRet > 0);
- if(!bOK)
- {
- INT iError = ::WSAGetLastError();
- bConnDropped = (( iError == WSAENETRESET) ||
- (iError == WSAECONNABORTED) ||
- (iError == WSAECONNRESET) ||
- (iError == WSAEINVAL) ||
- (iRet == 0));
- }
- }
- return(bConnDropped);
- }
- /********************************************************************/
- /* */
- /* Function name: SendResponse */
- /* Description : Send response to client. */
- /* */
- /********************************************************************/
- //发送响应给客户端
- BOOL CConnectSocket::SendResponse(LPCTSTR pstrFormat, ...)
- {
- CString str;
- // 格式化参数
- va_list args;
- va_start(args, pstrFormat);
- str.FormatV(pstrFormat, args);
- //判断连接是否在活动状态
- if (HasConnectionDropped())
- {
- FireStatusMessage("Could not send reply, disconnected.", 2);
- Close();
- // 通知线程已经停止,关闭连接
- m_pThread->PostThreadMessage(WM_THREADMSG, 1, 0);
- return FALSE;
- }
- int nBytes = CSocket::Send(str + "\r\n", str.GetLength()+2);
- if (nBytes == SOCKET_ERROR)
- {
- Close();
- FireStatusMessage("Could not send reply, disconnected.", 2);
- //通知线程连接已经关闭
- m_pThread->PostThreadMessage(WM_THREADMSG, 1, 0);
- return FALSE;
- }
- FireStatusMessage(str, 2);
- ((CConnectThread *)AfxGetThread())->IncSentBytes(nBytes);
- return TRUE;
- }
- /********************************************************************/
- /* */
- /* Function name: ParseCommand */
- /* Description : Parse and execute command from client. */
- /* */
- /* Based on code provided by FileZilla Server. */
- /* http://sourceforge.net/projects/filezilla */
- /* */
- /********************************************************************/
- //从客户端解析并执行命令
- void CConnectSocket::ParseCommand()
- {
- //命令列表
- static CFTPCommand commandList[] =
- {
- {TOK_ABOR, "ABOR", FALSE, "Abort transfer: ABOR"},
- {TOK_BYE, "BYE", FALSE, "Logout or break the connection: BYE"},
- {TOK_CDUP, "CDUP", FALSE, "Change to parent directory: CDUP"},
- {TOK_CWD, "CWD", TRUE, "Change working directory: CWD [directory-name]"},
- {TOK_DELE, "DELE", TRUE , "Delete file: DELE file-name"},
- {TOK_DIR, "DIR", FALSE, "Get directory listing: DIR [path-name]"},
- {TOK_HELP, "HELP", FALSE, "Show help: HELP [command]"},
- {TOK_LIST, "LIST", FALSE, "Get directory listing: LIST [path-name]"},
- {TOK_MKD, "MKD", TRUE, "Make directory: MKD path-name"},
- {TOK_NOOP, "NOOP", FALSE, "Do nothing: NOOP"},
- {TOK_PASS, "PASS", TRUE, "Supply a user password: PASS password"},
- {TOK_PASV, "PASV", FALSE, "Set server in passive mode: PASV"},
- {TOK_PORT, "PORT", TRUE, "Specify the client port number: PORT a0,a1,a2,a3,a4,a5"},
- {TOK_PWD, "PWD", FALSE, "Get current directory: PWD"},
- {TOK_QUIT, "QUIT", FALSE, "Logout or break the connection: QUIT"},
- {TOK_REST, "REST", TRUE, "Set restart transfer marker: REST marker"},
- {TOK_RETR, "RETR", TRUE, "Get file: RETR file-name"},
- {TOK_RMD, "RMD", TRUE, "Remove directory: RMD path-name"},
- {TOK_RNFR, "RNFR", TRUE, "Specify old path name of file to be renamed: RNFR file-name"},
- {TOK_RNTO, "RNTO", TRUE, "Specify new path name of file to be renamed: RNTO file-name"},
- {TOK_SIZE, "SIZE", TRUE, "Get filesize: SIZE file-name"},
- {TOK_STOR, "STOR", TRUE, "Store file: STOR file-name"},
- {TOK_SYST, "SYST", FALSE, "Get operating system type: SYST"},
- {TOK_TYPE, "TYPE", TRUE, "Set filetype: TYPE [A | I]"},
- {TOK_USER, "USER", TRUE, "Supply a username: USER username"},
- {TOK_ERROR, "", FALSE, ""},
- };
- // 解析命令
- CString strCommand, strArguments;
- if (!GetRxCommand(strCommand, strArguments))
- {
- return;
- }
- int nCommand;
- //在命令列表中查找命令
- for (nCommand = TOK_ABOR; nCommand < TOK_ERROR; nCommand++)
- {
- // 判断是否找到命令
- if (strCommand == commandList[nCommand].m_pszName)
- {
- if (commandList[nCommand].m_bHasArguments && (strArguments.IsEmpty()))
- {
- SendResponse("501 Syntax error: Invalid number of parameters.");
- return;
- }
- break;
- }
- }
- if (nCommand == TOK_ERROR)
- {
- // 命令不在我们的列表中
- SendResponse("501 Syntax error: Command not understood.");
- return;
- }
- //判断是否成功登录服务器
- if ((nCommand != TOK_USER && nCommand != TOK_PASS) && !m_bLoggedon)
- {
- SendResponse("530 Please login with USER and PASS.");
- return;
- }
- // 处理命令
- switch(nCommand)
- {
- //指定用户名
- case TOK_USER:
- {
- strArguments.MakeLower();
- m_bLoggedon = FALSE;
- m_strUserName = strArguments;
- CString strPeerAddress;
- UINT nPeerPort;
- //获得客户端IP地址和端口
- GetPeerName(strPeerAddress, nPeerPort);
- // 通知FTP服务器一个新的用户已经连接
- CConnectThread *pThread = (CConnectThread *)m_pThread;
- ((CCPhotoFTPReceive *)pThread->m_pWndServer)->m_pEventSink->OnFTPUserConnected(m_pThread->m_nThreadID, m_strUserName, strPeerAddress);
- SendResponse("331 User name ok, need password.");
- }
- break;
- // 指定密码
- case TOK_PASS:
- {
- //判断是否登录成功
- if (m_bLoggedon)
- {
- SendResponse("503 Login with USER first.");
- }
- else
- {
- // 用用户名和密码登录客户端
- CUser user;
- // 检查用户名
- if (theServer.m_UserManager.GetUser(m_strUserName, user))
- {
- // 检查密码
- if ((!user.m_strPassword.Compare(strArguments) || user.m_strPassword.IsEmpty()) && !user.m_bAccountDisabled)
- {
- // 设置用户路径
- m_strCurrentDir = "/";
- // 成功登录
- m_bLoggedon = TRUE;
- SendResponse("230 User successfully logged in.");
- break;
- }
- }
- SendResponse("530 Not logged in, user or password incorrect!");
- }
- }
- break;
- // 改变传输模式
- case TOK_TYPE:
- {
- SendResponse("200 Type set to %s", strArguments);
- }
- break;
- //打印当前路径
- case TOK_PWD:
- {
- SendResponse("257 \"%s\" is current directory.", m_strCurrentDir);
- }
- break;
- // 改变上层目录
- case TOK_CDUP:
- strArguments = "..";
- // 改变工作目录
- case TOK_CWD:
- {
- //改变到指定目录
- int nResult = theServer.m_UserManager.ChangeDirectory(m_strUserName, m_strCurrentDir, strArguments);
- switch(nResult)
- {
- case 0:
- SendResponse("250 CWD command successful. \"%s\" is current directory.", m_strCurrentDir);
- break;
- case 1:
- SendResponse("550 CWD command failed. \"%s\": Permission denied.", strArguments);
- break;
- default:
- SendResponse("550 CWD command failed. \"%s\": Directory not found.", strArguments);
- break;
- }
- }
- break;
- // 指定IP地址和端口
- case TOK_PORT:
- {
- CString strSub;
- int nCount=0;
- while (AfxExtractSubString(strSub, strArguments, nCount++, ','))
- {
- switch(nCount)
- {
- case 1:
- m_strRemoteHost = strSub;
- m_strRemoteHost += ".";
- break;
- case 2:
- m_strRemoteHost += strSub;
- m_strRemoteHost += ".";
- break;
- case 3:
- m_strRemoteHost += strSub;
- m_strRemoteHost += ".";
- break;
- case 4:
- m_strRemoteHost += strSub;
- break;
- case 5:
- m_nRemotePort = 256*atoi(strSub);
- break;
- case 6:
- m_nRemotePort += atoi(strSub);
- break;
- }
- }
- m_bPassiveMode = FALSE;
- SendResponse("200 Port command successful.");
- }
- // 改变到被动模式
- case TOK_PASV:
- {
- // 删除当前的数据连接
- DestroyDataConnection();
- // 创建新的数据套接字连接
- m_pDataSocket = new CDataSocket(this, -1);
- if (!m_pDataSocket->Create())
- {
- DestroyDataConnection();
- SendResponse("421 Failed to create socket.");
- break;
- }
- //开始侦听
- m_pDataSocket->Listen();
- m_pDataSocket->AsyncSelect();
- CString strIP, strTmp;
- UINT nPort;
- // 获得我们的IP地址
- GetSockName(strIP, nPort);
- //获得端口号
- m_pDataSocket->GetSockName(strTmp, nPort);
- // ss.Format ("11:%d", nPort);AfxMessageBox(ss);
- // 替换"."
- strIP.Replace(".",",");
- // 通知客户端要连接的IP地址和端口
- SendResponse("227 Entering Passive Mode (%s,%d,%d).", strIP, nPort/256, nPort%256);
- m_bPassiveMode = TRUE;
- break;
- }
- // 列出当前路径
- case TOK_LIST:
- case TOK_DIR:
- {
- // 如果不是被动模式,我们先需要PORT命令指定端口
- if(!m_bPassiveMode && (m_strRemoteHost == "" || m_nRemotePort == -1))
- {
- SendResponse("503 Bad sequence of commands.");
- }
- else
- {
- // 如果用户没有指定路径,用当前路径
- if (strArguments == "")
- {
- strArguments = m_strCurrentDir;
- }
- else
- {
- // 检查参数是文件名还是路径
- CString strResult;
- int nResult = theServer.m_UserManager.CheckFileName(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 (!CreateDataConnection(0, strListing))
- {
- DestroyDataConnection();
- }
- break;
- }
- }
- break;
- }
- // 获得文件
- case TOK_RETR:
- {
- // 如果不是被动模式,我们先需要PORT命令指定端口
- if(!m_bPassiveMode && (m_strRemoteHost == "" || m_nRemotePort == -1))
- {
- SendResponse("503 Bad sequence of commands.");
- break;
- }
- CString strResult;
- int nResult = theServer.m_UserManager.CheckFileName(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 (!CreateDataConnection(1, strResult))
- {
- DestroyDataConnection();
- }
- break;
- }
- break;
- }
- //客户端上传文件
- case TOK_STOR:
- {
- // 如果不是被动模式,我们先需要PORT命令指定端口
- if(!m_bPassiveMode && (m_strRemoteHost == "" || m_nRemotePort == -1))
- {
- SendResponse("503 Bad sequence of commands.");
- break;
- }
- /************************************************************************/
- /*
- 1.如果m_strCurrentDir包含域名字符串,表明下载的图片属于分店的,否则为本店在其他分店导入的订单相片;
- 2.一次只传一张相片,如果要写到增量表里的话,比较麻烦.只能先查询数据库是否有该分店的增量信息,如果有,且[opttime]仍为今天的,增量的content加上本次的相片名字;
- */
- /************************************************************************/
- CString strResult;
- int nResult = theServer.m_UserManager.CheckFileName(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 (!CreateDataConnection(2, strResult))
- {
- DestroyDataConnection();
- }
- break;
- }
- }
- break;
- //获得文件大小
- case TOK_SIZE:
- {
- CString strResult;
- int nResult = theServer.m_UserManager.CheckFileName(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:
- {
- CFileStatus status;
- CFile::GetStatus(strResult, status);
- SendResponse("213 %d", status.m_size);
- break;
- }
- }
- }
- break;
- // 删除文件
- case TOK_DELE:
- {
- CString strResult;
- int nResult = theServer.m_UserManager.CheckFileName(m_strUserName, strArguments, m_strCurrentDir, FTP_DELETE, strResult);
- switch(nResult)
- {
- case 1:
- SendResponse("550 Permission denied.");
- break;
- case 2:
- SendResponse("550 File not found.");
- break;
- default:
- //删除文件
- if (!DeleteFile(strResult))
- {
- SendResponse("450 Internal error deleting the file: \"%s\".", strArguments);
- }
- else
- {
- SendResponse("250 File \"%s\" was deleted successfully.", strArguments);
- }
- break;
- }
- }
- break;
- // 删除目录
- case TOK_RMD:
- {
- CString strResult;
- int nResult = theServer.m_UserManager.CheckDirectory(m_strUserName, strArguments, m_strCurrentDir, FTP_DELETE, strResult);
- switch(nResult)
- {
- case 1:
- SendResponse("550 Permission denied.");
- break;
- case 2:
- SendResponse("550 Directory not found.");
- break;
- default:
- // 删除目录
- if (!RemoveDirectory(strResult))
- {
- if (GetLastError() == ERROR_DIR_NOT_EMPTY)
- {
- SendResponse("550 Directory not empty.");
- }
- else
- {
- SendResponse("450 Internal error deleting the directory.");
- }
- }
- else
- {
- SendResponse("250 Directory deleted successfully.");
- }
- break;
- }
- }
- break;
- // 创建目录
- case TOK_MKD:
- {
- CString strResult;
- int nResult = theServer.m_UserManager.CheckDirectory(m_strUserName, strArguments, m_strCurrentDir, FTP_CREATE_DIR, strResult);
- switch(nResult)
- {
- case 0:
- SendResponse("550 Directory already exists.");
- break;
- case 1:
- SendResponse("550 Can't create directory. Permission denied.");
- break;
- default:
- //创建目录
- if (!MakeSureDirectoryPathExists(strResult))
- {
- SendResponse("450 Internal error creating the directory.");
- }
- else
- {
- SendResponse("250 Directory created successfully.");
- }
- break;
- }
- }
- break;
- //重命名文件名或者路径
- case TOK_RNFR:
- {
- CString strResult;
- int nResult = theServer.m_UserManager.CheckFileName(m_strUserName, strArguments, m_strCurrentDir, FTP_RENAME, strResult);
- if (nResult == 0)
- {
- m_strRenameFile = strResult;
- m_bRenameFile = TRUE;
- SendResponse("350 File exists, ready for destination name.");
- break;
- }
- else
- {
- // 用户端重命名目录
- nResult = theServer.m_UserManager.CheckDirectory(m_strUserName, strArguments, m_strCurrentDir, FTP_RENAME, strResult);
- switch(nResult)
- {
- case 0:
- m_strRenameFile = strResult;
- m_bRenameFile = FALSE;
- SendResponse("350 Directory exists, ready for destination name.");
- break;
- case 1:
- SendResponse("550 Permission denied.");
- break;
- default:
- SendResponse("550 File/directory not found.");
- break;
- }
- }
- }
- break;
- // 重命名文件名或目录
- case TOK_RNTO:
- {
- if (m_strRenameFile.IsEmpty())
- {
- SendResponse("503 Bad sequence of commands.");
- break;
- }
- if (m_bRenameFile)
- {
- CString strResult;
- // 检查目标文件名
- int nResult = theServer.m_UserManager.CheckFileName(m_strUserName, strArguments, m_strCurrentDir, FTP_RENAME, strResult);
- switch(nResult)
- {
- case 0:
- SendResponse("550 File already exists.");
- break;
- case 1:
- SendResponse("550 Permission denied.");
- break;
- default:
- // 重命名文件
- if (!MoveFile(m_strRenameFile, strResult))
- {
- SendResponse("450 Internal error renaming the file: \"%s\".", m_strRenameFile);
- }
- else
- {
- SendResponse("250 File \"%s\" renamed successfully.", m_strRenameFile);
- }
- break;
- }
- }
- else
- {
- CString strResult;
- // 检查目标路径名
- int nResult = theServer.m_UserManager.CheckDirectory(m_strUserName, strArguments, m_strCurrentDir, FTP_RENAME, strResult);
- switch(nResult)
- {
- case 0:
- SendResponse("550 Directory already exists.");
- break;
- case 1:
- SendResponse("550 Permission denied.");
- break;
- case 3:
- SendResponse("550 Directory invalid.");
- break;
- default:
- // 重命名路径
- if (!MoveFile(m_strRenameFile, strResult))
- {
- SendResponse("450 Internal error renaming the directory: \"%s\".", m_strRenameFile);
- }
- else
- {
- SendResponse("250 Directory \"%s\" renamed successfully.", m_strRenameFile);
- }
- break;
- }
- }
- }
- break;
- // 取消传输
- case TOK_ABOR:
- {
- if (m_pDataSocket)
- {
- if (m_pDataSocket->GetStatus() != XFERMODE_IDLE)
- {
- SendResponse("426 Data connection closed.");
- }
- //销毁数据连接
- m_pThread->PostThreadMessage(WM_THREADMSG, 0, 0);
- }
- SendResponse("226 ABOR command successful.");
- break;
- }
- // 获得系统信息
- case TOK_SYST:
- SendResponse("215 UNIX emulated by LYFZ FTP Server.");
- break;
- // 关闭连接
- case TOK_QUIT:
- case TOK_BYE:
- {
- // 发送再见消息给客户机
- CConnectThread *pThread = (CConnectThread *)m_pThread;
- SendResponse("220 %s", ((CCPhotoFTPReceive *)pThread->m_pWndServer)->GetGoodbyeMessage());
- Close();
- //通知线程已经结束关闭连接
- m_pThread->PostThreadMessage(WM_THREADMSG, 1, 0);
- break;
- }
- //重新启动传输
- case TOK_REST:
- {
- if (!IsNumeric(strArguments.GetBuffer(strArguments.GetLength())))
- {
- strArguments.ReleaseBuffer();
- SendResponse("501 Invalid parameter.");
- }
- else
- {
- strArguments.ReleaseBuffer();
- m_dwRestartOffset = atol(strArguments);
- SendResponse("350 Restarting at %d.", m_dwRestartOffset);
- }
- }
- break;
- //显示帮助信息
- case TOK_HELP:
- //如果客户端不指定命令名显示所有可有命令
- if (strArguments == "")
- {
- CString strResponse = "214-The following commands are recognized:\r\n";
- // 在命令列表中查找命令
- for (int i = TOK_ABOR; i < TOK_ERROR; i++)
- {
- strResponse += commandList[i].m_pszName;
- strResponse += "\r\n";
- }
- strResponse += "214 HELP command successful.";
- SendResponse(strResponse);
- }
- else
- {
- int nHelpCmd;
- // 在命令列表中查找命令
- for (nHelpCmd = TOK_ABOR; nHelpCmd < TOK_ERROR; nHelpCmd++)
- {
- //判断是否找到命令
- if (strArguments.CompareNoCase(commandList[nHelpCmd].m_pszName) == 0)
- {
- break;
- }
- }
- if (nHelpCmd != TOK_ERROR)
- {
- //显示命令帮助信息
- SendResponse("214 %s", commandList[nHelpCmd].m_pszDescription);
- }
- else
- {
- SendResponse("501 Unknown command %s", strArguments);
- }
- }
- break;
- // 空命令
- case TOK_NOOP:
- SendResponse("200 OK");
- break;
- default:
- SendResponse("502 Command not implemented - Try HELP.");
- break;
- }
- }
- /********************************************************************/
- /* */
- /* Function name: FireStatusMessage */
- /* Description : Fire status message. */
- /* */
- /********************************************************************/
- void CConnectSocket::FireStatusMessage(LPCTSTR lpszStatus, int nType)
- {
- CConnectThread *pThread = (CConnectThread *)m_pThread;
- ((CCPhotoFTPReceive *)pThread->m_pWndServer)->AddTraceLine(nType, "[%d] %s", m_pThread->m_nThreadID, lpszStatus);
- }
- /********************************************************************/
- /* */
- /* Function name: CreateDataConnection */
- /* Description : Create data transfer connection. */
- /* */
- /********************************************************************/
- BOOL CConnectSocket::CreateDataConnection(int nTransferType, LPCTSTR lpszData)
- {
- if (!m_bPassiveMode)
- {
- m_pDataSocket = new CDataSocket(this, nTransferType);
- if (m_pDataSocket->Create())
- {
- m_pDataSocket->AsyncSelect();
- m_pDataSocket->SetRestartOffset(m_dwRestartOffset);
- m_pDataSocket->SetData(lpszData);
- // connect to remote site
- if (m_pDataSocket->Connect(m_strRemoteHost, m_nRemotePort) == 0)
- {
- if (GetLastError() != WSAEWOULDBLOCK)
- {
- SendResponse("425 Can't open data connection.");
- return FALSE;
- }
- }
- switch(nTransferType)
- {
- case 0:
- SendResponse("150 Opening ASCII mode data connection for directory list.");
- break;
- case 1:
- case 2:
- SendResponse("150 Opening BINARY mode data connection for file transfer.");
- break;
- }
- }
- else
- {
- SendResponse("421 Failed to create data connection socket.");
- return FALSE;
- }
- }
- else
- {
- m_pDataSocket->SetRestartOffset(m_dwRestartOffset);
- m_pDataSocket->SetData(lpszData);
- m_pDataSocket->SetTransferType(nTransferType, TRUE);
- }
- return TRUE;
- }
- /********************************************************************/
- /* */
- /* Function name: DestroyDataConnection */
- /* Description : Close data transfer connection. */
- /* */
- /********************************************************************/
- void CConnectSocket::DestroyDataConnection()
- {
- if (!m_pDataSocket)
- return;
- /////////////////////////////xiao
- SOCKET s=m_pDataSocket->Detach ();
- closesocket( s) ;
- //////////////////////////////
- delete m_pDataSocket;
- // reset transfer status
- m_pDataSocket = NULL;
- m_strRemoteHost = "";
- m_nRemotePort = -1;
- m_dwRestartOffset = 0;
- m_bPassiveMode = FALSE;
- }
- //RETR
|