Beispiel #1
0
        /// <summary>
        /// Gets if specified message matches to specified search key.
        /// </summary>
        /// <param name="searchKey">SearchKey or SearchGroup.</param>
        /// <param name="no">IMAP message sequence number.</param>
        /// <param name="uid">IMAP message UID.</param>
        /// <param name="size">IMAP message size in bytes.</param>
        /// <param name="internalDate">IMAP message INTERNALDATE (dateTime when server stored message).</param>
        /// <param name="flags">IMAP message flags.</param>
        /// <param name="mime">Mime message main header only.</param>
        /// <param name="bodyText">Message body text.</param>
        /// <returns></returns>
        internal static bool Match_Key_Value(object searchKey,
                                             long no,
                                             long uid,
                                             long size,
                                             DateTime internalDate,
                                             IMAP_MessageFlags flags,
                                             Mime mime,
                                             string bodyText)
        {
            if (searchKey.GetType() == typeof(SearchKey))
            {
                if (!((SearchKey)searchKey).Match(no, uid, size, internalDate, flags, mime, bodyText))
                {
                    return(false);
                }
            }
            else if (searchKey.GetType() == typeof(SearchGroup))
            {
                if (!((SearchGroup)searchKey).Match(no, uid, size, internalDate, flags, mime, bodyText))
                {
                    return(false);
                }
            }

            return(true);
        }
        /// <summary>
        /// Converts message flags to string. Eg. \SEEN \DELETED .
        /// </summary>
        /// <returns></returns>
        public static string MessageFlagsToString(IMAP_MessageFlags msgFlags)
        {
            string retVal = "";
            if (((int) IMAP_MessageFlags.Answered & (int) msgFlags) != 0)
            {
                retVal += " \\ANSWERED";
            }
            if (((int) IMAP_MessageFlags.Flagged & (int) msgFlags) != 0)
            {
                retVal += " \\FLAGGED";
            }
            if (((int) IMAP_MessageFlags.Deleted & (int) msgFlags) != 0)
            {
                retVal += " \\DELETED";
            }
            if (((int) IMAP_MessageFlags.Seen & (int) msgFlags) != 0)
            {
                retVal += " \\SEEN";
            }
            if (((int) IMAP_MessageFlags.Draft & (int) msgFlags) != 0)
            {
                retVal += " \\DRAFT";
            }

            return retVal.Trim();
        }
        /// <summary>
        /// Parses message flags from string.
        /// </summary>
        /// <param name="flagsString">Message flags string.</param>
        /// <returns></returns>
        public static IMAP_MessageFlags ParseMessageFlags(string flagsString)
        {
            IMAP_MessageFlags mFlags = 0;

            flagsString = flagsString.ToUpper();

            if (flagsString.IndexOf("ANSWERED") > -1)
            {
                mFlags |= IMAP_MessageFlags.Answered;
            }
            if (flagsString.IndexOf("FLAGGED") > -1)
            {
                mFlags |= IMAP_MessageFlags.Flagged;
            }
            if (flagsString.IndexOf("DELETED") > -1)
            {
                mFlags |= IMAP_MessageFlags.Deleted;
            }
            if (flagsString.IndexOf("SEEN") > -1)
            {
                mFlags |= IMAP_MessageFlags.Seen;
            }
            if (flagsString.IndexOf("DRAFT") > -1)
            {
                mFlags |= IMAP_MessageFlags.Draft;
            }

            return(mFlags);
        }
Beispiel #4
0
        public static string[] MessageFlagsToStringArray(IMAP_MessageFlags msgFlags)
        {
            List <string> retVal = new List <string>();

            if (((int)IMAP_MessageFlags.Answered & (int)msgFlags) != 0)
            {
                retVal.Add("\\ANSWERED");
            }
            if (((int)IMAP_MessageFlags.Flagged & (int)msgFlags) != 0)
            {
                retVal.Add("\\FLAGGED");
            }
            if (((int)IMAP_MessageFlags.Deleted & (int)msgFlags) != 0)
            {
                retVal.Add("\\DELETED");
            }
            if (((int)IMAP_MessageFlags.Seen & (int)msgFlags) != 0)
            {
                retVal.Add("\\SEEN");
            }
            if (((int)IMAP_MessageFlags.Draft & (int)msgFlags) != 0)
            {
                retVal.Add("\\DRAFT");
            }

            return(retVal.ToArray());
        }
        /// <summary>
        /// Converts message flags to string. Eg. \SEEN \DELETED .
        /// </summary>
        /// <returns></returns>
        public static string MessageFlagsToString(IMAP_MessageFlags msgFlags)
        {
            string retVal = "";

            if (((int)IMAP_MessageFlags.Answered & (int)msgFlags) != 0)
            {
                retVal += " \\ANSWERED";
            }
            if (((int)IMAP_MessageFlags.Flagged & (int)msgFlags) != 0)
            {
                retVal += " \\FLAGGED";
            }
            if (((int)IMAP_MessageFlags.Deleted & (int)msgFlags) != 0)
            {
                retVal += " \\DELETED";
            }
            if (((int)IMAP_MessageFlags.Seen & (int)msgFlags) != 0)
            {
                retVal += " \\SEEN";
            }
            if (((int)IMAP_MessageFlags.Draft & (int)msgFlags) != 0)
            {
                retVal += " \\DRAFT";
            }

            return(retVal.Trim());
        }
Beispiel #6
0
 /// <summary>
 /// Default constructor.
 /// </summary>
 /// <param name="messages"></param>
 /// <param name="messageID">Internal messageID.</param>
 /// <param name="UID">Message UID. NOTE: message uid must increase all the time, for new messages.</param>
 /// <param name="flags">Message flags.</param>
 /// <param name="size">Message size.</param>
 /// <param name="date">Message receive date.</param>
 internal IMAP_Message(IMAP_Messages messages, string messageID, int UID, IMAP_MessageFlags flags, long size, DateTime date)
 {
     m_Messages  = messages;
     m_MessageID = messageID;
     m_UID       = UID;
     m_Flags     = flags;
     m_Size      = size;
     m_Date      = date;
 }
Beispiel #7
0
 /// <summary>
 /// Default constructor.
 /// </summary>
 /// <param name="messages"></param>
 /// <param name="messageID">Internal messageID.</param>
 /// <param name="UID">Message UID. NOTE: message uid must increase all the time, for new messages.</param>
 /// <param name="flags">Message flags.</param>
 /// <param name="size">Message size.</param>
 /// <param name="date">Message receive date.</param>
 internal IMAP_Message(IMAP_Messages messages,string messageID,int UID,IMAP_MessageFlags flags,long size,DateTime date)
 {
     m_Messages  = messages;
     m_MessageID = messageID;
     m_UID       = UID;
     m_Flags     = flags;
     m_Size      = size;
     m_Date      = date;
 }
Beispiel #8
0
 /// <summary>
 /// Default constructor.
 /// </summary>
 /// <param name="onwer">Owner collection.</param>
 /// <param name="id">Message ID.</param>
 /// <param name="uid">Message IMAP UID value.</param>
 /// <param name="internalDate">Message store date.</param>
 /// <param name="size">Message size in bytes.</param>
 /// <param name="flags">Message flags.</param>
 internal IMAP_Message(IMAP_MessageCollection onwer,string id,long uid,DateTime internalDate,long size,IMAP_MessageFlags flags)
 {
     m_pOwner       = onwer;
     m_ID           = id;
     m_UID          = uid;
     m_InternalDate = internalDate;
     m_Size         = size;
     m_Flags        = flags;
 }
 /// <summary>
 /// Default constructor.
 /// </summary>
 /// <param name="onwer">Owner collection.</param>
 /// <param name="id">Message ID.</param>
 /// <param name="uid">Message IMAP UID value.</param>
 /// <param name="internalDate">Message store date.</param>
 /// <param name="size">Message size in bytes.</param>
 /// <param name="flags">Message flags.</param>
 internal IMAP_Message(IMAP_MessageCollection onwer, string id, long uid, DateTime internalDate, long size, IMAP_MessageFlags flags)
 {
     m_pOwner       = onwer;
     m_ID           = id;
     m_UID          = uid;
     m_InternalDate = internalDate;
     m_Size         = size;
     m_Flags        = flags;
 }
        /// <summary>
        /// Gets if specified values match search criteria.
        /// </summary>
        /// <param name="no">Message sequence number.</param>
        /// <param name="uid">Message UID.</param>
        /// <param name="size">Message size in bytes.</param>
        /// <param name="internalDate">Message INTERNALDATE (dateTime when server stored message).</param>
        /// <param name="flags">Message flags.</param>
        /// <param name="header">Message header. This is only needed if this.IsHeaderNeeded is true.</param>
        /// <param name="bodyText">Message body text (must be decoded unicode text). This is only needed if this.IsBodyTextNeeded is true.</param>
        /// <returns></returns>
        public bool Matches(int no,int uid,int size,DateTime internalDate,IMAP_MessageFlags flags,string header,string bodyText)
        {
            // Parse header only if it's needed
            LumiSoft.Net.Mime.Mime m = null;
            if(m_pSearchCriteria.IsHeaderNeeded()){
                m = new LumiSoft.Net.Mime.Mime();
                m.MainEntity.Header.Parse(header);
            }

            return m_pSearchCriteria.Match(no,uid,size,internalDate,flags,m,bodyText);
        }
        /// <summary>
        /// Adds new message info to the collection.
        /// </summary>
        /// <param name="id">Message ID.</param>
        /// <param name="uid">Message IMAP UID value.</param>
        /// <param name="internalDate">Message store date.</param>
        /// <param name="size">Message size in bytes.</param>
        /// <param name="flags">Message flags.</param>
        /// <returns>Returns added IMAp message info.</returns>
        public IMAP_Message Add(string id,long uid,DateTime internalDate,long size,IMAP_MessageFlags flags)
        {
            if(uid < 1){
                throw new ArgumentException("Message UID value must be > 0 !");
            }

            IMAP_Message message = new IMAP_Message(this,id,uid,internalDate,size,flags);
            m_pMessages.Add(uid,message);

            return message;
        }
        /// <summary>
        /// Gets if specified values match search criteria.
        /// </summary>
        /// <param name="no">Message sequence number.</param>
        /// <param name="uid">Message UID.</param>
        /// <param name="size">Message size in bytes.</param>
        /// <param name="internalDate">Message INTERNALDATE (dateTime when server stored message).</param>
        /// <param name="flags">Message flags.</param>
        /// <param name="header">Message header. This is only needed if this.IsHeaderNeeded is true.</param>
        /// <param name="bodyText">Message body text (must be decoded unicode text). This is only needed if this.IsBodyTextNeeded is true.</param>
        /// <returns></returns>
        public bool Matches(int no, int uid, int size, DateTime internalDate, IMAP_MessageFlags flags, string header, string bodyText)
        {
            // Parse header only if it's needed
            LumiSoft.Net.Mime.Mime m = null;
            if (m_pSearchCriteria.IsHeaderNeeded())
            {
                m = new LumiSoft.Net.Mime.Mime();
                m.MainEntity.Header.Parse(header);
            }

            return(m_pSearchCriteria.Match(no, uid, size, internalDate, flags, m, bodyText));
        }
 /// <summary>
 /// Default constructor.
 /// </summary>
 /// <param name="no">Number of message in folder.</param>
 /// <param name="uid">Message UID.</param>
 /// <param name="size">Message size.</param>
 /// <param name="data">Message data.</param>
 /// <param name="flags">Message flags.</param>
 /// <param name="internalDate">Message INTERNALDATE.</param>
 /// <param name="envelope">Envelope string.</param>
 /// <param name="bodyStructure">BODYSTRUCTURE string.</param>
 /// <param name="fetchFlags">Specifies what data fetched from IMAP server.</param>
 internal IMAP_FetchItem(int no, int uid, int size, byte[] data, IMAP_MessageFlags flags, string internalDate, string envelope, string bodyStructure, IMAP_FetchItem_Flags fetchFlags)
 {
     m_No            = no;
     m_UID           = uid;
     m_Size          = size;
     m_Data          = data;
     m_Flags         = flags;
     m_InternalDate  = internalDate;
     m_Envelope      = envelope;
     m_FetchFlags    = fetchFlags;
     m_BodyStructure = bodyStructure;
 }
 /// <summary>
 /// Default constructor.
 /// </summary>
 /// <param name="no">Number of message in folder.</param>
 /// <param name="uid">Message UID.</param>
 /// <param name="size">Message size.</param>
 /// <param name="data">Message data.</param>
 /// <param name="flags">Message flags.</param>
 /// <param name="internalDate">Message INTERNALDATE.</param>
 /// <param name="envelope">Envelope string.</param>
 /// <param name="bodyStructure">BODYSTRUCTURE string.</param>
 /// <param name="fetchFlags">Specifies what data fetched from IMAP server.</param>
 internal IMAP_FetchItem(int no,int uid,int size,byte[] data,IMAP_MessageFlags flags,string internalDate,string envelope,string bodyStructure,IMAP_FetchItem_Flags fetchFlags)
 {
     m_No            = no;
     m_UID           = uid;
     m_Size          = size;
     m_Data          = data;
     m_Flags         = flags;
     m_InternalDate  = internalDate;
     m_Envelope      = envelope;
     m_FetchFlags    = fetchFlags;
     m_BodyStructure = bodyStructure;
 }
        /// <summary>
        /// Gets if specified message matches with this class search-key.
        /// </summary>
        /// <param name="no">IMAP message sequence number.</param>
        /// <param name="uid">IMAP message UID.</param>
        /// <param name="size">IMAP message size in bytes.</param>
        /// <param name="internalDate">IMAP message INTERNALDATE (dateTime when server stored message).</param>
        /// <param name="flags">IMAP message flags.</param>
        /// <param name="mime">Mime message main header only.</param>
        /// <param name="bodyText">Message body text.</param>
        /// <returns></returns>
        public bool Match(long no,long uid,long size,DateTime internalDate,IMAP_MessageFlags flags,LumiSoft.Net.Mime.Mime mime,string bodyText)
        {
            // We must match all keys, if one fails, no need to check others

            foreach(object searckKey in m_pSearchKeys){
                if(!Match_Key_Value(searckKey,no,uid,size,internalDate,flags,mime,bodyText)){
                    return false;
                }
            }

            return true;
        }
        /// <summary>
        /// Gets messages which has specified flags set.
        /// </summary>
        /// <param name="flags">Flags to match.</param>
        /// <returns></returns>
        public IMAP_Message[] GetWithFlags(IMAP_MessageFlags flags)
        {
            List <IMAP_Message> retVal = new List <IMAP_Message>();

            foreach (IMAP_Message message in m_pMessages.Values)
            {
                if ((message.Flags & flags) != 0)
                {
                    retVal.Add(message);
                }
            }
            return(retVal.ToArray());
        }
        public IMAP_Message[] GetWithFlags(IMAP_MessageFlags flags)
        {
            List <IMAP_Message> list = new List <IMAP_Message>();

            foreach (IMAP_Message current in this.m_pMessages.Values)
            {
                if ((current.Flags & flags) != IMAP_MessageFlags.None)
                {
                    list.Add(current);
                }
            }
            return(list.ToArray());
        }
        /// <summary>
        /// Gets if specified message matches with this class search-key.
        /// </summary>
        /// <param name="no">IMAP message sequence number.</param>
        /// <param name="uid">IMAP message UID.</param>
        /// <param name="size">IMAP message size in bytes.</param>
        /// <param name="internalDate">IMAP message INTERNALDATE (dateTime when server stored message).</param>
        /// <param name="flags">IMAP message flags.</param>
        /// <param name="message">Mime message main header only.</param>
        /// <param name="bodyText">Message body text.</param>
        /// <returns></returns>
        public bool Match(long no, long uid, long size, DateTime internalDate, IMAP_MessageFlags flags, Mail_Message message, string bodyText)
        {
            // We must match all keys, if one fails, no need to check others

            foreach (object searckKey in m_pSearchKeys)
            {
                if (!Match_Key_Value(searckKey, no, uid, size, internalDate, flags, message, bodyText))
                {
                    return(false);
                }
            }

            return(true);
        }
Beispiel #19
0
        /// <summary>
        /// Stores message folgs to sepcified messages range.
        /// </summary>
        /// <param name="startMsgNo">Start message number.</param>
        /// <param name="endMsgNo">End message number.</param>
        /// <param name="uidStore">Sepcifies if message numbers are message UID numbers.</param>
        /// <param name="msgFlags">Message flags to store.</param>
        public void StoreMessageFlags(int startMsgNo, int endMsgNo, bool uidStore, IMAP_MessageFlags msgFlags)
        {
            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 !");
            }

            if (uidStore)
            {
                m_pSocket.SendLine("a1 UID STORE " + startMsgNo + ":" + endMsgNo + " FLAGS (" + IMAP_Utils.MessageFlagsToString(msgFlags) + ")");
            }
            else
            {
                m_pSocket.SendLine("a1 STORE " + startMsgNo + ":" + endMsgNo + " FLAGS (" + IMAP_Utils.MessageFlagsToString(msgFlags) + ")");
            }

            // 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("*"))
                {
                    // Get rid of *
                    reply = reply.Substring(1).Trim();

                    reply = m_pSocket.ReadLine();
                }
            }

            reply = reply.Substring(reply.IndexOf(" ")).Trim();             // Remove Cmd tag

            if (!reply.ToUpper().StartsWith("OK"))
            {
                throw new Exception("Server returned:" + reply);
            }
        }
        public virtual void SetStarred(ChannelMessageHeader message, bool starred)
        {
            if (String.IsNullOrEmpty(message.SourceFolder))
            {
                return;
            }

            IMAP_MessageFlags flags = message.IsRead ? IMAP_MessageFlags.Seen : IMAP_MessageFlags.None;

            if (starred)
            {
                flags = (flags | IMAP_MessageFlags.Flagged);
            }

            connection.Client.SelectFolder(message.SourceFolder);
            connection.Client.StoreMessageFlags(new IMAP_SequenceSet(message.MessageNumber), flags, true);
        }
        /// <summary>
        /// Default constructor.
        /// </summary>
        /// <param name="fs">Message file stream.</param>
        public _InternalHeader(FileStream fs)
        {
            m_pFile = fs;

            StreamLineReader r    = new StreamLineReader(fs);
            string           line = r.ReadLineString();

            if (line != null && line.ToLower() == "<internalheader>")
            {
                line = r.ReadLineString();
                while (line.ToLower() != "</internalheader>")
                {
                    if (line.ToLower().StartsWith("#-messageflags:"))
                    {
                        m_MessageFlags = (IMAP_MessageFlags)Enum.Parse(typeof(IMAP_MessageFlags), line.Substring(15).Trim());
                    }
                    else if (line.ToLower().StartsWith("#-envelope:"))
                    {
                        m_Envelope = line.Substring(11).Trim();
                    }
                    else if (line.ToLower().StartsWith("#-body:"))
                    {
                        m_Body = line.Substring(7).Trim();
                    }

                    line = r.ReadLineString();
                }

                // Remove internal header
                if (fs.CanWrite)
                {
                    byte[] data = new byte[fs.Length - fs.Position];
                    fs.Read(data, 0, data.Length);
                    fs.Position = 0;
                    fs.Write(data, 0, data.Length);
                    fs.SetLength(data.Length);
                    fs.Position = 0;
                }
            }
            // Internal header doesn't exist
            else
            {
                fs.Position = 0;
            }
        }
Beispiel #22
0
        public _InternalHeader(FileStream fs)
        {
            this.m_pFile = fs;
            StreamLineReader streamLineReader = new StreamLineReader(fs);
            string           text             = streamLineReader.ReadLineString();

            if (text != null && text.ToLower() == "<internalheader>")
            {
                text = streamLineReader.ReadLineString();
                while (text.ToLower() != "</internalheader>")
                {
                    if (text.ToLower().StartsWith("#-messageflags:"))
                    {
                        this.m_MessageFlags = (IMAP_MessageFlags)Enum.Parse(typeof(IMAP_MessageFlags), text.Substring(15).Trim());
                    }
                    else if (text.ToLower().StartsWith("#-envelope:"))
                    {
                        this.m_Envelope = text.Substring(11).Trim();
                    }
                    else if (text.ToLower().StartsWith("#-body:"))
                    {
                        this.m_Body = text.Substring(7).Trim();
                    }
                    text = streamLineReader.ReadLineString();
                }
                if (fs.CanWrite)
                {
                    byte[] array = new byte[fs.Length - fs.Position];
                    fs.Read(array, 0, array.Length);
                    fs.Position = 0L;
                    fs.Write(array, 0, array.Length);
                    fs.SetLength((long)array.Length);
                    fs.Position = 0L;
                    return;
                }
            }
            else
            {
                fs.Position = 0L;
            }
        }
Beispiel #23
0
        /// <summary>
        /// Default constructor.
        /// </summary>
        /// <param name="fs">Message file stream.</param>
        public _InternalHeader(FileStream fs)
        {
            m_pFile = fs;
            
            StreamLineReader r = new StreamLineReader(fs);
            string line = r.ReadLineString();
            if(line!= null && line.ToLower() == "<internalheader>"){                
                line = r.ReadLineString();
                while(line.ToLower() != "</internalheader>"){
                    if(line.ToLower().StartsWith("#-messageflags:")){                        
                        m_MessageFlags = (IMAP_MessageFlags)Enum.Parse(typeof(IMAP_MessageFlags),line.Substring(15).Trim());
                    }
                    else if(line.ToLower().StartsWith("#-envelope:")){
                        m_Envelope = line.Substring(11).Trim();
                    }
                    else if(line.ToLower().StartsWith("#-body:")){
                        m_Body = line.Substring(7).Trim();
                    }

                    line = r.ReadLineString();
                }

                // Remove internal header
                if(fs.CanWrite){
                    byte[] data = new byte[fs.Length - fs.Position];
                    fs.Read(data,0,data.Length);
                    fs.Position = 0;
                    fs.Write(data,0,data.Length);
                    fs.SetLength(data.Length);
                    fs.Position = 0;
                }
            }
            // Internal header doesn't exist
            else{
                fs.Position = 0;
            }
        }
