aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVincent Richard <[email protected]>2006-04-23 08:48:19 +0000
committerVincent Richard <[email protected]>2006-04-23 08:48:19 +0000
commit6933fb8a30cf17ae90394fca5114b8e600ef2cfd (patch)
tree7f35e7226f7179993eb0a7cbdb9953a4fa19fa26
parentRenamed 'byte' to 'byte_t'. (diff)
downloadvmime-6933fb8a30cf17ae90394fca5114b8e600ef2cfd.tar.gz
vmime-6933fb8a30cf17ae90394fca5114b8e600ef2cfd.zip
Folder deletion.
-rw-r--r--ChangeLog5
-rw-r--r--src/net/imap/IMAPFolder.cpp37
-rw-r--r--src/net/maildir/maildirFolder.cpp36
-rw-r--r--src/net/maildir/maildirUtils.cpp41
-rw-r--r--src/net/pop3/POP3Folder.cpp6
-rw-r--r--vmime/net/folder.hpp31
-rw-r--r--vmime/net/imap/IMAPFolder.hpp2
-rw-r--r--vmime/net/maildir/maildirFolder.hpp2
-rw-r--r--vmime/net/maildir/maildirUtils.hpp6
-rw-r--r--vmime/net/pop3/POP3Folder.hpp2
10 files changed, 168 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index e9d59b68..e7a0ebc9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,11 @@
VERSION 0.8.1cvs
================
+2006-04-23 Vincent Richard <[email protected]>
+
+ * Added vmime::net::folder::destroy() to delete folders on IMAP and
+ maildir stores.
+
2006-04-18 Vincent Richard <[email protected]>
* Renamed 'byte' to 'byte_t' to fix compilation problems on Fedora
diff --git a/src/net/imap/IMAPFolder.cpp b/src/net/imap/IMAPFolder.cpp
index 0179620b..09d33b68 100644
--- a/src/net/imap/IMAPFolder.cpp
+++ b/src/net/imap/IMAPFolder.cpp
@@ -371,6 +371,43 @@ void IMAPFolder::create(const int type)
}
+void IMAPFolder::destroy()
+{
+ ref <IMAPStore> store = m_store.acquire();
+
+ if (!store)
+ throw exceptions::illegal_state("Store disconnected");
+
+ if (isOpen())
+ throw exceptions::illegal_state("Folder is open");
+
+ const string mailbox = IMAPUtils::pathToString
+ (m_connection->hierarchySeparator(), getFullPath());
+
+ std::ostringstream oss;
+ oss << "DELETE " << IMAPUtils::quoteString(mailbox);
+
+ m_connection->send(true, oss.str(), true);
+
+
+ utility::auto_ptr <IMAPParser::response> resp(m_connection->readResponse());
+
+ if (resp->isBad() || resp->response_done()->response_tagged()->
+ resp_cond_state()->status() != IMAPParser::resp_cond_state::OK)
+ {
+ throw exceptions::command_error("DELETE",
+ m_connection->getParser()->lastLine(), "bad response");
+ }
+
+ // Notify folder deleted
+ events::folderEvent event
+ (thisRef().dynamicCast <folder>(),
+ events::folderEvent::TYPE_DELETED, m_path, m_path);
+
+ notifyFolder(event);
+}
+
+
const bool IMAPFolder::exists()
{
ref <IMAPStore> store = m_store.acquire();
diff --git a/src/net/maildir/maildirFolder.cpp b/src/net/maildir/maildirFolder.cpp
index 7e596382..dc89f131 100644
--- a/src/net/maildir/maildirFolder.cpp
+++ b/src/net/maildir/maildirFolder.cpp
@@ -242,6 +242,42 @@ void maildirFolder::create(const int /* type */)
}
+void maildirFolder::destroy()
+{
+ ref <maildirStore> store = m_store.acquire();
+
+ if (!store)
+ throw exceptions::illegal_state("Store disconnected");
+ else if (isOpen())
+ throw exceptions::illegal_state("Folder is open");
+
+ // Delete 'folder' and '.folder.directory' directories
+ utility::fileSystemFactory* fsf = platformDependant::getHandler()->getFileSystemFactory();
+
+ ref <utility::file> rootDir = fsf->create
+ (maildirUtils::getFolderFSPath(store, m_path, maildirUtils::FOLDER_PATH_ROOT));
+ ref <utility::file> contDir = fsf->create
+ (maildirUtils::getFolderFSPath(store, m_path, maildirUtils::FOLDER_PATH_CONTAINER));
+
+ try
+ {
+ maildirUtils::recursiveFSDelete(rootDir);
+ maildirUtils::recursiveFSDelete(contDir);
+ }
+ catch (std::exception&)
+ {
+ // Ignore exception: anyway, we can't recover from this...
+ }
+
+ // Notify folder deleted
+ events::folderEvent event
+ (thisRef().dynamicCast <folder>(),
+ events::folderEvent::TYPE_DELETED, m_path, m_path);
+
+ notifyFolder(event);
+}
+
+
const bool maildirFolder::exists()
{
ref <maildirStore> store = m_store.acquire();
diff --git a/src/net/maildir/maildirUtils.cpp b/src/net/maildir/maildirUtils.cpp
index c0594a31..00a9a7b1 100644
--- a/src/net/maildir/maildirUtils.cpp
+++ b/src/net/maildir/maildirUtils.cpp
@@ -22,6 +22,9 @@
#include "vmime/utility/random.hpp"
+#include "vmime/exception.hpp"
+#include "vmime/platformDependant.hpp"
+
namespace vmime {
namespace net {
@@ -212,6 +215,44 @@ const utility::file::path::component maildirUtils::generateId()
}
+void maildirUtils::recursiveFSDelete(ref <utility::file> dir)
+{
+ ref <utility::fileIterator> files = dir->getFiles();
+
+ // First, delete files and subdirectories in this directory
+ while (files->hasMoreElements())
+ {
+ ref <utility::file> file = files->nextElement();
+
+ if (file->isDirectory())
+ {
+ maildirUtils::recursiveFSDelete(file);
+ }
+ else
+ {
+ try
+ {
+ file->remove();
+ }
+ catch (exceptions::filesystem_exception&)
+ {
+ // Ignore
+ }
+ }
+ }
+
+ // Then, delete this (empty) directory
+ try
+ {
+ dir->remove();
+ }
+ catch (exceptions::filesystem_exception&)
+ {
+ // Ignore
+ }
+}
+
+
//
// messageIdComparator
diff --git a/src/net/pop3/POP3Folder.cpp b/src/net/pop3/POP3Folder.cpp
index 657e1bdd..7ef4aa12 100644
--- a/src/net/pop3/POP3Folder.cpp
+++ b/src/net/pop3/POP3Folder.cpp
@@ -184,6 +184,12 @@ void POP3Folder::create(const int /* type */)
}
+void POP3Folder::destroy()
+{
+ throw exceptions::operation_not_supported();
+}
+
+
const bool POP3Folder::exists()
{
ref <POP3Store> store = m_store.acquire();
diff --git a/vmime/net/folder.hpp b/vmime/net/folder.hpp
index 5edba493..a6427c85 100644
--- a/vmime/net/folder.hpp
+++ b/vmime/net/folder.hpp
@@ -132,18 +132,21 @@ public:
* is not available, a more restricted mode will be selected automatically.
* If set to true and if the requested mode is not available, the opening
* will fail.
+ * @throw net_exception if an error occurs
*/
virtual void open(const int mode, bool failIfModeIsNotAvailable = false) = 0;
/** Close this folder.
*
* @param expunge if set to true, deleted messages are expunged
+ * @throw net_exception if an error occurs
*/
virtual void close(const bool expunge) = 0;
/** Create this folder.
*
* @param type folder type (see folder::Types)
+ * @throw net_exception if an error occurs
*/
virtual void create(const int type) = 0;
@@ -153,6 +156,13 @@ public:
*/
virtual const bool exists() = 0;
+ /** Delete this folder.
+ * The folder should be closed before attempting to delete it.
+ *
+ * @throw net_exception if an error occurs
+ */
+ virtual void destroy() = 0;
+
/** Test whether this folder is open.
*
* @return true if the folder is open, false otherwise
@@ -163,6 +173,7 @@ public:
*
* @param num message sequence number
* @return a new object referencing the specified message
+ * @throw net_exception if an error occurs
*/
virtual ref <message> getMessage(const int num) = 0;
@@ -171,6 +182,7 @@ public:
* @param from sequence number of the first message to get
* @param to sequence number of the last message to get
* @return new objects referencing the specified messages
+ * @throw net_exception if an error occurs
*/
virtual std::vector <ref <message> > getMessages(const int from = 1, const int to = -1) = 0;
@@ -178,6 +190,7 @@ public:
*
* @param nums sequence numbers of the messages to delete
* @return new objects referencing the specified messages
+ * @throw net_exception if an error occurs
*/
virtual std::vector <ref <message> > getMessages(const std::vector <int>& nums) = 0;
@@ -191,6 +204,7 @@ public:
*
* @param name sub-folder name
* @return a new object referencing the specified folder
+ * @throw net_exception if an error occurs
*/
virtual ref <folder> getFolder(const folder::path::component& name) = 0;
@@ -199,18 +213,21 @@ public:
* @param recursive if set to true, all the descendant are returned.
* If set to false, only the direct children are returned.
* @return list of sub-folders
+ * @throw net_exception if an error occurs
*/
virtual std::vector <ref <folder> > getFolders(const bool recursive = false) = 0;
/** Rename (move) this folder to another location.
*
* @param newPath new path of the folder
+ * @throw net_exception if an error occurs
*/
virtual void rename(const folder::path& newPath) = 0;
/** Remove a message in this folder.
*
* @param num sequence number of the message to delete
+ * @throw net_exception if an error occurs
*/
virtual void deleteMessage(const int num) = 0;
@@ -218,12 +235,14 @@ public:
*
* @param from sequence number of the first message to delete
* @param to sequence number of the last message to delete
+ * @throw net_exception if an error occurs
*/
virtual void deleteMessages(const int from = 1, const int to = -1) = 0;
/** Remove one or more messages from this folder.
*
* @param nums sequence numbers of the messages to delete
+ * @throw net_exception if an error occurs
*/
virtual void deleteMessages(const std::vector <int>& nums) = 0;
@@ -233,6 +252,7 @@ public:
* @param to sequence number of the last message to modify
* @param flags set of flags (see message::Flags)
* @param mode indicate how to treat old and new flags (see message::FlagsModes)
+ * @throw net_exception if an error occurs
*/
virtual void setMessageFlags(const int from, const int to, const int flags, const int mode = message::FLAG_MODE_SET) = 0;
@@ -241,6 +261,7 @@ public:
* @param nums sequence numbers of the messages to modify
* @param flags set of flags (see message::Flags)
* @param mode indicate how to treat old and new flags (see message::FlagsModes)
+ * @throw net_exception if an error occurs
*/
virtual void setMessageFlags(const std::vector <int>& nums, const int flags, const int mode = message::FLAG_MODE_SET) = 0;
@@ -250,6 +271,7 @@ public:
* @param flags flags for the new message
* @param date date/time for the new message (if NULL, the current time is used)
* @param progress progress listener, or NULL if not used
+ * @throw net_exception if an error occurs
*/
virtual void addMessage(ref <vmime::message> msg, const int flags = message::FLAG_UNDEFINED, vmime::datetime* date = NULL, utility::progressListener* progress = NULL) = 0;
@@ -260,6 +282,7 @@ public:
* @param flags flags for the new message
* @param date date/time for the new message (if NULL, the current time is used)
* @param progress progress listener, or NULL if not used
+ * @throw net_exception if an error occurs
*/
virtual void addMessage(utility::inputStream& is, const int size, const int flags = message::FLAG_UNDEFINED, vmime::datetime* date = NULL, utility::progressListener* progress = NULL) = 0;
@@ -267,6 +290,7 @@ public:
*
* @param dest destination folder path
* @param num sequence number of the message to copy
+ * @throw net_exception if an error occurs
*/
virtual void copyMessage(const folder::path& dest, const int num) = 0;
@@ -275,6 +299,7 @@ public:
* @param dest destination folder path
* @param from sequence number of the first message to copy
* @param to sequence number of the last message to copy
+ * @throw net_exception if an error occurs
*/
virtual void copyMessages(const folder::path& dest, const int from = 1, const int to = -1) = 0;
@@ -282,6 +307,7 @@ public:
*
* @param dest destination folder path
* @param nums sequence numbers of the messages to copy
+ * @throw net_exception if an error occurs
*/
virtual void copyMessages(const folder::path& dest, const std::vector <int>& nums) = 0;
@@ -289,10 +315,13 @@ public:
*
* @param count will receive the number of messages in the folder
* @param unseen will receive the number of unseen messages in the folder
+ * @throw net_exception if an error occurs
*/
virtual void status(int& count, int& unseen) = 0;
/** Expunge deleted messages.
+ *
+ * @throw net_exception if an error occurs
*/
virtual void expunge() = 0;
@@ -335,6 +364,7 @@ public:
* @param msg list of message sequence numbers
* @param options objects to fetch (combination of folder::FetchOptions flags)
* @param progress progress listener, or NULL if not used
+ * @throw net_exception if an error occurs
*/
virtual void fetchMessages(std::vector <ref <message> >& msg, const int options, utility::progressListener* progress = NULL) = 0;
@@ -342,6 +372,7 @@ public:
*
* @param msg the message
* @param options objects to fetch (combination of folder::FetchOptions flags)
+ * @throw net_exception if an error occurs
*/
virtual void fetchMessage(ref <message> msg, const int options) = 0;
diff --git a/vmime/net/imap/IMAPFolder.hpp b/vmime/net/imap/IMAPFolder.hpp
index 5662c349..2ad695f0 100644
--- a/vmime/net/imap/IMAPFolder.hpp
+++ b/vmime/net/imap/IMAPFolder.hpp
@@ -77,6 +77,8 @@ public:
const bool exists();
+ void destroy();
+
const bool isOpen() const;
ref <message> getMessage(const int num);
diff --git a/vmime/net/maildir/maildirFolder.hpp b/vmime/net/maildir/maildirFolder.hpp
index 1e073b47..d7a7d3be 100644
--- a/vmime/net/maildir/maildirFolder.hpp
+++ b/vmime/net/maildir/maildirFolder.hpp
@@ -78,6 +78,8 @@ public:
const bool exists();
+ void destroy();
+
const bool isOpen() const;
ref <message> getMessage(const int num);
diff --git a/vmime/net/maildir/maildirUtils.hpp b/vmime/net/maildir/maildirUtils.hpp
index 94484bd5..4f163bd5 100644
--- a/vmime/net/maildir/maildirUtils.hpp
+++ b/vmime/net/maildir/maildirUtils.hpp
@@ -148,6 +148,12 @@ public:
*/
static const utility::file::path::component generateId();
+ /** Recursively delete a directory on the file system.
+ *
+ * @param dir directory to delete
+ */
+ static void recursiveFSDelete(ref <utility::file> dir);
+
private:
static const vmime::word TMP_DIR;
diff --git a/vmime/net/pop3/POP3Folder.hpp b/vmime/net/pop3/POP3Folder.hpp
index 28a63c93..386f9ae7 100644
--- a/vmime/net/pop3/POP3Folder.hpp
+++ b/vmime/net/pop3/POP3Folder.hpp
@@ -76,6 +76,8 @@ public:
const bool exists();
+ void destroy();
+
const bool isOpen() const;
ref <message> getMessage(const int num);