зеркало из https://github.com/mozilla/pjs.git
fix handling of hosts without namespace extension, start working on utf7 stuff
This commit is contained in:
Родитель
e3821db151
Коммит
b452d4eb99
|
@ -94,6 +94,7 @@ public:
|
|||
|
||||
// Namespaces
|
||||
NS_IMETHOD GetNamespaceForMailboxForHost(const char *hostname, const char *userName, const char *mailbox_name, nsIMAPNamespace * & result) = 0;
|
||||
NS_IMETHOD SetNamespaceFromPrefForHost(const char *hostName, const char *userName, const char *namespacePref, EIMAPNamespaceType type) = 0;
|
||||
NS_IMETHOD AddNewNamespaceForHost(const char *hostname, const char *userName, nsIMAPNamespace *ns) = 0;
|
||||
NS_IMETHOD ClearServerAdvertisedNamespacesForHost(const char *hostName, const char *userName) = 0;
|
||||
NS_IMETHOD ClearPrefsNamespacesForHost(const char *hostName, const char *userName) = 0;
|
||||
|
|
|
@ -438,6 +438,38 @@ NS_IMETHODIMP nsIMAPHostSessionList::AddNewNamespaceForHost(const char *hostName
|
|||
return (host == NULL) ? NS_ERROR_ILLEGAL_VALUE : NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsIMAPHostSessionList::SetNamespaceFromPrefForHost(const char *hostName, const char *userName,
|
||||
const char *namespacePref, EIMAPNamespaceType nstype)
|
||||
{
|
||||
PR_EnterMonitor(gCachedHostInfoMonitor);
|
||||
nsIMAPHostInfo *host = FindHost(hostName, userName);
|
||||
if (host)
|
||||
{
|
||||
if (namespacePref)
|
||||
{
|
||||
int numNamespaces = host->fNamespaceList->UnserializeNamespaces(namespacePref, nsnull, 0);
|
||||
char **prefixes = (char**) PR_CALLOC(numNamespaces * sizeof(char*));
|
||||
if (prefixes)
|
||||
{
|
||||
int len = host->fNamespaceList->UnserializeNamespaces(namespacePref, prefixes, numNamespaces);
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
char *thisns = prefixes[i];
|
||||
char delimiter = '/'; // a guess
|
||||
if (PL_strlen(thisns) >= 1)
|
||||
delimiter = thisns[PL_strlen(thisns)-1];
|
||||
nsIMAPNamespace *ns = new nsIMAPNamespace(nstype, thisns, delimiter, PR_TRUE);
|
||||
if (ns)
|
||||
host->fNamespaceList->AddNewNamespace(ns);
|
||||
PR_FREEIF(thisns);
|
||||
}
|
||||
PR_Free(prefixes);
|
||||
}
|
||||
}
|
||||
}
|
||||
PR_ExitMonitor(gCachedHostInfoMonitor);
|
||||
return (host == NULL) ? NS_ERROR_ILLEGAL_VALUE : NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsIMAPHostSessionList::GetNamespaceForMailboxForHost(const char *hostName, const char *userName, const char *mailbox_name, nsIMAPNamespace * &result)
|
||||
{
|
||||
|
|
|
@ -120,6 +120,7 @@ public:
|
|||
|
||||
// Namespaces
|
||||
NS_IMETHOD GetNamespaceForMailboxForHost(const char *hostName, const char *userName, const char *mailbox_name, nsIMAPNamespace *&result);
|
||||
NS_IMETHOD SetNamespaceFromPrefForHost(const char *hostName, const char *userName, const char *namespacePref, EIMAPNamespaceType type);
|
||||
NS_IMETHOD AddNewNamespaceForHost(const char *hostName, const char *userName, nsIMAPNamespace *ns);
|
||||
NS_IMETHOD ClearServerAdvertisedNamespacesForHost(const char *hostName, const char *userName);
|
||||
NS_IMETHOD ClearPrefsNamespacesForHost(const char *hostName, const char *userName);
|
||||
|
|
|
@ -82,6 +82,43 @@ int nsIMAPNamespaceList::GetNumberOfNamespaces()
|
|||
return m_NamespaceList.Count();
|
||||
}
|
||||
|
||||
|
||||
nsresult nsIMAPNamespaceList::InitFromString(const char *nameSpaceString, EIMAPNamespaceType nstype)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
if (nameSpaceString)
|
||||
{
|
||||
int numNamespaces = UnserializeNamespaces(nameSpaceString, nsnull, 0);
|
||||
char **prefixes = (char**) PR_CALLOC(numNamespaces * sizeof(char*));
|
||||
if (prefixes)
|
||||
{
|
||||
int len = UnserializeNamespaces(nameSpaceString, prefixes, numNamespaces);
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
char *thisns = prefixes[i];
|
||||
char delimiter = '/'; // a guess
|
||||
if (PL_strlen(thisns) >= 1)
|
||||
delimiter = thisns[PL_strlen(thisns)-1];
|
||||
nsIMAPNamespace *ns = new nsIMAPNamespace(nstype, thisns, delimiter, PR_TRUE);
|
||||
if (ns)
|
||||
AddNewNamespace(ns);
|
||||
PR_FREEIF(thisns);
|
||||
}
|
||||
PR_Free(prefixes);
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult nsIMAPNamespaceList::OutputToString(nsString &string)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
int nsIMAPNamespaceList::GetNumberOfNamespaces(EIMAPNamespaceType type)
|
||||
{
|
||||
int nodeIndex = 0, count = 0;
|
||||
|
@ -203,7 +240,7 @@ nsIMAPNamespace *nsIMAPNamespaceList::GetNamespaceNumber(int nodeIndex, EIMAPNam
|
|||
return nspace;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsIMAPNamespace *nsIMAPNamespaceList::GetNamespaceForMailbox(const char *boxname)
|
||||
|
@ -219,7 +256,7 @@ nsIMAPNamespace *nsIMAPNamespaceList::GetNamespaceForMailbox(const char *boxname
|
|||
|
||||
int lengthMatched = -1;
|
||||
int currentMatchedLength = -1;
|
||||
nsIMAPNamespace *rv = NULL;
|
||||
nsIMAPNamespace *rv = nsnull;
|
||||
int nodeIndex = 0;
|
||||
|
||||
if (!PL_strcasecmp(boxname, "INBOX"))
|
||||
|
@ -239,3 +276,107 @@ nsIMAPNamespace *nsIMAPNamespaceList::GetNamespaceForMailbox(const char *boxname
|
|||
return rv;
|
||||
}
|
||||
|
||||
#define SERIALIZER_SEPARATORS ","
|
||||
|
||||
/* prefixes is an array of strings; len is the length of that array.
|
||||
If there is only one string, simply copy it and return it.
|
||||
Otherwise, put them in quotes and comma-delimit them.
|
||||
Returns a newly allocated string. */
|
||||
nsresult nsIMAPNamespaceList::SerializeNamespaces(char **prefixes, int len, nsString2 &serializedNamespaces)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
if (len <= 0)
|
||||
return rv;
|
||||
if (len == 1)
|
||||
{
|
||||
serializedNamespaces = prefixes[0];
|
||||
return rv;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
char *temp = nsnull;
|
||||
if (i == 0)
|
||||
{
|
||||
serializedNamespaces += "\"";
|
||||
|
||||
temp = PR_smprintf("\"%s\"",prefixes[i]); /* quote the string */
|
||||
}
|
||||
else
|
||||
{
|
||||
serializedNamespaces += ',';
|
||||
}
|
||||
serializedNamespaces += prefixes[i];
|
||||
serializedNamespaces += "\"";
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
/* str is the string which needs to be unserialized.
|
||||
If prefixes is NULL, simply returns the number of namespaces in str. (len is ignored)
|
||||
If prefixes is not NULL, it should be an array of length len which is to be filled in
|
||||
with newly-allocated string. Returns the number of strings filled in.
|
||||
*/
|
||||
int nsIMAPNamespaceList::UnserializeNamespaces(const char *str, char **prefixes, int len)
|
||||
{
|
||||
if (!str)
|
||||
return 0;
|
||||
if (!prefixes)
|
||||
{
|
||||
if (str[0] != '"')
|
||||
return 1;
|
||||
else
|
||||
{
|
||||
int count = 0;
|
||||
char *ourstr = PL_strdup(str);
|
||||
char *origOurStr = ourstr;
|
||||
if (ourstr)
|
||||
{
|
||||
char *token = nsCRT::strtok( ourstr, SERIALIZER_SEPARATORS, &ourstr );
|
||||
while (token != nsnull)
|
||||
{
|
||||
token = nsCRT::strtok( ourstr, SERIALIZER_SEPARATORS, &ourstr );
|
||||
count++;
|
||||
}
|
||||
PR_Free(origOurStr);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((str[0] != '"') && (len >= 1))
|
||||
{
|
||||
prefixes[0] = PL_strdup(str);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
int count = 0;
|
||||
char *ourstr = PL_strdup(str);
|
||||
char *origOurStr = ourstr;
|
||||
if (ourstr)
|
||||
{
|
||||
char *token = nsCRT::strtok( ourstr, SERIALIZER_SEPARATORS, &ourstr );
|
||||
while ((count < len) && (token != nsnull))
|
||||
{
|
||||
|
||||
char *current = PL_strdup(token), *where = current;
|
||||
if (where[0] == '"')
|
||||
where++;
|
||||
if (where[PL_strlen(where)-1] == '"')
|
||||
where[PL_strlen(where)-1] = 0;
|
||||
prefixes[count] = PL_strdup(where);
|
||||
PR_FREEIF(current);
|
||||
token = nsCRT::strtok( ourstr, SERIALIZER_SEPARATORS, &ourstr );
|
||||
count++;
|
||||
}
|
||||
PR_Free(origOurStr);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -56,6 +56,11 @@ public:
|
|||
|
||||
static nsIMAPNamespaceList *CreatensIMAPNamespaceList();
|
||||
|
||||
nsresult InitFromString(const char *nameSpaceString, EIMAPNamespaceType nstype);
|
||||
nsresult OutputToString(nsString2 &OutputString);
|
||||
int UnserializeNamespaces(const char *str, char **prefixes, int len);
|
||||
nsresult SerializeNamespaces(char **prefixes, int len, nsString2 &serializedNamespace);
|
||||
|
||||
void ClearNamespaces(PRBool deleteFromPrefsNamespaces, PRBool deleteServerAdvertisedNamespaces, PRBool reallyDelete);
|
||||
int GetNumberOfNamespaces();
|
||||
int GetNumberOfNamespaces(EIMAPNamespaceType);
|
||||
|
|
|
@ -72,6 +72,18 @@ public:
|
|||
NS_IMETHOD LoadNextQueuedUrl();
|
||||
NS_IMETHOD RemoveConnection(nsIImapProtocol* aImapConnection);
|
||||
|
||||
/* attribute string personal namespace; */
|
||||
NS_IMETHOD GetPersonalNamespace(char * *aPersonalNamespace);
|
||||
NS_IMETHOD SetPersonalNamespace(char * aPersonalNamespace);
|
||||
|
||||
/* attribute string public namespace; */
|
||||
NS_IMETHOD GetPublicNamespace(char * *aPublicNamespace);
|
||||
NS_IMETHOD SetPublicNamespace(char * aPublicNamespace);
|
||||
|
||||
/* attribute string personal namespace; */
|
||||
NS_IMETHOD GetOtherUsersNamespace(char * *aOtherUsersNamespace);
|
||||
NS_IMETHOD SetOtherUsersNamespace(char * aOtherUsersNamespace);
|
||||
|
||||
private:
|
||||
nsresult CreateImapConnection (nsIEventQueue* aEventQueue,
|
||||
nsIImapUrl* aImapUrl,
|
||||
|
@ -122,6 +134,36 @@ NS_IMETHODIMP nsImapIncomingServer::SetKey(char * aKey) // override nsMsgIncomi
|
|||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
hostSession->AddHostToList(hostName, userName);
|
||||
|
||||
char *personalNamespace = nsnull;
|
||||
char *publicNamespace = nsnull;
|
||||
char *otherUsersNamespace = nsnull;
|
||||
|
||||
rv = GetPersonalNamespace(&personalNamespace);
|
||||
rv = GetPublicNamespace(&publicNamespace);
|
||||
rv = GetOtherUsersNamespace(&otherUsersNamespace);
|
||||
|
||||
if (!personalNamespace && !publicNamespace && !otherUsersNamespace)
|
||||
personalNamespace = PL_strdup("\"\"");
|
||||
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
hostSession->SetNamespaceFromPrefForHost(hostName, userName, personalNamespace, kPersonalNamespace);
|
||||
PR_FREEIF(personalNamespace);
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
hostSession->SetNamespaceFromPrefForHost(hostName, userName, publicNamespace, kPublicNamespace);
|
||||
PR_FREEIF(publicNamespace);
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
hostSession->SetNamespaceFromPrefForHost(hostName, userName, otherUsersNamespace, kOtherUsersNamespace);
|
||||
PR_FREEIF(otherUsersNamespace);
|
||||
}
|
||||
|
||||
PR_FREEIF(userName);
|
||||
PR_FREEIF(hostName);
|
||||
|
||||
|
@ -152,6 +194,12 @@ NS_IMPL_SERVERPREF_INT(nsImapIncomingServer, MaximumConnectionsNumber,
|
|||
NS_IMPL_SERVERPREF_INT(nsImapIncomingServer, TimeOutLimits,
|
||||
"timeout");
|
||||
|
||||
NS_IMPL_SERVERPREF_STR(nsImapIncomingServer, PersonalNamespace, "namespace.personal");
|
||||
|
||||
NS_IMPL_SERVERPREF_STR(nsImapIncomingServer, PublicNamespace, "namespace.public");
|
||||
|
||||
NS_IMPL_SERVERPREF_STR(nsImapIncomingServer, OtherUsersNamespace, "namespace.other_users");
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsImapIncomingServer::GetImapConnectionAndLoadUrl(nsIEventQueue*
|
||||
aClientEventQueue,
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
#include "nsITransactionManager.h"
|
||||
#include "nsMsgTxn.h"
|
||||
#ifdef DEBUG_bienvenu
|
||||
#define DOING_FILTERS
|
||||
//#define DOING_FILTERS
|
||||
#endif
|
||||
#ifdef DOING_FILTERS
|
||||
#include "nsIMsgFilterHitNotify.h"
|
||||
|
|
|
@ -53,6 +53,8 @@ PRLogModuleInfo *IMAP;
|
|||
#include "nsIMsgIncomingServer.h"
|
||||
#include "nsIImapIncomingServer.h"
|
||||
|
||||
#include "nsICharsetConverterManager.h"
|
||||
|
||||
// for temp message hack
|
||||
#ifdef XP_UNIX
|
||||
#define MESSAGE_PATH "/usr/tmp/tempMessage.eml"
|
||||
|
@ -1539,15 +1541,13 @@ void nsImapProtocol::ProcessSelectedStateURL()
|
|||
char *convertedCanonicalName = NULL;
|
||||
if (nameStruct)
|
||||
{
|
||||
nameStruct->toUtf7Imap = PR_FALSE;
|
||||
nameStruct->sourceString = (unsigned char *) GetServerStateParser().GetSelectedMailboxName();
|
||||
nameStruct->convertedString = NULL;
|
||||
#ifdef DO_UTF7_YET
|
||||
ConvertImapUtf7(nameStruct, NULL);
|
||||
#endif
|
||||
if (nameStruct->convertedString)
|
||||
m_runningUrl->AllocateCanonicalPath((char *) nameStruct->convertedString,
|
||||
char *convertedName = CreateUtf7ConvertedString(GetServerStateParser().GetSelectedMailboxName(), PR_FALSE);
|
||||
if (convertedName)
|
||||
{
|
||||
m_runningUrl->AllocateCanonicalPath(convertedName,
|
||||
kOnlineHierarchySeparatorUnknown, &convertedCanonicalName);
|
||||
PR_Free(convertedName);
|
||||
}
|
||||
}
|
||||
|
||||
deleteMsg->onlineFolderName = convertedCanonicalName;
|
||||
|
@ -1581,15 +1581,13 @@ void nsImapProtocol::ProcessSelectedStateURL()
|
|||
char *convertedCanonicalName = NULL;
|
||||
if (nameStruct)
|
||||
{
|
||||
nameStruct->toUtf7Imap = PR_FALSE;
|
||||
nameStruct->sourceString = (unsigned char *) GetServerStateParser().GetSelectedMailboxName();
|
||||
nameStruct->convertedString = NULL;
|
||||
#ifdef DO_UTF7
|
||||
ConvertImapUtf7(nameStruct, NULL);
|
||||
#endif
|
||||
if (nameStruct->convertedString)
|
||||
m_runningUrl->AllocateCanonicalPath((char *) nameStruct->convertedString,
|
||||
kOnlineHierarchySeparatorUnknown, &convertedCanonicalName);
|
||||
char *convertedName = CreateUtf7ConvertedString(GetServerStateParser().GetSelectedMailboxName(), PR_FALSE);
|
||||
if (convertedName )
|
||||
{
|
||||
m_runningUrl->AllocateCanonicalPath(convertedName,
|
||||
kOnlineHierarchySeparatorUnknown, &convertedCanonicalName);
|
||||
PR_Free(convertedName);
|
||||
}
|
||||
}
|
||||
|
||||
deleteMsg->onlineFolderName = convertedCanonicalName;
|
||||
|
@ -3707,16 +3705,80 @@ nsImapProtocol::PercentProgressUpdateEvent(char *message, PRInt32 percent)
|
|||
m_imapMiscellaneousSink->PercentProgress(this, &aProgressInfo);
|
||||
}
|
||||
|
||||
// utility function calls made by the server
|
||||
// convert back and forth between imap utf7 and unicode.
|
||||
char*
|
||||
nsImapProtocol::CreateUtf7ConvertedString(const char * aSourceString, PRBool
|
||||
aConvertToUtf7Imap)
|
||||
nsImapProtocol::CreateUtf7ConvertedString(const char * aSourceString,
|
||||
PRBool aConvertToUtf7Imap)
|
||||
{
|
||||
nsresult res;
|
||||
char *dstPtr = nsnull;
|
||||
PRInt32 dstLength = 0;
|
||||
// ***** temporary **** Fix me ****
|
||||
if (aSourceString)
|
||||
return PL_strdup(aSourceString);
|
||||
else
|
||||
return nsnull;
|
||||
|
||||
// we haven't turned this code on yet - we're working on it.
|
||||
char *convertedString = NULL;
|
||||
|
||||
NS_WITH_SERVICE(nsICharsetConverterManager, ccm, kCharsetConverterManagerCID, &res);
|
||||
|
||||
if(NS_SUCCEEDED(res) && (nsnull != ccm))
|
||||
{
|
||||
nsString aCharset("x-imap4-modified-utf7");
|
||||
PRUnichar *unichars;
|
||||
PRInt32 unicharLength;
|
||||
|
||||
if (!aConvertToUtf7Imap)
|
||||
{
|
||||
// convert utf7 to unicode
|
||||
nsIUnicodeDecoder* decoder = nsnull;
|
||||
|
||||
res = ccm->GetUnicodeDecoder(&aCharset, &decoder);
|
||||
if(NS_SUCCEEDED(res) && (nsnull != decoder))
|
||||
{
|
||||
PRInt32 srcLen = PL_strlen(aSourceString);
|
||||
res = decoder->Length(aSourceString, 0, srcLen, &unicharLength);
|
||||
// temporary buffer to hold unicode string
|
||||
unichars = new PRUnichar[unicharLength];
|
||||
if (unichars == nsnull)
|
||||
{
|
||||
res = NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
else
|
||||
{
|
||||
res = decoder->Convert(unichars, 0, &unicharLength, aSourceString, 0, &srcLen);
|
||||
}
|
||||
NS_IF_RELEASE(decoder);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// convert from unicode to modified utf7
|
||||
nsIUnicodeEncoder* encoder = nsnull;
|
||||
aCharset.SetString("x-imap4-modified-utf7");
|
||||
res = ccm->GetUnicodeEncoder(&aCharset, &encoder);
|
||||
if(NS_SUCCEEDED(res) && (nsnull != encoder))
|
||||
{
|
||||
res = encoder->GetMaxLength(unichars, unicharLength, &dstLength);
|
||||
// allocale an output buffer
|
||||
dstPtr = (char *) PR_Malloc(dstLength + 1);
|
||||
if (dstPtr == nsnull)
|
||||
{
|
||||
res = NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
else
|
||||
{
|
||||
res = encoder->Convert(unichars, &unicharLength, dstPtr, &dstLength);
|
||||
}
|
||||
}
|
||||
NS_IF_RELEASE(encoder);
|
||||
}
|
||||
delete [] unichars;
|
||||
}
|
||||
|
||||
return convertedString;
|
||||
}
|
||||
|
||||
// imap commands issued by the parser
|
||||
|
@ -4405,10 +4467,12 @@ void nsImapProtocol::DiscoverMailboxList()
|
|||
const char *prefix = ns->GetPrefix();
|
||||
if (prefix)
|
||||
{
|
||||
static PRBool gHideUnusedNamespaces = PR_TRUE;
|
||||
// mscott -> WARNING!!! i where are we going to get this
|
||||
// global variable for unusued name spaces from??? *wince*
|
||||
#ifdef NOT_YET
|
||||
if (/* !gHideUnusedNamespaces && */ *prefix &&
|
||||
// dmb - we should get this from a per-host preference,
|
||||
// I'd say. But for now, just make it TRUE;
|
||||
if (!gHideUnusedNamespaces && *prefix &&
|
||||
PL_strcasecmp(prefix, "INBOX.")) // only do it for
|
||||
// non-empty namespace prefixes, and for non-INBOX prefix
|
||||
{
|
||||
|
@ -4452,7 +4516,6 @@ void nsImapProtocol::DiscoverMailboxList()
|
|||
else
|
||||
HandleMemoryFailure();
|
||||
}
|
||||
#endif
|
||||
|
||||
// now do the folders within this namespace
|
||||
nsString2 pattern("",eOneByte);
|
||||
|
|
Загрузка…
Ссылка в новой задаче