/// <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; }
/// <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); }