Click here to Skip to main content
Click here to Skip to main content
Add your own
alternative version
Go to top

How to create a spam filter or automatic category sort algorithm with your mail application

, 29 Jul 2012
This article describe about automatic category filters in mail applications.
SpamFilterSample-noexe.zip
SpamFilterSample
HigLabo.Mail.SampleApplication
Properties
HigLabo.Mail
Async
Common
HigLabo.Mail.csproj.user
HigLabo.Mail.csproj.vspscc
Imap
Command
Pop3
Command
Properties
Smtp
Command
SendMail
HigLabo.Net
Core
Extensions
HigLabo.Net.csproj.user
HigLabo.Net.csproj.vspscc
HigLabo.Net.Silverlight.csproj.user
HigLabo.Net.Silverlight.csproj.vspscc
HigLabo.Net.WindowsPhone7.csproj.user
HigLabo.Net.WindowsPhone7.csproj.vspscc
Http
OAuth
Properties
Socket
Reference
Properties
Reference.csproj.user
SpamFilterSample
bin
Debug
SpamFilterSample.vshost.exe.manifest
Properties
SpamFilterSample.csproj.user
SpamFilterSample.zip
bin
Debug
Release
HigLabo.Mail.dll
HigLabo.Mail.SampleApplication.exe
HigLabo.Net.dll
Newtonsoft.Json.dll
obj
x86
Debug
TempPE
Release
bin
Debug
Release
HigLabo.Mail.dll
HigLabo.Net.dll
Newtonsoft.Json.dll
HigLabo.Mail.csproj.user
HigLabo.Mail.csproj.vspscc
obj
Debug
TempPE
Release
bin
Debug
de
es
fr
it
ja
ko
ru
zh-Hans
zh-Hant
Release
de
System.Xml.Linq.resources.dll
es
System.Xml.Linq.resources.dll
fr
System.Xml.Linq.resources.dll
HigLabo.Net.dll
HigLabo.Net.Silverlight.dll
HigLabo.Net.WindowsPhone7.dll
it
System.Xml.Linq.resources.dll
ja
System.Xml.Linq.resources.dll
ko
System.Xml.Linq.resources.dll
Newtonsoft.Json.dll
Newtonsoft.Json.Silverlight.dll
Newtonsoft.Json.WindowsPhone7.dll
ru
System.Xml.Linq.resources.dll
System.Xml.Linq.dll
zh-Hans
System.Xml.Linq.resources.dll
zh-Hant
System.Xml.Linq.resources.dll
HigLabo.Net.csproj.user
HigLabo.Net.csproj.vspscc
HigLabo.Net.Silverlight.csproj.user
HigLabo.Net.Silverlight.csproj.vspscc
HigLabo.Net.WindowsPhone7.csproj.user
HigLabo.Net.WindowsPhone7.csproj.vspscc
obj
Debug
TempPE
Release
BayesianFilter.dll
bin
Debug
Reference.dll
Release
HtmlAgilityPack.dll
obj
Debug
TempPE
Reference.csproj.user
BayesianFilter.dll
HigLabo.Mail.dll
HigLabo.Net.dll
HtmlAgilityPack.dll
Lucene.Net.dll
Newtonsoft.Json.dll
SpamData
SpamFilterSample.exe
SpamFilterSample.vshost.exe
SpamFilterSample.vshost.exe.manifest
Release
obj
x86
Debug
TempPE
SpamFilterSample.csproj.user
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.IO;
using System.Collections.Generic;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using G = System.Collections.Generic;
using HigLabo.Net.Mail;
using HigLabo.Net.Internal;
using HigLabo.Net.Pop3;

