#include "srvpi.h"
SrvPI::SrvPI(string dbFilename, int connfd): packet(this), readpacket(this), db(DBFILENAME)
{
this->connfd = connfd;
connSockStream.init(connfd);
sessionCommandPacketCount = 0;
userID ="0";
this->fp = NULL;
}
bool SrvPI::recvOnePacket()
{
// clear temporary variables of one tinyFTP transaction
// this->filename.clear();
// this->abspath.clear();
int n;
packet.reset(NPACKET);
if ( (n = connSockStream.readn(packet.getPs(), PACKSIZE)) == 0)
{
this->saveUserState();
Socket::tcpClose(connfd);
Error::quit_pthread("client terminated prematurely");
} else if (n < 0){
this->saveUserState();
Socket::tcpClose(connfd);
Error::ret("connSockStream.readn() error");
Error::quit_pthread("socket connection exception");
} else {
packet.ntohp();
//packet.print();
}
return true;
}
bool SrvPI::sendOnePacketBlocked(PacketStruct * ps, size_t nbytes)
{
int m;
if ( (m = connSockStream.writen(ps, nbytes)) < 0 || (size_t)m != nbytes )
{
this->saveUserState();
Socket::tcpClose(connfd);
Error::ret("connSockStream.writen()");
Error::quit_pthread("socket connection exception");
return false;
} else {
return true;
}
}
bool SrvPI::sendOnePacket(PacketStruct * ps, size_t nbytes)
{
int n, m;
bool sendFlag = false;
int maxfdp1;
fd_set rset, wset;
FD_ZERO(&rset);
FD_ZERO(&wset);
while(!sendFlag) {
FD_SET(connfd, &rset);
FD_SET(connfd, &wset);
maxfdp1 = connfd + 1;
if (select(maxfdp1, &rset, &wset, NULL, NULL) < 0)
{
this->saveUserState();
Socket::tcpClose(connfd);
Error::ret("select error");
Error::quit_pthread("socket connection exception");
}
if (FD_ISSET(connfd, &rset)) /* socket is readable */
{
readpacket.reset(NPACKET);
if ( (n = connSockStream.readn(readpacket.getPs(), PACKSIZE)) == 0)
{
this->saveUserState();
Socket::tcpClose(connfd);
Error::quit_pthread("client terminated prematurely");
} else if (n < 0){
this->saveUserState();
Socket::tcpClose(connfd);
Error::ret("connSockStream.readn() error");
Error::quit_pthread("socket connection exception");
} else {
if (n == PACKSIZE)
{
readpacket.ntohp();
printf("sendOnePacket method recive one packet: %s\n", readpacket.getSBody().c_str());
//readpacket.print();
} else {
printf("ERROR: sendOnePacket method recive one packet: n != PACKSIZE");
}
}
}
if (FD_ISSET(connfd, &wset)) /* socket is writable */
{
if ( (m = connSockStream.writen(ps, nbytes)) < 0 || (size_t)m != nbytes )
{
this->saveUserState();
Socket::tcpClose(connfd);
Error::ret("connSockStream.writen()");
Error::quit_pthread("socket connection exception");
} else {
sendFlag = true;
}
}
}
return true;
}
void SrvPI::run()
{
recvOnePacket();
std::cout<< "\n\n\033[32mNewCMD connfd: " << connfd << " [" << userRootDir <<" " << userRCWD << "]\033[0m" << std::endl;
sessionCommandPacketCount++;
// if (std::stoul(userID) != packet.getSesid())
// {
// Error::quit_pthread("session failed");
// }
// vector<string> testVector;
// split("home", "///!", testVector);
// for (vector<string>::iterator iter=testVector.begin(); iter!=testVector.end(); ++iter)
// {
// std::cout << "test[" << *iter << "]" << '\n';
// }
if (packet.getTagid() == TAG_CMD)
{
switch(packet.getCmdid())
{
case USER:
cmdUSER();
break;
case PASS:
cmdPASS();
break;
case USERADD:
cmdUSERADD();
break;
case USERDEL:
cmdUSERDEL();
break;
case GET:
cmdGET();
break;
case RGET:
cmdRGET();
break;
case PUT:
cmdPUT();
break;
case RPUT:
cmdRPUT();
break;
case LS:
cmdLS();
break;
case CD:
cmdCD();
break;
case RM:
cmdRM();
break;
case PWD:
cmdPWD();
break;
case MKDIR:
cmdMKDIR();
break;
case RMDIR:
cmdRMDIR();
break;
case SHELL:
cmdSHELL();
break;
default:
Error::msg("Server: Sorry! this command function not finished yet.\n");
break;
}
} else {
Error::msg("Error: received packet is not a command.\n");
packet.print();
Error::quit_pthread("*********socket connection exception*********");
}
}
void SrvPI::split(std::string src, std::string token, vector<string>& vect)
{
int nbegin=0;
int nend=0;
while(nend != -1 && (unsigned int)nbegin < src.length() )
{
nend = src.find_first_of(token, nbegin);
if(nend == -1) {
vect.push_back(src.substr(nbegin, src.length()-nbegin));
} else {
if (nend != nbegin )
{
vect.push_back(src.substr(nbegin, nend-nbegin));
}
}
nbegin = nend + 1;
}
}
// static void Split(const char* content, const char* token, vector<std::string>& vect)
// {
// if(content == NULL)
// return;
// int len = strlen(content);
// if(len <= 0)
// return;
// char* pBuf =(char*)malloc(len+1);
// strcpy(pBuf , content);
// // not thread safe
// char* str = strtok(pBuf , token);
// while(str != NULL)
// {
// vect.push_back(str);
// str = strtok(NULL, token);
// }
// free(pBuf);
// }
void SrvPI::cmdUSER()
{
printf("USER request\n");
vector<string> paramVector;
split(packet.getSBody(), "\t", paramVector);
std::map<string, string> selectParamMap = { {"username", paramVector[0]} };
if (db.select("user", selectParamMap))
{
vector< map<string ,string> > resultMapVector = db.getResult();
if (!resultMapVector.empty())
{
packet.sendSTAT_OK("this username exists");
} else {
packet.sendSTAT_ERR("no such username");
}
}else {
packet.sendSTAT_ERR("Database select error");
}
}
void SrvPI::cmdPASS()
{
printf("PASS request\n");
vector<string> paramVector;
split(packet.getSBody(), DELIMITER, paramVector);
// for (vector<string>::iterator iter=paramVector.begin(); iter!=paramVector.end(); ++iter)
// {
// std::cout << "paramVector[" << *iter << "]" << '\n';
// }
std::map<string, string> selectParamMap = { {"username", paramVector[0]}, {"password", paramVector[1]} };
if (db.select("user", selectParamMap))
{
vector< map<string ,string> > resultMapVector = db.getResult();
if (!resultMapVector.empty())
{
// init userID, userRootDir, and userRCWD
userID = resultMapVector[0]["ID"];
userRootDir = ROOTDIR + resultMapVector[0]["USERNAME"];
userRCWD = resultMapVector[0]["RCWD"];
// set session ID: important
packet.setSessionID(std::stoul(userID));
//packet.print();
packet.sendSTAT_OK("Welcome to tinyFTP, written by Charles Wenchy <wenchy.zwz@gmail.com>\n" \
+ resultMapVector[0]["USERNAME"] + ", your last working directory is: ~" + userRCWD);
} else {
packet.sendSTAT_ERR("error: username mismatch password");
}
} else {
packet.sendSTAT_ERR("Database select error");
}
}
void SrvPI::cmdUSERADD()
{
printf("USERADD request\n");
if (userID != "1")
{
packet.sendSTAT_ERR("Permission denied, admin required");
return;
}
vector<string> paramVector;
split(packet.getSBody(), DELIMITER, paramVector);
std::map<string, string> selectParamMap = { {"username", paramVector[0]} };
if (db.select("user", selectParamMap))
{
vector< map<string ,string> > resultMapVector = db.getResult();
if (!resultMapVector.empty())
{
packet.sendSTAT_ERR("User '" + paramVector[0] + "' already exists");
return;
}
}else {
packet.sendSTAT_ERR("Database select error");
}
std::map<string, string> insertParamMap = { {"username", paramVector[0]}, {"password", paramVector[1]} };
if (db.insert("user", insertParamMap))
{
string path = ROOTDIR + paramVector[0];
if(mkdir(path.c_str(), 0777) == -1)
没有合适的资源?快使用搜索试试~ 我知道了~
cpp实现ftp服务器.zip
共30个文件
h:15个
cpp:14个
so:1个
需积分: 0 1 下载量 115 浏览量
2024-03-06
21:07:30
上传
评论
收藏 488KB ZIP 举报
温馨提示
用c++实现ftp服务器
资源推荐
资源详情
资源评论
收起资源包目录
cpp实现ftp服务器.zip (30个子文件)
tinyFTP-master
include
sqlite3.h 371KB
sqlite3ext.h 28KB
lib
libsqlite3.so 883KB
client
clipi.cpp 37KB
clidtp.h 919B
ui.cpp 7KB
clipi.h 3KB
ui.h 721B
client.cpp 642B
clidtp.cpp 6KB
common
common.cpp 16KB
sockstream.cpp 2KB
socket.cpp 3KB
error.h 1KB
database.cpp 17KB
common.h 7KB
pi.cpp 18B
packet.cpp 13KB
packet.h 3KB
sockstream.h 1KB
socket.h 1KB
database.h 1KB
pi.h 536B
error.cpp 2KB
server
srvdtp.cpp 12KB
srvdtp.h 890B
server.cpp 1KB
server.h 279B
srvpi.cpp 45KB
srvpi.h 2KB
共 30 条
- 1
资源评论
include<me>
- 粉丝: 10
- 资源: 6
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功