diff options
author | Wojtek Kosior <wk@koszkonutek-tmp.pl.eu.org> | 2021-04-30 00:33:56 +0200 |
---|---|---|
committer | Wojtek Kosior <wk@koszkonutek-tmp.pl.eu.org> | 2021-04-30 00:33:56 +0200 |
commit | aa4d426b4d3527d7e166df1a05058c9a4a0f6683 (patch) | |
tree | 4ff17ce8b89a2321b9d0ed4bcfc37c447bcb6820 /vmime-master/src/vmime/net/maildir/maildirUtils.cpp | |
download | smtps-and-pop3s-console-program-master.tar.gz smtps-and-pop3s-console-program-master.zip |
Diffstat (limited to 'vmime-master/src/vmime/net/maildir/maildirUtils.cpp')
-rw-r--r-- | vmime-master/src/vmime/net/maildir/maildirUtils.cpp | 288 |
1 files changed, 288 insertions, 0 deletions
diff --git a/vmime-master/src/vmime/net/maildir/maildirUtils.cpp b/vmime-master/src/vmime/net/maildir/maildirUtils.cpp new file mode 100644 index 0000000..9942e56 --- /dev/null +++ b/vmime-master/src/vmime/net/maildir/maildirUtils.cpp @@ -0,0 +1,288 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002 Vincent Richard <vincent@vmime.org> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_MAILDIR + + +#include "vmime/net/maildir/maildirUtils.hpp" +#include "vmime/net/maildir/maildirStore.hpp" + +#include "vmime/utility/random.hpp" +#include "vmime/platform.hpp" + +#include "vmime/exception.hpp" + + +namespace vmime { +namespace net { +namespace maildir { + + +bool maildirUtils::isMessageFile(const utility::file& file) { + + // Ignore files which name begins with '.' + if (file.isFile() && + file.getFullPath().getLastComponent().getBuffer().length() >= 1 && + file.getFullPath().getLastComponent().getBuffer()[0] != '.') { + + return true; + } + + return false; +} + + +// NOTE ABOUT ID/FLAGS SEPARATOR +// ----------------------------- +// In the maildir specification, the character ':' is used to separate +// the unique identifier and the message flags. +// +// On Windows (and particularly FAT file systems), ':' is not allowed +// in a filename, so we use a dash ('-') instead. This is the solution +// used by Mutt/Win32, so we also use it here. +// +// To be compatible between implementations, we check for both +// characters when reading file names. + + +const utility::file::path::component maildirUtils::extractId( + const utility::file::path::component& filename +) { + + size_t sep = filename.getBuffer().rfind(':'); // try colon + + if (sep == string::npos) { + sep = filename.getBuffer().rfind('-'); // try dash (Windows) + if (sep == string::npos) return (filename); + } + + return utility::path::component( + string(filename.getBuffer().begin(), filename.getBuffer().begin() + sep) + ); +} + + +int maildirUtils::extractFlags(const utility::file::path::component& comp) { + + size_t sep = comp.getBuffer().rfind(':'); // try colon + + if (sep == string::npos) { + sep = comp.getBuffer().rfind('-'); // try dash (Windows) + if (sep == string::npos) return 0; + } + + const string flagsString(comp.getBuffer().begin() + sep + 1, comp.getBuffer().end()); + const size_t count = flagsString.length(); + + int flags = 0; + + for (size_t i = 0 ; i < count ; ++i) { + + switch (flagsString[i]) { + case 'R': case 'r': flags |= message::FLAG_REPLIED; break; + case 'S': case 's': flags |= message::FLAG_SEEN; break; + case 'T': case 't': flags |= message::FLAG_DELETED; break; + case 'F': case 'f': flags |= message::FLAG_MARKED; break; + case 'P': case 'p': flags |= message::FLAG_PASSED; break; + case 'D': case 'd': flags |= message::FLAG_DRAFT; break; + } + } + + return flags; +} + + +const utility::file::path::component maildirUtils::buildFlags(const int flags) { + + string str; + str.reserve(8); + + str += "2,"; + + if (flags & message::FLAG_MARKED) str += "F"; + if (flags & message::FLAG_PASSED) str += "P"; + if (flags & message::FLAG_REPLIED) str += "R"; + if (flags & message::FLAG_SEEN) str += "S"; + if (flags & message::FLAG_DELETED) str += "T"; + if (flags & message::FLAG_DRAFT) str += "D"; + + return utility::file::path::component(str); +} + + +const utility::file::path::component maildirUtils::buildFilename( + const utility::file::path::component& id, + const int flags +) { + + if (flags == message::FLAG_RECENT) { + return id; + } else { + return buildFilename(id, buildFlags(flags)); + } +} + + +const utility::file::path::component maildirUtils::buildFilename( + const utility::file::path::component& id, + const utility::file::path::component& flags +) { + +#if VMIME_PLATFORM_IS_WINDOWS + static const char DELIMITER[] = "-"; +#else + static const char DELIMITER[] = ":"; +#endif + + return utility::path::component(id.getBuffer() + DELIMITER + flags.getBuffer()); +} + + +const utility::file::path::component maildirUtils::generateId() { + + std::ostringstream oss; + oss.imbue(std::locale::classic()); + + oss << utility::random::getTime(); + oss << "."; + oss << utility::random::getProcess(); + oss << "."; + oss << utility::random::getString(6); + oss << "."; + oss << platform::getHandler()->getHostName(); + + return utility::file::path::component(oss.str()); +} + + +void maildirUtils::recursiveFSDelete(const shared_ptr <utility::file>& dir) { + + shared_ptr <utility::fileIterator> files = dir->getFiles(); + + // First, delete files and subdirectories in this directory + while (files->hasMoreElements()) { + + shared_ptr <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 + } +} + + + +class maildirMessageSetEnumerator : public messageSetEnumerator { + +public: + + maildirMessageSetEnumerator(const size_t msgCount) + : m_msgCount(msgCount) { + + } + + void enumerateNumberMessageRange(const vmime::net::numberMessageRange& range) { + + size_t last = range.getLast(); + if (last == size_t(-1)) last = m_msgCount; + + for (size_t i = range.getFirst() ; i <= last ; ++i) { + list.push_back(i); + } + } + + void enumerateUIDMessageRange(const vmime::net::UIDMessageRange& /* range */) { + + // Not supported + } + +public: + + std::vector <size_t> list; + +private: + + size_t m_msgCount; +}; + + +// static +const std::vector <size_t> maildirUtils::messageSetToNumberList( + const messageSet& msgs, + const size_t msgCount +) { + + maildirMessageSetEnumerator en(msgCount); + msgs.enumerate(en); + + return en.list; +} + + + +// +// messageIdComparator +// + +maildirUtils::messageIdComparator::messageIdComparator( + const utility::file::path::component& comp +) + : m_comp(maildirUtils::extractId(comp)) { + +} + + +bool maildirUtils::messageIdComparator::operator()( + const utility::file::path::component& other +) const { + + return m_comp == maildirUtils::extractId(other); +} + + +} // maildir +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_MAILDIR + |