/// <summary> /// Gets top lines of message. /// </summary> /// <param name="nr">Message number which top lines to get.</param> /// <param name="nLines">Number of lines to get.</param> public byte[] GetTopOfMessage(int nr, int nLines) { if (!m_Connected) { throw new Exception("You must connect first !"); } if (!m_Authenticated) { throw new Exception("You must authenticate first !"); } Core.SendLine(m_pSocket, "TOP " + nr.ToString() + " " + nLines.ToString()); // Read first line of reply, check if it's ok string line = Core.ReadLine(m_pSocket); if (line.StartsWith("+OK")) { MemoryStream strm = new MemoryStream(); ReadReplyCode code = Core.ReadData(m_pSocket, out strm, null, 100000000, 30000, "\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> /// Reads line of data from Socket. /// </summary> /// <param name="socket"></param> /// <param name="maxLen"></param> /// <param name="idleTimeOut"></param> /// <returns></returns> public static string ReadLine(Socket socket, int maxLen, int idleTimeOut) { MemoryStream storeStream = null; ReadReplyCode code = ReadData(socket, out storeStream, null, maxLen, idleTimeOut, "\r\n", "\r\n"); if (code != ReadReplyCode.Ok) { throw new ReadException(code, code.ToString()); } return(System.Text.Encoding.Default.GetString(storeStream.ToArray()).Trim()); }
/// <summary> /// Reads line from socket. /// </summary> /// <param name="maxLength">Maximum length to read.</param> /// <returns></returns> public string ReadLine(long maxLength) { using (MemoryStream storeStream = new MemoryStream()){ ReadReplyCode code = ReadData(storeStream, maxLength, "\r\n", "\r\n"); if (code != ReadReplyCode.Ok) { throw new ReadException(code, code.ToString()); } return(m_pEncoding.GetString(storeStream.ToArray()).Trim()); } }
/// <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"; } Core.SendLine(m_pSocket, "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 = Core.ReadLine(m_pSocket); 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 = true; // 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 = Core.ReadData(m_pSocket, dataLen, storeStrm, true, 30000); if (code != ReadReplyCode.Ok) { throw new Exception("Read data:" + code.ToString()); } data = storeStrm.ToArray(); // Read last fetch line, can be ')' or some params')'. reply = Core.ReadLine(m_pSocket).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 = Core.ReadLine(m_pSocket); } } 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); }