?? server.cpp
字號(hào):
#include <fstream>
#include <sstream>
#include <unistd.h>
#include "server.h"
using namespace std;
const string Server::FTP_ROOT = ".";
TcpFactory* Server::listenTcp = new Tcpfactory;
map<string, string> Server::users;
Server::Server(Tcp* ctrl) {
pi = ctrl;
logon = false;
passive = false;
dataType = Tcp::ASCII;
}
Server::~Server() {
delete pi;
delete data;
}
Server* Server::listen(int port) {
listenTcp->setLocalPort(port);
return new Server(listenTcp->listen());
}
void Server::addUser(const string& username, const string& password) {
users.insert(make_pair(username, password));
}
void Server::start() {
delete listenTcp;
pi->write("220 FTP Server ready.");
while(true) {
string command = pi->read();
try {
if(command.substr(0, 5)=="USER ") {
map<string, string>::iterator user = users.find(command.substr(5));
if(user==users.end()) {
pi->write("530 Not logged in.");
logon = false;
continue;
}
if(user->second.length()) {
pi->write("331 User name okay, need password.");
if(pi->read()!="PASS "+user->second) {
pi->write("530 Not logged in.");
logon = false;
continue;
}
}
pi->write("230 User logged in, proceed.");
logon = true;
} else if(command.substr(0, 4)=="CWD ") {
if(checkPermission())
if(access(dir.buildFullname(FTP_ROOT, command.substr(4)).c_str(), X_OK))
pi->write("550 No such file or directory.");
else {
dir.cd(command.substr(4));
pi->write("250 CWD command successful.");
}
} else if(command=="CDUP") {
if(checkPermission()) {
dir.cd("..");
pi->write("200 CDUP command successful.");
}
} else if(command=="QUIT") {
pi->write("221 Goodbye.");
logon = false;
return;
} else if(command.substr(0, 5)=="PORT ") {
if(checkPermission()) {
int addr = 0;
int port;
int i = 5;
for(int j=0; j<5; j++) {
int comma = command.find(',', i);
if(j<4)
addr = (addr<<8)+atoi(command.substr(i, comma-i).c_str());
else
port = atoi(command.substr(i, comma-i).c_str());
i = comma+1;
}
port = (port<<8)+atoi(command.substr(i).c_str());
dtp.setDest(addr, port);
passive = false;
pi->write("200 PORT command successful.");
}
} else if(command=="PASV") {
if(checkPermission()) {
int addr = pi->getLocalAddr();
int port = rand();
stringstream ss;
ss << "227 Entering Passive Mode (" << (addr>>24) << ',';
ss << ((addr>>16)&0xff) << ',' << ((addr>>8)&0xff) << ',';
ss << (addr&0xff) << ',' << ((port>>8)&0xff) << ',';
ss << (port&0xff) << ").";
pi->write(ss.str());
passive = true;
dtp.setLocalPort(port);
data = dtp.listen();
}
} else if(command.substr(0, 5)=="TYPE ") {
if(checkPermission()) {
switch(command[5]) {
case 'A':
dataType = Tcp::ASCII;
break;
case 'I':
dataType = Tcp::IMAGE;
break;
default:
pi->write("504 Command not implemented for that parameter.");
continue;
}
pi->write(string("200 Type set to ") + command[5] + ".");
}
} else if(command.substr(0, 5)=="STOR " || command.substr(0, 5)=="APPE ") {
if(checkPermission()) {
string filename = dir.buildFullname(FTP_ROOT, command.substr(5));
ofstream os(filename.c_str(), command[0]=='S' ?
(dataType==Tcp::ASCII ? ios::out : ios::binary) :
(dataType==Tcp::ASCII ? ios::app : ios::app|ios::binary));
if(!os) {
pi->write("553 Requested action not taken.");
continue;
}
pi->write(string("150 Opening ") + (dataType==Tcp::ASCII ? "ASCII" : "Binary") +
" mode data connection for " + command.substr(5) + ".");
openDataConnection();
data->setDataType(dataType);
data->readToStream(os);
delete data;
pi->write("226 Transfer complete.");
}
} else if(command.substr(0, 5)=="RETR " || command.substr(0, 4)=="LIST") {
if(checkPermission()) {
string filename;
if(command[0]=='L')
if(command.length()==4) {
char tmp[] = "/tmp/ftpd.XXXXXX";
mkstemp(tmp);
filename = tmp;
system(string("ls -l " + dir.buildFullname(FTP_ROOT, "") + " > " +
filename).c_str());
} else if(command.length()>5 && command[4]==' ') {
char tmp[] = "/tmp/ftpd.XXXXXX";
mkstemp(tmp);
filename = tmp;
system(string("ls -l " + dir.buildFullname(FTP_ROOT, command[5]=='-' ?
" "+command.substr(5) : command.substr(5)) + " > " + filename).c_str());
} else {
pi->write("502 Command not implemented.");
continue;
}
else
filename = dir.buildFullname(FTP_ROOT, command.substr(5));
ifstream is(filename.c_str(), dataType==Tcp::ASCII?ios::in:ios::binary);
if(!is) {
pi->write("550 No such file or directory.");
continue;
}
pi->write(string("150 Opening ") + (dataType==Tcp::ASCII ? "ASCII" : "Binary") +
" mode data connection for " + (command[0]=='L' ? "file list" :
command.substr(5)) + ".");
openDataConnection();
if(command[0]!='L') data->setDataType(dataType);
data->writeFromStream(is);
delete data;
pi->write("226 Transfer complete.");
if(command[0]=='L') remove(filename.c_str());
}
} else if(command=="PWD") {
pi->write("257 \"" + string(dir) + "\" is current directory.");
} else if(command=="ABOR") {
pi->write("226 Closing data connection.");
} else if(command=="SYST") {
pi->write("215 UNIX Type: L8");
} else if(command.substr(0, 4)=="HELP") {
if(command.length()==4) {
pi->write("214-The following commands are recognized:");
pi->write(" CWD CDUP QUIT PORT PASV PWD SYST HELP");
pi->write(" NOOP TYPE MODE RETR STOR APPE ABOR USER");
pi->write(" PASS LIST");
pi->write("214 FTP daemon implemented by Meng Xiangliang");
} else if(command.length()>5 && command[4]==' ')
pi->write("214 Help message.");
else
pi->write("502 Command not implemented.");
} else if(command.substr(0, 5)=="MODE ") {
pi->write("504 Command not implemented for that parameter.");
} else if(command=="NOOP") {
pi->write("200 Command okay.");
} else
pi->write("502 Command not implemented.");
} catch(const char* message) {
cerr << "ERROR: " << message << endl;
}
}
}
bool Server::checkPermission() {
if(logon)
return true;
else {
pi->write("530 Not logged in.");
return false;
}
}
void Server::openDataConnection() {
if(passive)
passive = false;
else
data = dtp.connect();
}
int main(int argc, char* argv[]) {
Server::addUser("anonymous", "");
Server::addUser("mxl", "mxl");
while(true) {
Server* server = Server::listen(argc>1 ? atoi(argv[1]) : 2382);
if(fork()>0) {
server->start();
delete server;
return 0;
} else
delete server;
}
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -