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 | |
32 | namespace Poco { |
33 | namespace Net { |
34 | |
35 | |
36 | const std::string SMTPChannel::PROP_MAILHOST("mailhost" ); |
37 | const std::string SMTPChannel::PROP_SENDER("sender" ); |
38 | const std::string SMTPChannel::PROP_RECIPIENT("recipient" ); |
39 | const std::string SMTPChannel::PROP_LOCAL("local" ); |
40 | const std::string SMTPChannel::PROP_ATTACHMENT("attachment" ); |
41 | const std::string SMTPChannel::PROP_TYPE("type" ); |
42 | const std::string SMTPChannel::PROP_DELETE("delete" ); |
43 | const std::string SMTPChannel::PROP_THROW("throw" ); |
44 | |
45 | |
46 | SMTPChannel::SMTPChannel(): |
47 | _mailHost("localhost" ), |
48 | _local(true), |
49 | _type("text/plain" ), |
50 | _delete(false), |
51 | _throw(false) |
52 | { |
53 | } |
54 | |
55 | |
56 | SMTPChannel::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 | |
68 | SMTPChannel::~SMTPChannel() |
69 | { |
70 | try |
71 | { |
72 | close(); |
73 | } |
74 | catch (...) |
75 | { |
76 | poco_unexpected(); |
77 | } |
78 | } |
79 | |
80 | |
81 | void SMTPChannel::open() |
82 | { |
83 | } |
84 | |
85 | |
86 | void SMTPChannel::close() |
87 | { |
88 | } |
89 | |
90 | |
91 | void 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 | |
157 | void 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 | |
180 | std::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 | |
203 | void SMTPChannel::registerChannel() |
204 | { |
205 | Poco::LoggingFactory::defaultFactory().registerChannelClass("SMTPChannel" , |
206 | new Poco::Instantiator<SMTPChannel, Poco::Channel>); |
207 | } |
208 | |
209 | |
210 | } } // namespace Poco::Net |
211 | |