diff options
Diffstat (limited to 'vmime-master/examples')
| -rw-r--r-- | vmime-master/examples/CMakeLists.txt | 38 | ||||
| -rw-r--r-- | vmime-master/examples/example1.cpp | 107 | ||||
| -rw-r--r-- | vmime-master/examples/example2.cpp | 121 | ||||
| -rw-r--r-- | vmime-master/examples/example3.cpp | 153 | ||||
| -rw-r--r-- | vmime-master/examples/example4.cpp | 108 | ||||
| -rw-r--r-- | vmime-master/examples/example5.cpp | 85 | ||||
| -rw-r--r-- | vmime-master/examples/example6.cpp | 938 | ||||
| -rw-r--r-- | vmime-master/examples/example6_authenticator.hpp | 112 | ||||
| -rw-r--r-- | vmime-master/examples/example6_certificateVerifier.hpp | 64 | ||||
| -rw-r--r-- | vmime-master/examples/example6_timeoutHandler.hpp | 60 | ||||
| -rw-r--r-- | vmime-master/examples/example6_tracer.hpp | 59 | ||||
| -rw-r--r-- | vmime-master/examples/example7.cpp | 118 | ||||
| -rw-r--r-- | vmime-master/examples/viewer/CMakeLists.txt | 31 | ||||
| -rw-r--r-- | vmime-master/examples/viewer/viewer.cpp | 294 | 
14 files changed, 2288 insertions, 0 deletions
| 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 <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. +// + +// +// 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 <iostream> +#include <locale> +#include <clocale> + +#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 <vmime::mailbox>("you@elsewhere.com")); + +		mb.setRecipients(to); + +		vmime::addressList bcc; +		bcc.appendAddress(vmime::make_shared <vmime::mailbox>("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 <vmime::stringContentHandler>( +				"I'm writing this short text to test message construction " \ +				"using the vmime::messageBuilder component." +			) +		); + +		// Construction +		vmime::shared_ptr <vmime::message> 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 <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. +// + +// +// 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 <iostream> +#include <locale> +#include <clocale> + +#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 <vmime::mailbox>("you@elsewhere.com")); + +		mb.setRecipients(to); + +		vmime::addressList bcc; +		bcc.appendAddress(vmime::make_shared <vmime::mailbox>("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 <vmime::stringContentHandler>( +				"I'm writing this short text to test message construction " \ +				"with attachment, using the vmime::messageBuilder component." +			) +		); + +		// Adding an attachment +		vmime::shared_ptr <vmime::fileAttachment> a = +			vmime::make_shared <vmime::fileAttachment>( +				__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 <vmime::message> 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 <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. +// + +// +// 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 <iostream> +#include <locale> +#include <clocale> + +#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 <vmime::mailbox>("you@elsewhere.com")); + +		mb.setRecipients(to); + +		vmime::addressList bcc; +		bcc.appendAddress(vmime::make_shared <vmime::mailbox>("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 <vmime::htmlTextPart>(mb.getTextPart()); + +		// -- embed an image (the returned "CID" (content identifier) is used to reference +		// -- the image into HTML content). +		vmime::shared_ptr <vmime::utility::fileSystemFactory> fs = +			vmime::platform::getHandler()->getFileSystemFactory(); + +		vmime::shared_ptr <vmime::utility::file> imageFile = +			fs->create(fs->stringToPath("/path/to/image.jpg")); + +		vmime::shared_ptr <vmime::utility::fileReader> fileReader = +			imageFile->getFileReader(); + +		vmime::shared_ptr <vmime::contentHandler> imageCts = +			vmime::make_shared <vmime::streamContentHandler>( +				fileReader->getInputStream(), +				imageFile->getLength() +			); + +		vmime::shared_ptr <const vmime::htmlTextPart::embeddedObject> obj = +			textPart.addObject( +				imageCts, +				vmime::mediaType( +					vmime::mediaTypes::IMAGE, +					vmime::mediaTypes::IMAGE_JPEG +				) +			); + +		// -- message text +		textPart.setText( +			vmime::make_shared <vmime::stringContentHandler>( +				vmime::string("This is the <b>HTML text</b>.<br/>" +				"<img src=\"") + obj->getReferenceId() + vmime::string("\"/>") +			) +		); + +		textPart.setPlainText( +			vmime::make_shared <vmime::stringContentHandler>( +				"This is the plain text (without HTML formatting)." +			) +		); + +		// Construction +		vmime::shared_ptr <vmime::message> 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 <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. +// + +// +// 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 <iostream> +#include <locale> +#include <clocale> + +#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<const vmime::htmlTextPart&>(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<const vmime::textPart&>(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 <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. +// + +// +// 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 <iostream> +#include <locale> +#include <clocale> + +#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 <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 <iostream> +#include <sstream> +#include <vector> +#include <map> +#include <locale> +#include <clocale> + +#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 <vmime::net::session> 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 <vmime::net::serviceFactory> 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 <const vmime::exceptions::command_error*>(&e)) { + +		const vmime::exceptions::command_error& cee = +			dynamic_cast <const vmime::exceptions::command_error&>(e); + +		os << "    command = " << cee.command() << std::endl; +		os << "    response = " << cee.response() << std::endl; +	} + +	if (dynamic_cast <const vmime::exceptions::invalid_response*>(&e)) { + +		const vmime::exceptions::invalid_response& ir = +			dynamic_cast <const vmime::exceptions::invalid_response&>(e); + +		os << "    response = " << ir.response() << std::endl; +	} + +	if (dynamic_cast <const vmime::exceptions::connection_greeting_error*>(&e)) { + +		const vmime::exceptions::connection_greeting_error& cgee = +			dynamic_cast <const vmime::exceptions::connection_greeting_error&>(e); + +		os << "    response = " << cgee.response() << std::endl; +	} + +	if (dynamic_cast <const vmime::exceptions::authentication_error*>(&e)) { + +		const vmime::exceptions::authentication_error& aee = +			dynamic_cast <const vmime::exceptions::authentication_error&>(e); + +		os << "    response = " << aee.response() << std::endl; +	} + +	if (dynamic_cast <const vmime::exceptions::filesystem_exception*>(&e)) { + +		const vmime::exceptions::filesystem_exception& fse = +			dynamic_cast <const vmime::exceptions::filesystem_exception&>(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 <const vmime::net::messageStructure> s, +	const int level = 0 +) { + +	for (size_t i = 0 ; i < s->getPartCount() ; ++i) { + +		vmime::shared_ptr <const vmime::net::messagePart> 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 <vmime::net::folder> f) { + +	const vmime::string n = f->getName().getBuffer(); + +	if (n.empty()) {  // root folder + +		return "/"; + +	} else { + +		vmime::shared_ptr <vmime::net::folder> 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 <vmime::net::folder> 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 <vmime::shared_ptr <vmime::net::folder> > 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 <std::string>& 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 <vmime::net::transport> tr; + +		if (url.getUsername().empty() || url.getPassword().empty()) { +			tr = g_session->getTransport(url, vmime::make_shared <interactiveAuthenticator>()); +		} 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 <timeoutHandlerFactory>()); + +		// Set the object responsible for verifying certificates, in the +		// case a secured connection is used (TLS/SSL) +		tr->setCertificateVerifier( +			vmime::make_shared <interactiveCertificateVerifier>() +		); + +#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 <std::ostringstream> traceStream = vmime::make_shared <std::ostringstream>(); +		tr->setTracerFactory(vmime::make_shared <myTracerFactory>(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 <vmime::mailbox>(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 <vmime::net::store> st; + +		if (url.getUsername().empty() || url.getPassword().empty()) { +			st = g_session->getStore(url, vmime::make_shared <interactiveAuthenticator>()); +		} 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 <timeoutHandlerFactory>()); + +		// Set the object responsible for verifying certificates, in the +		// case a secured connection is used (TLS/SSL) +		st->setCertificateVerifier( +			vmime::make_shared <interactiveCertificateVerifier>() +		); + +#endif // VMIME_HAVE_TLS_SUPPORT + +		// Trace communication between client and server +		vmime::shared_ptr <std::ostringstream> traceStream = vmime::make_shared <std::ostringstream>(); +		st->setTracerFactory(vmime::make_shared <myTracerFactory>(traceStream)); + +		// Connect to the mail store +		st->connect(); + +		// Display some information about the connection +		vmime::shared_ptr <vmime::net::connectionInfos> 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 <vmime::net::folder> f = st->getDefaultFolder(); +//		vmime::shared_ptr <vmime::net::folder> 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 <vmime::size_t, vmime::shared_ptr <vmime::net::message> > MessageList; +			MessageList msgList; + +			try { + +				std::vector <std::string> 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 <vmime::net::message> 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 <vmime::message> parsedMsg = msg->getParsedMessage(); + +					std::vector <vmime::shared_ptr <const vmime::attachment> > attchs = +						vmime::attachmentHelper::findAttachmentsInMessage(parsedMsg); + +					if (attchs.size() > 0) { + +						std::cout << attchs.size() << " attachments found." << std::endl; + +						for (std::vector <vmime::shared_ptr <const vmime::attachment> >::iterator +						     it = attchs.begin() ; it != attchs.end() ; ++it) { + +							vmime::shared_ptr <const vmime::attachment> 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 <vmime::utility::fileSystemFactory> fsf +								= vmime::platform::getHandler()->getFileSystemFactory(); + +							vmime::shared_ptr <vmime::utility::file> 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 <vmime::utility::outputStream> 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 <vmime::net::folder> 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 <vmime::net::folder> 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 <vmime::mailbox>("you@elsewhere.com")); +					mb.setRecipients(to); + +					mb.setSubject(vmime::text("Test message from VMime example6")); +					mb.getTextPart()->setText( +						vmime::make_shared <vmime::stringContentHandler>( +							"Body of test message from VMime example6." +						) +					); + +					vmime::shared_ptr <vmime::message> 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 <const vmime::net::UIDMessageRange&>(range).getFirst(); + +							std::cout << "Message has successfully been added, " +							          << "its UID is '" << uid << "'." << std::endl; + +						} else { + +							const vmime::size_t number = +								dynamic_cast <const vmime::net::numberMessageRange&>(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 <const vmime::net::UIDMessageRange&>(range).getFirst(); + +							std::cout << "Message has successfully been copied, " +							          << "its UID is '" << uid << "'." << std::endl; + +						} else { + +							const vmime::size_t number = +								dynamic_cast <const vmime::net::numberMessageRange&>(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 <vmime::net::folder> f = st->getFolder(vmime::net::folder::path("c")); +			f->rename(vmime::net::folder::path("c2")); + +			vmime::shared_ptr <vmime::net::folder> 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 <vmime::net::folder> 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 <std::string> 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 <vmime::shared_ptr <vmime::security::sasl::SASLMechanism> > +		getAcceptableMechanisms( +			const std::vector <vmime::shared_ptr <vmime::security::sasl::SASLMechanism> >& available, +			const vmime::shared_ptr <vmime::security::sasl::SASLMechanism>& 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 <vmime::security::sasl::SASLMechanism>& 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 <vmime::security::cert::certificateChain>& 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 <vmime::security::cert::certificate> 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 <vmime::security::cert::X509Certificate>(cert) +					); + +					setX509TrustedCerts(m_trustedCerts); +					defaultCertificateVerifier::verify(chain, hostname); +				} + +				return; +			} + +			throw vmime::security::cert::certificateException("User did not accept the certificate."); +		} +	} + +private: + +	static std::vector <vmime::shared_ptr <vmime::security::cert::X509Certificate> > m_trustedCerts; +}; + + +std::vector <vmime::shared_ptr <vmime::security::cert::X509Certificate> > +	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 <ctime> + + +/** 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 <vmime::net::timeoutHandler> create() { + +		return vmime::make_shared <timeoutHandler>(); +	} +}; 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 <std::ostringstream>& stream, +		const vmime::shared_ptr <vmime::net::service>& 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 <std::ostringstream> m_stream; +	vmime::shared_ptr <vmime::net::service> m_service; +	const int m_connectionId; +}; + + +class myTracerFactory : public vmime::net::tracerFactory { + +public: + +	myTracerFactory(const vmime::shared_ptr <std::ostringstream>& stream) +		: m_stream(stream) { + +	} + +	vmime::shared_ptr <vmime::net::tracer> create( +		const vmime::shared_ptr <vmime::net::service>& serv, +		const int connectionId +	) { + +		return vmime::make_shared <myTracer>(m_stream, serv, connectionId); +	} + +private: + +	vmime::shared_ptr <std::ostringstream> 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 <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. +// + +// +// 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 <iostream> +#include <locale> +#include <clocale> + +#include "vmime/vmime.hpp" +#include "vmime/platforms/posix/posixHandler.hpp" + + +int main() { + +	// Enumerate encoders +	vmime::shared_ptr <vmime::utility::encoder::encoderFactory> ef = +		vmime::utility::encoder::encoderFactory::getInstance(); + +	std::cout << "Available encoders:" << std::endl; + +	for (size_t i = 0 ; i < ef->getEncoderCount() ; ++i) { + +		vmime::shared_ptr <const vmime::utility::encoder::encoderFactory::registeredEncoder> +			enc = ef->getEncoderAt(i); + +		std::cout << "  * " << enc->getName() << std::endl; + +		vmime::shared_ptr <vmime::utility::encoder::encoder> e = +			vmime::utility::encoder::encoderFactory::getInstance()->create(enc->getName()); + +		std::vector <vmime::string> props = e->getAvailableProperties(); + +		for (std::vector <vmime::string>::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 <vmime::net::serviceFactory> 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 <vmime::net::serviceInfos::property> props = +			serv.getInfos().getAvailableProperties(); + +		for (std::vector <vmime::net::serviceInfos::property>::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 <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. +// + +// +// 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 <iostream> +#include <fstream> +#include <vector> +#include <typeinfo> + +#include <gtk/gtk.h> + +#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 <vmime::message> currentMessage; + + + +void insertRowInModel( +	GtkTreeStore* model, +	vmime::shared_ptr <vmime::component> 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 <vmime::shared_ptr <vmime::component> > 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 <vmime::message> msg = vmime::make_shared <vmime::message>(); +	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...", "<control>O", NULL, G_CALLBACK(onFileOpen) }, +	{ "FileExit", GTK_STOCK_QUIT, "_Exit", "<control>Q", NULL, G_CALLBACK(gtk_main_quit) } +}; + +static const char* uiDefinition = +	"<ui>" \ +	"	<menubar name=\"MainMenuBar\">" \ +	"		<menu action=\"FileMenu\">" \ +	"			<menuitem action=\"FileOpen\"/>" \ +	"			<menuitem action=\"FileExit\"/>" \ +	"		</menu>" \ +	"	</menubar>" \ +	"</ui>"; + + +int main(int argc, char* argv[]) { + +	// VMime initialization +	vmime::platform::setHandler<vmime::platforms::posix::posixHandler>(); + +	// 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; +} | 
