Example #1
0
            public async Task IdAsync(cMethodControl pMC, cId pClientId, cTrace.cContext pParentContext)
            {
                var lContext = pParentContext.NewMethod(nameof(cSession), nameof(IdAsync), pMC, pClientId);

                if (mDisposed)
                {
                    throw new ObjectDisposedException(nameof(cSession));
                }
                if (_ConnectionState < eConnectionState.notauthenticated || _ConnectionState > eConnectionState.selected)
                {
                    throw new InvalidOperationException(kInvalidOperationExceptionMessage.NotConnected);
                }

                // install the permanent response data processor
                if (mIdResponseDataProcessor == null)
                {
                    mIdResponseDataProcessor = new cIdDataProcessor(mSynchroniser);
                    mPipeline.Install(mIdResponseDataProcessor);
                }

                using (var lBuilder = new cCommandDetailsBuilder())
                {
                    if (!_Capabilities.QResync)
                    {
                        lBuilder.Add(await mSelectExclusiveAccess.GetBlockAsync(pMC, lContext).ConfigureAwait(false)); // block select if mailbox-data delivered during the command would be ambiguous
                    }
                    lBuilder.Add(await mMSNUnsafeBlock.GetBlockAsync(pMC, lContext).ConfigureAwait(false));            // this command is msnunsafe

                    lBuilder.Add(kIdCommandPart);

                    if (pClientId == null || pClientId.Count == 0)
                    {
                        lBuilder.Add(cCommandPart.Nil);
                    }
                    else
                    {
                        lBuilder.BeginList(eListBracketing.bracketed);

                        foreach (var lPair in pClientId)
                        {
                            lBuilder.Add(mCommandPartFactory.AsString(lPair.Key));
                            lBuilder.Add(mCommandPartFactory.AsNString(lPair.Value));
                        }

                        lBuilder.EndList();
                    }

                    var lResult = await mPipeline.ExecuteAsync(pMC, lBuilder.EmitCommandDetails(), lContext).ConfigureAwait(false);

                    if (lResult.ResultType == eCommandResultType.ok)
                    {
                        lContext.TraceInformation("id success");
                        return;
                    }

                    throw new cProtocolErrorException(lResult, fCapabilities.id, lContext);
                }
            }
Example #2
0
            public async Task EnableAsync(cMethodControl pMC, fEnableableExtensions pExtensions, cTrace.cContext pParentContext)
            {
                var lContext = pParentContext.NewMethod(nameof(cSession), nameof(EnableAsync), pMC, pExtensions);

                if (mDisposed)
                {
                    throw new ObjectDisposedException(nameof(cSession));
                }
                if (_ConnectionState != eConnectionState.authenticated)
                {
                    throw new InvalidOperationException(kInvalidOperationExceptionMessage.NotAuthenticated);
                }

                using (var lBuilder = new cCommandDetailsBuilder())
                {
                    //  note the lack of locking - this can only called during connect

                    lBuilder.BeginList(eListBracketing.none);
                    lBuilder.Add(kEnableCommandPartEnable);
                    if ((pExtensions & fEnableableExtensions.utf8) != 0)
                    {
                        lBuilder.Add(kEnableCommandPartUTF8);
                    }
                    // more here as required
                    lBuilder.EndList();

                    var lHook = new cEnableCommandHook();
                    lBuilder.Add(lHook);

                    var lResult = await mPipeline.ExecuteAsync(pMC, lBuilder.EmitCommandDetails(), lContext).ConfigureAwait(false);

                    if (lResult.ResultType == eCommandResultType.ok)
                    {
                        var lEnabledExtensions = lHook.EnabledExtensions;
                        lContext.TraceInformation("enabled extensions {0}", lEnabledExtensions);
                        EnabledExtensions = EnabledExtensions | lEnabledExtensions;
                        lContext.TraceVerbose("current enabled extensions {0}", EnabledExtensions);
                        mSynchroniser.InvokePropertyChanged(nameof(cIMAPClient.EnabledExtensions), lContext);
                        return;
                    }

                    if (lHook.EnabledExtensions != fEnableableExtensions.none)
                    {
                        lContext.TraceError("received enabled on a failed enable");
                    }

                    throw new cProtocolErrorException(lResult, fCapabilities.enable, lContext);
                }
            }
Example #3
0
            public async Task StatusAsync(cMethodControl pMC, iMailboxHandle pMailboxHandle, cTrace.cContext pParentContext)
            {
                var lContext = pParentContext.NewMethod(nameof(cSession), nameof(StatusAsync), pMC, pMailboxHandle);

                if (mDisposed)
                {
                    throw new ObjectDisposedException(nameof(cSession));
                }
                if (_ConnectionState != eConnectionState.notselected && _ConnectionState != eConnectionState.selected)
                {
                    throw new InvalidOperationException(kInvalidOperationExceptionMessage.NotConnected);
                }
                if (pMailboxHandle == null)
                {
                    throw new ArgumentNullException(nameof(pMailboxHandle));
                }

                var lItem = mMailboxCache.CheckHandle(pMailboxHandle);

                if (mStatusAttributes == 0)
                {
                    return;
                }

                using (var lBuilder = new cCommandDetailsBuilder())
                {
                    lBuilder.Add(await mSelectExclusiveAccess.GetBlockAsync(pMC, lContext).ConfigureAwait(false)); // block select: the status command is not supported on the selected mailbox

                    var lMailboxHandle = mMailboxCache.SelectedMailboxDetails?.MailboxHandle;
                    if (ReferenceEquals(pMailboxHandle, lMailboxHandle))
                    {
                        return;
                    }

                    lBuilder.Add(await mMSNUnsafeBlock.GetBlockAsync(pMC, lContext).ConfigureAwait(false)); // status is msnunsafe

                    lBuilder.BeginList(eListBracketing.none);
                    lBuilder.Add(kStatusCommandPart);
                    lBuilder.Add(lItem.MailboxNameCommandPart);
                    lBuilder.AddStatusAttributes(mStatusAttributes);
                    lBuilder.EndList();

                    var lHook = new cStatusCommandHook(lItem);
                    lBuilder.Add(lHook);

                    var lResult = await mPipeline.ExecuteAsync(pMC, lBuilder.EmitCommandDetails(), lContext).ConfigureAwait(false);

                    if (lResult.ResultType == eCommandResultType.ok)
                    {
                        lContext.TraceInformation("status success");
                        return;
                    }

                    if (lResult.ResultType == eCommandResultType.no)
                    {
                        lContext.TraceInformation("status unsuccessful");
                        return;
                    }

                    fCapabilities lTryIgnoring;
                    if (_Capabilities.CondStore)
                    {
                        lTryIgnoring = fCapabilities.condstore;
                    }
                    else
                    {
                        lTryIgnoring = 0;
                    }

                    throw new cProtocolErrorException(lResult, lTryIgnoring, lContext);
                }
            }
Example #4
0
            public async Task <List <iMailboxHandle> > ListExtendedAsync(cMethodControl pMC, eListExtendedSelect pSelect, bool pRemote, string pListMailbox, char?pDelimiter, cMailboxPathPattern pPattern, bool pStatus, cTrace.cContext pParentContext)
            {
                var lContext = pParentContext.NewMethod(nameof(cSession), nameof(ListExtendedAsync), pMC, pSelect, pRemote, pListMailbox, pDelimiter, pPattern, pStatus);

                // caller needs to determine if list status is supported

                if (mDisposed)
                {
                    throw new ObjectDisposedException(nameof(cSession));
                }
                if (_ConnectionState != eConnectionState.notselected && _ConnectionState != eConnectionState.selected)
                {
                    throw new InvalidOperationException(kInvalidOperationExceptionMessage.NotConnected);
                }

                if (pListMailbox == null)
                {
                    throw new ArgumentNullException(nameof(pListMailbox));
                }
                if (pPattern == null)
                {
                    throw new ArgumentNullException(nameof(pPattern));
                }

                if (!mCommandPartFactory.TryAsListMailbox(pListMailbox, pDelimiter, out var lListMailboxCommandPart))
                {
                    throw new ArgumentOutOfRangeException(nameof(pListMailbox));
                }

                using (var lBuilder = new cCommandDetailsBuilder())
                {
                    if (!_Capabilities.QResync)
                    {
                        lBuilder.Add(await mSelectExclusiveAccess.GetBlockAsync(pMC, lContext).ConfigureAwait(false)); // block select if mailbox-data delivered during the command would be ambiguous
                    }
                    lBuilder.Add(await mMSNUnsafeBlock.GetBlockAsync(pMC, lContext).ConfigureAwait(false));            // this command is msnunsafe

                    lBuilder.BeginList(eListBracketing.none);

                    lBuilder.Add(kListExtendedCommandPartList);

                    lBuilder.BeginList(eListBracketing.ifany);

                    if (pSelect == eListExtendedSelect.subscribed)
                    {
                        lBuilder.Add(kListExtendedCommandPartSubscribed);
                    }
                    else if (pSelect == eListExtendedSelect.subscribedrecursive)
                    {
                        lBuilder.Add(kListExtendedCommandPartSubscribed);
                        lBuilder.Add(kListExtendedCommandPartRecursiveMatch);
                    }

                    if (pRemote)
                    {
                        lBuilder.Add(kListExtendedCommandPartRemote);
                    }

                    lBuilder.EndList();

                    lBuilder.Add(kListExtendedCommandPartMailbox);
                    lBuilder.Add(lListMailboxCommandPart);

                    // return options

                    lBuilder.BeginList(eListBracketing.ifany, kListExtendedCommandPartReturnSpace);

                    if ((mMailboxCacheDataItems & fMailboxCacheDataItems.subscribed) != 0)
                    {
                        lBuilder.Add(kListExtendedCommandPartSubscribed);
                    }
                    if ((mMailboxCacheDataItems & fMailboxCacheDataItems.children) != 0)
                    {
                        lBuilder.Add(kListExtendedCommandPartChildren);
                    }
                    if ((mMailboxCacheDataItems & fMailboxCacheDataItems.specialuse) != 0 && _Capabilities.SpecialUse)
                    {
                        lBuilder.Add(kListExtendedCommandPartSpecialUse);
                    }

                    if (pStatus)
                    {
                        lBuilder.Add(kListExtendedCommandPartStatus);
                        lBuilder.AddStatusAttributes(mStatusAttributes);
                    }

                    lBuilder.EndList();
                    lBuilder.EndList();

                    var lHook = new cListExtendedCommandHook(mMailboxCache, pSelect, pPattern, pStatus);
                    lBuilder.Add(lHook);

                    var lResult = await mPipeline.ExecuteAsync(pMC, lBuilder.EmitCommandDetails(), lContext).ConfigureAwait(false);

                    if (lResult.ResultType == eCommandResultType.ok)
                    {
                        lContext.TraceInformation("listextended success");
                        return(lHook.MailboxHandles);
                    }

                    fCapabilities lTryIgnoring = 0;

                    if ((mMailboxCacheDataItems & fMailboxCacheDataItems.specialuse) != 0 && _Capabilities.SpecialUse)
                    {
                        lTryIgnoring |= fCapabilities.specialuse;
                    }
                    if (pStatus)
                    {
                        lTryIgnoring |= fCapabilities.liststatus;
                    }
                    if (lTryIgnoring == 0)
                    {
                        lTryIgnoring |= fCapabilities.listextended;
                    }

                    if (lResult.ResultType == eCommandResultType.no)
                    {
                        throw new cUnsuccessfulCompletionException(lResult.ResponseText, lTryIgnoring, lContext);
                    }
                    throw new cProtocolErrorException(lResult, lTryIgnoring, lContext);
                }
            }