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