📄 inetmail.cxx
字号:
(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 &){}//////////////////////////////////////////////////////////////////////////////// PRFC822Channelconst char PRFC822Channel::MimeVersionTag[] = "MIME-version";const char PRFC822Channel::FromTag[] = "From";const char PRFC822Channel::ToTag[] = "To";const char PRFC822Channel::CCTag[] = "cc";const char PRFC822Channel::BCCTag[] = "bcc";const char PRFC822Channel::SubjectTag[] = "Subject";const char PRFC822Channel::DateTag[] = "Date";const char PRFC822Channel::ReturnPathTag[] = "Return-Path";const char PRFC822Channel::ReceivedTag[] = "Received";const char PRFC822Channel::MessageIDTag[] = "Message-ID";const char PRFC822Channel::MailerTag[] = "X-Mailer";const char PRFC822Channel::ContentTypeTag[] = "Content-Type";const char PRFC822Channel::ContentDispositionTag[] = "Content-Disposition";const char PRFC822Channel::ContentTransferEncodingTag[] = "Content-Transfer-Encoding";PRFC822Channel::PRFC822Channel(Direction direction){ writeHeaders = direction == Sending; writePartHeaders = FALSE; base64 = NULL;}PRFC822Channel::~PRFC822Channel(){ Close(); delete base64;}BOOL PRFC822Channel::Close(){ flush(); NextPart(""); // Flush out all the parts return PIndirectChannel::Close();}BOOL PRFC822Channel::Write(const void * buf, PINDEX len){ flush(); if (writeHeaders) { if (!headers.Contains(FromTag) || !headers.Contains(ToTag)) return FALSE; if (!headers.Contains(MimeVersionTag)) headers.SetAt(MimeVersionTag, "1.0"); if (!headers.Contains(DateTag)) headers.SetAt(DateTag, PTime().AsString()); if (writePartHeaders) headers.SetAt(ContentTypeTag, "multipart/mixed; boundary=\""+boundaries[0]+'"'); else if (!headers.Contains(ContentTypeTag)) headers.SetAt(ContentTypeTag, "text/plain"); PStringStream hdr; hdr << ::setfill('\r') << headers; if (!PIndirectChannel::Write(hdr.GetPointer(), hdr.GetLength())) return FALSE; if (base64 != NULL) base64->StartEncoding(); writeHeaders = FALSE; } if (writePartHeaders) { if (!partHeaders.Contains(ContentTypeTag)) partHeaders.SetAt(ContentTypeTag, "text/plain"); PStringStream hdr; hdr << "\n--" << boundaries[0] << '\n' << ::setfill('\r') << partHeaders; if (!PIndirectChannel::Write(hdr.GetPointer(), hdr.GetLength())) return FALSE; if (base64 != NULL) base64->StartEncoding(); writePartHeaders = FALSE; } BOOL ok; if (base64 == NULL) ok = PIndirectChannel::Write(buf, len); else { base64->ProcessEncoding(buf, len); PString str = base64->GetEncodedString(); ok = PIndirectChannel::Write(str.GetPointer(), str.GetLength()); } // Always return the lastWriteCount as the number of bytes expected to be // written, not teh actual number which with base64 encoding etc may be // significantly more. if (ok) lastWriteCount = len; return ok;}BOOL PRFC822Channel::OnOpen(){ if (writeHeaders) return TRUE; istream & this_stream = *this; this_stream >> headers; return !bad();}void PRFC822Channel::NewMessage(Direction direction){ NextPart(""); // Flush out all the parts boundaries.RemoveAll(); headers.RemoveAll(); partHeaders.RemoveAll(); writeHeaders = direction == Sending; writePartHeaders = FALSE;}PString PRFC822Channel::MultipartMessage(){ PString boundary; do { boundary.sprintf("PWLib.%lu.%u", time(NULL), rand()); } while (!MultipartMessage(boundary)); return boundary;}BOOL PRFC822Channel::MultipartMessage(const PString & boundary){ writePartHeaders = TRUE; for (PINDEX i = 0; i < boundaries.GetSize(); i++) { if (boundaries[i] == boundary) return FALSE; } if (boundaries.GetSize() > 0) { partHeaders.SetAt(ContentTypeTag, "multipart/mixed; boundary=\""+boundary+'"'); flush(); writePartHeaders = TRUE; } boundaries.InsertAt(0, new PString(boundary)); return TRUE;}void PRFC822Channel::NextPart(const PString & boundary){ if (base64 != NULL) { PBase64 * oldBase64 = base64; base64 = NULL; *this << oldBase64->CompleteEncoding() << '\n'; delete oldBase64; } while (boundaries.GetSize() > 0) { if (boundaries[0] == boundary) break; *this << "\n--" << boundaries[0] << "--\n"; boundaries.RemoveAt(0); } flush(); writePartHeaders = boundaries.GetSize() > 0; partHeaders.RemoveAll();}void PRFC822Channel::SetFromAddress(const PString & fromAddress){ SetHeaderField(FromTag, fromAddress);}void PRFC822Channel::SetToAddress(const PString & toAddress){ SetHeaderField(ToTag, toAddress);}void PRFC822Channel::SetCC(const PString & ccAddress){ SetHeaderField(CCTag, ccAddress);}void PRFC822Channel::SetBCC(const PString & bccAddress){ SetHeaderField(BCCTag, bccAddress);}void PRFC822Channel::SetSubject(const PString & subject){ SetHeaderField(SubjectTag, subject);}void PRFC822Channel::SetContentType(const PString & contentType){ SetHeaderField(ContentTypeTag, contentType);}void PRFC822Channel::SetContentAttachment(const PFilePath & file){ PString name = file.GetFileName(); SetHeaderField(ContentDispositionTag, "attachment; filename=\"" + name + '"'); SetHeaderField(ContentTypeTag, PMIMEInfo::GetContentType(file.GetType())+"; name=\"" + name + '"');}void PRFC822Channel::SetTransferEncoding(const PString & encoding, BOOL autoTranslate){ SetHeaderField(ContentTransferEncodingTag, encoding); if ((encoding *= "base64") && autoTranslate) base64 = new PBase64; else { delete base64; base64 = NULL; }}void PRFC822Channel::SetHeaderField(const PString & name, const PString & value){ if (writePartHeaders) partHeaders.SetAt(name, value); else if (writeHeaders) headers.SetAt(name, value); else PAssertAlways(PLogicError);}BOOL PRFC822Channel::SendWithSMTP(const PString & hostname){ PSMTPClient * smtp = new PSMTPClient; smtp->Connect(hostname); return SendWithSMTP(smtp);}BOOL PRFC822Channel::SendWithSMTP(PSMTPClient * smtp){ if (!Open(smtp)) return FALSE; if (!headers.Contains(FromTag) || !headers.Contains(ToTag)) return FALSE; return smtp->BeginMessage(headers[FromTag], headers[ToTag]);}// End Of File ///////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -