#include "__SMTP_DATA.h" #include "SMTPServer.h" #include "Log.h" #include #include 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 = ""; session.mode = RECEIVE_DATA; grabInput(session); // 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 != ".") { session.mailData << request << CRLF; } else { session.mode = WAIT_FOR_DATA; session.state = READY; clearGrab(session); // if(filterMessage(session.mailData)) { if(session.recipientList.size() > 0) { if(session.mailData.getLength() > 0) { coreutils::MString ID = queueMail(server, session.from, 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; } coreutils::MString __SMTP_DATA::generateMailFileName() { struct timespec timex; clock_gettime(CLOCK_REALTIME, &timex); std::stringstream temp; temp << timex.tv_sec << "." << std::setfill('0') << std::setw(9) << timex.tv_nsec; return coreutils::MString(temp.str()); } coreutils::MString __SMTP_DATA::queueMail(SMTPServer &server, coreutils::MString &sender, std::vector &recipientList, coreutils::MString &mailData) { coreutils::MString fileName; fileName << server.mailFileSystem.getMailPath() << "/.queue/" << generateMailFileName(); coreutils::File mailFile(fileName, O_CREAT | O_WRONLY, 0660); mailFile.write(mailData); for(coreutils::MString recipient: recipientList) { coreutils::MString newName; newName << fileName << "|" << recipient; link(fileName.c_str(), newName.c_str()); } unlink(fileName.c_str()); return fileName; } }