aboutsummaryrefslogtreecommitdiff
path: root/push.cpp
blob: e304403ab6506647d97e0ed3224bbcf74f32e4cf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#include <unistd.h>

#include "vmime/vmime.hpp"
#include "utilities.h"
#include "timeout_handler.hpp"
#include "exceptions.hpp"

extern "C" void validate_config(struct config *config)
{
	if (config->use_SSL == PARAM_NOT_GIVEN)
		config->use_SSL = PARAM_NO;	
	if (config->use_AUTH == PARAM_NOT_GIVEN)
		config->use_AUTH = PARAM_NO;

	if (is_empty_string(config->host))
		FAIL(MSG_BAD_VAR, "SERVER:host");
	if (!is_valid_port_number(config->port_SMTP))
		FAIL(MSG_BAD_PORT_VAR, "SERVER:port_smtp");
	if (!config->subject)
		FAIL(MSG_BAD_VAR, "MAIL:subject");
	if (!config->from)
		FAIL(MSG_BAD_VAR, "MAIL:from");
	if (!config->reply_to)
		FAIL(MSG_BAD_VAR, "MAIL:replyto");
	if (config->nto == 0)
		FAIL(MSG_NO_SECTION, "adresow odbiorcow", "CC");
	if (!config->msg_body)
		FAIL(MSG_NO_SECTION, "tresci wiadomosci", "MSG");
	if (config->use_AUTH) {
		if (!config->password)
			FAIL(MSG_BAD_VAR, "SERVER:password");
		if (is_empty_string(config->login))
			FAIL(MSG_BAD_VAR, "SERVER:login");
	}
	for (unsigned int i = 0; i < config->nfiles; i++) {
		if (access(config->files[i], F_OK) != 0)
			FAIL(MSG_ATTACH_NOT_EXIST, config->files[i]);
	}
}

void _perform_work(const struct config *config)
{
	vmime::messageBuilder mb;
	mb.setSubject(vmime::text(std::string(config->subject)));
	mb.setExpeditor(vmime::mailbox(std::string(config->from)));
	mb. getTextPart()->setText
		(vmime::make_shared<vmime::stringContentHandler>
		 (config->msg_body));
	for (unsigned int i = 0; i < config->nto; i++) {
		mb.getCopyRecipients().appendAddress
			(vmime::make_shared<vmime::mailbox>
			 (std::string(config->to[i])));
	}
	for (unsigned int i = 0; i < config->nfiles; i++) {
		const char *file_name =
			config->files[i] + strlen(config->files[i]) - 1;

		while (*file_name != '\\' &&
		       file_name != config->files[i])
			file_name--;

		vmime::shared_ptr<vmime::fileAttachment> att =
			vmime::make_shared<vmime::fileAttachment>
			(std::string(config->files[i]),
			 vmime::mediaType("application/octet-stream"));
		att->getFileInfo().setFilename(file_name);
		mb.appendAttachment(att);
	}

	vmime::shared_ptr<vmime::message> msg = mb.construct();
	vmime::shared_ptr<vmime::headerFieldFactory> hf =
		vmime::headerFieldFactory::getInstance();
	vmime::shared_ptr<vmime::headerField> reply_to =
		hf->create(vmime::fields::REPLY_TO);

	reply_to->setValue(vmime::make_shared<vmime::mailbox>
			   (std::string(config->reply_to)));
	msg->getHeader()->appendField(reply_to);

	vmime::shared_ptr<vmime::net::session> session =
		vmime::net::session::create();
	vmime::shared_ptr<vmime::net::transport> transport;
	std::string proto = config->use_SSL ? "smtps" : "smtp";

	session->getProperties().setProperty("transport.protocol", proto);
	session->getProperties().setProperty
		("transport." + proto + ".server.address",
		 std::string(config->host));
	session->getProperties().setProperty("server.port", config->port_SMTP);
	if (config->use_AUTH) {
		session->getProperties().setProperty
			("transport." + proto + ".auth.password",
			 std::string(config->password));
		session->getProperties().setProperty
			("transport." + proto + ".auth.username",
			 std::string(config->login));
		session->getProperties().setProperty
			("transport." + proto + ".options.need-authentication",
			 true);
	}
	transport = session->getTransport();
	if (config->use_SSL)
		transport->setCertificateVerifier
			(windows_root_certs_verifier());
	transport->setTimeoutHandlerFactory
		(vmime::make_shared<parameterized_timeout_handler_factory>
		 (config->timeout));
	transport->connect();
	transport->send(msg);
	transport->disconnect();
}

extern "C" void perform_work(const struct config *config)
{
	try {
		_perform_work(config);
		SUCCEED();
	} catch (vmime::exception &e) {
		handle_vmime_exception(&e);
	} catch (std::exception &e) {
		handle_std_exception(&e);
	}
}