comparison 3rdparty/vmime/examples/example6.cpp @ 0:a4671277546c tip

created the repository for the thymian project
author ferencd
date Tue, 17 Aug 2021 11:19:54 +0200
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:a4671277546c
1 //
2 // VMime library (http://www.vmime.org)
3 // Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
4 //
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License as
7 // published by the Free Software Foundation; either version 3 of
8 // the License, or (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License along
16 // with this program; if not, write to the Free Software Foundation, Inc.,
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 //
19 // Linking this library statically or dynamically with other modules is making
20 // a combined work based on this library. Thus, the terms and conditions of
21 // the GNU General Public License cover the whole combination.
22 //
23
24 #include <iostream>
25 #include <sstream>
26 #include <vector>
27 #include <map>
28 #include <locale>
29 #include <clocale>
30
31 #include "vmime/vmime.hpp"
32 #include "vmime/platforms/posix/posixHandler.hpp"
33
34 #include "example6_tracer.hpp"
35 #include "example6_authenticator.hpp"
36 #include "example6_certificateVerifier.hpp"
37 #include "example6_timeoutHandler.hpp"
38
39
40 // Global session object
41 static vmime::shared_ptr <vmime::net::session> g_session
42 = vmime::make_shared <vmime::net::session>();
43
44
45 /** Returns the messaging protocols supported by VMime.
46 *
47 * @param type service type (vmime::net::service::TYPE_STORE or
48 * vmime::net::service::TYPE_TRANSPORT)
49 */
50 static const std::string findAvailableProtocols(const vmime::net::service::Type type)
51 {
52 vmime::shared_ptr <vmime::net::serviceFactory> sf =
53 vmime::net::serviceFactory::getInstance();
54
55 std::ostringstream res;
56 int count = 0;
57
58 for (int i = 0 ; i < sf->getServiceCount() ; ++i)
59 {
60 const vmime::net::serviceFactory::registeredService& serv = *sf->getServiceAt(i);
61
62 if (serv.getType() == type)
63 {
64 if (count != 0)
65 res << ", ";
66
67 res << serv.getName();
68 ++count;
69 }
70 }
71
72 return res.str();
73 }
74
75
76 // Exception helper
77 static std::ostream& operator<<(std::ostream& os, const vmime::exception& e)
78 {
79 os << "* vmime::exceptions::" << e.name() << std::endl;
80 os << " what = " << e.what() << std::endl;
81
82 // More information for special exceptions
83 if (dynamic_cast <const vmime::exceptions::command_error*>(&e))
84 {
85 const vmime::exceptions::command_error& cee =
86 dynamic_cast <const vmime::exceptions::command_error&>(e);
87
88 os << " command = " << cee.command() << std::endl;
89 os << " response = " << cee.response() << std::endl;
90 }
91
92 if (dynamic_cast <const vmime::exceptions::invalid_response*>(&e))
93 {
94 const vmime::exceptions::invalid_response& ir =
95 dynamic_cast <const vmime::exceptions::invalid_response&>(e);
96
97 os << " response = " << ir.response() << std::endl;
98 }
99
100 if (dynamic_cast <const vmime::exceptions::connection_greeting_error*>(&e))
101 {
102 const vmime::exceptions::connection_greeting_error& cgee =
103 dynamic_cast <const vmime::exceptions::connection_greeting_error&>(e);
104
105 os << " response = " << cgee.response() << std::endl;
106 }
107
108 if (dynamic_cast <const vmime::exceptions::authentication_error*>(&e))
109 {
110 const vmime::exceptions::authentication_error& aee =
111 dynamic_cast <const vmime::exceptions::authentication_error&>(e);
112
113 os << " response = " << aee.response() << std::endl;
114 }
115
116 if (dynamic_cast <const vmime::exceptions::filesystem_exception*>(&e))
117 {
118 const vmime::exceptions::filesystem_exception& fse =
119 dynamic_cast <const vmime::exceptions::filesystem_exception&>(e);
120
121 os << " path = " << vmime::platform::getHandler()->
122 getFileSystemFactory()->pathToString(fse.path()) << std::endl;
123 }
124
125 if (e.other() != NULL)
126 os << *e.other();
127
128 return os;
129 }
130
131
132 /** Print the MIME structure of a message on the standard output.
133 *
134 * @param s structure object
135 * @param level current depth
136 */
137 static void printStructure(vmime::shared_ptr <const vmime::net::messageStructure> s, const int level = 0)
138 {
139 for (int i = 0 ; i < s->getPartCount() ; ++i)
140 {
141 vmime::shared_ptr <const vmime::net::messagePart> part = s->getPartAt(i);
142
143 for (int j = 0 ; j < level * 2 ; ++j)
144 std::cout << " ";
145
146 std::cout << (part->getNumber() + 1) << ". "
147 << part->getType().generate()
148 << " [" << part->getSize() << " byte(s)]"
149 << std::endl;
150
151 printStructure(part->getStructure(), level + 1);
152 }
153 }
154
155
156 static const vmime::string getFolderPathString(vmime::shared_ptr <vmime::net::folder> f)
157 {
158 const vmime::string n = f->getName().getBuffer();
159
160 if (n.empty()) // root folder
161 {
162 return "/";
163 }
164 else
165 {
166 vmime::shared_ptr <vmime::net::folder> p = f->getParent();
167 return getFolderPathString(p) + n + "/";
168 }
169 }
170
171
172 /** Print folders and sub-folders on the standard output.
173 *
174 * @param folder current folder
175 */
176 static void printFolders(vmime::shared_ptr <vmime::net::folder> folder, const int level = 0)
177 {
178 for (int j = 0 ; j < level * 2 ; ++j)
179 std::cout << " ";
180
181 std::cout << getFolderPathString(folder) << std::endl;
182
183 std::vector <vmime::shared_ptr <vmime::net::folder> > subFolders = folder->getFolders(false);
184
185 for (unsigned int i = 0 ; i < subFolders.size() ; ++i)
186 printFolders(subFolders[i], level + 1);
187 }
188
189
190 /** Print a menu on the standard output.
191 *
192 * @param choices menu choices
193 */
194 static unsigned int printMenu(const std::vector <std::string>& choices)
195 {
196 std::cout << std::endl;
197
198 for (unsigned int i = 0 ; i < choices.size() ; ++i)
199 std::cout << " " << (i + 1) << ". " << choices[i] << std::endl;
200
201 std::cout << std::endl;
202 std::cout << " Your choice? [1-" << choices.size() << "] ";
203 std::cout.flush();
204
205 std::string line;
206 std::getline(std::cin, line);
207
208 std::istringstream iss(line);
209
210 unsigned int choice = 0;
211 iss >> choice;
212
213 std::cout << std::endl;
214
215 if (choice < 1 || choice > choices.size())
216 return 0;
217 else
218 return choice;
219 }
220
221
222 /** Send a message interactively.
223 */
224 static void sendMessage()
225 {
226 try
227 {
228 // Request user to enter an URL
229 std::cout << "Enter an URL to connect to transport service." << std::endl;
230 std::cout << "Available protocols: " << findAvailableProtocols(vmime::net::service::TYPE_TRANSPORT) << std::endl;
231 std::cout << "(eg. smtp://myserver.com, sendmail://localhost)" << std::endl;
232 std::cout << "> ";
233 std::cout.flush();
234
235 vmime::string urlString;
236 std::getline(std::cin, urlString);
237
238 vmime::utility::url url(urlString);
239
240 vmime::shared_ptr <vmime::net::transport> tr;
241
242 if (url.getUsername().empty() || url.getPassword().empty())
243 tr = g_session->getTransport(url, vmime::make_shared <interactiveAuthenticator>());
244 else
245 tr = g_session->getTransport(url);
246
247 #if VMIME_HAVE_TLS_SUPPORT
248
249 // Enable TLS support if available
250 tr->setProperty("connection.tls", true);
251
252 // Set the time out handler
253 tr->setTimeoutHandlerFactory(vmime::make_shared <timeoutHandlerFactory>());
254
255 // Set the object responsible for verifying certificates, in the
256 // case a secured connection is used (TLS/SSL)
257 tr->setCertificateVerifier
258 (vmime::make_shared <interactiveCertificateVerifier>());
259
260 #endif // VMIME_HAVE_TLS_SUPPORT
261
262 // You can also set some properties (see example7 to know the properties
263 // available for each service). For example, for SMTP:
264 if (!url.getUsername().empty() || !url.getPassword().empty())
265 tr->setProperty("options.need-authentication", true);
266
267 // Trace communication between client and server
268 vmime::shared_ptr <std::ostringstream> traceStream = vmime::make_shared <std::ostringstream>();
269 tr->setTracerFactory(vmime::make_shared <myTracerFactory>(traceStream));
270
271 // Information about the mail
272 std::cout << "Enter email of the expeditor (eg. me@somewhere.com): ";
273 std::cout.flush();
274
275 vmime::string fromString;
276 std::getline(std::cin, fromString);
277
278 vmime::mailbox from(fromString);
279 vmime::mailboxList to;
280
281 for (bool cont = true ; cont ; )
282 {
283 std::cout << "Enter email of the recipient (empty to stop): ";
284 std::cout.flush();
285
286 vmime::string toString;
287 std::getline(std::cin, toString);
288
289 cont = (toString.size() != 0);
290
291 if (cont)
292 to.appendMailbox(vmime::make_shared <vmime::mailbox>(toString));
293 }
294
295 std::cout << "Enter message data, including headers (end with '.' on a single line):" << std::endl;
296
297 std::ostringstream data;
298
299 for (bool cont = true ; cont ; )
300 {
301 std::string line;
302 std::getline(std::cin, line);
303
304 if (line == ".")
305 cont = false;
306 else
307 data << line << "\r\n";
308 }
309
310 // Connect to server
311 tr->connect();
312
313 // Send the message
314 vmime::string msgData = data.str();
315 vmime::utility::inputStreamStringAdapter vis(msgData);
316
317 tr->send(from, to, vis, msgData.length());
318
319 // Note: you could also write this:
320 // vmime::message msg;
321 // ...
322 // tr->send(&msg);
323
324 // Display connection log
325 std::cout << std::endl;
326 std::cout << "Connection Trace:" << std::endl;
327 std::cout << "=================" << std::endl;
328 std::cout << traceStream->str();
329
330 tr->disconnect();
331 }
332 catch (vmime::exception& e)
333 {
334 std::cerr << std::endl;
335 std::cerr << e << std::endl;
336 throw;
337 }
338 catch (std::exception& e)
339 {
340 std::cerr << std::endl;
341 std::cerr << "std::exception: " << e.what() << std::endl;
342 throw;
343 }
344 }
345
346
347 /** Connect to a message store interactively.
348 */
349 static void connectStore()
350 {
351 try
352 {
353 // Request user to enter an URL
354 std::cout << "Enter an URL to connect to store service." << std::endl;
355 std::cout << "Available protocols: " << findAvailableProtocols(vmime::net::service::TYPE_STORE) << std::endl;
356 std::cout << "(eg. pop3://user:pass@myserver.com, imap://myserver.com:123)" << std::endl;
357 std::cout << "> ";
358 std::cout.flush();
359
360 vmime::string urlString;
361 std::getline(std::cin, urlString);
362
363 vmime::utility::url url(urlString);
364
365 // If no authenticator is given in argument to getStore(), a default one
366 // is used. Its behaviour is to get the user credentials from the
367 // session properties "auth.username" and "auth.password".
368 vmime::shared_ptr <vmime::net::store> st;
369
370 if (url.getUsername().empty() || url.getPassword().empty())
371 st = g_session->getStore(url, vmime::make_shared <interactiveAuthenticator>());
372 else
373 st = g_session->getStore(url);
374
375 #if VMIME_HAVE_TLS_SUPPORT
376
377 // Enable TLS support if available
378 st->setProperty("connection.tls", true);
379
380 // Set the time out handler
381 st->setTimeoutHandlerFactory(vmime::make_shared <timeoutHandlerFactory>());
382
383 // Set the object responsible for verifying certificates, in the
384 // case a secured connection is used (TLS/SSL)
385 st->setCertificateVerifier
386 (vmime::make_shared <interactiveCertificateVerifier>());
387
388 #endif // VMIME_HAVE_TLS_SUPPORT
389
390 // Trace communication between client and server
391 vmime::shared_ptr <std::ostringstream> traceStream = vmime::make_shared <std::ostringstream>();
392 st->setTracerFactory(vmime::make_shared <myTracerFactory>(traceStream));
393
394 // Connect to the mail store
395 st->connect();
396
397 // Display some information about the connection
398 vmime::shared_ptr <vmime::net::connectionInfos> ci = st->getConnectionInfos();
399
400 std::cout << std::endl;
401 std::cout << "Connected to '" << ci->getHost() << "' (port " << ci->getPort() << ")" << std::endl;
402 std::cout << "Connection is " << (st->isSecuredConnection() ? "" : "NOT ") << "secured." << std::endl;
403
404 // Open the default folder in this store
405 vmime::shared_ptr <vmime::net::folder> f = st->getDefaultFolder();
406 // vmime::shared_ptr <vmime::net::folder> f = st->getFolder(vmime::utility::path("a"));
407
408 f->open(vmime::net::folder::MODE_READ_WRITE);
409
410 int count = f->getMessageCount();
411
412 std::cout << std::endl;
413 std::cout << count << " message(s) in your inbox" << std::endl;
414
415 for (bool cont = true ; cont ; )
416 {
417 typedef std::map <int, vmime::shared_ptr <vmime::net::message> > MessageList;
418 MessageList msgList;
419
420 try
421 {
422 std::vector <std::string> choices;
423
424 choices.push_back("Show message flags");
425 choices.push_back("Show message structure");
426 choices.push_back("Show message header");
427 choices.push_back("Show message envelope");
428 choices.push_back("Extract whole message");
429 choices.push_back("Extract attachments");
430 choices.push_back("Status");
431 choices.push_back("List folders");
432 choices.push_back("Change folder");
433 choices.push_back("Add message (to the current folder)");
434 choices.push_back("Copy message (into the current folder)");
435 choices.push_back("Display trace output");
436 choices.push_back("Return to main menu");
437
438 const int choice = printMenu(choices);
439
440 // Request message number
441 vmime::shared_ptr <vmime::net::message> msg;
442
443 if (choice == 1 || choice == 2 || choice == 3 || choice == 4 ||
444 choice == 5 || choice == 6 || choice == 11)
445 {
446 std::cout << "Enter message number: ";
447 std::cout.flush();
448
449 std::string line;
450 std::getline(std::cin, line);
451
452 std::istringstream iss(line);
453
454 int num = 0;
455 iss >> num;
456
457 if (num < 1 || num > f->getMessageCount())
458 {
459 std::cerr << "Invalid message number." << std::endl;
460 continue;
461 }
462
463 MessageList::iterator it = msgList.find(num);
464
465 if (it != msgList.end())
466 {
467 msg = (*it).second;
468 }
469 else
470 {
471 msg = f->getMessage(num);
472 msgList.insert(MessageList::value_type(num, msg));
473 }
474
475 std::cout << std::endl;
476 }
477
478 switch (choice)
479 {
480 // Show message flags
481 case 1:
482
483 f->fetchMessage(msg, vmime::net::fetchAttributes::FLAGS);
484
485 if (msg->getFlags() & vmime::net::message::FLAG_SEEN)
486 std::cout << "FLAG_SEEN" << std::endl;
487 if (msg->getFlags() & vmime::net::message::FLAG_RECENT)
488 std::cout << "FLAG_RECENT" << std::endl;
489 if (msg->getFlags() & vmime::net::message::FLAG_REPLIED)
490 std::cout << "FLAG_REPLIED" << std::endl;
491 if (msg->getFlags() & vmime::net::message::FLAG_DELETED)
492 std::cout << "FLAG_DELETED" << std::endl;
493 if (msg->getFlags() & vmime::net::message::FLAG_MARKED)
494 std::cout << "FLAG_MARKED" << std::endl;
495 if (msg->getFlags() & vmime::net::message::FLAG_PASSED)
496 std::cout << "FLAG_PASSED" << std::endl;
497
498 break;
499
500 // Show message structure
501 case 2:
502
503 f->fetchMessage(msg, vmime::net::fetchAttributes::STRUCTURE);
504 printStructure(msg->getStructure());
505 break;
506
507 // Show message header
508 case 3:
509
510 f->fetchMessage(msg, vmime::net::fetchAttributes::FULL_HEADER);
511 std::cout << msg->getHeader()->generate() << std::endl;
512 break;
513
514 // Show message envelope
515 case 4:
516
517 f->fetchMessage(msg, vmime::net::fetchAttributes::ENVELOPE);
518
519 #define ENV_HELPER(x) \
520 try { std::cout << msg->getHeader()->x()->generate() << std::endl; } \
521 catch (vmime::exception) { /* In case the header field does not exist. */ }
522
523 ENV_HELPER(From)
524 ENV_HELPER(To)
525 ENV_HELPER(Date)
526 ENV_HELPER(Subject)
527
528 #undef ENV_HELPER
529
530 break;
531
532 // Extract whole message
533 case 5:
534 {
535 vmime::utility::outputStreamAdapter out(std::cout);
536 msg->extract(out);
537
538 break;
539 }
540 // Extract attachments
541 case 6:
542 {
543 vmime::shared_ptr <vmime::message> parsedMsg = msg->getParsedMessage();
544
545 std::vector <vmime::shared_ptr <const vmime::attachment> > attchs =
546 vmime::attachmentHelper::findAttachmentsInMessage(parsedMsg);
547
548 if (attchs.size() > 0)
549 {
550 std::cout << attchs.size() << " attachments found." << std::endl;
551
552 for (std::vector <vmime::shared_ptr <const vmime::attachment> >::iterator
553 it = attchs.begin() ; it != attchs.end() ; ++it)
554 {
555 vmime::shared_ptr <const vmime::attachment> att = *it;
556
557 // Get attachment size
558 vmime::size_t size = 0;
559
560 if (att->getData()->isEncoded())
561 size = att->getData()->getEncoding().getEncoder()->getDecodedSize(att->getData()->getLength());
562 else
563 size = att->getData()->getLength();
564
565 std::cout << "Found attachment '" << att->getName().getBuffer() << "'"
566 << ", size is " << size << " bytes:" << std::endl;
567
568 // Get attachment data
569 std::cout << std::endl;
570 std::cout << "========== BEGIN CONTENT ==========" << std::endl;
571
572 vmime::utility::outputStreamAdapter osa(std::cout);
573 att->getData()->extract(osa);
574
575 std::cout << std::endl;
576 std::cout << "========== END CONTENT ==========" << std::endl;
577
578 // Or write it to a file
579 /*
580 vmime::shared_ptr <vmime::utility::fileSystemFactory> fsf
581 = vmime::platform::getHandler()->getFileSystemFactory();
582
583 vmime::shared_ptr <vmime::utility::file> file
584 = fsf->create(vmime::utility::path::fromString
585 ("/path/to/attachment-file", "/", vmime::charsets::UTF_8));
586 // -or- ("C:\\Temp\\attachment-file", "\\", vmime::charsets::UTF_8));
587
588 file->createFile();
589
590 vmime::shared_ptr <vmime::utility::outputStream> output =
591 file->getFileWriter()->getOutputStream();
592
593 att->getData()->extract(*output.get());
594 */
595 }
596 }
597 else
598 {
599 std::cout << "No attachments found." << std::endl;
600 }
601
602 break;
603 }
604 // Status
605 case 7:
606 {
607 int count, unseen;
608 f->status(count, unseen);
609
610 std::cout << "Status: count=" << count << ", unseen=" << unseen << std::endl;
611 break;
612 }
613 // List folders
614 case 8:
615 {
616 vmime::shared_ptr <vmime::net::folder>
617 root = st->getRootFolder();
618
619 printFolders(root);
620 break;
621 }
622 // Change folder
623 case 9:
624 {
625 std::cout << "Enter folder path (eg. /root/subfolder):" << std::endl;
626 std::cout.flush();
627
628 std::string path;
629 std::getline(std::cin, path);
630
631 vmime::shared_ptr <vmime::net::folder> newFolder = st->getRootFolder();
632
633 for (std::string::size_type s = 0, p = 0 ; ; s = p + 1)
634 {
635 p = path.find_first_of('/', s);
636
637 const std::string x = (p == std::string::npos)
638 ? std::string(path.begin() + s, path.end())
639 : std::string(path.begin() + s, path.begin() + p);
640
641 if (!x.empty())
642 newFolder = newFolder->getFolder(x);
643
644 if (p == std::string::npos)
645 break;
646 }
647
648 newFolder->open(vmime::net::folder::MODE_READ_WRITE);
649
650 count = newFolder->getMessageCount();
651
652 std::cout << std::endl;
653 std::cout << count << " message(s) in this folder" << std::endl;
654
655 f->close(true); // 'true' to expunge deleted messages
656 f = newFolder;
657
658 break;
659 }
660 // Add message
661 case 10:
662 {
663 vmime::messageBuilder mb;
664
665 mb.setExpeditor(vmime::mailbox("me@somewhere.com"));
666
667 vmime::addressList to;
668 to.appendAddress(vmime::make_shared <vmime::mailbox>("you@elsewhere.com"));
669 mb.setRecipients(to);
670
671 mb.setSubject(vmime::text("Test message from VMime example6"));
672 mb.getTextPart()->setText(vmime::make_shared <vmime::stringContentHandler>(
673 "Body of test message from VMime example6."));
674
675 vmime::shared_ptr <vmime::message> msg = mb.construct();
676
677 vmime::net::messageSet set = f->addMessage(msg);
678
679 if (set.isEmpty())
680 {
681 std::cout << "Message has successfully been added, "
682 << "but its UID/number is not known." << std::endl;
683 }
684 else
685 {
686 const vmime::net::messageRange& range = set.getRangeAt(0);
687
688 if (set.isUIDSet())
689 {
690 const vmime::net::message::uid uid =
691 dynamic_cast <const vmime::net::UIDMessageRange&>(range).getFirst();
692
693 std::cout << "Message has successfully been added, "
694 << "its UID is '" << uid << "'." << std::endl;
695 }
696 else
697 {
698 const int number =
699 dynamic_cast <const vmime::net::numberMessageRange&>(range).getFirst();
700
701 std::cout << "Message has successfully been added, "
702 << "its number is '" << number << "'." << std::endl;
703 }
704 }
705
706 break;
707 }
708 // Copy message
709 case 11:
710 {
711 vmime::net::messageSet set = f->copyMessages(f->getFullPath(),
712 vmime::net::messageSet::byNumber(msg->getNumber()));
713
714 if (set.isEmpty())
715 {
716 std::cout << "Message has successfully been copied, "
717 << "but its UID/number is not known." << std::endl;
718 }
719 else
720 {
721 const vmime::net::messageRange& range = set.getRangeAt(0);
722
723 if (set.isUIDSet())
724 {
725 const vmime::net::message::uid uid =
726 dynamic_cast <const vmime::net::UIDMessageRange&>(range).getFirst();
727
728 std::cout << "Message has successfully been copied, "
729 << "its UID is '" << uid << "'." << std::endl;
730 }
731 else
732 {
733 const int number =
734 dynamic_cast <const vmime::net::numberMessageRange&>(range).getFirst();
735
736 std::cout << "Message has successfully been copied, "
737 << "its number is '" << number << "'." << std::endl;
738 }
739 }
740
741 break;
742 }
743 // Display trace output
744 case 12:
745
746 std::cout << std::endl;
747 std::cout << "Connection Trace:" << std::endl;
748 std::cout << "=================" << std::endl;
749 std::cout << traceStream->str();
750 break;
751
752 // Main menu
753 case 13:
754
755 f->close(true); // 'true' to expunge deleted messages
756 cont = false;
757 break;
758 }
759
760 /*
761 // Append message
762 std::istringstream iss(
763 "From: me@localhost\r\n"
764 "To: you@localhost\r\n"
765 "Subject: Message Text\r\n"
766 "\r\n"
767 "This is a test message...\r\n"
768 "Bye bye!\r\n"
769 );
770
771 f->addMessage(iss, iss.str().size());
772
773 // Folder renaming
774 {
775 vmime::shared_ptr <vmime::net::folder> f = st->getFolder(vmime::net::folder::path("c"));
776 f->rename(vmime::net::folder::path("c2"));
777
778 vmime::shared_ptr <vmime::net::folder> g = st->getFolder(vmime::net::folder::path("c2"));
779 g->rename(vmime::net::folder::path("c"));
780 }
781
782 // Message copy: copy all messages from 'f' to 'g'
783 {
784 vmime::shared_ptr <vmime::net::folder> g = st->getFolder(vmime::net::folder::path("TEMP"));
785
786 if (!g->exists())
787 g->create(vmime::net::folder::TYPE_CONTAINS_MESSAGES);
788
789 f->copyMessages(g->getFullPath());
790 }
791 */
792 }
793 catch (vmime::exception& e)
794 {
795 std::cerr << std::endl;
796 std::cerr << e << std::endl;
797 }
798 catch (std::exception& e)
799 {
800 std::cerr << std::endl;
801 std::cerr << "std::exception: " << e.what() << std::endl;
802 }
803 } // for(cont)
804
805 st->disconnect();
806 }
807 catch (vmime::exception& e)
808 {
809 std::cerr << std::endl;
810 std::cerr << e << std::endl;
811 throw;
812 }
813 catch (std::exception& e)
814 {
815 std::cerr << std::endl;
816 std::cerr << "std::exception: " << e.what() << std::endl;
817 throw;
818 }
819 }
820
821
822 /* Show the main menu.
823 *
824 * @return true to quit the program, false to continue
825 */
826 static bool menu()
827 {
828 std::vector <std::string> items;
829
830 items.push_back("Connect to a message store");
831 items.push_back("Send a message");
832 items.push_back("Quit");
833
834 switch (printMenu(items))
835 {
836 // Connect to store
837 case 1:
838
839 connectStore();
840 return false;
841
842 // Send a message
843 case 2:
844
845 sendMessage();
846 return false;
847
848 // Quit
849 case 3:
850
851 return true;
852
853 // Other choice
854 default:
855
856 return false;
857 }
858 }
859
860
861 int main()
862 {
863 // Set the global C and C++ locale to the user-configured locale.
864 // The locale should use UTF-8 encoding for these tests to run successfully.
865 try
866 {
867 std::locale::global(std::locale(""));
868 }
869 catch (std::exception &)
870 {
871 std::setlocale(LC_ALL, "");
872 }
873
874 for (bool quit = false ; !quit ; )
875 {
876 // Loop on main menu
877 quit = menu();
878 }
879
880 return 0;
881 }
882