Example #1
0
                public void Unselect(cTrace.cContext pParentContext)
                {
                    var lContext = pParentContext.NewMethod(nameof(cMailboxCache), nameof(Unselect));

                    if (mSelectedMailbox == null)
                    {
                        return;
                    }

                    var lMailboxHandle = mSelectedMailbox.MailboxHandle;

                    fMailboxProperties lProperties = fMailboxProperties.isselected;

                    if (mSelectedMailbox.SelectedForUpdate)
                    {
                        lProperties |= fMailboxProperties.isselectedforupdate;
                    }
                    if (mSelectedMailbox.AccessReadOnly)
                    {
                        lProperties |= fMailboxProperties.isaccessreadonly;
                    }

                    mSelectedMailbox = null;

                    mSetState(eConnectionState.notselected, lContext);
                    mSynchroniser.InvokeMailboxPropertiesChanged(lMailboxHandle, lProperties, lContext);
                    mSynchroniser.InvokePropertyChanged(nameof(cIMAPClient.SelectedMailbox), lContext);
                }
Example #2
0
            private async Task ZUIDStoreAsync(cMethodControl pMC, iMailboxHandle pMailboxHandle, uint pUIDValidity, cStoreFeedbackCollector pFeedbackCollector, eStoreOperation pOperation, cStorableFlags pFlags, ulong?pIfUnchangedSinceModSeq, cUIDStoreFeedback pFeedback, cTrace.cContext pParentContext)
            {
                var lContext = pParentContext.NewMethod(nameof(cSession), nameof(ZStoreAsync), pMC, pMailboxHandle, pUIDValidity, pFeedbackCollector, pOperation, pFlags, pIfUnchangedSinceModSeq, pFeedback);

                // no validation ... all the parameters have been validated already by the cSession by the time we get here

                using (var lBuilder = new cCommandDetailsBuilder())
                {
                    lBuilder.Add(await mSelectExclusiveAccess.GetBlockAsync(pMC, lContext).ConfigureAwait(false)); // block select

                    cSelectedMailbox lSelectedMailbox = mMailboxCache.CheckIsSelectedMailbox(pMailboxHandle, pUIDValidity);
                    if (!lSelectedMailbox.SelectedForUpdate)
                    {
                        throw new InvalidOperationException(kInvalidOperationExceptionMessage.NotSelectedForUpdate);
                    }

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

                    lBuilder.AddUIDValidity(pUIDValidity);                                                  // the command is sensitive to UIDValidity changes

                    // build the command
                    lBuilder.Add(kUIDStoreCommandPartUIDStoreSpace, new cTextCommandPart(cSequenceSet.FromUInts(pFeedbackCollector.UInts)), cCommandPart.Space);
                    if (pIfUnchangedSinceModSeq != null)
                    {
                        lBuilder.Add(kStoreCommandPartLParenUnchangedSinceSpace, new cTextCommandPart(pIfUnchangedSinceModSeq.Value), kStoreCommandPartRParenSpace);
                    }
                    lBuilder.Add(pOperation, pFlags);

                    // add the hook
                    var lHook = new cCommandHookStore(pFeedbackCollector, pFeedback, lSelectedMailbox);
                    lBuilder.Add(lHook);

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

                    // note: the base spec states that non-existent UIDs are ignored without comment => a NO from a UID STORE is unexpected

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

                    fCapabilities lTryIgnoring;
                    if (pIfUnchangedSinceModSeq == null)
                    {
                        lTryIgnoring = 0;
                    }
                    else
                    {
                        lTryIgnoring = fCapabilities.condstore;
                    }

                    if (lResult.ResultType == eCommandResultType.no)
                    {
                        throw new cUnsuccessfulCompletionException(lResult.ResponseText, lTryIgnoring, lContext);
                    }
                    throw new cProtocolErrorException(lResult, lTryIgnoring, lContext);
                }
            }
Example #3
0
            public async Task UIDStoreAsync(cMethodControl pMC, iMailboxHandle pMailboxHandle, cUIDStoreFeedback pFeedback, eStoreOperation pOperation, cStorableFlags pFlags, ulong?pIfUnchangedSinceModSeq, cTrace.cContext pParentContext)
            {
                var lContext = pParentContext.NewMethod(nameof(cSession), nameof(UIDStoreAsync), pMC, pMailboxHandle, pFeedback, pOperation, pFlags, pIfUnchangedSinceModSeq);

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

                if (pMailboxHandle == null)
                {
                    throw new ArgumentNullException(nameof(pMailboxHandle));
                }
                if (pFeedback == null)
                {
                    throw new ArgumentNullException(nameof(pFeedback));
                }
                if (pFlags == null)
                {
                    throw new ArgumentNullException(nameof(pFlags));
                }

                if (pFeedback.Count == 0)
                {
                    throw new ArgumentOutOfRangeException(nameof(pFeedback));
                }

                if (pIfUnchangedSinceModSeq == 0)
                {
                    throw new ArgumentOutOfRangeException(nameof(pIfUnchangedSinceModSeq));
                }
                if (pIfUnchangedSinceModSeq != null && !_Capabilities.CondStore)
                {
                    throw new InvalidOperationException(kInvalidOperationExceptionMessage.CondStoreNotInUse);
                }

                uint lUIDValidity = pFeedback[0].UID.UIDValidity;

                cSelectedMailbox lSelectedMailbox = mMailboxCache.CheckIsSelectedMailbox(pMailboxHandle, lUIDValidity); // to be repeated inside the select lock

                if (!lSelectedMailbox.SelectedForUpdate)
                {
                    throw new InvalidOperationException(kInvalidOperationExceptionMessage.NotSelectedForUpdate);                                      // to be repeated inside the select lock
                }
                cStoreFeedbackCollector lFeedbackCollector = new cStoreFeedbackCollector(pFeedback);

                await ZUIDStoreAsync(pMC, pMailboxHandle, lUIDValidity, lFeedbackCollector, pOperation, pFlags, pIfUnchangedSinceModSeq, pFeedback, lContext).ConfigureAwait(false);
            }
Example #4
0
                public void Select(iMailboxHandle pMailboxHandle, bool pForUpdate, bool pAccessReadOnly, bool pUIDNotSticky, cFetchableFlags pFlags, cPermanentFlags pPermanentFlags, int pExists, int pRecent, uint pUIDNext, uint pUIDValidity, uint pHighestModSeq, cTrace.cContext pParentContext)
                {
                    var lContext = pParentContext.NewMethod(nameof(cMailboxCache), nameof(Select), pMailboxHandle, pForUpdate, pAccessReadOnly, pUIDNotSticky, pFlags, pPermanentFlags, pExists, pRecent, pUIDNext, pUIDValidity, pHighestModSeq);

                    if (mSelectedMailbox != null)
                    {
                        throw new InvalidOperationException();
                    }

                    if (pMailboxHandle == null)
                    {
                        throw new ArgumentNullException(nameof(pMailboxHandle));
                    }
                    if (pFlags == null)
                    {
                        throw new ArgumentNullException(nameof(pFlags));
                    }

                    var lItem = CheckHandle(pMailboxHandle);

                    if (pExists < 0)
                    {
                        throw new ArgumentOutOfRangeException(nameof(pExists));
                    }
                    if (pRecent < 0)
                    {
                        throw new ArgumentOutOfRangeException(nameof(pRecent));
                    }

                    mSelectedMailbox = new cSelectedMailbox(mSynchroniser, lItem, pForUpdate, pAccessReadOnly, pExists, pRecent, pUIDNext, pUIDValidity, pHighestModSeq, lContext);

                    lItem.SetSelectedProperties(pUIDNotSticky, pFlags, pForUpdate, pPermanentFlags, lContext);

                    fMailboxProperties lProperties = fMailboxProperties.isselected;

                    if (pForUpdate)
                    {
                        lProperties |= fMailboxProperties.isselectedforupdate;
                    }
                    if (pAccessReadOnly)
                    {
                        lProperties |= fMailboxProperties.isaccessreadonly;
                    }

                    mSetState(eConnectionState.selected, lContext);
                    mSynchroniser.InvokeMailboxPropertiesChanged(pMailboxHandle, lProperties, lContext);
                    mSynchroniser.InvokePropertyChanged(nameof(cIMAPClient.SelectedMailbox), lContext);
                }
Example #5
0
            public Task <cCopyFeedback> CopyAsync(cMethodControl pMC, cMessageHandleList pSourceMessageHandles, iMailboxHandle pDestinationMailboxHandle, cTrace.cContext pParentContext)
            {
                var lContext = pParentContext.NewMethod(nameof(cSession), nameof(CopyAsync), pMC, pSourceMessageHandles, pDestinationMailboxHandle);

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

                if (pSourceMessageHandles == null)
                {
                    throw new ArgumentNullException(nameof(pSourceMessageHandles));
                }
                if (pDestinationMailboxHandle == null)
                {
                    throw new ArgumentNullException(nameof(pDestinationMailboxHandle));
                }

                if (pSourceMessageHandles.Count == 0)
                {
                    throw new ArgumentOutOfRangeException(nameof(pSourceMessageHandles));
                }

                cSelectedMailbox lSelectedMailbox = mMailboxCache.CheckInSelectedMailbox(pSourceMessageHandles); // to be repeated inside the select lock

                var lDestinationItem = mMailboxCache.CheckHandle(pDestinationMailboxHandle);

                if (pSourceMessageHandles.TrueForAll(h => h.UID != null))
                {
                    var lMessageHandle = pSourceMessageHandles.Find(h => h.Expunged);
                    if (lMessageHandle != null)
                    {
                        throw new cMessageExpungedException(lMessageHandle);
                    }
                    return(ZUIDCopyAsync(pMC, lSelectedMailbox.MailboxHandle, pSourceMessageHandles[0].UID.UIDValidity, new cUIntList(from h in pSourceMessageHandles select h.UID.UID), lDestinationItem, lContext));
                }
                else
                {
                    return(ZCopyAsync(pMC, pSourceMessageHandles, lDestinationItem, lContext));
                }
            }
Example #6
0
            public Task <cCopyFeedback> UIDCopyAsync(cMethodControl pMC, iMailboxHandle pSourceMailboxHandle, cUIDList pSourceUIDs, iMailboxHandle pDestinationMailboxHandle, cTrace.cContext pParentContext)
            {
                var lContext = pParentContext.NewMethod(nameof(cSession), nameof(UIDCopyAsync), pMC, pSourceMailboxHandle, pSourceUIDs, pDestinationMailboxHandle);

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

                if (pSourceMailboxHandle == null)
                {
                    throw new ArgumentNullException(nameof(pSourceMailboxHandle));
                }
                if (pSourceUIDs == null)
                {
                    throw new ArgumentNullException(nameof(pSourceUIDs));
                }
                if (pDestinationMailboxHandle == null)
                {
                    throw new ArgumentNullException(nameof(pDestinationMailboxHandle));
                }

                if (pSourceUIDs.Count == 0)
                {
                    throw new ArgumentOutOfRangeException(nameof(pSourceUIDs));
                }

                uint lSourceUIDValidity = pSourceUIDs[0].UIDValidity;

                cSelectedMailbox lSelectedMailbox = mMailboxCache.CheckIsSelectedMailbox(pSourceMailboxHandle, lSourceUIDValidity); // to be repeated inside the select lock

                var lDestinationItem = mMailboxCache.CheckHandle(pDestinationMailboxHandle);

                return(ZUIDCopyAsync(pMC, pSourceMailboxHandle, lSourceUIDValidity, new cUIntList(from lUID in pSourceUIDs select lUID.UID), lDestinationItem, lContext));
            }
Example #7
0
            private async Task <cCopyFeedback> ZUIDCopyAsync(cMethodControl pMC, iMailboxHandle pSourceMailboxHandle, uint pSourceUIDValidity, cUIntList pSourceUIDs, cMailboxCacheItem pDestinationItem, cTrace.cContext pParentContext)
            {
                var lContext = pParentContext.NewMethod(nameof(cSession), nameof(ZCopyAsync), pMC, pSourceMailboxHandle, pSourceUIDValidity, pSourceUIDs, pDestinationItem);

                using (var lBuilder = new cCommandDetailsBuilder())
                {
                    lBuilder.Add(await mSelectExclusiveAccess.GetBlockAsync(pMC, lContext).ConfigureAwait(false)); // block select

                    cSelectedMailbox lSelectedMailbox = mMailboxCache.CheckIsSelectedMailbox(pSourceMailboxHandle, pSourceUIDValidity);

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

                    lBuilder.AddUIDValidity(pSourceUIDValidity);                                            // the command is sensitive to UIDValidity changes

                    // build the command
                    lBuilder.Add(kUIDCopyCommandPart, new cTextCommandPart(cSequenceSet.FromUInts(pSourceUIDs)), cCommandPart.Space, pDestinationItem.MailboxNameCommandPart);

                    // add the hook
                    var lHook = new cCommandHookCopy(pSourceUIDValidity);
                    lBuilder.Add(lHook);

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

                    if (lResult.ResultType == eCommandResultType.ok)
                    {
                        lContext.TraceInformation("uid copy success");
                        return(lHook.Feedback);
                    }

                    if (lResult.ResultType == eCommandResultType.no)
                    {
                        throw new cUnsuccessfulCompletionException(lResult.ResponseText, 0, lContext);
                    }
                    throw new cProtocolErrorException(lResult, 0, lContext);
                }
            }
Example #8
0
            private async Task ZFetchCacheItemsAsync(cMethodControl pMC, cMessageHandleList pMessageHandles, cMessageCacheItems pItems, cTrace.cContext pParentContext)
            {
                var lContext = pParentContext.NewMethod(nameof(cSession), nameof(ZFetchCacheItemsAsync), pMC, pMessageHandles, pItems);

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

                if (pMessageHandles == null)
                {
                    throw new ArgumentNullException(nameof(pMessageHandles));
                }
                if (pItems == null)
                {
                    throw new ArgumentNullException(nameof(pItems));
                }

                if (pMessageHandles.Count == 0)
                {
                    throw new ArgumentOutOfRangeException(nameof(pMessageHandles));
                }
                if (pItems.IsEmpty)
                {
                    throw new ArgumentOutOfRangeException(nameof(pItems));
                }

                using (var lBuilder = new cCommandDetailsBuilder())
                {
                    lBuilder.Add(await mSelectExclusiveAccess.GetBlockAsync(pMC, lContext).ConfigureAwait(false)); // block select

                    cSelectedMailbox lSelectedMailbox = mMailboxCache.CheckInSelectedMailbox(pMessageHandles);

                    lBuilder.Add(await mPipeline.GetIdleBlockTokenAsync(pMC, lContext).ConfigureAwait(false)); // stop the pipeline from iding (idle is msnunsafe)
                    lBuilder.Add(await mMSNUnsafeBlock.GetTokenAsync(pMC, lContext).ConfigureAwait(false));    // wait until all commands that are msnunsafe complete, block all commands that are msnunsafe

                    // uidvalidity must be captured before the handles are resolved
                    lBuilder.AddUIDValidity(lSelectedMailbox.MessageCache.UIDValidity);

                    // resolve MSNs

                    cUIntList lMSNs = new cUIntList();

                    foreach (var lMessageHandle in pMessageHandles)
                    {
                        var lMSN = lSelectedMailbox.GetMSN(lMessageHandle);
                        if (lMSN != 0)
                        {
                            lMSNs.Add(lMSN);
                        }
                    }

                    if (lMSNs.Count == 0)
                    {
                        return;
                    }

                    // build command

                    lBuilder.Add(kFetchCommandPartFetchSpace, new cTextCommandPart(cSequenceSet.FromUInts(lMSNs)), cCommandPart.Space);
                    lBuilder.Add(pItems, lSelectedMailbox.MessageCache.NoModSeq);

                    // go

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

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

                    if (lResult.ResultType == eCommandResultType.no)
                    {
                        throw new cUnsuccessfulCompletionException(lResult.ResponseText, 0, lContext);
                    }
                    throw new cProtocolErrorException(lResult, 0, lContext);
                }
            }
 public cCommandHookBaseSearch(cSelectedMailbox pSelectedMailbox)
 {
     mSelectedMailbox = pSelectedMailbox ?? throw new ArgumentNullException(nameof(pSelectedMailbox));
 }
Example #10
0
            private async Task <cBody> ZFetchBodyAsync(cMethodControl pMC, iMessageHandle pMessageHandle, bool pBinary, cSection pSection, uint pOrigin, uint pLength, cTrace.cContext pParentContext)
            {
                // the caller must have checked that the binary option is compatible with the section (e.g. if binary is true the section can't specify a textpart)
                //  the length must be greater than zero

                var lContext = pParentContext.NewMethod(nameof(cSession), nameof(ZFetchBodyAsync), pMC, pMessageHandle, pBinary, pSection, pOrigin, pLength);

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

                if (pMessageHandle == null)
                {
                    throw new ArgumentNullException(nameof(pMessageHandle));
                }
                if (pSection == null)
                {
                    throw new ArgumentNullException(nameof(pSection));
                }

                using (var lBuilder = new cCommandDetailsBuilder())
                {
                    lBuilder.Add(await mSelectExclusiveAccess.GetBlockAsync(pMC, lContext).ConfigureAwait(false)); // block select

                    cSelectedMailbox lSelectedMailbox = mMailboxCache.CheckInSelectedMailbox(pMessageHandle);

                    lBuilder.Add(await mPipeline.GetIdleBlockTokenAsync(pMC, lContext).ConfigureAwait(false)); // stop the pipeline from iding (idle is msnunsafe)
                    lBuilder.Add(await mMSNUnsafeBlock.GetTokenAsync(pMC, lContext).ConfigureAwait(false));    // wait until all commands that are msnunsafe complete, block all commands that are msnunsafe

                    // uidvalidity must be set before the handle is resolved
                    lBuilder.AddUIDValidity(lSelectedMailbox.MessageCache.UIDValidity);

                    // resolve the MSN
                    uint lMSN = lSelectedMailbox.GetMSN(pMessageHandle);

                    if (lMSN == 0)
                    {
                        if (pMessageHandle.Expunged)
                        {
                            throw new cMessageExpungedException(pMessageHandle);
                        }
                        throw new ArgumentOutOfRangeException(nameof(pMessageHandle));
                    }

                    // build command

                    lBuilder.Add(kFetchCommandPartFetchSpace, new cTextCommandPart(lMSN));

                    if (pBinary)
                    {
                        lBuilder.Add(kFetchCommandPartSpaceBinaryPeekLBracket);
                    }
                    else
                    {
                        lBuilder.Add(kFetchCommandPartSpaceBodyPeekLBracket);
                    }

                    lBuilder.Add(pSection, pOrigin, pLength);

                    // hook
                    var lHook = new cCommandHookFetchBodyMSN(pBinary, pSection, pOrigin, lMSN);
                    lBuilder.Add(lHook);

                    // go

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

                    if (lResult.ResultType == eCommandResultType.ok)
                    {
                        lContext.TraceInformation("fetch body success");
                        if (lHook.Body == null)
                        {
                            throw new cRequestedDataNotReturnedException(lContext);
                        }
                        return(lHook.Body);
                    }

                    if (lHook.Body != null)
                    {
                        lContext.TraceError("received body on a failed fetch body");
                    }

                    fCapabilities lTryIgnoring;
                    if (pBinary)
                    {
                        lTryIgnoring = fCapabilities.binary;
                    }
                    else
                    {
                        lTryIgnoring = 0;
                    }

                    if (lResult.ResultType == eCommandResultType.no)
                    {
                        throw new cUnsuccessfulCompletionException(lResult.ResponseText, lTryIgnoring, lContext);
                    }
                    throw new cProtocolErrorException(lResult, lTryIgnoring, lContext);
                }
            }
Example #11
0
            private async Task ZUIDFetchCacheItemsAsync(cMethodControl pMC, iMailboxHandle pMailboxHandle, uint pUIDValidity, cUIntList pUIDs, cMessageCacheItems pItems, cTrace.cContext pParentContext)
            {
                // note that this will fail if the UIDValidity has changed (this is different to the behaviour of standard fetch)
                // note that the caller should have checked that pAttributes contains some attributes to fetch

                var lContext = pParentContext.NewMethod(nameof(cSession), nameof(ZUIDFetchCacheItemsAsync), pMC, pMailboxHandle, pUIDValidity, pUIDs, pItems);

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

                if (pMailboxHandle == null)
                {
                    throw new ArgumentNullException(nameof(pMailboxHandle));
                }
                if (pUIDs == null)
                {
                    throw new ArgumentNullException(nameof(pUIDs));
                }
                if (pItems == null)
                {
                    throw new ArgumentNullException(nameof(pItems));
                }

                if (pUIDs.Count == 0)
                {
                    throw new ArgumentOutOfRangeException(nameof(pUIDs));
                }
                if (pItems.IsEmpty)
                {
                    throw new ArgumentOutOfRangeException(nameof(pItems));
                }

                using (var lBuilder = new cCommandDetailsBuilder())
                {
                    lBuilder.Add(await mSelectExclusiveAccess.GetBlockAsync(pMC, lContext).ConfigureAwait(false)); // block select

                    cSelectedMailbox lSelectedMailbox = mMailboxCache.CheckIsSelectedMailbox(pMailboxHandle, pUIDValidity);

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

                    lBuilder.AddUIDValidity(pUIDValidity);                                                  // the command is sensitive to UIDValidity changes

                    lBuilder.Add(kFetchCommandPartUIDFetchSpace, new cTextCommandPart(cSequenceSet.FromUInts(pUIDs)), cCommandPart.Space);
                    lBuilder.Add(pItems, lSelectedMailbox.MessageCache.NoModSeq);

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

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

                    if (lResult.ResultType == eCommandResultType.no)
                    {
                        throw new cUnsuccessfulCompletionException(lResult.ResponseText, 0, lContext);
                    }
                    throw new cProtocolErrorException(lResult, 0, lContext);
                }
            }
Example #12
0
 public cSetUnseenCountCommandHook(cSelectedMailbox pSelectedMailbox) : base(pSelectedMailbox)
 {
 }
Example #13
0
 public cCommandHookStore(cStoreFeedbackCollector pFeedbackCollector, cUIDStoreFeedback pUIDStoreFeedback, cSelectedMailbox pSelectedMailbox)
 {
     mFeedbackCollector = pFeedbackCollector ?? throw new ArgumentNullException(nameof(pFeedbackCollector));
     mUIDStoreFeedback  = pUIDStoreFeedback;
     mSelectedMailbox   = pSelectedMailbox ?? throw new ArgumentNullException(nameof(pSelectedMailbox));
 }
Example #14
0
            private async Task <cCopyFeedback> ZCopyAsync(cMethodControl pMC, cMessageHandleList pSourceMessageHandles, cMailboxCacheItem pDestinationItem, cTrace.cContext pParentContext)
            {
                var lContext = pParentContext.NewMethod(nameof(cSession), nameof(ZCopyAsync), pMC, pSourceMessageHandles, pDestinationItem);

                using (var lBuilder = new cCommandDetailsBuilder())
                {
                    lBuilder.Add(await mSelectExclusiveAccess.GetBlockAsync(pMC, lContext).ConfigureAwait(false)); // block select

                    cSelectedMailbox lSelectedMailbox = mMailboxCache.CheckInSelectedMailbox(pSourceMessageHandles);

                    lBuilder.Add(await mPipeline.GetIdleBlockTokenAsync(pMC, lContext).ConfigureAwait(false)); // stop the pipeline from iding (idle is msnunsafe)
                    lBuilder.Add(await mMSNUnsafeBlock.GetTokenAsync(pMC, lContext).ConfigureAwait(false));    // wait until all commands that are msnunsafe complete, block all commands that are msnunsafe

                    // uidvalidity must be captured before the handles are resolved
                    var lUIDValidity = lSelectedMailbox.MessageCache.UIDValidity;
                    lBuilder.AddUIDValidity(lUIDValidity);

                    // resolve the handles to MSNs

                    cUIntList lMSNs = new cUIntList();

                    foreach (var lMessageHandle in pSourceMessageHandles)
                    {
                        var lMSN = lSelectedMailbox.GetMSN(lMessageHandle);

                        if (lMSN == 0)
                        {
                            if (lMessageHandle.Expunged)
                            {
                                throw new cMessageExpungedException(lMessageHandle);
                            }
                            else
                            {
                                throw new ArgumentOutOfRangeException(nameof(pSourceMessageHandles));
                            }
                        }

                        lMSNs.Add(lMSN);
                    }

                    // build the command
                    lBuilder.Add(kCopyCommandPart, new cTextCommandPart(cSequenceSet.FromUInts(lMSNs)), cCommandPart.Space, pDestinationItem.MailboxNameCommandPart);

                    // add the hook
                    var lHook = new cCommandHookCopy(lUIDValidity);
                    lBuilder.Add(lHook);

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

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

                    if (lResult.ResultType == eCommandResultType.no)
                    {
                        throw new cUnsuccessfulCompletionException(lResult.ResponseText, 0, lContext);
                    }
                    throw new cProtocolErrorException(lResult, 0, lContext);
                }
            }
                private readonly bool mSort; // if the results are coming sorted this should be set to true

                public cCommandHookSearchExtended(cCommandTag pCommandTag, cSelectedMailbox pSelectedMailbox, bool pSort) : base(pCommandTag, pSelectedMailbox)
                {
                    mSort = pSort;
                }
 public cSetUnseenCountExtendedCommandHook(cCommandTag pCommandTag, cSelectedMailbox pSelectedMailbox) : base(pCommandTag, pSelectedMailbox)
 {
 }
Example #17
0
            private async Task ZStoreAsync(cMethodControl pMC, cStoreFeedback pFeedback, eStoreOperation pOperation, cStorableFlags pFlags, ulong?pIfUnchangedSinceModSeq, cTrace.cContext pParentContext)
            {
                var lContext = pParentContext.NewMethod(nameof(cSession), nameof(ZStoreAsync), pMC, pFeedback, pOperation, pFlags, pIfUnchangedSinceModSeq);

                // no validation ... all the parameters have been validated already by the cSession by the time we get here

                using (var lBuilder = new cCommandDetailsBuilder())
                {
                    lBuilder.Add(await mSelectExclusiveAccess.GetBlockAsync(pMC, lContext).ConfigureAwait(false)); // block select

                    cSelectedMailbox lSelectedMailbox = mMailboxCache.CheckInSelectedMailbox(pFeedback);
                    if (!lSelectedMailbox.SelectedForUpdate)
                    {
                        throw new InvalidOperationException(kInvalidOperationExceptionMessage.NotSelectedForUpdate);
                    }

                    lBuilder.Add(await mPipeline.GetIdleBlockTokenAsync(pMC, lContext).ConfigureAwait(false)); // stop the pipeline from iding (idle is msnunsafe)
                    lBuilder.Add(await mMSNUnsafeBlock.GetTokenAsync(pMC, lContext).ConfigureAwait(false));    // wait until all commands that are msnunsafe complete, block all commands that are msnunsafe

                    // uidvalidity must be captured before the handles are resolved
                    lBuilder.AddUIDValidity(lSelectedMailbox.MessageCache.UIDValidity);

                    // collector
                    cStoreFeedbackCollector lFeedbackCollector = new cStoreFeedbackCollector();

                    // resolve the handles to MSNs
                    foreach (var lItem in pFeedback)
                    {
                        var lMSN = lSelectedMailbox.GetMSN(lItem.MessageHandle);
                        if (lMSN != 0)
                        {
                            lFeedbackCollector.Add(lMSN, lItem);
                        }
                    }

                    // if no handles were resolved, we are done
                    if (lFeedbackCollector.Count == 0)
                    {
                        return;
                    }

                    // build the command
                    lBuilder.Add(kStoreCommandPartStoreSpace, new cTextCommandPart(cSequenceSet.FromUInts(lFeedbackCollector.UInts)), cCommandPart.Space);
                    if (pIfUnchangedSinceModSeq != null)
                    {
                        lBuilder.Add(kStoreCommandPartLParenUnchangedSinceSpace, new cTextCommandPart(pIfUnchangedSinceModSeq.Value), kStoreCommandPartRParenSpace);
                    }
                    lBuilder.Add(pOperation, pFlags);

                    // add the hook
                    var lHook = new cCommandHookStore(lFeedbackCollector, null, lSelectedMailbox);
                    lBuilder.Add(lHook);

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

                    // NOTE: updates may have been done on both OK and NO responses (see rfc 2180/ 7162) so we can't throw on a NO for this command ... NO indicates that some (or all) of the messages have pending deletes

                    // throw on a bad
                    if (lResult.ResultType == eCommandResultType.bad)
                    {
                        fCapabilities lTryIgnoring;
                        if (pIfUnchangedSinceModSeq == null)
                        {
                            lTryIgnoring = 0;
                        }
                        else
                        {
                            lTryIgnoring = fCapabilities.condstore;
                        }
                        throw new cProtocolErrorException(lResult, lTryIgnoring, lContext);
                    }

                    if (lResult.ResultType == eCommandResultType.ok)
                    {
                        lContext.TraceInformation("store success");
                    }
                    else
                    {
                        lContext.TraceInformation("store possible partial success");
                    }
                }
            }
Example #18
0
 public cSortCommandHook(cSelectedMailbox pSelectedMailbox)
 {
     mSelectedMailbox = pSelectedMailbox ?? throw new ArgumentNullException(nameof(pSelectedMailbox));
 }
 public cCommandHookBaseSearchExtended(cCommandTag pCommandTag, cSelectedMailbox pSelectedMailbox)
 {
     mCommandTag      = pCommandTag ?? throw new ArgumentNullException(nameof(pCommandTag));
     mSelectedMailbox = pSelectedMailbox ?? throw new ArgumentNullException(nameof(pSelectedMailbox));
 }
Example #20
0
            public async Task <cMessageHandleList> UIDFetchCacheItemsAsync(cMethodControl pMC, iMailboxHandle pMailboxHandle, cUIDList pUIDs, cMessageCacheItems pItems, cProgress pProgress, cTrace.cContext pParentContext)
            {
                var lContext = pParentContext.NewMethod(nameof(cSession), nameof(UIDFetchCacheItemsAsync), pMC, pMailboxHandle, pUIDs, pItems);

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

                if (pMailboxHandle == null)
                {
                    throw new ArgumentNullException(nameof(pMailboxHandle));
                }
                if (pUIDs == null)
                {
                    throw new ArgumentNullException(nameof(pUIDs));
                }
                if (pItems == null)
                {
                    throw new ArgumentNullException(nameof(pItems));
                }
                if (pProgress == null)
                {
                    throw new ArgumentNullException(nameof(pProgress));
                }

                if (pUIDs.Count == 0)
                {
                    throw new ArgumentOutOfRangeException(nameof(pUIDs));
                }
                if (pItems.IsEmpty)
                {
                    throw new ArgumentOutOfRangeException(nameof(pItems));
                }

                uint lUIDValidity = pUIDs[0].UIDValidity;

                mMailboxCache.CheckIsSelectedMailbox(pMailboxHandle, lUIDValidity); // to be repeated inside the select lock

                // split the list into those messages I have handles for and those I dont
                /////////////////////////////////////////////////////////////////////////

                cMessageHandleList lMessageHandles = new cMessageHandleList();
                cUIDList           lUIDs           = new cUIDList();

                // check the selected mailbox and resolve uids -> handles whilst blocking select exclusive access
                //
                using (var lBlock = await mSelectExclusiveAccess.GetBlockAsync(pMC, lContext).ConfigureAwait(false))
                {
                    cSelectedMailbox lSelectedMailbox = mMailboxCache.CheckIsSelectedMailbox(pMailboxHandle, lUIDValidity);

                    foreach (var lUID in pUIDs)
                    {
                        var lMessageHandle = lSelectedMailbox.GetHandle(lUID);
                        if (lMessageHandle == null)
                        {
                            lUIDs.Add(lUID);                         // don't have a handle
                        }
                        else if (lMessageHandle.ContainsNone(pItems))
                        {
                            lUIDs.Add(lUID);                                           // have to get all the attributes, may as well fetch them with the ones where I might need all the attributes
                        }
                        else
                        {
                            lMessageHandles.Add(lMessageHandle);
                        }
                    }
                }

                // for the messages I have handles for, fetch the missing attributes
                ////////////////////////////////////////////////////////////////////

                if (lMessageHandles.Count > 0)
                {
                    // split the handles into groups based on what attributes need to be retrieved, for each group do the retrieval
                    foreach (var lGroup in ZFetchCacheItemsGroups(lMessageHandles, pItems))
                    {
                        await ZFetchCacheItemsAsync(pMC, lGroup, pProgress, lContext).ConfigureAwait(false);
                    }
                }

                // for the messages only identified by UID or where I have to get all the items
                ////////////////////////////////////////////////////////////////////////////////////

                if (lUIDs.Count > 0)
                {
                    await ZUIDFetchCacheItemsAsync(pMC, pMailboxHandle, lUIDs, pItems, pProgress, lContext).ConfigureAwait(false);

                    // resolve uids -> handles whilst blocking select exclusive access
                    //
                    using (var lBlock = await mSelectExclusiveAccess.GetBlockAsync(pMC, lContext).ConfigureAwait(false))
                    {
                        cSelectedMailbox lSelectedMailbox = mMailboxCache.CheckIsSelectedMailbox(pMailboxHandle, lUIDValidity);

                        foreach (var lUID in lUIDs)
                        {
                            var lMessageHandle = lSelectedMailbox.GetHandle(lUID);
                            if (lMessageHandle != null)
                            {
                                lMessageHandles.Add(lMessageHandle);
                            }
                        }
                    }
                }

                return(lMessageHandles);
            }
