#include "__SMTP_DATA.h" #include "SMTPServer.h" #include "Log.h" #include #include #define CRLF "\r\n" namespace mail { int __SMTP_DATA::processCommand(coreutils::ZString &request, SMTPSession &session, SMTPServer &server) { switch(session.mode) { case WAIT_FOR_DATA: switch(session.state) { case RCPT: session.out << "354 Enter the mail message terminated by ." << CRLF; session.mailData.str(""); session.mode = RECEIVE_DATA; grabInput(session); // setTimer(120.0f); break; case MAIL: session.out << "503 Please use RCPT first" << CRLF; break; default: session.out << "503 Please use MAIL first" << CRLF; break; } break; case RECEIVE_DATA: if(request.str() != ".") session.mailData << request.str() << CRLF; else { session.mode = WAIT_FOR_DATA; session.state = READY; clearGrab(session); // if(filterMessage(session.mailData)) { if(session.recipientList.size() > 0) { if(session.mailData.str().size() > 0) { std::string ID = queueMail(server, session.sender, session.recipientList, session.mailData); if(ID != "") { coreutils::Log(coreutils::LOG_INFO) << "Queued message " << ID << "."; session.out << "250 OK Queued message " << ID << CRLF; } else session.out << "550 Mail message too big" << CRLF; } else session.out << "550 Mail message was empty" << CRLF; } else session.out << "250 OK Queued message " << CRLF; // } else // data << "550 Message is probably spam" << CRLF; } break; } return 1; } std::string __SMTP_DATA::generateMailFileName() { std::stringstream temp; struct timespec timex; clock_gettime(CLOCK_REALTIME, &timex); temp << timex.tv_sec << "." << std::setfill('0') << std::setw(9) << timex.tv_nsec; return temp.str(); } std::string __SMTP_DATA::queueMail(SMTPServer &server, std::string sender, std::vector recipientList, std::stringstream &mailData) { std::string fileName = server.mailFileSystem.getMailPath() + "/.queue/" + generateMailFileName(); coreutils::File mailFile(fileName, O_CREAT | O_WRONLY, 0660); mailFile.write(mailData.str()); for(std::string recipient: recipientList) { std::string newName = fileName + recipient; link(fileName.c_str(), newName.c_str()); } unlink(fileName.c_str()); return fileName; } }