1//
2// SMTPChannel.cpp
3//
4// Library: Net
5// Package: Logging
6// Module: SMTPChannel
7//
8// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
9// and Contributors.
10//
11// SPDX-License-Identifier: BSL-1.0
12//
13
14
15#include "Poco/Net/SMTPChannel.h"
16#include "Poco/Net/MailMessage.h"
17#include "Poco/Net/MailRecipient.h"
18#include "Poco/Net/SMTPClientSession.h"
19#include "Poco/Net/StringPartSource.h"
20#include "Poco/Message.h"
21#include "Poco/DateTimeFormatter.h"
22#include "Poco/DateTimeFormat.h"
23#include "Poco/LocalDateTime.h"
24#include "Poco/LoggingFactory.h"
25#include "Poco/Instantiator.h"
26#include "Poco/NumberFormatter.h"
27#include "Poco/FileStream.h"
28#include "Poco/File.h"
29#include "Poco/Environment.h"
30
31
32namespace Poco {
33namespace Net {
34
35
36const std::string SMTPChannel::PROP_MAILHOST("mailhost");
37const std::string SMTPChannel::PROP_SENDER("sender");
38const std::string SMTPChannel::PROP_RECIPIENT("recipient");
39const std::string SMTPChannel::PROP_LOCAL("local");
40const std::string SMTPChannel::PROP_ATTACHMENT("attachment");
41const std::string SMTPChannel::PROP_TYPE("type");
42const std::string SMTPChannel::PROP_DELETE("delete");
43const std::string SMTPChannel::PROP_THROW("throw");
44
45
46SMTPChannel::SMTPChannel():
47 _mailHost("localhost"),
48 _local(true),
49 _type("text/plain"),
50 _delete(false),
51 _throw(false)
52{
53}
54
55
56SMTPChannel::SMTPChannel(const std::string& mailhost, const std::string& sender, const std::string& recipient):
57 _mailHost(mailhost),
58 _sender(sender),
59 _recipient(recipient),
60 _local(true),
61 _type("text/plain"),
62 _delete(false),
63 _throw(false)
64{
65}
66
67
68SMTPChannel::~SMTPChannel()
69{
70 try
71 {
72 close();
73 }
74 catch (...)
75 {
76 poco_unexpected();
77 }
78}
79
80
81void SMTPChannel::open()
82{
83}
84
85
86void SMTPChannel::close()
87{
88}
89
90
91void SMTPChannel::log(const Message& msg)
92{
93 try
94 {
95 MailMessage message;
96 message.setSender(_sender);
97 message.addRecipient(MailRecipient(MailRecipient::PRIMARY_RECIPIENT, _recipient));
98 message.setSubject("Log Message from " + _sender);
99 std::stringstream content;
100 content << "Log Message\r\n"
101 << "===========\r\n\r\n"
102 << "Host: " << Environment::nodeName() << "\r\n"
103 << "Logger: " << msg.getSource() << "\r\n";
104
105 if (_local)
106 {
107 DateTime dt(msg.getTime());
108 content << "Timestamp: " << DateTimeFormatter::format(LocalDateTime(dt), DateTimeFormat::RFC822_FORMAT) << "\r\n";
109 }
110 else
111 content << "Timestamp: " << DateTimeFormatter::format(msg.getTime(), DateTimeFormat::RFC822_FORMAT) << "\r\n";
112
113 content << "Priority: " << NumberFormatter::format(msg.getPriority()) << "\r\n"
114 << "Process ID: " << msg.getPid() << "\r\n"
115 << "Thread: " << msg.getThread() << " (ID: " << msg.getTid() << ")\r\n"
116 << "Message text: " << msg.getText() << "\r\n\r\n";
117
118 message.addContent(new StringPartSource(content.str()));
119
120 if (!_attachment.empty())
121 {
122 {
123 Poco::FileInputStream fis(_attachment, std::ios::in | std::ios::binary | std::ios::ate);
124 if (fis.good())
125 {
126 typedef std::allocator<std::string::value_type>::size_type SST;
127
128 std::streamoff size = fis.tellg();
129 poco_assert (std::numeric_limits<unsigned int>::max() >= size);
130 poco_assert (std::numeric_limits<SST>::max() >= size);
131 char* pMem = new char [static_cast<unsigned int>(size)];
132 fis.seekg(std::ios::beg);
133 fis.read(pMem, size);
134 message.addAttachment(_attachment,
135 new StringPartSource(std::string(pMem, static_cast<SST>(size)),
136 _type,
137 _attachment));
138
139 delete [] pMem;
140 }
141 }
142 if (_delete) File(_attachment).remove();
143 }
144
145 SMTPClientSession session(_mailHost);
146 session.login();
147 session.sendMessage(message);
148 session.close();
149 }
150 catch (Exception&)
151 {
152 if (_throw) throw;
153 }
154}
155
156
157void SMTPChannel::setProperty(const std::string& name, const std::string& value)
158{
159 if (name == PROP_MAILHOST)
160 _mailHost = value;
161 else if (name == PROP_SENDER)
162 _sender = value;
163 else if (name == PROP_RECIPIENT)
164 _recipient = value;
165 else if (name == PROP_LOCAL)
166 _local = isTrue(value);
167 else if (name == PROP_ATTACHMENT)
168 _attachment = value;
169 else if (name == PROP_TYPE)
170 _type = value;
171 else if (name == PROP_DELETE)
172 _delete = isTrue(value);
173 else if (name == PROP_THROW)
174 _throw = isTrue(value);
175 else
176 Channel::setProperty(name, value);
177}
178
179
180std::string SMTPChannel::getProperty(const std::string& name) const
181{
182 if (name == PROP_MAILHOST)
183 return _mailHost;
184 else if (name == PROP_SENDER)
185 return _sender;
186 else if (name == PROP_RECIPIENT)
187 return _recipient;
188 else if (name == PROP_LOCAL)
189 return _local ? "true" : "false";
190 else if (name == PROP_ATTACHMENT)
191 return _attachment;
192 else if (name == PROP_TYPE)
193 return _type;
194 else if (name == PROP_DELETE)
195 return _delete ? "true" : "false";
196 else if (name == PROP_THROW)
197 return _throw ? "true" : "false";
198 else
199 return Channel::getProperty(name);
200}
201
202
203void SMTPChannel::registerChannel()
204{
205 Poco::LoggingFactory::defaultFactory().registerChannelClass("SMTPChannel",
206 new Poco::Instantiator<SMTPChannel, Poco::Channel>);
207}
208
209
210} } // namespace Poco::Net
211