⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ftpuser.cpp

📁 在Linux下使用GCC编制的FTP服务器
💻 CPP
字号:
#include "Public.h"
#include "Tools.h"
#include "FtpUser.h"
#include <mysql/mysql.h>

CFtpUser::CFtpUser()
{
}

CFtpUser::~CFtpUser()
{
}

int CFtpUser::Load(const char *pszPasswd)
{
	MYSQL conn;
    MYSQL_RES *pRst;
    MYSQL_ROW  row;	
    PRIV priv;
	char szDbSvr[64],szDbName[64],szDbUser[64],szDbPasswd[64];
	string sSql;
	//
	ReadConfig("DBServer","127.0.0.1",szDbSvr,
				sizeof(szDbSvr),"./ftpsvr.cfg");
	ReadConfig("DBName","ftpsvr",szDbName,
				sizeof(szDbName),"./ftpsvr.cfg");
	ReadConfig("DBUser","ftpsvr",szDbUser,
				sizeof(szDbUser),"./ftpsvr.cfg");
	ReadConfig("DBPassword","123456",szDbPasswd,
				sizeof(szDbPasswd),"./ftpsvr.cfg");
    if(!mysql_init(&conn)){
        perror("Init mysql failed.");
        return -2;
    }
    if(!mysql_real_connect(
                    &conn,
                    szDbSvr,
                    szDbUser,
                    szDbPasswd,
                    szDbName,
                    0,
                    NULL,
                    0)){
        printf("Connect mysql fail:%s\n",mysql_error(&conn));
        return -3;
    }
    sSql="select RealRootDir,Dir,Privilege from FtpUser,Privilege"
		 " where FtpUser.Id=Privilege.Id and Name='";
    sSql+=m_sUser+"' and Password=PASSWORD('"+pszPasswd+"')";
	m_sRealRootDir.erase();
	m_priv.clear();
	if(mysql_query(&conn,sSql.c_str())==0){
		if((pRst=mysql_store_result(&conn))){
	    	while((row=mysql_fetch_row(pRst))){
	    		if(m_sRealRootDir.empty()){
	    			m_sRealRootDir=row[0];//重复赋值,
	    		}
	    		priv.sDir=row[1];
	    		strcpy(priv.szPriv,row[2]);
	    		m_priv.push_back(priv);
	    	}
		    mysql_free_result(pRst);
		}
    }
    mysql_close(&conn);
	if(m_sRealRootDir.empty() || m_priv.empty()){
    	printf("Query fail:%s\n",mysql_error(&conn));
		return -4;
	}
	m_sDir="/";
	if(m_sRealRootDir[m_sRealRootDir.length()-1]!='/')
		m_sRealRootDir+='/';
	return 0;
}

bool CFtpUser::IsLoaded()
{
	return !m_sDir.empty() && !m_sRealRootDir.empty();
}

const char *CFtpUser::GetDir()
{
	return m_sDir.c_str();
}

void CFtpUser::GetRealDir(string &sRealDir)
{
	DirToRealDir(sRealDir,m_sDir.c_str());
}

//变换虚拟目录
int CFtpUser::ChangeDir(const char *pszDir)
{
	string sNewDir,sNewRealDir;
	DIR *pDir;
	//
	if(!DirToAbsDir(sNewDir,pszDir))	
		return -1;
	if(sNewDir[sNewDir.length()-1]!='/')
		sNewDir+='/';
	if(!DirToRealDir(sNewRealDir,sNewDir.c_str()))
		return -2;
	if(!IsDir(sNewRealDir.c_str()))
		return -3;
	pDir=opendir(sNewRealDir.c_str());
	if(pDir==NULL)
		return -4;
	closedir(pDir);
	m_sDir=sNewDir;
	return 0;
}

int CFtpUser::Mkdir(const char *pszDir)
{
	string sRealDir;
	int iRet=DirToRealDir(sRealDir,pszDir,'w');
	if(iRet<0)
		return iRet;
	if(mkdir(sRealDir.c_str(),0700)!=0)
		return -4;
	return 0;
}

int CFtpUser::Rmdir(const char *pszDir)
{
	string sRealDir;
	int iRet=DirToRealDir(sRealDir,pszDir,'w');
	if(iRet<0)
		return iRet;
	if(!IsDir(sRealDir.c_str()))
		return -4;
	if(rmdir(sRealDir.c_str())!=0)
		return -5;
	return 0;
}

int CFtpUser::GetFileSize(const char *pszArg)
{
	string sRealFile;
	int iSize;
	int iRet=DirToRealDir(sRealFile,pszArg,'r');
	if(iRet<0)
		return iRet;
	if(!IsFile(sRealFile.c_str()))
		return -4;
	iSize=Tools::GetFileSize(sRealFile.c_str());
	if(iSize<0)
		return -5;
	return iSize;
}

int CFtpUser::RenameFrom(const char *pszArg)
{
	string sRealDir;
	int iRet=DirToRealDir(sRealDir,pszArg,'w');
	if(iRet<0)
		return iRet;
	if(!IsDir(sRealDir.c_str()) && 
	   !IsFile(sRealDir.c_str()))
		return -4;
	m_sRealFrom=sRealDir;
	return 0;
}

int CFtpUser::RenameTo(const char *pszArg)
{
	string sRealTo;
	if(m_sRealFrom.empty())
		return -1;
	int iRet=DirToRealDir(sRealTo,pszArg,'w');
	if(iRet<0)
		return iRet-1;
	if(rename(m_sRealFrom.c_str(),sRealTo.c_str())!=0)
		return -5;
	m_sRealFrom="";
	return 0;
}

int CFtpUser::BuildList(string &sList)
{
	string sRealDir,sFullPath;
	DIR *pDir;
	dirent *pDirInfo;
	struct stat fStatus;
	char szBuf[300];
	//
	sList="";
	if(!CheckPrivilege(m_sDir.c_str(),'r'))	
		return -1;
	GetRealDir(sRealDir);
	pDir=opendir(sRealDir.c_str());
	if(pDir==NULL){
		printf("operndir fail:%s\n",sRealDir.c_str());
		return -2;
	}
	while((pDirInfo=readdir(pDir)))
	{
		if(pDirInfo->d_name[0]=='.')
			continue;
		sFullPath=sRealDir+pDirInfo->d_name;
		if(stat(sFullPath.c_str(),&fStatus)==-1){
			break;
		}
		sprintf(
			szBuf,
			"%crwx------ %d user group %u %s %s\r\n",
			S_ISDIR(fStatus.st_mode)? 'd':'-',
			fStatus.st_nlink,
			(unsigned int)(fStatus.st_size),
			FormatDate(time_t(fStatus.st_mtime)),
			pDirInfo->d_name);
		sList+=szBuf;	
	}
	closedir(pDir);
	//printf("build list:%s\n",sList.c_str());
	return 0;
}

int CFtpUser::BuildStor(string &sRealFile,const char *pszFile)
{
	sRealFile="";
	return DirToRealDir(sRealFile,pszFile,'w');
}

int CFtpUser::BuildRetr(string &sRealFile,const char *pszFile)
{
	sRealFile="";
	int iRet=DirToRealDir(sRealFile,pszFile,'w');
	if(iRet<0)
		return iRet;
	if(!IsFile(sRealFile.c_str()))
		return -4;
	return 0;
}

bool CFtpUser::CheckPrivilege(const char *pszDir,
				    		  char cMode)
{
	vector<PRIV>::iterator pos;
	for(pos=m_priv.begin(); pos!=m_priv.end(); ++pos){
		if(strstr(pszDir,pos->sDir.c_str())){
			if(!strchr(pos->szPriv,cMode)){
				printf("Check %s %c fail\n",pszDir,cMode);
				return false;
			}
		}
	}
	return true;//采用不禁止就是允许的的规则
}

bool CFtpUser::DirToRealDir(string &sRealDir,
							const char *pszDir)
{
	sRealDir=m_sRealRootDir;
	sRealDir+=(pszDir+1);
	return true;
}

bool CFtpUser::RealDirToDir(string &sDir,
							const char *pszRealDir)
{
	if(m_sRealRootDir.find(pszRealDir)!=0)
		return false;
	sDir=m_sDir+(pszRealDir+m_sRealRootDir.length());
	return true;
}

bool CFtpUser::DirToAbsDir(string &sAbsDir,
						   const char *pszDir)
{
	size_t nPos;
    //pszDir是绝对路径的情况
    if(*pszDir=='/'){
		sAbsDir=pszDir;
    }else{//pszDir是相对路径的情况
		sAbsDir=m_sDir;
		//先处理"../../"的情况
		while(memcmp(pszDir,"..",2)==0){
			nPos=sAbsDir.rfind('/',sAbsDir.length()-2);
			if(nPos==string::npos){
				return false;//到根目录以上了
			}
			sAbsDir.erase(nPos+1);
			pszDir+=2;
			if(*pszDir=='/')
				pszDir++;
		}
		sAbsDir+=pszDir;
	}
	//不允许再包含".."之类的情况出现
	return sAbsDir.find("..")==string::npos;
}

const char *CFtpUser::FormatDate(time_t t)
{
	static char szBuf[64];
	struct tm* ptmTemp = localtime(&t);
	time_t tNow;
	//
	memset(szBuf,0,sizeof(szBuf));
	time(&tNow);
	if((tNow-t)/(24*3600)>365){
		strftime(szBuf,sizeof(szBuf),"%b %d %Y",ptmTemp);
	}else{
		strftime(szBuf,sizeof(szBuf),"%b %d %H:%M",ptmTemp);
	}
	return szBuf;
}

int CFtpUser::DeleFile(const char *pszFile)
{
	string sRealFile;
	int iRet=DirToRealDir(sRealFile,
						  pszFile,
						  'w');
	if(iRet<0)						  
		return iRet;
	if(unlink(sRealFile.c_str())!=0)
		return -4;
	return 0;
}

int CFtpUser::DirToRealDir(string &sRealDir,
						   const char *pszDir,
						   char chMode)
{
	string sDir;
	if(!DirToAbsDir(sDir,pszDir))
		return -1;
	if(!CheckPrivilege(sDir.c_str(),chMode))
		return -2;
	if(!DirToRealDir(sRealDir,sDir.c_str()))
		return -3;
	return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -