Пример #1
0
        /// <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;
        }
Пример #2
0
        /// <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);
        }