📄 inetmail.cxx
字号:
WriteResponse(503, "Sender already specified."); return; } PString fromDomain; PINDEX extendedArgPos = ParseMailPath(sender, "from", fromAddress, fromDomain, fromPath); if (extendedArgPos == 0 || fromAddress.IsEmpty()) { WriteResponse(501, "Syntax error."); return; } fromAddress += fromDomain; if (extendedHello) { PINDEX equalPos = sender.Find('=', extendedArgPos); PCaselessString body = sender(extendedArgPos, equalPos).Trim(); PCaselessString mime = sender.Mid(equalPos+1).Trim(); eightBitMIME = (body == "BODY" && mime == "8BITMIME"); } PString response = "Sender " + fromAddress; if (eightBitMIME) response += " and 8BITMIME"; WriteResponse(250, response + " Ok");}void PSMTPServer::OnDATA(){ if (fromAddress.IsEmpty()) { WriteResponse(503, "Need a valid MAIL command."); return; } if (toNames.GetSize() == 0) { WriteResponse(503, "Need a valid RCPT command."); return; } // Ok, everything is ready to start the message. if (!WriteResponse(354, eightBitMIME ? "Enter 8BITMIME message, terminate with '<CR><LF>.<CR><LF>'." : "Enter mail, terminate with '.' alone on a line.")) return; endMIMEDetectState = eightBitMIME ? StuffIdle : DontStuff; BOOL ok = TRUE; BOOL completed = FALSE; BOOL starting = TRUE; while (ok && !completed) { PCharArray buffer; if (eightBitMIME) ok = OnMIMEData(buffer, completed); else ok = OnTextData(buffer, completed); if (ok) { ok = HandleMessage(buffer, starting, completed); starting = FALSE; } } if (ok) WriteResponse(250, "Message received Ok."); else WriteResponse(554, "Message storage failed.");}BOOL PSMTPServer::OnUnknown(const PCaselessString & command){ WriteResponse(500, "Command \"" + command + "\" unrecognised."); return TRUE;}BOOL PSMTPServer::OnTextData(PCharArray & buffer, BOOL & completed){ PString line; while (ReadLine(line)) { PINDEX len = line.GetLength(); if (len == 1 && line[0] == '.') { completed = TRUE; return TRUE; } PINDEX start = (len > 1 && line[0] == '.' && line[1] == '.') ? 1 : 0; PINDEX size = buffer.GetSize(); len -= start; memcpy(buffer.GetPointer(size + len + 2) + size, ((const char *)line)+start, len); size += len; buffer[size++] = '\r'; buffer[size++] = '\n'; if (size > messageBufferSize) return TRUE; } return FALSE;}BOOL PSMTPServer::OnMIMEData(PCharArray & buffer, BOOL & completed){ PINDEX count = 0; int c; while ((c = ReadChar()) >= 0) { if (count >= buffer.GetSize()) buffer.SetSize(count + 100); switch (endMIMEDetectState) { case StuffIdle : buffer[count++] = (char)c; break; case StuffCR : endMIMEDetectState = c != '\n' ? StuffIdle : StuffCRLF; buffer[count++] = (char)c; break; case StuffCRLF : if (c == '.') endMIMEDetectState = StuffCRLFdot; else { endMIMEDetectState = StuffIdle; buffer[count++] = (char)c; } break; case StuffCRLFdot : switch (c) { case '\r' : endMIMEDetectState = StuffCRLFdotCR; break; case '.' : endMIMEDetectState = StuffIdle; buffer[count++] = (char)c; break; default : endMIMEDetectState = StuffIdle; buffer[count++] = '.'; buffer[count++] = (char)c; } break; case StuffCRLFdotCR : if (c == '\n') { completed = TRUE; return TRUE; } buffer[count++] = '.'; buffer[count++] = '\r'; buffer[count++] = (char)c; endMIMEDetectState = StuffIdle; default : PAssertAlways("Illegal SMTP state"); } if (count > messageBufferSize) { buffer.SetSize(messageBufferSize); return TRUE; } } return FALSE;}PSMTPServer::ForwardResult PSMTPServer::ForwardDomain(PCaselessString & userDomain, PCaselessString & forwardDomainList){ return userDomain.IsEmpty() && forwardDomainList.IsEmpty() ? LocalDomain : CannotForward;}PSMTPServer::LookUpResult PSMTPServer::LookUpName(const PCaselessString &, PString & expandedName){ expandedName = PString(); return LookUpError;}BOOL PSMTPServer::HandleMessage(PCharArray &, BOOL, BOOL){ return FALSE;}//////////////////////////////////////////////////////////////////////////////// PPOP3static char const * const POP3Commands[PPOP3::NumCommands] = { "USER", "PASS", "QUIT", "RSET", "NOOP", "STAT", "LIST", "RETR", "DELE", "APOP", "TOP", "UIDL"};PString PPOP3::okResponse = "+OK";PString PPOP3::errResponse = "-ERR";PPOP3::PPOP3() : PInternetProtocol("pop3 110", NumCommands, POP3Commands){}PINDEX PPOP3::ParseResponse(const PString & line){ lastResponseCode = line[0] == '+'; PINDEX endCode = line.Find(' '); if (endCode != P_MAX_INDEX) lastResponseInfo = line.Mid(endCode+1); else lastResponseInfo = PString(); return 0;}//////////////////////////////////////////////////////////////////////////////// PPOP3ClientPPOP3Client::PPOP3Client(){ loggedIn = FALSE;}PPOP3Client::~PPOP3Client(){ Close();}BOOL PPOP3Client::OnOpen(){ return ReadResponse() && lastResponseCode > 0;}BOOL PPOP3Client::Close(){ BOOL ok = TRUE; if (IsOpen() && loggedIn) { SetReadTimeout(60000); ok = ExecuteCommand(QUIT, "") > 0; } return PInternetProtocol::Close() && ok;}BOOL PPOP3Client::LogIn(const PString & username, const PString & password){ if (ExecuteCommand(USER, username) <= 0) return FALSE; if (ExecuteCommand(PASS, password) <= 0) return FALSE; loggedIn = TRUE; return TRUE;}int PPOP3Client::GetMessageCount(){ if (ExecuteCommand(STATcmd, "") <= 0) return -1; return (int)lastResponseInfo.AsInteger();}PUnsignedArray PPOP3Client::GetMessageSizes(){ PUnsignedArray sizes; if (ExecuteCommand(LIST, "") > 0) { PString msgInfo; while (ReadLine(msgInfo)) sizes.SetAt((PINDEX)msgInfo.AsInteger()-1, (unsigned)msgInfo.Mid(msgInfo.Find(' ')).AsInteger()); } return sizes;}PStringArray PPOP3Client::GetMessageHeaders(){ PStringArray headers; int count = GetMessageCount(); for (int msgNum = 1; msgNum <= count; msgNum++) { if (ExecuteCommand(TOP, PString(PString::Unsigned,msgNum) + " 0") > 0) { PString headerLine; while (ReadLine(headerLine, TRUE)) headers[msgNum-1] += headerLine; } } return headers;}BOOL PPOP3Client::BeginMessage(PINDEX messageNumber){ return ExecuteCommand(RETR, PString(PString::Unsigned, messageNumber)) > 0;}BOOL PPOP3Client::DeleteMessage(PINDEX messageNumber){ return ExecuteCommand(DELE, PString(PString::Unsigned, messageNumber)) > 0;}//////////////////////////////////////////////////////////////////////////////// PPOP3ServerPPOP3Server::PPOP3Server(){}BOOL PPOP3Server::OnOpen(){ return WriteResponse(okResponse, PIPSocket::GetHostName() + " POP3 server ready at " + PTime(PTime::MediumDateTime).AsString());}BOOL PPOP3Server::ProcessCommand(){ PString args; PINDEX num; if (!ReadCommand(num, args)) return FALSE; switch (num) { case USER : OnUSER(args); break; case PASS : OnPASS(args); break; case QUIT : OnQUIT(); return FALSE; case RSET : OnRSET(); break; case NOOP : OnNOOP(); break; case STATcmd : OnSTAT(); break; case LIST : OnLIST((PINDEX)args.AsInteger()); break; case RETR : OnRETR((PINDEX)args.AsInteger()); break; case DELE : OnDELE((PINDEX)args.AsInteger()); break; case TOP : if (args.Find(' ') == P_MAX_INDEX) WriteResponse(errResponse, "Syntax error"); else OnTOP((PINDEX)args.AsInteger(), (PINDEX)args.Mid(args.Find(' ')).AsInteger()); break; case UIDL : OnUIDL((PINDEX)args.AsInteger()); break; default : return OnUnknown(args); } return TRUE;}void PPOP3Server::OnUSER(const PString & name){ messageSizes.SetSize(0); messageIDs.SetSize(0); username = name; WriteResponse(okResponse, "User name accepted.");}void PPOP3Server::OnPASS(const PString & password){ if (username.IsEmpty()) WriteResponse(errResponse, "No user name specified."); else if (HandleOpenMailbox(username, password)) WriteResponse(okResponse, username + " mail is available."); else WriteResponse(errResponse, "No access to " + username + " mail."); messageDeletions.SetSize(messageIDs.GetSize());}void PPOP3Server::OnQUIT(){ for (PINDEX i = 0; i < messageDeletions.GetSize(); i++) if (messageDeletions[i]) HandleDeleteMessage(i+1, messageIDs[i]); WriteResponse(okResponse, PIPSocket::GetHostName() + " POP3 server signing off at " + PTime(PTime::MediumDateTime).AsString()); Close();}void PPOP3Server::OnRSET(){ for (PINDEX i = 0; i < messageDeletions.GetSize(); i++) messageDeletions[i] = FALSE; WriteResponse(okResponse, "Resetting state.");}void PPOP3Server::OnNOOP(){ WriteResponse(okResponse, "Doing nothing.");}void PPOP3Server::OnSTAT(){ DWORD total = 0; for (PINDEX i = 0; i < messageSizes.GetSize(); i++) total += messageSizes[i]; WriteResponse(okResponse, psprintf("%u %u", messageSizes.GetSize(), total));}void PPOP3Server::OnLIST(PINDEX msg){ if (msg == 0) { WriteResponse(okResponse, psprintf("%u messages.", messageSizes.GetSize())); for (PINDEX i = 0; i < messageSizes.GetSize(); i++) if (!messageDeletions[i]) WriteLine(psprintf("%u %u", i+1, messageSizes[i])); WriteLine("."); } else if (msg < 1 || msg > messageSizes.GetSize()) WriteResponse(errResponse, "No such message."); else WriteResponse(okResponse, psprintf("%u %u", msg, messageSizes[msg-1]));}void PPOP3Server::OnRETR(PINDEX msg){ if (msg < 1 || msg > messageDeletions.GetSize()) WriteResponse(errResponse, "No such message."); else { WriteResponse(okResponse, PString(PString::Unsigned, messageSizes[msg-1]) + " octets."); stuffingState = StuffIdle; HandleSendMessage(msg, messageIDs[msg-1], P_MAX_INDEX); stuffingState = DontStuff; WriteString(CRLFdotCRLF); }}void PPOP3Server::OnDELE(PINDEX msg){ if (msg < 1 || msg > messageDeletions.GetSize()) WriteResponse(errResponse, "No such message."); else { messageDeletions[msg-1] = TRUE; WriteResponse(okResponse, "Message marked for deletion."); }}void PPOP3Server::OnTOP(PINDEX msg, PINDEX count){ if (msg < 1 || msg > messageDeletions.GetSize()) WriteResponse(errResponse, "No such message."); else { WriteResponse(okResponse, "Top of message"); stuffingState = StuffIdle; HandleSendMessage(msg, messageIDs[msg-1], count); stuffingState = DontStuff; WriteString(CRLFdotCRLF); }}void PPOP3Server::OnUIDL(PINDEX msg){ if (msg == 0) { WriteResponse(okResponse, PString(PString::Unsigned, messageIDs.GetSize()) + " messages."); for (PINDEX i = 0; i < messageIDs.GetSize(); i++) if (!messageDeletions[i]) WriteLine(PString(PString::Unsigned, i+1) & messageIDs[i]); WriteLine("."); } else if (msg < 1 || msg > messageSizes.GetSize()) WriteResponse(errResponse, "No such message."); else WriteLine(PString(PString::Unsigned, msg) & messageIDs[msg-1]);}BOOL PPOP3Server::OnUnknown(const PCaselessString & command){ WriteResponse(errResponse, "Command \"" + command + "\" unrecognised."); return TRUE;}BOOL PPOP3Server::HandleOpenMailbox(const PString &, const PString &){ return FALSE;}void PPOP3Server::HandleSendMessage(PINDEX, const PString &, PINDEX){}void PPOP3Server::HandleDeleteMessage(PINDEX, const PString &){}// End Of File ///////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -