fix msf file names for imap folders with illegal characters, r=mscott 20324

This commit is contained in:
bienvenu%netscape.com 1999-12-07 05:51:53 +00:00
Родитель 7a9b108c96
Коммит 5eb045931d
8 изменённых файлов: 161 добавлений и 5 удалений

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

@ -275,7 +275,7 @@ interface nsIMsgFolder : nsIFolder {
/**
* local path of this folder
*/
readonly attribute nsIFileSpec path;
attribute nsIFileSpec path;
void markMessagesRead(in nsISupportsArray messages, in boolean markRead);
void markAllMessagesRead();

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

@ -30,6 +30,18 @@
#include "nsMsgBaseCID.h"
#include "nsIMsgMailNewsUrl.h"
#include "nsIMsgAccountManager.h"
#include "nsXPIDLString.h"
#if defined(XP_WIN16) || defined(XP_OS2)
#define MAX_FILE_LENGTH_WITHOUT_EXTENSION 8
#elif defined(XP_MAC)
#define MAX_FILE_LENGTH_WITHOUT_EXTENSION 26
#elif defined(XP_WIN32)
#define MAX_FILE_LENGTH_WITHOUT_EXTENSION 256
#else
#define MAX_FILE_LENGTH_WITHOUT_EXTENSION 32000
#endif
static NS_DEFINE_CID(kPrefServiceCID, NS_PREF_CID);
static NS_DEFINE_CID(kMsgAccountManagerCID, NS_MSGACCOUNTMANAGER_CID);
@ -320,6 +332,111 @@ nsresult nsMsgDBFolder::SendFlagNotifications(nsISupports *item, PRUint32 oldFla
return rv;
}
// path coming in is the root path without the leaf name,
// on the way out, it's the whole path.
nsresult nsMsgDBFolder::CreatePlatformLeafNameForDisk(const char *userLeafName, nsFileSpec &path, char **resultName)
{
const int charLimit = MAX_FILE_LENGTH_WITHOUT_EXTENSION; // set on platform specific basis
#if XP_MAC
nsCAutoString illegalChars = ":";
#elif defined(XP_WIN16) || defined(XP_OS2)
nsCAutoString illegalChars = "\"/\\[]:;=,|?<>*$. ";
#elif defined(XP_WIN32)
nsCAutoString illegalChars = "\"/\\[]:;=,|?<>*$";
#else // UNIX
nsCAutoString illegalChars = "";
#endif
if (!resultName || !userLeafName)
return NS_ERROR_NULL_POINTER;
*resultName = nsnull;
// mangledLeaf is the new leaf name.
// If userLeafName (a) contains all legal characters
// (b) is within the valid length for the given platform
// (c) does not already exist on the disk
// then we simply return nsCRT::strdup(userLeafName)
// Otherwise we mangle it
// leafLength is the length of mangledLeaf which we will return
// if userLeafName is greater than the maximum allowed for this
// platform, then we truncate and mangle it. Otherwise leave it alone.
PRInt32 leafLength;
// mangledPath is the entire path to the newly mangled leaf name
nsCAutoString mangledLeaf = userLeafName;
PRInt32 illegalCharacterIndex = mangledLeaf.FindCharInSet(illegalChars);
PRBool exists;
if (illegalCharacterIndex == kNotFound)
{
path += (const char *) mangledLeaf;
if (!path.Exists())
{
// if there are no illegal characters
// and the file doesn't already exist, then don't do anything to the string
// Note that this might be truncated to charLength, but if so, the file still
// does not exist, so we are OK.
*resultName = mangledLeaf.ToNewCString();
return (*resultName) ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
}
}
else
{
// First, replace all illegal characters with '_'
mangledLeaf.ReplaceChar(illegalChars, '_');
path += (const char *) mangledLeaf;
}
// if we are here, then any of the following may apply:
// (a) there were illegal characters
// (b) the file already existed
// Now, we have to loop until we find a filename that doesn't already
// exist on the disk
PRBool nameSpaceExhausted = FALSE;
nsXPIDLCString leafName;
path.SetLeafName(mangledLeaf.GetBuffer());
exists = path.Exists();
leafLength = mangledLeaf.Length();
if (exists)
{
if (leafLength >= 2)
mangledLeaf.SetCharAt(leafLength - 2, 'A');
mangledLeaf.SetCharAt(leafLength - 1, 'A'); // leafLength must be at least 1
}
while (!nameSpaceExhausted && path.Exists())
{
if (leafLength >= 2)
{
PRUnichar lastChar = mangledLeaf.CharAt(leafLength - 1);
mangledLeaf.SetCharAt(leafLength - 1, ++lastChar);
if (lastChar > 'Z')
{
mangledLeaf.SetCharAt(leafLength - 1,'A');
PRUnichar nextToLastChar = mangledLeaf.CharAt(leafLength - 2);
mangledLeaf.SetCharAt(leafLength - 2, nextToLastChar + 1);
nameSpaceExhausted = (nextToLastChar == 'Z');
}
}
else
{
PRUnichar lastChar = mangledLeaf.CharAt(leafLength - 1);
mangledLeaf.SetCharAt(leafLength - 1, ++lastChar);
nameSpaceExhausted = (lastChar == 'Z');
}
}
*resultName = mangledLeaf.ToNewCString();
return NS_OK;
}
NS_IMETHODIMP
nsMsgDBFolder::GetMsgDatabase(nsIMsgDatabase** aMsgDatabase)
{
@ -607,3 +724,4 @@ nsMsgDBFolder::OnStopRunningUrl(nsIURI *aUrl, nsresult aExitCode)
}
return NS_OK;
}

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

@ -76,6 +76,7 @@ protected:
nsresult ReadFromFolderCache(nsIMsgFolderCacheElement *element);
nsresult OnKeyAddedOrDeleted(nsMsgKey aKeyChanged, nsMsgKey aParentKey , PRInt32 aFlags,
nsIDBChangeListener * aInstigator, PRBool added, PRBool doFlat, PRBool doThread);
nsresult CreatePlatformLeafNameForDisk(const char *userLeafName, nsFileSpec &baseDir, char **resultName);
protected:
nsCOMPtr<nsIMsgDatabase> mDatabase;

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

@ -1733,8 +1733,13 @@ nsMsgFolder::GetPath(nsIFileSpec * *aPath)
nsCOMPtr<nsIFileSpec> path;
rv = server->GetLocalPath(getter_AddRefs(path));
if (NS_FAILED(rv)) return rv;
return rv;
}
NS_IMETHODIMP
nsMsgFolder::SetPath(nsIFileSpec * /* aPath */)
{
return NS_ERROR_NOT_IMPLEMENTED;
}

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

@ -141,6 +141,7 @@ public:
NS_IMETHOD GetRootFolder(nsIMsgFolder * *aRootFolder);
NS_IMETHOD GetMsgDatabase(nsIMsgDatabase * *aMsgDatabase);
NS_IMETHOD GetPath(nsIFileSpec * *aPath);
NS_IMETHOD SetPath(nsIFileSpec * aPath);
NS_IMETHOD MarkMessagesRead(nsISupportsArray *messages, PRBool markRead);
NS_IMETHOD MarkAllMessagesRead(void);
NS_IMETHOD MarkMessagesFlagged(nsISupportsArray *messages, PRBool markFlagged);

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

@ -289,7 +289,7 @@ static PRUint32 StringHash(const char *ubuf)
nsresult NS_MsgHashIfNecessary(nsCAutoString &name)
{
#if defined(XP_WIN16) || defined(XP_OS2)
#if defined(XP_OS2)
const PRUint32 MAX_LEN = 8;
#elif defined(XP_MAC)
const PRUint32 MAX_LEN = 25;

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

@ -176,6 +176,19 @@ NS_IMETHODIMP nsImapMailFolder::GetPath(nsIFileSpec** aPathName)
return NS_OK;
}
NS_IMETHODIMP nsImapMailFolder::SetPath(nsIFileSpec * aPathName)
{
if (!aPathName)
return NS_ERROR_NULL_POINTER;
if (! m_pathName)
{
m_pathName = new nsFileSpec("");
if (! m_pathName)
return NS_ERROR_OUT_OF_MEMORY;
}
return aPathName->GetFileSpec(m_pathName);
}
NS_IMETHODIMP nsImapMailFolder::Enumerate(nsIEnumerator* *result)
{
@ -314,6 +327,14 @@ nsresult nsImapMailFolder::CreateSubFolders(nsFileSpec &path)
}
AddSubfolder(&currentFolderNameStr, getter_AddRefs(child));
// make the imap folder remember the file spec it was created with.
if (child)
{
nsCOMPtr <nsIFileSpec> msfFileSpec;
nsresult rv = NS_NewFileSpecWithSpec(currentFolderPath, getter_AddRefs(msfFileSpec));
if (NS_SUCCEEDED(rv) && msfFileSpec)
child->SetPath(msfFileSpec);
}
PL_strfree(folderName);
}
return rv;
@ -544,9 +565,10 @@ NS_IMETHODIMP nsImapMailFolder::CreateClientSubfolderInfo(const char *folderName
return parentFolder->CreateClientSubfolderInfo(nsCAutoString(leafName));
}
// if we get here, it's really a leaf, and "this" is the parent.
folderNameStr = leafName;
path += folderNameStr;
// path += folderNameStr;
// Create an empty database for this mail folder, set its name from the user
nsCOMPtr<nsIMsgDatabase> mailDBFactory;
@ -557,6 +579,12 @@ NS_IMETHODIMP nsImapMailFolder::CreateClientSubfolderInfo(const char *folderName
{
nsCOMPtr<nsIMsgDatabase> unusedDB;
nsCOMPtr <nsIFileSpec> dbFileSpec;
nsXPIDLCString uniqueLeafName;
rv = CreatePlatformLeafNameForDisk(folderName, path, getter_Copies(uniqueLeafName));
path.SetLeafName(uniqueLeafName);
NS_NewFileSpecWithSpec(path, getter_AddRefs(dbFileSpec));
rv = mailDBFactory->Open(dbFileSpec, PR_TRUE, PR_TRUE, (nsIMsgDatabase **) getter_AddRefs(unusedDB));
@ -573,6 +601,8 @@ NS_IMETHODIMP nsImapMailFolder::CreateClientSubfolderInfo(const char *folderName
//Now let's create the actual new folder
rv = AddSubfolder(&folderNameStr, getter_AddRefs(child));
if (NS_SUCCEEDED(rv) && child)
child->SetPath(dbFileSpec);
nsCOMPtr <nsIMsgImapMailFolder> imapFolder = do_QueryInterface(child);
if (imapFolder)

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

@ -164,6 +164,7 @@ public:
NS_IMETHOD GetNewMessages(nsIMsgWindow *aWindow);
NS_IMETHOD GetPath(nsIFileSpec** aPathName);
NS_IMETHOD SetPath(nsIFileSpec * aPath);
// nsIMsgImapMailFolder methods
NS_DECL_NSIMSGIMAPMAILFOLDER
@ -314,7 +315,7 @@ protected:
nsresult BuildIdsAndKeyArray(nsISupportsArray* messages,
nsCString& msgIds, nsMsgKeyArray& keyArray);
nsNativeFileSpec *m_pathName;
nsFileSpec *m_pathName;
PRBool m_initialized;
PRBool m_haveDiscoveredAllFolders;
PRBool m_haveReadNameFromDB;