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