fix handling of hosts without namespace extension, start working on utf7 stuff

This commit is contained in:
bienvenu%netscape.com 1999-06-23 21:48:25 +00:00
Родитель e3821db151
Коммит b452d4eb99
8 изменённых файлов: 317 добавлений и 26 удалений

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

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