Beispiel #24
0
        /// <summary>
        /// Stores message to specified folder.
        /// </summary>
        /// <param name="folderName">Folder where to store message.</param>
        /// <param name="messageFlags">Message flags what are stored for message.</param>
        /// <param name="inernalDate">Internal date value what are stored for message.</param>
        /// <param name="data">Message data which to store.</param>
        /// <exception cref="ObjectDisposedException">Is raised when this object is disposed and this method is accessed.</exception>
        /// <exception cref="InvalidOperationException">Is raised when IMAP client is not connected,not authenticated and folder not selected.</exception>
        public void StoreMessage(string folderName, IMAP_MessageFlags messageFlags, DateTime inernalDate, byte[] data)
        {
            if (this.IsDisposed)
            {
                throw new ObjectDisposedException(this.GetType().Name);
            }
            if (!this.IsConnected)
            {
                throw new InvalidOperationException("You must connect first.");
            }
            if (!this.IsAuthenticated)
            {
                throw new InvalidOperationException("The command is only valid in authenticated state.");
            }

            // Ensure that we send right separator to server, we accept both \ and /.
            folderName = folderName.Replace('\\', this.PathSeparator).Replace('/', this.PathSeparator);

            string line = GetNextCmdTag() + " APPEND " + TextUtils.QuoteString(Core.Encode_IMAP_UTF7_String(folderName)) + " (" + IMAP_Utils.MessageFlagsToString(messageFlags) + ") \"" + IMAP_Utils.DateTimeToString(inernalDate) + "\" {" + data.Length + "}";
            int countWritten = this.TcpStream.WriteLine(line);
            LogAddWrite(countWritten, line);

            // Read un-tagged response lines while we get final response line or + send data.
            while (true)
            {
                line = this.ReadLine();

                // We have un-tagged resposne.
                if (line.StartsWith("*"))
                {
                    ProcessStatusResponse(line);
                }
                // Send data.
                else if (line.StartsWith("+"))
                {
                    // Send message.
                    this.TcpStream.Write(data, 0, data.Length);
                    LogAddWrite(data.Length, "Wrote " + data.Length.ToString() + " bytes.");

                    // Send CRLF, ends splitted command line.
                    this.TcpStream.Write(new byte[] { (byte)'\r', (byte)'\n' }, 0, 2);
                    LogAddWrite(data.Length, "Wrote CRLF.");
                }
                else
                {
                    break;
                }
            }

            if (!RemoveCmdTag(line).ToUpper().StartsWith("OK"))
            {
                throw new IMAP_ClientException(line);
            }
        }
        /// <summary>
        /// Gets if specified message matches with this class search-key.
        /// </summary>
        /// <param name="no">IMAP message sequence number.</param>
        /// <param name="uid">IMAP message UID.</param>
        /// <param name="size">IMAP message size in bytes.</param>
        /// <param name="internalDate">IMAP message INTERNALDATE (dateTime when server stored message).</param>
        /// <param name="flags">IMAP message flags.</param>
        /// <param name="mime">Mime message main header only.</param>
        /// <param name="bodyText">Message body text.</param>
        /// <returns></returns>
        public bool Match(long no,
                          long uid,
                          long size,
                          DateTime internalDate,
                          IMAP_MessageFlags flags,
                          Mime mime,
                          string bodyText)
        {
            #region ALL

            // ALL
            //		All messages in the mailbox; the default initial key for ANDing.
            if (m_SearchKeyName == "ALL")
            {
                return true;
            }

                #endregion

                #region BEFORE

                // BEFORE <date>
                //	Messages whose internal date (disregarding time and timezone)
                //	is earlier than the specified date.
            else if (m_SearchKeyName == "BEFORE")
            {
                if (internalDate.Date < (DateTime) m_SearchKeyValue)
                {
                    return true;
                }
            }

                #endregion

                #region BODY

                // BODY <string>
                //	Messages that contain the specified string in the body of the message.
                //
                //	NOTE: Compare must be done on decoded header and decoded body of message.
                //		  In all search keys that use strings, a message matches the key if
                //		  the string is a substring of the field.  The matching is case-insensitive.
            else if (m_SearchKeyName == "BODY")
            {
                string val = bodyText;
                if (val != null && val.ToLower().IndexOf(((string) m_SearchKeyValue).ToLower()) > -1)
                {
                    return true;
                }
            }

                #endregion

                #region HEADER

                // HEADER <field-name> <string>
                //	Messages that have a header with the specified field-name (as
                //	defined in [RFC-2822]) and that contains the specified string
                //	in the text of the header (what comes after the colon).  If the
                //	string to search is zero-length, this matches all messages that
                //	have a header line with the specified field-name regardless of
                //	the contents.
                //
                //	NOTE: Compare must be done on decoded header field value.
                //		  In all search keys that use strings, a message matches the key if
                //		  the string is a substring of the field.  The matching is case-insensitive.
            else if (m_SearchKeyName == "HEADER")
            {
                string[] headerField_value = (string[]) m_SearchKeyValue;

                // If header field name won't end with :, add it
                if (!headerField_value[0].EndsWith(":"))
                {
                    headerField_value[0] = headerField_value[0] + ":";
                }

                if (mime.MainEntity.Header.Contains(headerField_value[0]))
                {
                    if (headerField_value[1].Length == 0)
                    {
                        return true;
                    }
                    else if (
                        mime.MainEntity.Header.GetFirst(headerField_value[0]).Value.ToLower().IndexOf(
                            headerField_value[1].ToLower()) > -1)
                    {
                        return true;
                    }
                }
            }

                #endregion

                #region KEYWORD

                // KEYWORD <flag>
                //	Messages with the specified keyword flag set.
            else if (m_SearchKeyName == "KEYWORD")
            {
                if ((flags & IMAP_Utils.ParseMessageFlags((string) m_SearchKeyValue)) != 0)
                {
                    return true;
                }
            }

                #endregion
				
                #region LARGER
	
                // LARGER <n>
                //	Messages with an [RFC-2822] size larger than the specified number of octets.
            else if (m_SearchKeyName == "LARGER")
            {
                if (size > (long) m_SearchKeyValue)
                {
                    return true;
                }
            }

                #endregion

                #region NOT

                //	NOT <search-key> or (<search-key> <search-key> ...)(SearchGroup)
                //		Messages that do not match the specified search key.
            else if (m_SearchKeyName == "NOT")
            {
                return
                    !SearchGroup.Match_Key_Value(m_SearchKeyValue,
                                                 no,
                                                 uid,
                                                 size,
                                                 internalDate,
                                                 flags,
                                                 mime,
                                                 bodyText);
            }

                #endregion

                #region ON

                // ON <date>
                //	Messages whose internal date (disregarding time and timezone)
                //	is within the specified date.
            else if (m_SearchKeyName == "ON")
            {
                if (internalDate.Date == (DateTime) m_SearchKeyValue)
                {
                    return true;
                }
            }

                #endregion

                #region OR

                //	OR <search-key1> <search-key2> - SearckKey can be parenthesis list of keys !
                //		Messages that match either search key.
            else if (m_SearchKeyName == "OR")
            {
                object serachKey1 = ((object[]) m_SearchKeyValue)[0];
                object serachKey2 = ((object[]) m_SearchKeyValue)[1];

                if (
                    SearchGroup.Match_Key_Value(serachKey1, no, uid, size, internalDate, flags, mime, bodyText) ||
                    SearchGroup.Match_Key_Value(serachKey2, no, uid, size, internalDate, flags, mime, bodyText))
                {
                    return true;
                }
            }

                #endregion

                #region SENTBEFORE

                // SENTBEFORE <date>
                //	Messages whose [RFC-2822] Date: header (disregarding time and
                //	timezone) is earlier than the specified date.
            else if (m_SearchKeyName == "SENTBEFORE")
            {
                if (mime.MainEntity.Date.Date < (DateTime) m_SearchKeyValue)
                {
                    return true;
                }
            }

                #endregion

                #region SENTON

                // SENTON <date>
                //	Messages whose [RFC-2822] Date: header (disregarding time and
                //	timezone) is within the specified date.
            else if (m_SearchKeyName == "SENTON")
            {
                if (mime.MainEntity.Date.Date == (DateTime) m_SearchKeyValue)
                {
                    return true;
                }
            }

                #endregion

                #region SENTSINCE

                // SENTSINCE <date>
                //	Messages whose [RFC-2822] Date: header (disregarding time and
                //	timezone) is within or later than the specified date.
            else if (m_SearchKeyName == "SENTSINCE")
            {
                if (mime.MainEntity.Date.Date >= (DateTime) m_SearchKeyValue)
                {
                    return true;
                }
            }

                #endregion

                #region SINCE

                // SINCE <date>
                //	Messages whose internal date (disregarding time and timezone)
                //	is within or later than the specified date.	
            else if (m_SearchKeyName == "SINCE")
            {
                if (internalDate.Date >= (DateTime) m_SearchKeyValue)
                {
                    return true;
                }
            }

                #endregion

                #region SMALLER

                // SMALLER <n>
                //	Messages with an [RFC-2822] size smaller than the specified	number of octets.
            else if (m_SearchKeyName == "SMALLER")
            {
                if (size < (long) m_SearchKeyValue)
                {
                    return true;
                }
            }

                #endregion

                #region TEXT

                // TEXT <string>
                //	Messages that contain the specified string in the header or	body of the message.
                //
                //  NOTE: Compare must be done on decoded header and decoded body of message.
                //		  In all search keys that use strings, a message matches the key if
                //		  the string is a substring of the field.  The matching is case-insensitive.
            else if (m_SearchKeyName == "TEXT")
            {
                // See body first
                string val = bodyText;
                if (val != null && val.ToLower().IndexOf(((string) m_SearchKeyValue).ToLower()) > -1)
                {
                    return true;
                }

                // If we reach so far, that means body won't contain specified text and we need to check header.
                foreach (HeaderField headerField in mime.MainEntity.Header)
                {
                    if (headerField.Value.ToLower().IndexOf(((string) m_SearchKeyValue).ToLower()) > -1)
                    {
                        return true;
                    }
                }
            }

                #endregion

                #region UID

                // UID <sequence set>
                //	Messages with unique identifiers corresponding to the specified
                //	unique identifier set.  Sequence set ranges are permitted.
            else if (m_SearchKeyName == "UID")
            {
                return ((IMAP_SequenceSet) m_SearchKeyValue).Contains(uid);
            }

                #endregion

                #region UNKEYWORD

                // UNKEYWORD <flag>
                //	Messages that do not have the specified keyword flag set.
            else if (m_SearchKeyName == "UNKEYWORD")
            {
                if ((flags & IMAP_Utils.ParseMessageFlags((string) m_SearchKeyValue)) == 0)
                {
                    return true;
                }
            }

                #endregion

                #region SEQUENCESET

                // <sequence set>
                //		Messages with message sequence numbers corresponding to the
                //		specified message sequence number set.
            else if (m_SearchKeyName == "SEQUENCESET")
            {
                return ((IMAP_SequenceSet) m_SearchKeyValue).Contains(no);
            }

            #endregion

            return false;
        }