Example #21
0
            public async Task FetchBinarySizeAsync(cMethodControl pMC, iMessageHandle pMessageHandle, string pPart, cTrace.cContext pParentContext)
            {
                var lContext = pParentContext.NewMethod(nameof(cSession), nameof(FetchBinarySizeAsync), pMC, pMessageHandle, pPart);

                if (mDisposed)
                {
                    throw new ObjectDisposedException(nameof(cSession));
                }
                if (_ConnectionState != eConnectionState.selected)
                {
                    throw new InvalidOperationException(kInvalidOperationExceptionMessage.NotSelected);
                }
                if (pMessageHandle == null)
                {
                    throw new ArgumentNullException(nameof(pMessageHandle));
                }
                if (pPart == null)
                {
                    throw new ArgumentNullException(nameof(pPart));
                }

                if (!cCommandPartFactory.TryAsAtom(pPart, out var lPart))
                {
                    throw new ArgumentOutOfRangeException(nameof(pPart));
                }

                using (var lBuilder = new cCommandDetailsBuilder())
                {
                    lBuilder.Add(await mSelectExclusiveAccess.GetBlockAsync(pMC, lContext).ConfigureAwait(false)); // block select

                    cSelectedMailbox lSelectedMailbox = mMailboxCache.CheckInSelectedMailbox(pMessageHandle);

                    lBuilder.Add(await mPipeline.GetIdleBlockTokenAsync(pMC, lContext).ConfigureAwait(false)); // stop the pipeline from iding (idle is msnunsafe)
                    lBuilder.Add(await mMSNUnsafeBlock.GetTokenAsync(pMC, lContext).ConfigureAwait(false));    // wait until all commands that are msnunsafe complete, block all commands that are msnunsafe

                    // uidvalidity must be captured before the handles are resolved
                    lBuilder.AddUIDValidity(lSelectedMailbox.MessageCache.UIDValidity);

                    // resolve the MSN
                    uint lMSN = lSelectedMailbox.GetMSN(pMessageHandle);

                    if (lMSN == 0)
                    {
                        if (pMessageHandle.Expunged)
                        {
                            throw new cMessageExpungedException(pMessageHandle);
                        }
                        else
                        {
                            throw new ArgumentOutOfRangeException(nameof(pMessageHandle));
                        }
                    }

                    // build command
                    lBuilder.Add(kFetchCommandPartFetchSpace, new cTextCommandPart(lMSN), kFetchCommandPartSpaceBinarySizeLBracket, lPart, cCommandPart.RBracket);

                    // go

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

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

                    if (lResult.ResultType == eCommandResultType.no)
                    {
                        throw new cUnsuccessfulCompletionException(lResult.ResponseText, fCapabilities.binary, lContext);
                    }
                    throw new cProtocolErrorException(lResult, fCapabilities.binary, lContext);
                }
            }
Example #22
0
 public cSearchCommandHook(cSelectedMailbox pSelectedMailbox) : base(pSelectedMailbox)
 {
 }