зеркало из https://github.com/mozilla/gecko-dev.git
bunch of stuff to get message header download working
This commit is contained in:
Родитель
72bc82580f
Коммит
c48b623977
|
@ -133,6 +133,8 @@ public:
|
|||
|
||||
NS_IMETHOD GetImapPartToFetch(char **resultPart) const = 0;
|
||||
NS_IMETHOD AllocateCannonicalPath(const char *serverPath, char onlineDelimiter, char **allocatedPath ) const = 0;
|
||||
|
||||
NS_IMETHOD CreateListOfMessageIdsString(char **result) const = 0;
|
||||
};
|
||||
|
||||
#endif /* nsIImapUrl_h___ */
|
||||
|
|
|
@ -56,6 +56,7 @@ CPP_OBJS= .\$(OBJDIR)\nsImapUrl.obj \
|
|||
EXPORTS= nsImapUrl.h \
|
||||
nsImapProtocol.h \
|
||||
nsImapCore.h \
|
||||
nsImapFlagAndUidState.h \
|
||||
nsImapProxyEvent.h \
|
||||
nsImapHostSessionList.h \
|
||||
nsImapService.h \
|
||||
|
|
|
@ -68,10 +68,8 @@ nsIMAPBodyShell::nsIMAPBodyShell(nsImapProtocol *protocolConnection, const char
|
|||
NS_ASSERTION(buf, "null buffer passed to nsIMAPBodyShell constructor");
|
||||
if (!buf)
|
||||
return;
|
||||
m_UID = PR_smprintf("%ld",UID);
|
||||
NS_ASSERTION(m_UID, "out of memory in body shell");
|
||||
if (!m_UID)
|
||||
return;
|
||||
m_UID = "";
|
||||
m_UID.Append(UID, 10);
|
||||
#ifdef DEBUG_chrisf
|
||||
NS_ASSERTION(folderName);
|
||||
#endif
|
||||
|
@ -95,7 +93,6 @@ nsIMAPBodyShell::~nsIMAPBodyShell()
|
|||
{
|
||||
delete m_message;
|
||||
delete m_prefetchQueue;
|
||||
PR_FREEIF(m_UID);
|
||||
PR_FREEIF(m_folderName);
|
||||
}
|
||||
|
||||
|
@ -1509,7 +1506,7 @@ PRBool nsIMAPBodyShellCache::EjectEntry()
|
|||
|
||||
nsIMAPBodyShell *removedShell = (nsIMAPBodyShell *) (m_shellList->ElementAt(0));
|
||||
m_shellList->RemoveElementAt(0);
|
||||
nsCStringKey hashKey (removedShell->GetUID());
|
||||
nsCStringKey hashKey (removedShell->GetUID().GetBuffer());
|
||||
m_shellHash->Remove(&hashKey);
|
||||
delete removedShell;
|
||||
|
||||
|
@ -1529,11 +1526,11 @@ PRBool nsIMAPBodyShellCache::AddShellToCache(nsIMAPBodyShell *shell)
|
|||
// First, for safety sake, remove any entry with the given UID,
|
||||
// just in case we have a collision between two messages in different
|
||||
// folders with the same UID.
|
||||
nsCStringKey hashKey1(shell->GetUID());
|
||||
nsCStringKey hashKey1(shell->GetUID().GetBuffer());
|
||||
nsIMAPBodyShell *foundShell = (nsIMAPBodyShell *) m_shellHash->Get(&hashKey1);
|
||||
if (foundShell)
|
||||
{
|
||||
nsCStringKey hashKey(foundShell->GetUID());
|
||||
nsCStringKey hashKey(foundShell->GetUID().GetBuffer());
|
||||
m_shellHash->Remove(&hashKey);
|
||||
m_shellList->RemoveElement(foundShell);
|
||||
}
|
||||
|
@ -1541,7 +1538,7 @@ PRBool nsIMAPBodyShellCache::AddShellToCache(nsIMAPBodyShell *shell)
|
|||
// Add the new one to the cache
|
||||
m_shellList->AppendElement(shell);
|
||||
|
||||
nsCStringKey hashKey2 (shell->GetUID());
|
||||
nsCStringKey hashKey2 (shell->GetUID().GetBuffer());
|
||||
m_shellHash->Put(&hashKey2, shell);
|
||||
shell->SetIsCached(TRUE);
|
||||
|
||||
|
@ -1556,12 +1553,12 @@ PRBool nsIMAPBodyShellCache::AddShellToCache(nsIMAPBodyShell *shell)
|
|||
|
||||
}
|
||||
|
||||
nsIMAPBodyShell *nsIMAPBodyShellCache::FindShellForUID(const char *UID, const char *mailboxName)
|
||||
nsIMAPBodyShell *nsIMAPBodyShellCache::FindShellForUID(nsString2 &UID, const char *mailboxName)
|
||||
{
|
||||
if (!UID)
|
||||
return NULL;
|
||||
|
||||
nsCStringKey hashKey(UID);
|
||||
nsCStringKey hashKey(UID.GetBuffer());
|
||||
nsIMAPBodyShell *foundShell = (nsIMAPBodyShell *) m_shellHash->Get(&hashKey);
|
||||
|
||||
if (!foundShell)
|
||||
|
@ -1580,9 +1577,10 @@ nsIMAPBodyShell *nsIMAPBodyShellCache::FindShellForUID(const char *UID, const ch
|
|||
|
||||
nsIMAPBodyShell *nsIMAPBodyShellCache::FindShellForUID(PRUint32 UID, const char *mailboxName)
|
||||
{
|
||||
char *uidString = PR_smprintf("%ld", UID);
|
||||
nsString2 uidString;
|
||||
|
||||
uidString.Append(UID, 10);
|
||||
nsIMAPBodyShell *rv = FindShellForUID(uidString, mailboxName);
|
||||
PR_FREEIF(uidString);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@ nsIMAPBodyShell and associated classes
|
|||
|
||||
#include "nsImapCore.h"
|
||||
#include "nsIMAPGenericParser.h"
|
||||
#include "nsString2.h"
|
||||
|
||||
class nsImapProtocol;
|
||||
|
||||
|
@ -259,7 +260,7 @@ public:
|
|||
nsImapProtocol *GetConnection() { return m_protocolConnection; }
|
||||
PRBool GetPseudoInterrupted();
|
||||
PRBool DeathSignalReceived();
|
||||
const char *GetUID() { return m_UID; }
|
||||
nsString2 &GetUID() { return m_UID; }
|
||||
const char *GetFolderName() { return m_folderName; }
|
||||
char *GetGeneratingPart() { return m_generatingPart; }
|
||||
PRBool IsBeingGenerated() { return m_isBeingGenerated; } // Returns TRUE if this is in the process of being
|
||||
|
@ -276,7 +277,7 @@ protected:
|
|||
|
||||
PRBool m_isValid;
|
||||
nsImapProtocol *m_protocolConnection; // Connection, for filling in parts
|
||||
char *m_UID; // UID of this message
|
||||
nsString2 m_UID; // UID of this message
|
||||
char *m_folderName; // folder that contains this message
|
||||
char *m_generatingPart; // If a specific part is being generated, this is it. Otherwise, NULL.
|
||||
PRBool m_isBeingGenerated; // TRUE if this body shell is in the process of being generated
|
||||
|
@ -308,7 +309,7 @@ public:
|
|||
|
||||
PRBool AddShellToCache(nsIMAPBodyShell *shell); // Adds shell to cache, possibly ejecting
|
||||
// another entry based on scheme in EjectEntry().
|
||||
nsIMAPBodyShell *FindShellForUID(const char *UID, const char *mailboxName); // Looks up a shell in the cache given the message's UID.
|
||||
nsIMAPBodyShell *FindShellForUID(nsString2 &UID, const char *mailboxName); // Looks up a shell in the cache given the message's UID.
|
||||
nsIMAPBodyShell *FindShellForUID(PRUint32 UID, const char *mailboxName); // Looks up a shell in the cache given the message's UID.
|
||||
// Returns the shell if found, NULL if not found.
|
||||
|
||||
|
|
|
@ -619,12 +619,14 @@ NS_IMETHODIMP nsIMAPHostSessionList::AddShellToCacheForHost(const char *hostName
|
|||
|
||||
NS_IMETHODIMP nsIMAPHostSessionList::FindShellInCacheForHost(const char *hostName, const char *userName, const char *mailboxName, const char *UID, nsIMAPBodyShell &shell)
|
||||
{
|
||||
nsString2 uidString = UID;
|
||||
|
||||
PR_EnterMonitor(gCachedHostInfoMonitor);
|
||||
nsIMAPHostInfo *host = FindHost(hostName, userName);
|
||||
if (host)
|
||||
{
|
||||
if (host->fShellCache)
|
||||
shell = *host->fShellCache->FindShellForUID(UID, mailboxName);
|
||||
shell = *host->fShellCache->FindShellForUID(uidString, mailboxName);
|
||||
}
|
||||
PR_ExitMonitor(gCachedHostInfoMonitor);
|
||||
return (host == NULL) ? NS_ERROR_ILLEGAL_VALUE : NS_OK;
|
||||
|
|
|
@ -221,7 +221,7 @@ typedef struct _TunnelInfo {
|
|||
|
||||
typedef struct _delete_message_struct {
|
||||
char *onlineFolderName;
|
||||
XP_Bool deleteAllMsgs;
|
||||
PRBool deleteAllMsgs;
|
||||
char *msgIdString;
|
||||
} delete_message_struct;
|
||||
|
||||
|
@ -259,8 +259,8 @@ typedef struct _MessageSizeInfo
|
|||
{
|
||||
char *id;
|
||||
char *folderName;
|
||||
XP_Bool idIsUid;
|
||||
uint32 size;
|
||||
PRBool idIsUid;
|
||||
PRUint32 size;
|
||||
} MessageSizeInfo;
|
||||
|
||||
|
||||
|
@ -286,17 +286,17 @@ public:
|
|||
TLineDownloadCache();
|
||||
virtual ~TLineDownloadCache();
|
||||
|
||||
uint32 CurrentUID();
|
||||
uint32 SpaceAvailable();
|
||||
XP_Bool CacheEmpty();
|
||||
PRUint32 CurrentUID();
|
||||
PRUint32 SpaceAvailable();
|
||||
PRBool CacheEmpty();
|
||||
|
||||
msg_line_info *GetCurrentLineInfo();
|
||||
|
||||
void ResetCache();
|
||||
void CacheLine(const char *line, uint32 uid);
|
||||
void CacheLine(const char *line, PRUint32 uid);
|
||||
private:
|
||||
char fLineCache[kDownLoadCacheSize];
|
||||
uint32 fBytesUsed;
|
||||
PRUint32 fBytesUsed;
|
||||
|
||||
msg_line_info *fLineInfo;
|
||||
|
||||
|
|
|
@ -22,14 +22,13 @@
|
|||
#include "nsImapFlagAndUidState.h"
|
||||
|
||||
/* amount to expand for imap entry flags when we need more */
|
||||
const PRInt32 kFlagEntrySize = 100;
|
||||
|
||||
nsImapFlagAndUidState::nsImapFlagAndUidState(PRInt32 numberOfMessages, PRUint16 flags)
|
||||
{
|
||||
fNumberOfMessagesAdded = 0;
|
||||
fNumberOfMessageSlotsAllocated = numberOfMessages;
|
||||
if (!fNumberOfMessageSlotsAllocated)
|
||||
fNumberOfMessageSlotsAllocated = kFlagEntrySize;
|
||||
fNumberOfMessageSlotsAllocated = kImapFlagAndUidStateSize;
|
||||
fFlags = (imapMessageFlagsType*) PR_Malloc(sizeof(imapMessageFlagsType) * fNumberOfMessageSlotsAllocated); // new imapMessageFlagsType[fNumberOfMessageSlotsAllocated];
|
||||
|
||||
fUids.SetSize(fNumberOfMessageSlotsAllocated);
|
||||
|
@ -100,7 +99,7 @@ void nsImapFlagAndUidState::AddUidFlagPair(PRUint32 uid, imapMessageFlagsType fl
|
|||
// make sure there is room for this pair
|
||||
if (fNumberOfMessagesAdded >= fNumberOfMessageSlotsAllocated)
|
||||
{
|
||||
fNumberOfMessageSlotsAllocated += kFlagEntrySize;
|
||||
fNumberOfMessageSlotsAllocated += kImapFlagAndUidStateSize;
|
||||
fUids.SetSize(fNumberOfMessageSlotsAllocated);
|
||||
fFlags = (imapMessageFlagsType*) PR_REALLOC(fFlags, sizeof(imapMessageFlagsType) * fNumberOfMessageSlotsAllocated); // new imapMessageFlagsType[fNumberOfMessageSlotsAllocated];
|
||||
}
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
|
||||
#include "nsMsgKeyArray.h"
|
||||
|
||||
const PRInt32 kImapFlagAndUidStateSize = 100;
|
||||
|
||||
class nsImapFlagAndUidState {
|
||||
public:
|
||||
nsImapFlagAndUidState(int numberOfMessages, PRUint16 flags = 0);
|
||||
|
|
|
@ -50,6 +50,8 @@ static NS_DEFINE_CID(kNetServiceCID, NS_NETSERVICE_CID);
|
|||
|
||||
#define IMAP_DB_HEADERS "From To Cc Subject Date Priority X-Priority Message-ID References Newsgroups"
|
||||
|
||||
static const int32 kImapSleepTime = 1000000;
|
||||
|
||||
// **** helper class for downloading line ****
|
||||
TLineDownloadCache::TLineDownloadCache()
|
||||
{
|
||||
|
@ -64,12 +66,12 @@ TLineDownloadCache::~TLineDownloadCache()
|
|||
PR_FREEIF( fLineInfo);
|
||||
}
|
||||
|
||||
uint32 TLineDownloadCache::CurrentUID()
|
||||
PRUint32 TLineDownloadCache::CurrentUID()
|
||||
{
|
||||
return fLineInfo->uidOfMessage;
|
||||
}
|
||||
|
||||
uint32 TLineDownloadCache::SpaceAvailable()
|
||||
PRUint32 TLineDownloadCache::SpaceAvailable()
|
||||
{
|
||||
return kDownLoadCacheSize - fBytesUsed;
|
||||
}
|
||||
|
@ -84,14 +86,14 @@ void TLineDownloadCache::ResetCache()
|
|||
fBytesUsed = 0;
|
||||
}
|
||||
|
||||
XP_Bool TLineDownloadCache::CacheEmpty()
|
||||
PRBool TLineDownloadCache::CacheEmpty()
|
||||
{
|
||||
return fBytesUsed == 0;
|
||||
}
|
||||
|
||||
void TLineDownloadCache::CacheLine(const char *line, uint32 uid)
|
||||
void TLineDownloadCache::CacheLine(const char *line, PRUint32 uid)
|
||||
{
|
||||
uint32 lineLength = PL_strlen(line);
|
||||
PRUint32 lineLength = PL_strlen(line);
|
||||
NS_ASSERTION((lineLength + 1) <= SpaceAvailable(),
|
||||
"Oops... line length greater than space available");
|
||||
|
||||
|
@ -142,7 +144,7 @@ NS_IMETHODIMP nsImapProtocol::QueryInterface(const nsIID &aIID, void** aInstance
|
|||
}
|
||||
|
||||
nsImapProtocol::nsImapProtocol() :
|
||||
m_parser(*this), m_currentCommand(eOneByte, 0)
|
||||
m_parser(*this), m_currentCommand(eOneByte, 0), m_flagState(kImapFlagAndUidStateSize, PR_FALSE)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
m_runningUrl = nsnull; // initialize to NULL
|
||||
|
@ -163,6 +165,8 @@ nsImapProtocol::nsImapProtocol() :
|
|||
m_dataMemberMonitor = nsnull;
|
||||
m_threadDeathMonitor = nsnull;
|
||||
m_eventCompletionMonitor = nsnull;
|
||||
m_waitForBodyIdsMonitor = nsnull;
|
||||
m_fetchMsgListMonitor = nsnull;
|
||||
m_imapThreadIsRunning = PR_FALSE;
|
||||
m_consumer = nsnull;
|
||||
m_currentServerCommandTagNumber = 0;
|
||||
|
@ -256,6 +260,16 @@ nsImapProtocol::~nsImapProtocol()
|
|||
PR_DestroyMonitor(m_eventCompletionMonitor);
|
||||
m_eventCompletionMonitor = nsnull;
|
||||
}
|
||||
if (m_waitForBodyIdsMonitor)
|
||||
{
|
||||
PR_DestroyMonitor(m_waitForBodyIdsMonitor);
|
||||
m_waitForBodyIdsMonitor = nsnull;
|
||||
}
|
||||
if (m_fetchMsgListMonitor)
|
||||
{
|
||||
PR_DestroyMonitor(m_fetchMsgListMonitor);
|
||||
m_fetchMsgListMonitor = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
const char*
|
||||
|
@ -427,6 +441,8 @@ void nsImapProtocol::SetupWithUrl(nsIURL * aURL)
|
|||
m_dataMemberMonitor = PR_NewMonitor();
|
||||
m_threadDeathMonitor = PR_NewMonitor();
|
||||
m_eventCompletionMonitor = PR_NewMonitor();
|
||||
m_waitForBodyIdsMonitor = PR_NewMonitor();
|
||||
m_fetchMsgListMonitor = PR_NewMonitor();
|
||||
|
||||
m_thread = PR_CreateThread(PR_USER_THREAD, ImapThreadMain, (void*)
|
||||
this, PR_PRIORITY_NORMAL, PR_LOCAL_THREAD,
|
||||
|
@ -849,19 +865,19 @@ nsImapProtocol::AdjustChunkSize()
|
|||
// message...
|
||||
|
||||
void
|
||||
nsImapProtocol::FetchMessage(const char *messageIds,
|
||||
nsImapProtocol::FetchMessage(nsString2 &messageIds,
|
||||
nsIMAPeFetchFields whatToFetch,
|
||||
PRBool idIsUid,
|
||||
uint32 startByte, uint32 endByte,
|
||||
PRUint32 startByte, PRUint32 endByte,
|
||||
char *part)
|
||||
{
|
||||
IncrementCommandTagNumber();
|
||||
|
||||
char commandString[350];
|
||||
nsString2 commandString;
|
||||
if (idIsUid)
|
||||
PL_strcpy(commandString, "%s UID fetch");
|
||||
commandString = "%s UID fetch";
|
||||
else
|
||||
PL_strcpy(commandString, "%s fetch");
|
||||
commandString = "%s fetch";
|
||||
|
||||
switch (whatToFetch) {
|
||||
case kEveryThingRFC822:
|
||||
|
@ -872,16 +888,16 @@ nsImapProtocol::FetchMessage(const char *messageIds,
|
|||
if (GetServerStateParser().ServerHasIMAP4Rev1Capability())
|
||||
{
|
||||
if (GetServerStateParser().GetCapabilityFlag() & kHasXSenderCapability)
|
||||
PL_strcat(commandString, " %s (XSENDER UID RFC822.SIZE BODY[]");
|
||||
commandString.Append(" %s (XSENDER UID RFC822.SIZE BODY[]");
|
||||
else
|
||||
PL_strcat(commandString, " %s (UID RFC822.SIZE BODY[]");
|
||||
commandString.Append(" %s (UID RFC822.SIZE BODY[]");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GetServerStateParser().GetCapabilityFlag() & kHasXSenderCapability)
|
||||
PL_strcat(commandString, " %s (XSENDER UID RFC822.SIZE RFC822");
|
||||
commandString.Append(" %s (XSENDER UID RFC822.SIZE RFC822");
|
||||
else
|
||||
PL_strcat(commandString, " %s (UID RFC822.SIZE RFC822");
|
||||
commandString.Append(" %s (UID RFC822.SIZE RFC822");
|
||||
}
|
||||
if (endByte > 0)
|
||||
{
|
||||
|
@ -889,17 +905,17 @@ nsImapProtocol::FetchMessage(const char *messageIds,
|
|||
char *byterangeString = PR_smprintf("<%ld.%ld>",startByte,endByte);
|
||||
if (byterangeString)
|
||||
{
|
||||
PL_strcat(commandString, byterangeString);
|
||||
commandString.Append(byterangeString);
|
||||
PR_Free(byterangeString);
|
||||
}
|
||||
}
|
||||
PL_strcat(commandString, ")");
|
||||
commandString.Append(")");
|
||||
break;
|
||||
|
||||
case kEveryThingRFC822Peek:
|
||||
{
|
||||
char *formatString = "";
|
||||
uint32 server_capabilityFlags = GetServerStateParser().GetCapabilityFlag();
|
||||
PRUint32 server_capabilityFlags = GetServerStateParser().GetCapabilityFlag();
|
||||
|
||||
if (server_capabilityFlags & kIMAP4rev1Capability)
|
||||
{
|
||||
|
@ -917,7 +933,7 @@ nsImapProtocol::FetchMessage(const char *messageIds,
|
|||
formatString = " %s (UID RFC822.SIZE RFC822.peek)";
|
||||
}
|
||||
|
||||
PL_strcat(commandString, formatString);
|
||||
commandString.Append(formatString);
|
||||
}
|
||||
break;
|
||||
case kHeadersRFC822andUid:
|
||||
|
@ -943,46 +959,46 @@ nsImapProtocol::FetchMessage(const char *messageIds,
|
|||
char *what = PR_smprintf(" BODY.PEEK[HEADER.FIELDS (%s)])", headersToDL);
|
||||
if (what)
|
||||
{
|
||||
PL_strcat(commandString, " %s (UID RFC822.SIZE FLAGS");
|
||||
PL_strcat(commandString, what);
|
||||
commandString.Append(" %s (UID RFC822.SIZE FLAGS");
|
||||
commandString.Append(what);
|
||||
PR_Free(what);
|
||||
}
|
||||
else
|
||||
{
|
||||
PL_strcat(commandString, " %s (UID RFC822.SIZE BODY.PEEK[HEADER] FLAGS)");
|
||||
commandString.Append(" %s (UID RFC822.SIZE BODY.PEEK[HEADER] FLAGS)");
|
||||
}
|
||||
PR_Free(headersToDL);
|
||||
}
|
||||
else
|
||||
{
|
||||
PL_strcat(commandString, " %s (UID RFC822.SIZE BODY.PEEK[HEADER] FLAGS)");
|
||||
commandString.Append(" %s (UID RFC822.SIZE BODY.PEEK[HEADER] FLAGS)");
|
||||
}
|
||||
}
|
||||
else
|
||||
PL_strcat(commandString, " %s (UID RFC822.SIZE BODY.PEEK[HEADER] FLAGS)");
|
||||
commandString.Append(" %s (UID RFC822.SIZE BODY.PEEK[HEADER] FLAGS)");
|
||||
}
|
||||
else
|
||||
PL_strcat(commandString, " %s (UID RFC822.SIZE RFC822.HEADER FLAGS)");
|
||||
commandString.Append(" %s (UID RFC822.SIZE RFC822.HEADER FLAGS)");
|
||||
break;
|
||||
case kUid:
|
||||
PL_strcat(commandString, " %s (UID)");
|
||||
commandString.Append(" %s (UID)");
|
||||
break;
|
||||
case kFlags:
|
||||
PL_strcat(commandString, " %s (FLAGS)");
|
||||
commandString.Append(" %s (FLAGS)");
|
||||
break;
|
||||
case kRFC822Size:
|
||||
PL_strcat(commandString, " %s (RFC822.SIZE)");
|
||||
commandString.Append(" %s (RFC822.SIZE)");
|
||||
break;
|
||||
case kRFC822HeadersOnly:
|
||||
if (GetServerStateParser().ServerHasIMAP4Rev1Capability())
|
||||
{
|
||||
if (part)
|
||||
{
|
||||
PL_strcat(commandString, " %s (BODY[");
|
||||
commandString.Append(" %s (BODY[");
|
||||
char *what = PR_smprintf("%s.HEADER])", part);
|
||||
if (what)
|
||||
{
|
||||
PL_strcat(commandString, what);
|
||||
commandString.Append(what);
|
||||
PR_Free(what);
|
||||
}
|
||||
else
|
||||
|
@ -991,36 +1007,36 @@ nsImapProtocol::FetchMessage(const char *messageIds,
|
|||
else
|
||||
{
|
||||
// headers for the top-level message
|
||||
PL_strcat(commandString, " %s (BODY[HEADER])");
|
||||
commandString.Append(" %s (BODY[HEADER])");
|
||||
}
|
||||
}
|
||||
else
|
||||
PL_strcat(commandString, " %s (RFC822.HEADER)");
|
||||
commandString.Append(" %s (RFC822.HEADER)");
|
||||
break;
|
||||
case kMIMEPart:
|
||||
PL_strcat(commandString, " %s (BODY[%s]");
|
||||
commandString.Append(" %s (BODY[%s]");
|
||||
if (endByte > 0)
|
||||
{
|
||||
// if we are retrieving chunks
|
||||
char *byterangeString = PR_smprintf("<%ld.%ld>",startByte,endByte);
|
||||
if (byterangeString)
|
||||
{
|
||||
PL_strcat(commandString, byterangeString);
|
||||
commandString.Append(byterangeString);
|
||||
PR_Free(byterangeString);
|
||||
}
|
||||
}
|
||||
PL_strcat(commandString, ")");
|
||||
commandString.Append(")");
|
||||
break;
|
||||
case kMIMEHeader:
|
||||
PL_strcat(commandString, " %s (BODY[%s.MIME])");
|
||||
commandString.Append(" %s (BODY[%s.MIME])");
|
||||
break;
|
||||
};
|
||||
|
||||
PL_strcat(commandString,CRLF);
|
||||
commandString.Append(CRLF);
|
||||
|
||||
// since messageIds can be infinitely long, use a dynamic buffer rather than the fixed one
|
||||
const char *commandTag = GetServerCommandTag();
|
||||
int protocolStringSize = PL_strlen(commandString) + PL_strlen(messageIds) + PL_strlen(commandTag) + 1 +
|
||||
int protocolStringSize = commandString.Length() + messageIds.Length() + PL_strlen(commandTag) + 1 +
|
||||
(part ? PL_strlen(part) : 0);
|
||||
char *protocolString = (char *) PR_Malloc( protocolStringSize );
|
||||
|
||||
|
@ -1031,18 +1047,18 @@ nsImapProtocol::FetchMessage(const char *messageIds,
|
|||
{
|
||||
PR_snprintf(protocolString, // string to create
|
||||
protocolStringSize, // max size
|
||||
commandString, // format string
|
||||
commandString.GetBuffer(), // format string
|
||||
commandTag, // command tag
|
||||
messageIds,
|
||||
messageIds.GetBuffer(),
|
||||
part);
|
||||
}
|
||||
else
|
||||
{
|
||||
PR_snprintf(protocolString, // string to create
|
||||
protocolStringSize, // max size
|
||||
commandString, // format string
|
||||
commandString.GetBuffer(), // format string
|
||||
commandTag, // command tag
|
||||
messageIds);
|
||||
messageIds.GetBuffer());
|
||||
}
|
||||
|
||||
int ioStatus = SendData(protocolString);
|
||||
|
@ -1055,7 +1071,7 @@ nsImapProtocol::FetchMessage(const char *messageIds,
|
|||
HandleMemoryFailure();
|
||||
}
|
||||
|
||||
void nsImapProtocol::FetchTryChunking(const char *messageIds,
|
||||
void nsImapProtocol::FetchTryChunking(nsString2 &messageIds,
|
||||
nsIMAPeFetchFields whatToFetch,
|
||||
PRBool idIsUid,
|
||||
char *part,
|
||||
|
@ -1104,7 +1120,7 @@ void nsImapProtocol::FetchTryChunking(const char *messageIds,
|
|||
}
|
||||
|
||||
|
||||
void nsImapProtocol::PipelinedFetchMessageParts(const char *uid, nsIMAPMessagePartIDArray *parts)
|
||||
void nsImapProtocol::PipelinedFetchMessageParts(nsString2 &uid, nsIMAPMessagePartIDArray *parts)
|
||||
{
|
||||
// assumes no chunking
|
||||
|
||||
|
@ -1348,6 +1364,264 @@ void nsImapProtocol::AbortMessageDownLoad()
|
|||
}
|
||||
|
||||
|
||||
void nsImapProtocol::ProcessMailboxUpdate(PRBool handlePossibleUndo)
|
||||
{
|
||||
if (DeathSignalReceived())
|
||||
return;
|
||||
// fetch the flags and uids of all existing messages or new ones
|
||||
if (!DeathSignalReceived() && GetServerStateParser().NumberOfMessages())
|
||||
{
|
||||
if (handlePossibleUndo)
|
||||
{
|
||||
// undo any delete flags we may have asked to
|
||||
char *undoIds;
|
||||
|
||||
GetCurrentUrl()->CreateListOfMessageIdsString(&undoIds);
|
||||
if (undoIds && *undoIds)
|
||||
{
|
||||
// if this string started with a '-', then this is an undo of a delete
|
||||
// if its a '+' its a redo
|
||||
if (*undoIds == '-')
|
||||
Store(undoIds+1, "-FLAGS (\\Deleted)", TRUE); // most servers will fail silently on a failure, deal with it?
|
||||
else if (*undoIds == '+')
|
||||
Store(undoIds+1, "+FLAGS (\\Deleted)", TRUE); // most servers will fail silently on a failure, deal with it?
|
||||
else
|
||||
NS_ASSERTION(FALSE, "bogus undo Id's");
|
||||
}
|
||||
PR_FREEIF(undoIds);
|
||||
}
|
||||
|
||||
// make the parser record these flags
|
||||
nsString2 fetchStr;
|
||||
PRUint32 added = 0, deleted = 0;
|
||||
|
||||
added = m_flagState.GetNumberOfMessages();
|
||||
deleted = m_flagState.GetNumberOfDeletedMessages();
|
||||
|
||||
if (!added || (added == deleted))
|
||||
{
|
||||
nsString2 idsToFetch("1:*");
|
||||
FetchMessage(idsToFetch, kFlags, TRUE); // id string shows uids
|
||||
// lets see if we should expunge during a full sync of flags.
|
||||
if (!DeathSignalReceived()) // only expunge if not reading messages manually and before fetching new
|
||||
{
|
||||
// ### TODO read gExpungeThreshhold from prefs.
|
||||
if ((m_flagState.GetNumberOfDeletedMessages() >= 20/* gExpungeThreshold */) /*&&
|
||||
GetDeleteIsMoveToTrash() */)
|
||||
Expunge(); // might be expensive, test for user cancel
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
fetchStr.Append(GetServerStateParser().HighestRecordedUID() + 1, 10);
|
||||
fetchStr.Append(":*");
|
||||
|
||||
// sprintf(fetchStr, "%ld:*", GetServerStateParser().HighestRecordedUID() + 1);
|
||||
FetchMessage(fetchStr, kFlags, TRUE); // only new messages please
|
||||
}
|
||||
}
|
||||
else if (!DeathSignalReceived())
|
||||
GetServerStateParser().ResetFlagInfo(0);
|
||||
|
||||
mailbox_spec *new_spec = GetServerStateParser().CreateCurrentMailboxSpec();
|
||||
if (new_spec && !DeathSignalReceived())
|
||||
{
|
||||
#if 0
|
||||
MWContext *ct = NULL;
|
||||
|
||||
LIBNET_LOCK();
|
||||
if (!DeathSignalReceived())
|
||||
{
|
||||
// if this is an expunge url, libmsg will not ask for headers
|
||||
if (fCurrentUrl->GetIMAPurlType() == TIMAPUrl::kExpungeFolder)
|
||||
new_spec->box_flags |= kJustExpunged;
|
||||
|
||||
ct = new_spec->connection->fCurrentEntry->window_id;
|
||||
ct->imapURLPane = MSG_FindPane(fCurrentEntry->window_id, MSG_ANYPANE);
|
||||
}
|
||||
LIBNET_UNLOCK();
|
||||
if (ct)
|
||||
{
|
||||
if (!ct->currentIMAPfolder)
|
||||
ct->currentIMAPfolder = (MSG_IMAPFolderInfoMail *) MSG_FindImapFolder(ct->imapURLPane, fCurrentUrl->GetUrlHost(), "INBOX"); // use real folder name
|
||||
PR_EnterMonitor(fWaitForBodyIdsMonitor);
|
||||
UpdatedMailboxSpec(new_spec);
|
||||
}
|
||||
#endif // 0
|
||||
}
|
||||
else if (!new_spec)
|
||||
HandleMemoryFailure();
|
||||
|
||||
// Block until libmsg decides whether to download headers or not.
|
||||
PRUint32 *msgIdList = NULL;
|
||||
PRUint32 msgCount = 0;
|
||||
|
||||
if (!DeathSignalReceived())
|
||||
{
|
||||
WaitForPotentialListOfMsgsToFetch(&msgIdList, msgCount);
|
||||
|
||||
if (new_spec)
|
||||
PR_ExitMonitor(m_waitForBodyIdsMonitor);
|
||||
|
||||
if (msgIdList && !DeathSignalReceived() && GetServerStateParser().LastCommandSuccessful())
|
||||
{
|
||||
FolderHeaderDump(msgIdList, msgCount);
|
||||
PR_FREEIF( msgIdList);
|
||||
}
|
||||
// this might be bogus, how are we going to do pane notification and stuff when we fetch bodies without
|
||||
// headers!
|
||||
}
|
||||
// wait for a list of bodies to fetch.
|
||||
if (!DeathSignalReceived() && GetServerStateParser().LastCommandSuccessful())
|
||||
{
|
||||
WaitForPotentialListOfMsgsToFetch(&msgIdList, msgCount);
|
||||
if ( msgCount && !DeathSignalReceived() && GetServerStateParser().LastCommandSuccessful())
|
||||
{
|
||||
FolderMsgDump(msgIdList, msgCount, kEveryThingRFC822Peek);
|
||||
PR_FREEIF(msgIdList);
|
||||
}
|
||||
}
|
||||
if (DeathSignalReceived())
|
||||
GetServerStateParser().ResetFlagInfo(0);
|
||||
}
|
||||
|
||||
|
||||
void nsImapProtocol::FolderHeaderDump(PRUint32 *msgUids, PRUint32 msgCount)
|
||||
{
|
||||
FolderMsgDump(msgUids, msgCount, kHeadersRFC822andUid);
|
||||
|
||||
if (GetServerStateParser().NumberOfMessages())
|
||||
HeaderFetchCompleted();
|
||||
}
|
||||
|
||||
void nsImapProtocol::FolderMsgDump(PRUint32 *msgUids, PRUint32 msgCount, nsIMAPeFetchFields fields)
|
||||
{
|
||||
#if 0
|
||||
// lets worry about this progress stuff later.
|
||||
switch (fields) {
|
||||
case TIMAP4BlockingConnection::kHeadersRFC822andUid:
|
||||
fProgressStringId = XP_RECEIVING_MESSAGE_HEADERS_OF;
|
||||
break;
|
||||
case TIMAP4BlockingConnection::kFlags:
|
||||
fProgressStringId = XP_RECEIVING_MESSAGE_FLAGS_OF;
|
||||
break;
|
||||
default:
|
||||
fProgressStringId = XP_FOLDER_RECEIVING_MESSAGE_OF;
|
||||
break;
|
||||
}
|
||||
|
||||
fProgressIndex = 0;
|
||||
fProgressCount = msgCount;
|
||||
#endif // 0
|
||||
FolderMsgDumpLoop(msgUids, msgCount, fields);
|
||||
|
||||
// fProgressStringId = 0;
|
||||
}
|
||||
|
||||
void nsImapProtocol::WaitForPotentialListOfMsgsToFetch(PRUint32 **msgIdList, PRUint32 &msgCount)
|
||||
{
|
||||
PRIntervalTime sleepTime = kImapSleepTime;
|
||||
|
||||
PR_EnterMonitor(m_fetchMsgListMonitor);
|
||||
while(!m_fetchMsgListIsNew && !DeathSignalReceived())
|
||||
PR_Wait(m_fetchMsgListMonitor, sleepTime);
|
||||
m_fetchMsgListIsNew = FALSE;
|
||||
|
||||
*msgIdList = m_fetchMsgIdList;
|
||||
msgCount = m_fetchCount;
|
||||
|
||||
PR_ExitMonitor(m_fetchMsgListMonitor);
|
||||
}
|
||||
|
||||
|
||||
void nsImapProtocol::NotifyKeyList(PRUint32 *keys, PRUint32 keyCount)
|
||||
{
|
||||
PR_EnterMonitor(m_fetchMsgListMonitor);
|
||||
m_fetchMsgIdList = keys;
|
||||
m_fetchCount = keyCount;
|
||||
m_fetchMsgListIsNew = TRUE;
|
||||
PR_Notify(m_fetchMsgListMonitor);
|
||||
PR_ExitMonitor(m_fetchMsgListMonitor);
|
||||
}
|
||||
|
||||
void nsImapProtocol::FolderMsgDumpLoop(PRUint32 *msgUids, PRUint32 msgCount, nsIMAPeFetchFields fields)
|
||||
{
|
||||
// PastPasswordCheckEvent();
|
||||
|
||||
PRUint32 msgCountLeft = msgCount;
|
||||
PRUint32 msgsDownloaded = 0;
|
||||
do
|
||||
{
|
||||
nsString2 idString;
|
||||
|
||||
PRUint32 msgsToDownload = (msgCountLeft > 200) ? 200 : msgCountLeft;
|
||||
AllocateImapUidString(msgUids + msgsDownloaded, msgsToDownload, idString); // 20 * 200
|
||||
|
||||
// except I don't think this works ### DB
|
||||
FetchMessage(idString, fields, TRUE); // msg ids are uids
|
||||
|
||||
msgsDownloaded += msgsToDownload;
|
||||
msgCountLeft -= msgsDownloaded;
|
||||
|
||||
}
|
||||
while (msgCountLeft > 0);
|
||||
}
|
||||
|
||||
|
||||
void nsImapProtocol::HeaderFetchCompleted()
|
||||
{
|
||||
if (m_imapMiscellaneous)
|
||||
m_imapMiscellaneous->HeaderFetchCompleted(this);
|
||||
// need to block until this finishes - Jeff, how does that work?
|
||||
}
|
||||
|
||||
|
||||
void nsImapProtocol::AllocateImapUidString(PRUint32 *msgUids, PRUint32 msgCount, nsString2 &returnString)
|
||||
{
|
||||
int blocksAllocated = 1;
|
||||
|
||||
PRInt32 startSequence = (msgCount > 0) ? msgUids[0] : -1;
|
||||
PRInt32 curSequenceEnd = startSequence;
|
||||
PRUint32 total = msgCount;
|
||||
|
||||
for (PRUint32 keyIndex=0; keyIndex < total; keyIndex++)
|
||||
{
|
||||
PRInt32 curKey = msgUids[keyIndex];
|
||||
PRInt32 nextKey = (keyIndex + 1 < total) ? msgUids[keyIndex + 1] : -1;
|
||||
PRBool lastKey = (nextKey == -1);
|
||||
|
||||
if (lastKey)
|
||||
curSequenceEnd = curKey;
|
||||
if (nextKey == curSequenceEnd + 1 && !lastKey)
|
||||
{
|
||||
curSequenceEnd = nextKey;
|
||||
continue;
|
||||
}
|
||||
else if (curSequenceEnd > startSequence)
|
||||
{
|
||||
returnString.Append(startSequence, 10);
|
||||
returnString += ':';
|
||||
returnString.Append(curSequenceEnd, 10);
|
||||
if (!lastKey)
|
||||
returnString += ',';
|
||||
// sprintf(currentidString, "%ld:%ld,", startSequence, curSequenceEnd);
|
||||
startSequence = nextKey;
|
||||
curSequenceEnd = startSequence;
|
||||
}
|
||||
else
|
||||
{
|
||||
startSequence = nextKey;
|
||||
curSequenceEnd = startSequence;
|
||||
returnString.Append(msgUids[keyIndex], 10);
|
||||
if (!lastKey)
|
||||
returnString += ',';
|
||||
// sprintf(currentidString, "%ld,", msgUids[keyIndex]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// log info including current state...
|
||||
void nsImapProtocol::Log(const char *logSubName, const char *extraInfo, const char *logData)
|
||||
{
|
||||
|
@ -1395,7 +1669,7 @@ void nsImapProtocol::Log(const char *logSubName, const char *extraInfo, const ch
|
|||
// In 4.5, this posted an event back to libmsg and blocked until it got a response.
|
||||
// We may still have to do this.It would be nice if we could preflight this value,
|
||||
// but we may not always know when we'll need it.
|
||||
PRUint32 nsImapProtocol::GetMessageSize(const char *messageId, PRBool idsAreUids)
|
||||
PRUint32 nsImapProtocol::GetMessageSize(nsString2 &messageId, PRBool idsAreUids)
|
||||
{
|
||||
NS_ASSERTION(FALSE, "not implemented yet");
|
||||
return 0;
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
|
||||
#include "nsImapServerResponseParser.h"
|
||||
#include "nsImapProxyEvent.h"
|
||||
#include "nsImapFlagAndUidState.h"
|
||||
|
||||
class nsIMAPMessagePartIDArray;
|
||||
class nsIMsgIncomingServer;
|
||||
|
@ -90,17 +91,17 @@ public:
|
|||
PRBool GetShouldDownloadArbitraryHeaders();
|
||||
char *GetArbitraryHeadersToDownload();
|
||||
virtual void AdjustChunkSize();
|
||||
virtual void FetchMessage(const char *messageIds,
|
||||
virtual void FetchMessage(nsString2 &messageIds,
|
||||
nsIMAPeFetchFields whatToFetch,
|
||||
XP_Bool idAreUid,
|
||||
uint32 startByte = 0, uint32 endByte = 0,
|
||||
PRBool idAreUid,
|
||||
PRUint32 startByte = 0, PRUint32 endByte = 0,
|
||||
char *part = 0);
|
||||
void FetchTryChunking(const char *messageIds,
|
||||
void FetchTryChunking(nsString2 &messageIds,
|
||||
nsIMAPeFetchFields whatToFetch,
|
||||
PRBool idIsUid,
|
||||
char *part,
|
||||
PRUint32 downloadSize);
|
||||
virtual void PipelinedFetchMessageParts(const char *uid, nsIMAPMessagePartIDArray *parts);
|
||||
virtual void PipelinedFetchMessageParts(nsString2 &uid, nsIMAPMessagePartIDArray *parts);
|
||||
|
||||
// used when streaming a message fetch
|
||||
virtual void BeginMessageDownLoad(PRUint32 totalSize, // for user, headers and body
|
||||
|
@ -111,6 +112,7 @@ public:
|
|||
virtual void PostLineDownLoadEvent(msg_line_info *downloadLineDontDelete);
|
||||
virtual void AddXMozillaStatusLine(uint16 flags); // for XSender auth info
|
||||
|
||||
virtual void ProcessMailboxUpdate(PRBool handlePossibleUndo);
|
||||
// Send log output...
|
||||
void Log(const char *logSubName, const char *extraInfo, const char *logData);
|
||||
|
||||
|
@ -120,7 +122,7 @@ public:
|
|||
PRBool GetPseudoInterrupted();
|
||||
void PseudoInterrupt(PRBool the_interrupt);
|
||||
|
||||
PRUint32 GetMessageSize(const char *messageId, PRBool idsAreUids);
|
||||
PRUint32 GetMessageSize(nsString2 &messageId, PRBool idsAreUids);
|
||||
|
||||
PRBool DeathSignalReceived();
|
||||
void ResetProgressInfo();
|
||||
|
@ -215,6 +217,8 @@ private:
|
|||
PRMonitor *m_dataMemberMonitor;
|
||||
PRMonitor *m_threadDeathMonitor;
|
||||
PRMonitor *m_eventCompletionMonitor;
|
||||
PRMonitor *m_waitForBodyIdsMonitor;
|
||||
PRMonitor *m_fetchMsgListMonitor;
|
||||
|
||||
PRBool m_imapThreadIsRunning;
|
||||
static void ImapThreadMain(void *aParm);
|
||||
|
@ -241,6 +245,20 @@ private:
|
|||
virtual void ProcessCurrentURL();
|
||||
virtual void ParseIMAPandCheckForNewMail(char* commandString = nsnull);
|
||||
|
||||
// listing header functions
|
||||
void FolderHeaderDump(PRUint32 *msgUids, PRUint32 msgCount);
|
||||
void FolderMsgDump(PRUint32 *msgUids, PRUint32 msgCount, nsIMAPeFetchFields fields);
|
||||
void FolderMsgDumpLoop(PRUint32 *msgUids, PRUint32 msgCount, nsIMAPeFetchFields fields);
|
||||
void WaitForPotentialListOfMsgsToFetch(PRUint32 **msgIdList, PRUint32 &msgCount);
|
||||
void NotifyKeyList(PRUint32 *keys, PRUint32 keyCount);
|
||||
void AllocateImapUidString(PRUint32 *msgUids, PRUint32 msgCount, nsString2 &returnString);
|
||||
void HeaderFetchCompleted();
|
||||
|
||||
// header listing data
|
||||
PRBool m_fetchMsgListIsNew;
|
||||
PRUint32 m_fetchCount;
|
||||
PRUint32 *m_fetchMsgIdList;
|
||||
|
||||
// initialization function given a new url and transport layer
|
||||
void SetupWithUrl(nsIURL * aURL);
|
||||
|
||||
|
@ -253,9 +271,10 @@ private:
|
|||
PRInt32 SendData(const char * dataBuffer);
|
||||
|
||||
// state ported over from 4.5
|
||||
PRBool m_pseudoInterrupted;
|
||||
PRBool m_active;
|
||||
PRBool m_threadShouldDie;
|
||||
PRBool m_pseudoInterrupted;
|
||||
PRBool m_active;
|
||||
PRBool m_threadShouldDie;
|
||||
nsImapFlagAndUidState m_flagState;
|
||||
|
||||
// manage the IMAP server command tags
|
||||
char m_currentServerCommandTag[10]; // enough for a billion
|
||||
|
|
|
@ -63,6 +63,7 @@ nsImapUrl::nsImapUrl()
|
|||
m_imapMessage = nsnull;
|
||||
m_imapExtension = nsnull;
|
||||
m_imapMiscellaneous = nsnull;
|
||||
m_listOfMessageIds = nsnull;
|
||||
|
||||
m_runningUrl = PR_FALSE;
|
||||
|
||||
|
@ -86,6 +87,8 @@ nsImapUrl::~nsImapUrl()
|
|||
PR_FREEIF(m_protocol);
|
||||
PR_FREEIF(m_host);
|
||||
PR_FREEIF(m_search);
|
||||
PR_FREEIF(m_listOfMessageIds);
|
||||
|
||||
}
|
||||
|
||||
NS_IMPL_THREADSAFE_ADDREF(nsImapUrl);
|
||||
|
@ -732,6 +735,38 @@ NS_IMETHODIMP nsImapUrl::GetContentLength(PRInt32 *len)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsImapUrl::CreateListOfMessageIdsString(char **aResult) const
|
||||
{
|
||||
if (nsnull == aResult || !m_listOfMessageIds)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
NS_LOCK_INSTANCE();
|
||||
|
||||
char *returnIdString = PL_strdup(m_listOfMessageIds);
|
||||
if (returnIdString)
|
||||
{
|
||||
// mime may have glommed a "&part=" for a part download
|
||||
// we return the entire message and let mime extract
|
||||
// the part. Pop and news work this way also.
|
||||
// this algorithm truncates the "&part" string.
|
||||
char *currentChar = returnIdString;
|
||||
while (*currentChar && (*currentChar != '&'))
|
||||
currentChar++;
|
||||
if (*currentChar == '&')
|
||||
*currentChar = 0;
|
||||
|
||||
// we should also strip off anything after "/;section="
|
||||
// since that can specify an IMAP MIME part
|
||||
char *wherepart = PL_strstr(returnIdString, "/;section=");
|
||||
if (wherepart)
|
||||
*wherepart = 0;
|
||||
}
|
||||
*aResult = returnIdString;
|
||||
|
||||
NS_UNLOCK_INSTANCE();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// End of nsIURL support
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -106,6 +106,9 @@ public:
|
|||
|
||||
NS_IMETHOD GetImapPartToFetch(char **result) const;
|
||||
NS_IMETHOD AllocateCannonicalPath(const char *serverPath, char onlineDelimiter, char **allocatedPath ) const;
|
||||
|
||||
NS_IMETHOD CreateListOfMessageIdsString(char **result) const;
|
||||
|
||||
// nsImapUrl
|
||||
nsImapUrl();
|
||||
virtual ~nsImapUrl();
|
||||
|
@ -125,6 +128,8 @@ protected:
|
|||
PRUint32 m_port;
|
||||
char *m_search;
|
||||
char *m_errorMessage;
|
||||
char *m_listOfMessageIds;
|
||||
|
||||
|
||||
PRBool m_runningUrl;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче