fix bugs having to do with imap msg copying failing 46876 46914 etc r=mscott

This commit is contained in:
bienvenu%netscape.com 2000-08-03 01:25:12 +00:00
Родитель bbd930f258
Коммит 72afa1622a
4 изменённых файлов: 133 добавлений и 115 удалений

Просмотреть файл

@ -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;