зеркало из https://github.com/mozilla/gecko-dev.git
fix bugs having to do with imap msg copying failing 46876 46914 etc r=mscott
This commit is contained in:
Родитель
bbd930f258
Коммит
72afa1622a
|
@ -2765,61 +2765,72 @@ nsresult nsImapMailFolder::GetMessageHeader(nsMsgKey key, nsIMsgDBHdr ** aMsgHdr
|
|||
NS_IMETHODIMP
|
||||
nsImapMailFolder::OnlineCopyCompleted(nsIImapProtocol *aProtocol, ImapOnlineCopyState aCopyState)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aProtocol);
|
||||
NS_ENSURE_ARG_POINTER(aProtocol);
|
||||
|
||||
nsresult rv;
|
||||
nsresult rv;
|
||||
if (aCopyState == ImapOnlineCopyStateType::kSuccessfulCopy)
|
||||
{
|
||||
|
||||
nsCOMPtr <nsIImapUrl> imapUrl;
|
||||
rv = aProtocol->GetRunningImapURL(getter_AddRefs(imapUrl));
|
||||
if (NS_FAILED(rv) || !imapUrl) return NS_ERROR_FAILURE;
|
||||
|
||||
nsImapAction action;
|
||||
rv = imapUrl->GetImapAction(&action);
|
||||
nsImapAction action;
|
||||
rv = imapUrl->GetImapAction(&action);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
if (action == nsIImapUrl::nsImapOnlineToOfflineMove)
|
||||
{
|
||||
nsXPIDLCString messageIds;
|
||||
rv = imapUrl->CreateListOfMessageIdsString(getter_Copies(messageIds));
|
||||
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
nsCOMPtr<nsIEventQueue> queue;
|
||||
// get the Event Queue for this thread...
|
||||
NS_WITH_SERVICE(nsIEventQueueService, pEventQService,
|
||||
kEventQueueServiceCID, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = pEventQService->GetThreadEventQueue(NS_CURRENT_THREAD,
|
||||
getter_AddRefs(queue));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
if (action == nsIImapUrl::nsImapOnlineToOfflineMove)
|
||||
{
|
||||
nsXPIDLCString messageIds;
|
||||
rv = imapUrl->CreateListOfMessageIdsString(getter_Copies(messageIds));
|
||||
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
nsCOMPtr<nsIEventQueue> queue;
|
||||
// get the Event Queue for this thread...
|
||||
NS_WITH_SERVICE(nsIEventQueueService, pEventQService,
|
||||
kEventQueueServiceCID, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = pEventQService->GetThreadEventQueue(NS_CURRENT_THREAD,
|
||||
getter_AddRefs(queue));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
NS_WITH_SERVICE(nsIImapService, imapService, kCImapService, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = imapService->AddMessageFlags(queue, this, nsnull, nsnull,
|
||||
messageIds,
|
||||
kImapMsgDeletedFlag,
|
||||
PR_TRUE);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
nsMsgKeyArray affectedMessages;
|
||||
char *keyTokenString = nsCRT::strdup(messageIds);
|
||||
ParseUidString(keyTokenString, affectedMessages);
|
||||
if (mDatabase)
|
||||
mDatabase->DeleteMessages(&affectedMessages,NULL);
|
||||
nsCRT::free(keyTokenString);
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
/* unhandled action */
|
||||
else return NS_ERROR_FAILURE;
|
||||
NS_WITH_SERVICE(nsIImapService, imapService, kCImapService, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = imapService->AddMessageFlags(queue, this, nsnull, nsnull,
|
||||
messageIds,
|
||||
kImapMsgDeletedFlag,
|
||||
PR_TRUE);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
nsMsgKeyArray affectedMessages;
|
||||
char *keyTokenString = nsCRT::strdup(messageIds);
|
||||
ParseUidString(keyTokenString, affectedMessages);
|
||||
if (mDatabase)
|
||||
mDatabase->DeleteMessages(&affectedMessages,NULL);
|
||||
nsCRT::free(keyTokenString);
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
/* unhandled copystate */
|
||||
/* unhandled action */
|
||||
else return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return rv;
|
||||
/* unhandled copystate */
|
||||
else
|
||||
{
|
||||
// whoops, this is the wrong folder - should use the source folder
|
||||
if (m_copyState)
|
||||
{
|
||||
nsCOMPtr<nsIMsgFolder> srcFolder;
|
||||
srcFolder = do_QueryInterface(m_copyState->m_srcSupport, &rv);
|
||||
if (srcFolder)
|
||||
srcFolder->NotifyFolderEvent(mDeleteOrMoveMsgCompletedAtom);
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -3115,7 +3126,7 @@ nsImapMailFolder::OnStopRunningUrl(nsIURI *aUrl, nsresult aExitCode)
|
|||
UpdateFolder(aWindow);
|
||||
else
|
||||
UpdatePendingCounts(PR_TRUE, PR_FALSE);
|
||||
if (m_copyState->m_isMove)
|
||||
if (m_copyState->m_isMove && !m_copyState->m_isCrossServerOp)
|
||||
{
|
||||
nsCOMPtr<nsIMsgFolder> srcFolder;
|
||||
srcFolder =
|
||||
|
@ -3777,11 +3788,12 @@ nsImapMailFolder::CreateDirectoryForFolder(nsFileSpec &path) //** dup
|
|||
|
||||
return rv;
|
||||
}
|
||||
// used when copying from local mail folder (or other imap server?)
|
||||
// used when copying from local mail folder, or other imap server)
|
||||
nsresult
|
||||
nsImapMailFolder::CopyMessagesWithStream(nsIMsgFolder* srcFolder,
|
||||
nsISupportsArray* messages,
|
||||
PRBool isMove,
|
||||
PRBool isCrossServerOp,
|
||||
nsIMsgWindow *msgWindow,
|
||||
nsIMsgCopyServiceListener* listener)
|
||||
{
|
||||
|
@ -3794,6 +3806,7 @@ nsImapMailFolder::CopyMessagesWithStream(nsIMsgFolder* srcFolder,
|
|||
if(NS_FAILED(rv)) return rv;
|
||||
|
||||
m_copyState->m_streamCopy = PR_TRUE;
|
||||
m_copyState->m_isCrossServerOp = isCrossServerOp;
|
||||
|
||||
// ** jt - needs to create server to server move/copy undo msg txn
|
||||
nsCString messageIds;
|
||||
|
@ -3883,7 +3896,7 @@ nsImapMailFolder::CopyMessages(nsIMsgFolder* srcFolder,
|
|||
|
||||
// if the folders aren't on the same server, do a stream base copy
|
||||
if (!sameServer) {
|
||||
rv = CopyMessagesWithStream(srcFolder, messages, isMove, msgWindow, listener);
|
||||
rv = CopyMessagesWithStream(srcFolder, messages, isMove, PR_TRUE, msgWindow, listener);
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
@ -4040,7 +4053,7 @@ nsImapMailFolder::CopyStreamMessage(nsIMessage* message,
|
|||
return NS_ERROR_NO_INTERFACE;
|
||||
|
||||
rv = m_copyState->m_msgService->CopyMessage(uri, streamListener,
|
||||
isMove, nsnull, &url);
|
||||
isMove && !m_copyState->m_isCrossServerOp, nsnull, &url);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
@ -4048,7 +4061,7 @@ nsImapMailFolder::CopyStreamMessage(nsIMessage* message,
|
|||
nsImapMailCopyState::nsImapMailCopyState() : m_msgService(nsnull),
|
||||
m_isMove(PR_FALSE), m_selectedState(PR_FALSE), m_curIndex(0),
|
||||
m_totalCount(0), m_streamCopy(PR_FALSE), m_dataBuffer(nsnull),
|
||||
m_leftOver(0)
|
||||
m_leftOver(0), m_isCrossServerOp(PR_FALSE)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
}
|
||||
|
@ -4081,7 +4094,6 @@ nsImapMailCopyState::~nsImapMailCopyState()
|
|||
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS1(nsImapMailCopyState, nsImapMailCopyState)
|
||||
|
||||
|
||||
nsresult
|
||||
nsImapMailFolder::InitCopyState(nsISupports* srcSupport,
|
||||
nsISupportsArray* messages,
|
||||
|
@ -4092,7 +4104,7 @@ nsImapMailFolder::InitCopyState(nsISupports* srcSupport,
|
|||
nsresult rv = NS_OK;
|
||||
|
||||
if (!srcSupport || !messages) return NS_ERROR_NULL_POINTER;
|
||||
// NS_ASSERTION(!m_copyState, "move/copy already in progress");
|
||||
NS_ASSERTION(!m_copyState, "move/copy already in progress");
|
||||
if (m_copyState) return NS_ERROR_FAILURE;
|
||||
|
||||
nsImapMailCopyState* copyState = new nsImapMailCopyState();
|
||||
|
|
|
@ -82,6 +82,7 @@ public:
|
|||
// be Nntp, Mailbox, or Imap
|
||||
PRBool m_isMove; // is a move
|
||||
PRBool m_selectedState; // needs to be in selected state; append msg
|
||||
PRBool m_isCrossServerOp; // are we copying between imap servers?
|
||||
PRUint32 m_curIndex; // message index to the message array which we are
|
||||
// copying
|
||||
PRUint32 m_totalCount;// total count of messages we have to do
|
||||
|
@ -295,6 +296,7 @@ protected:
|
|||
nsresult CopyMessagesWithStream(nsIMsgFolder* srcFolder,
|
||||
nsISupportsArray* messages,
|
||||
PRBool isMove,
|
||||
PRBool isCrossServerOp,
|
||||
nsIMsgWindow *msgWindow,
|
||||
nsIMsgCopyServiceListener* listener);
|
||||
nsresult CopyStreamMessage(nsIMessage* message, nsIMsgFolder* dstFolder,
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include "nsImapProxyEvent.h"
|
||||
#include "nsIMAPHostSessionList.h"
|
||||
#include "nsIMAPBodyShell.h"
|
||||
#include "nsImapMailFolder.h"
|
||||
#include "nsImapServerResponseParser.h"
|
||||
#include "nspr.h"
|
||||
#include "plbase64.h"
|
||||
|
@ -76,7 +77,6 @@ PRLogModuleInfo *IMAP;
|
|||
#endif
|
||||
|
||||
#define ONE_SECOND ((PRUint32)1000) // one second
|
||||
#define FOUR_K ((PRUint32)4096)
|
||||
|
||||
const char *kImapTrashFolderName = "Trash"; // **** needs to be localized ****
|
||||
|
||||
|
@ -3285,43 +3285,46 @@ PRBool nsImapProtocol::CheckNewMail()
|
|||
// log info including current state...
|
||||
void nsImapProtocol::Log(const char *logSubName, const char *extraInfo, const char *logData)
|
||||
{
|
||||
static char *nonAuthStateName = "NA";
|
||||
static char *authStateName = "A";
|
||||
static char *selectedStateName = "S";
|
||||
// static char *waitingStateName = "W";
|
||||
char *stateName = NULL;
|
||||
const char *hostName = GetImapHostName(); // initilize to empty string
|
||||
switch (GetServerStateParser().GetIMAPstate())
|
||||
if (PR_LOG_TEST(IMAP, PR_LOG_ALWAYS))
|
||||
{
|
||||
case nsImapServerResponseParser::kFolderSelected:
|
||||
static char *nonAuthStateName = "NA";
|
||||
static char *authStateName = "A";
|
||||
static char *selectedStateName = "S";
|
||||
// static char *waitingStateName = "W";
|
||||
char *stateName = NULL;
|
||||
const char *hostName = GetImapHostName(); // initilize to empty string
|
||||
switch (GetServerStateParser().GetIMAPstate())
|
||||
{
|
||||
case nsImapServerResponseParser::kFolderSelected:
|
||||
if (m_runningUrl)
|
||||
{
|
||||
if (extraInfo)
|
||||
PR_LOG(IMAP, PR_LOG_ALWAYS, ("%s:%s-%s:%s:%s: %s", hostName,selectedStateName, GetServerStateParser().GetSelectedMailboxName(), logSubName, extraInfo, logData));
|
||||
else
|
||||
PR_LOG(IMAP, PR_LOG_ALWAYS, ("%s:%s-%s:%s: %s", hostName,selectedStateName, GetServerStateParser().GetSelectedMailboxName(), logSubName, logData));
|
||||
}
|
||||
return;
|
||||
break;
|
||||
case nsImapServerResponseParser::kNonAuthenticated:
|
||||
stateName = nonAuthStateName;
|
||||
break;
|
||||
case nsImapServerResponseParser::kAuthenticated:
|
||||
stateName = authStateName;
|
||||
break;
|
||||
#if 0 // *** this isn't a server state; its a status ***
|
||||
case nsImapServerResponseParser::kWaitingForMoreClientInput:
|
||||
stateName = waitingStateName;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (m_runningUrl)
|
||||
{
|
||||
if (extraInfo)
|
||||
PR_LOG(IMAP, PR_LOG_ALWAYS, ("%s:%s-%s:%s:%s: %s", hostName,selectedStateName, GetServerStateParser().GetSelectedMailboxName(), logSubName, extraInfo, logData));
|
||||
PR_LOG(IMAP, PR_LOG_ALWAYS, ("%s:%s:%s:%s: %s", hostName,stateName,logSubName,extraInfo,logData));
|
||||
else
|
||||
PR_LOG(IMAP, PR_LOG_ALWAYS, ("%s:%s-%s:%s: %s", hostName,selectedStateName, GetServerStateParser().GetSelectedMailboxName(), logSubName, logData));
|
||||
PR_LOG(IMAP, PR_LOG_ALWAYS, ("%s:%s:%s: %s",hostName,stateName,logSubName,logData));
|
||||
}
|
||||
return;
|
||||
break;
|
||||
case nsImapServerResponseParser::kNonAuthenticated:
|
||||
stateName = nonAuthStateName;
|
||||
break;
|
||||
case nsImapServerResponseParser::kAuthenticated:
|
||||
stateName = authStateName;
|
||||
break;
|
||||
#if 0 // *** this isn't a server state; its a status ***
|
||||
case nsImapServerResponseParser::kWaitingForMoreClientInput:
|
||||
stateName = waitingStateName;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (m_runningUrl)
|
||||
{
|
||||
if (extraInfo)
|
||||
PR_LOG(IMAP, PR_LOG_ALWAYS, ("%s:%s:%s:%s: %s", hostName,stateName,logSubName,extraInfo,logData));
|
||||
else
|
||||
PR_LOG(IMAP, PR_LOG_ALWAYS, ("%s:%s:%s: %s",hostName,stateName,logSubName,logData));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4204,11 +4207,18 @@ void nsImapProtocol::HandleCurrentUrlError()
|
|||
UpdatedMailboxSpec(notSelectedSpec);
|
||||
}
|
||||
}
|
||||
else if (fCurrentUrl->GetIMAPurlType() == TIMAPUrl::kOfflineToOnlineMove)
|
||||
{
|
||||
OnlineCopyCompleted(this, kFailedCopy);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
// this is to handle a move/copy failing, especially because the user
|
||||
// cancelled the password prompt.
|
||||
nsresult res;
|
||||
res = m_runningUrl->GetImapAction(&m_imapAction);
|
||||
if (m_imapAction == nsIImapUrl::nsImapOfflineToOnlineMove || m_imapAction == nsIImapUrl::nsImapAppendMsgFromFile
|
||||
|| m_imapAction == nsIImapUrl::nsImapAppendDraftFromFile)
|
||||
{
|
||||
if (m_imapMailFolderSink)
|
||||
m_imapMailFolderSink->OnlineCopyCompleted(this, ImapOnlineCopyStateType::kFailedCopy);
|
||||
}
|
||||
}
|
||||
|
||||
void nsImapProtocol::Capability()
|
||||
|
@ -4510,8 +4520,28 @@ void nsImapProtocol::OnAppendMsgFromFile()
|
|||
OnCreateServerSourceFolderPathString();
|
||||
if (mailboxName)
|
||||
{
|
||||
UploadMessageFromFile(fileSpec, mailboxName, kImapMsgSeenFlag);
|
||||
PR_Free( mailboxName );
|
||||
imapMessageFlagsType flagsToSet = kImapMsgSeenFlag;
|
||||
nsCOMPtr <nsISupports> copyState;
|
||||
m_runningUrl->GetCopyState(getter_AddRefs(copyState));
|
||||
if (copyState)
|
||||
{
|
||||
nsCOMPtr<nsImapMailCopyState> mailCopyState = do_QueryInterface(copyState, &rv);
|
||||
if (mailCopyState)
|
||||
{
|
||||
nsCOMPtr <nsIMessage> curMsg = mailCopyState->m_message;
|
||||
PRUint32 flags;
|
||||
|
||||
if (curMsg)
|
||||
{
|
||||
curMsg->GetFlags(&flags);
|
||||
if (! (flags & MSG_FLAG_READ))
|
||||
flagsToSet &= ~MSG_FLAG_READ;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
UploadMessageFromFile(fileSpec, mailboxName, flagsToSet);
|
||||
PR_Free( mailboxName );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -654,32 +654,6 @@ nsImapService::CopyMessage(const char * aSrcMailboxURI, nsIStreamListener *
|
|||
if (moveMessage)
|
||||
imapAction = nsIImapUrl::nsImapOnlineToOfflineMove;
|
||||
rv = FetchMessage(imapUrl,imapAction, folder, imapMessageSink,aURL, streamSupport, msgKey, PR_TRUE);
|
||||
if (NS_SUCCEEDED(rv) && moveMessage)
|
||||
{
|
||||
nsCOMPtr<nsIEventQueue> queue;
|
||||
// get the Event Queue for this thread...
|
||||
NS_WITH_SERVICE(nsIEventQueueService, pEventQService, kEventQueueServiceCID, &rv);
|
||||
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = pEventQService->GetThreadEventQueue(NS_CURRENT_THREAD, getter_AddRefs(queue));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// ** jt -- this really isn't an optimal way of deleting a
|
||||
// list of messages but I don't have a better way at this
|
||||
// moment
|
||||
rv = AddMessageFlags(queue, folder, aUrlListener, nsnull,
|
||||
msgKey,
|
||||
kImapMsgDeletedFlag,
|
||||
PR_TRUE);
|
||||
#if 0
|
||||
// ** jt -- don't think this is needed
|
||||
// ** jt -- force to update the folder
|
||||
if (NS_SUCCEEDED(rv))
|
||||
rv = SelectFolder(queue, folder, aUrlListener, nsnull,
|
||||
nsnull);
|
||||
#endif
|
||||
} // if move message
|
||||
} // if we got an imap message sink
|
||||
} // if we decomposed the imap message
|
||||
return rv;
|
||||
|
|
Загрузка…
Ссылка в новой задаче