⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 inetmail.cxx

📁 开源代码的pwlib的1.10.0版本,使用openh323的1.18.0版本毕备
💻 CXX
📖 第 1 页 / 共 3 页
字号:
                  (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 + -