#include "__SMTP_DATA.h" #include "SMTPSession.h" #include "SMTPServer.h" #include "Log.h" #include #include #define CRLF "\r\n" namespace mail { int __SMTP_DATA::processCommand(coreutils::ZString &request, core::TCPSession &session) { SMTPSession &s = dynamic_cast(session); SMTPServer &server = session.server; switch(session.mode) { case WAIT_FOR_DATA: switch(session.state) { case RCPT: s.out << "354 Enter the mail message terminated by ." << CRLF; s.mailData.str(""); s.mode = RECEIVE_DATA; server.commands.grabInput(&session, *this); // setTimer(120.0f); break; case MAIL: s.out << "503 Please use RCPT first" << CRLF; break; default: s.out << "503 Please use MAIL first" << CRLF; break; } break; case RECEIVE_DATA: if(request.str() != ".") s.mailData << request.str() << CRLF; else { s.mode = WAIT_FOR_DATA; s.state = READY; server.commands.clearGrab(&session); // if(filterMessage(session.mailData)) { if(s.recipientList.size() > 0) { if(s.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 << "."; s.out << "250 OK Queued message " << ID << CRLF; } else s.out << "550 Mail message too big" << CRLF; } else s.out << "550 Mail message was empty" << CRLF; } else s.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; } }