Beispiel #1
0
        /// <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);
            }
        }
Beispiel #2
0
        /// <summary>
        /// Reads specified amount of data from socket.
        /// </summary>
        /// <param name="storeStream">Stream where to store readed data.</param>
        /// <param name="countToRead">Amount of data to read.</param>
        /// <param name="storeToStream">Specifes if to store readed data to stream or junk it.</param>
        /// <returns></returns>
        public ReadReplyCode ReadData(Stream storeStream, long countToRead, bool storeToStream)
        {
            ReadReplyCode replyCode = ReadReplyCode.Ok;

            try
            {
                long readedCount = 0;
                while (readedCount < countToRead)
                {
                    byte[] b = new byte[4000];
                    // Ensure that we don't get more data than needed
                    if ((countToRead - readedCount) < 4000)
                    {
                        b = new byte[countToRead - readedCount];
                    }

                    int countRecieved = this.Receive(b);
                    if (countRecieved > 0)
                    {
                        readedCount += countRecieved;

                        if (storeToStream)
                        {
                            storeStream.Write(b, 0, countRecieved);
                        }
                    }
                    // Client disconnected
                    else
                    {
                        return(ReadReplyCode.SocketClosed);
                    }

                    OnActivity();
                }

                // Logging stuff
                if (m_pLogger != null)
                {
                    m_pLogger.AddReadEntry("Big binary, readed " + readedCount.ToString() + " bytes.", readedCount);
                }
            }
            catch (Exception x)
            {
                replyCode = ReadReplyCode.UnKnownError;

                if (x is SocketException)
                {
                    SocketException xS = (SocketException)x;
                    if (xS.ErrorCode == 10060)
                    {
                        return(ReadReplyCode.TimeOut);
                    }
                }
            }

            return(replyCode);
        }
Beispiel #3
0
        /// <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());
        }
Beispiel #4
0
        /// <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());
            }
        }
Beispiel #5
0
        /// <summary>
        /// Reads specified count of data from Socket.
        /// </summary>
        /// <param name="socket"></param>
        /// <param name="count">Number of bytes to read.</param>
        /// <param name="storeStrm"></param>
        /// <param name="storeToStream">If true stores readed data to stream, otherwise just junks specified amount of data.</param>
        /// <param name="cmdIdleTimeOut"></param>
        /// <returns></returns>
        public static ReadReplyCode ReadData(BufferedSocket socket, long count, Stream storeStrm, bool storeToStream, int cmdIdleTimeOut)
        {
            ReadReplyCode replyCode = ReadReplyCode.Ok;

            try{
                socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, cmdIdleTimeOut);

                long readedCount = 0;
                while (readedCount < count)
                {
                    byte[] b = new byte[4000];
                    // Ensure that we don't get more data than needed
                    if ((count - readedCount) < 4000)
                    {
                        b = new byte[count - readedCount];
                    }

                    int countRecieved = socket.Receive(b);
                    if (countRecieved > 0)
                    {
                        readedCount += countRecieved;

                        if (storeToStream)
                        {
                            storeStrm.Write(b, 0, countRecieved);
                        }
                    }
                    // Client disconnected
                    else
                    {
                        throw new Exception("Client disconnected");
                    }
                }
            }
            catch (Exception x) {
                replyCode = ReadReplyCode.UnKnownError;

                if (x is SocketException)
                {
                    SocketException xS = (SocketException)x;
                    if (xS.ErrorCode == 10060)
                    {
                        replyCode = ReadReplyCode.TimeOut;
                    }
                }
            }

            return(replyCode);
        }
Beispiel #6
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="code"></param>
 /// <param name="message"></param>
 public ReadException(ReadReplyCode code, string message) : base(message)
 {
     m_ReadReplyCode = code;
 }
 /// <summary>
 /// 
 /// </summary>
 /// <param name="code"></param>
 /// <param name="message"></param>
 public ReadException(ReadReplyCode code, string message) : base(message)
 {
     m_ReadReplyCode = code;
 }
