17 #if _RAKNET_SUPPORT_EmailSender==1 && _RAKNET_SUPPORT_TCPInterface==1 && _RAKNET_SUPPORT_FileOperations==1
40 using namespace SLNet;
45 const char *
EmailSender::Send(
const char *hostAddress,
unsigned short hostPort,
const char *sender,
const char *recipient,
const char *senderName,
const char *recipientName,
const char *subject,
const char *body,
FileList *attachedFiles,
bool doPrintf,
const char *password)
51 if (tcpInterface.
Start(0, 0)==
false)
52 return "Unknown error starting TCP";
53 emailServer=tcpInterface.
Connect(hostAddress, hostPort,
true);
55 return "Failed to connect to host";
56 #if OPEN_SSL_CLIENT_SUPPORT==1
57 tcpInterface.StartSSLClient(emailServer);
63 packet = tcpInterface.
Receive();
77 return "Timeout while waiting for initial data from server.";
79 tcpInterface.
Send(
"EHLO\r\n", 6, emailServer,
false);
81 bool authenticate=
false;
84 response=
GetResponse(&tcpInterface, emailServer, doPrintf);
86 if (response!=0 && strcmp(response,
"AUTHENTICATE")==0)
93 if (response!=0 && strcmp(response,
"CONTINUE")!=0)
103 sprintf_s(query,
"EHLO %s\r\n", sender);
104 tcpInterface.
Send(query, (
unsigned int)strlen(query), emailServer,
false);
105 response=
GetResponse(&tcpInterface, emailServer, doPrintf);
109 return "Password needed";
110 char *outputData = SLNet::OP_NEW_ARRAY<char >((
const int) (strlen(sender)+strlen(password)+2)*3,
_FILE_AND_LINE_ );
114 bs.
Write(sender,(
const unsigned int)strlen(sender));
117 bs.
Write(password,(
const unsigned int)strlen(password));
121 sprintf_s(query,
"AUTH PLAIN %s", outputData);
122 tcpInterface.
Send(query, (
unsigned int)strlen(query), emailServer,
false);
123 response=
GetResponse(&tcpInterface, emailServer, doPrintf);
130 sprintf_s(query,
"MAIL From: <%s>\r\n", sender);
132 sprintf_s(query,
"MAIL From: <>\r\n");
133 tcpInterface.
Send(query, (
unsigned int)strlen(query), emailServer,
false);
134 response=
GetResponse(&tcpInterface, emailServer, doPrintf);
139 sprintf_s(query,
"RCPT TO: <%s>\r\n", recipient);
141 sprintf_s(query,
"RCPT TO: <>\r\n");
142 tcpInterface.
Send(query, (
unsigned int)strlen(query), emailServer,
false);
143 response=
GetResponse(&tcpInterface, emailServer, doPrintf);
147 tcpInterface.
Send(
"DATA\r\n", (
unsigned int)strlen(
"DATA\r\n"), emailServer,
false);
151 response=
GetResponse(&tcpInterface, emailServer, doPrintf);
157 sprintf_s(query,
"Subject: %s\r\n", subject);
158 tcpInterface.
Send(query, (
unsigned int)strlen(query), emailServer,
false);
162 sprintf_s(query,
"From: %s\r\n", senderName);
163 tcpInterface.
Send(query, (
unsigned int)strlen(query), emailServer,
false);
167 sprintf_s(query,
"To: %s\r\n", recipientName);
168 tcpInterface.
Send(query, (
unsigned int)strlen(query), emailServer,
false);
171 const int boundarySize=60;
172 char boundary[boundarySize+1];
178 for (i=0; i < boundarySize; i++)
180 boundary[boundarySize]=0;
183 sprintf_s(query,
"MIME-version: 1.0\r\n");
184 tcpInterface.
Send(query, (
unsigned int)strlen(query), emailServer,
false);
188 sprintf_s(query,
"Content-type: multipart/mixed; BOUNDARY=\"%s\"\r\n\r\n", boundary);
189 tcpInterface.
Send(query, (
unsigned int)strlen(query), emailServer,
false);
191 sprintf_s(query,
"This is a multi-part message in MIME format.\r\n\r\n--%s\r\n", boundary);
192 tcpInterface.
Send(query, (
unsigned int)strlen(query), emailServer,
false);
195 sprintf_s(query,
"Content-Type: text/plain; charset=\"US-ASCII\"\r\n\r\n");
196 tcpInterface.
Send(query, (
unsigned int)strlen(query), emailServer,
false);
201 bodyLength=(int)strlen(body);
205 for (i=1, j=1; i < bodyLength; i++)
208 if (i < bodyLength-2 &&
222 else if (i <= bodyLength-3 &&
237 else if (i < bodyLength-1 &&
250 else if (i <= bodyLength-2 &&
264 newBody[j++]=body[i];
269 tcpInterface.
Send(newBody, j, emailServer,
false);
277 for (i=0; i < (int) attachedFiles->
fileList.
Size(); i++)
280 sprintf_s(query,
"\r\n--%s\r\n", boundary);
281 tcpInterface.
Send(query, (
unsigned int)strlen(query), emailServer,
false);
283 sprintf_s(query,
"Content-Type: APPLICATION/Octet-Stream; SizeOnDisk=%i; name=\"%s\"\r\nContent-Transfer-Encoding: BASE64\r\nContent-Description: %s\r\n\r\n", attachedFiles->
fileList[i].dataLengthBytes, attachedFiles->
fileList[i].filename.C_String(), attachedFiles->
fileList[i].filename.C_String());
284 tcpInterface.
Send(query, (
unsigned int)strlen(query), emailServer,
false);
291 tcpInterface.
Send(newBody, outputOffset, emailServer,
false);
297 sprintf_s(query,
"\r\n--%s--\r\n", boundary);
298 tcpInterface.
Send(query, (
unsigned int)strlen(query), emailServer,
false);
302 sprintf_s(query,
"\r\n.\r\n");
303 tcpInterface.
Send(query, (
unsigned int)strlen(query), emailServer,
false);
304 response=
GetResponse(&tcpInterface, emailServer, doPrintf);
308 tcpInterface.
Send(
"QUIT\r\n", (
unsigned int)strlen(
"QUIT\r\n"), emailServer,
false);
313 packet = tcpInterface.
Receive();
318 packet = tcpInterface.
Receive();
333 return "Connection to server lost.";
334 packet = tcpInterface->
Receive();
341 #if OPEN_SSL_CLIENT_SUPPORT==1
342 if (strstr((
const char*)packet->
data,
"220"))
345 return "AUTHENTICATE";
353 if (strstr((
const char*)packet->
data,
"235"))
355 if (strstr((
const char*)packet->
data,
"354"))
357 #if OPEN_SSL_CLIENT_SUPPORT==1
358 if (strstr((
const char*)packet->
data,
"250-STARTTLS"))
360 tcpInterface->
Send(
"STARTTLS\r\n", (
unsigned int) strlen(
"STARTTLS\r\n"), packet->
systemAddress,
false);
364 if (strstr((
const char*)packet->
data,
"250"))
366 if (strstr((
const char*)packet->
data,
"550"))
367 return "Failed on error code 550";
368 if (strstr((
const char*)packet->
data,
"553"))
369 return "Failed on error code 553";
378 #endif // _RAKNET_SUPPORT_*