Beispiel #26
0
 /// <summary>
 /// Adds new message to list.
 /// </summary>
 /// <param name="messageID">Internal messageID.</param>
 /// <param name="UID">Message UID. NOTE: message uid must increase all the time, for new messages.</param>
 /// <param name="flags">Message flags.</param>
 /// <param name="size">Message size.</param>
 /// <param name="date">Message receive date.</param>
 public void AddMessage(string messageID, int UID, IMAP_MessageFlags flags, long size, DateTime date)
 {
     m_Messages.Add(UID, new IMAP_Message(this, messageID, UID, flags, size, date));
 }
        /// <summary>
        /// Stores message to specified folder.
        /// </summary>
        /// <param name="folderName">Folder where to store message.</param>
        /// <param name="messageFlags">Message flags what are stored for message.</param>
        /// <param name="inernalDate">Internal date value what are stored for message.</param>
        /// <param name="data">Message data which to store.</param>
        public void StoreMessage(string folderName,IMAP_MessageFlags messageFlags,DateTime inernalDate,byte[] data)
        {
            if(!m_Connected){
                throw new Exception("You must connect first !");
            }
            if(!m_Authenticated){
                throw new Exception("You must authenticate first !");
            }

            // Ensure that we send right separator to server, we accept both \ and /.
            folderName = folderName.Replace('\\',this.PathSeparator).Replace('/',this.PathSeparator);

            m_pSocket.WriteLine("a1 APPEND \"" + Core.Encode_IMAP_UTF7_String(folderName) + "\" (" + IMAP_Utils.MessageFlagsToString(messageFlags) + ") \"" + IMAP_Utils.DateTimeToString(inernalDate) + "\" {" + data.Length + "}");

            // Read server resposnse
            string reply = m_pSocket.ReadLine();

            // There is STATUS reponse, read and process it
            while(reply.StartsWith("*")){
                ProcessStatusResponse(reply);

                reply = m_pSocket.ReadLine();
            }

            // We must get reply with starting +
            if(reply.StartsWith("+")){
                // Send message
                m_pSocket.Write(data);

                // Send CRLF, ends splitted command line
                m_pSocket.Write(new byte[]{(byte)'\r',(byte)'\n'});

                // Read server resposnse
                reply = m_pSocket.ReadLine();

                // There is STATUS reponse, read and process it
                while(reply.StartsWith("*")){
                    ProcessStatusResponse(reply);

                    reply = m_pSocket.ReadLine();
                }

                // We must get OK or otherwise there is error
                if(!RemoveCmdTag(reply).ToUpper().StartsWith("OK")){
                    throw new Exception("Server returned:" + reply);
                }
            }
            else{
                throw new Exception("Server returned:" + reply);
            }
        }
Beispiel #28
0
 /// <summary>
 /// Adds new message to list.
 /// </summary>
 /// <param name="messageID">Internal messageID.</param>
 /// <param name="UID">Message UID. NOTE: message uid must increase all the time, for new messages.</param>
 /// <param name="flags">Message flags.</param>
 /// <param name="size">Message size.</param>
 /// <param name="date">Message receive date.</param>
 public void AddMessage(string messageID,int UID,IMAP_MessageFlags flags,long size,DateTime date)
 {
     m_Messages.Add(UID,new IMAP_Message(this,messageID,UID,flags,size,date));
 }
 /// <summary>
 /// Stores IMAP message flags (\seen,\draft, ...).
 /// </summary>
 /// <param name="accessingUser">User who accesses this method. 
 /// User needs r permission to call this method or Exception is thrown. 
 /// There is special user 'system' for which permission check is skipped.</param>
 /// <param name="folderOwnerUser">User who's folder it is.</param>
 /// <param name="folder">Folder which message flags to store. For example: Inbox,Public Folders/Documnets .</param>
 /// <param name="message">Fix ME: ???</param>
 /// <param name="msgFlags">Message flags to store.</param>
 public void StoreMessageFlags(string accessingUser,string folderOwnerUser,string folder,LumiSoft.Net.IMAP.Server.IMAP_Message message,IMAP_MessageFlags msgFlags)
 {
     StoreMessageFlags(accessingUser,folderOwnerUser,folder,(int)message.UID,msgFlags);
 }
        /// <summary>
        /// Stores specified message flags to specified messages.
        /// </summary>
        /// <param name="sequence_set">IMAP sequence-set.</param>
        /// <param name="msgFlags">Message flags.</param>
        /// <param name="uidStore">Specifies if UID STORE or STORE. 
        /// For UID STORE all sequence_set numers must be message UID values and for normal STORE message numbers.</param>
        public void StoreMessageFlags(IMAP_SequenceSet sequence_set,IMAP_MessageFlags msgFlags,bool uidStore)
        {
            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 !");
            }

            if(uidStore){
                m_pSocket.WriteLine("a1 UID STORE " + sequence_set.ToSequenceSetString() + " FLAGS (" + IMAP_Utils.MessageFlagsToString(msgFlags) + ")");
            }
            else{
                m_pSocket.WriteLine("a1 STORE " + sequence_set.ToSequenceSetString() + " FLAGS (" + IMAP_Utils.MessageFlagsToString(msgFlags) + ")");
            }

            // Read server resposnse
            string reply = m_pSocket.ReadLine();

            // There is STATUS reponse, read and process it
            while(reply.StartsWith("*")){
                ProcessStatusResponse(reply);

                reply = m_pSocket.ReadLine();
            }

            // We must get OK or otherwise there is error
            if(!RemoveCmdTag(reply).ToUpper().StartsWith("OK")){
                throw new Exception("Server returned:" + reply);
            }
        }
 /// <summary>
 /// Gets messages which has specified flags set.
 /// </summary>
 /// <param name="flags">Flags to match.</param>
 /// <returns></returns>
 public IMAP_Message[] GetWithFlags(IMAP_MessageFlags flags)
 {
     List<IMAP_Message> retVal = new List<IMAP_Message>();
     foreach (IMAP_Message message in m_pMessages.Values)
     {
         if ((message.Flags & flags) != 0)
         {
             retVal.Add(message);
         }
     }
     return retVal.ToArray();
 }
        /// <summary>
        /// Sets specified message flags for specified user.
        /// </summary>
        /// <param name="userID">User ID.</param>
        /// <param name="folder">Folder.</param>
        /// <param name="uid">Message UID.</param>
        /// <param name="flags">Message flags.</param>
        public static void SetFlags(string userID,string folder,int uid,IMAP_MessageFlags flags)
        {
            using(FileStream fs = GetFlagsFile(userID,folder)){
                StreamLineReader r    = new StreamLineReader(fs);
                long             pos  = fs.Position;
                string           line = r.ReadLineString();
                while(line != null){
                    // Skip comment lines
                    if(!line.StartsWith("#")){
                        string[] userID_uid_flags = line.Split(' ');
                        // Update user message flags
                        if(userID_uid_flags[0] == userID && Convert.ToInt32(userID_uid_flags[1]) == uid){
                            fs.Position = pos;
                            byte[] record1 = System.Text.Encoding.ASCII.GetBytes(userID + " " + uid.ToString("d10") + " " + ((int)flags).ToString("d4") + "\r\n");
                            fs.Write(record1,0,record1.Length);
                            return;
                        }
                    }

                    pos  = fs.Position;
                    line = r.ReadLineString();
                }

                // If we reach here, then specified user has no flags for specified message, add new record.
                byte[] record = System.Text.Encoding.ASCII.GetBytes(userID + " " + uid.ToString("d10") + " " + ((int)flags).ToString("d4") + "\r\n");
                fs.Write(record,0,record.Length);
            }
        }
        /// <summary>
        /// Gets if specified message matches with this class search-key.
        /// </summary>
        /// <param name="no">IMAP message sequence number.</param>
        /// <param name="uid">IMAP message UID.</param>
        /// <param name="size">IMAP message size in bytes.</param>
        /// <param name="internalDate">IMAP message INTERNALDATE (dateTime when server stored message).</param>
        /// <param name="flags">IMAP message flags.</param>
        /// <param name="mime">Mime message main header only.</param>
        /// <param name="bodyText">Message body text.</param>
        /// <returns></returns>
        public bool Match(long no,
                          long uid,
                          long size,
                          DateTime internalDate,
                          IMAP_MessageFlags flags,
                          Mime mime,
                          string bodyText)
        {
            #region ALL

            // ALL
            //		All messages in the mailbox; the default initial key for ANDing.
            if (m_SearchKeyName == "ALL")
            {
                return(true);
            }

            #endregion

            #region BEFORE

            // BEFORE <date>
            //	Messages whose internal date (disregarding time and timezone)
            //	is earlier than the specified date.
            else if (m_SearchKeyName == "BEFORE")
            {
                if (internalDate.Date < (DateTime)m_SearchKeyValue)
                {
                    return(true);
                }
            }

            #endregion

            #region BODY

            // BODY <string>
            //	Messages that contain the specified string in the body of the message.
            //
            //	NOTE: Compare must be done on decoded header and decoded body of message.
            //		  In all search keys that use strings, a message matches the key if
            //		  the string is a substring of the field.  The matching is case-insensitive.
            else if (m_SearchKeyName == "BODY")
            {
                string val = bodyText;
                if (val != null && val.ToLower().IndexOf(((string)m_SearchKeyValue).ToLower()) > -1)
                {
                    return(true);
                }
            }

            #endregion

            #region HEADER

            // HEADER <field-name> <string>
            //	Messages that have a header with the specified field-name (as
            //	defined in [RFC-2822]) and that contains the specified string
            //	in the text of the header (what comes after the colon).  If the
            //	string to search is zero-length, this matches all messages that
            //	have a header line with the specified field-name regardless of
            //	the contents.
            //
            //	NOTE: Compare must be done on decoded header field value.
            //		  In all search keys that use strings, a message matches the key if
            //		  the string is a substring of the field.  The matching is case-insensitive.
            else if (m_SearchKeyName == "HEADER")
            {
                string[] headerField_value = (string[])m_SearchKeyValue;

                // If header field name won't end with :, add it
                if (!headerField_value[0].EndsWith(":"))
                {
                    headerField_value[0] = headerField_value[0] + ":";
                }

                if (mime.MainEntity.Header.Contains(headerField_value[0]))
                {
                    if (headerField_value[1].Length == 0)
                    {
                        return(true);
                    }
                    else if (
                        mime.MainEntity.Header.GetFirst(headerField_value[0]).Value.ToLower().IndexOf(
                            headerField_value[1].ToLower()) > -1)
                    {
                        return(true);
                    }
                }
            }

            #endregion

            #region KEYWORD

            // KEYWORD <flag>
            //	Messages with the specified keyword flag set.
            else if (m_SearchKeyName == "KEYWORD")
            {
                if ((flags & IMAP_Utils.ParseMessageFlags((string)m_SearchKeyValue)) != 0)
                {
                    return(true);
                }
            }

            #endregion

            #region LARGER

            // LARGER <n>
            //	Messages with an [RFC-2822] size larger than the specified number of octets.
            else if (m_SearchKeyName == "LARGER")
            {
                if (size > (long)m_SearchKeyValue)
                {
                    return(true);
                }
            }

            #endregion

            #region NOT

            //	NOT <search-key> or (<search-key> <search-key> ...)(SearchGroup)
            //		Messages that do not match the specified search key.
            else if (m_SearchKeyName == "NOT")
            {
                return
                    (!SearchGroup.Match_Key_Value(m_SearchKeyValue,
                                                  no,
                                                  uid,
                                                  size,
                                                  internalDate,
                                                  flags,
                                                  mime,
                                                  bodyText));
            }

            #endregion

            #region ON

            // ON <date>
            //	Messages whose internal date (disregarding time and timezone)
            //	is within the specified date.
            else if (m_SearchKeyName == "ON")
            {
                if (internalDate.Date == (DateTime)m_SearchKeyValue)
                {
                    return(true);
                }
            }

            #endregion

            #region OR

            //	OR <search-key1> <search-key2> - SearckKey can be parenthesis list of keys !
            //		Messages that match either search key.
            else if (m_SearchKeyName == "OR")
            {
                object serachKey1 = ((object[])m_SearchKeyValue)[0];
                object serachKey2 = ((object[])m_SearchKeyValue)[1];

                if (
                    SearchGroup.Match_Key_Value(serachKey1, no, uid, size, internalDate, flags, mime, bodyText) ||
                    SearchGroup.Match_Key_Value(serachKey2, no, uid, size, internalDate, flags, mime, bodyText))
                {
                    return(true);
                }
            }

            #endregion

            #region SENTBEFORE

            // SENTBEFORE <date>
            //	Messages whose [RFC-2822] Date: header (disregarding time and
            //	timezone) is earlier than the specified date.
            else if (m_SearchKeyName == "SENTBEFORE")
            {
                if (mime.MainEntity.Date.Date < (DateTime)m_SearchKeyValue)
                {
                    return(true);
                }
            }

            #endregion

            #region SENTON

            // SENTON <date>
            //	Messages whose [RFC-2822] Date: header (disregarding time and
            //	timezone) is within the specified date.
            else if (m_SearchKeyName == "SENTON")
            {
                if (mime.MainEntity.Date.Date == (DateTime)m_SearchKeyValue)
                {
                    return(true);
                }
            }

            #endregion

            #region SENTSINCE

            // SENTSINCE <date>
            //	Messages whose [RFC-2822] Date: header (disregarding time and
            //	timezone) is within or later than the specified date.
            else if (m_SearchKeyName == "SENTSINCE")
            {
                if (mime.MainEntity.Date.Date >= (DateTime)m_SearchKeyValue)
                {
                    return(true);
                }
            }

            #endregion

            #region SINCE

            // SINCE <date>
            //	Messages whose internal date (disregarding time and timezone)
            //	is within or later than the specified date.
            else if (m_SearchKeyName == "SINCE")
            {
                if (internalDate.Date >= (DateTime)m_SearchKeyValue)
                {
                    return(true);
                }
            }

            #endregion

            #region SMALLER

            // SMALLER <n>
            //	Messages with an [RFC-2822] size smaller than the specified	number of octets.
            else if (m_SearchKeyName == "SMALLER")
            {
                if (size < (long)m_SearchKeyValue)
                {
                    return(true);
                }
            }

            #endregion

            #region TEXT

            // TEXT <string>
            //	Messages that contain the specified string in the header or	body of the message.
            //
            //  NOTE: Compare must be done on decoded header and decoded body of message.
            //		  In all search keys that use strings, a message matches the key if
            //		  the string is a substring of the field.  The matching is case-insensitive.
            else if (m_SearchKeyName == "TEXT")
            {
                // See body first
                string val = bodyText;
                if (val != null && val.ToLower().IndexOf(((string)m_SearchKeyValue).ToLower()) > -1)
                {
                    return(true);
                }

                // If we reach so far, that means body won't contain specified text and we need to check header.
                foreach (HeaderField headerField in mime.MainEntity.Header)
                {
                    if (headerField.Value.ToLower().IndexOf(((string)m_SearchKeyValue).ToLower()) > -1)
                    {
                        return(true);
                    }
                }
            }

            #endregion

            #region UID

            // UID <sequence set>
            //	Messages with unique identifiers corresponding to the specified
            //	unique identifier set.  Sequence set ranges are permitted.
            else if (m_SearchKeyName == "UID")
            {
                return(((IMAP_SequenceSet)m_SearchKeyValue).Contains(uid));
            }

            #endregion

            #region UNKEYWORD

            // UNKEYWORD <flag>
            //	Messages that do not have the specified keyword flag set.
            else if (m_SearchKeyName == "UNKEYWORD")
            {
                if ((flags & IMAP_Utils.ParseMessageFlags((string)m_SearchKeyValue)) == 0)
                {
                    return(true);
                }
            }

            #endregion

            #region SEQUENCESET

            // <sequence set>
            //		Messages with message sequence numbers corresponding to the
            //		specified message sequence number set.
            else if (m_SearchKeyName == "SEQUENCESET")
            {
                return(((IMAP_SequenceSet)m_SearchKeyValue).Contains(no));
            }

            #endregion

            return(false);
        }
Beispiel #34
0
        public static string[] MessageFlagsToStringArray(IMAP_MessageFlags msgFlags)
        {
            List<string> retVal = new List<string>();

            if(((int)IMAP_MessageFlags.Answered & (int)msgFlags) != 0){
				retVal.Add("\\ANSWERED");
			}
			if(((int)IMAP_MessageFlags.Flagged & (int)msgFlags) != 0){
				retVal.Add("\\FLAGGED");
			}
			if(((int)IMAP_MessageFlags.Deleted & (int)msgFlags) != 0){
				retVal.Add("\\DELETED");
			}
			if(((int)IMAP_MessageFlags.Seen & (int)msgFlags) != 0){
				retVal.Add("\\SEEN");
			}
			if(((int)IMAP_MessageFlags.Draft & (int)msgFlags) != 0){
				retVal.Add("\\DRAFT");
			}

            return retVal.ToArray();
        }
        /// <summary>
        /// Stores IMAP message flags (\seen,\draft, ...).
        /// </summary>
        /// <param name="accessingUser">User who accesses this method. 
        /// User needs r permission to call this method or Exception is thrown. 
        /// There is special user 'system' for which permission check is skipped.</param>
        /// <param name="folderOwnerUser">User who's folder it is.</param>
        /// <param name="folder">Folder which message flags to store. For example: Inbox,Public Folders/Documnets .</param>
        /// <param name="message">Fix ME: ???</param>
        /// <param name="msgFlags">Message flags to store.</param>
        public void StoreMessageFlags(string accessingUser,string folderOwnerUser,string folder,LumiSoft.Net.IMAP.Server.IMAP_Message message,IMAP_MessageFlags msgFlags)
        {
            /* Implementation notes:
                *) Validate values. Throw ArgumnetExcetion if invalid values.
                *) Ensure that user exists.
                *) Normalize folder. Remove '/' from folder start and end, ... .
                *) Do Shared Folders mapping.
                *) Ensure that folder exists. Throw Exception if don't.
                *) Remove all message flags which permissions user doesn't have.
                *) Store message.
            */

            //--- Validate values -------------------//
            ArgsValidator.ValidateUserName(folderOwnerUser);
            ArgsValidator.ValidateFolder(folder);
            ArgsValidator.ValidateNotNull(message);
            //---------------------------------------//

            // Ensure that user exists.
            if(!UserExists(folderOwnerUser)){
                throw new Exception("User '" + folderOwnerUser + "' doesn't exist !");
            }

            // Normalize folder. Remove '/' from folder start and end.
            folder = API_Utlis.NormalizeFolder(folder);

            // Do Shared Folders mapping.
            string originalFolder = folder;
            SharedFolderMapInfo mappedFolder = MapSharedFolder(originalFolder);
            if(mappedFolder.IsSharedFolder){
                folderOwnerUser = mappedFolder.FolderOnwer;
                folder = mappedFolder.Folder;

                if(folderOwnerUser == "" || folder == ""){
                    throw new ArgumentException("Specified root folder '" + originalFolder + "' isn't accessible !");
                }
            }

            // Ensure that folder exists. Throw Exception if don't.
            if(!FolderExists(folderOwnerUser + "/" + folder)){
                throw new Exception("Folder '" + folder + "' doesn't exist !");
            }

            // Remove all message flags which permissions user doesn't have.
            if(accessingUser != "system"){
                IMAP_ACL_Flags userACL = GetUserACL(folderOwnerUser,folder,accessingUser);
                if((userACL & IMAP_ACL_Flags.s) == 0){
                    msgFlags &= ~IMAP_MessageFlags.Seen;
                }
                else if((userACL & IMAP_ACL_Flags.d) == 0){
                    msgFlags &= ~IMAP_MessageFlags.Deleted;
                }
                else if((userACL & IMAP_ACL_Flags.s) == 0){
                    msgFlags &= (~IMAP_MessageFlags.Answered | ~IMAP_MessageFlags.Draft | ~IMAP_MessageFlags.Flagged);
                }
            }

            //--- Store message flags
            using(WSqlCommand sqlCmd = new WSqlCommand(m_ConStr,"lspr_StoreMessageFlags")){
                sqlCmd.AddParameter("_userName"     ,NpgsqlDbType.Varchar,folderOwnerUser);
                sqlCmd.AddParameter("_folder"       ,NpgsqlDbType.Varchar,folder);
                sqlCmd.AddParameter("_messageID"    ,NpgsqlDbType.Varchar,message.ID);
                sqlCmd.AddParameter("_messageFlags" ,NpgsqlDbType.Integer,(int)message.Flags);

                DataSet ds = sqlCmd.Execute();
            }
        }
        /// <summary>
        /// Stores message to specified folder.
        /// </summary>
        /// <param name="accessingUser">User who accesses this method. 
        /// User needs r permission to call this method or Exception is thrown. 
        /// There is special user 'system' for which permission check is skipped.</param>
        /// <param name="folderOwnerUser">User who's folder it is.</param>
        /// <param name="folder">Folder where to store message. For example: Inbox,Public Folders/Documnets .</param>
        /// <param name="msgStream">Stream where message has stored. Stream position must be at the beginning of the message.</param>
        /// <param name="date">Recieve date.</param>
        /// <param name="flags">Message flags.</param>
        public void StoreMessage(string accessingUser,string folderOwnerUser,string folder,Stream msgStream,DateTime date,IMAP_MessageFlags flags)
        {
            /* Implementation notes:
                *) Validate values. Throw ArgumnetExcetion if invalid values.
                *) Ensure that user exists.
                *) Normalize folder. Remove '/' from folder start and end, ... .
                *) Do Shared Folders mapping.
                *) Ensure that folder exists. Throw Exception if don't.
                *) See if user has sufficient permissions. User requires 'p' or 'i' permission.
                    There is builtin user system, skip ACL for it.
                *) Store message.
            */

            //--- Validate values -------------------//
            ArgsValidator.ValidateUserName(folderOwnerUser);
            ArgsValidator.ValidateFolder(folder);
            ArgsValidator.ValidateNotNull(msgStream);
            //---------------------------------------//

            // Ensure that user exists.
            if(!UserExists(folderOwnerUser)){
                throw new Exception("User '" + folderOwnerUser + "' doesn't exist !");
            }

            // Normalize folder. Remove '/' from folder start and end.
            folder = API_Utlis.NormalizeFolder(folder);

            // Do Shared Folders mapping.
            string originalFolder = folder;
            SharedFolderMapInfo mappedFolder = MapSharedFolder(originalFolder);
            if(mappedFolder.IsSharedFolder){
                folderOwnerUser = mappedFolder.FolderOnwer;
                folder = mappedFolder.Folder;

                if(folderOwnerUser == "" || folder == ""){
                    throw new ArgumentException("Specified root folder '" + originalFolder + "' isn't accessible !");
                }
            }

            // Ensure that folder exists. Throw Exception if don't.
            if(!FolderExists(folderOwnerUser + "/" + folder)){
                throw new Exception("Folder '" + folder + "' doesn't exist !");
            }

            // See if user has sufficient permissions. User requires 'p' or 'i' permission.
            //  There is builtin user system, skip ACL for it.
            if(accessingUser.ToLower() != "system"){
                IMAP_ACL_Flags acl = GetUserACL(folderOwnerUser,folder,accessingUser);
                if((acl & IMAP_ACL_Flags.p) == 0 && (acl & IMAP_ACL_Flags.i) == 0){
                    throw new InsufficientPermissionsException("Insufficient permissions for folder '" + accessingUser + "/" + folder + "' !");
                }
            }

            //--- Store message
            byte[] topLines = GetTopLines(msgStream,50);
            msgStream.Position = 0;
            byte[] messageData = new byte[msgStream.Length];
            msgStream.Read(messageData,0,messageData.Length);
            Mime m = null;
            try{
                msgStream.Position = 0;
                m = Mime.Parse(msgStream);
            }
            catch(Exception x){
                m = LumiSoft.Net.Mime.Mime.CreateSimple(new AddressList(),new AddressList(),"[BAD MESSAGE] Bad message, message parsing failed !","NOTE: Bad message, message parsing failed !\r\n\r\n" + x.Message,"");
            }
            byte[] envelope = System.Text.Encoding.Default.GetBytes(IMAP_Envelope.ConstructEnvelope(m.MainEntity));
            byte[] body     = System.Text.Encoding.Default.GetBytes(IMAP_BODY.ConstructBodyStructure(m,false));

            using(WSqlCommand sqlCmd = new WSqlCommand(m_ConStr,"lspr_StoreMessage")){
                sqlCmd.AddParameter("_userName"     ,NpgsqlDbType.Varchar   ,folderOwnerUser);
                sqlCmd.AddParameter("_folder"       ,NpgsqlDbType.Varchar   ,folder);
                sqlCmd.AddParameter("_messageID"    ,NpgsqlDbType.Varchar   ,Guid.NewGuid().ToString());
                sqlCmd.AddParameter("_size"         ,NpgsqlDbType.Integer   ,msgStream.Length);
                sqlCmd.AddParameter("_messageFlags" ,NpgsqlDbType.Integer   ,(int)flags);
                sqlCmd.AddParameter("_date"         ,NpgsqlDbType.Timestamp ,date);
                sqlCmd.AddParameter("_topLines"     ,NpgsqlDbType.Bytea     ,topLines);
                sqlCmd.AddParameter("_data"         ,NpgsqlDbType.Bytea     ,messageData);
                sqlCmd.AddParameter("_imapEnvelope" ,NpgsqlDbType.Bytea     ,envelope);
                sqlCmd.AddParameter("_imapBody"     ,NpgsqlDbType.Bytea     ,body);

                DataSet ds = sqlCmd.Execute();
            }
        }
        /// <summary>
        /// Stores message to specified mailbox.
        /// </summary>
        /// <param name="mailbox">Mailbox name.</param>
        /// <param name="folder">Folder where to store message. Eg. 'Inbox'.</param>
        /// <param name="msgStream">Stream where message has stored.</param>
        /// <param name="to">Recipient email address.</param>
        /// <param name="from">Sendred email address.</param>
        /// <param name="isRelay">Specifies if message must be relayed.</param>
        /// <param name="date">Recieve date.</param>
        /// <param name="flags">Message flags.</param>
        public void StoreMessage(string mailbox,string folder,MemoryStream msgStream,string to,string from,bool isRelay,DateTime date,IMAP_MessageFlags flags)
        {
            // Store relay messages locally
            if(isRelay){
                // Create dummy file name
                string filename = Guid.NewGuid().ToString();
                       filename = filename.Substring(0,22);
                       filename = filename.Replace("-","_");

                string path = m_MailStorePath + "Relay\\";

                // Check if Directory exists, if not Create
                if(!Directory.Exists(path)){
                    Directory.CreateDirectory(path);
                }

                //---- Write message data to file -------------------------------//
                using(FileStream fStream = File.Create(path + "\\" + filename + ".eml",(int)msgStream.Length)){

                    // Write internal relay info line at the beginning of messsage.
                    // Note: This line is skipped when sending to destination host,
                    // actual message begins from 2 line.
                    // Header struct: 'RelayInfo:IsUndeliveredWarningSent<TAB>To<TAB>Sender<TAB>Date\r\n'
                    string internalServerHead = "RelayInfo:0\t" + to + "\t" + from + "\t" + DateTime.Now.ToString("r",System.Globalization.DateTimeFormatInfo.InvariantInfo) + "\r\n";
                    byte[] sHead = System.Text.Encoding.Default.GetBytes(internalServerHead);
                    fStream.Write(sHead,0,sHead.Length);

                    msgStream.WriteTo(fStream);
                }
                //---------------------------------------------------------------//

                return; // !!!
            }

            switch(m_DB_Type)
            {
                #region DB_Type.XML

                case DB_Type.XML:
                    string path = m_MailStorePath + "MailBoxes\\" + mailbox + "\\" + folder + "\\";

                    // Check if Directory exists, if not Create for Inbox only
                    if(!Directory.Exists(path)){
                        if(folder.ToLower().Trim() == "inbox"){
                            Directory.CreateDirectory(path);
                        }
                        else{
                            throw new Exception("Folder '" + folder + "' doesn't exist");
                        }
                    }

                    string fileName = date.ToString("yyyyMMddHHmmss") + "_" + GetNextUid(mailbox,folder) + "_" + Convert.ToString((int)flags);

                    //---- Write message data to file -------------------------------//
                    using(FileStream fStream = File.Create(path + fileName + ".eml",(int)msgStream.Length)){
                        msgStream.WriteTo(fStream);
                    }
                    //---------------------------------------------------------------//

                    break;

                #endregion

                #region DB_Type.MSSQL

                case DB_Type.MSSQL:

                    byte[] topLines = null;
                    topLines = GetTopLines(msgStream,50);

                    using(WSqlCommand sqlCmd = new WSqlCommand(m_ConStr,"lspr_StoreMessage")){
                        sqlCmd.AddParameter("@MailBox"      ,SqlDbType.NVarChar ,mailbox);
                        sqlCmd.AddParameter("@Folder"       ,SqlDbType.NVarChar ,folder);
                        sqlCmd.AddParameter("@Data"         ,SqlDbType.Image    ,msgStream.ToArray());
                        sqlCmd.AddParameter("@Size"         ,SqlDbType.BigInt   ,msgStream.Length);
                        sqlCmd.AddParameter("@TopLines"     ,SqlDbType.Image    ,topLines);
                        sqlCmd.AddParameter("@Date"         ,SqlDbType.DateTime ,date);
                        sqlCmd.AddParameter("@MessageFlags" ,SqlDbType.Int      ,(int)flags);

                        DataSet ds = sqlCmd.Execute();
                    }
                    break;

                #endregion
            }
        }
