📄 warsvrprotocolftp.cpp
字号:
#include "StdAfx.h"#include "WarSvrProtocolFtp.h" // class implemented#ifdef ERROR# undef ERROR#endif#ifndef WAR_LOG_H# include "WarLog.h"#endif#ifndef WAR_SVR_PROTOCOL_FTP_MACROS_H# include "WarSvrProtocolFtpMacros.h"#endif#ifndef WAR_SVR_PROTOCOL_FTP_CMD_ALL_H# include "WarSvrProtocolFtpCmdAll.h" #endif#ifndef WAR_AUTO_LOCK_H# include "WarAutoLock.h"#endif#ifndef WAR_SVR_ENGINE_H# include "WarSvrEngine.h"#endif#ifndef WAR_TIMER_H# include "WarTimer.h"#endif#ifndef WAR_PERFMON_DEF_H# include "WarPerfmonDef.h"#endif#ifndef WAR_USER_AUTH_IMPERSONATE_H# include "WarUserAuthImpersonate.h"#endif#ifndef WAR_UNICODE_H# include "WarUnicode.h"#endif#define AUTO_LOCK WarAutoLock MyLock(mSvrLock);#define AUTO_DATA_LOCK WarAutoLock my_lock(mSvrLock);/////////////////////////////// MACROS ////////////////////////////////////////* * Definitions for the TELNET protocol. */#define IAC 255 /* interpret as command: */#define DONT 254 /* you are not to use option */#define DO 253 /* please, you use option */#define WONT 252 /* I won't use option */#define WILL 251 /* I will use option *//////////////////////////////// PUBLIC /////////////////////////////////////////============================= LIFECYCLE ====================================WarSvrProtocolFtp::WarSvrProtocolFtp(war_socket_io_ptr_t& companionPtr, WarSvrDefinition& svrDefinion) :WarSvrProtocol(companionPtr, svrDefinion),mCurrentFileLength(0),mLastTransferTime((war_time_t)0),mCurrentpendingBytes(0),mCurrentInputBytes(0){ mProtocolType = PROT_FTP; WarLog err_log(WARLOG_ERROR, "WarSvrProtocolFtp::WarSvrProtocolFtp()", this); WAR_DB_PERFMON_INC(WAR_PRFDEBUG_NUM_FTPCTL); AddLogIdentifierTag("FTPD");#define ADD_MACRO(name, arg) { \ war_macro_ptr_t tmp_ptr = new name arg;\ mReply.InstallMacro(tmp_ptr);\} try { mReply.AssignToServer(this); ADD_MACRO(MacroProgramname, ;) ADD_MACRO(MacroProgramversion, ;) ADD_MACRO(MacroPrgcopyright, ;) ADD_MACRO(MacroUser, (*this)) ADD_MACRO(MacroOrigin, (mRemoteAddress)) ADD_MACRO(MacroOsname, ;) ADD_MACRO(MacroPwd, (*this)) ADD_MACRO(MacroCurrentfilename, (mCurrentFile)) ADD_MACRO(MacroCurrentpath, (mCurrentFile)) ADD_MACRO(MacroRest, (mTransferMode)) ADD_MACRO(MacroCurrenttype, (mTransferMode)) ADD_MACRO(MacroCurrentstructure, (mTransferMode)) ADD_MACRO(MacroCurrentform, (mTransferMode)) ADD_MACRO(MacroCurrentmode, (mTransferMode)) ADD_MACRO(MacroHelpcmds, (GetFtpCmds())) ADD_MACRO(MacroHostdomainname, (mLocalAddress)) ADD_MACRO(MacroRemotedomainname, (mRemoteAddress)) ADD_MACRO(MacroHostaddress, (mLocalAddress)) ADD_MACRO(MacroRemoteaddress, (mRemoteAddress)) ADD_MACRO(MacroRcvbytes, (mFtpStat)) ADD_MACRO(MacroSndbytes, (mFtpStat)) ADD_MACRO(MacroRcvfiles, (mFtpStat)) ADD_MACRO(MacroSndfiles, (mFtpStat)) ADD_MACRO(MacroNumbytes, (mFtpStat)) ADD_MACRO(MacroNumfiles, (mFtpStat)) ADD_MACRO(MacroTrafficinbytes, (mFtpStat)) ADD_MACRO(MacroTrafficoutbytes, (mFtpStat)) ADD_MACRO(MacroTrafficnumbytes, (mFtpStat)) ADD_MACRO(MacroRcvtransfers, (mFtpStat)) ADD_MACRO(MacroSndtransfers, (mFtpStat)) ADD_MACRO(MacroNumtransfers, (mFtpStat)) ADD_MACRO(MacroDataconn, (*this)) ADD_MACRO(MacroFeatures, (*this)) ADD_MACRO(MacroLocaltime, ;) ADD_MACRO(MacroGmttime, ;) ADD_MACRO(MacroCurrentcmd, (mFtpCommands)) ADD_MACRO(MacroCurrentfilelen, (mCurrentFileLength)) ADD_MACRO(MacroCurrenttransbytes, (mLastTransferBytes)) ADD_MACRO(MacroCurrenttransrate, (mLastTransferCps)) ADD_MACRO(MacroCurrenttranstime, (mLastTransferTime)) ADD_MACRO(MacroDirmsg, (*this)) ADD_MACRO(MacroEmail, (*this)) ADD_MACRO(MacroExplainerr, (mLastError)) ADD_MACRO(MacroGreeting, (*this)) ADD_MACRO(MacroDiskfree, (*this)) ADD_MACRO(MacroIdletimelm, (mIdleTimeSeconds)) ADD_MACRO(MacroSystemname, (GetSiteName())) ADD_MACRO(MacroRfc1700OsName, (*this)) } catch(WarException& ex) { err_log << "Caught exception during macro setup. " << ex.Explain() << " I'm ignoring the error and continuing." << war_endl; }#undef ADD_MACRO#define ADD_FTPCMD(cmd) {\ war_ftpcmd_ptr_t tmp_ptr = new cmd(*this);\ mFtpCommands.InnstallCommand(tmp_ptr);\} try { mFtpCommands.AssignToServer(this); ADD_FTPCMD(FtpCmdUser); ADD_FTPCMD(FtpCmdPass); ADD_FTPCMD(FtpCmdPort); ADD_FTPCMD(FtpCmdPasv); ADD_FTPCMD(FtpCmdType); ADD_FTPCMD(FtpCmdRetr); ADD_FTPCMD(FtpCmdList); ADD_FTPCMD(FtpCmdNlst); ADD_FTPCMD(FtpCmdCwd); ADD_FTPCMD(FtpCmdCdup); ADD_FTPCMD(FtpCmdPwd); ADD_FTPCMD(FtpCmdQuit); ADD_FTPCMD(FtpCmdStor); ADD_FTPCMD(FtpCmdStou); ADD_FTPCMD(FtpCmdRest); ADD_FTPCMD(FtpCmdSyst); ADD_FTPCMD(FtpCmdHelp); ADD_FTPCMD(FtpCmdAcct); ADD_FTPCMD(FtpCmdSmnt); ADD_FTPCMD(FtpCmdRein); ADD_FTPCMD(FtpCmdStru); ADD_FTPCMD(FtpCmdMode); ADD_FTPCMD(FtpCmdAllo); ADD_FTPCMD(FtpCmdAppe); ADD_FTPCMD(FtpCmdRnfr); ADD_FTPCMD(FtpCmdRnto); ADD_FTPCMD(FtpCmdAbor); ADD_FTPCMD(FtpCmdDele); ADD_FTPCMD(FtpCmdRmd); ADD_FTPCMD(FtpCmdMkd); ADD_FTPCMD(FtpCmdStat); ADD_FTPCMD(FtpCmdNoop); ADD_FTPCMD(FtpCmdSite); ADD_FTPCMD(FtpCmdMdtm); ADD_FTPCMD(FtpCmdSize);#if WAR_RFC2389 ADD_FTPCMD(FtpCmdFeat); ADD_FTPCMD(FtpCmdOpts);#endif // WAR_RFC2389#undef ADD_FTPCMD mFtpCommands.InstallAlias("XPWD", "PWD"); mFtpCommands.InstallAlias("XCWD", "CWD"); mFtpCommands.InstallAlias("XRMD", "RMD"); mFtpCommands.InstallAlias("XMKD", "MKD"); } catch(WarException& ex) { err_log << "Caught exception during command setup. " << ex.Explain() << " I'm ignoring the error and continuing. (I'm stupid!)" << war_endl; }}// WarSvrProtocolFtpWarSvrProtocolFtp::~WarSvrProtocolFtp(){ AUTO_DATA_LOCK if (!mDataConnectionPtr.IsEmpty()) { if (mDataConnectionPtr->IsOpen()) mDataConnectionPtr->Abort(WAR_FTPDERR_ABORTED); mDataConnectionPtr = NULL; } WAR_DB_PERFMON_DEC(WAR_PRFDEBUG_NUM_FTPCTL);}// ~WarSvrProtocolFtp//============================= OPERATORS ====================================//============================= OPERATIONS ===================================void WarSvrProtocolFtp::Abort(const WarError& reason) throw(WarException){ CloseConnection(reason, true);}void WarSvrProtocolFtp::CloseConnection(const WarError& reason, bool doSayGoodbye){ mLastError = reason; if (mDataConnectionPtr) { try { if (mDataConnectionPtr->IsOpen()) { mDataConnectionPtr->Abort(WAR_FTPDERR_ABORTED); mDataConnectionPtr = NULL; } } catch(WarException) { ; } } if (IsOpen()) { if (doSayGoodbye) { try { if (reason) { // Throws if the socket operation fails mReply << SM_CTRLC_CLOSED_ERR << reason.Explain() << FTPR_BYE_421; } else { // Throws if the socket operation fails mReply << SM_GOODBYE_QUIT << FTPR_BYE_421; } } catch(WarException) { ; } } Close(); } Logout(); GetEngine().UnregisterSession(*this); // Kill references WarTimer::GetTimer().KillEvent( (WarPtrWrapper<class WarTimerEvent>&)mTimerPtr); mTimerPtr = NULL; WarThrow(reason, NULL);}void WarSvrProtocolFtp::CreateDataConnection() throw(WarException){ war_socket_io_ptr_t io_ptr; io_ptr = mpCompanion->CreateSame(); mDataConnectionPtr = new WarSvrProtocolFtpDataConn(io_ptr, *this); }void WarSvrProtocolFtp::InnstallSiteCommand(war_ftpcmd_ptr_t& command, bool doReplace) throw(WarException){ ((FtpCmdSite *)(mFtpCommands.GetCmdPtr("SITE")))->InnstallCommand( command, doReplace);}void WarSvrProtocolFtp::InstallSiteAlias(war_ccstr_t strAlias, war_ccstr_t strCommand) throw(WarException){ ((FtpCmdSite *)(mFtpCommands.GetCmdPtr("SITE")))->InstallAlias( strAlias, strCommand);}//============================= ACCESS ===================================WarSvrProtocolFtpCmd *WarSvrProtocolFtp::GetCmdPtr(war_ccstr_t cmdName){ return mFtpCommands.GetCmdPtr(cmdName);}//============================= INQUIRY ===================================#if WAR_RFC2389const std::string WarSvrProtocolFtp::GetFeatures() const{ return mFtpCommands.GetFeatures();}#endif // WAR_RFC2389//============================ Callback ===================================void WarSvrProtocolFtp::OnTimer(){ AUTO_LOCK war_datasck_ptr_t my_dataconn_ptr; { if (!IsOpen()) return; if (IsTransfering() && !mDataConnectionPtr.IsEmpty()) { // Check the data connection if (mDataConnectionPtr->GetIdleTimeSince().IsTimeOut()) { mDataConnectionPtr->Abort(WAR_ERR_TIMED_OUT); } } else { // Check our own timer if (mIdleTime.IsTimeOut(mIdleTimeSeconds * 1000)) { try { CloseConnection(WarError(WAR_ERR_TIMED_OUT), false); } catch(WarException) { return; } } } } return;}void WarSvrProtocolFtp::OnTransferStart(bool isSending, bool isTmpFile, bool isStou){#ifdef DEBUG if (isStou) { assert(false == isSending); }#endif // Transfer in progress if (isStou) mReply << SM_STARTING_STOU; else if (isSending) mReply << SM_STARTING_RETR; else mReply << SM_STARTING_SEND; if (!mDataConnectionPtr.IsEmpty() && mDataConnectionPtr->IsOpen()) mReply << FTPR_USING_OPEN_CONN_OK_125; else mReply << FTPR_OPENING_CONN_OK_150; SetConnectionState(isSending ? PUTFILE : GETFILE); }void WarSvrProtocolFtp::OnTransferDone(const WarError& status){ mLastError = status; ResetIdleTimer(); if (mDataConnectionPtr && mDataConnectionPtr->IsOpen()) mDataConnectionPtr->Close(); ConnectionStatesE state = GetConnectionState(); WarLog debug_log(WARLOG_DEBUG, "WarSvrProtocolFtp::OnTransferDone()", this); WarLog trans_log(state == GETFILE ? WARLOG_RCVFILE : WARLOG_SNDFILE, "WarSvrProtocolFtp::OnTransferDone()", this); std::string status_text; int st_offset = ((state == GETFILE) ? 0 : 1) + (status ? 4 : 0); // Update statistics if (mDataConnectionPtr) { mLastTransferBytes = mDataConnectionPtr->GetBytesReceived() + mDataConnectionPtr->GetBytesSent(); mLastTransferTime = mDataConnectionPtr->GetConnectedTime(); if (mLastTransferTime.mTime) mLastTransferCps = (mLastTransferBytes * 1000) / mLastTransferTime.mTime; else mLastTransferCps = 0; if (mDataConnectionPtr->GetBytesReceived() > 0) AddToSessionFiles(mCurrentFile); } else { mLastTransferBytes = 0; mLastTransferCps = 0; mLastTransferTime.mTime = 0; } try { if (st_offset >= 0) { mFtpStat.AddValue((WarSvrProtocolFtpStat::StatItemE) (WarSvrProtocolFtpStat::ST_FILETRANS_BYTES_IN + st_offset), ((st_offset % 1) == 0) ? mDataConnectionPtr->GetBytesSent() : mDataConnectionPtr->GetBytesReceived());
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -