/* * /// <summary> * /// Transfers specified message to specified socket. This is good for example transfering message from remote POP3 server to POP3 client. * /// </summary> * /// <param name="nr">Message number.</param> * /// <param name="socket">Socket where to store message.</param> * public void GetMessage(int nr,Socket socket) * { * if(!m_Connected){ * throw new Exception("You must connect first !"); * } * * if(!m_Authenticated){ * throw new Exception("You must authenticate first !"); * } * * Core.SendLine(m_pSocket,"RETR " + nr.ToString()); * * // Read first line of reply, check if it's ok * string line = Core.ReadLine(m_pSocket); * if(line.StartsWith("+OK")){ * NetworkStream readStream = new NetworkStream(m_pSocket); * NetworkStream storeStream = new NetworkStream(socket); * * byte[] crlf = new byte[]{(byte)'\r',(byte)'\n'}; * StreamLineReader reader = new StreamLineReader(readStream); * byte[] lineData = reader.ReadLine(); * while(lineData != null){ * // End of message reached * if(lineData.Length == 1 && lineData[0] == '.'){ * return; * } * * storeStream.Write(lineData,0,lineData.Length); * storeStream.Write(crlf,0,crlf.Length); * lineData = reader.ReadLine(); * } * } * else{ * throw new Exception("Server returned:" + line); * } * } */ /// <summary> /// Gets specified message. /// </summary> /// <param name="nr">Message number.</param> public byte[] GetMessage(int nr) { if (!m_Connected) { throw new Exception("You must connect first !"); } if (!m_Authenticated) { throw new Exception("You must authenticate first !"); } m_pSocket.SendLine("RETR " + nr.ToString()); // Read first line of reply, check if it's ok string line = m_pSocket.ReadLine(); if (line.StartsWith("+OK")) { MemoryStream strm = new MemoryStream(); ReadReplyCode code = m_pSocket.ReadData(strm, 100000000, "\r\n.\r\n", ".\r\n"); if (code != ReadReplyCode.Ok) { throw new Exception("Error:" + code.ToString()); } return(Core.DoPeriodHandling(strm, false).ToArray()); } else { throw new Exception("Server returned:" + line); } }
/// <summary> /// Fetches messages headers or full messages data. /// </summary> /// <param name="startMsgNo">Start message number.</param> /// <param name="endMsgNo">End message number. -1 = last.</param> /// <param name="uidFetch">Specifies if startMsgNo and endMsgNo is message UIDs.</param> /// <param name="headersOnly">If true message headers are retrieved, otherwise full message retrieved.</param> /// <param name="setSeenFlag">If true message seen flag is setted.</param> /// <returns></returns> public IMAP_FetchItem[] FetchMessages(int startMsgNo, int endMsgNo, bool uidFetch, bool headersOnly, bool setSeenFlag) { if (!m_Connected) { throw new Exception("You must connect first !"); } if (!m_Authenticated) { throw new Exception("You must authenticate first !"); } if (m_SelectedFolder.Length == 0) { throw new Exception("You must select folder first !"); } ArrayList fetchItems = new ArrayList(); string endMsg = endMsgNo.ToString(); if (endMsgNo < 1) { endMsg = "*"; } string headers = ""; if (headersOnly) { headers = "HEADER"; } string uidF = ""; if (uidFetch) { uidF = "UID "; } string seenFl = ""; if (!setSeenFlag) { seenFl = ".PEEK"; } m_pSocket.SendLine("a1 " + uidF + "FETCH " + startMsgNo + ":" + endMsg + " (UID RFC822.SIZE FLAGS BODY" + seenFl + "[" + headers + "])"); // Must get lines with * and cmdTag + OK or cmdTag BAD/NO string reply = m_pSocket.ReadLine(); if (reply.StartsWith("*")) { // Read multiline response while (reply.StartsWith("*")) { // Fetch may return status response there, skip them if (IsStatusResponse(reply)) { continue; } // Get rid of * 1 FETCH and parse params. Reply:* 1 FETCH (UID 12 BODY[] ...) reply = reply.Substring(reply.IndexOf("FETCH (") + 7); int uid = 0; int size = 0; byte[] data = null; bool isNewMsg = true; bool isAnswered = false; // Loop fetch result fields for (int i = 0; i < 4; i++) { // UID field if (reply.ToUpper().StartsWith("UID")) { reply = reply.Substring(3).Trim(); // Remove UID word from reply if (reply.IndexOf(" ") > -1) { uid = Convert.ToInt32(reply.Substring(0, reply.IndexOf(" "))); reply = reply.Substring(reply.IndexOf(" ")).Trim(); // Remove UID value from reply } else // Last param, no ending ' ' { uid = Convert.ToInt32(reply.Substring(0)); reply = ""; } } // RFC822.SIZE field else if (reply.ToUpper().StartsWith("RFC822.SIZE")) { reply = reply.Substring(11).Trim(); // Remove RFC822.SIZE word from reply if (reply.IndexOf(" ") > -1) { size = Convert.ToInt32(reply.Substring(0, reply.IndexOf(" "))); reply = reply.Substring(reply.IndexOf(" ")).Trim(); // Remove RFC822.SIZE value from reply } else { // Last param, no ending ' ' size = Convert.ToInt32(reply.Substring(0)); reply = ""; } } // BODY.PEEK field else if (reply.ToUpper().StartsWith("BODY")) { // Get data. Find {dataLen} int dataLen = Convert.ToInt32(reply.Substring(reply.IndexOf("{") + 1, reply.IndexOf("}") - reply.IndexOf("{") - 1)); MemoryStream storeStrm = new MemoryStream(dataLen); ReadReplyCode code = m_pSocket.ReadData(storeStrm, dataLen, true); if (code != ReadReplyCode.Ok) { throw new Exception("Read data:" + code.ToString()); } data = storeStrm.ToArray(); // Read last fetch line, can be ')' or some params')'. reply = m_pSocket.ReadLine().Trim(); if (!reply.EndsWith(")")) { throw new Exception("UnExpected fetch end ! value:" + reply); } else { reply = reply.Substring(0, reply.Length - 1).Trim(); // Remove ')' from reply } } // FLAGS field else if (reply.ToUpper().StartsWith("FLAGS")) { if (reply.ToUpper().IndexOf("\\SEEN") > -1) { isNewMsg = false; } if (reply.ToUpper().IndexOf("\\ANSWERED") > -1) { isAnswered = true; } reply = reply.Substring(reply.IndexOf(")") + 1).Trim(); // Remove FLAGS value from reply } } fetchItems.Add(new IMAP_FetchItem(uid, size, data, headersOnly, isNewMsg, isAnswered)); reply = m_pSocket.ReadLine(); } } reply = reply.Substring(reply.IndexOf(" ")).Trim(); // Remove Cmd tag if (!reply.ToUpper().StartsWith("OK")) { if (!reply.ToUpper().StartsWith("NO")) { throw new Exception("Server returned:" + reply); } } IMAP_FetchItem[] retVal = new IMAP_FetchItem[fetchItems.Count]; fetchItems.CopyTo(retVal); return(retVal); }