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

📄 inetmail.cxx

📁 pwlib源码库
💻 CXX
📖 第 1 页 / 共 3 页
字号:
}void PSMTPServer::OnVRFY(const PCaselessString & name){  PString expandedName;  switch (LookUpName(name, expandedName)) {    case AmbiguousUser :      WriteResponse(553, "User \"" + name + "\" ambiguous.");      break;    case ValidUser :      WriteResponse(250, expandedName);      break;    case UnknownUser :      WriteResponse(550, "Name \"" + name + "\" does not match anything.");      break;    default :      WriteResponse(550, "Error verifying user \"" + name + "\".");  }}void PSMTPServer::OnEXPN(const PCaselessString &){  WriteResponse(502, "I don't do that. Sorry.");}static PINDEX ParseMailPath(const PCaselessString & args,                            const PCaselessString & subCmd,                            PString & name,                            PString & domain,                            PString & forwardList){  PINDEX colon = args.Find(':');  if (colon == P_MAX_INDEX)    return 0;  PCaselessString word = args.Left(colon).Trim();  if (subCmd != word)    return 0;  PINDEX leftAngle = args.Find('<', colon);  if (leftAngle == P_MAX_INDEX)    return 0;  PINDEX finishQuote;  PINDEX startQuote = args.Find('"', leftAngle);  if (startQuote == P_MAX_INDEX) {    colon = args.Find(':', leftAngle);    if (colon == P_MAX_INDEX)      colon = leftAngle;    finishQuote = startQuote = colon+1;  }  else {    finishQuote = args.Find('"', startQuote+1);    if (finishQuote == P_MAX_INDEX)      finishQuote = startQuote;    colon = args.Find(':', leftAngle);    if (colon > startQuote)      colon = leftAngle;  }  PINDEX rightAngle = args.Find('>', finishQuote);  if (rightAngle == P_MAX_INDEX)    return 0;  PINDEX at = args.Find('@', finishQuote);  if (at > rightAngle)    at = rightAngle;  if (startQuote == finishQuote)    finishQuote = at;  name = args(startQuote, finishQuote-1);  domain = args(at+1, rightAngle-1);  forwardList = args(leftAngle+1, colon-1);  return rightAngle+1;}void PSMTPServer::OnRCPT(const PCaselessString & recipient){  PCaselessString toName;  PCaselessString toDomain;  PCaselessString forwardList;  if (ParseMailPath(recipient, "to", toName, toDomain, forwardList) == 0)    WriteResponse(501, "Syntax error.");  else {    switch (ForwardDomain(toDomain, forwardList)) {      case CannotForward :        WriteResponse(550, "Cannot do forwarding.");        break;      case WillForward :        if (!forwardList)          forwardList += ":";        forwardList += toName;        if (!toDomain)          forwardList += "@" + toDomain;        toNames.AppendString(toName);        toDomains.AppendString(forwardList);        break;      case LocalDomain :      {        PString expandedName;        switch (LookUpName(toName, expandedName)) {          case ValidUser :            WriteResponse(250, "Recipient " + toName + " Ok");            toNames.AppendString(toName);            toDomains.AppendString("");            break;          case AmbiguousUser :            WriteResponse(553, "User ambiguous.");            break;          case UnknownUser :            WriteResponse(550, "User unknown.");            break;          default :            WriteResponse(550, "Error verifying user.");        }      }    }  }}void PSMTPServer::OnMAIL(const PCaselessString & sender){  sendCommand = WasMAIL;  OnSendMail(sender);}void PSMTPServer::OnSEND(const PCaselessString & sender){  sendCommand = WasSEND;  OnSendMail(sender);}void PSMTPServer::OnSAML(const PCaselessString & sender){  sendCommand = WasSAML;  OnSendMail(sender);}void PSMTPServer::OnSOML(const PCaselessString & sender){  sendCommand = WasSOML;  OnSendMail(sender);}void PSMTPServer::OnSendMail(const PCaselessString & sender){  if (!fromAddress) {    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",  "AUTH"};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(){  if (!ReadResponse() || lastResponseCode <= 0)    return FALSE;  // APOP login command supported?  PINDEX i = lastResponseInfo.FindRegEx("<.*@.*>");  if (i != P_MAX_INDEX)    apopBanner = lastResponseInfo.Mid(i);  return TRUE;}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, int options){#if P_SASL2  PString mech;  PSASLClient auth("pop", username, username, password);  if ((options & UseSASL) && ExecuteCommand(AUTH, "") > 0) {    PStringSet serverMechs;    while (ReadLine(mech) && mech[0] != '.')      serverMechs.Include(mech);    mech = PString::Empty();    PStringSet ourMechs;    if (auth.Init("", ourMechs)) {      if (!(options & AllowClearTextSASL)) {        ourMechs.Exclude("PLAIN");        ourMechs.Exclude("LOGIN");      }      for (PINDEX i = 0, max = serverMechs.GetSize() ; i < max ; i++)        if (ourMechs.Contains(serverMechs.GetKeyAt(i))) {          mech = serverMechs.GetKeyAt(i);          break;        }    }  }  PString output;  if ((options & UseSASL) && !mech.IsEmpty() && auth.Start(mech, output)) {    if (ExecuteCommand(AUTH, mech) <= 0)      return FALSE;    PSASLClient::PSASLResult result;    do {      result = auth.Negotiate(lastResponseInfo, output);            if (result == PSASLClient::Fail)        return FALSE;      if (!output.IsEmpty()) {        WriteLine(output);        if (!ReadResponse() || !lastResponseCode)          return FALSE;      }    } while (result == PSASLClient::Continue);    auth.End();  }  else {#endif    if (!apopBanner.IsEmpty()) { // let's try with APOP      PMessageDigest::Result bin_digest;      PMessageDigest5::Encode(apopBanner + password, bin_digest);      PString digest;      const BYTE * data = bin_digest.GetPointer();      for (PINDEX i = 0, max = bin_digest.GetSize(); i < max ; i++)        digest.sprintf("%02x", (unsigned)data[i]);      if (ExecuteCommand(APOP, username + " " + digest) > 0)        return loggedIn = TRUE;    }    // No SASL and APOP didn't work for us    // If we really have to, we'll go with the plain old USER/PASS scheme    if (!(options & AllowUserPass))      return FALSE;    if (ExecuteCommand(USER, username) <= 0)      return FALSE;    if (ExecuteCommand(PASS, password) <= 0)      return FALSE;#if P_SASL2  }#endif  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) && isdigit(msgInfo[0]))      sizes.SetAt((PINDEX)msgInfo.AsInteger()-1,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -