Пример #1
0
        /// <summary>
        /// Parses an untagged ID response.
        /// </summary>
        /// <param name="engine">The IMAP engine.</param>
        /// <param name="ic">The IMAP command.</param>
        /// <param name="index">The index.</param>
        public static void ParseImplementation(ImapEngine engine, ImapCommand ic, int index)
        {
            var token          = engine.ReadToken(ic.CancellationToken);
            var implementation = new ImapImplementation();

            ic.UserData = implementation;

            if (token.Type == ImapTokenType.Nil)
            {
                return;
            }

            if (token.Type != ImapTokenType.OpenParen)
            {
                throw ImapEngine.UnexpectedToken(token, false);
            }

            token = engine.PeekToken(ic.CancellationToken);

            while (token.Type != ImapTokenType.CloseParen)
            {
                var property = ImapUtils.ReadStringToken(engine, ic.CancellationToken);
                var value    = ImapUtils.ReadNStringToken(engine, false, ic.CancellationToken);

                implementation.Properties[property] = value;

                token = engine.PeekToken(ic.CancellationToken);
            }

            // read the ')' token
            engine.ReadToken(ic.CancellationToken);
        }
        public void TestParseDovcotEnvelopeWithGroupAddresses()
        {
            const string text = "(\"Mon, 13 Jul 2015 21:15:32 -0400\" \"Test message\" ((\"Example From\" NIL \"from\" \"example.com\")) ((\"Example Sender\" NIL \"sender\" \"example.com\")) ((\"Example Reply-To\" NIL \"reply-to\" \"example.com\")) ((NIL NIL \"boys\" NIL)(NIL NIL \"aaron\" \"MISSING_DOMAIN\")(NIL NIL \"jeff\" \"MISSING_DOMAIN\")(NIL NIL \"zach\" \"MISSING_DOMAIN\")(NIL NIL NIL NIL)(NIL NIL \"girls\" NIL)(NIL NIL \"alice\" \"MISSING_DOMAIN\")(NIL NIL \"hailey\" \"MISSING_DOMAIN\")(NIL NIL \"jenny\" \"MISSING_DOMAIN\")(NIL NIL NIL NIL)) NIL NIL NIL \"<*****@*****.**>\")";

            using (var memory = new MemoryStream(Encoding.ASCII.GetBytes(text), false)) {
                using (var tokenizer = new ImapStream(memory, null, new NullProtocolLogger())) {
                    using (var engine = new ImapEngine(null)) {
                        Envelope envelope;

                        engine.SetStream(tokenizer);

                        try {
                            envelope = ImapUtils.ParseEnvelopeAsync(engine, false, CancellationToken.None).GetAwaiter().GetResult();
                        } catch (Exception ex) {
                            Assert.Fail("Parsing ENVELOPE failed: {0}", ex);
                            return;
                        }

                        Assert.AreEqual("\"Example Sender\" <*****@*****.**>", envelope.Sender.ToString());
                        Assert.AreEqual("\"Example From\" <*****@*****.**>", envelope.From.ToString());
                        Assert.AreEqual("\"Example Reply-To\" <*****@*****.**>", envelope.ReplyTo.ToString());
                        Assert.AreEqual("boys: aaron, jeff, zach;, girls: alice, hailey, jenny;", envelope.To.ToString());
                    }
                }
            }
        }
Пример #3
0
        static MessageThread ParseThread(ImapEngine engine, CancellationToken cancellationToken)
        {
            var token = engine.ReadToken (cancellationToken);
            MessageThread thread, node, child;
            uint uid;

            if (token.Type != ImapTokenType.Atom || !uint.TryParse ((string) token.Value, out uid))
                throw ImapEngine.UnexpectedToken (token, false);

            node = thread = new MessageThread (new UniqueId (uid));

            do {
                token = engine.ReadToken (cancellationToken);

                if (token.Type == ImapTokenType.CloseParen)
                    break;

                if (token.Type == ImapTokenType.OpenParen) {
                    child = ParseThread (engine, cancellationToken);
                    node.Add (child);
                } else {
                    if (token.Type != ImapTokenType.Atom || !uint.TryParse ((string) token.Value, out uid))
                        throw ImapEngine.UnexpectedToken (token, false);

                    child = new MessageThread (new UniqueId (uid));
                    node.Add (child);
                    node = child;
                }
            } while (true);

            return thread;
        }
Пример #4
0
        static ContentType ParseContentType(ImapEngine engine, CancellationToken cancellationToken)
        {
            var         type    = ReadStringToken(engine, cancellationToken);
            var         subtype = ReadStringToken(engine, cancellationToken);
            var         token   = engine.ReadToken(cancellationToken);
            ContentType contentType;

            if (token.Type == ImapTokenType.Nil)
            {
                return(new ContentType(type, subtype));
            }

            if (token.Type != ImapTokenType.OpenParen)
            {
                throw ImapEngine.UnexpectedToken(token, false);
            }

            var builder = new StringBuilder();

            builder.AppendFormat("{0}/{1}", type, subtype);

            ParseParameterList(builder, engine, cancellationToken);

            if (!ContentType.TryParse(builder.ToString(), out contentType))
            {
                contentType = new ContentType(type, subtype);
            }

            return(contentType);
        }
Пример #5
0
        internal static ImapStringType GetStringType(ImapEngine engine, string value, bool allowAtom)
        {
            var type = allowAtom ? ImapStringType.Atom : ImapStringType.QString;

            if (value == null)
            {
                return(ImapStringType.Nil);
            }

            if (value.Length == 0)
            {
                return(ImapStringType.QString);
            }

            for (int i = 0; i < value.Length; i++)
            {
                if (!IsAtom(value[i]))
                {
                    if (!IsQuotedSafe(engine, value[i]))
                    {
                        return(ImapStringType.Literal);
                    }

                    type = ImapStringType.QString;
                }
            }

            return(type);
        }
Пример #6
0
        /// <summary>
        /// Parses the X-GM-LABELS list.
        /// </summary>
        /// <returns>The message labels.</returns>
        /// <param name="engine">The IMAP engine.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        public static ReadOnlyCollection <string> ParseLabelsList(ImapEngine engine, CancellationToken cancellationToken)
        {
            var token  = engine.ReadToken(cancellationToken);
            var labels = new List <string> ();

            if (token.Type != ImapTokenType.OpenParen)
            {
                throw ImapEngine.UnexpectedToken(token, false);
            }

            // Note: GMail's IMAP implementation is broken and does not quote strings with ']' like it should.
            token = engine.ReadToken(ImapStream.GMailLabelSpecials, cancellationToken);

            while (token.Type == ImapTokenType.Flag || token.Type == ImapTokenType.Atom || token.Type == ImapTokenType.QString)
            {
                var label = engine.DecodeMailboxName((string)token.Value);

                labels.Add(label);

                token = engine.ReadToken(cancellationToken);
            }

            if (token.Type != ImapTokenType.CloseParen)
            {
                throw ImapEngine.UnexpectedToken(token, false);
            }

            return(new ReadOnlyCollection <string> (labels));
        }
Пример #7
0
        static string ReadNStringToken(ImapEngine engine, bool rfc2047, CancellationToken cancellationToken)
        {
            var    token = engine.ReadToken(cancellationToken);
            string value;

            switch (token.Type)
            {
            case ImapTokenType.Literal:
                value = engine.ReadLiteral(cancellationToken);
                break;

            case ImapTokenType.QString:
            case ImapTokenType.Atom:
                value = (string)token.Value;
                break;

            case ImapTokenType.Nil:
                return(null);

            default:
                throw ImapEngine.UnexpectedToken(token, false);
            }

            return(rfc2047 ? Rfc2047.DecodeText(Latin1.GetBytes(value)) : value);
        }
Пример #8
0
        public void TestParseResponseCodeBadCharset()
        {
            const string text = "BADCHARSET (US-ASCII \"iso-8859-1\" UTF-8)] This is some free-form text\r\n";

            using (var memory = new MemoryStream(Encoding.ASCII.GetBytes(text), false)) {
                using (var tokenizer = new ImapStream(memory, null, new NullProtocolLogger())) {
                    using (var engine = new ImapEngine(null)) {
                        ImapResponseCode respCode;

                        engine.SetStream(tokenizer);

                        try {
                            respCode = engine.ParseResponseCodeAsync(true, false, CancellationToken.None).GetAwaiter().GetResult();
                        } catch (Exception ex) {
                            Assert.Fail("Parsing RESP-CODE failed: {0}", ex);
                            return;
                        }

                        Assert.AreEqual(ImapResponseCodeType.BadCharset, respCode.Type);
                        Assert.AreEqual("This is some free-form text", respCode.Message);

                        Assert.AreEqual(3, engine.SupportedCharsets.Count);
                        Assert.IsTrue(engine.SupportedCharsets.Contains("US-ASCII"), "US-ASCII");
                        Assert.IsTrue(engine.SupportedCharsets.Contains("iso-8859-1"), "iso-8859-1");
                        Assert.IsTrue(engine.SupportedCharsets.Contains("UTF-8"), "UTF-8");
                    }
                }
            }
        }
Пример #9
0
        public void TestParseResponseCodeBadUrl()
        {
            const string text = "BADURL \"/INBOX;UIDVALIDITY=785799047/;UID=113330;section=1.5.9\"] CATENATE append has failed, one message expunged\r\n";

            using (var memory = new MemoryStream(Encoding.ASCII.GetBytes(text), false)) {
                using (var tokenizer = new ImapStream(memory, null, new NullProtocolLogger())) {
                    using (var engine = new ImapEngine(null)) {
                        ImapResponseCode respCode;

                        engine.SetStream(tokenizer);

                        try {
                            respCode = engine.ParseResponseCodeAsync(true, false, CancellationToken.None).GetAwaiter().GetResult();
                        } catch (Exception ex) {
                            Assert.Fail("Parsing RESP-CODE failed: {0}", ex);
                            return;
                        }

                        Assert.AreEqual(ImapResponseCodeType.BadUrl, respCode.Type);
                        Assert.AreEqual("CATENATE append has failed, one message expunged", respCode.Message);

                        var badurl = (BadUrlResponseCode)respCode;
                        Assert.AreEqual("/INBOX;UIDVALIDITY=785799047/;UID=113330;section=1.5.9", badurl.BadUrl);
                    }
                }
            }
        }
Пример #10
0
        public void TestParseResponseCodeNoUpdate()
        {
            const string text = "NOUPDATE \"B02\"] Too many contexts\r\n";

            using (var memory = new MemoryStream(Encoding.ASCII.GetBytes(text), false)) {
                using (var tokenizer = new ImapStream(memory, null, new NullProtocolLogger())) {
                    using (var engine = new ImapEngine(null)) {
                        ImapResponseCode respCode;

                        engine.SetStream(tokenizer);

                        try {
                            respCode = engine.ParseResponseCodeAsync(false, false, CancellationToken.None).GetAwaiter().GetResult();
                        } catch (Exception ex) {
                            Assert.Fail("Parsing RESP-CODE failed: {0}", ex);
                            return;
                        }

                        Assert.AreEqual(ImapResponseCodeType.NoUpdate, respCode.Type);
                        Assert.AreEqual("Too many contexts", respCode.Message);

                        var noupdate = (NoUpdateResponseCode)respCode;
                        Assert.AreEqual("B02", noupdate.Tag);
                    }
                }
            }
        }
Пример #11
0
        public void TestParseResponseCodeUndefinedFilter()
        {
            const string text = "UNDEFINED-FILTER filter-name] This is some free-form text\r\n";

            using (var memory = new MemoryStream(Encoding.ASCII.GetBytes(text), false)) {
                using (var tokenizer = new ImapStream(memory, null, new NullProtocolLogger())) {
                    using (var engine = new ImapEngine(null)) {
                        ImapResponseCode respCode;

                        engine.SetStream(tokenizer);

                        try {
                            respCode = engine.ParseResponseCodeAsync(true, false, CancellationToken.None).GetAwaiter().GetResult();
                        } catch (Exception ex) {
                            Assert.Fail("Parsing RESP-CODE failed: {0}", ex);
                            return;
                        }

                        Assert.AreEqual(ImapResponseCodeType.UndefinedFilter, respCode.Type);
                        Assert.AreEqual("This is some free-form text", respCode.Message);

                        var undefined = (UndefinedFilterResponseCode)respCode;
                        Assert.AreEqual("filter-name", undefined.Name);
                    }
                }
            }
        }
Пример #12
0
        public void TestParseResponseCodeMaxConvertParts()
        {
            const string text = "MAXCONVERTPARTS 1] This is some free-form text\r\n";

            using (var memory = new MemoryStream(Encoding.ASCII.GetBytes(text), false)) {
                using (var tokenizer = new ImapStream(memory, null, new NullProtocolLogger())) {
                    using (var engine = new ImapEngine(null)) {
                        ImapResponseCode respCode;

                        engine.SetStream(tokenizer);

                        try {
                            respCode = engine.ParseResponseCodeAsync(true, false, CancellationToken.None).GetAwaiter().GetResult();
                        } catch (Exception ex) {
                            Assert.Fail("Parsing RESP-CODE failed: {0}", ex);
                            return;
                        }

                        Assert.AreEqual(ImapResponseCodeType.MaxConvertParts, respCode.Type);
                        Assert.AreEqual("This is some free-form text", respCode.Message);

                        var maxconvert = (MaxConvertResponseCode)respCode;
                        Assert.AreEqual(1, maxconvert.MaxConvert);
                    }
                }
            }
        }
Пример #13
0
        public void TestParseShortDovecotExampleThread()
        {
            const string text = "((352)(381))\r\n";

            using (var memory = new MemoryStream(Encoding.ASCII.GetBytes(text), false)) {
                using (var tokenizer = new ImapStream(memory, null, new NullProtocolLogger())) {
                    using (var engine = new ImapEngine(null)) {
                        IList <MessageThread> threads;

                        engine.SetStream(tokenizer);

                        try {
                            threads = ImapUtils.ParseThreadsAsync(engine, 0, false, CancellationToken.None).GetAwaiter().GetResult();
                        } catch (Exception ex) {
                            Assert.Fail("Parsing THREAD response failed: {0}", ex);
                            return;
                        }

                        var token = engine.ReadToken(CancellationToken.None);
                        Assert.AreEqual(ImapTokenType.Eoln, token.Type, "Expected new-line, but got: {0}", token);

                        Assert.AreEqual(1, threads.Count, "Expected 1 thread.");

                        Assert.AreEqual((uint)0, threads[0].UniqueId.Value.Id);

                        var children = threads[0].Children;
                        Assert.AreEqual(2, children.Count, "Expected 2 children.");

                        Assert.AreEqual((uint)352, children[0].UniqueId.Value.Id);
                        Assert.AreEqual((uint)381, children[1].UniqueId.Value.Id);
                    }
                }
            }
        }
Пример #14
0
        public void TestParseLongDovecotExampleThread()
        {
            const string text = "(3 4 5 6 7)(1)((2)(8)(15))(9)(16)(10)(11)(12 13)(14)(17)(18)(19)(20)(21)(22)(23)(24)(25 (26)(29 39)(31)(32))(27)(28)(38 35)(30 33 34)(37)(36)(40)(41)((42 43)(44)(48)(49)(50)(51 52))(45)((46)(55))(47)(53)(54)(56)(57 (58)(59)(60)(63))((61)(62))(64)(65)(70)((66)(67)(68)(69)(71))(72 73 (74)(75)(76 77))\r\n";

            using (var memory = new MemoryStream(Encoding.ASCII.GetBytes(text), false)) {
                using (var tokenizer = new ImapStream(memory, null, new NullProtocolLogger())) {
                    using (var engine = new ImapEngine(null)) {
                        IList <MessageThread> threads;

                        engine.SetStream(tokenizer);

                        try {
                            threads = ImapUtils.ParseThreadsAsync(engine, 0, false, CancellationToken.None).GetAwaiter().GetResult();
                        } catch (Exception ex) {
                            Assert.Fail("Parsing THREAD response failed: {0}", ex);
                            return;
                        }

                        var token = engine.ReadToken(CancellationToken.None);
                        Assert.AreEqual(ImapTokenType.Eoln, token.Type, "Expected new-line, but got: {0}", token);

                        Assert.AreEqual(40, threads.Count, "Expected 40 threads.");

                        Assert.AreEqual((uint)3, threads[0].UniqueId.Value.Id);
                        Assert.AreEqual((uint)1, threads[1].UniqueId.Value.Id);
                        Assert.AreEqual((uint)0, threads[2].UniqueId.Value.Id);

                        var branches = threads[2].Children.ToArray();
                        Assert.AreEqual(3, branches.Length, "Expected 3 children.");
                    }
                }
            }
        }
Пример #15
0
        static void ParseEnvelopeAddressList(InternetAddressList list, ImapEngine engine, CancellationToken cancellationToken)
        {
            var token = engine.ReadToken(cancellationToken);

            if (token.Type == ImapTokenType.Nil)
            {
                return;
            }

            if (token.Type != ImapTokenType.OpenParen)
            {
                throw ImapEngine.UnexpectedToken(token, false);
            }

            do
            {
                token = engine.ReadToken(cancellationToken);

                if (token.Type == ImapTokenType.CloseParen)
                {
                    break;
                }

                if (token.Type != ImapTokenType.OpenParen)
                {
                    throw ImapEngine.UnexpectedToken(token, false);
                }

                AddEnvelopeAddress(list, engine, cancellationToken);
            } while (true);
        }
Пример #16
0
 /// <summary>
 /// Initializes a new instance of the <see cref="MailKit.Net.Imap.ImapIdleContext"/> class.
 /// </summary>
 /// <remarks>
 /// Creates a new <see cref="MailKit.Net.Imap.ImapIdleContext"/>.
 /// </remarks>
 /// <param name="engine">The IMAP engine.</param>
 /// <param name="doneToken">The done token.</param>
 /// <param name="cancellationToken">The cancellation token.</param>
 public ImapIdleContext(ImapEngine engine, CancellationToken doneToken, CancellationToken cancellationToken)
 {
     source            = CancellationTokenSource.CreateLinkedTokenSource(doneToken, cancellationToken);
     CancellationToken = cancellationToken;
     DoneToken         = doneToken;
     Engine            = engine;
 }
Пример #17
0
        static DateTimeOffset?ParseEnvelopeDate(ImapEngine engine, CancellationToken cancellationToken)
        {
            var            token = engine.ReadToken(cancellationToken);
            DateTimeOffset date;
            string         value;

            switch (token.Type)
            {
            case ImapTokenType.Literal:
                value = engine.ReadLiteral(cancellationToken);
                break;

            case ImapTokenType.QString:
            case ImapTokenType.Atom:
                value = (string)token.Value;
                break;

            case ImapTokenType.Nil:
                return(null);

            default:
                throw ImapEngine.UnexpectedToken(token, false);
            }

            if (!DateUtils.TryParseDateTime(value, out date))
            {
                return(null);
            }

            return(date);
        }
Пример #18
0
        static void SkipBodyExtensions(ImapEngine engine, CancellationToken cancellationToken)
        {
            var token = engine.ReadToken (cancellationToken);

            switch (token.Type) {
            case ImapTokenType.OpenParen:
                do {
                    token = engine.PeekToken (cancellationToken);

                    if (token.Type == ImapTokenType.CloseParen)
                        break;

                    SkipBodyExtensions (engine, cancellationToken);
                } while (true);

                // read the ')'
                engine.ReadToken (cancellationToken);
                break;
            case ImapTokenType.Literal:
                engine.ReadLiteral (cancellationToken);
                break;
            case ImapTokenType.QString:
            case ImapTokenType.Atom:
            case ImapTokenType.Nil:
                break;
            default:
                throw ImapEngine.UnexpectedToken (token, false);
            }
        }
Пример #19
0
        /// <summary>
        /// Parses the threads.
        /// </summary>
        /// <returns>The threads.</returns>
        /// <param name="engine">The IMAP engine.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        public static IList <MessageThread> ParseThreads(ImapEngine engine, CancellationToken cancellationToken)
        {
            var       threads = new List <MessageThread> ();
            ImapToken token;

            do
            {
                token = engine.PeekToken(cancellationToken);

                if (token.Type == ImapTokenType.Eoln)
                {
                    break;
                }

                token = engine.ReadToken(cancellationToken);

                if (token.Type != ImapTokenType.OpenParen)
                {
                    throw ImapEngine.UnexpectedToken(token, false);
                }

                threads.Add(ParseThread(engine, cancellationToken));
            } while (true);

            return(threads);
        }
Пример #20
0
        /// <summary>
        /// Parses the ENVELOPE parenthesized list.
        /// </summary>
        /// <returns>The envelope.</returns>
        /// <param name="engine">The IMAP engine.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        public static Envelope ParseEnvelope(ImapEngine engine, CancellationToken cancellationToken)
        {
            var token = engine.ReadToken (cancellationToken);
            string nstring;

            if (token.Type != ImapTokenType.OpenParen)
                throw ImapEngine.UnexpectedToken (token, false);

            var envelope = new Envelope ();
            envelope.Date = ParseEnvelopeDate (engine, cancellationToken);
            envelope.Subject = ReadNStringToken (engine, true, cancellationToken);
            ParseEnvelopeAddressList (envelope.From, engine, cancellationToken);
            ParseEnvelopeAddressList (envelope.Sender, engine, cancellationToken);
            ParseEnvelopeAddressList (envelope.ReplyTo, engine, cancellationToken);
            ParseEnvelopeAddressList (envelope.To, engine, cancellationToken);
            ParseEnvelopeAddressList (envelope.Cc, engine, cancellationToken);
            ParseEnvelopeAddressList (envelope.Bcc, engine, cancellationToken);

            if ((nstring = ReadNStringToken (engine, false, cancellationToken)) != null)
                envelope.InReplyTo = MimeUtils.EnumerateReferences (nstring).FirstOrDefault ();

            if ((nstring = ReadNStringToken (engine, false, cancellationToken)) != null)
                envelope.MessageId = MimeUtils.EnumerateReferences (nstring).FirstOrDefault ();

            token = engine.ReadToken (cancellationToken);

            if (token.Type != ImapTokenType.CloseParen)
                throw ImapEngine.UnexpectedToken (token, false);

            return envelope;
        }
Пример #21
0
        static void ParseParameterList(StringBuilder builder, ImapEngine engine, CancellationToken cancellationToken)
        {
            ImapToken token;

            do
            {
                token = engine.PeekToken(cancellationToken);

                if (token.Type == ImapTokenType.CloseParen)
                {
                    break;
                }

                var name  = ReadStringToken(engine, cancellationToken);
                var value = ReadStringToken(engine, cancellationToken);

                builder.Append("; ").Append(name).Append('=');

                if (NeedsQuoting(value))
                {
                    builder.Append(MimeUtils.Quote(value));
                }
                else
                {
                    builder.Append(value);
                }
            } while (true);

            // read the ')'
            engine.ReadToken(cancellationToken);
        }
Пример #22
0
        static ContentDisposition ParseContentDisposition(ImapEngine engine, CancellationToken cancellationToken)
        {
            var token = engine.ReadToken (cancellationToken);

            if (token.Type == ImapTokenType.Nil)
                return null;

            if (token.Type != ImapTokenType.OpenParen)
                throw ImapEngine.UnexpectedToken (token, false);

            var dsp = ReadStringToken (engine, cancellationToken);
            var builder = new StringBuilder (dsp);
            ContentDisposition disposition;

            token = engine.ReadToken (cancellationToken);

            if (token.Type == ImapTokenType.OpenParen)
                ParseParameterList (builder, engine, cancellationToken);
            else if (token.Type != ImapTokenType.Nil)
                throw ImapEngine.UnexpectedToken (token, false);

            token = engine.ReadToken (cancellationToken);

            if (token.Type != ImapTokenType.CloseParen)
                throw ImapEngine.UnexpectedToken (token, false);

            if (!ContentDisposition.TryParse (builder.ToString (), out disposition))
                disposition = new ContentDisposition (dsp);

            return disposition;
        }
Пример #23
0
            /// <summary>
            /// Format the IMAP NOTIFY command for this particular IMAP mailbox filter.
            /// </summary>
            /// <remarks>
            /// Formats the IMAP NOTIFY command for this particular IMAP mailbox filter.
            /// </remarks>
            /// <param name="engine">The IMAP engine.</param>
            /// <param name="command">The IMAP command builder.</param>
            /// <param name="args">The IMAP command argument builder.</param>
            internal override void Format(ImapEngine engine, StringBuilder command, IList <object> args)
            {
                command.Append(Name);
                command.Append(' ');

                // FIXME: should we verify that each ImapFolder belongs to this ImapEngine?

                if (folders.Length == 1)
                {
                    command.Append("%F");
                    args.Add(folders[0]);
                }
                else
                {
                    command.Append("(");

                    for (int i = 0; i < folders.Length; i++)
                    {
                        if (i > 0)
                        {
                            command.Append(" ");
                        }
                        command.Append("%F");
                        args.Add(folders[i]);
                    }

                    command.Append(")");
                }
            }
Пример #24
0
        static void ParseParameterList(StringBuilder builder, ImapEngine engine, CancellationToken cancellationToken)
        {
            ImapToken token;

            do {
                token = engine.PeekToken (cancellationToken);

                if (token.Type == ImapTokenType.CloseParen)
                    break;

                var name = ReadStringToken (engine, cancellationToken);

                // Note: technically, the value should also be a 'string' token and not an 'nstring',
                // but issue #124 reveals a server that is sending NIL for boundary values.
                var value = ReadNStringToken (engine, false, cancellationToken) ?? string.Empty;

                builder.Append ("; ").Append (name).Append ('=');

                if (NeedsQuoting (value))
                    builder.Append (MimeUtils.Quote (value));
                else
                    builder.Append (value);
            } while (true);

            // read the ')'
            engine.ReadToken (cancellationToken);
        }
Пример #25
0
        static int EstimateStringLength(ImapEngine engine, FormatOptions options, bool allowAtom, string value, out bool eoln)
        {
            eoln = false;

            switch (GetStringType(engine, value, allowAtom))
            {
            case ImapStringType.Literal:
                var literal = Encoding.UTF8.GetByteCount(value);
                var plus    = CanUseNonSynchronizedLiteral(engine, literal);
                int length  = "{}\r\n".Length;

                length += literal.ToString(CultureInfo.InvariantCulture).Length;
                if (plus)
                {
                    length++;
                }

                eoln = true;

                return(length++);

            case ImapStringType.QString:
                return(Encoding.UTF8.GetByteCount(MimeUtils.Quote(value)));

            case ImapStringType.Nil:
                return(Nil.Length);

            default:
                return(value.Length);
            }
        }