Beispiel #38
0
 /// <summary>
 /// Sets message flags.
 /// </summary>
 /// <param name="flags">Message flags.</param>
 internal void SetFlags(IMAP_MessageFlags flags)
 {
     m_Flags = flags;
 }
        /// <summary>
        /// Gets if specified message matches to specified search key.
        /// </summary>
        /// <param name="searchKey">SearchKey or SearchGroup.</param>
        /// <param name="no">IMAP message sequence number.</param>
        /// <param name="uid">IMAP message UID.</param>
        /// <param name="size">IMAP message size in bytes.</param>
        /// <param name="internalDate">IMAP message INTERNALDATE (dateTime when server stored message).</param>
        /// <param name="flags">IMAP message flags.</param>
        /// <param name="mime">Mime message main header only.</param>
        /// <param name="bodyText">Message body text.</param>
        /// <returns></returns>
        internal static bool Match_Key_Value(object searchKey,
                                             long no,
                                             long uid,
                                             long size,
                                             DateTime internalDate,
                                             IMAP_MessageFlags flags,
                                             Mime mime,
                                             string bodyText)
        {
            if (searchKey.GetType() == typeof (SearchKey))
            {
                if (!((SearchKey) searchKey).Match(no, uid, size, internalDate, flags, mime, bodyText))
                {
                    return false;
                }
            }
            else if (searchKey.GetType() == typeof (SearchGroup))
            {
                if (!((SearchGroup) searchKey).Match(no, uid, size, internalDate, flags, mime, bodyText))
                {
                    return false;
                }
            }

            return true;
        }
        /// <summary>
        /// Stores IMAP message flags (\seen,\draft, ...).
        /// </summary>
        /// <param name="accessingUser">User who accesses this method. 
        /// User needs r permission to call this method or Exception is thrown. 
        /// There is special user 'system' for which permission check is skipped.</param>
        /// <param name="folderOwnerUser">User who's folder it is.</param>
        /// <param name="folder">Folder which message flags to store. For example: Inbox,Public Folders/Documnets .</param>
        /// <param name="uid">Message UID.</param>
        /// <param name="msgFlags">Message flags to store.</param>
        private void StoreMessageFlags(string accessingUser,string folderOwnerUser,string folder,int uid,IMAP_MessageFlags msgFlags)
        {
            /* Implementation notes:
                *) Validate values. Throw ArgumnetExcetion if invalid values.
                *) Ensure that user exists.
                *) Normalize folder. Remove '/' from folder start and end, ... .
                *) Do Shared Folders mapping.
                *) Ensure that folder exists. Throw Exception if don't.
                *) Remove all message flags which permissions user doesn't have.
                *) Store message.
            */

            //--- Validate values -------------------//
            ArgsValidator.ValidateUserName(folderOwnerUser);
            ArgsValidator.ValidateFolder(folder);
            //---------------------------------------//

            // Ensure that user exists.
            if(!UserExists(folderOwnerUser)){
                throw new Exception("User '" + folderOwnerUser + "' doesn't exist !");
            }

            // Normalize folder. Remove '/' from folder start and end.
            folder = API_Utlis.NormalizeFolder(folder);

            // Do Shared Folders mapping.
            string originalFolder = folder;
            SharedFolderMapInfo mappedFolder = MapSharedFolder(originalFolder);
            if(mappedFolder.IsSharedFolder){
                folderOwnerUser = mappedFolder.FolderOnwer;
                folder = mappedFolder.Folder;

                if(folderOwnerUser == "" || folder == ""){
                    throw new ArgumentException("Specified root folder '" + originalFolder + "' isn't accessible !");
                }
            }

            // Ensure that folder exists. Throw Exception if don't.
            if(!FolderExists(folderOwnerUser + "/" + folder)){
                throw new Exception("Folder '" + folder + "' doesn't exist !");
            }

            // Remove all message flags which permissions user doesn't have.
            if(accessingUser != "system"){
                IMAP_ACL_Flags userACL = GetUserACL(folderOwnerUser,folder,accessingUser);
                if((userACL & IMAP_ACL_Flags.s) == 0){
                    msgFlags &= ~IMAP_MessageFlags.Seen;
                }
                else if((userACL & IMAP_ACL_Flags.d) == 0){
                    msgFlags &= ~IMAP_MessageFlags.Deleted;
                }
                else if((userACL & IMAP_ACL_Flags.s) == 0){
                    msgFlags &= (~IMAP_MessageFlags.Answered | ~IMAP_MessageFlags.Draft | ~IMAP_MessageFlags.Flagged);
                }
            }

            //--- Store flags
            FolderMessageFlagsManager.SetFlags(
                GetUserID(folderOwnerUser),
                API_Utlis.PathFix(API_Utlis.DirectoryExists(API_Utlis.PathFix(m_MailStorePath + "Mailboxes\\" + folderOwnerUser + "\\" + Core.Encode_IMAP_UTF7_String(folder))) + "\\"),
                uid,
                msgFlags
            );
        }
		/// <summary>
		/// Stores message folgs to sepcified messages range.
		/// </summary>
		/// <param name="startMsgNo">Start message number.</param>
		/// <param name="endMsgNo">End message number.</param>
		/// <param name="uidStore">Sepcifies if message numbers are message UID numbers.</param>
		/// <param name="msgFlags">Message flags to store.</param>
		public void StoreMessageFlags(int startMsgNo,int endMsgNo,bool uidStore,IMAP_MessageFlags msgFlags)
		{
			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 !");
			}

			if(uidStore){
				m_pSocket.SendLine("a1 UID STORE " + startMsgNo + ":" + endMsgNo + " FLAGS (" + IMAP_Utils.MessageFlagsToString(msgFlags) + ")");
			}
			else{
				m_pSocket.SendLine("a1 STORE " + startMsgNo + ":" + endMsgNo + " FLAGS (" + IMAP_Utils.MessageFlagsToString(msgFlags) + ")");
			}

			// 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("*")){
					// Get rid of *
					reply = reply.Substring(1).Trim();
										
					reply = m_pSocket.ReadLine();
				}
			}
			
			reply = reply.Substring(reply.IndexOf(" ")).Trim(); // Remove Cmd tag

			if(!reply.ToUpper().StartsWith("OK")){
				throw new Exception("Server returned:" + reply);
			}
		}
        /// <summary>
        /// Stores message to specified folder.
        /// </summary>
        /// <param name="accessingUser">User who accesses this method. 
        /// User needs r permission to call this method or Exception is thrown. 
        /// There is special user 'system' for which permission check is skipped.</param>
        /// <param name="folderOwnerUser">User who's folder it is.</param>
        /// <param name="folder">Folder where to store message. For example: Inbox,Public Folders/Documnets .</param>
        /// <param name="msgStream">Stream where message has stored. Stream position must be at the beginning of the message.</param>
        /// <param name="date">Recieve date.</param>
        /// <param name="flags">Message flags.</param>
        public void StoreMessage(string accessingUser,string folderOwnerUser,string folder,Stream msgStream,DateTime date,IMAP_MessageFlags flags)
        {
            /* Implementation notes:
                *) Validate values. Throw ArgumnetExcetion if invalid values.
                *) Ensure that user exists.
                *) Normalize folder. Remove '/' from folder start and end, ... .
                *) Do Shared Folders mapping.
                *) Ensure that folder exists. Throw Exception if don't.
                *) See if user has sufficient permissions. User requires 'p' or 'i' permission.
                    There is builtin user system, skip ACL for it.
                *) Store message.
            */

            //--- Validate values -------------------//
            ArgsValidator.ValidateUserName(folderOwnerUser);
            ArgsValidator.ValidateFolder(folder);
            ArgsValidator.ValidateNotNull(msgStream);
            //---------------------------------------//

            // Ensure that user exists.
            if(!UserExists(folderOwnerUser)){
                throw new Exception("User '" + folderOwnerUser + "' doesn't exist !");
            }

            // Normalize folder. Remove '/' from folder start and end.
            folder = API_Utlis.NormalizeFolder(folder);

            // Do Shared Folders mapping.
            string originalFolder = folder;
            SharedFolderMapInfo mappedFolder = MapSharedFolder(originalFolder);
            if(mappedFolder.IsSharedFolder){
                folderOwnerUser = mappedFolder.FolderOnwer;
                folder = mappedFolder.Folder;

                if(folderOwnerUser == "" || folder == ""){
                    throw new ArgumentException("Specified root folder '" + originalFolder + "' isn't accessible !");
                }
            }

            // Ensure that folder exists. Throw Exception if don't.
            if(!FolderExists(folderOwnerUser + "/" + folder)){
                throw new Exception("Folder '" + folder + "' doesn't exist !");
            }

            // See if user has sufficient permissions. User requires 'p' or 'i' permission.
            //  There is builtin user system, skip ACL for it.
            if(accessingUser.ToLower() != "system"){
                IMAP_ACL_Flags acl = GetUserACL(folderOwnerUser,folder,accessingUser);
                if((acl & IMAP_ACL_Flags.p) == 0 && (acl & IMAP_ACL_Flags.i) == 0){
                    throw new InsufficientPermissionsException("Insufficient permissions for folder '" + accessingUser + "/" + folder + "' !");
                }
            }

            //--- Store message
            string path = API_Utlis.PathFix(API_Utlis.DirectoryExists(API_Utlis.PathFix(m_MailStorePath + "Mailboxes\\" + folderOwnerUser + "\\" + Core.Encode_IMAP_UTF7_String(folder))) + "\\");

            long fileSize = msgStream.Length - msgStream.Position;
            int uid = GetNextUid(folderOwnerUser,folder);
            string fileName = CreateMessageFileName(date.ToUniversalTime(),uid);

            //---- Write message data to file -----------------------------------------------------//
            using(FileStream fs = File.Create(path + fileName + ".eml")){
                msgStream.Position = 0;
                API_Utlis.StreamCopy(msgStream,fs);
            }

            // Check that stored file exists, some AV programs just delete stored file, if conatins virus
            if(!File.Exists(path + fileName + ".eml")){
                return;
            }

            // Increase mailbox size
            ChangeMailboxSize(folderOwnerUser,fileSize);

            //-------------------------------------------------------------------------------------//

            // Store message info to messages info db.
            FolderMessagesInfoManager.Append(path,uid,(int)fileSize,date.ToUniversalTime());

            // Recent is default falgs, so we need to store message flags only if not \Recent
            if(flags != IMAP_MessageFlags.Recent){
                StoreMessageFlags(accessingUser,folderOwnerUser,folder,uid,flags);
            }
        }
        public IMAP_Message Add(string id, long uid, DateTime internalDate, long size, IMAP_MessageFlags flags)
        {
            if (uid < 1L)
            {
                throw new ArgumentException("Message UID value must be > 0 !");
            }
            IMAP_Message iMAP_Message = new IMAP_Message(this, id, uid, internalDate, size, flags);

            this.m_pMessages.Add(uid, iMAP_Message);
            return(iMAP_Message);
        }
 /// <summary>
 /// Sets message flags.
 /// </summary>
 /// <param name="flags">Message flags.</param>
 internal void SetFlags(IMAP_MessageFlags flags)
 {
     m_Flags = flags;
 }