Beispiel #8
0
        /// <summary>
        /// Reads reply from socket.
        /// </summary>
        /// <param name="socket"></param>
        /// <param name="replyData">Data that has been readen from socket.</param>
        /// <param name="addData">Data that has will be written at the beginning of read data. This param may be null.</param>
        /// <param name="maxLength">Maximum Length of data which may read.</param>
        /// <param name="cmdIdleTimeOut">Command idle time out in milliseconds.</param>
        /// <param name="terminator">Terminator string which terminates reading. eg '\r\n'.</param>
        /// <param name="removeFromEnd">Removes following string from reply.NOTE: removes only if ReadReplyCode is Ok.</param>
        /// <returns>Return reply code.</returns>
        public static ReadReplyCode ReadData(Socket socket, out MemoryStream replyData, byte[] addData, int maxLength, int cmdIdleTimeOut, string terminator, string removeFromEnd)
        {
            ReadReplyCode replyCode = ReadReplyCode.Ok;

            replyData = null;

            try{
                socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, cmdIdleTimeOut);

                replyData = new MemoryStream();
                _FixedStack stack            = new _FixedStack(terminator);
                int         nextReadWriteLen = 1;

                while (nextReadWriteLen > 0)
                {
                    //Read byte(s)
                    byte[] b             = new byte[nextReadWriteLen];
                    int    countRecieved = socket.Receive(b);
                    if (countRecieved > 0)
                    {
                        // Write byte(s) to buffer, if length isn't exceeded.
                        if (replyCode != ReadReplyCode.LengthExceeded)
                        {
                            replyData.Write(b, 0, countRecieved);
                        }

                        // Write to stack(terminator checker)
                        nextReadWriteLen = stack.Push(b, countRecieved);

                        //---- Check if maximum length is exceeded ---------------------------------//
                        if (replyCode != ReadReplyCode.LengthExceeded && replyData.Length > maxLength)
                        {
                            replyCode = ReadReplyCode.LengthExceeded;
                        }
                        //--------------------------------------------------------------------------//
                    }
                    // Client disconnected
                    else
                    {
                        throw new Exception("Client disconnected");
                    }
                }

                // If reply is ok then remove chars if any specified by 'removeFromEnd'.
                if (replyCode == ReadReplyCode.Ok && removeFromEnd.Length > 0)
                {
                    replyData.SetLength(replyData.Length - removeFromEnd.Length);
                }
            }
            catch (Exception x) {
                replyCode = ReadReplyCode.UnKnownError;

                if (x is SocketException)
                {
                    SocketException xS = (SocketException)x;
                    if (xS.ErrorCode == 10060)
                    {
                        replyCode = ReadReplyCode.TimeOut;
                    }
                }
            }

            return(replyCode);
        }
Beispiel #9
0
        // 3 types of read
        //   1) To some terminator
        //   2) Specified length
        //   3) While socket is closed with ShutDown

        #region method ReadData (terminator)

        /// <summary>
        /// Reads data from socket while specified terminator is reached.
        /// If maximum length is exceeded, reading continues but data won't be stored to stream.
        /// </summary>
        /// <param name="storeStream">Stream where to store readed data.</param>
        /// <param name="maxLength">Maximum length to read.</param>
        /// <param name="terminator">Terminator which trminates reading.</param>
        /// <param name="removeFromEnd">Part of trminator what to remove from end. Can be empty or max part is terminator.</param>
        /// <returns></returns>
        public ReadReplyCode ReadData(Stream storeStream, long maxLength, string terminator, string removeFromEnd)
        {
            if (storeStream == null)
            {
                throw new Exception("Parameter storeStream can't be null !");
            }

            ReadReplyCode replyCode = ReadReplyCode.Ok;

            try{
                _FixedStack stack            = new _FixedStack(terminator);
                long        readedCount      = 0;
                int         nextReadWriteLen = 1;
                while (nextReadWriteLen > 0)
                {
                    //Read byte(s)
                    byte[] b             = new byte[nextReadWriteLen];
                    int    countRecieved = this.Receive(b);
                    if (countRecieved > 0)
                    {
                        readedCount += countRecieved;

                        // Write byte(s) to buffer, if length isn't exceeded.
                        if (readedCount <= maxLength)
                        {
                            storeStream.Write(b, 0, countRecieved);
                        }

                        // Write to stack(terminator checker)
                        nextReadWriteLen = stack.Push(b, countRecieved);
                    }
                    // Client disconnected
                    else
                    {
                        return(ReadReplyCode.SocketClosed);
                    }

                    OnActivity();
                }

                // Check if length is exceeded
                if (readedCount > maxLength)
                {
                    return(ReadReplyCode.LengthExceeded);
                }

                // If reply is ok then remove chars if any specified by 'removeFromEnd'.
                if (replyCode == ReadReplyCode.Ok && removeFromEnd.Length > 0)
                {
                    storeStream.SetLength(storeStream.Length - removeFromEnd.Length);
                }

                // Logging stuff
                if (m_pLogger != null)
                {
                    if (storeStream is MemoryStream && storeStream.Length < 200)
                    {
                        MemoryStream ms = (MemoryStream)storeStream;
                        m_pLogger.AddReadEntry(m_pEncoding.GetString(ms.ToArray()));
                    }
                    else
                    {
                        m_pLogger.AddReadEntry("Big binary, readed " + readedCount.ToString() + " bytes.");
                    }
                }
            }
            catch (Exception x) {
                replyCode = ReadReplyCode.UnKnownError;

                if (x is SocketException)
                {
                    SocketException xS = (SocketException)x;
                    if (xS.ErrorCode == 10060)
                    {
                        return(ReadReplyCode.TimeOut);
                    }
                }
            }

            return(replyCode);
        }
Beispiel #10
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);
        }
Beispiel #11
0
 /// <summary>
 /// Creates a new instance of <see cref="ReadException"/> exception.
 /// </summary>
 /// <param name="code">Read error code.</param>
 /// <param name="message">The message that describes the error.</param>
 /// <param name="innerException">The exception that is the cause of the current exception, or a null reference
 /// (Nothing in Visual Basic) if no inner exception is specified.</param>
 public ReadException(ReadReplyCode code, string message, Exception innerException) : base(message, innerException)
 {
     ReadReplyCode = code;
 }