Пример #26
0
            internal override void Format(ImapEngine engine, StringBuilder command, IList <object> args)
            {
                command.Append(Name);
                command.Append(' ');

                if (folders.Length == 1)
                {
                    command.Append("%F");
                    args.Add(folders[0]);
                }
                else
                {
                    command.Append("(");

                    for (int i = 0; i < folders.Length; i++)
                    {
                        if (i > 0)
                        {
                            command.Append(" ");
                        }
                        command.Append("%F");
                        args.Add(folders[i]);
                    }

                    command.Append(")");
                }
            }
Пример #27
0
        static void AddEnvelopeAddress(InternetAddressList list, ImapEngine engine, CancellationToken cancellationToken)
        {
            var       values = new string[4];
            ImapToken token;
            int       index = 0;

            do
            {
                token = engine.ReadToken(cancellationToken);

                switch (token.Type)
                {
                case ImapTokenType.Literal:
                    values[index] = engine.ReadLiteral(cancellationToken);
                    break;

                case ImapTokenType.QString:
                case ImapTokenType.Atom:
                    values[index] = (string)token.Value;
                    break;

                case ImapTokenType.Nil:
                    break;

                default:
                    throw ImapEngine.UnexpectedToken(token, false);
                }

                index++;
            } while (index < 4);

            token = engine.ReadToken(cancellationToken);

            if (token.Type != ImapTokenType.CloseParen)
            {
                throw ImapEngine.UnexpectedToken(token, false);
            }

            string name = null;

            if (values[0] != null)
            {
                // Note: since the ImapEngine.ReadLiteral() uses iso-8859-1
                // to convert bytes to unicode, we can undo that here:
                name = Rfc2047.DecodePhrase(Latin1.GetBytes(values[0]));
            }

            string     address = values[3] != null ? values[2] + "@" + values[3] : values[2];
            DomainList route;

            if (values[1] != null && DomainList.TryParse(values[1], out route))
            {
                list.Add(new MailboxAddress(name, route, address));
            }
            else
            {
                list.Add(new MailboxAddress(name, address));
            }
        }
Пример #28
0
        /// <summary>
        /// Callback method to be used as the ImapCommand's ContinuationHandler.
        /// </summary>
        /// <remarks>
        /// Callback method to be used as the ImapCommand's ContinuationHandler.
        /// </remarks>
        /// <param name="engine">The ImapEngine.</param>
        /// <param name="ic">The ImapCommand.</param>
        /// <param name="text">The text.</param>
        /// <param name="doAsync"><c>true</c> if the command is being run asynchronously; otherwise, <c>false</c>.</param>
        /// <returns></returns>
        public Task ContinuationHandler(ImapEngine engine, ImapCommand ic, string text, bool doAsync)
        {
            Engine.State = ImapEngineState.Idle;

            registration = DoneToken.Register(IdleComplete);

            return(Task.FromResult(true));
        }
Пример #29
0
 /// <summary>
 /// Initializes a new instance of the <see cref="MailKit.Net.Imap.ImapFolderConstructorArgs"/> class.
 /// </summary>
 /// <param name="engine">The IMAP command engine.</param>
 /// <param name="encodedName">The encoded name.</param>
 /// <param name="attributes">The attributes.</param>
 /// <param name="delim">The directory separator.</param>
 internal ImapFolderConstructorArgs(ImapEngine engine, string encodedName, FolderAttributes attributes, char delim)
 {
     FullName           = engine.DecodeMailboxName(encodedName);
     Name               = GetBaseName(FullName, delim);
     DirectorySeparator = delim;
     EncodedName        = encodedName;
     Attributes         = attributes;
     Engine             = engine;
 }
Пример #30
0
        static uint ReadNumber(ImapEngine engine, CancellationToken cancellationToken)
        {
            var token = engine.ReadToken (cancellationToken);
            uint number;

            if (token.Type != ImapTokenType.Atom || !uint.TryParse ((string) token.Value, out number))
                throw ImapEngine.UnexpectedToken (token, false);

            return number;
        }