Beispiel #45
0
        /// <summary>
        /// Stores specified message flags to specified messages.
        /// </summary>
        /// <param name="sequence_set">IMAP sequence-set.</param>
        /// <param name="msgFlags">Message flags.</param>
        /// <param name="uidStore">Specifies if UID STORE or STORE. 
        /// For UID STORE all sequence_set numers must be message UID values and for normal STORE message numbers.</param>
        /// <exception cref="ObjectDisposedException">Is raised when this object is disposed and this method is accessed.</exception>
        /// <exception cref="InvalidOperationException">Is raised when IMAP client is not connected,not authenticated and folder not selected.</exception>
        public void StoreMessageFlags(IMAP_SequenceSet sequence_set, IMAP_MessageFlags msgFlags, bool uidStore)
        {
            if (this.IsDisposed)
            {
                throw new ObjectDisposedException(this.GetType().Name);
            }
            if (!this.IsConnected)
            {
                throw new InvalidOperationException("You must connect first.");
            }
            if (!this.IsAuthenticated)
            {
                throw new InvalidOperationException("The command is only valid in authenticated state.");
            }
            if (m_SelectedFolder.Length == 0)
            {
                throw new InvalidOperationException("The command is only valid in selected state.");
            }

            string line = "";
            if (uidStore)
            {
                line = GetNextCmdTag() + " UID STORE " + sequence_set.ToSequenceSetString() + " FLAGS (" + IMAP_Utils.MessageFlagsToString(msgFlags) + ")";
            }
            else
            {
                line = GetNextCmdTag() + " STORE " + sequence_set.ToSequenceSetString() + " FLAGS (" + IMAP_Utils.MessageFlagsToString(msgFlags) + ")";
            }
            int countWritten = this.TcpStream.WriteLine(line);
            LogAddWrite(countWritten, line);

            // Read un-tagged response lines while we get final response line.
            while (true)
            {
                line = this.ReadLine();

                // We have un-tagged resposne.
                if (line.StartsWith("*"))
                {
                    ProcessStatusResponse(line);
                }
                else
                {
                    break;
                }
            }

            if (!RemoveCmdTag(line).ToUpper().StartsWith("OK"))
            {
                throw new IMAP_ClientException(line);
            }
        }