namespace HigLabo.Net.Imap
{
    /// Represent and probide functionality about IMAP command.
    /// <summary>
    /// Represent and probide functionality about IMAP command.
    /// </summary>
    public class ImapClient : SocketClient, IDisposable
    {
        /// <summary>
        /// 
        /// </summary>
        public static readonly Int32 DefaultTagNo = 1;
        /// <summary>
        /// 
        /// </summary>
        public class RegexList
        {
            /// <summary>
            /// 
            /// </summary>
            public static readonly Regex SelectFolderResultFlagsLine = new Regex(@"^\* FLAGS \((?<Flags>[^)]*)\)\r\n", RegexOptions.Singleline | RegexOptions.IgnoreCase);
            /// <summary>
            /// 
            /// </summary>
            public static readonly Regex SelectFolderResult = new Regex(@"^\* (?<exst>\d+) EXISTS\r\n\* (?<rcnt>\d+) RECENT\r\n", RegexOptions.Multiline | RegexOptions.IgnoreCase);
            /// <summary>
            /// 
            /// </summary>
            public static readonly Regex GetListFolderResult = new Regex("^\\* LIST \\(((?<opt>\\\\\\w+)\\s?)+\\) \".\" \"(?<name>.*?)\"", RegexOptions.Multiline | RegexOptions.IgnoreCase);
            /// <summary>
            /// 
            /// </summary>
            public static readonly Regex GetLsubFolderResult = new Regex("^\\* LSUB \\(((?<opt>\\\\\\w+)\\s?)+\\) \".\" \"(?<name>.*?)\"", RegexOptions.Multiline | RegexOptions.IgnoreCase);
            /// <summary>
            /// 
            /// </summary>
            public static readonly Regex GetRlsubFolderResult = new Regex("^\\* LSUB \\(\\) \".\" (?<name>.*)", RegexOptions.Multiline | RegexOptions.IgnoreCase);
        }
        /// <summary>
        /// 
        /// </summary>
        public static readonly Int32 DefaultPort = 143;
        private ImapConnectionState _State = ImapConnectionState.Disconnected;
        /// <summary>
        /// Get connection state.
        /// </summary>
        public ImapConnectionState State
        {
            get
            {
                if (this.Socket == null ||
                    this.Socket.Connected == false)
                {
                    this._State = ImapConnectionState.Disconnected;
                }
                return this._State;
            }
        }
        /// <summary>
        /// Get selected folder
        /// </summary>
        public ImapFolder CurrentFolder { get; private set; }
        /// <summary>
        /// Get connection is ready.
        /// </summary>
        public Boolean Available
        {
            get { return this._State != ImapConnectionState.Disconnected; }
        }
        /// <summary>
        /// 
        /// </summary>
        public Int32 TagNo { get; set; }
        private String Tag
        {
            get { return "tag" + this.TagNo; }
        }
        /// <summary>
        /// 
        /// </summary>
        public ImapClient(String serverName)
            : base(serverName, DefaultPort)
        {
            this.TagNo = ImapClient.DefaultTagNo;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="serverName"></param>
        /// <param name="port"></param>
        /// <param name="userName"></param>
        /// <param name="password"></param>
        public ImapClient(String serverName, Int32 port, String userName, String password)
            : base(serverName, port)
        {
            this.UserName = userName;
            this.Password = password;
            this.TagNo = ImapClient.DefaultTagNo;
        }
        /// <summary>
        /// Open connection to a server.
        /// </summary>
        public ImapConnectionState Open()
        {
            if (this.Connect() == true)
            {
                this._State = ImapConnectionState.Connected;
            }
            else
            {
                this._State = ImapConnectionState.Disconnected;
            }
            return this._State;
        }
        /// サーバーへの接続が開かれていない場合、サーバーへの接続を開きます。
        /// <summary>
        /// Ensure connection is opened.
        /// サーバーへの接続が開かれていない場合、サーバーへの接続を開きます。
        /// </summary>
        public ImapConnectionState EnsureOpen()
        {
            if ((this.Socket != null) &&
                this.Socket.Connected)
            { return this._State; }

            return this.Open();
        }
        private void ValidateState(ImapConnectionState state)
        {
            this.ValidateState(state, false);
        }
        private void ValidateState(ImapConnectionState state, Boolean folderSelected)
        {
            if (this._State != state)
            {
                switch (state)
                {
                    case ImapConnectionState.Disconnected: throw new MailClientException("You can execute this command only when State is Disconnected");
                    case ImapConnectionState.Connected: throw new MailClientException("You can execute this command only when State is Connected");
                    case ImapConnectionState.Authenticated: throw new MailClientException("You can execute this command only when State is Authenticated");
                    default: throw new MailClientException();
                }
            }
            if (folderSelected == true && this.CurrentFolder == null)
            {
                throw new MailClientException("You must select folder before executing this command."
                  + "You can select folder by calling SelectFolder,ExecuteSelect,ExecuteExamine method of this object.");
            }
        }
        private String GetResponse()
        {
            MemoryStream ms = new MemoryStream();
            this.GetResponse(ms);
            return this.ResponseEncoding.GetString(ms.ToArray());
        }
        private void GetResponse(Stream stream)
        {
            Byte[] bb = this.GetResponseBytes(new ImapDataReceiveContext(this.Tag, this.ResponseEncoding));
            this.ReadText(stream, bb);
            this.Commnicating = false;
        }
        private void ReadText(Stream stream, Byte[] bytes)
        {
            String CurrentLine = "";
            Byte[] bb = null;
            StringReader sr = new StringReader(this.ResponseEncoding.GetString(bytes));

            while (true)
            {
                CurrentLine = sr.ReadLine();
                if (CurrentLine == null) { break; }
                bb = ResponseEncoding.GetBytes(CurrentLine + MailParser.NewLine);
                stream.Write(bb, 0, bb.Length);
            }
        }
        /// <summary>
        /// Log in to IMAP server.
        /// </summary>
        /// <returns></returns>
        public Boolean Authenticate()
        {
            if (this._State == ImapConnectionState.Authenticated) { return true; }
            var rs = this.ExecuteLogin();
            return this.State == ImapConnectionState.Authenticated;
        }
        private String Execute(String command)
        {
            this.Send(command);
            this.Commnicating = true;
            return this.GetResponse();
        }
        /// <summary>
        /// Send capability command to IMAP server.
        /// </summary>
        /// <returns></returns>
        public CapabilityResult ExecuteCapability()
        {
            String s = this.Execute(this.Tag + " CAPABILITY");
            return new CapabilityResult(this.Tag, s);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public ImapCommandResult ExecuteLogin()
        {
            if (this.EnsureOpen() == ImapConnectionState.Disconnected) { throw new MailClientException(); }

            String commandText = String.Format(this.Tag + " LOGIN {0} {1}", this.UserName, this.Password);
            String s = this.Execute(commandText);
            ImapCommandResult rs = new ImapCommandResult(this.Tag, s);
            if (rs.Status == ImapCommandResultStatus.Ok)
            {
                this._State = ImapConnectionState.Authenticated;
            }
            else
            {
                this._State = ImapConnectionState.Connected;
            }
            return rs;
        }
        /// <summary>
        /// Send Logout command to IMAP server.
        /// </summary>
        /// <returns></returns>
        public ImapCommandResult ExecuteLogout()
        {
            this.ValidateState(ImapConnectionState.Authenticated);
            String s = this.Execute(this.Tag + " Logout");
            var rs = new ImapCommandResult(this.Tag, s);
            if (rs.Status == ImapCommandResultStatus.Ok)
            {
                this._State = ImapConnectionState.Connected;
            }
            return rs;
        }
        /// <summary>
        /// Send select command to IMAP server.
        /// </summary>
        /// <returns></returns>
        public SelectResult ExecuteSelect(String folderName)
        {
            this.ValidateState(ImapConnectionState.Authenticated);
            String commandText = String.Format(this.Tag + " Select {0}", NamingConversion.EncodeString(folderName));
            String s = this.Execute(commandText);
            var rs = this.GetSelectResult(folderName, s);
            this.CurrentFolder = new ImapFolder(rs);
            return rs;
        }
        /// <summary>
        /// Send examine command to IMAP server.
        /// </summary>
        /// <returns></returns>
        public SelectResult ExecuteExamine(String folderName)
        {
            this.ValidateState(ImapConnectionState.Authenticated);
            String commandText = String.Format(this.Tag + " Examine {0}", NamingConversion.EncodeString(folderName));
            String s = this.Execute(commandText);
            var rs = this.GetSelectResult(folderName, s);
            this.CurrentFolder = new ImapFolder(rs);
            return rs;
        }
        private SelectResult GetSelectResult(String folderName, String text)
        {
            var rs = new ImapCommandResult(this.Tag, text);
            if (rs.Status == ImapCommandResultStatus.Ok)
            {
                Int32 exists = 0;
                Int32 recent = 0;
                List<String> l = new List<string>();
                Match m = null;
                m = RegexList.SelectFolderResult.Match(rs.Text);
                if (m.Success)
                {
                    Int32.TryParse(m.Groups["exst"].Value, out exists);
                    Int32.TryParse(m.Groups["rcnt"].Value, out recent);
                }
                m = RegexList.SelectFolderResultFlagsLine.Match(rs.Text);
                if (m.Success == true)
                {
                    String flags = m.Groups["Flags"].Value;
                    foreach (var el in flags.Split(' '))
                    {
                        if (el.StartsWith("\\") == true)
                        {
                            l.Add(el.Substring(1, el.Length - 1));
                        }
                    }
                }
                return new SelectResult(folderName, exists, recent, l.ToArray());
            }
            throw new MailClientException();
        }
        /// <summary>
        /// Send create folder command to IMAP server.
        /// </summary>
        /// <returns></returns>
        public ImapCommandResult ExecuteCreate(String folderName)
        {
            this.ValidateState(ImapConnectionState.Authenticated);
            String commandText = String.Format(this.Tag + " Create {0}", NamingConversion.EncodeString(folderName));
            String s = this.Execute(commandText);
            return new ImapCommandResult(this.Tag, s);
        }
        /// <summary>
        /// Send delete folder command to IMAP server.
        /// </summary>
        /// <returns></returns>
        public ImapCommandResult ExecuteDelete(String folderName)
        {
            this.ValidateState(ImapConnectionState.Authenticated);
            String commandText = String.Format(this.Tag + " Delete {0}", NamingConversion.EncodeString(folderName));
            String s = this.Execute(commandText);
            return new ImapCommandResult(this.Tag, s);
        }
        /// <summary>
        /// Send close command to IMAP server.
        /// </summary>
        /// <returns></returns>
        public ImapCommandResult ExecuteClose()
        {
            this.ValidateState(ImapConnectionState.Authenticated);
            String s = this.Execute(this.Tag + " Close");
            this.CurrentFolder = null;
            return new ImapCommandResult(this.Tag, s);
        }
        /// <summary>
        /// Send list command to IMAP server.
        /// </summary>
        /// <param name="folderName"></param>
        /// <param name="recursive"></param>
        /// <returns></returns>
        public ListResult ExecuteList(String folderName, Boolean recursive)
        {
            this.ValidateState(ImapConnectionState.Authenticated);

            List<ListLineResult> l = new List<ListLineResult>();
            String name = "";
            Boolean noSelect = false;
            Boolean hasChildren = false;
            String rc = "%";
            if (recursive == true)
            {
                rc = "*";
            }
            String s = this.Execute(String.Format(this.Tag + " LIST \"{0}\" \"{1}\"", folderName, rc));
            foreach (Match m in RegexList.GetListFolderResult.Matches(s))
            {
                name = NamingConversion.DecodeString(m.Groups["name"].Value);
                foreach (Capture c in m.Groups["opt"].Captures)
                {
                    if (c.Value.ToString() == "\\Noselect")
                    {
                        noSelect = true;
                    }
                    else if (c.Value.ToString() == "\\HasNoChildren")
                    {
                        hasChildren = false;
                    }
                    else if (c.Value.ToString() == "\\HasChildren")
                    {
                        hasChildren = true;
                    }
                }
                l.Add(new ListLineResult(name, noSelect, hasChildren));
            }
            return new ListResult(l);
        }
        /// <summary>
        /// Send subscribe command to IMAP server.
        /// </summary>
        /// <returns></returns>
        public ImapCommandResult ExecuteSubscribe(String folderName)
        {
            this.ValidateState(ImapConnectionState.Authenticated);
            String s = this.Execute(this.Tag + " subscribe " + folderName);
            return new ImapCommandResult(this.Tag, s);
        }
        /// <summary>
        /// Send unsubscribe command to IMAP server.
        /// </summary>
        /// <returns></returns>
        public ImapCommandResult ExecuteUnsubscribe(String folderName)
        {
            this.ValidateState(ImapConnectionState.Authenticated);
            String s = this.Execute(this.Tag + " Unsubscribe " + folderName);
            return new ImapCommandResult(this.Tag, s);
        }
        /// <summary>
        /// Send list command to IMAP server.
        /// </summary>
        /// <param name="folderName"></param>
        /// <param name="recursive"></param>
        /// <returns></returns>
        public ListResult ExecuteLsub(String folderName, Boolean recursive)
        {
            this.ValidateState(ImapConnectionState.Authenticated);

            List<ListLineResult> l = new List<ListLineResult>();
            String name = "";
            Boolean noSelect = false;
            Boolean hasChildren = false;
            String rc = "%";
            if (recursive == true)
            {
                rc = "*";
            }
            String s = this.Execute(String.Format(this.Tag + " Lsub \"{0}\" \"{1}\"", folderName, rc));
            foreach (Match m in RegexList.GetLsubFolderResult.Matches(s))
            {
                name = NamingConversion.DecodeString(m.Groups["name"].Value);
                foreach (Capture c in m.Groups["opt"].Captures)
                {
                    if (c.Value.ToString() == "\\Noselect")
                    {
                        noSelect = true;
                    }
                    else if (c.Value.ToString() == "\\HasNoChildren")
                    {
                        hasChildren = false;
                    }
                    else if (c.Value.ToString() == "\\HasChildren")
                    {
                        hasChildren = true;
                    }
                }
                l.Add(new ListLineResult(name, noSelect, hasChildren));
            }
            return new ListResult(l);
        }
        /// <summary>
        /// Send Fetch command to IMAP server.
        /// </summary>
        /// <param name="mailIndex"></param>
        /// <returns></returns>
        public MailMessage ExecuteFetch(Int64 mailIndex)
        {
            this.ValidateState(ImapConnectionState.Authenticated, true);
            String s = this.Execute(String.Format(this.Tag + " FETCH {0} (BODY[])", mailIndex));
            Regex messageRegex = new Regex(@"^\* \d+ FETCH \([^\r\n]*BODY\[\] \{\d+\}\r\n(?<msg>.*?)\)\r\n" + this.Tag + " OK"
                , RegexOptions.Multiline | RegexOptions.Singleline);
            Match m = messageRegex.Match(s);
            if (m.Success)
            {
                s = m.Groups["msg"].Value;
                return new MailMessage(s, mailIndex);
            }
            throw new MailClientException();
        }
        /// <summary>
        /// Send search command to IMAP server.
        /// </summary>
        /// <returns></returns>
        public SearchResult ExecuteSearch(String searchText)
        {
            this.ValidateState(ImapConnectionState.Authenticated, true);
            String s = this.Execute(this.Tag + " SEARCH " + searchText);
            return new SearchResult(this.Tag, s);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="mailIndex"></param>
        /// <param name="command"></param>
        /// <param name="flags"></param>
        /// <returns></returns>
        public ImapCommandResult ExecuteStore(Int64 mailIndex, StoreItem command, String flags)
        {
            this.ValidateState(ImapConnectionState.Authenticated, true);
            StringBuilder sb = new StringBuilder(256);
            sb.Append(this.Tag);
            sb.Append(" STORE ");
            sb.Append(mailIndex);
            sb.Append(" ");
            if (command == StoreItem.FlagsReplace)
            {
                sb.Append("FLAGS ");
            }
            else if (command == StoreItem.FlagsReplaceSilent)
            {
                sb.Append("FLAGS.SILENT ");
            }
            else if (command == StoreItem.FlagsAdd)
            {
                sb.Append("+FLAGS ");
            }
            else if (command == StoreItem.FlagsAddSilent)
            {
                sb.Append("+FLAGS.SILENT ");
            }
            else if (command == StoreItem.FlagsRemove)
            {
                sb.Append("-FLAGS ");
            }
            else if (command == StoreItem.FlagsRemoveSilent)
            {
                sb.Append("-FLAGS.SILENT ");
            }
            else
            {
                throw new ArgumentException("command");
            }
            if (String.IsNullOrEmpty(flags))
            {
                throw new ArgumentException("flags");
            }
            sb.Append("(");
            sb.Append(flags);
            sb.Append(")");

            var s = this.Execute(sb.ToString());
            return new ImapCommandResult(this.Tag, s);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="folderName"></param>
        /// <param name="mailData"></param>
        /// <returns></returns>
        public ImapCommandResult ExecuteAppend(String folderName, String mailData)
        {
            return this.ExecuteAppend(folderName, mailData, "", DateTimeOffset.Now);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="folderName"></param>
        /// <param name="mailData"></param>
        /// <param name="flag"></param>
        /// <param name="datetime"></param>
        /// <returns></returns>
        public ImapCommandResult ExecuteAppend(String folderName, String mailData, String flag, DateTimeOffset datetime)
        {
            String commandText = String.Format(this.Tag + " APPEND \"{0}\" ({1}) \"{2}\" "
                , NamingConversion.EncodeString(folderName), flag, MailParser.DateTimeOffsetString(datetime));
            commandText += "{" + mailData.Length + "}";
            String s = this.Execute(commandText);
            var rs = new ImapCommandResult(this.Tag, s);
            if (rs.Status == ImapCommandResultStatus.Ok ||
                rs.Status == ImapCommandResultStatus.None)
            {
                var ss = this.Execute(mailData);
                return new ImapCommandResult(this.Tag, ss);
            }
            return rs;
        }
        /// <summary>
        /// Send rename folder command to IMAP server.
        /// </summary>
        /// <returns></returns>
        public ImapCommandResult ExecuteRename(String oldFolderName, String folderName)
        {
            this.ValidateState(ImapConnectionState.Authenticated);
            String commandText = String.Format(this.Tag + " Rename {0} {1}", NamingConversion.EncodeString(oldFolderName), NamingConversion.EncodeString(folderName));
            String s = this.Execute(commandText);
            var rs = new ImapCommandResult(this.Tag, s);
            if (rs.Status == ImapCommandResultStatus.Ok ||
                rs.Status == ImapCommandResultStatus.None)
            {
                return rs;
            }
            return rs;
        }
        /// <summary>
        /// Send rlsub command to IMAP server.
        /// </summary>
        /// <param name="folderName"></param>
        /// <param name="recursive"></param>
        /// <returns></returns>
        public ListResult ExecuteRlsub(String folderName, Boolean recursive)
        {
            this.ValidateState(ImapConnectionState.Authenticated);

            List<ListLineResult> l = new List<ListLineResult>();
            String name = "";
            Boolean noSelect = false;
            Boolean hasChildren = false;
            String rc = "%";
            if (recursive == true)
            {
                rc = "*";
            }
            String s = this.Execute(String.Format(this.Tag + " RLSUB \"{0}\" \"{1}\"", folderName, rc));
            foreach (Match m in RegexList.GetRlsubFolderResult.Matches(s))
            {
                name = NamingConversion.DecodeString(m.Groups["name"].Value);
                foreach (Capture c in m.Groups["opt"].Captures)
                {
                    if (c.Value.ToString() == "\\Noselect")
                    {
                        noSelect = true;
                    }
                    else if (c.Value.ToString() == "\\HasNoChildren")
                    {
                        hasChildren = false;
                    }
                    else if (c.Value.ToString() == "\\HasChildren")
                    {
                        hasChildren = true;
                    }
                }
                l.Add(new ListLineResult(name, noSelect, hasChildren));
            }
            return new ListResult(l);

        }
        /// <summary>
        /// Send status command to IMAP server.
        /// </summary>
        /// <param name="folderName"></param>
        /// <param name="message"></param>
        /// <param name="recent"></param>
        /// <param name="uidnext"></param>
        /// <param name="uidvalidity"></param>
        /// <param name="unseen"></param>
        /// <returns></returns>
        public ImapCommandResult ExecuteStatus(String folderName, Boolean message, Boolean recent, Boolean uidnext, Boolean uidvalidity, Boolean unseen)
        {
            String s = null;
            this.ValidateState(ImapConnectionState.Authenticated);
            StringBuilder sb = new StringBuilder(256);
            sb.Append(this.Tag);
            sb.Append(" Status");
            sb.Append(" ");
            sb.Append(folderName);
            if (message || recent || uidnext || uidvalidity || unseen)
            {
                sb.Append(" ");
                sb.Append("(");
                if (message)
                {
                    sb.Append("messages");
                }

                if (recent)
                {
                    sb.Append(" recent");
                }

                if (uidnext)
                {
                    sb.Append(" uidnext");
                }

                if (uidvalidity)
                {
                    sb.Append(" uidvalidity");
                }

                if (unseen)
                {
                    sb.Append(" unseen");
                }

                sb.Append(")");
            }

            s = this.Execute(sb.ToString());
            var rs = new ImapCommandResult(this.Tag, s);
            if (rs.Status == ImapCommandResultStatus.Ok ||
                rs.Status == ImapCommandResultStatus.None)
            {
                return rs;
            }
            return rs;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public ImapCommandResult ExecuteCheck()
        {
            this.ValidateState(ImapConnectionState.Authenticated, true);
            String s = this.Execute(this.Tag + " Check");
            return new ImapCommandResult(this.Tag, s);
        }
        /// <summary>
        /// Send copy command to IMAP server.
        /// </summary>
        /// <param name="mailindexstart"></param>
        /// <param name="mailindexend"></param>
        /// <param name="folderName"></param>
        /// <returns></returns>
        public ImapCommandResult ExecuteCopy(Int32 mailindexstart, Int32 mailindexend, String folderName)
        {
            String s = null;
            this.ValidateState(ImapConnectionState.Authenticated);
            StringBuilder sb = new StringBuilder(256);
            sb.Append(this.Tag);
            sb.Append(" Copy ");
            if (!Int32.Equals(mailindexstart, 0))
            {
                sb.Append(mailindexstart);
            }
            if (!Int32.Equals(mailindexend, 0) && !Int32.Equals(mailindexstart, 0))
            {
                sb.Append(":");
                sb.Append(mailindexend);
            }
            else if (!Int32.Equals(mailindexend, 0))
            {
                sb.Append(mailindexend);
            }
            sb.Append(" ");
            sb.Append(folderName);

            s = this.Execute(sb.ToString());
            var rs = new ImapCommandResult(this.Tag, s);
            if (rs.Status == ImapCommandResultStatus.Ok ||
                rs.Status == ImapCommandResultStatus.None)
            {
                return rs;
            }
            return rs;

        }
        /// <summary>
        /// Send UID command to IMAP server.
        /// <param name="command"></param>
        /// </summary>
        /// <returns></returns>
        public ImapCommandResult ExecuteUid(String command)
        {
            this.ValidateState(ImapConnectionState.Authenticated);
            String s = this.Execute(this.Tag + " UID " + command);
            return new ImapCommandResult(this.Tag, s);
        }
        /// <summary>
        /// Send NAMESPACE command to IMAP server.
        /// </summary>
        /// <returns></returns>
        public ImapCommandResult ExecuteNamespace()
        {
            this.ValidateState(ImapConnectionState.Authenticated);
            String s = this.Execute(this.Tag + " NAMESPACE");
            return new ImapCommandResult(this.Tag, s);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public ImapIdleCommand CreateImapIdleCommand()
        {
            return new ImapIdleCommand(this.Tag, this.ResponseEncoding);
        }
        /// <summary>
        /// Send IDLE command to IMAP server.
        /// You can receive message from server by register event handler to MessageReceived event of ImapIdleCommand object
        /// </summary>
        /// <returns></returns>
        public void ExecuteIdle(ImapIdleCommand command)
        {
            this.ValidateState(ImapConnectionState.Authenticated);
            this.Send(this.Tag + " IDLE");
            var bb = command.GetByteArray();
            command.IAsyncResult = this.Stream.BeginRead(bb, 0, bb.Length, this.ExecuteIdleCallback, command);
            this._State = ImapConnectionState.Idle;
        }
        private void ExecuteIdleCallback(IAsyncResult result)
        {
            DataReceiveContext cx = null;

            try
            {
                cx = (DataReceiveContext)result.AsyncState;
                if (this.Socket == null)
                {
                    throw new SocketClientException("Connection is closed");
                }
                Int32 size = Stream.EndRead(result);
                if (cx.ReadBuffer(size) == true)
                {
                    var bb = cx.GetByteArray();
                    this.Stream.BeginRead(bb, 0, bb.Length, this.GetResponseCallback, cx);
                }
                else
                {
                    cx.Dispose();
                }
            }
            catch (Exception ex)
            {
                cx.Exception = ex;
                this.OnError(ex);
            }
            finally
            {
                if (cx.Exception != null)
                {
                    cx.Dispose();
                }
            }
        }
        /// <summary>
        /// Send done command to IMAP server.
        /// </summary>
        /// <returns></returns>
        public ImapCommandResult ExecuteDone(ImapIdleCommand command)
        {
            this.ValidateState(ImapConnectionState.Idle);
            if (command.IAsyncResult != null)
            {
                var x = this.Stream.EndRead(command.IAsyncResult);
            }
            String s = this.Execute("DONE");

            this._State = ImapConnectionState.Authenticated;

            return new ImapCommandResult(this.Tag, s);
        }
        /// <summary>
        /// Send GetQuota command to IMAP server.
        /// <param name="resourceName"></param>
        /// </summary>
        /// <returns></returns>
        public ImapCommandResult ExecuteGetQuota(String resourceName)
        {
            String s = this.Execute(this.Tag + " GetQuota " + resourceName);
            return new ImapCommandResult(this.Tag, s);
        }
        /// <summary>
        /// Send SETQUOTA command to IMAP server.
        /// <param name="resourceName"></param>
        /// </summary>
        /// <returns></returns>
        public ImapCommandResult ExecuteSetQuota(String resourceName)
        {
            String s = this.Execute(this.Tag + " SETQUOTA " + resourceName);
            return new ImapCommandResult(this.Tag, s);
        }
        /// <summary>
        /// Send GETQUOTAROOT command to IMAP server.
        /// <param name="folderName"></param>
        /// </summary>
        /// <returns></returns>
        public ImapCommandResult ExecuteGetQuotaRoot(String folderName)
        {
            String s = this.Execute(this.Tag + " GETQUOTAROOT " + folderName);
            String commandText = String.Format(this.Tag + " GETQUOTAROOT {0}", NamingConversion.EncodeString(folderName));
            return new ImapCommandResult(this.Tag, s);
        }
        /// <summary>
        /// Send noop command to IMAP server.
        /// </summary>
        /// <returns></returns>
        public ImapCommandResult ExecuteNoop()
        {
            this.ValidateState(ImapConnectionState.Authenticated);
            String s = this.Execute(this.Tag + " NOOP");
            return new ImapCommandResult(this.Tag, s);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public ImapCommandResult ExecuteExpunge()
        {
            this.ValidateState(ImapConnectionState.Authenticated);
            String s = this.Execute(this.Tag + " EXPUNGE");
            return new ImapCommandResult(this.Tag, s);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="folderName"></param>
        public ImapFolder SelectFolder(String folderName)
        {
            var rs = this.ExecuteSelect(folderName);
            return new ImapFolder(rs);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="folderName"></param>
        public void UnselectFolder(String folderName)
        {
            this.ExecuteClose();
        }
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public List<ImapFolder> GetAllFolders()
        {
            return this.GetFolders("", true);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="folderName"></param>
        /// <param name="recursive"></param>
        /// <returns></returns>
        public List<ImapFolder> GetFolders(String folderName, Boolean recursive)
        {
            ValidateState(ImapConnectionState.Authenticated);
            List<ImapFolder> l = new List<ImapFolder>();
            var rs = this.ExecuteList(folderName, recursive);
            foreach (var el in rs.Lines)
            {
                l.Add(new ImapFolder(el));
            }
            return l;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="mailIndex"></param>
        /// <returns></returns>
        public MailMessage GetMessage(Int64 mailIndex)
        {
            return this.ExecuteFetch(mailIndex);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="mailIndex"></param>
        /// <returns></returns>
        public Boolean DeleteEMail(params Int64[] mailIndex)
        {
            this.ValidateState(ImapConnectionState.Authenticated, true);
            return this.DeleteEMail(this.CurrentFolder.Name, mailIndex);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="folderName"></param>
        /// <param name="mailIndex"></param>
        /// <returns></returns>
        public Boolean DeleteEMail(String folderName, params Int64[] mailIndex)
        {
            if (this.EnsureOpen() == ImapConnectionState.Disconnected) { return false; }
            if (this.Authenticate() == false) { return false; }

            for (int i = 0; i < mailIndex.Length; i++)
            {
                var rs = this.ExecuteStore(mailIndex[i], StoreItem.FlagsAdd, @"\Deleted");
                if (rs.Status != ImapCommandResultStatus.Ok) { return false; }
            }
            this.ExecuteExpunge();
            this.ExecuteLogout();
            return true;
        }
        /// <summary>
        /// disconnect connection to IMAP server.
        /// </summary>
        public void Close()
        {
            this.Socket.Close();
            this.Socket = null;
            this._State = ImapConnectionState.Disconnected;
        }
        /// <summary>
        /// 
        /// </summary>
        ~ImapClient()
        {
            this.Dispose(false);
        }
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The MIT License

Share

About the Author

Higty
Web Developer
Japan Japan
I'm Working at Software Company in Tokyo.

| Advertise | Privacy | Mobile
Web04 | 2.8.140922.1 | Last Updated 30 Jul 2012
Article Copyright 2012 by Higty
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid