// --------------------------- constructor ----------------------- public Pop3Message( Int64 InMailDropPosition, SocketExchange InEx) { m_inboxPosition = InMailDropPosition; mSockEx = InEx; // object used to receive the mail message in a background thread. mSockThreadState = new SockThreadState( ); mSockThreadState.SockEx = InEx; mSockThreadState.sb = new StringBuilder( ); // load email ... LoadEmail(InEx, InMailDropPosition); // get body (if it exists) ... IEnumerator multipartEnumerator = MultipartEnumerator; while (multipartEnumerator.MoveNext()) { Pop3Component multipart = (Pop3Component) multipartEnumerator.Current; if (multipart.IsBody) { m_body = multipart.Data; break; } } }
// ---------------------- LoadEmail --------------------------- private void LoadEmail(SocketExchange InEx, Int64 InMailDropPosition) { // tell the server we want to read the message. InEx.Send("retr " + InMailDropPosition + PopConstants.CrLf); InEx.ExpectedResponseCodes = new ExpectedResponseCodes(PopConstants.Ok, PopConstants.Error); InEx.SendReceive("retr " + InMailDropPosition + PopConstants.CrLf); InEx.ThrowIfUnexpectedResponse( ); // -ERR response. no such message number. if (InEx.ResponseCode == PopConstants.Error) { } else { // for now, receive SSL link messages in the same thread. if (InEx.ConnectedSecureSocket != null) { StringBuilder mail = null; mail = ReceiveMessage_SameThread(InEx); InEx.LoadResponseMessage(mail.ToString( )); } // receive in a background thread. else { StartReceive(InEx); InEx.LoadResponseMessage(mSockThreadState.sb.ToString( )); } } // parse email ... mParts = MimeCommon.MessagePartSplitter(InEx.ResponseMessage); string[] lines = MimeCommon.MessageLineSplitter(InEx.ResponseMessage); mAttachments = null; MimeAttachment attach = (MimeAttachment)Attachments.FirstAttachment( ).Current; if (attach != null) { attach.SaveAs("c:\\apress\\attachment.txt"); } // if (1 == 2) // DumpHeader(InEx, InMailDropPosition); for (int ix = 0; ix < lines.Length; ++ix) { InEx.Logger.AddMessage(NetworkRole.Server, lines[ix]); } ParseEmail(lines); // remove reading pop3State ... mSockThreadState = null; }
// ------------------------- ReceiveCallback ------------------------- // receive MailMessage in background thread. private void ReceiveCallback(IAsyncResult InResult) { try { // Retrieve the state object and the client socket // from the asynchronous state object. SockThreadState sockThreadState = (SockThreadState)InResult.AsyncState; SocketExchange sockEx = sockThreadState.SockEx; Socket client = sockEx.ConnectedSocket; Socket secureSock = sockEx.ConnectedSecureSocket; int BufferSx = SockThreadState.BufferSize; int LoopCx = 0; while (true) { // a simple loop count. dont let it overflow. ++LoopCx; if (LoopCx > 1000) { LoopCx = 2; } // receive from the socket. int ReadCx; if (LoopCx == 1) { if (client != null) { ReadCx = client.EndReceive(InResult); } else { ReadCx = secureSock.EndReceive(InResult); } } else { if (client != null) { ReadCx = client.Receive( sockThreadState.buffer, 0, BufferSx, SocketFlags.None); } else { ReadCx = secureSock.Receive( sockThreadState.buffer, 0, BufferSx, SocketFlags.None); } } // did not receive anything. probably should leave. if (ReadCx == 0) { break; } // There might be more data, // so store the data received so far. string block = Encoding.ASCII.GetString(sockThreadState.buffer, 0, ReadCx); sockThreadState.sb.Append(block); // is this the end of the message if (sockThreadState.sb.Tail(5) == "\r\n.\r\n") { break; } } } catch (Exception e) { throw new Pop3ReceiveException( "ReceiveCallback error" + e.ToString( )); } finally { m_manualEvent.Set( ); } }
// ---------------------- LoadEmail --------------------------- private void LoadEmail(SocketExchange InEx, System.Int64 InMailDropPosition) { // tell the server we want to read the message. InEx.Send("retr " + InMailDropPosition + PopConstants.CrLf); InEx.ExpectedResponseCodes = new ExpectedResponseCodes(PopConstants.Ok, PopConstants.Error); InEx.SendReceive("retr " + InMailDropPosition + PopConstants.CrLf); InEx.ThrowIfUnexpectedResponse( ); // -ERR response. no such message number. if (InEx.ResponseCode == PopConstants.Error) { } else { // for now, receive SSL link messages in the same thread. if (InEx.ConnectedSecureSocket != null) { StringBuilder mail = null; mail = ReceiveMessage_SameThread(InEx); InEx.LoadResponseMessage(mail.ToString( )); } // receive in a background thread. else { StartReceive(InEx); InEx.LoadResponseMessage(mSockThreadState.sb.ToString( )); } } // parse email ... mParts = MimeCommon.MessagePartSplitter(InEx.ResponseMessage); string[] lines = MimeCommon.MessageLineSplitter(InEx.ResponseMessage); if (1 == 2) { mParts = MimeCommon.MessagePartSplitter(lines); } mAttachments = null; MimeAttachment attach = (MimeAttachment)Attachments.FirstAttachment( ).Current; if (attach != null) { attach.SaveAs("c:\\apress\\attachment.txt"); } if (1 == 2) { // dump the header lines of the top part. InEx.Logger.AddMessage(NetworkRole.Server, "--- start header line dump ---"); MimeTopPart topPart = ( MimeTopPart )mParts.GetTopPart( ); for (int Ix = 0; Ix < topPart.PropertyLines.Length; ++Ix) { InEx.Logger.AddMessage(NetworkRole.Server, topPart.PropertyLines[Ix]); } for (int Ix = 0; Ix < topPart.MessageLines.Length; ++Ix) { InEx.Logger.AddMessage(NetworkRole.Server, topPart.MessageLines[Ix]); } InEx.Logger.AddMessage(NetworkRole.Server, "--- end of header line dump ---"); // dump the lines of each part. foreach (MimeMessagePart part in mParts) { InEx.Logger.AddMessage(NetworkRole.Server, "** message part **"); InEx.Logger.AddMessage(NetworkRole.Server, "** property lines **"); foreach (string line in part.PropertyLines) { InEx.Logger.AddMessage(NetworkRole.Server, line); } InEx.Logger.AddMessage(NetworkRole.Server, "** message lines **"); foreach (string line in part.MessageLines) { InEx.Logger.AddMessage(NetworkRole.Server, line); } } InEx.Logger.AddMessage(NetworkRole.Server, "---- end of parts ----------"); } for (int ix = 0; ix < lines.Length; ++ix) { InEx.Logger.AddMessage(NetworkRole.Server, lines[ix]); } ParseEmail(lines); // remove reading pop3State ... mSockThreadState = null; }