Beispiel #46
0
		/// <summary>
		/// Stores message to specified folder.
		/// </summary>
        /// <param name="accessingUser">User who accesses this method. 
        /// User needs r permission to call this method or Exception is thrown. 
        /// There is special user 'system' for which permission check is skipped.</param>
        /// <param name="folderOwnerUser">User who's folder it is.</param>
        /// <param name="folder">Folder where to store message. For example: Inbox,Public Folders/Documnets .</param>
		/// <param name="msgStream">Stream where message has stored. Stream position must be at the beginning of the message.</param>
		/// <param name="date">Recieve date.</param>
		/// <param name="flags">Message flags.</param>
		public void StoreMessage(string accessingUser,string folderOwnerUser,string folder,Stream msgStream,DateTime date,IMAP_MessageFlags flags)
		{
            /* Implementation notes:
                *) Validate values. Throw ArgumnetExcetion if invalid values.
                *) Ensure that user exists.
                *) Normalize folder. Remove '/' from folder start and end, ... .
                *) Do Shared Folders mapping.
                *) Ensure that folder exists. Throw Exception if don't.
                *) See if user has sufficient permissions. User requires 'p' or 'i' permission.
                    There is builtin user system, skip ACL for it.
                *) Store message.
            */

            //--- Validate values -------------------//
            ArgsValidator.ValidateUserName(folderOwnerUser);
            ArgsValidator.ValidateFolder(folder);
            ArgsValidator.ValidateNotNull(msgStream);
            //---------------------------------------//

            // Ensure that user exists.
            if(!UserExists(folderOwnerUser)){
                throw new Exception("User '" + folderOwnerUser + "' doesn't exist !");
            }

            // Normalize folder. Remove '/' from folder start and end.
            folder = API_Utlis.NormalizeFolder(folder);

            // Do Shared Folders mapping.
            string originalFolder = folder;
            SharedFolderMapInfo mappedFolder = MapSharedFolder(originalFolder);
            if(mappedFolder.IsSharedFolder){
                folderOwnerUser = mappedFolder.FolderOnwer;
                folder = mappedFolder.Folder;

                if(folderOwnerUser == "" || folder == ""){
                    throw new ArgumentException("Specified root folder '" + originalFolder + "' isn't accessible !");
                }
            }

            // Ensure that folder exists. Throw Exception if don't.
            if(!FolderExists(folderOwnerUser + "/" + folder)){
                throw new Exception("Folder '" + folder + "' doesn't exist !");
            }

            // See if user has sufficient permissions. User requires 'p' or 'i' permission.
            //  There is builtin user system, skip ACL for it.
            if(accessingUser.ToLower() != "system"){
                IMAP_ACL_Flags acl = GetUserACL(folderOwnerUser,folder,accessingUser);
                if((acl & IMAP_ACL_Flags.p) == 0 && (acl & IMAP_ACL_Flags.i) == 0){
                    throw new InsufficientPermissionsException("Insufficient permissions for folder '" + accessingUser + "/" + folder + "' !");
                }
            }

            //--- Store message
            MemoryStream msgMemStream = new MemoryStream();
            Net_Utils.StreamCopy(msgStream,msgMemStream,32000);
	        byte[] messageData = msgMemStream.ToArray();
            byte[] topLines = GetTopLines(new MemoryStream(messageData),50);
            Mail_Message message = null;
            try{
                msgStream.Position = 0;
                message = Mail_Message.ParseFromByte(messageData);
            }
            catch(Exception x){
                message = new Mail_Message();
                message.MimeVersion = "1.0";
                message.MessageID = MIME_Utils.CreateMessageID();
                message.Date = DateTime.Now;
                message.From = new Mail_t_MailboxList();
                message.From.Add(new Mail_t_Mailbox("system","system"));
                message.To = new Mail_t_AddressList();
                message.To.Add(new Mail_t_Mailbox("system","system"));
                message.Subject = "[BAD MESSAGE] Bad message, message parsing failed !";

                //--- multipart/mixed -------------------------------------------------------------------------------------------------
                MIME_h_ContentType contentType_multipartMixed = new MIME_h_ContentType(MIME_MediaTypes.Multipart.mixed);
                contentType_multipartMixed.Param_Boundary = Guid.NewGuid().ToString().Replace('-','.');
                MIME_b_MultipartMixed multipartMixed = new MIME_b_MultipartMixed(contentType_multipartMixed);
                message.Body = multipartMixed;

                    //--- text/plain ---------------------------------------------------------------------------------------------------
                    MIME_Entity entity_text_plain = new MIME_Entity();
                    MIME_b_Text text_plain = new MIME_b_Text(MIME_MediaTypes.Text.plain);
                    entity_text_plain.Body = text_plain;
                    text_plain.SetText(MIME_TransferEncodings.QuotedPrintable,Encoding.UTF8,"NOTE: Bad message, message parsing failed.\r\n\r\n");
                    multipartMixed.BodyParts.Add(entity_text_plain);
            }
            byte[] envelope = System.Text.Encoding.Default.GetBytes(IMAP_Envelope.ConstructEnvelope(message));
            byte[] body     = System.Text.Encoding.Default.GetBytes(IMAP_BODY.ConstructBodyStructure(message,false));

			using(WSqlCommand sqlCmd = new WSqlCommand(m_ConStr,"lspr_StoreMessage")){
				sqlCmd.AddParameter("_userName"     ,NpgsqlDbType.Varchar   ,folderOwnerUser);
				sqlCmd.AddParameter("_folder"       ,NpgsqlDbType.Varchar   ,folder);
				sqlCmd.AddParameter("_messageID"    ,NpgsqlDbType.Varchar   ,Guid.NewGuid().ToString());
				sqlCmd.AddParameter("_size"         ,NpgsqlDbType.Integer   ,messageData.Length);
				sqlCmd.AddParameter("_messageFlags" ,NpgsqlDbType.Integer   ,(int)flags);
				sqlCmd.AddParameter("_date"         ,NpgsqlDbType.Timestamp ,date);
				sqlCmd.AddParameter("_topLines"     ,NpgsqlDbType.Bytea     ,topLines);
				sqlCmd.AddParameter("_data"         ,NpgsqlDbType.Bytea     ,messageData);
                sqlCmd.AddParameter("_imapEnvelope" ,NpgsqlDbType.Bytea     ,envelope);
                sqlCmd.AddParameter("_imapBody"     ,NpgsqlDbType.Bytea     ,body);

				DataSet ds = sqlCmd.Execute();
			}
		}
        /// <summary>
        /// Stores message to specified folder.
        /// </summary>
        /// <param name="accessingUser">User who accesses this method. 
        /// User needs r permission to call this method or Exception is thrown. 
        /// There is special user 'system' for which permission check is skipped.</param>
        /// <param name="folderOwnerUser">User who's folder it is.</param>
        /// <param name="folder">Folder where to store message. For example: Inbox,Public Folders/Documnets .</param>
        /// <param name="msgStream">Stream where message has stored. Stream position must be at the beginning of the message.</param>
        /// <param name="date">Recieve date.</param>
        /// <param name="flags">Message flags.</param>
        public void StoreMessage(string accessingUser,string folderOwnerUser,string folder,Stream msgStream,DateTime date,IMAP_MessageFlags flags)
        {
            /* Implementation notes:
                *) Validate values. Throw ArgumnetExcetion if invalid values.
                *) Ensure that user exists.
                *) Normalize folder. Remove '/' from folder start and end, ... .
                *) Do Shared Folders mapping.
                *) Ensure that folder exists. Throw Exception if don't.
                *) See if user has sufficient permissions. User requires 'p' or 'i' permission.
                    There is builtin user system, skip ACL for it.
                *) Store message.
            */

            //--- Validate values -------------------//
            ArgsValidator.ValidateUserName(folderOwnerUser);
            ArgsValidator.ValidateFolder(folder);
            ArgsValidator.ValidateNotNull(msgStream);
            //---------------------------------------//

            // Ensure that user exists.
            if(!UserExists(folderOwnerUser)){
                throw new Exception("User '" + folderOwnerUser + "' doesn't exist !");
            }

            // Normalize folder. Remove '/' from folder start and end.
            folder = API_Utlis.NormalizeFolder(folder);

            // Do Shared Folders mapping.
            string originalFolder = folder;
            SharedFolderMapInfo mappedFolder = MapSharedFolder(originalFolder);
            if(mappedFolder.IsSharedFolder){
                folderOwnerUser = mappedFolder.FolderOnwer;
                folder = mappedFolder.Folder;

                if(folderOwnerUser == "" || folder == ""){
                    throw new ArgumentException("Specified root folder '" + originalFolder + "' isn't accessible !");
                }
            }

            // Ensure that folder exists. Throw Exception if don't.
            if(!FolderExists(folderOwnerUser + "/" + folder)){
                throw new Exception("Folder '" + folder + "' doesn't exist !");
            }

            // See if user has sufficient permissions. User requires 'p' or 'i' permission.
            //  There is builtin user system, skip ACL for it.
            if(accessingUser.ToLower() != "system"){
                IMAP_ACL_Flags acl = GetUserACL(folderOwnerUser,folder,accessingUser);
                if((acl & IMAP_ACL_Flags.p) == 0 && (acl & IMAP_ACL_Flags.i) == 0){
                    throw new InsufficientPermissionsException("Insufficient permissions for folder '" + accessingUser + "/" + folder + "' !");
                }
            }

            //--- Store message
            byte[] topLines = GetTopLines(msgStream,50);
            msgStream.Position = 0;
            byte[] messageData = new byte[msgStream.Length];
            msgStream.Read(messageData,0,messageData.Length);
            using(WSqlCommand sqlCmd = new WSqlCommand(m_ConStr,"lspr_StoreMessage")){
                sqlCmd.AddParameter("@MailBox"      ,SqlDbType.NVarChar ,folderOwnerUser);
                sqlCmd.AddParameter("@Folder"       ,SqlDbType.NVarChar ,folder);
                sqlCmd.AddParameter("@Data"         ,SqlDbType.Image    ,messageData);
                sqlCmd.AddParameter("@Size"         ,SqlDbType.BigInt   ,msgStream.Length);
                sqlCmd.AddParameter("@TopLines"     ,SqlDbType.Image    ,topLines);
                sqlCmd.AddParameter("@Date"         ,SqlDbType.DateTime ,date);
                sqlCmd.AddParameter("@MessageFlags" ,SqlDbType.Int      ,(int)flags);

                DataSet ds = sqlCmd.Execute();

                if(ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0){
                    throw new Exception(ds.Tables[0].Rows[0]["ErrorText"].ToString());
                }
            }
        }