Done rename() operation on 'maildir' + fixed some bugs/limitations in maildir/IMAP.

This commit is contained in:
Vincent Richard 2004-12-22 11:01:17 +00:00
parent 056e22f76f
commit a4251085d2
3 changed files with 116 additions and 23 deletions

View File

@ -323,6 +323,8 @@ void IMAPFolder::create(const int type)
throw exceptions::illegal_state("Folder is open");
else if (exists())
throw exceptions::illegal_state("Folder already exists");
else if (!m_store->isValidFolderName(m_name))
throw exceptions::invalid_folder_name();
// Emit the "CREATE" command
//
@ -1258,10 +1260,12 @@ void IMAPFolder::rename(const folder::path& newPath)
{
if (!m_store)
throw exceptions::illegal_state("Store disconnected");
else if (isOpen())
throw exceptions::illegal_state("Folder open");
else if (m_path.isEmpty() || newPath.isEmpty())
throw exceptions::illegal_operation("Cannot rename root folder");
else if (m_path.getSize() == 1 && m_name.getBuffer() == "INBOX")
throw exceptions::illegal_operation("Cannot rename 'INBOX' folder");
else if (!m_store->isValidFolderName(newPath.getLastComponent()))
throw exceptions::invalid_folder_name();
// Build the request text
std::ostringstream command;

View File

@ -124,7 +124,7 @@ void maildirFolder::open(const int mode, bool /* failIfModeIsNotAvailable */)
else if (isOpen())
throw exceptions::illegal_state("Folder is already open");
else if (!exists())
throw exceptions::illegal_state("Folder already exists");
throw exceptions::illegal_state("Folder does not exist");
scanFolder();
@ -141,6 +141,9 @@ void maildirFolder::close(const bool expunge)
if (!isOpen())
throw exceptions::illegal_state("Folder not open");
if (expunge)
this->expunge();
m_open = false;
m_mode = -1;
@ -176,7 +179,7 @@ void maildirFolder::unregisterMessage(maildirMessage* msg)
}
void maildirFolder::create(const int type)
void maildirFolder::create(const int /* type */)
{
if (!m_store)
throw exceptions::illegal_state("Store disconnected");
@ -184,21 +187,8 @@ void maildirFolder::create(const int type)
throw exceptions::illegal_state("Folder is open");
else if (exists())
throw exceptions::illegal_state("Folder already exists");
// Folder name cannot start with '.'
if (!m_path.isEmpty())
{
const path::component& comp = m_path.getLastComponent();
const int length = comp.getBuffer().length();
int pos = 0;
while ((pos < length) && (comp.getBuffer()[pos] == '.'))
++pos;
if (pos != 0)
throw exceptions::invalid_folder_name("Name cannot start with '.'");
}
else if (!m_store->isValidFolderName(m_name))
throw exceptions::invalid_folder_name();
// Create directory on file system
try
@ -521,7 +511,92 @@ void maildirFolder::listFolders(std::vector <folder*>& list, const bool recursiv
void maildirFolder::rename(const folder::path& newPath)
{
// TODO
if (!m_store)
throw exceptions::illegal_state("Store disconnected");
else if (m_path.isEmpty() || newPath.isEmpty())
throw exceptions::illegal_operation("Cannot rename root folder");
else if (!m_store->isValidFolderName(newPath.getLastComponent()))
throw exceptions::invalid_folder_name();
// Rename the directory on the file system
utility::fileSystemFactory* fsf = platformDependant::getHandler()->getFileSystemFactory();
utility::auto_ptr <utility::file> rootDir = fsf->create
(maildirUtils::getFolderFSPath(m_store, m_path, maildirUtils::FOLDER_PATH_ROOT));
utility::auto_ptr <utility::file> contDir = fsf->create
(maildirUtils::getFolderFSPath(m_store, m_path, maildirUtils::FOLDER_PATH_CONTAINER));
try
{
const utility::file::path newRootPath =
maildirUtils::getFolderFSPath(m_store, newPath, maildirUtils::FOLDER_PATH_ROOT);
const utility::file::path newContPath =
maildirUtils::getFolderFSPath(m_store, newPath, maildirUtils::FOLDER_PATH_CONTAINER);
rootDir->rename(newRootPath);
// Container directory may not exist, so ignore error when trying to rename it
try
{
contDir->rename(newContPath);
}
catch (exceptions::filesystem_exception& e)
{
// Ignore
}
}
catch (exceptions::filesystem_exception& e)
{
// Revert to old location
const utility::file::path rootPath =
maildirUtils::getFolderFSPath(m_store, m_path, maildirUtils::FOLDER_PATH_ROOT);
const utility::file::path contPath =
maildirUtils::getFolderFSPath(m_store, m_path, maildirUtils::FOLDER_PATH_CONTAINER);
try
{
rootDir->rename(rootPath);
contDir->rename(contPath);
}
catch (exceptions::filesystem_exception& e)
{
// Ignore
}
throw exceptions::command_error("RENAME", "", "", e);
}
// Notify folder renamed
folder::path oldPath(m_path);
m_path = newPath;
m_name = newPath.getLastComponent();
events::folderEvent event(this, events::folderEvent::TYPE_RENAMED, oldPath, newPath);
notifyFolder(event);
// Notify folders with the same path
for (std::list <maildirFolder*>::iterator it = m_store->m_folders.begin() ;
it != m_store->m_folders.end() ; ++it)
{
if ((*it) != this && (*it)->getFullPath() == oldPath)
{
(*it)->m_path = newPath;
(*it)->m_name = newPath.getLastComponent();
events::folderEvent event(*it, events::folderEvent::TYPE_RENAMED, oldPath, newPath);
(*it)->notifyFolder(event);
}
else if ((*it) != this && oldPath.isParentOf((*it)->getFullPath()))
{
folder::path oldPath((*it)->m_path);
(*it)->m_path.renameParent(oldPath, newPath);
events::folderEvent event(*it, events::folderEvent::TYPE_RENAMED, oldPath, (*it)->m_path);
(*it)->notifyFolder(event);
}
}
}

View File

@ -77,9 +77,23 @@ folder* maildirStore::getFolder(const folder::path& path)
const bool maildirStore::isValidFolderName(const folder::path::component& name)
{
return (platformDependant::getHandler()->
getFileSystemFactory()->isValidPathComponent(name) &&
name.getBuffer().find_first_of(".") == string::npos);
if (!platformDependant::getHandler()->getFileSystemFactory()->isValidPathComponent(name))
return false;
const string& buf = name.getBuffer();
// Name cannot start/end with spaces
if (stringUtils::trim(buf) != name.getBuffer())
return false;
// Name cannot start with '.'
const int length = buf.length();
int pos = 0;
while ((pos < length) && (buf[pos] == '.'))
++pos;
return (pos == 0);
}