aboutsummaryrefslogtreecommitdiff
path: root/vmime-master/examples
diff options
context:
space:
mode:
authorWojtek Kosior <wk@koszkonutek-tmp.pl.eu.org>2021-04-30 00:33:56 +0200
committerWojtek Kosior <wk@koszkonutek-tmp.pl.eu.org>2021-04-30 00:33:56 +0200
commitaa4d426b4d3527d7e166df1a05058c9a4a0f6683 (patch)
tree4ff17ce8b89a2321b9d0ed4bcfc37c447bcb6820 /vmime-master/examples
downloadsmtps-and-pop3s-console-program-master.tar.gz
smtps-and-pop3s-console-program-master.zip
initial/final commitHEADmaster
Diffstat (limited to 'vmime-master/examples')
-rw-r--r--vmime-master/examples/CMakeLists.txt38
-rw-r--r--vmime-master/examples/example1.cpp107
-rw-r--r--vmime-master/examples/example2.cpp121
-rw-r--r--vmime-master/examples/example3.cpp153
-rw-r--r--vmime-master/examples/example4.cpp108
-rw-r--r--vmime-master/examples/example5.cpp85
-rw-r--r--vmime-master/examples/example6.cpp938
-rw-r--r--vmime-master/examples/example6_authenticator.hpp112
-rw-r--r--vmime-master/examples/example6_certificateVerifier.hpp64
-rw-r--r--vmime-master/examples/example6_timeoutHandler.hpp60
-rw-r--r--vmime-master/examples/example6_tracer.hpp59
-rw-r--r--vmime-master/examples/example7.cpp118
-rw-r--r--vmime-master/examples/viewer/CMakeLists.txt31
-rw-r--r--vmime-master/examples/viewer/viewer.cpp294
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;
+}