aboutsummaryrefslogtreecommitdiff
#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);
	}
}