Done rename() operation on 'maildir' + fixed some bugs/limitations in maildir/IMAP.
This commit is contained in:
parent
056e22f76f
commit
a4251085d2
@ -323,6 +323,8 @@ void IMAPFolder::create(const int type)
|
|||||||
throw exceptions::illegal_state("Folder is open");
|
throw exceptions::illegal_state("Folder is open");
|
||||||
else if (exists())
|
else if (exists())
|
||||||
throw exceptions::illegal_state("Folder already exists");
|
throw exceptions::illegal_state("Folder already exists");
|
||||||
|
else if (!m_store->isValidFolderName(m_name))
|
||||||
|
throw exceptions::invalid_folder_name();
|
||||||
|
|
||||||
// Emit the "CREATE" command
|
// Emit the "CREATE" command
|
||||||
//
|
//
|
||||||
@ -1258,10 +1260,12 @@ void IMAPFolder::rename(const folder::path& newPath)
|
|||||||
{
|
{
|
||||||
if (!m_store)
|
if (!m_store)
|
||||||
throw exceptions::illegal_state("Store disconnected");
|
throw exceptions::illegal_state("Store disconnected");
|
||||||
else if (isOpen())
|
else if (m_path.isEmpty() || newPath.isEmpty())
|
||||||
throw exceptions::illegal_state("Folder open");
|
throw exceptions::illegal_operation("Cannot rename root folder");
|
||||||
else if (m_path.getSize() == 1 && m_name.getBuffer() == "INBOX")
|
else if (m_path.getSize() == 1 && m_name.getBuffer() == "INBOX")
|
||||||
throw exceptions::illegal_operation("Cannot rename 'INBOX' folder");
|
throw exceptions::illegal_operation("Cannot rename 'INBOX' folder");
|
||||||
|
else if (!m_store->isValidFolderName(newPath.getLastComponent()))
|
||||||
|
throw exceptions::invalid_folder_name();
|
||||||
|
|
||||||
// Build the request text
|
// Build the request text
|
||||||
std::ostringstream command;
|
std::ostringstream command;
|
||||||
|
@ -124,7 +124,7 @@ void maildirFolder::open(const int mode, bool /* failIfModeIsNotAvailable */)
|
|||||||
else if (isOpen())
|
else if (isOpen())
|
||||||
throw exceptions::illegal_state("Folder is already open");
|
throw exceptions::illegal_state("Folder is already open");
|
||||||
else if (!exists())
|
else if (!exists())
|
||||||
throw exceptions::illegal_state("Folder already exists");
|
throw exceptions::illegal_state("Folder does not exist");
|
||||||
|
|
||||||
scanFolder();
|
scanFolder();
|
||||||
|
|
||||||
@ -141,6 +141,9 @@ void maildirFolder::close(const bool expunge)
|
|||||||
if (!isOpen())
|
if (!isOpen())
|
||||||
throw exceptions::illegal_state("Folder not open");
|
throw exceptions::illegal_state("Folder not open");
|
||||||
|
|
||||||
|
if (expunge)
|
||||||
|
this->expunge();
|
||||||
|
|
||||||
m_open = false;
|
m_open = false;
|
||||||
m_mode = -1;
|
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)
|
if (!m_store)
|
||||||
throw exceptions::illegal_state("Store disconnected");
|
throw exceptions::illegal_state("Store disconnected");
|
||||||
@ -184,21 +187,8 @@ void maildirFolder::create(const int type)
|
|||||||
throw exceptions::illegal_state("Folder is open");
|
throw exceptions::illegal_state("Folder is open");
|
||||||
else if (exists())
|
else if (exists())
|
||||||
throw exceptions::illegal_state("Folder already exists");
|
throw exceptions::illegal_state("Folder already exists");
|
||||||
|
else if (!m_store->isValidFolderName(m_name))
|
||||||
// Folder name cannot start with '.'
|
throw exceptions::invalid_folder_name();
|
||||||
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 '.'");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create directory on file system
|
// Create directory on file system
|
||||||
try
|
try
|
||||||
@ -521,7 +511,92 @@ void maildirFolder::listFolders(std::vector <folder*>& list, const bool recursiv
|
|||||||
|
|
||||||
void maildirFolder::rename(const folder::path& newPath)
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -77,9 +77,23 @@ folder* maildirStore::getFolder(const folder::path& path)
|
|||||||
|
|
||||||
const bool maildirStore::isValidFolderName(const folder::path::component& name)
|
const bool maildirStore::isValidFolderName(const folder::path::component& name)
|
||||||
{
|
{
|
||||||
return (platformDependant::getHandler()->
|
if (!platformDependant::getHandler()->getFileSystemFactory()->isValidPathComponent(name))
|
||||||
getFileSystemFactory()->isValidPathComponent(name) &&
|
return false;
|
||||||
name.getBuffer().find_first_of(".") == string::npos);
|
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user