From aa4d426b4d3527d7e166df1a05058c9a4a0f6683 Mon Sep 17 00:00:00 2001 From: Wojtek Kosior Date: Fri, 30 Apr 2021 00:33:56 +0200 Subject: initial/final commit --- vmime-master/examples/CMakeLists.txt | 38 + vmime-master/examples/example1.cpp | 107 +++ vmime-master/examples/example2.cpp | 121 +++ vmime-master/examples/example3.cpp | 153 ++++ vmime-master/examples/example4.cpp | 108 +++ vmime-master/examples/example5.cpp | 85 ++ vmime-master/examples/example6.cpp | 938 +++++++++++++++++++++ vmime-master/examples/example6_authenticator.hpp | 112 +++ .../examples/example6_certificateVerifier.hpp | 64 ++ vmime-master/examples/example6_timeoutHandler.hpp | 60 ++ vmime-master/examples/example6_tracer.hpp | 59 ++ vmime-master/examples/example7.cpp | 118 +++ vmime-master/examples/viewer/CMakeLists.txt | 31 + vmime-master/examples/viewer/viewer.cpp | 294 +++++++ 14 files changed, 2288 insertions(+) create mode 100644 vmime-master/examples/CMakeLists.txt create mode 100644 vmime-master/examples/example1.cpp create mode 100644 vmime-master/examples/example2.cpp create mode 100644 vmime-master/examples/example3.cpp create mode 100644 vmime-master/examples/example4.cpp create mode 100644 vmime-master/examples/example5.cpp create mode 100644 vmime-master/examples/example6.cpp create mode 100644 vmime-master/examples/example6_authenticator.hpp create mode 100644 vmime-master/examples/example6_certificateVerifier.hpp create mode 100644 vmime-master/examples/example6_timeoutHandler.hpp create mode 100644 vmime-master/examples/example6_tracer.hpp create mode 100644 vmime-master/examples/example7.cpp create mode 100644 vmime-master/examples/viewer/CMakeLists.txt create mode 100644 vmime-master/examples/viewer/viewer.cpp (limited to 'vmime-master/examples') diff --git a/vmime-master/examples/CMakeLists.txt b/vmime-master/examples/CMakeLists.txt new file mode 100644 index 0000000..9e6998f --- /dev/null +++ b/vmime-master/examples/CMakeLists.txt @@ -0,0 +1,38 @@ + +IF(VMIME_BUILD_SAMPLES) + + ADD_SUBDIRECTORY(viewer) + + FILE( + GLOB + VMIME_SAMPLES_SRC_FILES + ${CMAKE_SOURCE_DIR}/examples/*.cpp + ) + + # Build one file for each sample + FOREACH(VMIME_SAMPLE_SRC_FILE ${VMIME_SAMPLES_SRC_FILES}) + + GET_FILENAME_COMPONENT(VMIME_SAMPLE_NAME "${VMIME_SAMPLE_SRC_FILE}" NAME_WE) + + ADD_EXECUTABLE( + ${VMIME_SAMPLE_NAME} + ${VMIME_SAMPLE_SRC_FILE} + ) + + TARGET_LINK_LIBRARIES( + ${VMIME_SAMPLE_NAME} + ${VMIME_LIBRARY_NAME} + ) + + ADD_DEPENDENCIES( + ${VMIME_SAMPLE_NAME} + ${VMIME_LIBRARY_NAME} + ) + + ENDFOREACH() + +ELSE() + + MESSAGE(FATAL_ERROR "Examples are not to be built (set VMIME_BUILD_SAMPLES to YES.") + +ENDIF() diff --git a/vmime-master/examples/example1.cpp b/vmime-master/examples/example1.cpp new file mode 100644 index 0000000..c698fa7 --- /dev/null +++ b/vmime-master/examples/example1.cpp @@ -0,0 +1,107 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002 Vincent Richard +// +// 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. +// + +// +// EXAMPLE DESCRIPTION: +// ==================== +// This sample program demonstrate the use of the messageBuilder component +// to build a simple message. +// +// For more information, please visit: +// http://www.vmime.org/ +// + +#include +#include +#include + +#include "vmime/vmime.hpp" +#include "vmime/platforms/posix/posixHandler.hpp" + + +int main() { + + std::cout << std::endl; + + // Set the global C and C++ locale to the user-configured locale. + // The locale should use UTF-8 encoding for these tests to run successfully. + try { + std::locale::global(std::locale("")); + } catch (std::exception &) { + std::setlocale(LC_ALL, ""); + } + + try { + + vmime::messageBuilder mb; + + // Fill in the basic fields + mb.setExpeditor(vmime::mailbox("me@somewhere.com")); + + vmime::addressList to; + to.appendAddress(vmime::make_shared ("you@elsewhere.com")); + + mb.setRecipients(to); + + vmime::addressList bcc; + bcc.appendAddress(vmime::make_shared ("you-bcc@nowhere.com")); + + mb.setBlindCopyRecipients(bcc); + + mb.setSubject(vmime::text("My first message generated with vmime::messageBuilder")); + + // Message body + mb.getTextPart()->setText( + vmime::make_shared ( + "I'm writing this short text to test message construction " \ + "using the vmime::messageBuilder component." + ) + ); + + // Construction + vmime::shared_ptr msg = mb.construct(); + + // Raw text generation + std::cout << "Generated message:" << std::endl; + std::cout << "==================" << std::endl; + + vmime::utility::outputStreamAdapter out(std::cout); + msg->generate(out); + + // VMime exception + } catch (vmime::exception& e) { + + std::cout << "vmime::exception: " << e.what() << std::endl; + throw; + + // Standard exception + } catch (std::exception& e) { + + std::cout << "std::exception: " << e.what() << std::endl; + throw; + } + + std::cout << std::endl; + + return 0; +} diff --git a/vmime-master/examples/example2.cpp b/vmime-master/examples/example2.cpp new file mode 100644 index 0000000..da01d75 --- /dev/null +++ b/vmime-master/examples/example2.cpp @@ -0,0 +1,121 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002 Vincent Richard +// +// 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. +// + +// +// EXAMPLE DESCRIPTION: +// ==================== +// This sample program demonstrate the use of the messageBuilder component +// to build a simple message with an attachment. +// +// For more information, please visit: +// http://www.vmime.org/ +// + +#include +#include +#include + +#include "vmime/vmime.hpp" +#include "vmime/platforms/posix/posixHandler.hpp" + + +int main() { + + std::cout << std::endl; + + // Set the global C and C++ locale to the user-configured locale. + // The locale should use UTF-8 encoding for these tests to run successfully. + try { + std::locale::global(std::locale("")); + } catch (std::exception &) { + std::setlocale(LC_ALL, ""); + } + + try { + + vmime::messageBuilder mb; + + // Fill in the basic fields + mb.setExpeditor(vmime::mailbox("me@somewhere.com")); + + vmime::addressList to; + to.appendAddress(vmime::make_shared ("you@elsewhere.com")); + + mb.setRecipients(to); + + vmime::addressList bcc; + bcc.appendAddress(vmime::make_shared ("you-bcc@nowhere.com")); + + mb.setBlindCopyRecipients(bcc); + + mb.setSubject(vmime::text("My first message generated with vmime::messageBuilder")); + + // Message body + mb.getTextPart()->setText( + vmime::make_shared ( + "I'm writing this short text to test message construction " \ + "with attachment, using the vmime::messageBuilder component." + ) + ); + + // Adding an attachment + vmime::shared_ptr a = + vmime::make_shared ( + __FILE__, // full path to file + vmime::mediaType("application/octet-stream"), // content type + vmime::text("My first attachment") // description + ); + + a->getFileInfo().setFilename("example2.cpp"); + a->getFileInfo().setCreationDate(vmime::datetime("30 Apr 2003 14:30:00 +0200")); + + mb.attach(a); + + // Construction + vmime::shared_ptr msg = mb.construct(); + + // Raw text generation + vmime::string dataToSend = msg->generate(); + + std::cout << "Generated message:" << std::endl; + std::cout << "==================" << std::endl; + std::cout << std::endl; + std::cout << dataToSend << std::endl; + + // VMime exception + } catch (vmime::exception& e) { + + std::cout << "vmime::exception: " << e.what() << std::endl; + throw; + + // Standard exception + } catch (std::exception& e) { + + std::cout << "std::exception: " << e.what() << std::endl; + throw; + } + + std::cout << std::endl; + + return 0; +} diff --git a/vmime-master/examples/example3.cpp b/vmime-master/examples/example3.cpp new file mode 100644 index 0000000..b452225 --- /dev/null +++ b/vmime-master/examples/example3.cpp @@ -0,0 +1,153 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002 Vincent Richard +// +// 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. +// + +// +// EXAMPLE DESCRIPTION: +// ==================== +// This sample program demonstrate the use of the messageBuilder component +// to build a complex message (HTML content, plain text and embedded image). +// +// For more information, please visit: +// http://www.vmime.org/ +// + +#include +#include +#include + +#include "vmime/vmime.hpp" +#include "vmime/platforms/posix/posixHandler.hpp" + + +int main() { + + std::cout << std::endl; + + // Set the global C and C++ locale to the user-configured locale. + // The locale should use UTF-8 encoding for these tests to run successfully. + try { + std::locale::global(std::locale("")); + } catch (std::exception &) { + std::setlocale(LC_ALL, ""); + } + + try { + + vmime::messageBuilder mb; + + // Fill in the basic fields + mb.setExpeditor(vmime::mailbox("me@somewhere.com")); + + vmime::addressList to; + to.appendAddress(vmime::make_shared ("you@elsewhere.com")); + + mb.setRecipients(to); + + vmime::addressList bcc; + bcc.appendAddress(vmime::make_shared ("you-bcc@nowhere.com")); + + mb.setBlindCopyRecipients(bcc); + + mb.setSubject(vmime::text("My first message generated with vmime::messageBuilder")); + + // Set the content-type to "text/html" + mb.constructTextPart( + vmime::mediaType( + vmime::mediaTypes::TEXT, + vmime::mediaTypes::TEXT_HTML + ) + ); + + // Fill in the text part: the message is available in two formats: HTML and plain text. + // HTML text part also includes an inline image (embedded into the message). + vmime::htmlTextPart& textPart = + *vmime::dynamicCast (mb.getTextPart()); + + // -- embed an image (the returned "CID" (content identifier) is used to reference + // -- the image into HTML content). + vmime::shared_ptr fs = + vmime::platform::getHandler()->getFileSystemFactory(); + + vmime::shared_ptr imageFile = + fs->create(fs->stringToPath("/path/to/image.jpg")); + + vmime::shared_ptr fileReader = + imageFile->getFileReader(); + + vmime::shared_ptr imageCts = + vmime::make_shared ( + fileReader->getInputStream(), + imageFile->getLength() + ); + + vmime::shared_ptr obj = + textPart.addObject( + imageCts, + vmime::mediaType( + vmime::mediaTypes::IMAGE, + vmime::mediaTypes::IMAGE_JPEG + ) + ); + + // -- message text + textPart.setText( + vmime::make_shared ( + vmime::string("This is the HTML text.
" + "getReferenceId() + vmime::string("\"/>") + ) + ); + + textPart.setPlainText( + vmime::make_shared ( + "This is the plain text (without HTML formatting)." + ) + ); + + // Construction + vmime::shared_ptr msg = mb.construct(); + + // Raw text generation + vmime::string dataToSend = msg->generate(); + + std::cout << "Generated message:" << std::endl; + std::cout << "==================" << std::endl; + std::cout << std::endl; + std::cout << dataToSend << std::endl; + + // VMime exception + } catch (vmime::exception& e) { + + std::cout << "vmime::exception: " << e.what() << std::endl; + throw; + + // Standard exception + } catch (std::exception& e) { + + std::cout << "std::exception: " << e.what() << std::endl; + throw; + } + + std::cout << std::endl; + + return 0; +} diff --git a/vmime-master/examples/example4.cpp b/vmime-master/examples/example4.cpp new file mode 100644 index 0000000..4d50c2e --- /dev/null +++ b/vmime-master/examples/example4.cpp @@ -0,0 +1,108 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002 Vincent Richard +// +// 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. +// + +// +// EXAMPLE DESCRIPTION: +// ==================== +// This sample program demonstrate the use of the messageParser component +// to enumerate the text parts in a message. +// +// For more information, please visit: +// http://www.vmime.org/ +// + +#include +#include +#include + +#include "vmime/vmime.hpp" +#include "vmime/platforms/posix/posixHandler.hpp" + + +int main() { + + std::cout << std::endl; + + // Set the global C and C++ locale to the user-configured locale. + // The locale should use UTF-8 encoding for these tests to run successfully. + try { + std::locale::global(std::locale("")); + } catch (std::exception &) { + std::setlocale(LC_ALL, ""); + } + + try { + + vmime::messageParser mp("<...MIME message content...>"); + + // Enumerate text parts + for (size_t i = 0 ; i < mp.getTextPartCount() ; ++i) { + + const vmime::textPart& part = *mp.getTextPartAt(i); + + // Output content-type of the part + std::cout << part.getType().generate() << std::endl; + + // text/html + if (part.getType().getSubType() == vmime::mediaTypes::TEXT_HTML) { + + const vmime::htmlTextPart& hp = dynamic_cast(part); + + // HTML text is in "hp.getText()" + // Corresponding plain text is in "hp.getPlainText()" + + // Enumerate embedded objects (eg. images) + for (size_t j = 0 ; j < hp.getObjectCount() ; ++j) { + + const vmime::htmlTextPart::embeddedObject& obj = *hp.getObjectAt(j); + + // Identifier (content-id or content-location) is in "obj.getId()" + // Object data is in "obj.getData()" + } + + // text/plain + } else { + + const vmime::textPart& tp = dynamic_cast(part); + + // Text is in "tp.getText()" + } + } + + // VMime exception + } catch (vmime::exception& e) { + + std::cout << "vmime::exception: " << e.what() << std::endl; + throw; + + // Standard exception + } catch (std::exception& e) { + + std::cout << "std::exception: " << e.what() << std::endl; + throw; + } + + std::cout << std::endl; + + return 0; +} diff --git a/vmime-master/examples/example5.cpp b/vmime-master/examples/example5.cpp new file mode 100644 index 0000000..24d5cbf --- /dev/null +++ b/vmime-master/examples/example5.cpp @@ -0,0 +1,85 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002 Vincent Richard +// +// 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. +// + +// +// EXAMPLE DESCRIPTION: +// ==================== +// This sample program demonstrate the use of the messageParser component +// to enumerate the attachments in a message. +// +// For more information, please visit: +// http://www.vmime.org/ +// + +#include +#include +#include + +#include "vmime/vmime.hpp" +#include "vmime/platforms/posix/posixHandler.hpp" + + +int main() { + + std::cout << std::endl; + + // Set the global C and C++ locale to the user-configured locale. + // The locale should use UTF-8 encoding for these tests to run successfully. + try { + std::locale::global(std::locale("")); + } catch (std::exception &) { + std::setlocale(LC_ALL, ""); + } + + try { + + vmime::messageParser mp("<...MIME message content...>"); + + // Enumerate attachments + for (size_t i = 0 ; i < mp.getAttachmentCount() ; ++i) { + + const vmime::attachment& att = *mp.getAttachmentAt(i); + + // Media type (content type) is in "att.getType()" + // Name is in "att.getName()" + // Description is in "att.getDescription()" + // Data is in "att.getData()" + } + + // VMime exception + } catch (vmime::exception& e) { + + std::cout << "vmime::exception: " << e.what() << std::endl; + throw; + + // Standard exception + } catch (std::exception& e) { + + std::cout << "std::exception: " << e.what() << std::endl; + throw; + } + + std::cout << std::endl; + + return 0; +} diff --git a/vmime-master/examples/example6.cpp b/vmime-master/examples/example6.cpp new file mode 100644 index 0000000..add24b3 --- /dev/null +++ b/vmime-master/examples/example6.cpp @@ -0,0 +1,938 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002 Vincent Richard +// +// 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 +#include +#include +#include +#include +#include + +#include "vmime/vmime.hpp" +#include "vmime/platforms/posix/posixHandler.hpp" + +#include "example6_tracer.hpp" +#include "example6_authenticator.hpp" +#include "example6_certificateVerifier.hpp" +#include "example6_timeoutHandler.hpp" + + +// Global session object +static vmime::shared_ptr g_session = vmime::net::session::create(); + + +/** Returns the messaging protocols supported by VMime. + * + * @param type service type (vmime::net::service::TYPE_STORE or + * vmime::net::service::TYPE_TRANSPORT) + */ +static const std::string findAvailableProtocols(const vmime::net::service::Type type) { + + vmime::shared_ptr sf = + vmime::net::serviceFactory::getInstance(); + + std::ostringstream res; + size_t count = 0; + + for (size_t i = 0 ; i < sf->getServiceCount() ; ++i) { + + const vmime::net::serviceFactory::registeredService& serv = *sf->getServiceAt(i); + + if (serv.getType() == type) { + + if (count != 0) { + res << ", "; + } + + res << serv.getName(); + ++count; + } + } + + return res.str(); +} + + +// Exception helper +static std::ostream& operator<<(std::ostream& os, const vmime::exception& e) { + + os << "* vmime::exceptions::" << e.name() << std::endl; + os << " what = " << e.what() << std::endl; + + // More information for special exceptions + if (dynamic_cast (&e)) { + + const vmime::exceptions::command_error& cee = + dynamic_cast (e); + + os << " command = " << cee.command() << std::endl; + os << " response = " << cee.response() << std::endl; + } + + if (dynamic_cast (&e)) { + + const vmime::exceptions::invalid_response& ir = + dynamic_cast (e); + + os << " response = " << ir.response() << std::endl; + } + + if (dynamic_cast (&e)) { + + const vmime::exceptions::connection_greeting_error& cgee = + dynamic_cast (e); + + os << " response = " << cgee.response() << std::endl; + } + + if (dynamic_cast (&e)) { + + const vmime::exceptions::authentication_error& aee = + dynamic_cast (e); + + os << " response = " << aee.response() << std::endl; + } + + if (dynamic_cast (&e)) { + + const vmime::exceptions::filesystem_exception& fse = + dynamic_cast (e); + + os << " path = " << vmime::platform::getHandler()-> + getFileSystemFactory()->pathToString(fse.path()) << std::endl; + } + + if (e.other()) { + os << *e.other(); + } + + return os; +} + + +/** Print the MIME structure of a message on the standard output. + * + * @param s structure object + * @param level current depth + */ +static void printStructure( + vmime::shared_ptr s, + const int level = 0 +) { + + for (size_t i = 0 ; i < s->getPartCount() ; ++i) { + + vmime::shared_ptr part = s->getPartAt(i); + + for (int j = 0 ; j < level * 2 ; ++j) { + std::cout << " "; + } + + std::cout + << (part->getNumber() + 1) << ". " + << part->getType().generate() + << " [" << part->getSize() << " byte(s)]" + << std::endl; + + printStructure(part->getStructure(), level + 1); + } +} + + +static const vmime::string getFolderPathString(vmime::shared_ptr f) { + + const vmime::string n = f->getName().getBuffer(); + + if (n.empty()) { // root folder + + return "/"; + + } else { + + vmime::shared_ptr p = f->getParent(); + return getFolderPathString(p) + n + "/"; + } +} + + +/** Print folders and sub-folders on the standard output. + * + * @param folder current folder + */ +static void printFolders(vmime::shared_ptr folder, const int level = 0) { + + for (int j = 0 ; j < level * 2 ; ++j) { + std::cout << " "; + } + + const vmime::net::folderAttributes attr = folder->getAttributes(); + std::ostringstream attrStr; + + if (attr.getSpecialUse() == vmime::net::folderAttributes::SPECIALUSE_ALL) { + attrStr << " \\use:All"; + } else if (attr.getSpecialUse() == vmime::net::folderAttributes::SPECIALUSE_ARCHIVE) { + attrStr << " \\use:Archive"; + } else if (attr.getSpecialUse() == vmime::net::folderAttributes::SPECIALUSE_DRAFTS) { + attrStr << " \\use:Drafts"; + } else if (attr.getSpecialUse() == vmime::net::folderAttributes::SPECIALUSE_FLAGGED) { + attrStr << " \\use:Flagged"; + } else if (attr.getSpecialUse() == vmime::net::folderAttributes::SPECIALUSE_JUNK) { + attrStr << " \\use:Junk"; + } else if (attr.getSpecialUse() == vmime::net::folderAttributes::SPECIALUSE_SENT) { + attrStr << " \\use:Sent"; + } else if (attr.getSpecialUse() == vmime::net::folderAttributes::SPECIALUSE_TRASH) { + attrStr << " \\use:Trash"; + } else if (attr.getSpecialUse() == vmime::net::folderAttributes::SPECIALUSE_IMPORTANT) { + attrStr << " \\use:Important"; + } + + if (attr.getFlags() & vmime::net::folderAttributes::FLAG_HAS_CHILDREN) { + attrStr << " \\flag:HasChildren"; + } + if (attr.getFlags() & vmime::net::folderAttributes::FLAG_NO_OPEN) { + attrStr << " \\flag:NoOpen"; + } + + for (size_t i = 0, n = attr.getUserFlags().size() ; i < n ; ++i) { + attrStr << " \\" << attr.getUserFlags()[i]; + } + + std::cout << getFolderPathString(folder); + std::cout << " " << attrStr.str(); + std::cout << std::endl; + + std::vector > subFolders = folder->getFolders(false); + + for (unsigned int i = 0 ; i < subFolders.size() ; ++i) { + printFolders(subFolders[i], level + 1); + } +} + + +/** Print a menu on the standard output. + * + * @param choices menu choices + */ +static unsigned int printMenu(const std::vector & choices) { + + std::cout << std::endl; + + for (unsigned int i = 0 ; i < choices.size() ; ++i) { + std::cout << " " << (i + 1) << ". " << choices[i] << std::endl; + } + + std::cout << std::endl; + std::cout << " Your choice? [1-" << choices.size() << "] "; + std::cout.flush(); + + std::string line; + std::getline(std::cin, line); + + std::istringstream iss(line); + + unsigned int choice = 0; + iss >> choice; + + std::cout << std::endl; + + if (choice < 1 || choice > choices.size()) { + return 0; + } else { + return choice; + } +} + + +/** Send a message interactively. + */ +static void sendMessage() { + + try { + + // Request user to enter an URL + std::cout << "Enter an URL to connect to transport service." << std::endl; + std::cout << "Available protocols: " << findAvailableProtocols(vmime::net::service::TYPE_TRANSPORT) << std::endl; + std::cout << "(eg. smtp://myserver.com, sendmail://localhost)" << std::endl; + std::cout << "> "; + std::cout.flush(); + + vmime::string urlString; + std::getline(std::cin, urlString); + + vmime::utility::url url(urlString); + + vmime::shared_ptr tr; + + if (url.getUsername().empty() || url.getPassword().empty()) { + tr = g_session->getTransport(url, vmime::make_shared ()); + } else { + tr = g_session->getTransport(url); + } + +#if VMIME_HAVE_TLS_SUPPORT + + // Enable TLS support if available + tr->setProperty("connection.tls", true); + + // Set the time out handler + tr->setTimeoutHandlerFactory(vmime::make_shared ()); + + // Set the object responsible for verifying certificates, in the + // case a secured connection is used (TLS/SSL) + tr->setCertificateVerifier( + vmime::make_shared () + ); + +#endif // VMIME_HAVE_TLS_SUPPORT + + // You can also set some properties (see example7 to know the properties + // available for each service). For example, for SMTP: + if (!url.getUsername().empty() || !url.getPassword().empty()) { + tr->setProperty("options.need-authentication", true); + } + + // Trace communication between client and server + vmime::shared_ptr traceStream = vmime::make_shared (); + tr->setTracerFactory(vmime::make_shared (traceStream)); + + // Information about the mail + std::cout << "Enter email of the expeditor (eg. me@somewhere.com): "; + std::cout.flush(); + + vmime::string fromString; + std::getline(std::cin, fromString); + + vmime::mailbox from(fromString); + vmime::mailboxList to; + + for (bool cont = true ; cont ; ) { + + std::cout << "Enter email of the recipient (empty to stop): "; + std::cout.flush(); + + vmime::string toString; + std::getline(std::cin, toString); + + cont = (toString.size() != 0); + + if (cont) { + to.appendMailbox(vmime::make_shared (toString)); + } + } + + std::cout << "Enter message data, including headers (end with '.' on a single line):" << std::endl; + + std::ostringstream data; + + for (bool cont = true ; cont ; ) { + + std::string line; + std::getline(std::cin, line); + + if (line == ".") { + cont = false; + } else { + data << line << "\r\n"; + } + } + + // Connect to server + tr->connect(); + + // Send the message + vmime::string msgData = data.str(); + vmime::utility::inputStreamStringAdapter vis(msgData); + + tr->send(from, to, vis, msgData.length()); + + // Note: you could also write this: + // vmime::message msg; + // ... + // tr->send(&msg); + + // Display connection log + std::cout << std::endl; + std::cout << "Connection Trace:" << std::endl; + std::cout << "=================" << std::endl; + std::cout << traceStream->str(); + + tr->disconnect(); + + } catch (vmime::exception& e) { + + std::cerr << std::endl; + std::cerr << e << std::endl; + throw; + + } catch (std::exception& e) { + + std::cerr << std::endl; + std::cerr << "std::exception: " << e.what() << std::endl; + throw; + } +} + + +/** Connect to a message store interactively. + */ +static void connectStore() { + + try { + + // Request user to enter an URL + std::cout << "Enter an URL to connect to store service." << std::endl; + std::cout << "Available protocols: " << findAvailableProtocols(vmime::net::service::TYPE_STORE) << std::endl; + std::cout << "(eg. pop3://user:pass@myserver.com, imap://myserver.com:123)" << std::endl; + std::cout << "> "; + std::cout.flush(); + + vmime::string urlString; + std::getline(std::cin, urlString); + + vmime::utility::url url(urlString); + + // If no authenticator is given in argument to getStore(), a default one + // is used. Its behaviour is to get the user credentials from the + // session properties "auth.username" and "auth.password". + vmime::shared_ptr st; + + if (url.getUsername().empty() || url.getPassword().empty()) { + st = g_session->getStore(url, vmime::make_shared ()); + } else { + st = g_session->getStore(url); + } + +#if VMIME_HAVE_TLS_SUPPORT + + // Enable TLS support if available + st->setProperty("connection.tls", true); + + // Set the time out handler + st->setTimeoutHandlerFactory(vmime::make_shared ()); + + // Set the object responsible for verifying certificates, in the + // case a secured connection is used (TLS/SSL) + st->setCertificateVerifier( + vmime::make_shared () + ); + +#endif // VMIME_HAVE_TLS_SUPPORT + + // Trace communication between client and server + vmime::shared_ptr traceStream = vmime::make_shared (); + st->setTracerFactory(vmime::make_shared (traceStream)); + + // Connect to the mail store + st->connect(); + + // Display some information about the connection + vmime::shared_ptr ci = st->getConnectionInfos(); + + std::cout << std::endl; + std::cout << "Connected to '" << ci->getHost() << "' (port " << ci->getPort() << ")" << std::endl; + std::cout << "Connection is " << (st->isSecuredConnection() ? "" : "NOT ") << "secured." << std::endl; + + // Open the default folder in this store + vmime::shared_ptr f = st->getDefaultFolder(); +// vmime::shared_ptr f = st->getFolder(vmime::utility::path("a")); + + f->open(vmime::net::folder::MODE_READ_WRITE); + + vmime::size_t count = f->getMessageCount(); + + std::cout << std::endl; + std::cout << count << " message(s) in your inbox" << std::endl; + + for (bool cont = true ; cont ; ) { + + typedef std::map > MessageList; + MessageList msgList; + + try { + + std::vector choices; + + choices.push_back("Show message flags"); + choices.push_back("Show message structure"); + choices.push_back("Show message header"); + choices.push_back("Show message envelope"); + choices.push_back("Extract whole message"); + choices.push_back("Extract attachments"); + choices.push_back("Status"); + choices.push_back("List folders"); + choices.push_back("Change folder"); + choices.push_back("Add message (to the current folder)"); + choices.push_back("Copy message (into the current folder)"); + choices.push_back("Display trace output"); + choices.push_back("Return to main menu"); + + const int choice = printMenu(choices); + + // Request message number + vmime::shared_ptr msg; + + if (choice == 1 || choice == 2 || choice == 3 || choice == 4 || + choice == 5 || choice == 6 || choice == 11) { + + std::cout << "Enter message number: "; + std::cout.flush(); + + std::string line; + std::getline(std::cin, line); + + std::istringstream iss(line); + + vmime::size_t num = 0; + iss >> num; + + if (num < 1 || num > f->getMessageCount()) { + + std::cerr << "Invalid message number." << std::endl; + continue; + } + + MessageList::iterator it = msgList.find(num); + + if (it != msgList.end()) { + + msg = (*it).second; + + } else { + + msg = f->getMessage(num); + msgList.insert(MessageList::value_type(num, msg)); + } + + std::cout << std::endl; + } + + switch (choice) { + + // Show message flags + case 1: + + f->fetchMessage(msg, vmime::net::fetchAttributes::FLAGS); + + if (msg->getFlags() & vmime::net::message::FLAG_SEEN) { + std::cout << "FLAG_SEEN" << std::endl; + } + if (msg->getFlags() & vmime::net::message::FLAG_RECENT) { + std::cout << "FLAG_RECENT" << std::endl; + } + if (msg->getFlags() & vmime::net::message::FLAG_REPLIED) { + std::cout << "FLAG_REPLIED" << std::endl; + } + if (msg->getFlags() & vmime::net::message::FLAG_DELETED) { + std::cout << "FLAG_DELETED" << std::endl; + } + if (msg->getFlags() & vmime::net::message::FLAG_MARKED) { + std::cout << "FLAG_MARKED" << std::endl; + } + if (msg->getFlags() & vmime::net::message::FLAG_PASSED) { + std::cout << "FLAG_PASSED" << std::endl; + } + + break; + + // Show message structure + case 2: + + f->fetchMessage(msg, vmime::net::fetchAttributes::STRUCTURE); + printStructure(msg->getStructure()); + break; + + // Show message header + case 3: + + f->fetchMessage(msg, vmime::net::fetchAttributes::FULL_HEADER); + std::cout << msg->getHeader()->generate() << std::endl; + break; + + // Show message envelope + case 4: { + + vmime::net::fetchAttributes attr(vmime::net::fetchAttributes::ENVELOPE); + + // If you also want to fetch "Received: " fields: + //attr.add("Received"); + + f->fetchMessage(msg, attr); + + std::cout << msg->getHeader()->generate() << std::endl; + + break; + } + // Extract whole message + case 5: { + + vmime::utility::outputStreamAdapter out(std::cout); + msg->extract(out); + + break; + } + // Extract attachments + case 6: { + + vmime::shared_ptr parsedMsg = msg->getParsedMessage(); + + std::vector > attchs = + vmime::attachmentHelper::findAttachmentsInMessage(parsedMsg); + + if (attchs.size() > 0) { + + std::cout << attchs.size() << " attachments found." << std::endl; + + for (std::vector >::iterator + it = attchs.begin() ; it != attchs.end() ; ++it) { + + vmime::shared_ptr att = *it; + + // Get attachment size + vmime::size_t size = 0; + + if (att->getData()->isEncoded()) { + size = att->getData()->getEncoding().getEncoder()->getDecodedSize(att->getData()->getLength()); + } else { + size = att->getData()->getLength(); + } + + std::cout << "Found attachment '" << att->getName().getBuffer() << "'" + << ", size is " << size << " bytes:" << std::endl; + + // Get attachment data + std::cout << std::endl; + std::cout << "========== BEGIN CONTENT ==========" << std::endl; + + vmime::utility::outputStreamAdapter osa(std::cout); + att->getData()->extract(osa); + + std::cout << std::endl; + std::cout << "========== END CONTENT ==========" << std::endl; + + // Or write it to a file + /* + vmime::shared_ptr fsf + = vmime::platform::getHandler()->getFileSystemFactory(); + + vmime::shared_ptr file + = fsf->create(vmime::utility::path::fromString + ("/path/to/attachment-file", "/", vmime::charsets::UTF_8)); + // -or- ("C:\\Temp\\attachment-file", "\\", vmime::charsets::UTF_8)); + + file->createFile(); + + vmime::shared_ptr output = + file->getFileWriter()->getOutputStream(); + + att->getData()->extract(*output.get()); + */ + } + + } else { + + std::cout << "No attachments found." << std::endl; + } + + break; + } + // Status + case 7: { + + vmime::size_t count, unseen; + f->status(count, unseen); + + std::cout << "Status: count=" << count << ", unseen=" << unseen << std::endl; + break; + } + // List folders + case 8: { + + vmime::shared_ptr root = st->getRootFolder(); + + printFolders(root); + break; + } + // Change folder + case 9: { + + std::cout << "Enter folder path (eg. /root/subfolder):" << std::endl; + std::cout.flush(); + + std::string path; + std::getline(std::cin, path); + + vmime::shared_ptr newFolder = st->getRootFolder(); + + for (std::string::size_type s = 0, p = 0 ; ; s = p + 1) { + + p = path.find_first_of('/', s); + + const std::string x = (p == std::string::npos) + ? std::string(path.begin() + s, path.end()) + : std::string(path.begin() + s, path.begin() + p); + + if (!x.empty()) { + newFolder = newFolder->getFolder(vmime::utility::path::component(x)); + } + + if (p == std::string::npos) { + break; + } + } + + newFolder->open(vmime::net::folder::MODE_READ_WRITE); + + count = newFolder->getMessageCount(); + + std::cout << std::endl; + std::cout << count << " message(s) in this folder" << std::endl; + + f->close(true); // 'true' to expunge deleted messages + f = newFolder; + + break; + } + // Add message + case 10: { + + vmime::messageBuilder mb; + + mb.setExpeditor(vmime::mailbox("me@somewhere.com")); + + vmime::addressList to; + to.appendAddress(vmime::make_shared ("you@elsewhere.com")); + mb.setRecipients(to); + + mb.setSubject(vmime::text("Test message from VMime example6")); + mb.getTextPart()->setText( + vmime::make_shared ( + "Body of test message from VMime example6." + ) + ); + + vmime::shared_ptr msg = mb.construct(); + + vmime::net::messageSet set = f->addMessage(msg); + + if (set.isEmpty()) { + + std::cout << "Message has successfully been added, " + << "but its UID/number is not known." << std::endl; + + } else { + + const vmime::net::messageRange& range = set.getRangeAt(0); + + if (set.isUIDSet()) { + + const vmime::net::message::uid uid = + dynamic_cast (range).getFirst(); + + std::cout << "Message has successfully been added, " + << "its UID is '" << uid << "'." << std::endl; + + } else { + + const vmime::size_t number = + dynamic_cast (range).getFirst(); + + std::cout << "Message has successfully been added, " + << "its number is '" << number << "'." << std::endl; + } + } + + break; + } + // Copy message + case 11: { + + vmime::net::messageSet set = f->copyMessages(f->getFullPath(), + vmime::net::messageSet::byNumber(msg->getNumber())); + + if (set.isEmpty()) { + + std::cout << "Message has successfully been copied, " + << "but its UID/number is not known." << std::endl; + + } else { + + const vmime::net::messageRange& range = set.getRangeAt(0); + + if (set.isUIDSet()) { + + const vmime::net::message::uid uid = + dynamic_cast (range).getFirst(); + + std::cout << "Message has successfully been copied, " + << "its UID is '" << uid << "'." << std::endl; + + } else { + + const vmime::size_t number = + dynamic_cast (range).getFirst(); + + std::cout << "Message has successfully been copied, " + << "its number is '" << number << "'." << std::endl; + } + } + + break; + } + // Display trace output + case 12: + + std::cout << std::endl; + std::cout << "Connection Trace:" << std::endl; + std::cout << "=================" << std::endl; + std::cout << traceStream->str(); + break; + + // Main menu + case 13: + + f->close(true); // 'true' to expunge deleted messages + cont = false; + break; + } + +/* + // Append message + std::istringstream iss( + "From: me@localhost\r\n" + "To: you@localhost\r\n" + "Subject: Message Text\r\n" + "\r\n" + "This is a test message...\r\n" + "Bye bye!\r\n" + ); + + f->addMessage(iss, iss.str().size()); + + // Folder renaming + { + vmime::shared_ptr f = st->getFolder(vmime::net::folder::path("c")); + f->rename(vmime::net::folder::path("c2")); + + vmime::shared_ptr g = st->getFolder(vmime::net::folder::path("c2")); + g->rename(vmime::net::folder::path("c")); + } + + // Message copy: copy all messages from 'f' to 'g' + { + vmime::shared_ptr g = st->getFolder(vmime::net::folder::path("TEMP")); + + if (!g->exists()) { + g->create(vmime::net::folder::TYPE_CONTAINS_MESSAGES); + } + + f->copyMessages(g->getFullPath()); + } +*/ + + } catch (vmime::exception& e) { + + std::cerr << std::endl; + std::cerr << e << std::endl; + + } catch (std::exception& e) { + + std::cerr << std::endl; + std::cerr << "std::exception: " << e.what() << std::endl; + } + + } // for(cont) + + st->disconnect(); + + } catch (vmime::exception& e) { + + std::cerr << std::endl; + std::cerr << e << std::endl; + throw; + + } catch (std::exception& e) { + + std::cerr << std::endl; + std::cerr << "std::exception: " << e.what() << std::endl; + throw; + } +} + + +/* Show the main menu. + * + * @return true to quit the program, false to continue + */ +static bool menu() { + + std::vector items; + + items.push_back("Connect to a message store"); + items.push_back("Send a message"); + items.push_back("Quit"); + + switch (printMenu(items)) { + + // Connect to store + case 1: + + connectStore(); + return false; + + // Send a message + case 2: + + sendMessage(); + return false; + + // Quit + case 3: + + return true; + + // Other choice + default: + + return false; + } +} + + +int main() { + + // Set the global C and C++ locale to the user-configured locale. + // The locale should use UTF-8 encoding for these tests to run successfully. + try { + std::locale::global(std::locale("")); + } catch (std::exception &) { + std::setlocale(LC_ALL, ""); + } + + for (bool quit = false ; !quit ; ) { + + // Loop on main menu + quit = menu(); + } + + return 0; +} diff --git a/vmime-master/examples/example6_authenticator.hpp b/vmime-master/examples/example6_authenticator.hpp new file mode 100644 index 0000000..56f0239 --- /dev/null +++ b/vmime-master/examples/example6_authenticator.hpp @@ -0,0 +1,112 @@ + + +#if VMIME_HAVE_SASL_SUPPORT + +// SASL authentication handler +class interactiveAuthenticator : public vmime::security::sasl::defaultSASLAuthenticator { + + const std::vector > + getAcceptableMechanisms( + const std::vector >& available, + const vmime::shared_ptr & suggested + ) const { + + std::cout << std::endl << "Available SASL mechanisms:" << std::endl; + + for (unsigned int i = 0 ; i < available.size() ; ++i) { + + std::cout << " " << available[i]->getName(); + + if (suggested && available[i]->getName() == suggested->getName()) { + std::cout << "(suggested)"; + } + } + + std::cout << std::endl << std::endl; + + return defaultSASLAuthenticator::getAcceptableMechanisms(available, suggested); + } + + void setSASLMechanism(const vmime::shared_ptr & mech) { + + std::cout << "Trying '" << mech->getName() << "' authentication mechanism" << std::endl; + + defaultSASLAuthenticator::setSASLMechanism(mech); + } + + const vmime::string getUsername() const { + + if (m_username.empty()) { + m_username = getUserInput("Username"); + } + + return m_username; + } + + const vmime::string getPassword() const { + + if (m_password.empty()) { + m_password = getUserInput("Password"); + } + + return m_password; + } + + static const vmime::string getUserInput(const std::string& prompt) { + + std::cout << prompt << ": "; + std::cout.flush(); + + vmime::string res; + std::getline(std::cin, res); + + return res; + } + +private: + + mutable vmime::string m_username; + mutable vmime::string m_password; +}; + +#else // !VMIME_HAVE_SASL_SUPPORT + +// Simple authentication handler +class interactiveAuthenticator : public vmime::security::defaultAuthenticator { + + const vmime::string getUsername() const { + + if (m_username.empty()) { + m_username = getUserInput("Username"); + } + + return m_username; + } + + const vmime::string getPassword() const { + + if (m_password.empty()) { + m_password = getUserInput("Password"); + } + + return m_password; + } + + static const vmime::string getUserInput(const std::string& prompt) { + + std::cout << prompt << ": "; + std::cout.flush(); + + vmime::string res; + std::getline(std::cin, res); + + return res; + } + +private: + + mutable vmime::string m_username; + mutable vmime::string m_password; +}; + +#endif // VMIME_HAVE_SASL_SUPPORT diff --git a/vmime-master/examples/example6_certificateVerifier.hpp b/vmime-master/examples/example6_certificateVerifier.hpp new file mode 100644 index 0000000..3d8bf82 --- /dev/null +++ b/vmime-master/examples/example6_certificateVerifier.hpp @@ -0,0 +1,64 @@ + + +#if VMIME_HAVE_TLS_SUPPORT + +// Certificate verifier (TLS/SSL) +class interactiveCertificateVerifier : public vmime::security::cert::defaultCertificateVerifier { + +public: + + void verify( + const vmime::shared_ptr & chain, + const vmime::string& hostname + ) { + + try { + + setX509TrustedCerts(m_trustedCerts); + + defaultCertificateVerifier::verify(chain, hostname); + + } catch (vmime::security::cert::certificateException&) { + + // Obtain subject's certificate + vmime::shared_ptr cert = chain->getAt(0); + + std::cout << std::endl; + std::cout << "Server sent a '" << cert->getType() << "'" << " certificate." << std::endl; + std::cout << "Do you want to accept this certificate? (Y/n) "; + std::cout.flush(); + + std::string answer; + std::getline(std::cin, answer); + + if (answer.length() != 0 && + (answer[0] == 'Y' || answer[0] == 'y')) { + + // Accept it, and remember user's choice for later + if (cert->getType() == "X.509") { + + m_trustedCerts.push_back( + vmime::dynamicCast (cert) + ); + + setX509TrustedCerts(m_trustedCerts); + defaultCertificateVerifier::verify(chain, hostname); + } + + return; + } + + throw vmime::security::cert::certificateException("User did not accept the certificate."); + } + } + +private: + + static std::vector > m_trustedCerts; +}; + + +std::vector > + interactiveCertificateVerifier::m_trustedCerts; + +#endif // VMIME_HAVE_TLS_SUPPORT diff --git a/vmime-master/examples/example6_timeoutHandler.hpp b/vmime-master/examples/example6_timeoutHandler.hpp new file mode 100644 index 0000000..7999084 --- /dev/null +++ b/vmime-master/examples/example6_timeoutHandler.hpp @@ -0,0 +1,60 @@ +#include + + +/** Time out handler. + * Used to stop the current operation after too much time, or if the user + * requested cancellation. + */ +class timeoutHandler : public vmime::net::timeoutHandler { + +public: + + timeoutHandler() + : m_start(time(NULL)) { + + } + + bool isTimeOut() { + + // This is a cancellation point: return true if you want to cancel + // the current operation. If you return true, handleTimeOut() will + // be called just after this, and before actually cancelling the + // operation + + // 10 seconds timeout + return (time(NULL) - m_start) >= 10; // seconds + } + + void resetTimeOut() { + + // Called at the beginning of an operation (eg. connecting, + // a read() or a write() on a socket...) + m_start = time(NULL); + } + + bool handleTimeOut() { + + // If isTimeOut() returned true, this function will be called. This + // allows you to interact with the user, ie. display a prompt to + // know whether he wants to cancel the operation. + + // If you return false here, the operation will be actually cancelled. + // If true, the time out is reset and the operation continues. + return false; + } + +private: + + time_t m_start; +}; + + +class timeoutHandlerFactory : public vmime::net::timeoutHandlerFactory { + +public: + + vmime::shared_ptr create() { + + return vmime::make_shared (); + } +}; diff --git a/vmime-master/examples/example6_tracer.hpp b/vmime-master/examples/example6_tracer.hpp new file mode 100644 index 0000000..27090cf --- /dev/null +++ b/vmime-master/examples/example6_tracer.hpp @@ -0,0 +1,59 @@ + +/** Tracer used to demonstrate logging communication between client and server. + */ +class myTracer : public vmime::net::tracer { + +public: + + myTracer( + const vmime::shared_ptr & stream, + const vmime::shared_ptr & serv, + const int connectionId + ) + : m_stream(stream), + m_service(serv), + m_connectionId(connectionId) { + + } + + void traceSend(const vmime::string& line) { + + *m_stream << "[" << m_service->getProtocolName() << ":" << m_connectionId + << "] C: " << line << std::endl; + } + + void traceReceive(const vmime::string& line) { + + *m_stream << "[" << m_service->getProtocolName() << ":" << m_connectionId + << "] S: " << line << std::endl; + } + +private: + + vmime::shared_ptr m_stream; + vmime::shared_ptr m_service; + const int m_connectionId; +}; + + +class myTracerFactory : public vmime::net::tracerFactory { + +public: + + myTracerFactory(const vmime::shared_ptr & stream) + : m_stream(stream) { + + } + + vmime::shared_ptr create( + const vmime::shared_ptr & serv, + const int connectionId + ) { + + return vmime::make_shared (m_stream, serv, connectionId); + } + +private: + + vmime::shared_ptr m_stream; +}; diff --git a/vmime-master/examples/example7.cpp b/vmime-master/examples/example7.cpp new file mode 100644 index 0000000..db96dbd --- /dev/null +++ b/vmime-master/examples/example7.cpp @@ -0,0 +1,118 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002 Vincent Richard +// +// 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. +// + +// +// EXAMPLE DESCRIPTION: +// ==================== +// This sample program demonstrates how to enumerate encoders and +// messaging services in VMime. +// +// For more information, please visit: +// http://www.vmime.org/ +// + +#include +#include +#include + +#include "vmime/vmime.hpp" +#include "vmime/platforms/posix/posixHandler.hpp" + + +int main() { + + // Enumerate encoders + vmime::shared_ptr ef = + vmime::utility::encoder::encoderFactory::getInstance(); + + std::cout << "Available encoders:" << std::endl; + + for (size_t i = 0 ; i < ef->getEncoderCount() ; ++i) { + + vmime::shared_ptr + enc = ef->getEncoderAt(i); + + std::cout << " * " << enc->getName() << std::endl; + + vmime::shared_ptr e = + vmime::utility::encoder::encoderFactory::getInstance()->create(enc->getName()); + + std::vector props = e->getAvailableProperties(); + + for (std::vector ::const_iterator it = props.begin() ; it != props.end() ; ++it) { + std::cout << " - " << *it << std::endl; + } + } + + std::cout << std::endl; + + // Enumerate messaging services and their properties + vmime::shared_ptr sf = + vmime::net::serviceFactory::getInstance(); + + std::cout << "Available messaging services:" << std::endl; + + for (size_t i = 0 ; i < sf->getServiceCount() ; ++i) { + + const vmime::net::serviceFactory::registeredService& serv = *sf->getServiceAt(i); + + std::cout << " * " << serv.getName() << std::endl; + + std::vector props = + serv.getInfos().getAvailableProperties(); + + for (std::vector ::const_iterator it = props.begin() ; + it != props.end() ; ++it) { + + const vmime::net::serviceInfos::property& p = *it; + + const vmime::string name = serv.getInfos().getPropertyPrefix() + p.getName(); + + vmime::string type; + + switch (p.getType()) { + case vmime::net::serviceInfos::property::TYPE_INTEGER: type = "TYPE_INTEGER"; break; + case vmime::net::serviceInfos::property::TYPE_STRING: type = "TYPE_STRING"; break; + case vmime::net::serviceInfos::property::TYPE_BOOLEAN: type = "TYPE_BOOLEAN"; break; + default: type = "(unknown)"; break; + } + + vmime::string flags; + + if (p.getFlags() & vmime::net::serviceInfos::property::FLAG_REQUIRED) { + flags += " FLAG_REQUIRED"; + } + if (p.getFlags() & vmime::net::serviceInfos::property::FLAG_HIDDEN) { + flags += " FLAG_HIDDEN"; + } + + std::cout << " - " << serv.getInfos().getPropertyPrefix() + p.getName(); + std::cout << " (type=" << type << ", flags=" << flags; + std::cout << ", defaultValue=" << p.getDefaultValue() << ")" << std::endl; + } + } + + std::cout << std::endl; + + return 0; +} diff --git a/vmime-master/examples/viewer/CMakeLists.txt b/vmime-master/examples/viewer/CMakeLists.txt new file mode 100644 index 0000000..c8d9316 --- /dev/null +++ b/vmime-master/examples/viewer/CMakeLists.txt @@ -0,0 +1,31 @@ + +IF(VMIME_BUILD_SAMPLES) + + FIND_PACKAGE(PkgConfig REQUIRED) + PKG_CHECK_MODULES(GTK3 REQUIRED gtk+-3.0) + + INCLUDE_DIRECTORIES(${GTK3_INCLUDE_DIRS}) + LINK_DIRECTORIES(${GTK3_LIBRARY_DIRS}) + ADD_DEFINITIONS(${GTK3_CFLAGS_OTHER}) + + ADD_EXECUTABLE( + viewer + viewer.cpp + ) + + TARGET_LINK_LIBRARIES( + viewer + ${VMIME_LIBRARY_NAME} + ${GTK3_LIBRARIES} + ) + + ADD_DEPENDENCIES( + viewer + ${VMIME_LIBRARY_NAME} + ) + +ELSE() + + MESSAGE(FATAL_ERROR "Examples are not to be built (set VMIME_BUILD_SAMPLES to YES.") + +ENDIF() diff --git a/vmime-master/examples/viewer/viewer.cpp b/vmime-master/examples/viewer/viewer.cpp new file mode 100644 index 0000000..a03120a --- /dev/null +++ b/vmime-master/examples/viewer/viewer.cpp @@ -0,0 +1,294 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002 Vincent Richard +// +// 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. +// + +// +// EXAMPLE DESCRIPTION: +// ==================== +// A simple MIME viewer to show all the components of a message. +// The user interface is written using GTK+ 2.6. +// +// For more information, please visit: +// http://www.vmime.org/ +// + +#include +#include +#include +#include + +#include + +#include "vmime/vmime.hpp" +#include "vmime/platforms/posix/posixHandler.hpp" + + + +GtkWidget* window = NULL; +GtkWidget* treeView = NULL; +GtkWidget* textArea = NULL; + +GtkTreeStore* treeModel = NULL; + +vmime::shared_ptr currentMessage; + + + +void insertRowInModel( + GtkTreeStore* model, + vmime::shared_ptr comp, + GtkTreeIter* parent = NULL +) { + + GtkTreeIter iter; + + gtk_tree_store_append(model, &iter, parent); + gtk_tree_store_set(model, &iter, 0, typeid(*comp).name(), 1, comp.get(), -1); + + const std::vector > children = comp->getChildComponents(); + + for (int i = 0 ; i < children.size() ; ++i) { + insertRowInModel(model, children[i], &iter); + } +} + + +void updateTreeView() { + + GtkTreeStore* model = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(treeView))); + + g_object_ref(model); + gtk_tree_view_set_model(GTK_TREE_VIEW(treeView), NULL); + + gtk_tree_store_clear(model); + + insertRowInModel(model, currentMessage); + + gtk_tree_view_set_model(GTK_TREE_VIEW(treeView), GTK_TREE_MODEL(model)); + g_object_unref(model); +} + + +static void treeViewSelChanged(GtkTreeView* treeView, gpointer userData) { + + GtkTreePath* path = NULL; + GtkTreeViewColumn* col = NULL; + + gtk_tree_view_get_cursor(treeView, &path, &col); + + GtkTreeIter iter; + gtk_tree_model_get_iter(GTK_TREE_MODEL(treeModel), &iter, path); + + vmime::component* comp = NULL; + gtk_tree_model_get(GTK_TREE_MODEL(treeModel), &iter, 1, &comp, -1); + + GtkTextBuffer* textBuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textArea)); + GtkTextIter start, end; + + gtk_text_buffer_get_iter_at_offset(textBuffer, &start, comp->getParsedOffset()); + gtk_text_buffer_get_iter_at_offset(textBuffer, &end, comp->getParsedOffset() + comp->getParsedLength()); + + gtk_text_buffer_select_range(textBuffer, &start, &end); + + gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(textArea), &start, 0.0, FALSE, 0.0, 0.0); + + gtk_tree_path_free(path); +} + + +static void destroy(GtkWidget* widget, gpointer data) { + + gtk_main_quit(); +} + + +void openFile(const std::string& filename) { + + std::ifstream file; + file.open(filename.c_str(), std::ios::in | std::ios::binary); + + if (!file) { + std::cerr << "Can't open file '" << filename << "'." << std::endl; + return; + } + + vmime::string data; + char buffer[16384]; + + do { + file.read(buffer, sizeof(buffer)); + data += vmime::string(buffer, file.gcount()); + } while (file.gcount()); + + vmime::shared_ptr msg = vmime::make_shared (); + msg->parse(data); + + currentMessage = msg; + + char* convData = g_convert_with_fallback(data.c_str(), data.length(), + "UTF-8", "ISO-8859-1", "?", NULL, NULL, NULL); + + if (!convData) { + + gtk_text_buffer_set_text(gtk_text_view_get_buffer(GTK_TEXT_VIEW(textArea)), + "GLib UTF-8 conversion error.", -1); + + } else { + + gtk_text_buffer_set_text(gtk_text_view_get_buffer(GTK_TEXT_VIEW(textArea)), + convData, strlen(convData)); + + g_free(convData); + } + + updateTreeView(); +} + + +static void onFileOpen() { + + GtkWidget* dlg = gtk_file_chooser_dialog_new( + "Open Message File", + GTK_WINDOW(window), + GTK_FILE_CHOOSER_ACTION_OPEN, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, + NULL + ); + + if (gtk_dialog_run(GTK_DIALOG(dlg)) == GTK_RESPONSE_ACCEPT) { + + char* filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dlg)); + + openFile(filename); + + g_free(filename); + } + + gtk_widget_destroy(dlg); +} + + + +// UI definitions +static const GtkActionEntry uiActions[] = { + { "FileMenu", NULL, "_File" }, + { "FileOpen", GTK_STOCK_OPEN, "_Open...", "O", NULL, G_CALLBACK(onFileOpen) }, + { "FileExit", GTK_STOCK_QUIT, "_Exit", "Q", NULL, G_CALLBACK(gtk_main_quit) } +}; + +static const char* uiDefinition = + "" \ + " " \ + " " \ + " " \ + " " \ + " " \ + " " \ + ""; + + +int main(int argc, char* argv[]) { + + // VMime initialization + vmime::platform::setHandler(); + + // GTK+ initialization + gtk_init(&argc, &argv); + + // Create a new window + window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + + gtk_window_set_default_size(GTK_WINDOW(window), 800, 550); + gtk_window_set_title(GTK_WINDOW(window), "VMime Viewer Example"); + + g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(destroy), NULL); + + GtkWidget* vbox = gtk_vbox_new(FALSE, 0); + gtk_container_add(GTK_CONTAINER(window), vbox); + + // Menubar + GtkActionGroup* actionGroup = gtk_action_group_new ("Actions"); + gtk_action_group_add_actions(actionGroup, uiActions, G_N_ELEMENTS(uiActions), NULL); + + GtkUIManager* uiManager = gtk_ui_manager_new(); + gtk_ui_manager_insert_action_group(uiManager, actionGroup, 1); + gtk_ui_manager_add_ui_from_string(uiManager, uiDefinition, -1, NULL); + + GtkWidget* menuBar = gtk_ui_manager_get_widget(uiManager, "/MainMenuBar"); + + gtk_box_pack_start(GTK_BOX(vbox), menuBar, FALSE, FALSE, 0); + + // Horizontal Pane + GtkWidget* hpane = gtk_hpaned_new(); + gtk_box_pack_start(GTK_BOX(vbox), hpane, TRUE, TRUE, 0); + + // Tree View + treeModel = gtk_tree_store_new(2, G_TYPE_STRING, G_TYPE_POINTER); + + treeView = gtk_tree_view_new(); + + g_signal_connect(G_OBJECT(treeView), "cursor-changed", G_CALLBACK(treeViewSelChanged), NULL); + + GtkWidget* scroll = gtk_scrolled_window_new(NULL, NULL); + + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scroll), GTK_SHADOW_IN); + gtk_container_add(GTK_CONTAINER(scroll), treeView); + + gtk_paned_add1(GTK_PANED(hpane), scroll); + + GtkTreeViewColumn* col = gtk_tree_view_column_new(); + gtk_tree_view_column_set_title(col, "Component Name"); + gtk_tree_view_append_column(GTK_TREE_VIEW(treeView), col); + + GtkCellRenderer* renderer = gtk_cell_renderer_text_new(); + + gtk_tree_view_column_pack_start(col, renderer, TRUE); + gtk_tree_view_column_add_attribute(col, renderer, "text", 0); + + gtk_tree_view_set_model(GTK_TREE_VIEW(treeView), GTK_TREE_MODEL(treeModel)); + g_object_unref(treeModel); + + gtk_widget_set_size_request(treeView, 200, 100); + + // Text Area + textArea = gtk_text_view_new(); + + gtk_text_view_set_editable(GTK_TEXT_VIEW(textArea), FALSE); + + scroll = gtk_scrolled_window_new(NULL, NULL); + + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scroll), GTK_SHADOW_IN); + gtk_container_add(GTK_CONTAINER(scroll), textArea); + + gtk_paned_add2(GTK_PANED(hpane), scroll); + + // Show main window + gtk_widget_show_all(window); + + // GTK main loop + gtk_main(); + + return 0; +} -- cgit v1.2.3