📄 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;
}
//////////////////////////////////////////////////////////////////////////////
// PPOP3Server
PPOP3Server::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 &)
{
}
//////////////////////////////////////////////////////////////////////////////
// PRFC822Channel
const 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 + -